@name hologaphic_object_launcher
@inputs Cam:wirelink Pod:wirelink

#Entities
@persist [Torso,Head,Left_Leg,Right_Leg,Left_Arm,Right_Arm]:entity
#Sizes
@persist [Size_Torso,Size_Head]:vector
@persist [Size_Left_Arm,Size_Right_Arm]:vector
@persist [Size_Left_Leg,Size_Right_Leg]:vector
@persist [Size,Scale]:vector
#Positions
@persist [Pos_Torso,Pos_Head]:vector
@persist [Pos_Left_Arm,Pos_Right_Arm]:vector
@persist [Pos_Left_Leg,Pos_Right_Leg]:vector
#Animation
@persist Animation:string
@persist Animation_Walk_Legs
@persist Animation_Walk_Arms
@persist Animation_Walk_Speed
@persist Animation_Walk_Angle
@persist Animation_Head_Entity:entity
@persist Animation_Head_Target:vector
@persist Animation_Head_Direction:vector

@persist Animation_POV
@persist Animation_FOV
#Offsets
@persist [Offset_A_Left_Leg,Offset_A_Right_Leg]:angle
@persist [Offset_A_Left_Arm,Offset_A_Right_Arm]:angle
@persist [Offset_A_Torso]:angle

@persist [Offset_P_Left_Leg,Offset_P_Right_Leg]:vector
@persist [Offset_P_Left_Arm,Offset_P_Right_Arm]:vector
#Physics
@persist Physics_Walk_Speed #Walk Speed (No Shift)
@persist Physics_Run_Speed #Run Speed (Shift)
@persist Physics_Jump_Power #(TODO)Jump Power
@persist Physics_Gravity #Gravity (9.8)
@persist Physics_Torso_Height #Ranger Down
@persist Physics_Torso_Width #Ranger Forward
@persist Physics_Fall_Time #Amount of time in air
@persist Physics_Airborn #Is player in air?
@persist Physics_Jumping #Player jumping
@persist Physics_Move:vector #Amount moved in this frame
@persist Object:entity
@persist Rescale

@persist W S A D Shift Space Reload Fire

############################
#Animated Karacter by Ronny#
############################

###########CONTROLS##########
# W - Forward               #
# S - Backward              #
# A - Left                  #
# D - Right                 #
# Reload - Change Views     #
# Shift - Run               #
# Mouse1 - Pickup and Throw #
#############################

#######DIRECTIONS########
# Pick up objects and   #
# Throw them around.    #
#########################

interval(10)
runOnChat(1)

W = Pod["W",number]
S = Pod["S",number]
A = Pod["A",number]
D = Pod["D",number]
Shift = Pod["Shift",number]
Space = Pod["Space",number]
Reload = Pod["R",number]
Fire = Pod["Mouse1",number]&!Pod["R",number]
ZoomIn = Pod["R",number]&Pod["Mouse2",number]
ZoomOut = Pod["R",number]&Pod["Mouse2",number]

Cam["Activated",number] = Pod["Active",number]

User = Pod["Entity",entity]:driver()

Seat = Pod["Entity",entity]


