PrecacheSound("ambient/atmosphere/terrain_rumble1.wav") PrecacheSound("misc/rd_robot_explosion01.wav") PrecacheSound("items/powerup_pickup_strength.wav") PrecacheSound("npc/vort/health_charge.wav") PrecacheSound("npc/scanner/cbot_discharge1.wav") PrecacheSound("vo/mvm/mght/demoman_mvm_m_specialcompleted11.mp3") PrecacheSound("npc/roller/mine/rmine_explode_shock1.wav") PrecacheModel("models/props_mvm/robot_spawnpoint_warning.mdl") PrecacheModel("models/bots/demo_boss/bot_demo_boss_gibby.mdl") PopExtUtil.PrecacheParticle("fireSmoke_collumnP") PopExtUtil.PrecacheParticle("charge_up") PopExtUtil.PrecacheParticle("eyeboss_vortex_blue") PopExtUtil.PrecacheParticle("eyeboss_tp_vortex") PopExtUtil.PrecacheParticle("ghost_glow") PopExtUtil.PrecacheParticle("utaunt_elebound_purple_glow") PopExtUtil.PrecacheParticle("utaunt_elebound_purple_head1") PopExtUtil.PrecacheParticle("utaunt_elebound_purple_head2") PopExtUtil.PrecacheParticle("utaunt_elebound_purple_head3") PopExtUtil.PrecacheParticle("utaunt_elebound_purple_head4") PopExtUtil.PrecacheParticle("utaunt_elebound_purple_parent") PopExtUtil.PrecacheParticle("mvm_tank_destroy_smoke") PopExtUtil.PrecacheParticle("mvm_tank_destroy_embers") PopExtUtil.PrecacheParticle("mvm_tank_destroy_bloom") PopExtUtil.PrecacheParticle("mvm_tank_destroy_smokefront") PopExtUtil.PrecacheParticle("rd_robot_explosion_smoke_linger") PopExt.AddRobotTag("bombi_explosion", { OnSpawn = function(bot,tag) { local scope = bot.GetScriptScope() local wep = bot.GetActiveWeapon() scope.FindRocket <- function(owner) { local entity = null for (local entity; entity = FindByClassnameWithin(entity, "tf_projectile_*", owner.GetOrigin(), 500);) { if (entity.GetOwner() == owner) { continue } entity.ValidateScriptScope() return entity } return null } PopExtUtil.OnWeaponFire(wep, function(){ local rocket = scope.FindRocket(bot) if (rocket == null) return PopExtUtil.SetDestroyCallback(rocket, function(){ local impactPoint = self.GetOrigin() SpawnEntityFromTable("info_particle_system", { origin = impactPoint start_active = 1 effect_name = "rd_robot_explosion_smoke_linger" }) }) }) } }) const MAX_PLAYERS = 10 local NUKE_DONE = false local NUKE_READY = false local PREVIOUS_HP = 98000 local APPLY_AIRBORNE_ATTRS = true local DO_STOMP = false local PHASE_2 = true local PHASE_3 = true local NUKE_WARNING = false local warning = null local warningTime = 0.0 function SetDestroyCallback(entity, callback) { entity.ValidateScriptScope(); local scope = entity.GetScriptScope(); scope.setdelegate({}.setdelegate({ parent = scope.getdelegate() id = entity.GetScriptId() index = entity.entindex() callback = callback _get = function(k) { return parent[k]; } _delslot = function(k) { if (k == id) { entity = EntIndexToHScript(index); local scope = entity.GetScriptScope(); scope.self <- entity; callback.pcall(scope); } delete parent[k]; } }) ); } function DispatchParticleEffectOn(entity, name) { if(entity == null) return if(name == null) { entity.AcceptInput("DispatchEffect", "ParticleEffectStop", null, null); return } local hParticle = CreateByClassname("trigger_particle") hParticle.KeyValueFromString("particle_name", name) hParticle.KeyValueFromInt("attachment_type", 1) hParticle.KeyValueFromInt("spawnflags", 64) hParticle.DispatchSpawn() hParticle.AcceptInput("StartTouch", null, entity, entity) hParticle.Kill() } function DispatchInfoParticleSystem(entity, particle_name, vertical_offset) { local iparticle = SpawnEntityFromTable("info_particle_system", { effect_name = particle_name, targetname = "boss_charged", start_active = 1, origin = entity.GetOrigin() + Vector(0, 0, vertical_offset), angles = Vector(0, 0, 0) }); iparticle.AcceptInput("SetParent", "!activator", entity, entity) } function IsOnGround(bot) { return bot.GetFlags() & FL_ONGROUND } function BossStomp(bot) { ScreenShake(Vector(), 8, 40, 1, 0, 0, true) local StompOrigin = bot.GetOrigin() + Vector(0, 0, 15) local stompBomb = CreateByClassname("tf_generic_bomb") stompBomb.KeyValueFromInt("damage", 300) stompBomb.KeyValueFromInt("radius", 450) stompBomb.KeyValueFromInt("friendlyfire", 0) stompBomb.DispatchSpawn() stompBomb.SetAbsOrigin(StompOrigin) stompBomb.SetTeam(bot.GetTeam()) stompBomb.AcceptInput("Detonate", null, bot, bot) DispatchParticleEffect("hammer_impact_button", StompOrigin, Vector(0, 0, 0)) local StompRadiusSquared = 202500 for (local i = 0, i_max = MaxClients(); i < i_max; i++) { local player = PlayerInstanceFromIndex(i + 1); // 0 is always worldspawn if (player == null) break if (((StompOrigin) - player.GetOrigin()).LengthSqr() < StompRadiusSquared) { player.SetAbsVelocity(Vector(0, 0, 500)) } bot.EmitSound("npc/roller/mine/rmine_explode_shock1.wav") } EntFireByHandle(stompBomb, "Kill", "", 0.1, null, null); } function BossExplode(bot) { ScreenShake(Vector(), 16, 40, 2, 0, 0, true) ScreenShake(Vector(), 16, 40, 3, 0, 0, true) ScreenShake(Vector(), 16, 40, 2, 0, 0, true) local explosionOrigin = bot.GetOrigin() + Vector(0, 0, 15) local explosion = CreateByClassname("tf_generic_bomb") explosion.KeyValueFromInt("damage", 5000) explosion.KeyValueFromInt("radius", 650) explosion.KeyValueFromInt("friendlyfire", 0) //explosion.KeyValueFromString("explode_particle", "fireSmoke_collumnP") explosion.DispatchSpawn() explosion.SetAbsOrigin(explosionOrigin) explosion.SetTeam(bot.GetTeam()) explosion.AcceptInput("Detonate", null, bot, bot) EntFireByHandle(explosion, "Kill", "", 0.5, null, null); DispatchParticleEffect("fireSmoke_collumnP", explosionOrigin, Vector(0, 0, 1)) DispatchParticleEffect("mvm_tank_destroy_smoke", explosionOrigin, Vector(0, 0, 0)) DispatchParticleEffect("mvm_tank_destroy_embers", explosionOrigin, Vector(0, 0, 0)) DispatchParticleEffect("hammer_impact_button", explosionOrigin, Vector(0, 0, 0)) DispatchParticleEffect("hammer_impact_button_dust2", explosionOrigin, Vector(0, 0, 0)) //explosion.Kill() local playersHit = []; local explosionRadiusSquared = 422500; for (local i = 0, i_max = MaxClients(); i < i_max; i++) { local player = PlayerInstanceFromIndex(i + 1); // 0 is always worldspawn if (player == null) break if (((explosionOrigin) - player.GetOrigin()).LengthSqr() < explosionRadiusSquared) { player.AddCondEx(71, 5, bot) player.SetAbsVelocity(Vector(0, 0, 1500)) if (player.GetMaxHealth() > 10000) { player.TakeDamage(15000, DMG_BLAST, self) } } } bot.EmitSound("misc/rd_robot_explosion01.wav") bot.EmitSound("misc/rd_robot_explosion01.wav") NUKE_DONE = true } function phaseTwo(bot) { local weapon = PopExtUtil.GiveWeapon(bot, "tf_weapon_grenadelauncher", 1151) weapon.AddAttribute("faster reload rate", 0.1, -1) weapon.AddAttribute("Blast radius increased", 2.3, -1) weapon.AddAttribute("fire rate penalty HIDDEN", 2.0, -1) weapon.AddAttribute("damage bonus HIDDEN", 6.0, -1) weapon.AddAttribute("clip size upgrade atomic", 4, -1) weapon.AddAttribute("use large smoke explosion", 1, -1) weapon.AddAttribute("override projectile type", 17, -1) local scope = weapon.GetScriptScope() } function phaseThree(bot) { bot.AddCond(113) local weapon = PopExtUtil.GiveWeapon(bot, "tf_weapon_grenadelauncher", 308) weapon.AddAttribute("faster reload rate", -0.5, -1) weapon.AddAttribute("Blast radius increased", 1.3, -1) weapon.AddAttribute("fire rate penalty HIDDEN", 0.4, -1) weapon.AddAttribute("damage bonus HIDDEN", 3.0, -1) weapon.AddAttribute("projectile spread angle penalty", 3, -1) weapon.AddAttribute("clip size upgrade atomic", 4, -1) local scope = weapon.GetScriptScope() } ::DestroyerThink <- function () { local origin = self.GetOrigin() local melee = PopExtUtil.GetItemInSlot(self, 2) local secondary = PopExtUtil.GetItemInSlot(self, 1) local primary = PopExtUtil.GetItemInSlot(self, 0) local manipulator = AI_Bot(self) local maxhp = self.GetMaxHealth() local curHp = self.GetHealth() local eyepos_start = self.EyePosition()+self.EyeAngles().Forward() *100 local eyepos_end = null if (curHp < 48000 && PHASE_2) { phaseTwo(self) PHASE_2 = false } if (curHp < 24000 && PHASE_3) { phaseThree(self) PHASE_3 = false } if (!IsOnGround(self) && APPLY_AIRBORNE_ATTRS) { self.AddCustomAttribute("health regen", 4000, -1) self.AddCustomAttribute("damage bonus", 2.5, -1) APPLY_AIRBORNE_ATTRS = false DO_STOMP = true } else if (IsOnGround(self) && DO_STOMP) { BossStomp(self) self.RemoveCustomAttribute("health regen") APPLY_AIRBORNE_ATTRS = true DO_STOMP = false } if (Time() > nextExplosionTime) { if (!NUKE_READY) { DispatchInfoParticleSystem(self, "utaunt_elebound_purple_parent", 45) DispatchInfoParticleSystem(self, "utaunt_elebound_purple_head4", 55) DispatchInfoParticleSystem(self, "utaunt_elebound_purple_head3", 35) DispatchInfoParticleSystem(self, "utaunt_elebound_purple_glow", 25) DispatchInfoParticleSystem(self, "utaunt_elebound_purple_glow", 35) DispatchInfoParticleSystem(self, "utaunt_elebound_purple_glow", 55) DispatchInfoParticleSystem(self, "ghost_glow", 50) ClientPrint(null, 3, "NUKE READY") self.EmitSound("items/powerup_pickup_strength.wav") self.AddCond(11) self.AddCustomAttribute("CARD: move speed bonus", 0.7, -1) self.AddCustomAttribute("CARD: damage bonus", 2, -1) self.AddCustomAttribute("fire rate bonus HIDDEN", 0.7, -1) self.AddCustomAttribute("dmg from ranged reduced", 0.1, -1) self.AddCustomAttribute("dmg from melee increased", 1.0, -1) NUKE_READY = true NUKE_DONE = false PREVIOUS_HP = curHp } if (!NUKE_DONE && curHp + 1500 < PREVIOUS_HP) { if (!NUKE_WARNING) { warning = SpawnEntityFromTable("prop_dynamic", { model = "models/props_mvm/robot_spawnpoint_warning.mdl", origin = self.GetOrigin() + Vector(0, 0, -100), angles = Vector(0, 0, 0), targetname = "indicator_warn", skin = 3, modelscale = 0.2 }) self.EmitSound("vo/mvm/mght/demoman_mvm_m_autoonfire03.mp3") self.EmitSound("npc/vort/health_charge.wav") self.EmitSound("npc/scanner/cbot_discharge1.wav") self.AddCustomAttribute("gesture speed increase", 0.65, -1) self.Taunt(0,11) local chargeUp = SpawnEntityFromTable("info_particle_system", { effect_name = "charge_up", start_active = 1, origin = self.GetOrigin() + Vector(0, 0, 80), targetname = "charge_up_eff", angles = Vector(0, 0, 0) }); warning.SetModelScale(9, 1) warningTime = Time() + 3.0 NUKE_WARNING = true } else if (Time() > warningTime) { ClientPrint(null, 3, "NUKE DETONATED") BossExplode(self) EntFire("charge_up_eff","Kill") EntFire("boss_charged","Stop") EntFire("boss_charged","Kill") self.EmitSound("vo/mvm/mght/demoman_mvm_m_specialcompleted11.mp3") self.RemoveCond(11) self.RemoveCustomAttribute("CARD: damage bonus") self.RemoveCustomAttribute("CARD: move speed bonus") self.RemoveCustomAttribute("fire rate bonus HIDDEN") self.RemoveCustomAttribute("dmg from ranged reduced") self.RemoveCustomAttribute("dmg from melee increased") self.RemoveCustomAttribute("gesture speed increase") if (warning != null) { warning.Kill() warning = null } nextExplosionTime = Time() + explosionCooldown NUKE_READY = false NUKE_DONE = true NUKE_WARNING = false } } } return -1 } ::DestroyerEnable <- function() { local playerScope = self.GetScriptScope() local wep = PopExtUtil.GetItemInSlot(self, 2) local getwepID = NetProps.GetPropInt(wep, "m_AttributeManager.m_Item.m_iItemDefinitionIndex") if (self != null && self.IsBotOfType(TF_BOT_TYPE)) { self.ValidateScriptScope() if (!("PlayerThinkTable" in self.GetScriptScope())) self.GetScriptScope().PlayerThinkTable <- {} if (self.HasBotTag("bot_destroyer")) { self.ValidateScriptScope(); self.SetCustomModelWithClassAnimations("models/bots/demo_boss/bot_demo_boss_gibby.mdl") playerScope.destroyer_buttons_last <- 0 playerScope.explosionCooldown <- 10 playerScope.nextExplosionTime <- Time() playerScope.nukeWarningTime <- 0 playerScope.serverTime <- 0 // local axe = PopExtUtil.GiveWeapon(self, "tf_weapon_sword", 266) // // local model = CreateByClassname("tf_wearable") //PopExtUtil.CreatePlayerWearable(self, "models/weapons/c_models/c_argent_axe/c_argent_axe.mdl", true, "effect_hand_r", true) // axe.AddAttribute("melee range multiplier", 2.75, -1) // axe.AddAttribute("fire rate penalty", 1.5, -1) // axe.AddAttribute("hand scale", 1.5, -1) PopExtUtil.AddThinkToEnt(self, "DestroyerThink"); } } } //////////////////////////ON GAME EVENTS ::DestroyerEvents <- { function OnGameEvent_player_spawn(params) { local player = GetPlayerFromUserID(params.userid); local playerScope = player.GetScriptScope() local wep = PopExtUtil.GetItemInSlot(player, 2) local getwepID = NetProps.GetPropInt(wep, "m_AttributeManager.m_Item.m_iItemDefinitionIndex") if (player != null && player.IsBotOfType(TF_BOT_TYPE)) { EntFireByHandle(player, "CallScriptFunction", "DestroyerEnable", 0.1, null, null); } } } __CollectGameEventCallbacks(DestroyerEvents);