//Air raid script. //Original written by Pealover: https://steamcommunity.com/id/Pealover/, as seen in Quetzal - Aztec Aeriality (Operation Galvanized Gauntlet) //Rewritten for use on MvM Terrorlict, a map originally by Sntr //Code re-write and map remaster by Seelpit //ent_create point_worldtext targetname testext textsize 40 message 0 rendermode 3 //ent_create logic_timer targetname testimer refiretime 5 //ent_create logic_case targetname testcase //ent_fire testcase AddOutput "OnCase01 testext:SetText:1:0:-1" //ent_fire testcase AddOutput "OnCase02 testext:SetText:2:0:-1" //ent_fire testimer AddOutput "OnTimer testcase:PickRandomShuffle::0:-1" //ent_create math_counter targetname testcount //ent_fire testcount addoutput "outvalue testimer:RefireTime::0:-1" //ent_fire testcount addoutput "outvalue testimer:Enable::0:-1" ::TerrorAir <- { gamerules_entity = Entities.FindByName(null, "gamerules") plane_count = 0 airraid_dmg_mult = 1 airraid_active = false AirRaid_Start = function(iDmgMult) { if (airraid_active) return; EntFireByHandle(gamerules_entity, "PlayVO", "mvm/ambient_mp3/mvm_siren.mp3", 3.0, null, null) // AssignThinkToThinksTable("AirRaid_SpawnPlaneTemplate_Think") for (local i = 1; i <= Constants.Server.MAX_PLAYERS; i++) { local player = PlayerInstanceFromIndex(i) if (player == null) continue; if (IsPlayerABot(player)) continue; EntFireByHandle(player, "SetScriptOverlayMaterial", "airraid_warning_overlay", 0.0, null, null); EntFireByHandle(player, "SetScriptOverlayMaterial", "", 8.0, null, null); } airraid_active = true plane_count = 0 airraid_dmg_mult = iDmgMult } AirRaid_Stop = function() { airraid_active = false } //AirRaid_SpawnPlaneTemplate //Spawns in rocket-shooting planes that follow a path. //TODO: fill in correct vectors, measure good random vec, correct angle AirRaid_SpawnPlaneTemplate = function(sLane) { local vecOrigin = Vector(-3428,0,1400) sLane = sLane.tolower() if (sLane == "left" || sLane == "l") { vecOrigin = Vector(-3428,456,1400) vecOrigin.y = vecOrigin.y + RandomInt(0,400) } else if (sLane == "right" || sLane == "r") { vecOrigin = Vector(-3428,-736,1400) vecOrigin.y = vecOrigin.y + RandomInt(-400,0) } else if (sLane == "mid" || sLane == "m") { vecOrigin = Vector(-3428,-146,1400) vecOrigin.y = vecOrigin.y + RandomInt(-100,100) } else { printl("ERROR: Unknown lane specified for AirRaid_SpawnPlaneTemplate(). Valid values: left, l, right, r, mid, m") return } local plane = SpawnEntityFromTable("prop_dynamic", { targetname = "plane_model_" + plane_count origin = vecOrigin angles = QAngle(10, 0, 0) model = "models/props_frontline/warhawk_animfix.mdl" playbackrate = 1.0 DefaultAnim = "Slow_Spin" body = 1 skin = 3 solid = 0 }) plane_count = plane_count + 1 plane.ValidateScriptScope() AddThinkToEnt(plane, "AirRaid_Plane_Think") } AirRaid_Plane_Think = function() { local scope = self.GetScriptScope() if (!("tick" in scope)) { scope.tick <- 1 scope.height <- self.GetOrigin().z scope.smoke <- SpawnEntityFromTable("info_particle_system", { targetname = "plane_trail_" + plane_count origin = self.GetOrigin(), angles = QAngle(0,180,0), start_active = 0, effect_name = "rockettrail" }) EntFireByHandle(scope.smoke, "SetParent", "!activator", -1.0, self, null) EntFireByHandle(scope.smoke, "Start", "", 0.1, self, null) EntFireByHandle(scope.smoke, "RunScriptCode", "self.SetLocalOrigin(Vector(15,0,15))", 0.1, self, null) scope.sound <- SpawnEntityFromTable("ambient_generic", { health = 10 spawnflags = 0 radius = 15000 pitchstart = 100 pitch = 100 message = "planesound.wav" SourceEntityName = self.GetName() }) scope.weapon <- SpawnEntityFromTable("tf_point_weapon_mimic", { targetname = "plane_gun" origin = self.GetOrigin() + Vector(0,0,-25) angles = self.GetAbsAngles() + QAngle(85,0,0) TeamNum = 3 speedmin = 715 speedmax = 715 WeaponType = 0 SplashRadius = 146 Damage = 90 * airraid_dmg_mult crits = 0 }) EntFireByHandle(scope.weapon, "SetParent", "!activator", -1.0, self, null) scope.weapon.SetOwner(self) } //Movement, different behavior based on x origin. //Default: Move forward 10 units per tick. local vecMovement = Vector(10,0,0) //Special: if middle lane and near clocktower, start moving up. if (self.GetOrigin().x > 2800 && self.GetOrigin().y <= -46 && self.GetOrigin().y >= -246) { vecMovement = Vector(10,0,1 + 0.08 * (self.GetOrigin().z - 1400)) if (self.GetAbsAngles().x >= -45) self.SetAbsAngles(QAngle(self.GetAbsAngles().x, self.GetAbsAngles().y, self.GetAbsAngles().z) + QAngle(-1 * vecMovement.z,0,0)) } self.SetOrigin(Vector(self.GetOrigin().x, self.GetOrigin().y, self.GetOrigin().z) + vecMovement) if (scope.tick % 7 == 0) { for (local player; player = Entities.FindByClassnameWithin(player, "player", self.GetOrigin(), 100.0); ) player.TakeDamage(1000.0, 64, self) ScreenShake(self.GetOrigin(), 16.0, 10.0, 0.5, 1000.0, 0, true) } if (scope.tick % 22 == 0 && self.GetOrigin().x > -2000.0) EntFireByHandle(scope.weapon, "FireOnce", null, -1.0, null, null) //Path "end". if (self.GetOrigin().x > 4000.0 || self.GetOrigin().z > 1700) { EntFireByHandle(scope.sound, "StopSound", null, -1.0, null, null) // local other_planes = false // for (local ent; ent = Entities.FindByModel(ent, self.GetModelName()); ) if (ent != self) other_planes = true // if (!other_planes) // { // RemoveThinkFromThinksTable("AirRaid_BombControl") // HideIcon("plane_lite_blu") // } self.Kill() return 1 } scope.tick = scope.tick + 1 return -1 } } foreach (key, val in TerrorAir) getroottable()[key] <- getroottable()["TerrorAir"][key] // __CollectGameEventCallbacks(TerrorAir.GLOBAL_CALLBACKS)