@name Takkun
@inputs 
@outputs Animation_Name:string Animation_Link:string Dist FPS_Num
@persist Q5:array Table:table Loop:array Keyz:array Rate:array Animations:table House:array
@persist Animation:string Animation_Name:string Animation_Hold:string Animation_Link:string Hold_Name:string Mode:string Animation_Linked:string
@persist FPS Time Timez Animate Repeat Ended Start Trail Modez Sub_Mode Scale Scale_Pitch Scale_Turn Stand_Timer FPS_Num
@persist Base:entity Pos:vector Vel:vector Doggy_Angle:angle
@persist ZZ_Pos:array ZZ_Ang:array ZZ_Scale:array Ani_Pos:array
if(first())
{
    runOnTick(1)
    runOnChat(1)
    Pos=entity():pos()+vec(-1,0,40)
    ZZ_Pos=array(vec(),-vec(4.3,0,-2.5),-vec(7.1,0,0.93),-vec(10.11,0,0.27),-vec(7.2,0,4.2),-vec(10.8,0,2.8),-vec(6,0,3.5),vec(3.6,-2,0),vec(3.6,-2,0),vec(3.3,0,0),vec(3.8,-1.9,0),vec(-1,0,3.5),vec(3.8,1.1,0.6),vec(3.8,1.67,-0.1),vec(3.9,2.48,-0.1),vec(3.8,3.1,0.6),vec(3.8,4,0),vec(-1,3.5,-6),vec(-1.65,3.5,-6.075),vec(-1,-3.5,-6),vec(-1.65,-3.5,-6.075),vec(-8.5,3.5,-5.75),vec(-9.15,3.5,-5.825),vec(-8.5,-3.5,-5.75),vec(-9.15,-3.5,-5.825),vec(-11.5,0,1.055))
    ZZ_Ang=array(ang(),ang(15,0,0),ang(),ang(15,0,0),ang(7,0,90),ang(51,0,90),ang(-97,0,0),ang(90,0,0),ang(90,0,0),ang(),ang(),ang(180,0,0),ang(0,0,75),ang(0,0,-77),ang(0,0,77),ang(0,0,-75),ang(),ang(),ang(0,0,90),ang(),ang(0,0,90),ang(),ang(0,0,90),ang(),ang(0,0,90),ang(90,0,0))
    ZZ_Scale=array(vec(8,10,10),vec(5,10,5),vec(8,10,6),vec(3,10,4),vec(7.7,1,10),vec(3.3,1.65,10),vec(3.3,10,5),vec(4,4,4),vec(3.8,3.8,2.5),vec(1.5,10.18,10.18),vec(0.5,6.2,0.5),vec(3,10.18,2.5),vec(0.5,1.8,0.5),vec(0.5,3.3,0.5),vec(0.5,3.3,0.5),vec(0.5,1.8,0.5),vec(0.5,1.6,0.5),vec(1.5,2,4.6),vec(1.1,4.6,2),vec(1.5,2,4.6),vec(1.1,4.6,2),vec(1.5,2,4.6),vec(1.4,4.6,2),vec(1.5,2,4.6),vec(1.4,4.6,2),vec(1.5,1.5,6))
    Scale=1
    for(I=1,26)
    {
        holoCreate(-I,Pos+(ZZ_Pos:vector(I)),vec(),ZZ_Ang:angle(I))
        holoScaleUnits(-I,ZZ_Scale:vector(I))
        if(I!=1&I<=17)
        {
            holoParent(-I,-1)
        }
        holoColor(-I,vec(175,161,64))
        holoMaterial(-I,"models/debug/debugwhite")
        #holoRenderFX(-I,1)
    }
    holoColor(-8,vec(90,67,30))
    holoColor(-9,vec(205,140,0))
    holoMaterial(-9,"phoenix_storms/mat/mat_phx_metallic")
    holoColor(-10,vec(125,111,64))
    holoColor(-11,vec())
    holoColor(-12,vec(135,101,14))
    holoColor(-26,vec(120,80,0))
    for(I=13,17)
    {
        holoColor(-I,vec())
    }
    holoParent(-19,-18)
    holoParent(-21,-20)
    holoParent(-23,-22)
    holoParent(-25,-24)
    holoModel(-2,"prism")
    holoModel(-5,"hqcylinder")
    holoModel(-6,"hqcylinder")
    holoModel(-7,"prism")
    holoModel(-8,"hqtorus2")
    holoModel(-9,"dome")
    holoModel(-12,"prism")
    holoModel(-19,"hqcylinder")
    holoModel(-21,"hqcylinder")
    holoModel(-23,"hqcylinder")
    holoModel(-25,"hqcylinder")
    holoModel(-26,"pyramid")
    Base=holoEntity(-1)
    Yelp="Yelp|1,npc/dog/dog_growl2.wav,500,100"
    Sounds=array(Yelp)
    #===========================================#
    #===========================================#
    #================ANIMATION!=================#
    #===========================================#
    #===========================================#
    Walking="Walking//1/270/-1*0|0,0,0|1|0,0,0*1*0|0,0,0|10|45,0,0|20|0,0,15|30|-45,0,0|40|0,0,0*4*0|-45,0,0|10|0,0,0|20|45,0,0|30|0,0,-15|40|-45,0,0*2*0|0,0,-15|10|-45,0,0|20|0,0,0|30|45,0,0|40|0,0,-15*3*0|45,0,0|10|0,0,15|20|-45,0,0|30|0,0,0|40|45,0,0*5*0|25,0,0|15|30,30,0|30|25,0,0|45|30,-30,0|60|25,0,0"
    Falling="Falling//1/45/-1*0|0,0,0|1|0,0,0*1*0|0,0,70|5|22.5,0,65|10|0,0,60|15|-22.5,0,65|20|0,0,70*2*0|0,0,-70|5|22.5,0,-65|10|0,0,-60|15|-22.5,0,-65|20|0,0,-70*3*0|0,0,70|5|22.5,0,65|10|0,0,60|15|-22.5,0,65|20|0,0,70*4*0|0,0,-70|5|22.5,0,-65|10|0,0,-60|15|-22.5,0,-65|20|0,0,-70*5*0|80,0,0|2|80,10,0|7|80,-10,0|9|80,0,0"
    Siting="Siting//1/45/-1*0|-18,0,0|10|-18,0,0*3*0|-90,0,0|10|-90,0,0*4*0|-90,0,0|10|-90,0,0*2*0|-45,0,0|10|-45,0,0*1*0|-45,0,0|10|-45,0,0*5*0|0,0,0|8|5,30,0|16|0,0,0|24|5,-30,0|32|0,0,0"
    SitDown="SitDown/Siting/0/45/-1*0|0,0,0|20|-18,0,0*3*0|0,0,0|20|-90,0,0*4*0|0,0,0|20|-90,0,0*1*0|0,0,0|15|-45,0,0|20|-45,0,0*2*0|0,0,0|15|-45,0,0|20|-45,0,0*"
    Standing="Standing//1/45/-1*0|0,0,0|1|0,0,0*1*0|0,0,0|140|0,0,0*2*0|0,0,0|140|0,0,0*3*0|0,0,0|140|0,0,0*4*0|0,0,0|140|0,0,0*5*0|-10,0,0|40|5,10,0|70|-10,0,0|110|5,-10,0|140|-10,0,0"
    Pause="Pause/Standing/0/20/-1*0|0,0,0|1|0,0,0*1*0|0,0,0|140|0,0,0*2*0|0,0,0|140|0,0,0*3*0|0,0,0|140|0,0,0*4*0|0,0,0|140|0,0,0*5*0|-10,0,0|40|5,10,0|70|-10,0,0|110|5,-10,0|140|-10,0,0"
    SitUp="SitUp/Standing/0/45/-1*0|-18,0,0|20|0,0,0*3*0|-90,0,0|20|0,0,0*4*0|-90,0,0|20|0,0,0*1*0|-45,0,0|5|0,0,0|20|0,0,0*2*0|-45,0,0|5|0,0,0|20|0,0,0*"
    Running="Running//1/67/1*0|0,0,0|5|45,0,0|7|0,0,10|10|-45,0,0|15|0,0,0*3*0|0,0,10|3|-45,0,0|8|0,0,0|13|45,0,0|15|0,0,10*2*0|0,0,0|5|45,0,0|7|0,0,-10|10|-45,0,0|15|0,0,0*4*0|0,0,-10|3|-45,0,0|8|0,0,0|13|45,0,0|15|0,0,-10*-1*0|0,0,0|1|0,0,0*5*0|0,0,0|5|10,0,0|10|0,0,0|15|-10,0,0|20|0,0,0"
    Lay="Lay//1/45/1*0|-80,0,0|1|-80,0,0*2*0|-80,0,0|1|-80,0,0*3*0|-80,0,0|10|-80,0,0*4*0|-80,0,0|1|-80,0,0*5*0|0,0,0|8|5,30,0|16|0,0,0|24|5,-30,0|32|0,0,0*-1*0|0,0,0|1|0,0,0*"
    LayDown="LayDown/Lay/0/20/1*0|0,0,0|10|-80,0,0*2*0|0,0,0|10|-80,0,0*3*0|0,0,0|10|-80,0,0*4*0|0,0,0|10|-80,0,0*5*0|0,0,0|10|-25,0,0*-1*0|0,0,0|5|-10,0,0|10|0,0,0*"
    LayUp="LayUp/Standing/0/20/1*0|-80,0,0|10|0,0,0*2*0|-80,0,0|10|0,0,0*3*0|-80,0,0|10|0,0,0*4*0|-80,0,0|10|0,0,0*5*0|-30,0,0|10|0,0,0*-1*0|0,0,0|5|-10,0,0|10|0,0,0*"
    
    Temp=array(Standing,SitUp,Walking,Siting,SitDown,Falling,Running,Lay,LayDown,LayUp,Pause)
    #Temp=array()
    #Temp[1,string]=Standing
    #Temp[2,string]=SitUp
    #Temp[3,string]=Walking
    #Temp[4,string]=Siting
    #Temp[5,string]=SitDown
    #Temp[6,string]=Falling
    #Temp[7,string]=Running
    #Temp[8,string]=Lay
    #Temp[9,string]=LayDown
    #Temp[10,string]=LayUp
    
    for(I=1,Temp:count())
    {
        Animation=Temp:string(I)
        Animation_Name=Animation:explode("/"):string(1)
        Animations[Animation_Name,string]=Animation
    }
    Animation=Standing
    FPS=Animation:explode("/"):string(4):toNumber()
    FPS=10000/FPS
    #===#
    Time=curtime()*10000
    Start=Time
    Ended=0
    #Mode_Ready=1
    House=array(entity():pos(),entity():angles(),entity():pos()+(entity():forward()*40))
}
if(changed(Scale))
{
    if(!first())
    {
        Pos=Base:pos()
        for(I5=0.01,0,-0.01)
        {
            Scale1=Scale+I5
            for(I=1,26)
            {
                if(I==8){Sc=vec(5,5,5)}else{Sc=ZZ_Scale:vector(I)}
                holoPos(-I,Pos+(ZZ_Pos:vector(I)*Scale1))
                holoAng(-I,ZZ_Ang:angle(I))
                holoScaleUnits(-I,Sc*Scale)
            }
            for(I=1,5)
            {
                holoPos(I,Pos+(Ani_Pos:vector(I)*Scale1))
                holoAng(I,ang())
                holoScaleUnits(I,vec(1,1,1))
            }
        }
    }
    Scale_Pitch=(Scale-1)*10
    Scale_Turn=max(1,Scale/2)
}
Now=curtime()*10000
if(Now-Time>10000&!Animate)
{
    Time=curtime()*10000
    Start=Time
    Animate=1
    Ani_Pos=array(vec(-1,3.5,-4.6),vec(-1,-3.5,-4.6),vec(-8.5,3.5,-4.35),vec(-8.5,-3.5,-4.35),vec(-11,0,1))
    for(I=1,5)
    {
        holoCreate(I,Pos+Ani_Pos:vector(I),vec(),ang())
        holoScaleUnits(I,vec(1,1,1))
        holoParent(I,-1)
        holoAlpha(I,0)
    }
    holoParent(-18,1)
    holoParent(-20,2)
    holoParent(-22,3)
    holoParent(-24,4)
    holoParent(-26,5)
    holoAlpha(5,0)
}
if(changed(Animation))
{
    TempArray=Animation:explode("/")
    Animation_Name=TempArray:string(1)
    Animation_Link=TempArray:string(2)
    Repeat=TempArray:string(3):toNumber()
    FPS=TempArray:string(4):toNumber()
    FPS_Num=FPS
    Array=TempArray:string(5):explode("*")
    FPS=10000/FPS
    Temp=array()
    Table=table()
    Loop=array()
    Q5=array()
    Keyz=array()
    Rate=array()
    TempNum=0
    for(I=2,Array:count(),2)
    {
        TempNum+=Temp:count()
        Table["P"+Array:string(I-1),number]=TempNum+1
        Loop:pushNumber(Array:string(I-1):toNumber())
        Temp=Array:string(I):explode("|")
        for(Q=2,Temp:count(),2)
        {
            Temp1=Temp:string(Q):explode(",")
            Q5:pushNumber(Temp:string(Q-1):toNumber())
            Q5:pushAngle(ang(Temp1:string(1):toNumber(),Temp1:string(2):toNumber(),Temp1:string(3):toNumber()))
        }
    }
    Loop:pushNumber(0)
    Table["P0",number]=Q5:count()
    for(I=1,Loop:count())
    {
        Index=Table[("P"+toString(Loop:number(I))),number]
        Key=vec(Q5:number(Index),Q5:number(Index+2),3)
        Keyz[I,vector]=Key
        Rate[I,angle]=(Q5:angle(Index+Key:z())-Q5:angle(Index+Key:z()-2))/(Key:y()-Key:x())
    }
    Time=curtime()*10000
    Start=Time
    Ended=0
}
if(Animate)
{
    if(Now-Time>FPS&!Ended)
    {
        Time=Now
        for(I=1,Loop:count())
        {
            Index=Table[("P"+toString(Loop:number(I))),number]
            Key=Keyz:vector(I)+vec(1,0,0)
            Ang=Q5:angle(Index+Key:z()-2)+(Rate:angle(I)*(Key:x()-Q5:number(Index+Key:z()-3)))
            holoAng(Loop:number(I),Doggy_Angle+Ang)
            if(Ang:pitch()==0&Ang:yaw()==0&Ang:roll())
            {
                if(Animation_Name=="Walking"|Animation_Name=="Running")
                {
                    A=floor(curtime()*1000)
                    holoEntity(I):soundPlay(A,1,"player/footsteps/grass4.wav")
                    soundPitch(A,200-Scale_Pitch)
                }
            }
            if(Animation_Link!="")
            {
                Animation_Linked=Animation_Name
            }
            if(Key:x()>=Key:y())
            {
                Key+=vec(0,0,2)
                Key=Key:setY(Q5:number(Index+Key:z()-1))
                Rate[I,angle]=(Q5:angle(Index+Key:z())-Q5:angle(Index+Key:z()-2))/(Key:y()-Key:x())
                if(Key:z()+Index>Table[("P"+toString(Loop:number(I+1))),number])#===Note May Cause Timeing Error===#
                {
                    if(Repeat)
                    {
                        Key=vec(Q5:number(Index),Q5:number(Index+2),3)
                        Rate[I,angle]=(Q5:angle(Index+Key:z())-Q5:angle(Index+Key:z()-2))/(Key:y()-Key:x())
                    }
                    elseif(Now-Start>5000)
                    {
                        if(Animation_Link!="")
                        {
                            Animation=Animations[Animation_Link,string]
                        }
                        else
                        {
                            Animation_Linked=""
                            Ended=1
                        }
                    }
                }
            }
            Keyz[I,vector]=Key
        }
    }
    #===========================================#
    Movement=1
    if(Movement)
    {
        Lift=8.2*Scale
        R=rangerOffset(10000,Base:pos()+vec(0,0,Lift),vec(0,0,-1))
        Laying=(Animation_Name:find("Lay"))*2.3*Scale
        if(R:distance()>Lift-Laying)
        {
            Vel-=vec(0,0,0.05*Scale)
        }
        Doggy=(Base:pos()+Vel):setZ(max((Base:pos()+Vel):z(),R:position():z()+Lift-Laying))
        if(Doggy:z()==R:position():z()+Lift-Laying)
        {
            Vel=Vel:setZ(0)
        }
        if(Doggy:isInWorld())
        {
            holoPos(-1,Doggy)
        }
    }
}
if(Animate)
{
    if(Vel:z()<-1&Animation_Name!="Falling")
    {
        Animation_Hold=Animation_Name
        Hold_Name=Animation_Name
        Animation=Animations["Falling",string]
    }
    if(Vel:z()>-1&Animation_Name=="Falling")
    {
        if(Animation_Linked!="")
        {
            Animation=Animations[Animation_Linked,string]
        }
        else
        {
            Animation=Animations[Animation_Hold,string]
        }
    }
    if(Animation_Name=="Standing")
    {
        if(!Stand_Timer)
        {
            Stand_Timer=Now
        }
        if(Now-Stand_Timer>30000)
        {
            Animation=Animations["SitDown",string]
        }
    }
    else
    {
        Stand_Timer=0
    }
    if(Animation_Name=="Walking")
    {
        Vel=(Base:forward()*Scale/((45/FPS_Num)*10)):setZ(Vel:z())
    }
    if(Animation_Name=="Running")
    {
        Vel=(Base:forward()*Scale*(FPS_Num/45)):setZ(Vel:z())
    }
    if(Animation_Name=="Pause")
    {
        Vel=Vel*vec(0.9,0.9,1)
    }
    Vel=Vel*vec(0.95,0.95,1)
    if(Modez)
    {
        if(Trail&!Animation_Name:find("Sit"))
        {
            Trail=0
            soundPurge()
            holoEntity(-6):removeTrails()
        }
        if(Mode=="follow_old"&Animation_Name!="Falling")
        {
            Dist=Base:pos():distance(owner():pos())/Scale
            if(inrange(Dist,70,150)&Animation_Name!="Walking")
            {
                if(Animation_Name:find("Sit")&Animation_Name!="SitUp")
                {
                    Animation=Animations["SitUp",string]
                }
                if(Animation_Name=="Standing")
                {
                    Animation=Animations["Walking",string]
                }
            }
            if(Dist>150&Animation_Name!="Running")
            {
                Animation=Animations["Running",string]
            }
            if(Dist<=70&!Animation_Name:find("Sit"))
            {
                Animation=Animations["SitDown",string]
            }
            if(Animation_Name=="Walking"|Animation_Name=="Running")
            {
                Doggy_Angle-=ang(0,Base:bearing(owner():pos())*Scale_Turn/50,0)
            }
            if(Vel:length()<1&Animation_Name:find("Sit")&!Trail)
            {
                Trail=1
                soundPurge()
                A=floor(curtime()*1000)
                Ent=holoEntity(-6)
                Ent:setTrails(15*Scale,25*Scale,5*Scale,"trails/smoke",vec(185,150,90),180)
                Ent:soundPlay(A+I,2,"HL1/fvox/hiss.wav")
                soundPitch(A+I,70-Scale_Pitch/10)
                soundVolume(A+I,100)
            }
        }
        if(Mode=="follow"&Animation_Name!="Falling")
        {
            Dist=Base:pos():setZ(0):distance(owner():pos():setZ(0))/(1+(Scale-1)*0.1)
            if(inrange(Dist,80,120)&Animation_Name=="Running")
            {
                Animation=Animations["Standing",string]
            }
            if(inrange(Dist,80,200)&Animation_Name!="Walking")
            {
                if(Animation_Name=="Siting")
                {
                    Animation=Animations["SitUp",string]
                }
                if(Animation_Name=="Standing")
                {
                    Animation=Animations["Walking",string]
                }
            }
            if(Dist>200&Animation_Name!="Running")
            {
                Animation=Animations["Running",string]
            }
            if(Dist<80&((Animation_Name!="Standing"&Animation_Name!="Pause")&!Animation_Name:find("Sit")))
            {
                Animation=Animations["Pause",string]
            }
            if(Animation_Name=="Walking"|Animation_Name=="Running")
            {
                Doggy_Angle-=ang(0,Base:bearing(owner():pos())*Scale_Turn/50,0)
            }
        }
        if(Mode=="laydown")
        {
            if(Sub_Mode==1)
            {
                Tar=House:vector(3)
            }
            if(Sub_Mode==2)
            {
                Tar=House:vector(1)
            }
            Dist=Base:pos():setZ(0):distance(Tar:setZ(0))/Scale
            if(inrange(Dist,10,50)&Animation_Name=="Running")
            {
                Animation=Animations["Standing",string]
            }
            if(inrange(Dist,10,50)&Animation_Name!="Walking")
            {
                if(Animation_Name:find("Sit")&Animation_Name!="SitUp")
                {
                    Animation=Animations["SitUp",string]
                }
                if(Animation_Name=="Standing")
                {
                    Animation=Animations["Walking",string]
                }
            }
            if(Dist>50&Animation_Name!="Running")
            {
                Animation=Animations["Running",string]
            }
            if(Dist<=10)
            {
                if(Sub_Mode==2)
                {
                    if(!Animation_Name:find("Lay"))
                    {
                        Doggy_Angle+=ang(0,House:angle(2):yaw()-Base:angles():yaw(),0)*Scale_Turn/50
                    }
                    if(!Animation_Name:find("Lay"))
                    {
                        TempNumber=House:angle(2):yaw()
                        if(inrange(Base:angles():yaw(),TempNumber-15,TempNumber+15))
                        {
                            Animation=Animations["LayDown",string]
                        }
                    }
                    if(Animation_Name=="Walking")
                    {
                        Animation=Animations["Standing",string]
                    }
                }
                if(Sub_Mode==1)
                {
                    Sub_Mode=2
                    Doggy_Angle=Doggy_Angle*ang(0,1,0)
                }
            }
            if(Dist>50&Sub_Mode==2)
            {
                Sub_Mode=1
            }
            if(Animation_Name=="Walking"|Animation_Name=="Running")
            {
                Doggy_Angle-=ang(0,Base:bearing(Tar)*Scale_Turn/50,0)
            }
        }
        if(Mode=="sit")
        {
            if(!Animation_Name:find("Sit")&Animation_Name!="Falling")
            {
                Animation=Animations["SitDown",string]
            }
        }
    }
    else
    {
        if(Animation_Name=="Standing")
        {
            Modez=1
        }
        if(Animation_Name:find("Sit")&Animation_Name!="SitUp")
        {
            Animation=Animations["SitUp",string]
        }
        if(Animation_Name:find("Lay")&Animation_Name!="LayUp")
        {
            Animation=Animations["LayUp",string]
        }
        if(Animation_Name:find("Walking")|Animation_Name:find("Running"))
        {
            Animation=Animations["Standing",string]
        }
    }
}
if(chatClk(owner()))
{
    Said=lastSaid():lower():explode(" ")
    Said1=lastSaid():lower()
    if(Said1:find("sit"))
    {
        Mode="sit"
    }
    if(Said1:find("follow"))
    {
        Mode="follow"
    }
    if(Said1:find("follow_old"))
    {
        Mode="follow_old"
    }
    if(Said1:find("go laydown"))
    {
        Mode="laydown"
        Sub_Mode=1
    }
    if(Said:string(1)=="scale")
    {
        Scale=Said:string(2):toNumber()
    }
    if(changed(Mode)){Modez=0}
}