local boss = nil local WaveStarted = false local Summon_Pos_Table = { [1] = { { offset = Vector(0, -128, 64), type = 0 }, { offset = Vector(0, -256, 64), type = 0 }, { offset = Vector(0, 128, 64), type = 0 }, { offset = Vector(0, 256, 64), type = 0 }, { offset = Vector(192, 0, 96), type = 2 }, { offset = Vector(192, -192, 80), type = 1 }, { offset = Vector(192, 192, 80), type = 1 } }, [2] = { { offset = Vector(128, -192, 96), type = 2 }, { offset = Vector(-128, -192, 96), type = 2 }, { offset = Vector(128, 192, 96), type = 2 }, { offset = Vector(-128, 192, 96), type = 2 } }, [3] = { { offset = Vector(-64, -64, 80), type = 1 }, { offset = Vector(-128, 0, 80), type = 1 }, { offset = Vector(-64, 64, 80), type = 1 }, { offset = Vector(128, -256, 64), type = 0 }, { offset = Vector(128, -128, 64), type = 0 }, { offset = Vector(128, 128, 64), type = 0 }, { offset = Vector(128, 256, 64), type = 0 }, { offset = Vector(256, -192, 64), type = 0 }, { offset = Vector(256, -64, 64), type = 0 }, { offset = Vector(256, 64, 64), type = 0 }, { offset = Vector(256, 128, 64), type = 0 } }, [4] = { { offset = Vector(0, -192, 96), type = 2 }, { offset = Vector(0, 192, 96), type = 2 } }, [5] = { { offset = Vector(-192, -192, 64), type = 0 }, { offset = Vector(-192, 0, 64), type = 0 }, { offset = Vector(-192, 192, 64), type = 0 }, { offset = Vector(64, -128, 80), type = 1 }, { offset = Vector(192, 0, 80), type = 1 }, { offset = Vector(64, 128, 80), type = 1 } }, [6] = { { offset = Vector(256, 0, 96), type = 2 }, { offset = Vector(192, -128, 64), type = 0 }, { offset = Vector(160, -64, 64), type = 0 }, { offset = Vector(128, 0, 64), type = 0 }, { offset = Vector(160, 64, 64), type = 0 }, { offset = Vector(192, 128, 64), type = 0 } }, [7] = { { offset = Vector(192, 0, 80), type = 1 }, { offset = Vector(128, -128, 80), type = 1 }, { offset = Vector(0, -192, 80), type = 1 }, { offset = Vector(-128, -128, 80), type = 1 }, { offset = Vector(-192, 0, 80), type = 1 }, { offset = Vector(-128, 128, 80), type = 1 }, { offset = Vector(0, 192, 80), type = 1 }, { offset = Vector(128, 128, 80), type = 1 } }, [8] = { { offset = Vector(-128, -256, 64), type = 0 }, { offset = Vector(-128, 256, 64), type = 0 }, { offset = Vector(0, -128, 80), type = 1 }, { offset = Vector(0, 128, 80), type = 1 } }, [9] = { { offset = Vector(-128, 0, 96), type = 2 } }, [10] = { { offset = Vector(128, -256, 80), type = 1 }, { offset = Vector(0, -256, 80), type = 1 }, { offset = Vector(128, 256, 80), type = 1 }, { offset = Vector(0, 256, 80), type = 1 } } } local Summon_Queue_Table = {} function has_value (tab, val) --copied from stack overflow for index, value in pairs(tab) do if value == val then return true end end return false end CEntity.IsMidair = function(self) if (IsValidAlivePlayer(self)) then return not (self.movetype == MOVETYPE_WALK and (self.m_fFlags & FL_ONGROUND ~= 0)); end end function IsValidAlivePlayer(ent) return IsValid(ent) and ent:IsPlayer() and ent:IsAlive(); end function OnWaveStart(wave) WaveStarted = true end function OnWaveInit() WaveStarted = false end function OnGameTick() for _, player in pairs(ents.GetAllPlayers()) do if ( player:IsBot() ) and ( boss ~= nil ) and ( ents.FindByName("indicator"):IsValid() ) and ( player ~= boss ) then if player:GetAbsOrigin():Distance(ents.FindByName("indicator"):GetAbsOrigin()) < 384 then player:AddCond(28) player:AddCond(113) else player:RemoveCond(28) player:RemoveCond(113) end if player.bIsSummon then if player:InCond(51) then player:SetAttributeValue("no_attack", 1) else player:SetAttributeValue("no_attack", nil) end end end end end function OnWaveSpawnBot(bot, wave, tags) bot.bIsSummon = false if has_value(tags, "bot_boss") then boss = bot bot.CanDoSpecialAttack = true bot.UpdateZone = timer.Create(10, function() if ( ents.FindByName("indicator"):IsValid() ) and ( bot.m_iHealth < 20001 ) and ( bot.m_iTeamNum == 3 ) and ( bot:IsAlive() ) and ( bot.CanDoSpecialAttack ) then ents.FindByName("indicator"):SetAbsOrigin(bot:GetAbsOrigin() + Vector(0,0,16)) end end, 0) bot:AddCallback(ON_DEATH, function() pcall(timer.Stop, bot.UpdateZone) WaveStarted = false ents.FindByName("indicator"):AcceptInput("kill") for i=1, #Summon_Pos_Table do ents.FindByName("interface"):AcceptInput("$KillWavespawn", "Boss_Summon_Type_" .. tostring(i) ) ents.FindByName("interface"):AcceptInput("$PauseWavespawn", "Boss_Summon_Type_" .. tostring(i) ) end end) end for i, sTag in pairs(tags) do if ( boss ~= nil ) and ( string.match(tostring(sTag), "bot_common") ) then for t, v in pairs(Summon_Queue_Table) do if ( Summon_Queue_Table[t].type == 0 ) and ( not Summon_Queue_Table[t].used ) then bot:SetAbsOrigin(Summon_Queue_Table[t].pos) Summon_Queue_Table[t].used = true break end end bot:AddCond(51, 3) bot:AddCond(32, 3) bot.bIsSummon = true util.ParticleEffect("teleportedin_blue", bot:GetAbsOrigin()) util.ParticleEffect("teleported_blue", bot:GetAbsOrigin()) util.ParticleEffect("wrenchmotron_teleport_beam", bot:GetAbsOrigin()) elseif ( boss ~= nil ) and ( string.match(tostring(sTag), "bot_minigiant") ) then for t, v in pairs(Summon_Queue_Table) do if ( Summon_Queue_Table[t].type == 1 ) and ( not Summon_Queue_Table[t].used ) then bot:SetAbsOrigin(Summon_Queue_Table[t].pos) Summon_Queue_Table[t].used = true break end end bot:AddCond(51, 3) bot:AddCond(32, 3) bot.bIsSummon = true util.ParticleEffect("teleportedin_blue", bot:GetAbsOrigin()) util.ParticleEffect("teleported_blue", bot:GetAbsOrigin()) util.ParticleEffect("wrenchmotron_teleport_beam", bot:GetAbsOrigin()) elseif ( boss ~= nil ) and ( string.match(tostring(sTag), "bot_giant") )then for t, v in pairs(Summon_Queue_Table) do if ( Summon_Queue_Table[t].type == 2 ) and ( not Summon_Queue_Table[t].used ) then bot:SetAbsOrigin(Summon_Queue_Table[t].pos) Summon_Queue_Table[t].used = true break end end bot:AddCond(51, 3) bot:AddCond(32, 3) bot.bIsSummon = true util.ParticleEffect("teleportedin_blue", bot:GetAbsOrigin()) util.ParticleEffect("teleported_blue", bot:GetAbsOrigin()) util.ParticleEffect("wrenchmotron_teleport_beam", bot:GetAbsOrigin()) end end end function TrackThisTank(_, activator) local tank = ents.FindByName("Car_Tank") tank:AddCallback(ON_DEATH, function() pcall(timer.Stop, Timer) for i, bot in pairs(ents.GetAllPlayers()) do if ( bot:IsBot() ) and ( bot == boss ) then bot:SetAttributeValue("cannot pick up intelligence", nil) bot:SetAbsOrigin(tank:GetAbsOrigin()) bot:AcceptInput("SetHealth", 50000 ) BossGroundSlam() end end end) tank:AddCallback(ON_REMOVE, function() pcall(timer.Stop, Timer) for i, bot in pairs(ents.GetAllPlayers()) do if ( bot:IsBot() ) and ( bot == boss ) then bot:SetAttributeValue("cannot pick up intelligence", nil) bot:SetAbsOrigin(tank:GetAbsOrigin()) bot:AcceptInput("SetHealth", 50000 ) BossGroundSlam() end end end) local Timer = timer.Create(0.1, function() if ( IsValid(tank) ) and ( boss ~= nil ) then for i, player in pairs(ents.GetAllPlayers()) do if ( player:IsBot() ) and ( player == boss ) then player:AcceptInput("SetHealth", tank.m_iHealth + 65000 ) end end else pcall(timer.Stop, Timer) end end, 0) end function ClusterBomb(projectile) projectile:AddCallback(ON_REMOVE, function(ent) ents.FindByName("CB_Spawner"):Teleport(projectile:GetAbsOrigin() + Vector(0, 0, -72)) ents.FindByName("CB_Spawner"):AcceptInput("ForceSpawn") end) end function RockCluster(projectile) projectile:AddCallback(ON_REMOVE, function(ent) ents.FindByName("RC_Spawner"):Teleport(projectile:GetAbsOrigin() + Vector(0, 0, 8)) ents.FindByName("RC_Spawner"):AcceptInput("ForceSpawn") end) end function BossGroundSlam() for i, bot in pairs(ents.GetAllPlayers()) do if ( bot:IsBot() ) and ( bot == boss ) and ( bot.CanDoSpecialAttack ) then bot:AddCond(87) bot:AddCond(28) bot:AddCond(93) bot.CanDoSpecialAttack = false bot:SetLocalVelocity( Vector(0,0,1200) ) bot:AcceptInput("$PlaySequence", "taunt_yeti") timer.Simple(1,function() local tarpos = bot:GetAbsOrigin() timer.Create(0.1, function() bot:SetAbsOrigin(tarpos) bot:SetLocalVelocity( Vector(0,0,0) ) end, 30) end) timer.Simple(4.5, function() bot:SetLocalVelocity( Vector(0,0,-3500) ) end) timer.Simple(5.2, function() ents.FindByName("RR_Spawner"):Teleport(bot:GetAbsOrigin() + Vector(0, 0, 8)) ents.FindByName("RR_Spawner"):AcceptInput("ForceSpawn") for _, player in pairs(ents.GetAllPlayers()) do player:PlaySoundToSelf("ambient/explosions/explode_9.wav") end for _, player in pairs(ents.FindInSphere(bot:GetAbsOrigin(),256)) do if ( player:IsRealPlayer() ) and ( not player:IsMidair() ) then player:TakeDamage({Attacker = bot, Damage = 80, DamageType = DMG_CRUSH}) end end for _, player in pairs(ents.FindInSphere(bot:GetAbsOrigin(),750)) do if player:IsRealPlayer() then local mod = ( 750 - ( player:GetAbsOrigin():Distance(bot:GetAbsOrigin()) ) ) / 750 player:PlaySoundToSelf("ambient/explosions/explode_4.wav") if not player:IsMidair() then player:SetLocalVelocity( ( player.m_vecVelocity * 0.5 ) + ( Vector( 0,0,1200 ) * mod ) ) end end end util.ParticleEffect("hammer_impact_button",bot:GetAbsOrigin()) end) timer.Simple(10.2, function() ents.FindByName("RR_Spawner"):Teleport(bot:GetAbsOrigin() + Vector(0, 0, 8)) ents.FindByName("RR_Spawner"):AcceptInput("ForceSpawn") for _, player in pairs(ents.GetAllPlayers()) do player:PlaySoundToSelf("ambient/explosions/explode_9.wav") end for _, player in pairs(ents.FindInSphere(bot:GetAbsOrigin(),256)) do if ( player:IsRealPlayer() ) and ( not player:IsMidair() ) then player:TakeDamage({Attacker = bot, Damage = 80, DamageType = DMG_CRUSH}) end end for _, player in pairs(ents.FindInSphere(bot:GetAbsOrigin(),750)) do if player:IsRealPlayer() then local mod = ( 750 - ( player:GetAbsOrigin():Distance(bot:GetAbsOrigin()) ) ) / 750 player:PlaySoundToSelf("ambient/explosions/explode_4.wav") if not player:IsMidair() then player:SetLocalVelocity( ( player.m_vecVelocity * 0.5 ) + ( Vector( 0,0,1200 ) * mod ) ) end end end util.ParticleEffect("hammer_impact_button",bot:GetAbsOrigin()) end) timer.Simple(12, function() bot:RemoveCond(87) bot:RemoveCond(28) bot:RemoveCond(93) bot:RemoveCond(7) bot.CanDoSpecialAttack = true end) end end end function BossEnrage() for i, bot in pairs(ents.GetAllPlayers()) do if ( bot:IsBot() ) and ( bot == boss ) then bot:AddCond(87) bot:AddCond(28) bot:AddCond(93) bot:AcceptInput("$PlaySequence", "taunt_unleashed_rage_heavy") timer.Simple(5, function() bot:RemoveCond(87) bot:RemoveCond(28) bot:RemoveCond(93) bot:RemoveCond(7) bot:AddCond(90,15) end) end end end function BossRocketRain() for i, bot in pairs(ents.GetAllPlayers()) do if ( bot:IsBot() ) and ( bot == boss ) and ( bot.CanDoSpecialAttack ) then bot:AddCond(87) bot:AddCond(28) bot:AddCond(93) bot.CanDoSpecialAttack = false bot:AcceptInput("$PlaySequence", "layer_taunt_cyoa_PDA_intro") SummonRockets() timer.Simple(1.8, function() bot:AcceptInput("$PlaySequence", "layer_taunt_cyoa_PDA_outro") end) timer.Simple(2.3, function() bot:RemoveCond(87) bot:RemoveCond(28) bot:RemoveCond(93) bot:RemoveCond(7) bot.CanDoSpecialAttack = true end) end end end function SummonRockets() local index = 0 timer.Create(0.5, function() if WaveStarted then for i=1, math.random(1,2) do RecountPlayers() --function from robot_extras.lua local RandomPlayer = PlayerTable[math.random(0,#PlayerTable)] --table from robot_extras.lua OrbitalRocketMain(RandomPlayer,boss,index) --function from robot_extras.lua index = index + 1 end end end, 60) end function BossSummon() for i, bot in pairs(ents.GetAllPlayers()) do if ( bot:IsBot() ) and ( bot == boss ) and ( bot.CanDoSpecialAttack ) then Summon() bot:AddCond(87) bot:AddCond(28) bot:AddCond(93) bot.CanDoSpecialAttack = false bot:AcceptInput("$PlaySequence", "taunt_crushing_headache") timer.Simple(1.8, function() for _, player in pairs(ents.GetAllPlayers()) do player:PlaySoundToSelf("mvm/mvm_tele_deliver.wav") end end) timer.Simple(3.5, function() bot:RemoveCond(87) bot:RemoveCond(28) bot:RemoveCond(93) bot:RemoveCond(7) bot.CanDoSpecialAttack = true end) end end end function Summon() for i, v in pairs(Summon_Queue_Table) do Summon_Queue_Table[i] = nil end if ents.FindByName("indicator"):IsValid() then ents.FindByName("indicator"):AcceptInput("kill") end local KeyValues = { model = "models/props_gameplay/cap_circle_768.mdl", skin = 2, origin = boss:GetAbsOrigin(), disableshadows = 1, targetname = 'indicator' } ents.CreateWithKeys("prop_dynamic", KeyValues, true, true) timer.Simple(0.1, function() ents.FindByName("indicator"):SetAbsOrigin(boss:GetAbsOrigin() + Vector(0,0,16)) ents.FindByName("indicator"):SetAbsAngles(boss:GetAbsAngles()) end) local rand = math.random(1,#Summon_Pos_Table) for i, v in pairs(Summon_Pos_Table[rand]) do ents.FindByName("interface"):AcceptInput("$KillWavespawn", "Boss_Summon_Type_" .. tostring(rand) ) local KeyValues = { model = "models/props_mvm/reversemvm_redbot_wall.mdl", disableshadows = 1, targetname = 'bot_spawner' .. tostring(i), rendercolor = "0 204 255", rendermode = 1 } ents.CreateWithKeys("prop_dynamic", KeyValues, true, true) local prop = ents.FindByName('bot_spawner' .. tostring(i)) local par = ents.FindByName('indicator') if Summon_Pos_Table[rand][i].type == 0 then ents.FindByName('bot_spawner' .. tostring(i))["modelscale"] = 0.5 elseif Summon_Pos_Table[rand][i].type == 1 then prop["modelscale"] = 0.65 else prop["modelscale"] = 0.8 end timer.Simple(0.11, function() prop:AcceptInput("SetParent", par) prop:SetAbsOrigin(par:GetAbsOrigin()) end) timer.Simple(0.12, function() prop:AcceptInput("SetLocalOrigin", Summon_Pos_Table[rand][i].offset) prop:SetAbsAngles(par:GetAbsAngles()) end) timer.Simple(0.13, function() Summon_Queue_Table[i] = { pos = prop:GetAbsOrigin(), type = Summon_Pos_Table[rand][i].type, used = false } end) timer.Simple(1.8, function() ents.FindByName("interface"):AcceptInput("$ResumeWavespawn", "Boss_Summon_Type_" .. tostring(rand) ) end) timer.Simple(1.9, function() ents.FindByName("interface"):AcceptInput("$PauseWavespawn", "Boss_Summon_Type_" .. tostring(rand) ) for i, v in pairs(Summon_Queue_Table) do Summon_Queue_Table[i] = nil end prop:AcceptInput("kill") end) end end function DisableNaturalRespawns() for _, player in pairs(ents.GetAllPlayers()) do if player:IsRealPlayer() then player:SetAttributeValue("min respawn time", 1337) player:SetAttributeValue("cannot disguise", 1) player:RemoveCond(2) player:RemoveCond(3) player:RemoveCond(4) player:SetAttributeValue("mult cloak rate", 69420) --disableds CnD and normal cloak end end end function EnableNaturalRespawns() for _, player in pairs(ents.GetAllPlayers()) do if player:IsRealPlayer() then player:SetAttributeValue("min respawn time", nil) player:SetAttributeValue("cannot disguise", nil) player:SetAttributeValue("mult cloak rate", nil) end end end