@name Joy Clone
@inputs [RTCam JAna JHat JBut User Gun]:wirelink
#@inputs Mode:string Config:table FireCount Isolated
@outputs Rag:entity B:bone [LHand RHand LFoot RFoot]:vector
#@outputs LeftClick RightClick Reload Mode:string Freeze Isolate Config:table
@persist [Rag Stool]:entity Angle:angle X Y Z Position:vector
@persist [Bones Active Poz]:array [Tools Pose]:table
@persist Torso RightShoulder LeftShoulder LeftElbow
@persist RightHand RightHip RightKnee Head LeftHip LeftHand
@persist RightElbow LeftKnee LeftFoot RightFoot
#@model models/player/items/all_class/treasure_hat_oct.mdl
#@model models/player/items/all_class/oh_xmas_tree.mdl
#@model models/player/items/demo/crown.mdl

@trigger 
runOnTick(1)

if(JAna:entity()){
    Xaxis=JAna["1",number] #Left stick X
    Yaxis=JAna["2",number] #Left Stick Y
    Xaxis2=JAna["3",number] #Right Stick X
    Yaxis2=JAna["4",number] #Right Stick Y
    Zaxis=JAna["5",number] #Trigger analog (Left down, right up)
    Lstick=JAna["6",number] #Left Stick button
    Rstick=JAna["7",number] #Right stick button
    But9=JAna["8",number] #Center Ring left 
}
if(JHat:entity()){
    HatU=JHat["1",number] #Hat up
    HatD=JHat["2",number] #Hat Down
    HatL=JHat["3",number] #Hat Left
    HatR=JHat["4",number] #Hat Right
    HatC=JHat["5",number] #Hat Centered
    But9=JHat["6",number] #Center Ring Left
    But10=JHat["7",number] #Center Ring Right
    But13=JHat["8",number] #Center Ring Middle
}
if(JBut:entity()){
    But1=JBut["1",number] #Square / 1
    But2=JBut["2",number] #X / 2
    But3=JBut["3",number] #Circle / 3
    But4=JBut["4",number] #Triangle /4
    But5=JBut["5",number] #Left front button
    But6=JBut["6",number] #Right front button
    But7=JBut["7",number] #Left trigger
    But8=JBut["8",number] #Right trigger
}


if(first()){ #establish bone shortcuts for HL2 ragdolls
    Torso = 1
    RightShoulder = 2
    LeftShoulder = 3
    LeftElbow = 4
    LeftHand = 5
    RightElbow = 6            
    RightHand = 7
    RightHip = 8
    RightKnee = 9
    Head = 10
    LeftHip = 11
    LeftKnee = 12
    LeftFoot = 13
    RightFoot = 14
#    for(C=1,3){
#        holoCreate(C,entity():pos())
#    }
    #A sequence of recorded relative possitions based from the head as a fixed point
    Pose=table()
    #                            At Side      Forward       T-Pose
    Pose[RightHand,array]=array(vec(-30,4,1),vec(-22,-4,12),vec(-28,-11,2))
    Pose[LeftHand,array]=array(vec(-30,4,-2),vec(-22,-4,-12),vec(-29,-6,1))
    
    
    #                           Standing      Step forward  Step Back
    Pose[LeftFoot,array]=array(vec(-29,-53,-3),vec(-45,-38,4),vec(-26,-54,-5))
    Pose[RightFoot,array]=array(vec(-38,-47,2),vec(-42,-42,5),vec(-26,-54,1))

    
    Poz=array()
    Poz[1,vector]=vec()
    Poz[2,vector]=Pose[LeftHand,array][2,vector]
    Poz[3,vector]=Pose[RightHand,array][2,vector]
    Poz[3,vector]=Pose[LeftHand,array][1,vector]
    Poz[3,vector]=Pose[RightHand,array][1,vector]
    
    
    #Get tools for him to hold
    Tools=table()
    Tools[1,entity]=RTCam:entity():isConstrainedTo()
    Tools[3,entity]=User:entity()
    Tools[4,entity]=Gun:entity()
    
    Get=entity():getConstraints()
    for(C=1,Get:count()){
        if(Get[C,entity]:type()=="prop_ragdoll"){
            Rag=Get[C,entity]
        }
        if((Get[C,entity]:type()=="stool_turret")|(Get[C,entity]:model()=="models/weapons/w_physics.mdl")){
            Tools[2,entity]=Get[C,entity]:isConstrainedTo()
            Stool=Get[C,entity]
        }
    }
    
    #ragdoll bones
    Bones=array()
    Bones=Rag:bones()
        
    Active=array()
    Active:pushBone(Bones[Head,bone])
    Active:pushBone(Bones[LeftHand,bone])
    Active:pushBone(Bones[RightHand,bone])
    Active:pushBone(Bones[LeftFoot,bone])
    Active:pushBone(Bones[RightFoot,bone])

}

Rate=5 
Angle+=angnorm(ang(-Yaxis2*Rate,-Xaxis2*Rate,0))
SPEED=6
Run=SPEED*2
Sprint=Run*2
if(first()|duped()){
    Position=entity():pos()+vec(0,0,100) 
    X=Position:x()
    Y=Position:y()
    Z=Position:z()
    entity():setMass(4000)
}
if(But9){Activated=1}
if(But10){Activated=0}
RTCam["Activate",number]=Activated

