# Usage:
# 1. Put this expression chip on any object.
# 2. Weld a vehicle (chair) to the very same object
# 3. Create an Adv.Pod_Controller and link it to the chair
# 4. Wire expression chip with pod controller
# 5. Unfreeze the object and fly away.
# --------------------------------------------------
# Usualy I wire Forward, Left, Back and Right to the WASD keys
# and Shift, Space and Active accordingly.
# The contraption can be controlled just like any other vehicle:
# WASD - Directions, Space - going up, Shift - SpeedMod
# NOTE: this contraption can be used not only by the owner.
# NOTE2: this contraption can understand more than one input at a
# time, that means you can go forward and to the side at
# the same time.
# NOTE3: Works best when contraption is transparent, or semi transparent.

@name Flying_expression_with_horribly_long_name
@inputs Forward Back Left Right Shift Space Active
@persist Pos:vector Drag Doing Veh:entity Driver:entity

runOnTick(1)
E = entity():isWeldedTo()
E:propNotSolid(0)
Drag = E:isPlayerHolding()
Speed = 200 + (600 * Shift)
Doing = Forward + Back + Left + Right + Space
Fwd = Bck = Rgt = Lft = Spc = vec(0,0,0)
if(first()){
    Pos = E:pos()
    Idx = 0
    while(Idx <= E:hasConstraints("Weld")){
        if(E:isConstrainedTo("Weld", Idx):isVehicle()){
            Veh = E:isConstrainedTo("Weld", Idx)
            break
        }
        Idx += 1
    }
    Driver = owner()
}
if(E:mass() != 50000){E:setMass(50000)}
if(changed(Active) & Active){
    if(Veh:isVehicle()) { Driver = Veh:driver() }
    Veh:hintDriver("Hello " + Driver:name() + ". Thank you for using 3dfactor contraption.", 7)
    Veh:hintDriver("You can contact him via 3dfactor@gmail.com or just by visiting www.wiremod.com.", 7)
}
if(changed(Drag) & !Drag | changed(Doing) & !Doing){
    Pos = E:pos()
}
if(Forward){
    Fwd = Driver:eye()
}
if(Back){
    Bck = -Driver:eye()
}
if(Right){
    Rgt = (Driver:eye()*vec(1,1,0)):cross(E:up())
}
if(Left){
    Lft = (-Driver:eye()*vec(1,1,0)):cross(E:up())
}
if(Space){
    Spc = vec(0,0,1)
}
if(Doing){
    Pos = ((Fwd + Bck) + (Lft + Rgt) + Spc)* Speed + E:pos()
}
if(!E:isFrozen() & !Drag){
    E:applyForce((Pos - E:pos() - E:vel())*(E:mass() + 9.15))
    E:applyAngForce((ang(0,0,0) - E:angles() - E:angVel()) * E:mass())
}  
