@name Caber Demoman
@persist [Entity Owner Frame Platform Demoman Target Lua]:entity
@persist Props:array Meta:table [Lua_Explosion]:string Active

runOnChat(1)

if(first()) {
    # z-size of frame: 290.3
    # z-size of platform: 98
    
    Entity=entity()
    Owner=owner()
    
    Frame=propSpawn("models/props_lab/teleportframe.mdl",Entity:toWorld(vec()),Entity:toWorld(ang()),1)
    
    Props:pushEntity(Frame)
    
    holoCreate(1,Entity:toWorld(vec(31,0,44)),vec(1),Entity:toWorld(ang()))
    holoModel(1,"models/props_lab/teleplatform.mdl")
    holoParent(1,Frame)
    
    Platform=holoEntity(1)
    
    holoCreate(2,Platform:toWorld(vec(10,0,10)),vec(1),Platform:toWorld(ang(0,180,0)))
    holoModel(2,"models/props_lab/teleportring.mdl")
    holoParent(2,1)
    
    holoCreate(3,Platform:toWorld(vec(10,0,30)),vec(1),Platform:toWorld(ang(0,180,0)))
    holoModel(3,"models/props_lab/teleportring.mdl")
    holoParent(3,1)
    
    holoCreate(4,Platform:toWorld(vec(10,0,50)),vec(1),Platform:toWorld(ang(0,180,0)))
    holoModel(4,"models/props_lab/teleportring.mdl")
    holoParent(4,1)
    
    holoCreate(5,Platform:toWorld(vec(5,0,0)),vec(0.8),Platform:toWorld(ang()))
    holoModel(5,"models/player/demo.mdl")
    holoParent(5,1)
    Demoman=holoEntity(5)
    
    local Hand_BasePos=Demoman:attachmentPos("effect_hand_R")
    local Hand_BaseAng=Demoman:attachmentAng("effect_hand_R")
    
    local Head_BasePos=Demoman:attachmentPos("head")
    local Head_BaseAng=Demoman:attachmentAng("head")
    
    local Eyes_BasePos=Demoman:attachmentPos("eyes")
    local Eyes_BaseAng=Demoman:attachmentAng("eyes")
    
    local Back_BasePos=Demoman:attachmentPos("flag")
    local Back_BaseAng=Demoman:attachmentAng("flag")
    
    holoCreate(6,toWorld(vec(0,0,2),Hand_BaseAng,Hand_BasePos,Hand_BaseAng),vec(0.8),toWorldAng(Hand_BasePos,ang(160,0,0),Hand_BasePos,Hand_BaseAng))
    holoModel(6,"models/weapons/c_models/c_caber/c_caber.mdl")
    holoParentAttachment(6,Demoman,"effect_hand_R")
    
    holoCreate(8,toWorld(vec(0,0,-8),Head_BaseAng,Head_BasePos,Head_BaseAng),vec(0.8),Head_BaseAng)
    holoModel(8,"models/player/items/demo/demo_fiesta_shades.mdl")
    holoParentAttachment(8,Demoman,"eyes")
    
    holoCreate(9,toWorld(vec(0,0,-6.5),Head_BaseAng,Head_BasePos,Head_BaseAng),vec(0.8),Head_BaseAng)
    holoModel(9,"models/player/items/all_class/treasure_hat_01_demo.mdl")
    holoParentAttachment(9,Demoman,"head")
    
    holoCreate(10,Demoman:toWorld(vec(0,0,15)),vec(0.8),Demoman:angles())
    holoParentAttachment(10,Demoman,"flag")
    holoModel(10,"models/workshop/weapons/c_models/c_paratooper_pack/c_paratrooper_pack.mdl")
    
    holoCreate(11,Demoman:toWorld(vec(0,0,15)),vec(0.8),Demoman:angles())
    holoModel(11,"models/workshop/weapons/c_models/c_paratooper_pack/c_paratrooper_parachute.mdl")
    holoParentAttachment(11,Demoman,"flag")
        
    holoAlpha(5,0)
    holoAlpha(6,0)
    holoAlpha(7,0)
    holoAlpha(8,0)
    holoAlpha(9,0)
    holoAlpha(10,0)
    holoAlpha(11,0)
    
    function number demoSpawn() {
        Active=1
        holoAnim(5,"taunt_woohoo")
        
        holoAlpha(5,255)
        holoAlpha(6,255)
        holoAlpha(7,255)
        holoAlpha(8,255)
        holoAlpha(9,255)
        holoAlpha(10,255)
        holoAlpha(11,255)
        
        Demoman:soundPlay("woohoo",0,"vo/taunts/demoman_taunts17.mp3")
        Meta["Enter",number]=-100
        for(I=5,11) {
            holoClip(I,1,Platform:pos(),vec(0,0,1),1)
            holoClipEnabled(I,1,1)
        }
        timer("Enter",100)
        timer("StockAnim",4866)
        timer("StartLaunch",5000)
        
        return 0
    }
    
    function number parachute_Open() {
        holoAnim(11,"deploy")
        timer("ChuteIdle",600)
    }
    
    #########################
    # Lua Strings - CT Only #
    #########################
    findByClass("lua_run")
    Lua=find()
    
    Lua_Explosion="
        local Pos=Vector(%d,%d,%d)
        for i=1,5 do ParticleEffect(\"grenade_final\",Pos,Angle(0, 0, 0),nil) end
        util.ScreenShake(Pos,500,500,2,500)
        
        local Explode=ents.Create('env_explosion')
	       Explode:SetPos(Pos)
	       Explode:Spawn()
	       Explode:SetKeyValue('iMagnitude','%d')
	       Explode:SetKeyValue('spawnflags','64')
	       Explode:Fire('Explode',0,0 )
    "
    
    function lua_Run(S:string) {
        # Lua:set("RunPassedCode",S)
        luaRun(S)
    }
    
    function explode(V:vector,Damage) {
        V+=vec(0,0,30)
        local String=format(Lua_Explosion,V:x(),V:y(),V:z(),Damage)
        lua_Run(String)
    }
}

if(clk("Enter")) {
    if(Meta["Enter",number]<0) {
        Meta["Enter",number]=clamp(Meta["Enter",number]+4,-100,0)
        holoPos(5,Platform:toWorld(vec(0,0,Meta["Enter",number])))
        timer("Enter",100)
    } else {
        for(I=5,11) {
            holoClipEnabled(I,1,0)
        }
    }
}

if(clk("StockAnim")) {
    holoAnim(5,"stand_melee")
}

if(clk("ChuteIdle")) {
    holoAnim(11,"deploy_idle")
}

if(clk("StartLaunch")) {
    Platform:soundPlay(0,0,"ambient/machines/hydraulic_1.wav")
    Meta["BasePos",vector]=Platform:pos()
    Meta["FinPos",vector]=Platform:toWorld(vec(0,0,120))
    Meta["Diff",vector]=Meta["FinPos",vector]-Meta["BasePos",vector]
    Meta["i",number]=0
    timer("Rise",0)
}

if(clk("Rise")) {
    if(Meta["i",number]<1) {
        Meta["i",number]=Meta["i",number]+0.025
        holoPos(1,Meta["i",number] * Meta["Diff",vector] + Meta["BasePos",vector])
        timer("Rise",100)
    } else {
        timer("Launch01",1500)
    }
}

if(clk("Launch01")) {
    Platform:soundPlay("stop",0,"ambient/levels/labs/machine_stop1.wav")
    Meta["Sparkup",number]=0
    timer("Launch02",1000)
}

if(clk("Launch02")) {
    if(Meta["Sparkup",number]<3) {
        Meta["Sparkup",number]=Meta["Sparkup",number]+1
        local Sounds=array(
            "ambient/energy/newspark09.wav",
            "ambient/energy/newspark10.wav",
            "ambient/energy/newspark11.wav"
        )
        Platform:soundPlay(2,0,Sounds[Meta["Sparkup",number]+1,string])
        timer("Launch02",500)
    } else {
        Platform:soundPlay(3,0,"ambient/levels/labs/teleport_mechanism_windup1.wav")
        Meta["RingSpeed",number]=0
        Meta["Ring1",number]=0
        Meta["Ring2",number]=0
        Meta["Ring3",number]=0
        timer("TeleportLoop",4606)
        timer("Launch03",100)
        timer("Launch04",7000)
    }
}

if(clk("TeleportLoop")) {
    Platform:soundPlay(3,0,"ambient/levels/labs/machine_ring_resonance_loop1.wav")
    Platform:soundPlay(4,0,"ambient/levels/labs/teleport_rings_loop2.wav")
}

if(clk("Launch03")) {
    Meta["RingSpeed",number]=clamp(Meta["RingSpeed",number]+0.02,0,1)
    Meta["Ring1",number]=Meta["Ring1",number]+Meta["RingSpeed",number]*100
    Meta["Ring2",number]=Meta["Ring1",number]+Meta["RingSpeed",number]*-125
    Meta["Ring3",number]=Meta["Ring1",number]+Meta["RingSpeed",number]*150
    holoAng(2,Platform:toWorld(ang(0,180+Meta["Ring1",number],0)))
    holoAng(3,Platform:toWorld(ang(0,180+Meta["Ring2",number],0)))
    holoAng(4,Platform:toWorld(ang(0,180+Meta["Ring3",number],0)))
    timer("Launch03",100)
}

if(clk("Launch04")) {
    # soundStop(3)
    # Platform:soundPlay(3,0,"ambient/levels/labs/teleport_malfunctioning.wav")
    timer("Launch05",1500)
}

if(clk("Launch05")) {
    soundStop(3)
    soundStop(4)
    Platform:soundPlay(5,0,"ambient/levels/labs/teleport_winddown1.wav")
    Platform:soundPlay(6,0,"ambient/explosions/explode_3.wav")
    explode(Platform:pos(),0)
    holoUnparent(5)
    
    Meta["Start",vector]=Demoman:pos()
    Meta["Mid",vector]=((Demoman:pos()+Target:pos())/2):setZ(2000)
    Meta["End",vector]=Target:pos()
    Meta["t",number]=0
    
    holoAnim(5,"airwalk_MELEE")
    
    stoptimer("Launch03")
    timer("Launch06",0)
    timer("Launch07",8000)
    timer("DemoLoop",0)
}

if(clk("Launch06")) {
    Meta["RingSpeed",number]=clamp(Meta["RingSpeed",number]-0.02,0,1)
    if(Meta["RingSpeed",number]>0) {
        Meta["Ring1",number]=Meta["Ring1",number]+Meta["RingSpeed",number]*100
        Meta["Ring2",number]=Meta["Ring1",number]+Meta["RingSpeed",number]*-125
        Meta["Ring3",number]=Meta["Ring1",number]+Meta["RingSpeed",number]*150
        holoAng(2,Platform:toWorld(ang(0,180+Meta["Ring1",number],0)))
        holoAng(3,Platform:toWorld(ang(0,180+Meta["Ring2",number],0)))
        holoAng(4,Platform:toWorld(ang(0,180+Meta["Ring3",number],0)))
    } else {
        Meta["Ring1",number]=Meta["Ring1",number]%360/1.05
        Meta["Ring2",number]=Meta["Ring1",number]%360/1.05
        Meta["Ring3",number]=Meta["Ring1",number]%360/1.05
        holoAng(2,Platform:toWorld(ang(0,180+Meta["Ring1",number],0)))
        holoAng(3,Platform:toWorld(ang(0,180+Meta["Ring2",number],0)))
        holoAng(4,Platform:toWorld(ang(0,180+Meta["Ring3",number],0)))
    }
    timer("Launch06",100)
}

if(clk("Launch07")) {
    stoptimer("Launch06")
    Meta["Ring1",number]=0
    Meta["Ring2",number]=0
    Meta["Ring3",number]=0
    holoAng(2,Platform:toWorld(ang(0,180,0)))
    holoAng(3,Platform:toWorld(ang(0,180,0)))
    holoAng(4,Platform:toWorld(ang(0,180,0)))
    timer("Launch08",0)
    Platform:soundPlay(0,0,"ambient/machines/hydraulic_1.wav")
}

if(clk("Launch08")) {
    if(Meta["i",number]>0) {
        Meta["i",number]=Meta["i",number]-0.025
        holoPos(1,Meta["i",number] * Meta["Diff",vector] + Meta["BasePos",vector])
        timer("Launch08",100)
    } else {
        timer("Launch09",1500)
    }
}

if(clk("Launch09")) {
    Platform:soundPlay("stop",0,"ambient/levels/labs/machine_stop1.wav")
}

if(clk("DemoLoop")) {
    if(Meta["t",number]<1) {
        local Speed=(Meta["t",number]>0.5 & Meta["t",number]<0.9) ? 0.01 : 0.02
        Meta["t",number]=Meta["t",number]+Speed
        if(Meta["t",number]==0.5){
            parachute_Open()
        }
        if(Meta["t",number]==0.9) {
            holoAnim(11,"retract")
        }
        holoPos(5,bezier(Meta["Start",vector],Meta["Mid",vector],Target:pos(),Meta["t",number]))
        holoAng(5,(Target:pos()-Demoman:pos()):toAngle()*ang(0,1,0))
        timer("DemoLoop",100)
    } else {
        Demoman:soundPlay("Explode",0,"ambient/explosions/explode_4.wav")
        holoAlpha(5,0)
        holoAlpha(6,0)
        holoAlpha(7,0)
        holoAlpha(8,0)
        holoAlpha(9,0)
        holoAlpha(10,0)
        holoAlpha(11,0)
        holoPos(5,Platform:toWorld(vec(5,0,0)))
        holoAng(5,Platform:toWorld(ang()))
        holoParent(5,1)
        explode(Target:pos(),100)
        Active=0
    }
}

if(chatClk(Owner) & Owner:lastSaid():sub(1,1)=="!") {
    local Args=Owner:lastSaid():sub(2):explode(" ")
    local Command=Args:shiftString()
    if(Command=="caber") {
        if(!Active) {
            local Player=Args[1,string]:lower()
            local Targetee=noentity()
            foreach(I,V:entity=players()) {
                if(V:name():lower():matchFirst(Player)) {
                    Targetee=V
                    printColor(vec(255,255,0),"[Caber] ",vec(0,255,255),Targetee:name(),vec(255)," has been targeted.")
                    break
                }
            }
            
            if(Targetee==noentity()) {
                printColor(vec(255,255,0),"[Caber] ",vec(255,0,0),Args[1,string],vec(255)," is not a player.")
            } else {
                Target=Targetee
                demoSpawn()
            }
        } else {
            printColor(vec(255,255,0),"[Caber] ",vec(255,0,0),"Launch already in progress.")
        }
    }
}