#W=Yaxis>0
#S=Yaxis<0
#A=Xaxis<0
#D=Xaxis>0
#Space=But8
#Alt=But7
#R=But1
#Mouse1=But6
#Mouse2=But5
#Use=But1
#Shift=Lstick
#if(Activated){
#    SinY0=sin(Angle:yaw())
#    SinP90=sin(Angle:pitch()+90)
#    CosP90=cos(Angle:pitch()+90)
#    CosY0=cos(Angle:yaw())
#    if(W) {Y +=SinY0*SinP90*SPEED*((Shift*Run)+1)
#           X +=CosY0*SinP90*SPEED*((Shift*Run)+1)
#           Z +=CosP90*SPEED*((Shift*Run)+1)}
#    if(S) {Y -=SinY0*SPEED*SinP90*((Shift*Run)+1)
#           X -=CosY0*SPEED*SinP90*((Shift*Run)+1)
#           Z -=CosP90*SPEED*((Shift*Run)+1)}
#    if(A) {Y +=CosY0*SPEED*((Shift*Run)+1)
#           X -=SinY0*SPEED*((Shift*Run)+1)}
#    if(D) {Y -=CosY0*SPEED*((Shift*Run)+1)
#           X +=SinY0*SPEED*((Shift*Run)+1)}
#    if(Space) {Z +=1*(Shift*Sprint)+1}
#    if(Alt) {Z -=1*(Shift*Sprint)+1}
#    
#    if(R){
#        Position=entity():pos()+vec(0,0,100) 
#        X=Position:x()
#        Y=Position:y()
#        Z=Position:z()
#    }
#    if(vec(X,Y,Z):isInWorld()){Position=vec(X,Y,Z)}
#    #Direction = 
#
#}


#Hover ranger
FloatHeight=72+(50*Lstick)
rangerFilter(Rag)
RATE=10
Ground=rangerOffset(20000,Rag:pos(),vec(0,0,-1)):position():z()
Height=vec(Rag:pos():x()+Xaxis*RATE,Rag:pos():y()+Yaxis*RATE,Ground+FloatHeight)

#set height to 

Rate=2 
Angle+=angnorm(ang(0,-Xaxis2*Rate,-Yaxis2*Rate*0))

Relative=Bones[Head,bone]:pos()
LHand=Bones[LeftHand,bone]:toLocal(Relative)
RHand=Bones[RightHand,bone]:toLocal(Relative)
LFoot=Bones[LeftFoot,bone]:toLocal(Relative)
RFoot=Bones[RightFoot,bone]:toLocal(Relative)


XYZ=Height
#B=Bones[Head,bone]

if(first()){holoCreate(1,entity():pos())}
for(C=1,Active:count()){
    #B=Active[C,bone]
    B=Bones[Head,bone]
    if(C==1){XYZ=Height}
    #if(C==2){XYZ=Bones[Head,bone]:toWorld(Poz[2,vector])}
    #if(C==3){XYZ=Bones[Head,bone]:toWorld(Poz[3,vector])}
    #holoPos(C,XYZ)
    #
    Speed=(B:mass()/4)*100
    B:applyForce(Speed*(XYZ-B:pos())-B:vel()*B:mass())
    
    #rotate
    rangerFilter(entity():getConstraints())
    Aim=rangerOffset(2000,B:pos(),Angle:forward()):position()
    holoPos(1,Aim)
    Dir = B:pos()-(Aim)
    Q = quat(Dir:toAngle())*qRotation(vec(0,0,1),-90) #-Y
    B:applyTorque((150*B:toLocal(rotationVector(Q/quat(B:angles()))+B:pos())-12*B:angVelVector())*B:inertia())
}

#if(But9){Activated=1}
#if(But10){Activated=0}

#for(C=1,Tools:count()){ 
#    #This is move to vector code 
#    Speed=100*(Self:mass()/2)
#    Self=Tools[C,entity]
#    XYZ=Position+Loc[C,vector]
#    Dist=XYZ-Self:pos()
#    Vel=Dist/Time
#    Self:applyForce(Speed*Dist-Self:vel()*Self:mass())
#    
#    #This aims the arms
#    
#    #if(C==5){Grab=+Grabber["Grabbed Entity",entity]:vel()}else{Grab=vec()}
#    #Dir = G:pos()-(F:pos()+F:vel()/(!CanDo*10))
#    Dir = Self:pos()-(Aim)
#    #Q = quat(Dir:toAngle())*qRotation(vec(0,0,1),180) #X
#    #Q = quat(Dir:toAngle())*qRotation(vec(0,1,0),-90) #Z
#    #Q = quat(Dir:toAngle())*qRotation(vec(0,0,1),90) #Y
#    if(C<=3){
#        Q = quat(Dir:toAngle())*qRotation(vec(0,0,1),180) #X
#    }else{
#        Q = quat(Dir:toAngle())*qRotation(vec(0,1,0),-90) #Z
#    }
#    Self:applyTorque((150*Self:toLocal(rotationVector(Q/quat(Self))+Self:pos())-12*Self:angVelVector())*Self:inertia())
#} 
