@name Generic Test E2 #1
@inputs 
@outputs 
@outputs Boats:table Props:array 

runOnLast(1)
runOnTick(1)

if(first()) {
    function createBoat(Seat:entity) {
        local Table = table()
        
        local B = holoCreate(1,Seat:toWorld(vec(0,0,0)),vec(1),Seat:toWorld(ang()))
        holoModel(1,"models/editor/axis_helper_thick.mdl")
        holoAlpha(1,0)
        holoMaterial(1,"models/effects/vol_light001")
        holoParent(1,Seat)
        
        local Prop = noentity()
        local Hull = table()
        
        Prop = propSpawn("models/props_combine/breenpod_inner.mdl",Seat:toWorld(vec(-0,55,-14)),Seat:toWorld(ang(90,90,180)),1)
        Prop:setMass(200)
        Props:pushEntity(Prop)
        Hull["front",entity] = Prop

        Prop = propSpawn("models/props_combine/breenpod_inner.mdl",Seat:toWorld(vec(-0,-55,-14)),Seat:toWorld(ang(90,90,0)),1)
        Prop:setMass(100)
        Props:pushEntity(Prop)
        Hull["back",entity] = Prop
        
        Prop = propSpawn("models/props_c17/tv_monitor01.mdl",Seat:toWorld(vec(0,-20,6.5)),Seat:toWorld(ang(-90,-90,180)),1)
        Prop:setMass(100)
        Props:pushEntity(Prop)
        Hull["bridge",entity] = Prop
        
        # Hull
        noCollide(Hull["front",entity],Hull["back",entity])
        weld(Hull["front",entity],Hull["back",entity])
        weld(Hull["front",entity],Seat)
        weld(Hull["back",entity],Seat)
        
        # Bridge (TV)
        noCollide(Hull["bridge",entity],Hull["front",entity])
        noCollide(Hull["bridge",entity],Hull["back",entity])
        noCollide(Hull["bridge",entity],Seat)
        weld(Hull["bridge",entity],Seat)
        weld(Hull["bridge",entity],Hull["front",entity])
        weld(Hull["bridge",entity],Hull["back",entity])
        

        Table["b",entity] = B
        Table["seat",entity] = Seat
        Table["props",table] = Hull:clone()

        if(map() == "gm_construct" | map():sub(1,12) == "rp_construct") {
            Table["water_height",number] = -156
        }
        
        Boats:pushTable(Table)
    }
    
    function entity:stabilize(Ang:angle){
        TarQ = quat(Ang)
        CurQ = quat(This)
        Q = TarQ/CurQ
        V = This:toLocal(rotationVector(Q)+This:pos())
        This:applyTorque(((V*20 - This:angVelVector())*50*This:inertia())*vec(2,1,1))
    }
    
    function entity:float(I) {
        local T = Boats[I,table]
        local Seat = T["seat",entity]
        rangerHitWater(1)
        rangerHitEntities(0)
        local B = T["b",entity]
        local R = rangerOffset(B:pos()+(-B:up()*6),B:pos()+(-B:up()*8))

        if(Seat:pos():z() < T["water_height",number]+12 & R:hit()) {
            local Forward = T["movement_forward",number]
            local Back = T["movement_back",number]
            local Left = T["movement_left",number]
            local Right = T["movement_right",number]
            
            local SpeedMod = clamp(abs(This:velL():y())/100,0.1,1)
            
            local MoveOffset=
                (T["movement_forward",number] ? Seat:forward()*1 : vec()) + 
                (T["movement_back",number] ? Seat:forward()*-1 : vec())
                
            local BaseVel=This:vel()
            local Center=This:pos()
            local DampingAxes=vec(0.05,0.01,1)
            
            local DampingOffset=
                This:toWorld(This:toLocal(Center+BaseVel)*DampingAxes)-Center
            
            local Pos = (Seat:pos()):setZ(T["water_height",number]+10)
            Vec = (Pos - This:pos())-This:vel()*vec(0,0,1)
            This:applyForce((Vec+MoveOffset-DampingOffset)*(This:mass()+500))
            
            #-vec(Seat:vel():x()*0.05,Seat:vel():y()*0.01,Seat:vel():z()*0)
            This:applyAngForce(ang(0,(Left * -2) + (Right * 2),0)*SpeedMod*(This:mass()+500))
        }
    }
}


if(owner():keyReload() & owner():aimEntity():model() == "models/nova/airboat_seat.mdl") {
    local I = 0
    local Found = 0
    if(Boats:count() > 0) {
        for(I=1,Boats:count()) {
            if(Boats[I,table]["seat",entity] == owner():aimEntity()) {
                Found = 1
                break
            }
        }
        
        if(Found == 0) {
            createBoat(owner():aimEntity())
        }
    } else {
        createBoat(owner():aimEntity())
    }
}

if(tickClk()) {
    if(Boats:count() > 0) {
        local I = 0
        for(I=1,Boats:count()) {
            local T = Boats[I,table]
            local B = T["b",entity]
            local Seat = T["seat",entity]
            local Ply = Seat:driver()
            
            T["movement_forward",number] = Ply:keyForward()
            T["movement_back",number] = Ply:keyBack()
            T["movement_right",number] = Ply:keyLeft()
            T["movement_left",number] = Ply:keyRight()
            
            Seat:float(I)
            Seat:stabilize(ang(0,Seat:angles():yaw(),0))
        }
    }
}

if(last()) {
    if(Boats:count() > 0) {
        local I = 0
        for(I=1,Boats:count()) {
            Boats[I,table]["seat",entity]:propFreeze(1)
        }
    }
    holoDeleteAll()
    soundPurge()
    Props:propDelete()
}
