::PEA_GLOBAL <- { strip_romevision_items = false gamerules_entity = Entities.FindByName(null, "gamerules") objective_resource_entity = Entities.FindByClassname(null, "tf_objective_resource") mission = NetProps.GetPropString(Entities.FindByClassname(null, "tf_objective_resource"), "m_iszMvMPopfileName") GLOBAL_CALLBACKS = { OnGameEvent_recalculate_holidays = function(params) // do cleanup after mission switch { if ("MapCleanup" in PEA) ::MapCleanup() if (GetRoundState() == 3 && NetProps.GetPropString(objective_resource_entity, "m_iszMvMPopfileName") != mission) { foreach (thing, var in PEA) if (thing in getroottable()) delete getroottable()[thing] for (local i = 1; i <= Constants.Server.MAX_PLAYERS; i++) { local player = PlayerInstanceFromIndex(i) if (player == null) continue if (player.GetScriptScope() != null) { foreach (thing in player.GetScriptScope()) { try { thing.GetClassname() } catch (e) { continue } if (!thing.IsPlayer()) thing.Kill() } } player.TerminateScriptScope() } delete ::PEA } } OnGameEvent_player_spawn = function(params) { local bot = GetPlayerFromUserID(params.userid); if (bot.IsFakeClient()) { EntFireByHandle(bot, "CallScriptFunction", "GlobalBotTagCheck", -1.0, null, null) if (strip_romevision_items) for (local child = bot.FirstMoveChild(); child != null; child = child.NextMovePeer()) if (child.GetClassname() == "tf_wearable" && child.GetModelName().find("tw_") != null) EntFireByHandle(child, "Kill", null, -1.0, null, null) } } OnGameEvent_player_death = function(params) { local dead_player = GetPlayerFromUserID(params.userid) if (dead_player.IsFakeClient()) { for (local cash; cash = Entities.FindByClassname(cash, "item_currencypack_custom"); ) AddThinkToEnt(cash, "ImprovedCashCollection_Think") local projectiles_leftbehind = false for (local ent; ent = Entities.FindByClassname(ent, "tf_projectile_*"); ) { if (ent.GetOwner() == dead_player || NetProps.GetPropEntity(ent, "m_hThrower") == dead_player) { projectiles_leftbehind = true; break } } if (!projectiles_leftbehind) EntFireByHandle(dead_player, "RunScriptCode", "self.ForceChangeTeam(1, true)", -1.0, null, null) } } } ImprovedCashCollection_Think = function() { try // tends to throw harmless errors about collecting player becoming null { for (local player_to_collect; player_to_collect = Entities.FindByClassnameWithin(player_to_collect, "player", self.GetOrigin(), 288); ) { if (player_to_collect != null && player_to_collect.GetTeam() == 2 && !player_to_collect.IsFakeClient() && NetProps.GetPropInt(player_to_collect, "m_lifeState") == 0 && NetProps.GetPropInt(player_to_collect, "m_PlayerClass") == Constants.ETFClass.TF_CLASS_SCOUT) { self.Teleport(true, player_to_collect.GetOrigin(), false, QAngle(0, 0, 0), false, Vector(0, 0, 0)) self.DisableDraw() return 1 // stop reiterating after the teleport } } } catch (e) { return } return -1 } DisableRomevision = function(change_carrier = true, change_bots = false) { if (change_carrier) { for (local ent; ent = Entities.FindByModel(ent, "models/bots/boss_bot/carrier.mdl"); ) { NetProps.SetPropIntArray(ent, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/carrier.mdl"), 0) NetProps.SetPropIntArray(ent, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/carrier.mdl"), 1) NetProps.SetPropIntArray(ent, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/carrier.mdl"), 2) NetProps.SetPropIntArray(ent, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/carrier.mdl"), 3) } for (local ent; ent = Entities.FindByModel(ent, "models/bots/boss_bot/carrier_parts.mdl"); ) { NetProps.SetPropIntArray(ent, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/carrier_parts.mdl"), 0) NetProps.SetPropIntArray(ent, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/carrier_parts.mdl"), 1) NetProps.SetPropIntArray(ent, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/carrier_parts.mdl"), 2) NetProps.SetPropIntArray(ent, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/carrier_parts.mdl"), 3) } } if (change_bots) strip_romevision_items = true } GlobalBotTagCheck = function() { if (self.HasBotTag("disband_squad")) self.DisbandCurrentSquad() } BlimpFinder_Think = function() { for (local blimp; blimp = Entities.FindByName(blimp, "blimpboss"); ) { if (blimp.GetScriptScope() != null) continue else SetUpBlimp(blimp) } } InstantReady_Think = function() { if (!countdown_skipped && NetProps.GetPropBoolArray(gamerules_entity, "m_bPlayerReady", 1)) { NetProps.SetPropFloat(gamerules_entity, "m_flRestartRoundTime", Time()) countdown_skipped = true } } ThinksTable = {} GlobalThinker = function() { local scope = self.GetScriptScope() if (!("tick" in scope)) scope.tick <- 1 foreach (func in ThinksTable) func() scope.tick <- scope.tick + 1 return -1 } AssignThinkToThinksTable = function(think) { getroottable()["ThinksTable"][think] <- getroottable()[think] delete getroottable()[think] } SetUpBlimp = function(blimp) { NetProps.SetPropIntArray(blimp, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp.mdl"), 0) NetProps.SetPropIntArray(blimp, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp.mdl"), 1) NetProps.SetPropIntArray(blimp, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp.mdl"), 2) NetProps.SetPropIntArray(blimp, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp.mdl"), 3) local child_array = [] for (local child = blimp.FirstMoveChild(); child != null; child = child.NextMovePeer()) child_array.append(child) foreach (child in child_array) child.Kill() blimp.SetSkin(1) local train = SpawnEntityFromTable("func_tracktrain", { targetname = "blimp_train" target = "blimp_path1" startspeed = blimp_speed speed = blimp_speed origin = Entities.FindByName(null, "blimp_path1").GetOrigin() orientationtype = 1 spawnflags = 136 volume = 10 model = "*2" rendermode = 1 renderamt = 0 solid = 0 }) train.ValidateScriptScope() train.GetScriptScope().parented_blimp <- blimp blimp.ValidateScriptScope() blimp.GetScriptScope().pathtrain <- train blimp.SetModelScale(("blimp_scale" in PEA) ? blimp_scale : 1, -1) AddThinkToEnt(blimp, "Blimp_Think") } CleanUpBlimp = function() { RemoveBlimpIcon() for (local train; train = Entities.FindByName(train, "blimp_train"); ) if (!train.GetScriptScope().parented_blimp.IsValid()) train.Kill() for (local cash; cash = Entities.FindByClassname(cash, "item_currencypack_custom"); ) AddThinkToEnt(cash, "ImprovedCashCollection_Think") } Blimp_Think = function() { local scope = self.GetScriptScope() if (!("tick" in scope)) { PrecacheSound("npc/combine_gunship/ping_search.wav") scope.tick <- 1 scope.model <- self.GetModelName() scope.Deploy_Bomb_1 <- function() { self.ResetSequence(1) self.SetCycle(0) EntFire("!self", "CallScriptFunction", "Deploy_Bomb_2", 8.0) EmitSoundEx( { sound_name = "MVM.TankDeploy", filter = 5, entity = self, volume = 1, soundlevel = 150, flags = 1, channel = 6 }) } scope.Deploy_Bomb_2 <- function() { if (self == null) return switch (GetMapName()) { case "mvm_hanami_rc1": { EntFire("win_bots", "RoundWin") EntFire("hatch_destroy_relay", "Trigger") break } case "mvm_null_b9a": { soldier_statue.Kill() EntFire("bots_win", "RoundWin") EntFire("end_pit_destroy_particle", "Start") EntFire("pit_explosion_wav", "PlaySound") EntFire("hatch_explo_kill_players", "Enable") EntFire("hatch_explo_kill_players", "Disable", null, 0.5) EntFire("hatch_magnet_pit", "Enable") EntFire("trigger_hurt_hatch_fire", "Enable") break } } } } self.SetOrigin(scope.pathtrain.GetOrigin()) self.SetAbsAngles(QAngle(0, scope.pathtrain.GetAbsAngles().y, 0)) self.GetLocomotionInterface().Reset() if (scope.model != self.GetModelName()) { if (self.GetModelName() == "models/bots/boss_bot/boss_tank_damage1.mdl") { NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage1.mdl"), 0) NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage1.mdl"), 1) NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage1.mdl"), 2) NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage1.mdl"), 3) } if (self.GetModelName() == "models/bots/boss_bot/boss_tank_damage2.mdl") { NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage2.mdl"), 0) NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage2.mdl"), 1) NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage2.mdl"), 2) NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage2.mdl"), 3) } if (self.GetModelName() == "models/bots/boss_bot/boss_tank_damage3.mdl") { NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage3.mdl"), 0) NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage3.mdl"), 1) NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage3.mdl"), 2) NetProps.SetPropIntArray(self, "m_nModelIndexOverrides", PrecacheModel("models/bots/boss_bot/boss_blimp_damage3.mdl"), 3) } } EmitSoundEx( { sound_name = "MVM.TankPing", filter = 5, entity = self, volume = 1, soundlevel = 150, flags = 4, channel = 6 }) EmitSoundEx( { sound_name = "MVM.TankEngineLoop", filter = 5, entity = self, volume = 1, soundlevel = 150, flags = 4, channel = 6 }) if (scope.tick % 333 == 0) { EmitSoundEx( { sound_name = "npc/combine_gunship/ping_search.wav", filter = 5, entity = self, volume = 1, soundlevel = 150, flags = 1, channel = 6 }) } scope.tick = scope.tick + 1 return -1 } } if (!("PEA" in getroottable())) ::PEA <- {} foreach (thing, var in PEA_GLOBAL) getroottable()["PEA"][thing] <- getroottable()["PEA_GLOBAL"][thing] foreach (thing, var in PEA) getroottable()[thing] <- getroottable()["PEA"][thing] delete ::PEA_GLOBAL if ("SetUpBlimpPath" in PEA) ::SetUpBlimpPath() for (local ent; ent = Entities.FindByName(ent, "blimp_path*"); ) if (NetProps.GetPropEntity(ent, "m_pnext") == null) EntityOutputs.AddOutput(ent, "OnPass", "!activator", "RunScriptCode", "self.GetScriptScope().parented_blimp.GetScriptScope().Deploy_Bomb_1()", -1.0, -1.0) switch (GetMapName()) { case "mvm_hanami_rc1": AssignThinkToThinksTable("BlimpFinder_Think"); break case "mvm_null_b9a": AssignThinkToThinksTable("BlimpFinder_Think"); break case "mvm_quetzal_rc5": AssignThinkToThinksTable("BlimpFinder_Think"); break case "mvm_hoovydam_b10": DisableRomevision(); EntFire("initMain_roadside", "Trigger"); break case "mvm_derelict_rc2": DisableRomevision(); break case "mvm_sequoia_rc4": DisableRomevision(); break case "mvm_decay_rc1": DisableRomevision(true, true); break } if (debug) { PEA["countdown_skipped"] <- false getroottable()["countdown_skipped"] <- PEA["countdown_skipped"] AssignThinkToThinksTable("InstantReady_Think") } if ("CALLBACKS" in PEA) __CollectGameEventCallbacks(PEA.CALLBACKS) __CollectGameEventCallbacks(PEA.GLOBAL_CALLBACKS) AddThinkToEnt(gamerules_entity, "GlobalThinker")