#animated karacter
if(first()|dupefinished()){Scale = vec(1,1,1)}
if(first()|dupefinished()|Rescale)
{
    holoCreate(1,vec(),vec(),ang())#Torso
    holoCreate(2,vec(),vec(),ang())#Head
    holoCreate(3,vec(),vec(),ang())#Left Leg
    holoCreate(4,vec(),vec(),ang())#Right Leg
    holoCreate(5,vec(),vec(),ang())#Left Arm
    holoCreate(6,vec(),vec(),ang())#Right Arm
    
    Torso = holoEntity(1)
    Head = holoEntity(2)
    Left_Leg = holoEntity(3)
    Right_Leg = holoEntity(4)
    Left_Arm = holoEntity(5)
    Right_Arm = holoEntity(6)
    
    Color_Torso = vec4(10,180,20,255) #Green
    Color_Head = vec4(220,180,30,255) #Peach
    Color_Left_Leg = vec4(30,80,150,255) #Dark Blue
    Color_Right_Leg = vec4(30,80,150,255) #Dark Blue
    Color_Left_Arm = vec4(30,190,45,255) #Greener
    Color_Right_Arm = vec4(30,190,45,255) #Greener
    
    #Scale = vec(1,1,1)*0.5
    Holo_Scale = 12.5 #Currently
    
    #Sizes
    Size_Torso = vec(16,8,24)*Scale
    Size_Head = vec(12,12,12)*Scale
    Size_Left_Leg = vec(8,8,24)*Scale
    Size_Right_Leg = vec(8,8,24)*Scale
    Size_Left_Arm = vec(8,8,24)*Scale
    Size_Right_Arm = vec(8,8,24)*Scale
    Size = vec(
        Size_Left_Arm:x()+Size_Torso:x()+Size_Right_Arm:x(),
        Size_Torso:y(),
        Size_Head:z()+Size_Torso:z()+Size_Left_Leg:z()    
    )
    
    #Positions
    Pos_Torso = entity():pos()+vec(0,0,0)
    #Relative to body
    Pos_Head = vec(0,0,Size_Torso:z()/2+Size_Head:z()/2)
    #Legs
    Leg_Distance = Size_Left_Leg:x()/2
    Leg_Lower = Size_Torso:z()/2+Size_Left_Leg:z()/2
    Pos_Left_Leg = vec(-Leg_Distance,0,-Leg_Lower)
    Pos_Right_Leg = vec(Leg_Distance,0,-Leg_Lower)
    #Arms
    Arm_Distance = (Size_Torso:x()/2+Size_Left_Leg:x()/2)
    Pos_Left_Arm = vec(-Arm_Distance,0,0)
    Pos_Right_Arm = vec(Arm_Distance,0,0)
    
    holoPos(1,Pos_Torso)
    holoScale(1,Size_Torso/Holo_Scale)
    holoColor(1,Color_Torso)
    
    holoPos(2,Pos_Torso+Pos_Head)
    holoScale(2,Size_Head/Holo_Scale)
    holoColor(2,Color_Head)
    holoParent(2,1)
    
    holoPos(3,Pos_Torso+Pos_Left_Leg)
    holoScale(3,Size_Left_Leg/Holo_Scale)
    holoColor(3,Color_Left_Leg)
    holoParent(3,1)
    
    holoPos(4,Pos_Torso+Pos_Right_Leg)
    holoScale(4,Size_Right_Leg/Holo_Scale)
    holoColor(4,Color_Right_Leg)
    holoParent(4,1)
    
    holoPos(5,Pos_Torso+Pos_Left_Arm)
    holoScale(5,Size_Left_Arm/Holo_Scale)
    holoColor(5,Color_Left_Arm)
    holoParent(5,1)
    
    holoPos(6,Pos_Torso+Pos_Right_Arm)
    holoScale(6,Size_Right_Arm/Holo_Scale)
    holoColor(6,Color_Right_Arm)
    holoParent(6,1)
    
    #holoCreate(7)
    
    Animation = "idle"
    Animation_FOV = 60
    
    Physics_Walk_Speed = 2.5*Scale:y()
    Physics_Run_Speed = 5*Scale:y()*5
    Physics_Jump_Power = 3*Scale:z()
    Physics_Torso_Height = Size_Torso:z()/2+Size_Left_Leg:z()
    Physics_Torso_Width = Size_Torso:y()
    Physics_Gravity = 9.8*Scale:z()
    
    Player_Health = 100
    
    Weapon = 1
    Weapon_Model = "models/weapons/w_pist_deagle.mdl"
    Weapon_Pos = Pos_Torso+Pos_Right_Arm+Size_Right_Arm*vec(0,0,0.5)
    Weapon_Damage = 10
    Weapon_Reload = 0
    Weapon_Reload_Time = 3 #In seconds
    Weapon_Recoil = 20 #In degrees
    
    Rescale = 0
}









if(chatClk(owner()))
{
    Args = lastSaid():explode(" ")
    Command = Args[1,string]:lower()
    if(Command=="/scale"){Scale = vec(1,1,1)*Args[2,string]:toNumber(),Rescale = 1}
}






####PHYSICS####

