::CONST <- getconsttable() ::ROOT <- getroottable() ::MAX_CLIENTS <- MaxClients().tointeger() IncludeScript("alternatewaves", getroottable()) PrecacheSound("ptx/other/player_dash2_0.wav") PrecacheSound("ptx/other/player_dash2_1.wav") PrecacheSound("ptx/other/player_dash2_4.wav") PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "eb_projectile_core02"}) local PlayerManager = FindByClassname(null, "tf_player_manager") local hGameRules = FindByClassname(null, "tf_gamerules") if (!("ConstantNamingConvention" in ROOT)) foreach (a,b in Constants) foreach (k,v in b) { CONST[k] <- v != null ? v : 0 ROOT[k] <- v != null ? v : 0 } foreach(k, v in ::Entities.getclass()) if (k != "IsValid" && !(k in ROOT)) ROOT[k] <- ::Entitiesndenv(::Entities) foreach(k, v in ::NetProps.getclass()) if (k != "IsValid" && !(k in ROOT)) ROOT[k] <- ::NetProps[k].bindenv(::NetProps) local OTHER_CONSTANTS = { MASK_ALL = -1 MASK_SPLITAREAPORTAL = 48 MASK_SOLID_BRUSHONLY = 16395 MASK_WATER = 16432 MASK_BLOCKLOS = 16449 MASK_OPAQUE = 16513 MASK_DEADSOLID = 65547 MASK_PLAYERSOLID_BRUSHONLY = 81931 MASK_NPCWORLDSTTIC = 131083 MASK_NPCSOLID_BRUSHONLY = 147467 MASK_CURRENT = 16515072 MASK_SHOT_PORTAL = 33570819 MASK_SOLID = 33570827 MASK_BLOCKLOS_AND_NPCS = 33570881 MASK_OPAQUE_AND_NPCS = 33570945 MASK_VISIBLE_AND_NPCS = 33579137 MASK_PLAYERSOLID = 33636363 MASK_NPCSOLID = 33701899 MASK_SHOT_HULL = 100679691 MASK_SHOT = 1174421507 TF_STUN_NONE = 0 TF_STUN_MOVEMENT = 1 TF_STUN_CONTROLS = 2 TF_STUN_MOVEMENT_FORWARD_ONLY = 4 TF_STUN_SPECIAL_SOUND = 8 TF_STUN_DODGE_COOLDOWN = 16 TF_STUN_NO_EFFECTS = 32 TF_STUN_LOSER_STATE = 64 TF_STUN_BY_TRIGGER = 128 TF_STUN_SOUND = 256 SND_NOFLAGS = 0 SND_CHANGE_VOL = 1 SND_CHANGE_PITCH = 2 SND_STOP = 4 SND_SPAWNING = 8 SND_DELAY = 16 SND_STOP_LOOPING = 32 SND_SPEAKER = 64 SND_SHOULDPAUSE = 128 SND_IGNORE_PHONEMES = 256 SND_IGNORE_NAME = 512 SND_DO_NOT_OVERWRITE_EXISTING_ON_CHANNEL = 1024 // damagefilter redefinitions DMG_USE_HITLOCATIONS = DMG_AIRBOAT DMG_HALF_FALLOFF = DMG_RADIATION DMG_CRITICAL = DMG_ACID DMG_RADIUS_MAX = DMG_ENERGYBEAM DMG_IGNITE = DMG_PLASMA DMG_USEDISTANCEMOD = DMG_SLOWBURN DMG_NOCLOSEDISTANCEMOD = DMG_POISON DMG_MELEE = DMG_BLAST_SURFACE DMG_DONT_COUNT_DAMAGE_TOWARDS_CRIT_RATE = DMG_DISSOLVE } PrecacheSound("#ptx/ost/cultist_base.mp3") PrecacheSound("#ptx/ost/break_music.mp3") PrecacheSound("#ptx/ost/mars_core_ambient.mp3") PrecacheSound("#ptx/ost/hell_on_earth.mp3") PrecacheSound("#ptx/ost/reclaimed_earth.mp3") PrecacheSound("#ptx/ost/bfg_division_2020.mp3") PrecacheSound("#ptx/ost/transitions/transition_1.wav") PrecacheSound("#ptx/ost/transitions/transition_2_long.wav") local Classes = ["", "scout", "sniper", "soldier", "demo", "medic", "heavy", "pyro", "spy", "engineer", "civilian"] local MUSIC_LIST = [ "#ptx/ost/cultist_base.mp3| Cultist Base - Mick Gordon", "#ptx/ost/mars_core_ambient.mp3| Mars Core - Phobos - Mick Gordon", "#ptx/ost/hell_on_earth.mp3| Hell on Earth - Mick Gordon", "#ptx/ost/bfg_division_2020.mp3| BFG Division 2020 - Mick Gordon", "#ptx/ost/reclaimed_earth.mp3| Reclaimed Earth - Andrew Hulshult", "#ptx/ost/break_music.mp3| Hell on Earth - Mick Gordon" ] local TORNADO_PARTICLE_DISTRIBUTION = [ "lava_fireball", "lava_fireball_01", "lava_fireball_02", ] local MaxAmmoTable = { [TF_CLASS_SCOUT] = { ["tf_weapon_scattergun"] = 32, ["tf_weapon_handgun_scout_primary"] = 32, ["tf_weapon_soda_popper"] = 32, ["tf_weapon_pep_brawler_blaster"] = 32, ["tf_weapon_handgun_scout_secondary"] = 36, ["tf_weapon_pistol"] = 36, }, [TF_CLASS_SOLDIER] = { ["tf_weapon_rocketlauncher"] = 20, ["tf_weapon_rocketlauncher_directhit"] = 20, ["tf_weapon_rocketlauncher_airstrike"] = 20, [237] = 60, ["tf_weapon_shotgun_soldier"] = 32, ["tf_weapon_shotgun"] = 32, }, [TF_CLASS_PYRO] = { ["tf_weapon_flamethrower"] = 200, ["tf_weapon_rocketlauncher_fireball"] = 40, ["tf_weapon_shotgun_pyro"] = 32, ["tf_weapon_shotgun"] = 32, ["tf_weapon_flaregun"] = 16, }, [TF_CLASS_DEMOMAN] = { ["tf_weapon_grenadelauncher"] = 16, ["tf_weapon_cannon"] = 16, ["tf_weapon_pipebomblauncher"] = 24, [265] = 72, }, [TF_CLASS_HEAVYWEAPONS] = { ["tf_weapon_minigun"] = 200, ["tf_weapon_shotgun_hwg"] = 32, ["tf_weapon_shotgun"] = 32, }, [TF_CLASS_ENGINEER] = { ["tf_weapon_shotgun"] = 32, ["tf_weapon_sentry_revenge"] = 32, ["tf_weapon_shotgun_building_rescue"] = 16, [9] = 32, ["tf_weapon_pistol"] = 200, }, [TF_CLASS_MEDIC] = { ["tf_weapon_syringegun_medic"] = 150, ["tf_weapon_crossbow"] = 38, }, [TF_CLASS_SNIPER] = { ["tf_weapon_sniperrifle"] = 25, ["tf_weapon_sniperrifle_decap"] = 25, ["tf_weapon_sniperrifle_classic"] = 25, ["tf_weapon_compound_bow"] = 12, ["tf_weapon_smg"] = 75, ["tf_weapon_charged_smg"] = 75, }, [TF_CLASS_SPY] = { ["tf_weapon_revolver"] = 24, }, } local telePoints_NORMAL = [ Vector(-289, -124, 26), Vector(-434, 87, 26), Vector(-443, 301, 26), Vector(-576, -301, 26), Vector(-758, -93, 26), Vector(-896, -576, 26), Vector(-1183, 527, 195), Vector(-819, 709, 285), Vector(-585, 651, 284), Vector(-802, 984, 291), Vector(-592, 961, 286), Vector(-1344, 165, 195), Vector(-1409, -150, 237), Vector(-1498, -525, 237), Vector(-1508, -925, 237), Vector(-944, -947, 280), Vector(-569, -821, 301), Vector(-961, -980, 46), Vector(-937, -1350, 45), Vector(-581, -1478, 49), Vector(-1283, -1878, 225), Vector(-1240, -2417, 225), Vector(-892, -2214, 54), Vector(-880, -1803, 32), Vector(-679, -2652, 65), Vector(-306, -1972, -27), Vector(-202, -2603, 65), Vector(27, -2951, 97), Vector(-133, -1497, 64), Vector(421, -1942, -3), Vector(293, -1453, 50), Vector(531, -2614, 38), Vector(893, -2533, 33), Vector(856, -2225, 33), Vector(844, -1821, 33), Vector(1403, -2456, 104), Vector(1404, -1888, 40), Vector(1392, -2054, 232), Vector(1425, -1723, 232), Vector(954, -1151, 232), Vector(1278, -1159, 232), Vector(1171, -596, 168), Vector(1180, -219, 168), Vector(774, -1167, 40), Vector(659, -497, 40), Vector(840, -69, 45), Vector(658, 24, 40), Vector(912, 386, 104), Vector(576, 346, 104), Vector(163, 1, 40), Vector(-83, 26, 90), Vector(-120, 458, 84), Vector(-172, 821, 70), Vector(165, 859, 90), Vector(-140, 1161, 26), Vector(451, 1450, 186), Vector(-80, 1522, 4), Vector(274, 1843, -4), Vector(245, 2182, -6), Vector(-125, 2121, -6), Vector(-702, 1975, 49) ]; // 16 for giants local telePoints_BIG = [ Vector(160, 224, 40), Vector(-128, 96, 40), Vector(-640, 64, 40), Vector(-960, -320, 40), Vector(-960, -864, 41), Vector(-960, -1120, 40), Vector(-768, -1504, 40), Vector(-352, -1504, 60), Vector(96, -1536, 70), Vector(512, -1376, 40), Vector(672, -1024, 40), Vector(672, -672, 40), Vector(704, -352, 40), Vector(512, -64, 40), Vector(160, -800, 40), Vector(-1504, -704, 232), Vector(-1216, -2176, 232), Vector(128, -416, 296), Vector(1312, -1536, 232), Vector(768, -1984, 40), Vector(1280, -2720, 40), Vector(224, -2400, 72), Vector(-512, -2208, -12) ]; // 6 GIGA local telePoints_GIGA = [ Vector(-27,884, -60), Vector(-223, 154, 36), Vector(-1486, -325, 228), Vector(184, -1974, -28), Vector(-36, -2581, 68), Vector(802, -1482, 36) ]; local takenTelePoints_NORMAL = []; for (local i = 0; i < telePoints_NORMAL.len(); i++) { takenTelePoints_NORMAL.append(null); } local takenTelePoints_BIG = []; for (local i = 0; i < telePoints_BIG.len(); i++) { takenTelePoints_BIG.append(null); } local takenTelePoints_GIGA = []; for (local i = 0; i < telePoints_GIGA.len(); i++) { takenTelePoints_GIGA.append(null); } function PickRandomItem(table) { if (table == null || table.len() == 0) { return null } local randomIndex = RandomInt(0, table.len() - 1) return table[randomIndex] } function findElement(array, value) { for (local i = 0; i < array.len(); i++) { if (array[i] == value) { return i; } } return -1; } function formatWithLeadingZeros(num, digits) { local str = num.tostring(); while (str.len() < digits) { str = "0" + str; } return str; } function Round(num, decimals=0) { if (decimals <= 0) return floor(num + 0.5) local mod = pow(10, decimals) return floor((num * mod) + 0.5) / mod } function GetItemInSlot(player, slot) { local item for (local i = 0; i < 7; i++) { local wep = GetPropEntityArray(player, "m_hMyWeapons", i) if ( wep == null || wep.GetSlot() != slot) continue item = wep break } return item } function GetItemIndex(item) { return GetPropInt(item, "m_AttributeManager.m_Item.m_iItemDefinitionIndex") } function GetWeaponMaxAmmo(player, wep) { if (wep == null) return local slot = wep.GetSlot() local classname = wep.GetClassname() local itemid = GetItemIndex(wep) local table = MaxAmmoTable[player.GetPlayerClass()] if (!(itemid in table) && !(classname in table)) return -1 local base_max = (itemid in table) ? table[itemid] : table[classname] return base_max } function GetPlayerUserID(player) { return GetPropIntArray(PlayerManager, "m_iUserID", player.entindex()) } function clamp(value, min, max) { if (value < min) return min; if (value > max) return max; return value; } foreach(k,v in OTHER_CONSTANTS) if(!(k in ROOT)) { CONST[k] <- v ROOT[k] <- v } ::HellOnEarth <- { WAVE_ACTIVE = false MAIN_WAVE_ACTIVE = false RED_PLAYERS = true BOTS_PEACEFUL = false TOTAL_TEAM_POINTS = 1 CURR_RANK_IMAGE = -1 TEAM_WIPE_ACTIVE = false hThinkEnt = SpawnEntityFromTable("logic_relay", {}) function CreateExplosion(_vecLocation, _flDmg, _flRange, _hInflictor, _flForceMultiplier = 0.0, _flUpwardForce = 0.0, _iTeamnum = TF_TEAM_RED) { ScreenShake ( _vecLocation, 5000, 5000, 4, 350, 0, true ); if ( _hInflictor.IsPlayer() ) { _hInflictor.SetHealth( 1 ); } local _hBomb = SpawnEntityFromTable( "tf_generic_bomb", { explode_particle = "rd_robot_explosion", sound = "ambient/explosions/explode_8.wav", damage = _flDmg.tostring(), radius = _flRange.tostring(), friendlyfire = "0", }); local _hPfxEnt = SpawnEntityFromTable( "info_particle_system", { effect_name = FX_DEMOGUTS, start_active = "0", targetname = "Explosion_PFX_Ent", origin = _vecLocation, }); _hPfxEnt.ValidateScriptScope(); _hPfxEnt.GetScriptScope ().m_flKillTime <- ( Time() + 2.0 ).tofloat(); AddThinkToEnt( _hPfxEnt, "KillMeThink" ); _hBomb.ValidateScriptScope(); _hBomb.GetScriptScope ().m_flKillTime <- ( Time() + 0.1 ).tofloat(); _hBomb.GetScriptScope ().m_hOwner <- _hInflictor; _hPfxEnt.DispatchSpawn(); EntFireByHandle ( _hPfxEnt, "Start", "", -1, null, null ) SetPropInt ( _hBomb, "m_iTeamNum", _iTeamnum ); EmitSoundOn ( "Breakable.MatFlesh", _hBomb ); EmitSoundOn ( "Halloween.Merasmus_Hiding_Explode", _hBomb ); _hBomb.DispatchSpawn(); _hBomb.SetTeam ( _iTeamnum ); _hBomb.SetOrigin ( _vecLocation ); _hBomb.SetOwner ( _hInflictor ); _hBomb.KeyValueFromString( "classname", KILLICON_DEMOMAN_BOOM ); _hBomb.TakeDamage(1, DMG_CLUB, _hInflictor) _hInflictor.TakeDamage(1, DMG_NEVERGIB, _hInflictor) return; } function AddTeamPoints(amount) { PrecacheSound("#ptx/cinematic/death_stinger_mp.wav"); PrecacheSound("#ptx/misc/demonic_spawn.wav") if (TOTAL_TEAM_POINTS + amount < 0) return; local prev = TOTAL_TEAM_POINTS; TOTAL_TEAM_POINTS += amount; local message local newImage = 0 local threshold = 0 local maxPoints = 9999 if (TOTAL_TEAM_POINTS > maxPoints) { TOTAL_TEAM_POINTS = maxPoints; threshold = 0; message = "Ultra Nightmare" newImage = 4; } else if (TOTAL_TEAM_POINTS > 5000) { threshold = 9999; message = "Nightmare" newImage = 3; } else if (TOTAL_TEAM_POINTS > 1000) { threshold = 5000; message = "Ultra Violence" newImage = 2; } else if (TOTAL_TEAM_POINTS > 100) { threshold = 1000; message = "Hurt Me Plenty" newImage = 1 } else { threshold = 100; message = "Too Young To Die" newImage = 0; } if (newImage == CURR_RANK_IMAGE) return; CURR_RANK_IMAGE = newImage; HellOnEarth.ShowDiffImage(newImage); ClientPrint(null, 4, "Current Rank: " + message + ", Points: " + TOTAL_TEAM_POINTS.tostring()) playSoundToEveryone(amount > 0 ? "#ptx/cinematic/death_stinger_mp.wav" : "#ptx/misc/demonic_spawn.wav") } function CreatePointThink() { local hPoints = SpawnEntityFromTable("logic_script", {}) hPoints.ValidateScriptScope() local hPoints_scope = hPoints.GetScriptScope() hPoints_scope.curPoints <- HellOnEarth.TOTAL_TEAM_POINTS hPoints_scope.threshold <- 100 hPoints_scope.lastDisplayTime <- Time() hPoints_scope.hText <- SpawnEntityFromTable("game_text", { spawnflags = 1, channel = 4, holdtime = 1, color = "144 238 144" x = 0.28 y = 0.77 }); hPoints_scope.Think <- function () { if (HellOnEarth.TOTAL_TEAM_POINTS != curPoints) { if (HellOnEarth.TOTAL_TEAM_POINTS > 9999) { HellOnEarth.TOTAL_TEAM_POINTS = 9999; threshold = 0; } else if (HellOnEarth.TOTAL_TEAM_POINTS > 5000) { threshold = 9999; } else if (HellOnEarth.TOTAL_TEAM_POINTS > 1000) { threshold = 5000; } else if (HellOnEarth.TOTAL_TEAM_POINTS > 100) { threshold = 1000; } else { threshold = 100; } local formattedPoints = formatWithLeadingZeros(HellOnEarth.TOTAL_TEAM_POINTS, 4); local formattedThreshold = threshold > 0 ? formatWithLeadingZeros(threshold, 4) : ""; local displayText = formattedPoints + (threshold > 0 ? "/" + formattedThreshold : ""); if (HellOnEarth.TOTAL_TEAM_POINTS == 9999) hText.AcceptInput("SetPosX", "0.3", null, null) else hText.AcceptInput("SetPosX", "0.28", null, null) SetPropString(hText, "m_iszMessage", displayText) } if (Time() - lastDisplayTime >= 1 || HellOnEarth.TOTAL_TEAM_POINTS != curPoints) { hText.AcceptInput("Display", null, null, null) lastDisplayTime = Time() } return -1 } AddThinkToEnt(hPoints, "Think") } function GetBotKillDuration(health) { return health >= 10000 ? 45.0 : health <= 500 ? 10.0 : 10.0 + (35.0 * log10(1 + ((health - 200) / 9800) * 9)); } function CalculateRewardPoints(maxHP) { return maxHP > 6000 ? 500 : 10 + (490 * pow(maxHP / 6000, 2)); } function TimedPointRobot(hPlayer) { PrecacheSound("#ptx/other/armor_pickup.wav") HellOnEarth.playSoundFromEntity(hPlayer, "#ptx/other/armor_pickup.wav", 1750) local hTimedScript = SpawnEntityFromTable("logic_script", {}) local PointGlow = SpawnEntityFromTable("info_particle_system", { origin = hPlayer.GetCenter() effect_name = "superrare_beams1" start_active = 1 }) PointGlow.AcceptInput("SetParent", "!activator", hPlayer, null) hTimedScript.ValidateScriptScope() local hTimedScript_scope = hTimedScript.GetScriptScope() local pointsToReceive = CalculateRewardPoints(hPlayer.GetMaxHealth()) ACCUMULATED_POINTS += pointsToReceive hTimedScript_scope.timeRemaining <- GetBotKillDuration(hPlayer.GetMaxHealth()) hTimedScript_scope.timeStart <- 0; hTimedScript_scope.pointsGained <- pointsToReceive hTimedScript_scope.hGlow <- SpawnEntityFromTable("tf_glow", { GlowColor = "0 255 0 255", target = "bignet", Mode = "0", StartDisabled = "1" }); SetPropEntity(hTimedScript_scope.hGlow, "m_hTarget", hPlayer) hTimedScript_scope.hGlow.AcceptInput("Enable", null, null, null) hTimedScript_scope.Think <- function () { local elapsed = timeStart ? (Time() - timeStart) : 0; if (elapsed == 0) { timeStart <- Time() elapsed = 0 } local duration = timeRemaining if (elapsed >= duration) { hGlow.AcceptInput("Disable", null, null, null) hGlow.Kill() NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") EntFireByHandle(PointGlow, "Stop", null, 0, null, null) PointGlow.Kill() return -1 } if (!hPlayer.IsAlive()) { PrecacheSound("Player.ReceiveSouls") hGlow.AcceptInput("Disable", null, null, null) hGlow.Kill() NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") HellOnEarth.playSoundToEveryone("Player.ReceiveSouls") HellOnEarth.AddTeamPoints(floor(pointsGained * (1 - (elapsed / duration)))) EntFireByHandle(PointGlow, "Stop", null, 0, null, null) PointGlow.Kill() return -1 } local progress = elapsed / duration; local r, g, b if (progress <= 0.5) { r = floor(255 * (progress / 0.5)) g = 255 b = 0 } else { r = 255 g = floor(255 * (1.0 - (progress - 0.5) / 0.5)) b = 0 } local newColor = r.tostring() + " " + g.tostring() + " " + b.tostring() + " 255" hGlow.AcceptInput("SetGlowColor", newColor, null, null) return -1 } AddThinkToEnt(hTimedScript, "Think") } function TimedBotSetup(hEntity) { if (RandomFloat(0, 1) < 0.1) { local delay = 4 if (hEntity.HasBotTag("robot_posessed") || hEntity.GetMaxHealth() > 4000) { delay = 5 } EntFireByHandle(hEntity, "runscriptcode", "HellOnEarth.TimedPointRobot(self)", delay, null, null) } } function BotTagsAndAttrs(hPlayer) { if (!hPlayer || !hPlayer.IsFakeClient()) return if (hPlayer.HasBotTag("bot_vip")) { hPlayer.ValidateScriptScope() local hPlayer_scope = hPlayer.GetScriptScope() hPlayer_scope.Think <- function () { HellOnEarth.AddTeamPoints(1) return 1 } AddThinkToEnt(hPlayer, "Think") } if (hPlayer.HasBotTag("bot_heavy")) { local class_str = Classes[hPlayer.GetPlayerClass()] EntFireByHandle(hPlayer, "SetCustomModelWithClassAnimations", format("models/player/%s.mdl", class_str), 0, null, null) EntFireByHandle(hPlayer, "RunScriptCode", format("HellOnEarth.PlayerRobotModel(self, `models/bots/heavy_boss/bot_heavy_boss_gibby.mdl`)", class_str, class_str), 0, null, null) } } function PlayerRobotModel(player, model) { player.ValidateScriptScope() local scope = player.GetScriptScope() local wearable = CreateByClassname("tf_wearable") SetPropInt(player, "m_nForcedSkin", 4) SetPropBool(player, "m_bForcedSkin", true) SetPropString(wearable, "m_iName", "__bot_bonemerge_model") SetPropInt(wearable, "m_nModelIndex", PrecacheModel(model)) SetPropBool(wearable, "m_bValidatedAttachedEntity", true) SetPropBool(wearable, "m_AttributeManager.m_Item.m_iItemDefinitionIndex", true) SetPropEntity(wearable, "m_hOwnerEntity", player) wearable.SetTeam(player.GetTeam()) wearable.SetOwner(player) DispatchSpawn(wearable) EntFireByHandle(wearable, "SetParent", "!activator", -1, player, player) SetPropInt(wearable, "m_fEffects", EF_BONEMERGE|EF_BONEMERGE_FASTCULL) scope.wearable <- wearable SetPropInt(player, "m_nRenderMode", kRenderTransColor) SetPropInt(player, "m_clrRender", 0) scope.PlayerThinkTable.BotModelThink <- function() { if (wearable.IsValid() && (player.IsTaunting() || wearable.GetMoveParent() != player)) EntFireByHandle(wearable, "SetParent", "!activator", -1, player, player) return -1 } } function playSoundFromEntity(hEntity, soundname, huRange = 99999) { local hEnt = hEntity; if (typeof(hEntity) == "string") { hEnt = Entities.FindByName(null, hEntity) } local snd_lvl = (40 + (20 * log10(huRange / 36))).tointeger() PrecacheSound(soundname) EmitSoundEx({ sound_name = soundname entity = hEnt volume = 1 sound_level = snd_lvl filter_type = RECIPIENT_FILTER_GLOBAL }) } function killSoundFromEntity(hEntity, soundname) { local hEnt = hEntity; if (typeof(hEntity) == "string") { hEnt = Entities.FindByName(null, hEntity) } local snd_lvl = (40 + (20 * log10(99999 / 36))).tointeger() PrecacheSound(soundname) EmitSoundEx({ sound_name = soundname entity = hEnt volume = 1 sound_level = snd_lvl flags = SND_STOP filter_type = RECIPIENT_FILTER_GLOBAL }) } function playSoundToEveryone(sfx) { for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(!hPlayer || hPlayer.IsFakeClient()) continue PrecacheSound("#" + sfx) EmitSoundEx({ sound_name = "#" + sfx volume = 1 entity = hPlayer filter_type = RECIPIENT_FILTER_SINGLE_PLAYER }) } } function ExecutorBuff(self) { HellOnEarth.playSoundFromEntity(self, "ambient/levels/citadel/zapper_warmup4.wav", 1000) local particles_to_play if (RandomInt(0, 1) == 0) { self.AddCustomAttribute("CARD: move speed bonus", 2.0, 10) self.AddCustomAttribute("CARD: damage bonus", 1.3, 10) self.AddCustomAttribute("mult dmg vs giants", 25, 10) self.AddCustomAttribute("heal on kill", 500, 10) self.AddCustomAttribute("fire rate bonus HIDDEN", 0.75, 10) self.AddCustomAttribute("melee cleave attack", 1, 10) self.AddCustomAttribute("CARD: dmg taken from bullets reduced", 0.5, 10) particles_to_play = ["utaunt_elebound_yellow_parent", "utaunt_elebound_yellow_glow"] } else { self.AddCustomAttribute("CARD: move speed bonus", 0.9, 10) self.AddCustomAttribute("CARD: damage bonus", 1.75, 10) self.AddCustomAttribute("CARD: health regen", 80, 10) self.AddCustomAttribute("heal on kill", 500, 10) self.AddCustomAttribute("fire rate bonus HIDDEN", 1.25, 10) self.AddCustomAttribute("melee cleave attack", 1, 10) self.AddCustomAttribute("dmg from ranged reduced", 0.25, 10) particles_to_play = ["utaunt_elebound_green_parent", "utaunt_elebound_green_glow"] } local BuffIndicator = SpawnEntityFromTable("info_particle_system", { origin = self.GetOrigin() + Vector(0, 0, 25) effect_name = particles_to_play[0] start_active = 1 }) local BuffIndicatorGlow = SpawnEntityFromTable("info_particle_system", { origin = self.GetOrigin() + Vector(0, 0, 25) effect_name = particles_to_play[1] start_active = 1 }) BuffIndicator.AcceptInput("SetParent", "!activator", self, null) BuffIndicatorGlow.AcceptInput("SetParent", "!activator", self, null) EntFireByHandle(BuffIndicator, "Stop", null, 10, null, null) EntFireByHandle(BuffIndicatorGlow, "Stop", null, 10, null, null) EntFireByHandle(BuffIndicator, "Kill", null, 10.7, null, null) EntFireByHandle(BuffIndicatorGlow, "Kill", null, 10.7, null, null) } function engyParticle(building) { local x = SpawnEntityFromTable("info_particle_system", { targetname = "engi_teleporter" origin = building.GetOrigin() + Vector(0, 0, 15) effect_name = "utaunt_poweraura_teamcolor_blue" start_active = 1 }) HellOnEarth.playSoundFromEntity(x, "ambient/levels/citadel/weaponstrip1_adpcm.wav") } function ShowDiffImage(Index) { local difficultyImage switch(Index) { case -1: difficultyImage = null break case 0: difficultyImage = "hud/ptx_too_young_to_die" break case 1: difficultyImage = "hud/ptx_hurt_me_plenty" break case 2: difficultyImage = "hud/ptx_ultra_violence" break case 3: difficultyImage = "hud/ptx_nightmare" break case 4: difficultyImage = "hud/ptx_ultra_nightmare" break } for(local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(hPlayer && !hPlayer.IsFakeClient()) hPlayer.SetScriptOverlayMaterial(difficultyImage) } } function flickerBetweenWaves() { local dummyEnt = SpawnEntityFromTable("prop_dynamic", { model = "models/props_hydro/barrel_crate_half.mdl", origin = "0 0 0", disableshadows = 1 }) dummyEnt.DisableDraw() SetPropBool(dummyEnt, "m_bForcePurgeFixedupStrings", true) dummyEnt.ValidateScriptScope() local dummyEntscope = dummyEnt.GetScriptScope() dummyEntscope.NEXT_FLICKER_TIME <- Time() + RandomInt(0, 3); dummyEntscope.NEXT_FLICKER_DURATION <- 0; dummyEntscope.DO_FLICK <- false; dummyEntscope.Think <- function() { if (Time() > NEXT_FLICKER_TIME) { DO_FLICK = true NEXT_FLICKER_DURATION = Time() + RandomFloat(0, 0.35) NEXT_FLICKER_TIME = Time() + RandomInt(0, 3) } if (DO_FLICK) { if (Time() < NEXT_FLICKER_DURATION) { HellOnEarth.AlternateWavebars(0) } else { HellOnEarth.AlternateWavebars(-1) DO_FLICK = false } } return -1 } AddThinkToEnt(dummyEnt, "Think") } function AlternateWavebars(wave_num) { // 0 - the new AlternateWaves.ClearWaveIcons() EntFire("tf_objective_resource", "$SetClientProp$m_nMvMEventPopfileType", wave_num == 0 ? "1" : "0", -1) EntFire("tf_objective_resource", "$SetClientProp$m_nMannVsMachineWaveCount", wave_num.tostring(), -1) EntFire("tf_objective_resource", "$SetClientProp$m_nMannVsMachineMaxWaveCount", "0", -1) switch (wave_num) { case 0: AlternateWaves.AddWaveIcons([ [ "heavy_zombie_arm1_lite", 3, MVM_CLASS_FLAG_MINIBOSS ], [ "heavy_zombie_lite", 250, MVM_CLASS_FLAG_MINIBOSS ], ["blu2_lite", 0, MVM_CLASS_FLAG_SUPPORT], ["teleporter", 0, MVM_CLASS_FLAG_SUPPORT], ["heavy_zombie_breach_lite", 50, MVM_CLASS_FLAG_MINIBOSS], ["heavy_head_red_nys", 5, MVM_CLASS_FLAG_MINIBOSS], ["dead_red_lite", 150, MVM_CLASS_FLAG_MINIBOSS], ["dead_bleed_lite", 45, MVM_CLASS_FLAG_MINIBOSS], ["pyro_membrain_lite", 75, MVM_CLASS_FLAG_MINIBOSS], ["robo_extremethreat", 15, MVM_CLASS_FLAG_MINIBOSS], ["dead_flame_lite", 80, MVM_CLASS_FLAG_MINIBOSS], ["demo_automaton_red_nys", 40, MVM_CLASS_FLAG_MINIBOSS], ["soldier_pickaxe_equalize", 80, MVM_CLASS_FLAG_MINIBOSS], ["shotgun_lite", 60, MVM_CLASS_FLAG_MINIBOSS], ["soldier_gib_lite", 20, MVM_CLASS_FLAG_MINIBOSS], ["goliatron_rocket_lite", 30, MVM_CLASS_FLAG_MINIBOSS], ["soldier_barrage_incendiary_nys", 6, MVM_CLASS_FLAG_MINIBOSS], ["baron_ptyx", 2, MVM_CLASS_FLAG_MINIBOSS], ["baron_armor_ptyx", 1, MVM_CLASS_FLAG_MINIBOSS], ["marauder_red", 3, MVM_CLASS_FLAG_MINIBOSS], ]) break case -1: EntFire("tf_objective_resource", "$SetClientProp$m_nMvMEventPopfileType", "0", -1) EntFire("tf_objective_resource", "$SetClientProp$m_nMannVsMachineWaveCount", "1", -1) EntFire("tf_objective_resource", "$SetClientProp$m_nMannVsMachineMaxWaveCount", "5", -1) AlternateWaves.AddWaveIcons([ ["pyro_dragon_fury", 3, MVM_CLASS_FLAG_MINIBOSS], ["soldier_spammer", 1, MVM_CLASS_FLAG_MINIBOSS], ["heavy_deflector", 2, MVM_CLASS_FLAG_MINIBOSS], ["heavy_champ", 22, MVM_CLASS_FLAG_NORMAL], ["heavy_gru", 10, MVM_CLASS_FLAG_NORMAL], ["demoknight_skullcutter_armored", 8, MVM_CLASS_FLAG_NORMAL], ["medic_uber", 2, MVM_CLASS_FLAG_NORMAL], ["scout_fan", 24, MVM_CLASS_FLAG_NORMAL], ["soldier_bison_spammer", 6, MVM_CLASS_FLAG_NORMAL], ["heavy_armored_shotgun", 8, MVM_CLASS_FLAG_NORMAL], ["pyro", 16, MVM_CLASS_FLAG_ALWAYSCRIT] ]) break } } function OnGameEvent_recalculate_holidays(_) { if(GetRoundState() == 3) { if(GetPropString(FindByClassname(null, "tf_objective_resource"), "m_iszMvMPopfileName").find("hell_on_earth") == null) Convars.SetValue("sig_etc_unintended_class_weapon_display_meters", 1) local hGameRules = FindByClassname(null, "tf_gamerules") if(hGameRules) { SetPropInt(hGameRules, "m_halloweenScenario", 0) SetPropBool(hGameRules, "m_bShowMatchSummary", false) } for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(!hPlayer) continue if(hPlayer.IsFakeClient()) continue hPlayer.SetScriptOverlayMaterial(null) if(hPlayer.GetTeam() == 3) { hPlayer.ForceChangeTeam(2, true) hPlayer.ForceRespawn() } } //if(hThinkEnt && hThinkEnt.IsValid()) // hThinkEnt.Kill() delete ::HellOnEarth } } function UnstuckEntity(entity) { ::MASK_PLAYERSOLID <- 33636363 local origin = entity.GetOrigin(); local trace = { start = origin, end = origin, hullmin = entity.GetBoundingMins(), hullmax = entity.GetBoundingMaxs(), mask = MASK_PLAYERSOLID, ignore = entity } TraceHull(trace); if ("startsolid" in trace) { local dirs = [Vector(0, 0, 1), Vector(0, 0, -1), Vector(1, 0, 0), Vector(-1, 0, 0), Vector(0, 1, 0), Vector(0, -1, 0)] for (local i = 16; i <= 96; i += 16) { foreach (dir in dirs) { trace.start = origin + dir * i; trace.end = trace.start; delete trace.startsolid; TraceHull(trace); if (!("startsolid" in trace)) { entity.SetAbsOrigin(trace.end); return true; } } } return false; } return true; } function PlayMusic(number, SEND_MESSAGE = true) { // stop all previous songs playing foreach (song in MUSIC_LIST) { SetMusicState(false, split(song, "|")[0]) } local song_to_play if (number > MUSIC_LIST.len()) { return } // 1 - cultist base // 2 - mars core ambience // 3 - hell on earth // 4 - bfg division // 5 - reclaimed earth // 6 - hell on earth drop song_to_play = split(MUSIC_LIST[number - 1], "|") if (SEND_MESSAGE) ClientPrint(null, 3, "\x07FFA07ANow Playing: \x07FFFFF" + song_to_play[1]) SetMusicState(true, song_to_play[0], 1) } function SetMusicState(play, sound, sVolume = 1) { for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(!hPlayer || hPlayer.IsFakeClient()) continue EmitSoundEx({ sound_name = sound volume = sVolume entity = hPlayer filter_type = RECIPIENT_FILTER_SINGLE_PLAYER flags = play ? SND_NOFLAGS : SND_STOP }) } } // UTIL FUNCS 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 DispatchHudHint(message, hang_time = 10) { local hint = CreateByClassname("env_hudhint") hint.KeyValueFromString("message", message) hint.DispatchSpawn() hint.AcceptInput("ShowHudHint", null, null, null) EntFireByHandle(hint, "HideHudHint", null, hang_time, null, null) EntFireByHandle(hint, "Kill", null, hang_time, null, null) } function DispatchParticleAttached(entity, name, attachment) { if(entity == null) return if(name == null) { entity.AcceptInput("DispatchEffect", "ParticleEffectStop", null, null); return } local hParticle = CreateByClassname("trigger_particle") hParticle.KeyValueFromInt("attachment_type", 4) hParticle.KeyValueFromInt("spawnflags", 64) hParticle.KeyValueFromString("particle_name", name) hParticle.KeyValueFromString("attachment_name", attachment) hParticle.DispatchSpawn() hParticle.AcceptInput("StartTouch", "", entity, entity) hParticle.Kill() } 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 DispatchParticleEffectClient(player, name, origin, angles) { local hProxy = CreateByClassname("obj_teleporter") hProxy.SetAbsOrigin(origin) hProxy.SetForwardVector(angles) hProxy.DispatchSpawn() hProxy.DisableDraw() hoxy.AddEFlags(EFL_NO_THINK_FUNCTION) hProxy.Setid(SOLID_NONE) SetPropBool(hProxy, "m_bPlacing", true) SetPropInt(hProxy, "m_fObjectFlags", 2) SetPropInt(hProxy, "m_lifeState", 2) SetPropEntity(hProxy, "m_hBuilder", player) 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, hProxy, hProxy) EntFireByHandle(hProxy, "Kill", null, 0.066, null, null) hParticle.Kill() } function DisplayAnnotation(hEnt, sText, flDuration, origin = Vector(0, 0, 0), bVisibleToOthers = false, flDelay = -1) { if(flDelay < 0.033) flDelay = 0.033 local bRealClient = hEnt.IsPlayer() && !hEnt.IsFakeClient() local hAnnotationFollow if(bRealClient) { hAnnotationFollow = SpawnEntityFromTable("prop_dynamic", { model = "models/props_hydro/barrel_crate_half.mdl", origin = origin, disableshadows = 1 }) hAnnotationFollow.DisableDraw() SetPropEntity(hAnnotationFollow, "m_hMovePeer", hEnt.FirstMoveChild()) SetPropEntity(hEnt, "m_hMoveChild", hAnnotationFollow) SetPropEntity(hAnnotationFollow, "m_hMoveParent", hEnt) SpawnEntityFromTable("info_target", { spawnflags = 0x01 }).AcceptInput("SetParent", "!activator", hAnnotationFollow, null) EntFireByHandle(hAnnotationFollow, "Kill", null, flDelay + flDuration + 0.2, null, null) SetPropBool(hAnnotationFollow, "m_bForcePurgeFixedupStrings", true) } DoEntFire("bignet", "RunScriptCode" format(@" local index = activator.entindex() local hTarget = SpawnEntityFromTable(`info_target`, { spawnflags = 0x01 }) hTarget.AcceptInput(`SetParent`, `!activator`, activator, null) local anno = function(entindex1, entindex2){ SendGlobalGameEvent(`show_annotation`, { id = RandomInt(5000, 50000) text = `%s` follow_entindex = entindex1 visibilityBitfield = entindex2 play_sound = `misc/null.wav` show_distance = false show_effect = false lifetime = %f })} EntFireByHandle(hTarget, `Kill`, null, %f, null, null) %s %s", sText, flDuration, flDuration, bVisibleToOthers ? "anno(activator.entindex(), ((1 << 31) - 1) & ~(1 << (index > 30 ? 0 : index)))" : "", bRealClient ? "anno(caller.entindex(), 1 << (index > 30 ? 30 : index))" : "" ), flDelay, hEnt, hAnnotationFollow) } // MISC END ------ // RESPAWN LOGIC function PlayerRespawn() // credit to crilly for figuring out the bug, wouldnt have found it myself (at least not as fast) { local hMaxCurrency = 0 for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(!hPlayer || hPlayer.IsFakeClient()) continue if (hPlayer.IsAlive()) { if (hPlayer.GetCurrency() > hMaxCurrency) hMaxCurrency = hPlayer.GetCurrency() } } local MaxCurrMultiplier = hMaxCurrency / 250 for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(!hPlayer || hPlayer.IsFakeClient()) continue if (hPlayer.IsAlive()) { hPlayer.AddCondEx(32, 60, hPlayer) ClientPrint(hPlayer, 3, "\x07FF0000You survived...") } else { hPlayer.ForceRegenerateAndRespawn() if (hPlayer.GetCurrency() < 250) { local howMuch = hMaxCurrency > 250 ? MaxCurrMultiplier * 250 : 250 hPlayer.AddCurrency(howMuch) ClientPrint(hPlayer, 3, format("\x04You have received a \x07FFFF33$%d \x04bonus", howMuch)) } DispatchParticleEffect("teleported_blue", hPlayer.GetOrigin(), Vector(0, 0, 0)) DispatchParticleEffect("teleportedin_blue", hPlayer.GetOrigin(), Vector(0, 0, 0)) } } } function initiateRandomCutscene() { local delayBeforeStarting = RandomInt(30, 60) EntFire("first_warning", "Trigger", null, delayBeforeStarting - 5) EntFire("second_warning", "Trigger", null, delayBeforeStarting + 30) EntFire("final_warning", "Trigger", null, delayBeforeStarting + 60) // 60 seconds before the main cutscene } function setHudOverlay(name, holdtime = 5) { for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if (!hPlayer || hPlayer.IsFakeClient()) continue EntFire("bignet", "RunScriptCode", "activator.SetScriptOverlayMaterial(`effects/imcookin`); activator.SetHudHideFlags(-1); activator.ForceChangeTeam(2, true)", -1, hPlayer) EntFire("bignet", "RunScriptCode", "activator.SetScriptOverlayMaterial(null); activator.SetHudHideFlags(0)", 10, hPlayer) } } function mapTransformationUtil() { BOTS_PEACEFUL = false MAIN_WAVE_ACTIVE = true WAVE_ACTIVE = true RED_PLAYERS = false TEAM_WIPE_ACTIVE = true for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(!hPlayer || hPlayer.IsFakeClient()) continue hPlayer.ForceChangeTeam(3, true) hPlayer.AddCustomAttribute("min respawn time", 9999, -1); hPlayer.AddCustomAttribute("crit mod disabled", 0, -1); hPlayer.AddCustomAttribute("is miniboss", 1, -1); hPlayer.AddCustomAttribute("ammo regen", 0, -1); hPlayer.ValidateScriptScope() local hPlayer_scope = hPlayer.GetScriptScope() // thank you braindawg hPlayer_scope.ThinkTable.PackThink <- function() { local origin = self.GetOrigin() for ( local ent; ent = FindByClassnameWithin(ent, "item_*", origin, 40); ) { if (ent.IsEFlagSet(1048576)) continue if (GetPropInt(ent, "m_fEffects") & EF_NODRAW) continue local classname = ent.GetClassname() if (startswith(classname, "item_currencypack_")) continue local refill = false local is_health = false local multiplier = 0.0 if (endswith(classname, "_small")) multiplier = 0.2 else if (endswith(classname, "_medium")) multiplier = 0.5 else if (endswith(classname, "_full")) multiplier = 1.0 if (startswith(classname, "item_ammopack_")) { local metal = GetPropIntArray(self, "m_iAmmo", 3) local maxmetal = 200 if (metal < maxmetal) { local maxmult = Round(maxmetal * multiplier) local setvalue = (metal + maxmult > maxmetal) ? maxmetal : metal + maxmult SetPropIntArray(self, "m_iAmmo", setvalue, 3) refill = true } for (local i = 0; i < 2; ++i) { local wep = GetItemInSlot(self, i) local ammo = GetPropIntArray(self, "m_iAmmo", i+1) local maxammo = GetWeaponMaxAmmo(self, wep) if (ammo >= maxammo) continue else { local maxmult = Round(maxammo * multiplier) local setvalue = (ammo + maxmult > maxammo) ? maxammo : ammo + maxmult SetPropIntArray(self, "m_iAmmo", setvalue, i+1) refill = true } } } else if (startswith(classname, "item_healthkit_")) { is_health = true local hp = self.GetHealth() local maxhp = self.GetMaxHealth() if (hp >= maxhp) continue refill = true local maxmult = Round(maxhp * multiplier) local setvalue = (hp + maxmult > maxhp) ? maxhp : hp + maxmult self.ExtinguishPlayerBurning() SendGlobalGameEvent("player_healed", { patient = GetPlayerUserID(self) healer = 0 amount = setvalue - hp }) SendGlobalGameEvent("player_healonhit", { entindex = self.entindex() weapon_def_index = 65535 amount = setvalue - hp }) self.SetHealth(setvalue) } if (refill) { if (is_health) EmitSoundOnClient("HealthKit.Touch", self) else EmitSoundOnClient("AmmoPack.Touch", self) ent.AddEFlags(1048576) EntFireByHandle(ent, "Disable", "", -1, null, null) EntFireByHandle(ent, "Enable", "", 10, null, null) EntFireByHandle(ent, "RunScriptCode", "self.RemoveEFlags(1048576)", 10, null, null) } } } } for (local x = -1600.211426; x <= 1386.814331; x += 450) { for (local y = 2326.353760; y >= -2788.551270; y -= 450) { DispatchParticleEffectObj("cauldron_embers", Vector(x, y, -20), Vector(1, 0, 0), "fire_rain"); } } HellOnEarth.ShowDiffImage(CURR_RANK_IMAGE) HellOnEarth.AlternateWavebars(0) EntFire("bignet", "runscriptcode", "TextualTimer.Start()", 5, null) EntFire("bignet", "runscriptcode", "TextualTimer.bHideText = false", 5, null) IncludeScript("textualtimer_v3", getroottable()) TextualTimer.SetParams({ minutes = 3 seconds = 59 x = -1 y = 0.77 color = "0 255 555" relayname = "carrier_logic_spawn" }) TextualTimer.AddCallbacks({ "120" : function() { EntFire("tf_gamerules", "PlayVO", "vo/announcer_ends_2min.mp3") } "60" : function() { EntFire("tf_gamerules", "PlayVO", "Announcer.RoundEnds60seconds") } "30" : function() { EntFire("tf_gamerules", "PlayVO", "Announcer.RoundEnds30seconds") } "20" : function() { EntFire("tf_gamerules", "PlayVO", "Announcer.RoundEnds20seconds") } "10" : function() { EntFire("tf_gamerules", "PlayVO", "Announcer.RoundEnds10seconds") } "5" : function() { EntFire("tf_gamerules", "PlayVO", "Announcer.RoundEnds5seconds") } "4" : function() { EntFire("tf_gamerules", "PlayVO", "Announcer.RoundEnds4seconds") } "3" : function() { EntFire("tf_gamerules", "PlayVO", "Announcer.RoundEnds3seconds") } "2" : function() { EntFire("tf_gamerules", "PlayVO", "Announcer.RoundEnds2seconds") } "1" : function() { EntFire("tf_gamerules", "PlayVO", "Announcer.RoundEnds1seconds") } }) TextualTimer.Start() } function passivyRobot(hPlayer) { hPlayer.AcceptInput("$BotCommand", "switch_action Mobber", null, null) hPlayer.AcceptInput("$BotCommand", "interrupt_action_queue -pos -48 37 68 -lookpos -248 1438 -40 -duration 50", null, null) hPlayer.RemoveCustomAttribute("dmg taken mult from special damage type") hPlayer.AddCustomAttribute("CARD: move speed bonus", 0.875, 30) hPlayer.AddCustomAttribute("no_attack", 1, 30) } function bluRobotStun() { BOTS_PEACEFUL = true EntFire("intel", "ForceDrop", null, 0, null) EntFire("intel", "ForceResetSilent", null, 0.1, null) for (local hPlayer; hPlayer = Entities.FindByClassname(hPlayer, "player");) { if (hPlayer.IsBotOfType(1337) && hPlayer.GetTeam() == 3) { DispatchParticleEffect("bot_death_sparks", hPlayer.GetOrigin() + Vector(0, 0, (40 * (hPlayer.GetModelScale() + 0.2))), Vector(0, 0, 0)) hPlayer.AddCondEx(71, 3, null) passivyRobot(hPlayer) local drips = DispatchParticleEffectObj("bot_drips_cheap", hPlayer.GetOrigin() + Vector(0, 0, (60 * (hPlayer.GetModelScale() + 0.2)))) local string_to_play EntFireByHandle(drips, "Kill", null, 3, null, null) switch (hPlayer.GetPlayerClass()) { case 1: // scout string_to_play = "vo/mvm/norm/scout_mvm_paincrticialdeath02.mp3" break case 2: // Sniper string_to_play = "vo/mvm/norm/sniper_mvm_paincrticialdeath01.mp3" break case 3: // Soldier string_to_play = "vo/mvm/norm/soldier_mvm_paincrticialdeath02.mp3" break case 4: // Demo string_to_play = "vo/mvm/norm/demoman_mvm_paincrticialdeath05.mp3" case 5: // Medic string_to_play = "vo/mvm/norm/medic_mvm_paincrticialdeath01.mp3" break case 9: // Engy string_to_play = "vo/mvm/norm/engineer_mvm_paincriticaldeath01.mp3" break case 6: // Heavy string_to_play = "vo/mvm/norm/heavy_mvm_paincrticialdeath01.mp3" break case 7: // Pyro string_to_play = "vo/mvm/norm/pyro_mvm_paincrticialdeath01.mp3" break default: string_to_play = "vo/mvm/norm/soldier_mvm_paincrticialdeath02.mp3" // Spy break } PrecacheSound("#" + string_to_play) playSoundFromEntity(hPlayer, "#" + string_to_play, 750) } } } hLastPlayer = true function SethLastPlayer(value) { hLastPlayer = value } function RemoveLastAttrs() { for(local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(hPlayer && hPlayer.GetTeam() == 3 && hPlayer.IsAlive() && !(hPlayer.IsBotOfType(TF_BOT_TYPE)) && !(hPlayer.IsFakeClient())) { hPlayer.RemoveCondEx(97, true) hPlayer.RemoveCondEx(16, true) } } } function EternalWeapons(hPlayer) { hPlayer.ValidateScriptScope() local hPlayer_scope = hPlayer.GetScriptScope() if (!("ThinkTable" in hPlayer_scope)) hPlayer_scope.ThinkTable<- {} hPlayer_scope.LastActiveWeapon <- hPlayer.GetActiveWeapon() hPlayer_scope.CurrentActiveWeapon <- hPlayer.GetActiveWeapon() hPlayer_scope.ThinkTable.EternalThink <- function() { if (CurrentActiveWeapon && LastActiveWeapon) { CurrentActiveWeapon = self.GetActiveWeapon() if (!CurrentActiveWeapon.IsValid() || !LastActiveWeapon.IsValid()) { CurrentActiveWeapon = self.GetActiveWeapon() LastActiveWeapon = self.GetActiveWeapon() } local lastMaxClip = LastActiveWeapon.GetMaxClip1() if (CurrentActiveWeapon != LastActiveWeapon) { local hSlot = LastActiveWeapon.GetSlot() SetPropFloat(LastActiveWeapon, "m_flNextPrimaryAttack", 0) local ammo = GetPropIntArray(self, "m_iAmmo", LastActiveWeapon.GetPrimaryAmmoType()) if (lastMaxClip == 1 && LastActiveWeapon.Clip1() == 0 && ammo > 0) { LastActiveWeapon.SetClip1(1) SetPropIntArray(self, "m_iAmmo", ammo - 1, LastActiveWeapon.GetPrimaryAmmoType()) } LastActiveWeapon = CurrentActiveWeapon } } } } function GiveDashAbility(hPlayer, iCooldown, iPower = 2000) { hPlayer.ValidateScriptScope() local hPlayer_scope = hPlayer.GetScriptScope() if (!("ThinkTable" in hPlayer.GetScriptScope())) hPlayer.GetScriptScope().ThinkTable<- {} hPlayer_scope.hGameText <- SpawnEntityFromTable("game_text", { channel = 3 color = "255 0 0" holdtime = 1 x = 0.8 y = 0.8 }) hPlayer_scope.flRechargeTime <- Time() + iCooldown hPlayer_scope.iDashesLast <- 0 hPlayer_scope.iDashesCount <- 0 hPlayer_scope.ThinkTable.Think <- function() { local flTime = Time() if(iDashesCount == 0) { local flRechargeTimeDuration = iCooldown if(iDashesLast == 1) { hGameText.KeyValueFromString("color", "255 0 0") flRechargeTime = flTime + flRechargeTimeDuration } local iMessageMaxLength = 10 local sMessage = "Dash\n" if(flTime >= flRechargeTime) { hGameText.KeyValueFromString("color", "0 255 0") for(local i = 1; i <= iMessageMaxLength; i++) sMessage += "■" sMessage += " READY" iDashesCount = iDashesCount + 1 } else { // this logic by lite local flTimeRemaining = flRechargeTime - flTime local flTimeRemainingPercent = 1 - flTimeRemaining / flRechargeTimeDuration local flMessagePercent = 1.0 / iMessageMaxLength local iRechargeMeter = (flTimeRemainingPercent / flMessagePercent).tointeger() for(local i = 1; i <= iRechargeMeter; i++) sMessage += "■", iMessageMaxLength-- for(local i = 1; i <= iMessageMaxLength; i++) sMessage += "□" sMessage += format(" %i", ceil(flTimeRemaining)) } SetPropString(hGameText, "m_iszMessage", sMessage) } iDashesLast = iDashesCount try { hGameText.AcceptInput("Display", null, hPlayer, null) } catch(Exception) { local i = 1 } if (iDashesCount == 1 && (hPlayer.GetFlags() & FL_DUCKING)) { iDashesCount = iDashesCount - 1 local dashDirection = hPlayer.EyeAngles().Forward() dashDirection.z = 0.1 hPlayer.SetVelocity(dashDirection * 1200) hPlayer.SetGravity(0.000001) local snd_lvl = (40 + (20 * log10(1250 / 36))).tointeger() EmitSoundEx({ sound_name = "PlayerDash" entity = hPlayer volume = 1 sound_level = snd_lvl }) EntFireByHandle(hPlayer, "runscriptcode", "self.SetGravity(1)", 0.25, null, null) } } hPlayer_scope.PlayerThinks <- function() { foreach (name, func in hPlayer_scope.ThinkTable) { func.call(hPlayer_scope) } return -1 } AddThinkToEnt(hPlayer, "PlayerThinks") SetDestroyCallback(hPlayer, function() { if(hGameText && hGameText.IsValid()) hGameText.Destroy() }) } function Decide(hPlayer) { local cooldown = 1 switch (hPlayer.GetPlayerClass()) { case 1: // scout cooldown = 2 break case 2: // Sniper cooldown = 3 break case 3: // Soldier cooldown = 5 break case 4: // Demo cooldown = 4 case 5: // Medic cooldown = 3 break case 9: // Engy cooldown = 5 break case 6: // Heavy cooldown = 5 break case 7: // Pyro cooldown = 4 break } HellOnEarth.GiveDashAbility(hPlayer, cooldown) //ClientPrint(hPlayer, 3, format("\x0700ff00Your cooldown time is: \x073399ff%d seconds", cooldown)) } function ForceCustomDashCooldown(hPlayer, cooldown) { HellOnEarth.GiveDashAbility(hPlayer, cooldown) ClientPrint(hPlayer, 3, format("\x0700ff00Your cooldown time is: \x073399ff%d seconds", cooldown)) } function DistributeDash() { for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(!hPlayer || hPlayer.IsFakeClient()) continue Decide(hPlayer) EternalWeapons(hPlayer) } } // RANDOM SPAWN LOGIC // 1. Particle Pre function DispatchParticleEffectObj(name, hOrigin, hAngles = Vector(0, 0, 0), hTarget = null) { if (hTarget) { return SpawnEntityFromTable("info_particle_system", { origin = hOrigin effect_name = name start_active = 1 angles = hAngles targetname = hTarget }) } return SpawnEntityFromTable("info_particle_system", { origin = hOrigin effect_name = name start_active = 1 angles = hAngles }) } function TeleporterParticleSequence_REGULAR(hPos) // TIME FOR REGULAR: 4 SECONDS { local hFirst = DispatchParticleEffectObj("utaunt_poweraura_teamcolor_red", hPos) local hSecond = DispatchParticleEffectObj("dxhr_lightningball_parent_red", hPos + Vector(0, 0, 40)) EntFireByHandle(hFirst, "Stop", null, 4.5, null, null) EntFireByHandle(hSecond, "Stop", null, 4.5, null, null) EntFireByHandle(hFirst, "Kill", null, 5, null, null) EntFireByHandle(hSecond, "Kill", null, 5, null, null) } function TeleporterParticleSequence_POSESSED(hPos) // TIME FOR POSESSED: 5 SECONDS { local hFirst = DispatchParticleEffectObj("utaunt_poweraura_purple_parent", hPos); local hSecond = DispatchParticleEffectObj("utaunt_hellswirl_smoke", hPos + Vector(0, 0, 40)); local hThird = DispatchParticleEffectObj("utaunt_arcane_purple_parent", hPos); local hFourth = DispatchParticleEffectObj("utaunt_elebound_purple_glow", hPos + Vector(0, 0, 40)); EntFireByHandle(hFirst, "Stop", null, 5.5, null, null); EntFireByHandle(hSecond, "Stop", null, 5.5, null, null); EntFireByHandle(hThird, "Stop", null, 5.5, null, null); EntFireByHandle(hFourth, "Stop", null, 5.5, null, null); EntFireByHandle(hFirst, "Kill", null, 6, null, null); EntFireByHandle(hSecond, "Kill", null, 6, null, null); EntFireByHandle(hThird, "Kill", null, 6, null, null); EntFireByHandle(hFourth, "Kill", null, 6, null, null); } function TeleporterParticleSequence_GIANT(hPos) // TIME FOR GIANT: 5 SECONDS { local hFirst = DispatchParticleEffectObj("dxhr_lightningball_parent_red", hPos + Vector(0, 0, 40)); local hSecond = DispatchParticleEffectObj("mannpower_imbalance_red", hPos + Vector(0, 0, 40)); local hThird = DispatchParticleEffectObj("utaunt_god_lava_flame1", hPos); local hFourth = DispatchParticleEffectObj("utaunt_poweraura_teamcolor_red", hPos + Vector(0, 0, 0)); EntFireByHandle(hFirst, "Stop", null, 5.5, null, null); EntFireByHandle(hSecond, "Stop", null, 5.5, null, null); EntFireByHandle(hThird, "Stop", null, 5.5, null, null); EntFireByHandle(hFourth, "Stop", null, 5.5, null, null); EntFireByHandle(hFirst, "Kill", null, 6, null, null); EntFireByHandle(hSecond, "Kill", null, 6, null, null); EntFireByHandle(hThird, "Kill", null, 6, null, null); EntFireByHandle(hFourth, "Kill", null, 6, null, null); } function TeleportBot(hPos, hEntity, RESET_INDEX) { hEntity.AcceptInput("$GiveItem", "Basic Spellbook", null, null) local delay = 4 if (hEntity.HasBotTag("robot_posessed") || hEntity.GetMaxHealth() > 4000) { delay = 5 } local hItem for (local hChild = hEntity.FirstMoveChild(); hChild; hChild = hChild.NextMovePeer()) { if(hChild.GetClassname() == "tf_weapon_spellbook") { hItem = hChild; break } } SetPropBool(hItem, "m_bForcePurgeFixedupStrings", true) hItem.ValidateScriptScope() local hItem_scope = hItem.GetScriptScope() hItem_scope.teleportEnemy <- Time() + delay hItem_scope.doParticle <- true hItem_scope.IS_DONE <- false hItem_scope.Think <- function() { if (hItem_scope.doParticle) { if (hEntity.HasBotTag("robot_posessed")) { HellOnEarth.TeleporterParticleSequence_POSESSED(hPos) } else if (hEntity.GetMaxHealth() > 4000) { HellOnEarth.TeleporterParticleSequence_GIANT(hPos) } else { HellOnEarth.TeleporterParticleSequence_REGULAR(hPos) } PrecacheSound("#ptx/other/argent_energy_teleport.mp3") local snd_lvl = (40 + (20 * log10(850 / 36))).tointeger() EmitSoundEx({ sound_name = "#ptx/other/argent_energy_teleport.mp3" origin = hPos volume = 1 sound_level = snd_lvl filter_type = RECIPIENT_FILTER_GLOBAL }) hItem_scope.doParticle = false } if (hItem_scope.teleportEnemy < Time() && !IS_DONE) { PrecacheSound("#ptx/misc/demonic_spawn.wav") IS_DONE = true hEntity.SetAbsOrigin(hPos) hEntity.RemoveCustomAttribute("mult_player_movespeed_active") hEntity.AddCondEx(TF_COND_INVULNERABLE_USER_BUFF, 0.5, null) local snd_lvl = (40 + (20 * log10(950 / 36))).tointeger() EmitSoundEx({ sound_name = "#ptx/misc/demonic_spawn.wav" origin = hPos volume = 1 sound_level = snd_lvl }) if (hEntity.HasBotTag("robot_posessed")) { DispatchParticleEffect("bombinomicon_flash_halloween", hPos, Vector(0, 0, 50)) } else if (hEntity.GetMaxHealth() > 4000) { DispatchParticleEffect("asplode_hoodoo_burning_debris", hPos, Vector(0, 0, 120)) } else { DispatchParticleEffect("powercore_embers_red", hPos, Vector(0, 0, 0)) } HellOnEarth.resetTakenTelePoint(hEntity, RESET_INDEX) } if (hItem_scope.teleportEnemy + 1 < Time()) { HellOnEarth.UnstuckEntity(hEntity) NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") } return -1 } AddThinkToEnt(hItem, "Think") } function getTelePoint(hEntity) { local health = hEntity.GetMaxHealth(); if (health < 750) { while (true) { local index = RandomInt(0, telePoints_NORMAL.len() - 1); if (takenTelePoints_NORMAL[index] == null) { takenTelePoints_NORMAL[index] = 1; return [index, telePoints_NORMAL[index]]; } } } else if (health >= 750 && health < 10000) { while (true) { local index = RandomInt(0, telePoints_BIG.len() - 1); if (takenTelePoints_BIG[index] == null) { takenTelePoints_BIG[index] = 1; return [index, telePoints_BIG[index]]; } } } else { while (true) { local index = RandomInt(0, telePoints_GIGA.len() - 1); if (takenTelePoints_GIGA[index] == null) { takenTelePoints_GIGA[index] = 1; return [index, telePoints_GIGA[index]]; } } } } function resetTakenTelePoint(hEntity, index) { local health = hEntity.GetMaxHealth(); if (health < 750) { takenTelePoints_NORMAL[index] = null; } else if (health >= 750 && health < 10000) { takenTelePoints_BIG[index] = null; } else { takenTelePoints_GIGA[index] = null; } } function ChangePlayerTeamMvM(player, teamnum = TF_TEAM_PVE_INVADERS) { local GameRules = FindByClassname(null, "tf_gamerules") if (GameRules) { SetPropBool(GameRules, "m_bPlayingMannVsMachine", false); player.ForceChangeTeam(teamnum, false); SetPropBool(GameRules, "m_bPlayingMannVsMachine", true); } } function EndWaveReverse(doteamswitch = true) { local HumanArray = [] local BotArray = [] for(local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(hPlayer && hPlayer.GetTeam() == 3 && hPlayer.IsAlive() && !(hPlayer.IsBotOfType(TF_BOT_TYPE)) && !(hPlayer.IsFakeClient())) { HumanArray.append(hPlayer) } else if (hPlayer && hPlayer.IsBotOfType(TF_BOT_TYPE)) { BotArray.append(hPlayer) } } local temp = CreateByClassname("info_teleport_destination") //move to red if (doteamswitch) foreach (player in HumanArray) HellOnEarth.ChangePlayerTeamMvM(player, TF_TEAM_PVE_DEFENDERS) temp.ValidateScriptScope() temp.GetScriptScope().ClearWave <- function() { if (doteamswitch) foreach (player in HumanArray) HellOnEarth.ChangePlayerTeamMvM(player, TF_TEAM_PVE_INVADERS) SetPropString(self, "m_iszScriptThinkFunction", "") EntFireByHandle(self, "Kill", "", -1, null, null) local TriggerHurt = CreateByClassname("trigger_hurt") TriggerHurt.DispatchSpawn() //kill all bots foreach (bot in BotArray) if (GetPropInt(bot, "m_lifeState") == 0 && bot.GetTeam() == TF_TEAM_PVE_DEFENDERS) bot.TakeDamage(INT_MAX, 0, this.TriggerHurt); } AddThinkToEnt(temp, "ClearWave") } function test() { local owner for(local i = 1; i <= MAX_CLIENTS; i++) { local hEnt = PlayerInstanceFromIndex(i) if(hEnt && hEnt.IsAlive() && hEnt.IsBotOfType(TF_BOT_TYPE)) { owner = hEnt break } } local spawn_direction = owner.GetRightVector() spawn_direction.z = 0 local effect_duration = 8.0 local fireball_amount = 64 local base_distance_from_owner = 16 local max_altitude = 150 local DIRECTION_MODE = 1 local intensity_multiplier = 1 local spawn_rate = 0.05 local speed_increment = 50 for (local i = 0; i < fireball_amount; i = i + 1) { local altitude_ratio = RandomFloat(0, 1) local orbiter_altitude_above_head = altitude_ratio * max_altitude local adjusted_distance = base_distance_from_owner + (altitude_ratio * 50) * intensity_multiplier local angle_variation = RandomFloat(-10, 10) * intensity_multiplier local orbiter_spawn_point = owner.EyePosition() + spawn_direction * adjusted_distance local orbiter_speed = RandomInt(750, 900) * DIRECTION_MODE + RandomFloat(-100, 100) * intensity_multiplier local orbiter = SpawnEntityFromTable("info_particle_system", { origin = orbiter_spawn_point + Vector(0, 0, orbiter_altitude_above_head), effect_name = PickRandomItem(TORNADO_PARTICLE_DISTRIBUTION), start_active = 1 }); orbiter.SetForwardVector(owner.EyePosition() - orbiter_spawn_point) NetProps.SetPropBool(orbiter, "m_bForcePurgeFixedupStrings", true) EntFireByHandle(orbiter, "Kill", "", effect_duration, null, null) orbiter.ValidateScriptScope() orbiter.GetScriptScope().distanceToMaintain <- adjusted_distance orbiter.GetScriptScope().pawnToFollow <- owner orbiter.GetScriptScope().pawnPreviousPosition <- owner.EyePosition() orbiter.GetScriptScope().moveDirection <- orbiter.GetRightVector() orbiter.GetScriptScope().speed <- orbiter_speed orbiter.GetScriptScope().angleVariation <- angle_variation orbiter.GetScriptScope().Think <- function() { if (!self || !self.IsValid()) { return 1.0; } local tick_time = FrameTime() local offset = Vector(0, 0, 0) if (pawnToFollow && pawnToFollow.IsValid()) { offset = (pawnToFollow.EyePosition() - pawnPreviousPosition) offset.z = 0 pawnPreviousPosition = pawnToFollow.EyePosition() } local angle_offset = Vector(0, 0, sin(angleVariation * tick_time) * 10) local new_position = (self.GetOrigin() + self.GetRightVector() * speed * tick_time + angle_offset) + offset local height_adjustment = RandomFloat(-5, 5) * tick_time new_position.z = new_position.z + height_adjustment self.SetAbsOrigin(new_position) if (!pawnToFollow || !pawnToFollow.IsValid()) { self.SetForwardVector(pawnPreviousPosition - self.GetOrigin()) } else { self.SetForwardVector(pawnToFollow.EyePosition() - self.GetOrigin()) } return -1.0; } AddThinkToEnt(orbiter, "think") base_distance_from_owner = base_distance_from_owner + RandomFloat(8, 16) * intensity_multiplier DIRECTION_MODE = DIRECTION_MODE * -1 intensity_multiplier = intensity_multiplier + 0.05 speed_increment = speed_increment + 10 } } // EVENTS --------------------------------- EVENTS function OnGameEvent_player_activate(params) { HellOnEarth.AddTeamPoints(0) } function OnGameEvent_player_spawn(params) { local hPlayer = GetPlayerFromUserID(params.userid); EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.BotTagsAndAttrs(self)", 0.001, null, null) if (hPlayer && !hPlayer.IsBotOfType(TF_BOT_TYPE)) { HellOnEarth.ShowDiffImage(CURR_RANK_IMAGE) } if (RED_PLAYERS && !hPlayer.IsBotOfType(TF_BOT_TYPE) && hPlayer.GetTeam() == 3) { EntFireByHandle(hPlayer, "runscriptcode", "self.ForceChangeTeam(2, true)", 0.001, null, null) } if (hPlayer != null && hPlayer.IsBotOfType(TF_BOT_TYPE)) { if (MAIN_WAVE_ACTIVE) { EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.finalizeTeleportation(self)", 0.001, null, null) EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.TimedBotSetup(self)", 0.001, null, null) } if (BOTS_PEACEFUL) { EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.passivyRobot(self)", 0.01, null, null) } } } function OnGameEvent_player_builtobject(params) { local ent = GetPlayerFromUserID(params.userid); if (params.object == 1 && ent.IsBotOfType(1337)) { if (ent.HasBotTag("bot_vip")) { local building = EntIndexToHScript(params.index) HellOnEarth.DisplayAnnotation(building, "protect the teleporter to keep the reinforcements coming", 10, building.GetOrigin()) building.SetMaxHealth(3000) building.SetModelScale(1.5, 0) EntFireByHandle(building, "runscriptcode", "HellOnEarth.engyParticle(self)", 20, null, null) ent.AcceptInput("$ChangeAttributes", "switch_action Mobber", null, null) ent.AcceptInput("$BotCommand", "WeaponSwitchSlot 0", null, null) } } } function finalizeTeleportation(hPlayer) { if (hPlayer.HasBotTag("bot_ignore")) return hPlayer.AddCond(TF_COND_REPROGRAMMED) hPlayer.AddCustomAttribute("dmg taken mult from special damage type 1", 0.2, -1) hPlayer.AddCustomAttribute("special damage type", 2, -1) hPlayer.AddCustomAttribute("mult_player_movespeed_active", 0.01, -1) local teleInfo = getTelePoint(hPlayer) local Trace = { start = teleInfo[1] end = teleInfo[1] - Vector(0, 0, 100) mask = MASK_VISIBLE_AND_NPCS & ~(CONTENTS_MONSTER) } TraceLineEx(Trace) TeleportBot(Trace.pos, hPlayer, teleInfo[0]) } function OnScriptHook_OnTakeDamage(params) { local hVictim = params.const_entity if(hVictim.IsPlayer() && hVictim.IsBotOfType(TF_BOT_TYPE)) { if(hVictim.HasBotTag("bot_metal")) DispatchParticleEffect("manmelter_impact_sparks02", params.damage_position, Vector(0, 0, 1)) if(hVictim.HasBotTag("bot_argent")) DispatchParticleEffect("powercore_flash_red", params.damage_position, Vector(0, 0, 1)) if(hVictim.HasBotTag("bot_toxic")) DispatchParticleEffect("merasmus_blood", hVictim.GetCenter(), Vector(1)) if(hVictim.HasBotTag("bot_blood")) DispatchParticleEffect("tfc_sniper_mist", hVictim.GetCenter(), Vector(1)) if(hVictim.HasBotTag("bot_flesh")) DispatchParticleEffect("blood_impact_backscatter", hVictim.GetCenter(), Vector(1)) } } function OnGameEvent_player_changeclass(params) { local hPlayer = GetPlayerFromUserID(params.userid) if(!hPlayer || hPlayer.IsFakeClient()) return EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.EternalWeapons(self)", 0.1, null, null) EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.Decide(self)", 0.1, null, null) } function OnGameEvent_player_death(params) { local hPlayer = GetPlayerFromUserID(params.userid) local isBot = hPlayer.IsBotOfType(TF_BOT_TYPE) if (HellOnEarth.WAVE_ACTIVE) { if (isBot) { if (hPlayer.HasBotTag("bot_vip")) HellOnEarth.AddTeamPoints(-100) if (hPlayer.HasBotTag("bot_fire")) CreateExplosion(hPlayer.GetCenter(),25, 150, hPlayer, 1.0) if (hPlayer.HasBotTag("bot_explode_death")) CreateExplosion(hPlayer.GetCenter(),100, 250, hPlayer, 1.0) if (hPlayer.HasBotTag("bot_argent")) DispatchParticleEffect("spell_batball_impact_red", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_toxic")) DispatchParticleEffect("merasmus_dazed_blood", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_blood_small")) DispatchParticleEffect("env_sawblood", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_blood_big")) DispatchParticleEffect("tfc_sniper_mist2", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_posessed")) DispatchParticleEffect("halloween_ghost_smoke", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_posessed_big")) DispatchParticleEffect("halloween_boss_death", hPlayer.GetCenter(), Vector(0,0,0)) } else { PrecacheSound("Halloween.Sreams") playSoundToEveryone("Halloween.Sreams") HellOnEarth.AddTeamPoints(-1 * hPlayer.GetMaxHealth()) } if (HellOnEarth.TEAM_WIPE_ACTIVE) { local iAlivePlayers = 0 for(local i = 1; i <= MAX_CLIENTS; i++) { local hEnt = PlayerInstanceFromIndex(i) if(hEnt && hEnt.IsAlive() && !(hEnt.IsBotOfType(TF_BOT_TYPE))) { iAlivePlayers++ } } if(iAlivePlayers == 1 && hPlayer) { PrecacheSound("npc/combine_gunship/ping_patrol.wav") hPlayer.AddCondEx(97, -1, null) hPlayer.AddCondEx(16, -1, null) HellOnEarth.playSoundToEveryone("npc/combine_gunship/ping_patrol.wav") ScreenShake(hPlayer.GetOrigin(), 5, 15, 1, 9999, 0, true) for(local i = 1; i <= MAX_CLIENTS; i++) { local hBot = PlayerInstanceFromIndex(i) if(hPlayer && hPlayer.GetTeam() == hBot.GetTeam() && hPlayer.IsBotOfType(TF_BOT_TYPE)) { hPlayer.AddCondEx(32, -1, null) } } } if(iAlivePlayers == 0) { SpawnEntityFromTable("game_round_win", { teamnum = 2, force_map_reset = 1 }).AcceptInput("RoundWin", null, null, null) } } } } } HellOnEarth.DistributeDash() HellOnEarth.CreatePointThink() HellOnEarth.AddTeamPoints(-1) EntFire("tf_objective_resource", "$SetClientProp$m_nMannVsMachineMaxWaveCount", "5", -1) __CollectGameEventCallbacks(HellOnEarth)