@name Speed Boat Attack
@inputs [POD CAM EGP HOLOEMITTER]:wirelink
@outputs 
@persist [E O B B2 BE DY PC JO BB BC ARM LAS]:entity GO
@persist DYC [DYPos BPos DYBS DYBC POS DCP TORQ]:vector [DYAng BAng]:angle
@persist USE RB M1B M2B M1 M2 W A S D R Shift Space Alt F [CAMS PJ OPJ HITS]:array CS HT
@persist BUILDING APOS AANG AANG2 SP ASP AFW TAFW DPOS:vector
@persist BPR BF DEATHCAM DCT DCA READY AS:table PJT ACT LS CT
@persist EGP_TIME Stat STATUS:array FLIR
@persist [BoatModel DockYardModel]:string BVOA SHT [BT PLST PLN]:gtable
@model models/props_lab/huladoll.mdl

#####
#UKE#
#####

if(first() | duped()){timer("go",2000), hint("E2 will be run in about 2sec.",15),entity():setMaterial("models/shiny"), entity():setColor(vec())}

if(clk("go")&owner()["IsBuilding",number] != 1){
    runOnTick(1)
    runOnLast(1)
    runOnChat(1)
    
    E = entity()
    O = owner()
    
    E:setMaterial("models/shiny")
    E:setColor(vec(255,215,0)) #Gold
    
    holoCreate(1337,E:pos(),vec())
    holoAlpha(1337,0)
    holoEntity(1337):setTrails(0,10,1.5,"trails/laser",vec(255,130,0),255)
    CT = systime()
    
    AS = table(
        "arm" = array(
            "/npc/dog/dog_servo1.wav",
            "/npc/dog/dog_servo2.wav",
            "/npc/dog/dog_servo3.wav",
            "/npc/dog/dog_servo5.wav",
            "/npc/dog/dog_servo6.wav",
            "/npc/dog/dog_servo8.wav",
            "/npc/dog/dog_servo10.wav",
            "/npc/dog/dog_servo12.wav"
        ),
        "laser" = array(
            "/npc/roller/mine/rmine_shockvehicle1.wav",
            "/npc/roller/mine/rmine_shockvehicle2.wav"
        ),
        "ambient" = array(
            "/ambient/water/lake_water.wav",
            "/ambient/machines/lab_loop1.wav"
        ),
        "boat" = table(
            "built" = "/plats/crane/vertical_stop.wav",
            "fire"  = "/npc/combine_gunship/attack_start2.wav",
            "motor" = "/ambient/machines/engine1.wav",
            "motor2"= "/ambient/water/water_in_boat1.wav",
            "start" = "/vehicles/jetski/jetski_no_gas_start.wav",
            "stop"  = "/vehicles/jetski/jetski_off.wav",
            "die"   = "/npc/scanner/cbot_energyexplosion1.wav"
        ),
        "hitsound" = array(
            "npc/vort/foot_hit.wav",
            "npc/zombie/zombie_hit.wav",
            "/ambient/misc/brass_bell_f.wav"
        )
    )
    BT = gTable("SpeedBoatAttack",1)
    PLST = gTable("SpeedBoatAttack_PlayerStats",1)
    PLN = gTable("SpeedBoatAttack_PlayerNames",1)
    Stat=0
    STATUS=array(
        "Right click in order to build a boat.",
        "Left click to undock and drive.",
        "Left click to return to the dockyard."
    )
    
    BoatModel = "models/Items/AR2_Grenade.mdl"
    DockYardModel = "models/props_phx/misc/potato_launcher_chamber.mdl"
    
    BPos = vec(-0.7,0,-14)
    BAng = ang(90,0,0)
    
    DYPos = E["DYPos",vector]
    DYAng = E["DYAng",angle]
    DYC   = 1
    
    DYBS=vec(14.610655784607,14.610652923584,23.473651885986)
    DYBC=vec(0,0,-10.28112411499)
    
    CAMS = array(
        vec(-2.64,2.85,-1.76),
        ang(47.15,-90.16,89.87),
        vec(-2.69,-0.03,-1.4),
        ang(87.87,-10.45,169.53),
        vec(-1.85,-6.53,-14.17),
        ang(-0.26,87.68,-90),
        vec(-5.01,-6.94,-14.11),
        ang(0.16,61.94,-90.1),
        vec(-7.44,-4.05,-14),
        ang(-0.42,37.08,-89.46),
        vec(-4.46,7.68,-13.34),
        ang(0.18,-59.09,90.1),
        vec(-5.91,5.81,-13.44),
        ang(0.27,-40.17,90.32),
        vec(-7.27,4.6,-13.44),
        ang(0.2,-28.07,90.37),
        vec(5.47,-4.86,-29.09),
        ang(-58.63,143.19,-138.78),
        vec(-4.76,1.47,-32.2),
        ang(-65.91,-9.3,10.16),
        vec(-0.53,0.11,-30.95),
        ang(-80.74,-3.77,3.8),
        vec(-1.9,1.17,8.72),
        ang(84.04,-2.95,177.03),
        vec(4.13,-0.58,-4.1),
        ang(64.45,167.13,-14.22),
        vec(-6.11,-1.91,-10.71),
        ang(25.6,18.75,-141.86)
    )
    
    function entity spawnDock(POS:vector, ANG:angle){
        TD = propSpawn(DockYardModel,POS,ANG,1)
        TD:setMaterial("phoenix_storms/bluemetal")
        TD:setColor(vec4(255,255,255,255))
        
        TD:soundPlay(4,0,AS["ambient",array][2,string])
        soundPitch(4,80)
        soundVolume(4,0.02)
        
        PC=holoCreate(10,TD:toWorld(vec(0,0,1)),vec(),TD:toWorld(ang(-90,0,0)))
        holoScaleUnits(10,vec(3,3.4,3.4))
        holoModel(10,"models/props_c17/pipe_cap005c.mdl")
        holoMaterial(10,"models/shiny")
        holoColor(10,vec(40,40,40))
        holoParent(10,TD)
        
        PC:soundPlay(5,0,AS["ambient",array][1,string])
        soundPitch(5,80)
        soundVolume(5,0.2)
        
        holoCreate(11,TD:toWorld(vec(0,10.55,-10)),vec(),TD:toWorld(ang(0,0,0)))
        holoScaleUnits(11,vec(0.69229726286278,0.79282853669922,1)*5)
        holoModel(11,"models/props_c17/utilityconducter001.mdl")
        holoMaterial(11,"phoenix_storms/bluemetal")
        holoParent(11,TD)
        
        holoCreate(12,TD:toWorld(vec(0,-10.55,-10)),vec(),TD:toWorld(ang(0,180,0)))
        holoScaleUnits(12,vec(0.69229726286278,0.79282853669922,1)*5)
        holoModel(12,"models/props_c17/utilityconducter001.mdl")
        holoMaterial(12,"phoenix_storms/bluemetal")
        holoParent(12,TD)
        
        holoCreate(13,TD:toWorld(vec(-5.8,0,-11.5)),vec(),TD:toWorld(ang(0,90,90)))
        holoScaleUnits(13,vec(3,8,3.6))
        holoModel(13,"models/props_c17/utilityconnecter003.mdl")
        holoMaterial(13,"phoenix_storms/fender_chrome")
        holoParent(13,TD)
        
        JO=holoCreate(14,TD:toWorld(vec(-5.3,0,-7)),vec(),TD:toWorld(ang(0,0,0)))
        holoScaleUnits(14,vec(2,2,3))
        holoModel(14,"models/props_junk/PopCan01a.mdl")
        holoMaterial(14,"phoenix_storms/fender_chrome")
        holoParent(14,TD)
        
        holoCreate(142,TD:toWorld(vec(-5.1,0,-7)),vec(),TD:toWorld(ang(0,0,0)))
        holoParent(142,14)
        
        ARM=holoCreate(15,holoEntity(14):toWorld(vec(0.2,0,3.3)),vec(),holoEntity(14):toWorld(ang(60,180,0)))
        holoScaleUnits(15,vec(0.36,0.36,0.36))
        holoModel(15,"models/props_combine/breen_arm.mdl")
        holoParent(15,142)
        holoClipEnabled(15,1)
        holoClip(15,vec(0,0,-1.6),vec(0,0,-1),0)
        
        LAS=holoCreate(152,holoEntity(15):toWorld(vec(1.5,0,-5)),vec(),holoEntity(15):toWorld(ang(0,0,0)))
        holoParent(152,15)
        holoModel(152,"models/hunter/plates/plate.mdl")
        holoMaterial(152,"models/props_combine/tprings_globe")
        holoColor(152,vec(255,0,0))
        holoDisableShading(152,1)
        
        holoCreate(16,TD:toWorld(vec(0,5.2,-11.9)),vec(),TD:toWorld(ang(90,0,0)))
        holoScaleUnits(16,vec(20*0.25,3.2*0.25,1.5))
        holoModel(16,"models/hunter/plates/plate1x1.mdl")
        holoMaterial(16,"phoenix_storms/middle")
        holoColor(16,vec(140,140,160))
        holoParent(16,TD)
        
        holoCreate(17,TD:toWorld(vec(0,-5.2,-11.9)),vec(),TD:toWorld(ang(90,0,0)))
        holoScaleUnits(17,vec(20*0.25,3.2*0.25,1.5))
        holoModel(17,"models/hunter/plates/plate1x1.mdl")
        holoMaterial(17,"phoenix_storms/middle")
        holoColor(17,vec(140,140,160))
        holoParent(17,TD)
        
        holoCreate(18,TD:toWorld(vec(-0.1,0,-4.8)),vec(),TD:toWorld(ang(0,90,90)))
        holoScaleUnits(18,vec(14*0.25,8*0.25,2))
        holoModel(18,"models/hunter/plates/plate1x1.mdl")
        holoMaterial(18,"phoenix_storms/middle")
        holoColor(18,vec(140,140,160))
        holoParent(18,TD)
        
        holoCreate(19,TD:toWorld(vec(-0.96,-5,-2.8)),vec(),TD:toWorld(ang(40,90,90)))
        holoScaleUnits(19,vec(0.36,0.36,0.36))
        holoModel(19,"models/props_junk/wood_crate002a.mdl")
        holoParent(19,TD)
        
        holoCreate(20,TD:toWorld(vec(-0.96,4,-2.5)),vec(),TD:toWorld(ang(10,90,90)))
        holoScaleUnits(20,vec(0.36,0.36,0.36))
        holoModel(20,"models/props_junk/wood_crate001a.mdl")
        holoParent(20,TD)
        
        holoCreate(21,TD:toWorld(vec(-2.2,-4.8,-2.8)),vec(),TD:toWorld(ang(-30,90,90)))
        holoScaleUnits(21,vec(0.36,0.36,0.36))
        holoModel(21,"models/props_junk/wood_crate001a.mdl")
        holoParent(21,TD)
        
        holoCreate(22,TD:toWorld(vec(-0.96,5,-3.8)),vec(),TD:toWorld(ang(30,90,90)))
        holoScaleUnits(22,vec(0.36,0.36,0.36))
        holoModel(22,"models/props_junk/wood_crate001a.mdl")
        holoParent(22,TD)
        
        holoCreate(23,TD:toWorld(vec(-4.85,4.1,-12)),vec(),TD:toWorld(ang(0,-40,90)))
        holoScaleUnits(23,vec(1,11,1))
        holoModel(23,"models/props_c17/light_decklight01_on.mdl")
        holoParent(23,TD)
        
        holoCreate(24,TD:toWorld(vec(-4.85,-4.1,-12)),vec(),TD:toWorld(ang(0,40,90)))
        holoScaleUnits(24,vec(1,11,1))
        holoModel(24,"models/props_c17/light_decklight01_on.mdl")
        holoParent(24,TD)
        
        holoCreate(25,TD:toWorld(vec(-4,0,-21.2)),vec(),TD:toWorld(ang(-90,0,0)))
        holoScaleUnits(25,vec(4,2.5,1.3))
        holoModel(25,"models/XQM/panel180.mdl")
        holoMaterial(25,"phoenix_storms/glass")
        holoParent(25,TD)
        
        for(I = 10, 25){
            holoVisible(I,players(),1)
        }
        holoVisible(142,players(),1)
        holoVisible(152,players(),1)
        return TD
    }

    function boatSpawn(){
        if(!B:isValid() & DY:isValid()){
            B=propSpawn(BoatModel,DY:toWorld(vec(-0.7,0,-14)),DY:toWorld(ang(90,180,0)),1)
            B:setMass(200)
            B:setAlpha(0)
            B:propNotSolid(1)
            B2=holoCreate(100,B:toWorld(vec(0,0,1.2)),vec(),B:toWorld(ang()))
            holoScaleUnits(100,vec(0.36,0.36,0.36))
            holoModel(100,"models/props_italian/boat_wooden03a.mdl")
            holoMaterial(100,"phoenix_storms/fender_chrome")
            holoParent(100,B)
            
            if(B2:model() != "models/props_italian/boat_wooden03a.mdl"){
                holoModel(100,"models/props_canal/boat002b.mdl")
                holoPos(100,B:toWorld(vec(0.2,0,1.2)))
                holoScaleUnits(100,vec(6.5,2.6,2.2))
            }
            
            BT["Boat_"+B:id(),entity] = B
            BT["Boat_"+B:id()+"_Hits",number] = 0
            
            BE=holoCreate(101,B:toWorld(vec(-1,-0.14,1.3)),vec(),B:toWorld(ang(-98,180,0)))
            holoScaleUnits(101,vec(0.7,0.7,0.7) )
            holoModel(101,"models/props_c17/TrapPropeller_Engine.mdl")
            holoMaterial(101,"phoenix_storms/fender_chrome")
            holoParent(101,B)
            
            holoCreate(102,B:toWorld(vec(-2,0,1)),vec(),B:toWorld(ang(-100,0,0)))
            holoScaleUnits(102,vec(1, 1, 2.2) )
            holoModel(102,"models/props_pipes/valvewheel002.mdl")
            holoMaterial(102,"phoenix_storms/fender_chrome")
            holoParent(102,B)
            
            BC=holoCreate(103,B:toWorld(vec(3.2,0,2.2)),vec(),B:toWorld(ang(0,0,0)))
            holoScaleUnits(103,vec(1, 1, 1) )
            holoModel(103,"icosphere3")
            holoMaterial(103,"phoenix_storms/fender_chrome")
            holoParent(103,B)
            
            BB=holoCreate(104,BC:toWorld(vec(0.6,0,0.3)),vec(),BC:toWorld(ang(-90,0,0)))
            holoScaleUnits(104,vec(1, 1, 1) )
            holoModel(104,"models/props_combine/breenlight.mdl")
            holoParent(104,BC)
            
            for(I=100,104){
                holoAlpha(I,0)
                holoVisible(I,players(),1)
            }
        }
    }
    
    function boatBreak(){
        if(B:isValid()){
            B:soundPlay(1,1,AS["boat",table]["die",string])
            BT:removeEntity("Boat_"+B:id())
            BT:removeNumber("Boat_"+B:id()+"_Hits")
            DEATHCAM = 1
            DCP=B:pos()
            DCT=curtime()+3
            DCA=B:angles():yaw()
            B:propFreeze(1)
            X=propSpawn("models/props_phx/misc/potato_launcher_explosive.mdl",B:pos()-vec(0,0,25),1)
            B:propDelete()
            X:propBreak()
            for(I=100,104){
                holoDelete(I)
            }
            READY=0
            BUILDING=0
            B=noentity()
        }
    }
    function dyHolo(){
        if(holoEntity(1):isValid()){
            holoDelete(1)
            holoDelete(2)
            holoDelete(3)
        }else{
            DYH=holoCreate(1)
            holoModel(1,DockYardModel)
            holoColor(1,vec(100,150,255),150)
            holoMaterial(1,"phoenix_storms/middle")
            holoCreate(2,vec(),vec())
            holoModel(2,"hq_stube_thin")
            holoScaleUnits(2,vec(30,30,2))
            holoColor(2,vec(255,255,255),150)
            holoCreate(3,vec(),vec())
            holoModel(3,"hq_stube_thin")
            holoScaleUnits(3,vec(30,30,2))
            holoColor(3,vec(255,255,255),150)
        }
    }
    
    function number dyhPosition(){
        HO = holoEntity(1)
        rangerHitWater(1)
        RD1=rangerOffsetHull(100,HO:toWorld(DYBC)+vec(0,0,15),vec(0,0,-1),vec(30,30,0))
        rangerHitWater(1)
        RD2=rangerOffsetHull(100,HO:toWorld(vec(0,0,-DYBS:z()-18))+vec(0,0,15),vec(0,0,-1),vec(30,30,0))
        holoPos(2,RD1:pos())
        holoPos(3,RD2:pos())
        if(RD1:matType() == "slosh" & RD2:matType() == "slosh" & !RD1:startSolid() & !RD2:startSolid()){
            holoColor(1,vec(100,150,255),150)
            return 1
        }else{
            holoColor(1,vec(255,0,0),150)
            return 0
        }
    }
    
    function vector dyhMove(){
        if(holoEntity(1):isValid()){
            rangerHitWater(1)
            rangerFilter(array(O))
            RD=rangerOffset(O:shootPos(),O:aimPos())
            RDP=RD:pos()
            holoAng(1,ang(90,holoEntity(1):angles():yaw(),0))
            holoPos(1,RDP)
            return RDP
        }else{
            return vec()
        }
    }
    function angle dyhRot(){
        if(holoEntity(1):isValid()){
            rangerHitWater(1)
            rangerFilter(array(O))
            RD=rangerOffset(O:shootPos(),O:aimPos())
            RDP=RD:pos()
            ANG=ang(90,180-bearing(holoEntity(1):pos(),ang(),RDP),0)
            holoAng(1,ANG)
            return ANG
        }else{
            return ang()
        }
    }
    GO = 1
    if(BT["L",number] == 0){
        BT["L",number] = 3
    }
    dsSetScope(2)
    dsJoinGroup("SpeedBoatAttack")
    if(DYPos == vec()){
        DYC = 0
        dyHolo()
        DYAng = ang(90,0,0)
        O["IsBuilding",number] = 1
    }else{
        DY = spawnDock(DYPos, DYAng)
        AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"If you want to move the dockyard then look at it or the E2-chip and say \"move\".")
        printColor(AR)
    }
    POS=DY:pos()
    CS = 1
    
    EGP:egpClear()
    EGP:egpCircleOutline(1,vec2(),vec2(6,6))
    EGP:egpColor(1,vec4(0,0,0,120))
    EGP:egpCircleOutline(2,vec2(),vec2(4,4))
    EGP:egpColor(2,vec4(255,0,0,160))
    EGP:egpParent(2,1)
    EGP:egpRoundedBox(3,vec2(),vec2(100,66))
    EGP:egpColor(3,vec4(0,165,255,200))
    EGP:egpText(4,"Damage:",vec2(-8,-30))
    EGP:egpSize(4,17)
    EGP:egpAlign(4,1)
    EGP:egpParent(4,3)
    EGP:egpText(5,(BT["Boat_"+B:id()+"_Hits",number]/BT["L",number])+"%",vec2())
    EGP:egpSize(5,25)
    EGP:egpAlign(5,1,1)
    EGP:egpParent(5,3)
    EGP:egpRoundedBox(6,vec2(),vec2(300,30))
    EGP:egpColor(6,vec4(0,165,255,200))
    EGP:egpText(7,STATUS[Stat,string],vec2())
    EGP:egpSize(7,17)
    EGP:egpAlign(7,1,1)
    EGP:egpParent(7,6)
    
    EGP:egp3DTracker(8,DY:toWorld(vec(-10,0,-18)))
    EGP:egpTriangle(9,vec2(),vec2(-10,-20),vec2(10,-20))
    EGP:egpColor(9,vec4(0,165,255,180))
    EGP:egpParent(9,8)
    
    EGP:egpTriangleOutline(10,vec2(0,4),vec2(-12,-22),vec2(12,-22))
    EGP:egpSize(10,3)
    EGP:egpColor(10,vec4(255,255,255,120))
    EGP:egpParent(10,8)
    
    for(I=1,5){
        EGP:egp3DTracker(9+I*2,vec())
        EGP:egpText(10+I*2,"HIT",vec2(0,-10))
        EGP:egpFont(10+I*2, "CoolVetica", 15 )
        EGP:egpAlign(10+I*2,1,1)
        EGP:egpColor(10+I*2,vec4(255,0,0,130))
        EGP:egpParent(10+I*2,9+I*2)
    }
    if(Stat == 0){
        EGP:egpAlpha(6,0)
        EGP:egpAlpha(7,0)
    }else{
        EGP:egpAlpha(6,200)
        EGP:egpAlpha(7,200)
        EGP:egpSetText(7,STATUS[Stat,string])
    }
}
if(clk("go")&!GO){timer("go",1000)}
if(GO){
    SEAT=POD["Entity",entity]
    DR=SEAT:driver()
    
    HE=HOLOEMITTER:entity()
    
    if(->HOLOEMITTER&HE:parent()!=holoEntity(152)&O:lastSaid():upper()!="SBA_DUPE"){
        HE:setPos(holoEntity(152):pos())
        if(HE:pos():distance(holoEntity(152):pos())<1){
            HE:parentTo(holoEntity(152))
            HE:propNotSolid(1)
            HE:setAlpha(1)
            HE:propFreeze(1)
            HOLOEMITTER["FadeTime",number]=0.4
            HOLOEMITTER["LineBeam",number]=0
            HOLOEMITTER["GroundBeam",number]=1
            HOLOEMITTER["Size",number]=3
            HOLOEMITTER["Local",number]=0
            holoPos(152,holoEntity(15):toWorld(vec(1.5,0,-5)))
            holoScale(152,vec())
        }
    }
    #####
    #UKE#
    #####
    if(tickClk()){
        SY = systime()
        SST= sin((SY+CT)*50)
        holoPos(1337,E:toWorld(vec(5,0,5):rotate(ang(SST*35,systime()*500,0))))
        
        if(DYC == 0){
            USE = O:keyUse()
            RB  = O:keyReload()
            M1B = O:keyAttack1()
            M2B = O:keyAttack2()
        
            print(_HUD_PRINTCENTER,"Place the dockyard somewhere on the water. Hold R to rotate, R + 'Left Mouse Button' to confirm.")
            if(RB){
                DYAng = dyhRot()
            }else{
                DYPos = dyhMove()
            }
            VALID = dyhPosition()
            
            if(VALID==1 & M1B & RB){
                dyHolo()
                E["DYPos",vector]   = DYPos
                E["DYAng",angle]    = DYAng
                DYC   = 1
                DY = spawnDock(DYPos, DYAng)
                O["IsBuilding",number] = 0
                print(_HUD_PRINTCENTER,"")
                DY:soundPlay(12,1,"/ambient/machines/floodgate_stop1.wav",0.5)
                soundPitch(12,120)
                soundVolume(12,0.36)
            }
        }else{
            ACT=POD["Active",number]
            
            W=POD["W",number]
            A=POD["A",number]
            S=POD["S",number]
            D=POD["D",number]
            R=POD["R",number]
            F=POD["Light",number]
            Z=POD["Zoom",number]
            Alt=POD["Alt",number]
            Shift=POD["Shift",number]
            Space=POD["Space",number]
            M1=POD["Mouse1",number]
            M2=POD["Mouse2",number]
            
            CAM["Activated",number] = ACT * ->CAM * ->POD
            VAN=E:toWorld(SEAT:toLocal(DR:eyeAngles()))
            
            BVOA = B:isValid() * ACT * (!B:isFrozen())
            
            if(ACT & $ACT){
                ScrSize = egpScrSize(DR)
                
                EGP:egpPos(1,ScrSize/2 - vec2(1,0))
                EGP:egpPos(3,ScrSize - vec2(200,160))
                EGP:egpPos(6,ScrSize * vec2(0.5,1) - vec2(0,50))
                
                PLN[DR:steamID()+"_NAME",string]=DR:name():sub(1,18)
            }
            
            if(BVOA&$BVOA){
                B:soundPlay(6,1,AS["boat",table]["start",string])
                soundVolume(6,0.4)
                BE:soundPlay(10,0,AS["boat",table]["motor",string])
                B2:soundPlay(11,0,AS["ambient",array][1,string])
            }elseif(!BVOA&$BVOA){
                CAM["FLIR",number] = 0
                if(B:isValid()){
                    B:soundPlay(6,1,AS["boat",table]["stop",string])
                    soundVolume(6,0.4)
                }
                soundStop(10)
                soundStop(11)
            }
            
            if((!B:isValid()|BUILDING|READY)&!DEATHCAM){
                
                if(BT["H_"+DR:steamID(),number]!=1){
                    AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"Use W and S to switch between the cameras.")
                    SEAT:printColorDriver(AR)
                    AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"Right Mouse Button to build a boat.")
                    SEAT:printColorDriver(AR)
                    AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"Left Mouse Button to drive it.")
                    SEAT:printColorDriver(AR)
                    AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"W A S D to move, shift turbo, alt slower, left click fire, right click FLIR and zoomkey to aim.")
                    SEAT:printColorDriver(AR)
                    AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"Say \"stats\" to get all players statistics.")
                    SEAT:printColorDriver(AR)
                    AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"Say \"help\" to get the helptext.")
                    SEAT:printColorDriver(AR)

                    BT["H_"+DR:steamID(),number]=1
                }
                SI = sin(VAN:yaw())
                CO = cos(VAN:yaw())
                
                CS = CS + (W&$W) - (S&$S)
                if(CS>CAMS:count()/2){CS=1}
                if(CS<1){CS=CAMS:count()/2}
        
                CAM["Position",vector] = DY:toWorld(CAMS[(CS*2-1),vector])
                CAM["Angle",angle] = DY:toWorld(CAMS[(CS*2),angle])
                if(!BUILDING&!READY){
                    Stat=1
                }elseif(!BUILDING&READY){
                    Stat=2
                }else{
                    Stat=0
                }
                if(!BUILDING & M2 & !READY){
                    APOS = random(-10,-16)
                    SP=0.05
                    AANG = randint(-90,90)
                    BUILDING=1
                    BPR = 0
                    ASP=random(0.8,1.3)
                    AFW=randint(0,1)
                    AFW = AFW == 0 ? -1 : 1
                    DPOS=randvec(BPos+vec(-1,-1,-3),BPos+vec(1,1,3))
                    BF=curtime()+6
                    boatSpawn()
                }elseif(BUILDING){
                    HOLOEMITTER["Active",number]=1
                    BPR = clamp(1-floor((BF-curtime())/4,1),0,1)
                    for(I=100,104){
                        holoAlpha(I,255*clamp(BPR,0,1))
                    }
                    
                    if(BPR<1){
                        LP14=DY:toLocal(JO:pos())
                        Z14  = LP14:z()
                        if(abs(APOS-Z14)<=0.1){
                            APOS = random(-10,-16)
                            SP=random(0.01,0.03)
                            DPOS=randvec(BPos+vec(-1,-1,-3),BPos+vec(1,1,3))
                            AAR = AS["arm",array]
                            ARM:soundPlay(2,1,AAR[randint(1,AAR:count()),string])
                            soundPitch(2,140)
                            soundVolume(2,0.1)
                            
                            LAR = AS["laser",array]
                            LAS:soundPlay(3,1,LAR[randint(1,LAR:count()),string])
                            soundPitch(3,140)
                            soundVolume(3,0.05)
                        }else{
                            holoPos(14,DY:toWorld(vec(-5.3,0,clamp(Z14+clamp(APOS-Z14,-0.15,0.15),-16,-10))))
                        }
                        
                        LA142=JO:toLocal(holoEntity(142):angles())
                        Y142  = LA142:yaw()
                        if(abs(AANG-Y142)<=0.1){
                            AANG = randint(-90,90)
                            ASP=random(0.8,1.3)
                            AFW=randint(0,1)
                            AFW = AFW == 0 ? -1 : 1
                            DPOS=randvec(BPos+vec(-1,-1,-3),BPos+vec(1,1,3))
                            
                            AAR = AS["arm",array]
                            ARM:soundPlay(2,1,AAR[randint(1,AAR:count()),string])
                            soundPitch(2,140)
                            soundVolume(2,0.1)
                            
                            LAR = AS["laser",array]
                            LAS:soundPlay(3,1,LAR[randint(1,LAR:count()),string])
                            soundPitch(3,140)
                            soundVolume(3,0.05)
                        }else{
                            TAFW = clamp(TAFW + clamp(AFW-TAFW,-(ASP/12),ASP/12),-1,1) 
                            holoAng(142,JO:toWorld(ang(cos(Y142)*70*TAFW,clamp(Y142+clamp(AANG-Y142,-ASP,ASP),-90,90),-sin(Y142)*90)))
                        }
                        DPOS2 = holoEntity(15):toWorld(vec(1.5,0,-5))
                        DPOS3 = DY:toWorld(DPOS)
                        if(!->HOLOEMITTER){
                            holoPos(152,(DPOS3+DPOS2)/2)
                            holoAng(152,(DPOS3-DPOS2):toAngle())
                            holoAng(152,holoEntity(152):toWorld(ang(0,0,65)))
                            holoScaleUnits(152,vec((DPOS3-DPOS2):length(),0.1,0.3))
                        }else{
                            HOLOEMITTER["Pos",vector]=DPOS3
                            HOLOEMITTER["Color",vector]=vec(255,0,0)
                        }
                    }else{
                        Stat=2
                        HOLOEMITTER["Active",number]=0
                        holoPos(152,holoEntity(15):toWorld(vec(1.5,0,-5)))
                        holoScale(152,vec())
                        LP14=DY:toLocal(JO:pos())
                        Z14     = LP14:z()
                        P14     = clamp(Z14+clamp(-7-Z14,-0.15,0.15),-16,-7)
                        holoPos(14,DY:toWorld(vec(-5.3,0,P14)))
                        
                        LA142   = holoEntity(142):angles()
                        DLA124  = DY:toWorld(ang(0,0,0)) - LA142
                        AN      = LA142 + ang(clamp(DLA124:pitch(),-1,1),clamp(DLA124:yaw(),-4,4),clamp(DLA124:roll(),-1,1))
                        holoAng(142,AN)  
                        
                        if(BPR>=1 & (P14+7) == 0 & AN == DY:toWorld(ang(0,0,0)) & !READY){
                            B:soundPlay(1,1,AS["boat",table]["built",string],0.8)
                            soundVolume(1,0.5)
                            
                            BUILDING = 0
                            READY=1
                        }
                    }
                }elseif(B:isValid()&!BUILDING&READY&M1){
                    B:propFreeze(0)
                    B:propNotSolid(0)
                    READY=0
                    Stat=0
                }
            }else{
                if(!DEATHCAM){
                    InWater = B:isUnderWater()
                    
                    BV = B:velL()
                    BVA = B:angVel()
                    MBV=-(B:toWorld(BV*vec(0.1,4,14)*InWater)-B:pos())*B:inertia():length()*3
                    MBV = MBV + vec(((W+Shift)*4-S) + (abs(B:toLocal(MBV+B:pos()):y()) * sign(BV:x()) *0.01),0,0):rotate(B:toWorld(ang(45,0,0)))*InWater*(1-0.6*Alt)*B:inertia():length()*150*(1+Shift)
                    B:applyForce(MBV)       
                    BVX= BV:x()
                    EAN=B:toWorld(ang(clamp((BVX/60)^2 * sign(BVX),0,1)*30,clamp((BVX/10)^2 * sign(BVX)  *(A-D),-1,1)*-40,0))
                    TORQ = (vec(-EAN:roll(),-EAN:pitch(),(3.6*(A-D)*sign(1+W-S*2)))*150)
                    B:applyTorque((TORQ + $TORQ*5 - B:angVelVector()*5)*B:inertia()*InWater)
    
                    holoAng(102,holoEntity(102):toWorld(ang(0,(BV:x()/3)*5+((W-S)*3),0)))
                    soundPitch(10,60 + clamp(abs(BV:x())/6,0,40))
                    soundVolume(10,0.05 + clamp(abs(BV:x())/100,0,0.1))
                    soundPitch(11,120 + clamp(abs(BV:x())/6,0,40))
                    soundVolume(11,0.4 + clamp(abs(BV:x())/120,0,0.2))
                    
                    rangerFilter(B)
                    VAN2 = (VAN + ang(6,B:angles():yaw(),0))*ang(-1,1,0)
                    if(!Z){
                        CRD = rangerOffsetHull(10,B:pos()+vec(0,0,5),vec(1,0,0):rotate(VAN2),vec(3,3,3))
                    }else{
                        CRD = rangerOffsetHull(2,holoEntity(104):toWorld(vec(0.1,0,-0.5)),vec(1,0,0):rotate(VAN2),vec(3,3,3))
                    }
                    rangerHitWater(1)
                    RD=rangerOffset(100000,CRD:pos(),vec(-1,0,0):rotate(VAN2))
                    BCP     = BC:pos()
                    BCA     = BC:angles()
                    RDP   = RD:pos()
                    BEA=bearing(BCP,BCA,RDP)
                    ELE=elevation(BCP,BCA,RDP)
    
                    TANG = -ang(ELE,BEA,0)
                    RANG = BC:toWorld(ang(-90,0,0)+TANG)
                    holoPos(104,BC:toWorld(vec(0.6,0,0.3):rotate(TANG)))
                    holoAng(104,RANG)
                    
                }else{
                    VAN2 = (ang(sin(VAN:pitch())*4,sin(VAN:yaw())*4+DCA+sin(curtime()*6)*60,0)*(1-clamp((DCT-curtime())/10,0,1)^2))*ang(-1,1,0)
                    CRD = rangerOffsetHull(45,DCP+vec(0,0,10),vec(1,0,0):rotate(VAN2),vec(3,3,3))
                    if(DCT<curtime()){
                        if(M1|M2|Space){DEATHCAM=0,Stat=0}else{Stat=3}
                        }
                }
                
                if(BVOA == 1){
                    if(M2&$M2){
                        FLIR=!FLIR
                        CAM["FLIR",number]=FLIR
                    }
                    if(M1 & $M1 & PJ:count()<6 & LS < curtime()){
                        if(SHT!=0 & PJ:count() == 0 & OPJ:count() == 0){SHT =0}
                        ID = 310+SHT
                        PX = holoCreate(ID,BCP,vec())
                        LS = curtime() + 0.25
                        holoAlpha(ID,0)
                        PX["DIR",vector] = (vec(250,0,0)):rotate((RDP-BCP):toAngle())
                        PX["CT",number]=curtime()+4
                        PX["ROT",number]=random(0,360)
                        PX:setTrails(0.7,0,1,"trails/laser",vec(255,255,255),200)
                        PJ[PJ:count()+1,number] = ID
                        PX["POS",vector]=BCP
                        SHT++
    
                        BC:soundPlay(7,1,AS["boat",table]["fire",string],0.1)
                        soundVolume(7,0.25)
                        soundPitch(7,130)
                        
                        PX:soundPlay(20+ID,0,"/npc/combine_gunship/dropship_engine_near_loop1.wav")
                        soundPitch(20+ID,160)
                        soundVolume(20+ID,0.04)
                    }
                }
                
                CAM["Position",vector] = CRD:pos()
                CAM["Angle",angle] = (VAN2+ang(0,180,0))*ang(-1,1,0)
            }
        }
        
        if(holoEntity(OPJ[1,number])["Death",number] < curtime()){
            holoDelete(OPJ[1,number])
            OPJ:shift()
        }
        
        PJT = systime()
        for(I=1,PJ:count()){
            PJC = PJ[I,number]
            PJE= holoEntity(PJC)
            
            TI = PJE["CT",number]
            DIS = PJE["DI",number]
            POS = PJE["POS",vector]
            
            DIR = PJE["DIR",vector]
            DT = $PJT
            NPOS = POS + DIR*DT
            PJE["POS",vector] = NPOS
            
            ST = (systime()+PX["ROT",number])*4000
            holoPos(PJC , NPOS + vec(0,sin(ST)*0.3,cos(ST)*0.3):rotate(DIR:toAngle()))
            rangerFilter(B)
            rangerHitWater(1)
            RD = rangerOffsetHull(NPOS, NPOS + DIR*DT, vec(3,3,0.5))
            RDE = RD:entity()
            if(RD:hit() | TI < curtime()){
                RDP = RD:pos()
                OPJ[OPJ:count()+1,number]=PJC
                PJE["Death",number] = curtime() + 2
                PJ:remove(I)
                holoPos(PJC , RDP)
                soundStop(20+PJC)
                if(RD:matType() == "slosh"){
                    PJE:soundPlay(20+PJC,1,"/ambient/water/water_splash1.wav")
                    soundVolume(20+PJC , 0.06)
                }elseif(BT["Boat_"+RDE:id(),entity] == RDE){
                    HAR=AS["hitsound",array]
                    BC:soundPlay(20+PJC,1,HAR[randint(1,HAR:count()),string])
                    soundVolume(20+PJC , 0.08)
                    dsSend("HitBoat_"+RDE:id(),"SpeedBoatAttack",DR)
                    HITS[HITS:count()+1,vector4]=vec4(RDP:x(),RDP:y(),RDP:z(),curtime()+0.7)
                    STAT=PLST[DR:steamID()+"_",vector]
                    PLST[DR:steamID()+"_",vector]=vec(STAT:x()+1,STAT:y(),STAT:z())
                    if(HITS:count()>5){
                        HITS:shift()
                    }
                }elseif(RD:hit()){
                    PJE:soundPlay(20+PJC,1,"/ambient/machines/catapult_throw.wav",0.1)
                    soundVolume(20+PJC , 0.04)
                }else{
                    PJE:soundPlay(20+PJC,1,"/npc/scanner/cbot_servochatter.wav",0.5)
                    soundVolume(20+PJC , 0.06)
                    soundPitch(20+PJC,80)
                }
            }
        }
        
        if(EGP_TIME < curtime()){
            EGP_TIME = curtime() + (1/egpMaxUmsgPerSecond())*2
            EGP:egpText(5,floor(BT["Boat_"+B:id()+"_Hits",number]/BT["L",number]*100)+"%",vec2())
            
            if(Stat == 0){
                EGP:egpAlpha(6,0)
                EGP:egpAlpha(7,0)
            }else{
                EGP:egpColor(6,vec4(0,165,255,200))
                EGP:egpAlpha(7,200)
                EGP:egpSetText(7,STATUS[Stat,string])
            }
            rangerFilter(B)
            RD = rangerOffset(B:pos() + vec(0,0,4), DY:toWorld(vec(-15,0,-18)))
            ALP = 0.1 + 0.9*(1-clamp(RD:distance()/300,0,1))*!RD:hit()
            EGP:egpColor(9,vec4(0,165,255,180*ALP))
            EGP:egpColor(10,vec4(255,255,255,120*ALP))

            EGP:egpPos(8,DY:toWorld(vec(-10,0,-18)))
            
            if(B:isValid()&!BUILDING&!READY){
                EGP:egpAlpha(1,120)
                EGP:egpAlpha(3,200)
                EGP:egpAlpha(4,200)
                EGP:egpAlpha(5,200)
                if(LS < curtime()){
                    EGP:egpColor(2,vec4(255,0,0,200))
                }else{
                    EGP:egpColor(2,vec4(255,255,255,100))
                }
            }else{
                EGP:egpAlpha(1,0)
                EGP:egpAlpha(2,0)
                EGP:egpAlpha(3,0)
                EGP:egpAlpha(4,0)
                EGP:egpAlpha(5,0)
            }
            for(I=1,5){
                V4  = HITS[I,vector4]
                POS = vec(V4:x(),V4:y(),V4:z())
                LT  = 1-clamp((curtime()-V4:w())/0.7,0,1)
                
                EGP:egp3DTracker(9+I*2,POS)
                EGP:egpAlpha(10+I*2,200*LT)
            }
        }
    }
    
    if(dsClk()){
        if(dsClkName() == "HitBoat_"+B:id()){
            L = BT["L",number]
            LHIT = BT["Boat_"+B:id()+"_Hits",number]
            NHIT = LHIT + 1
            BT["Boat_"+B:id()+"_Hits",number] = NHIT
            ATKR=dsGetEntity()
            if(NHIT>=L){
                STAT=PLST[ATKR:steamID()+"_",vector]
                PLST[ATKR:steamID()+"_",vector]=vec(STAT:x(),STAT:y()+1,STAT:z())
                STAT=PLST[DR:steamID()+"_",vector]
                PLST[DR:steamID()+"_",vector]=vec(STAT:x(),STAT:y(),STAT:z()+1)
                boatBreak()
            }
        }
    }
    
    if(!DY:isFrozen()){
        DY:propFreeze(1)
        DY:setPos(DYPos)
        DY:setAng(DYAng)
    }
    
    if(last()){
        if(HE:isValid()){
            HE:deparent()
            HE:propFreeze(1)
            HE:propNotSolid(0)
            HE:setAlpha(255)
            HE:setPos(E:pos()+vec(0,0,20))
        }
        B:propDelete()
        BT:removeEntity("Boat_"+B:id())
        BT:removeNumber("Boat_"+B:id()+"_Hits")
        if(O["IsBuilding",number] == 1 & !DY:isValid()){
            O["IsBuilding",number] = 0
        }
        DY:propDelete()
        holoDeleteAll()
        soundPurge()
    }
    
    if(chatClk(DR)){
        if(DR:lastSaid():lower()=="stats"){
            PLS=PLST:toTable()
            SR = array(vec(200,255,255),"Name, ",vec(255,120,30)," Frags, ",vec(70,100,170)," Deaths, ",vec(0,200,200)," Hits")
            SEAT:printColorDriver(SR)
            foreach(K,V:vector = PLS){
                if( PLN[K+"NAME",string] != "" ){
                    SR = array(vec(200,255,255),PLN[K+"NAME",string]+", ",vec(255,120,30)," "+V:y()+", ",vec(70,100,170)," "+V:z()+", ",vec(0,200,200)," "+V:x()+", ")
                    SEAT:printColorDriver(SR)
                }
            }
        }elseif(DR:lastSaid():lower()=="help"){
            AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"Use W and S to switch between the cameras.")
            SEAT:printColorDriver(AR)
            AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"Right Mouse Button to build a boat.")
            SEAT:printColorDriver(AR)
            AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"Left Mouse Button to drive it.")
            SEAT:printColorDriver(AR)
            AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"W A S D to move, shift turbo, alt slower, left click fire, right click FLIR and zoomkey to aim.")
            SEAT:printColorDriver(AR)
            AR=array(vec(0,165,255),"Info: ",vec(255,255,255),"Say \"stats\" to get all players statistics.")
            SEAT:printColorDriver(AR)
        }
    }
    if(chatClk(O) & O != DR){
        if(O:lastSaid():lower()=="move" & (O:aimEntity()==E | O:aimEntity()== DY | O:aimEntity()== B)){
            E["DYPos",vector]   = vec()
            E["DYAng",angle]    = ang()
            hideChat(1)
            reset()
        }
    }
}
#####
#UKE#
#####