Ranger = rangerOffset(Physics_Torso_Height,Torso:pos(),vec(0,0,-1))
if(Physics_Gravity > 0&!Ranger:hit())
{
    if(Physics_Fall_Time == 0){Physics_Fall_Time = curtime()}
    Time = curtime()-Physics_Fall_Time
    Fall = (Physics_Gravity*(Time*Time))-Physics_Gravity*((Time-0.4)*(Time-0.4))
    Physics_Move = Physics_Move-vec(0,0,Fall)
    Physics_Airborn = 1
}
else
{
    Physics_Airborn = 0
    Physics_Fall_Time = 0
    Physics_Jumping = 0
}
if(Ranger:hit()&Ranger:distance()<Physics_Torso_Height-2)
{
    Physics_Move = Physics_Move+vec(0,0,Physics_Torso_Height-Ranger:distance()-1)
}



if((W|S)&(!A&!D))
{
    Ranger = rangerOffset(Physics_Torso_Width,Torso:pos(),Torso:right()*(W-S))
    if(!Ranger:hit())
    {
        Speed = (Shift==1?Physics_Run_Speed : Physics_Walk_Speed)
        Physics_Move = Physics_Move+(Torso:right()*Speed)*(W-S)
        if(Shift){Animation = "run"}else{Animation = "walk"}
        if(Object){Animation="fall"}
    }
}


if(A|D)
{
    Offset_A_Torso = ang(0,90*(A-D)-(W-S)*45*(A-D),0)
    Ranger = rangerOffset(Physics_Torso_Width,Torso:pos(),Torso:right()*(A-D))
    if(!Ranger:hit())
    {
        Speed = (Shift==1?Physics_Run_Speed : Physics_Walk_Speed)
        Physics_Move = Physics_Move+(Torso:right()*Speed)
        if(Shift){Animation = "run"}else{Animation = "walk"}
        if(Object){Animation = "fall"}
    }else{Offset_A_Torso = ang()}
}else{Offset_A_Torso = ang()}
if(Physics_Jumping)
{
    Physics_Move = Physics_Move+vec(0,0,Physics_Jump_Power)
}
if(Space&!Physics_Jumping)
{
    Physics_Jumping = 1
    Physics_Move = Physics_Move+vec(0,0,Physics_Jump_Power)
}


if(Physics_Move!=vec())
{
    holoPos(1,Torso:pos()+Physics_Move)
    if(Physics_Move:z()<0){Animation = "idle_fall"}
    Physics_Move = vec()
}
else
{
    if(!Object){Animation = "idle"}
    if(Object){Animation = "idle_fall"}
}

if(Fire&$Fire)
{
    if(!Object){
        Ranger = rangerOffset(50*Scale:y(),Head:pos(),User:eye())
        if(Ranger:entity()){Object = Ranger:entity(),Object:setMass(50000)}
    }
    elseif(Object){
        Object:propFreeze(0)
        Object:applyForce(User:eye()*50000*Object:mass())
        Object = noentity()
    }
}

if(Object)
{
    Object:setAng(Torso:angles())
    Top = Torso:pos()+Size_Torso*vec(0,0,0.5)+Size_Right_Arm*vec(0,0,1)
    Off = Object:pos()-Object:massCenter()
    Half = (Object:boxMax()/2)*vec(0,0,1)
    #holoPos(7,Top)
    Object:setPos(Top+Off+Half)
    Object:propFreeze(1)
}


#####ANIMATION#####



Angle = ang(0,0,cos(curtime()*Animation_Walk_Speed)*Animation_Walk_Angle)
Adjustment = vec(0,0,Size_Left_Leg:z()/2):rotate(Angle):setZ(0)

if(Animation_Walk_Legs){
    Offset_A_Left_Leg = Angle
    Offset_P_Left_Leg = Pos_Left_Leg-Adjustment
    
    Offset_A_Right_Leg = -Angle
    Offset_P_Right_Leg = Pos_Right_Leg+Adjustment
}
if(Animation_Walk_Arms){
    Offset_A_Left_Arm = -Angle
    Offset_P_Left_Arm = Pos_Left_Arm+Adjustment
    
    Offset_A_Right_Arm = Angle
    Offset_P_Right_Arm = Pos_Right_Arm-Adjustment
}


#A change in animation!
if(changed(Animation))
{
    Animation = Animation:lower()
    #print("Animation set to "+Animation)
    if(Animation=="idle")
    {
        Animation_Walk_Legs = 0
        Animation_Walk_Arms = 0
        Offset_A_Left_Leg = ang()
        Offset_A_Right_Leg = ang()
        Offset_A_Left_Arm = ang()
        Offset_A_Right_Arm = ang()
        
        Offset_P_Left_Leg = Pos_Left_Leg
        Offset_P_Right_Leg = Pos_Right_Leg
        Offset_P_Left_Arm = Pos_Left_Arm
        Offset_P_Right_Arm = Pos_Right_Arm
    }
    if(Animation=="walk")
    {
        Animation_Walk_Legs = 1
        Animation_Walk_Arms = 1
        Animation_Walk_Speed = 500
        Animation_Walk_Angle = 30
    }
    if(Animation=="run")
    {
        Animation_Walk_Legs = 1
        Animation_Walk_Arms = 1
        Animation_Walk_Speed = 1000
        Animation_Walk_Angle = 50
    }
    if(Animation=="idle_fall")
    {
        Animation_Walk_Legs = 0
        Animation_Walk_Arms = 0
        Offset_A_Left_Leg = ang()
        Offset_A_Right_Leg = ang()
        Offset_A_Left_Arm = ang()
        Offset_A_Right_Arm = ang()
        
        Offset_P_Left_Leg = Pos_Left_Leg
        Offset_P_Right_Leg = Pos_Right_Leg
        Offset_P_Left_Arm = Pos_Left_Arm+Size_Left_Arm*vec(0,0,1)
        Offset_P_Right_Arm = Pos_Right_Arm+Size_Right_Arm*vec(0,0,1)
    }
    if(Animation=="fall")
    {
        Animation_Walk_Legs = 1
        Animation_Walk_Arms = 0
        Offset_A_Left_Leg = ang()
        Offset_A_Right_Leg = ang()
        Offset_A_Left_Arm = ang()
        Offset_A_Right_Arm = ang()
        
        Offset_P_Left_Leg = Pos_Left_Leg
        Offset_P_Right_Leg = Pos_Right_Leg
        Offset_P_Left_Arm = Pos_Left_Arm+Size_Left_Arm*vec(0,0,1)
        Offset_P_Right_Arm = Pos_Right_Arm+Size_Right_Arm*vec(0,0,1)
    }
}


if(chatClk(owner()))
{
    Args = lastSaid():explode(" ")
    Cmd = Args[1,string]:lower()
    Arg1 = Args[2,string]
    Arg2 = Args[3,string]
    Arg3 = Args[4,string]
    if(Cmd=="/anim"){
        Animation = Arg1
    }
}

holoAng(1,ang(0,User:eye():toAngle():yaw()+90,0)+Offset_A_Torso)

#Calculate all the positions
holoUnparent(2)
holoUnparent(3)
holoUnparent(4)
holoUnparent(5)
holoUnparent(6)

holoPos(3,Torso:pos()+Offset_P_Left_Leg:rotate(Torso:angles()))
holoPos(4,Torso:pos()+Offset_P_Right_Leg:rotate(Torso:angles()))
holoPos(5,Torso:pos()+Offset_P_Left_Arm:rotate(Torso:angles()))
holoPos(6,Torso:pos()+Offset_P_Right_Arm:rotate(Torso:angles()))

holoAng(2,User:eye():toAngle())
holoAng(3,Offset_A_Left_Leg+Torso:angles())
holoAng(4,Offset_A_Right_Leg+Torso:angles())
holoAng(5,Offset_A_Left_Arm+Torso:angles())
holoAng(6,Offset_A_Right_Arm+Torso:angles())

holoParent(2,1)
holoParent(3,1)
holoParent(4,1)
holoParent(5,1)
holoParent(6,1)


if(Reload&$Reload){Animation_POV = !Animation_POV}

if(!Animation_POV){
    Cam["Position",vector] = Head:pos()
    Cam["Direction",vector] = User:eye()
}else{
    CamPos = Head:pos()-Head:forward()*Animation_FOV*Scale:x()
    Direction = -CamPos+Head:pos()
    Cam["Position",vector] = CamPos
    Cam["Direction",vector] = Direction:normalized()
}
