::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") PrecacheSound("ptx/cinematic/axe_warning_red.wav") PrecacheSound("ptx/cinematic/asteroid_collision_02.wav") PrecacheSound("ptx/other/armor_pickup.wav") PrecacheSound("Baron.RoarBig") PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "mvm_tank_destroy_embers"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "projectile_fireball_crit_red_sparks"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "doublejump_smoke_alt"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "spell_fireball_tendril_parent_red"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "flaregun_trail_crit_red"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "halloweeen_boss_summon"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "doom_hellunit_spawn_large"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "mvm_pow_smash"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "doom_cyberdemon_missile_blast"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "spore_splash"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "eyeboss_tp_escape"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "halloween_ghost_smoke"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "halloween_boss_death"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "ds3_cinder_bless_cast"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "dskart_blade_hit"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "halloween_boss_death_cloud"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "railgun_single_explode"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "projectile_fireball"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "acid_ground"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "area_of_fog"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "healthgained_red_large"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "lava_playertouch_embers"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "railgun_broken_fire"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "railgun_explode_pulse4"}) local PlayerManager = FindByClassname(null, "tf_player_manager") local hGameRules = FindByClassname(null, "tf_gamerules") local hObjectiveResource = FindByClassname(null, "tf_objective_resource") local hClientCommand = SpawnEntityFromTable("point_clientcommand",{targetname = "cmd"}) 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/blood_swamps.mp3") PrecacheSound("#ptx/ost/atone_intro.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/blood_swamps.mp3| Blood Swamps - Andrew Hulshult", "#ptx/ost/reclaimed_earth.mp3| Reclaimed Earth - Andrew Hulshult", "#ptx/ost/break_music.mp3| unknown", "#ptx/ost/atone_intro.mp3| Atone To Fire - Snurper Bob" ] local enemy_types_to_damage = [ "player", "obj_sentrygun", "obj_dispenser", "obj_teleporter", "base_boss", "tank_boss", "tf_zombie" ] 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(-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 RemapValClamped(v, A, B, C, D) { if (A == B) { if (v >= B) return D return C } local cv = (v - A) / (B - A) if (cv <= 0.0) return C if (cv >= 1.0) return D return C + (D - C) * cv } 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 } function test1(name) { PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = name}) DispatchParticleEffect(name, Vector(24, -2049, 346), Vector()) } ::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 VIP_DEATH_LOSE_COND = true DISPLAY_TEXT = true ENGINEER_SETUP = true ENGINEER_TELEPORTER = null ENGINEER_THINK_ADD = SpawnEntityFromTable("logic_script", {}) hThinkEnt = SpawnEntityFromTable("logic_relay", {}) hTriggerParticlePosessedEnt = SpawnEntityFromTable("trigger_particle", { targetname = "posessed_particle", particle_name = "ghost_pumpkin", attachment_type = "1", spawnflags = "64", //OnStartTouch = "player,$DisplayTextChat,TOUCHINGSOMEONE,-1,-1" }) function ToggleText() { if (HellOnEarth.DISPLAY_TEXT) HellOnEarth.DISPLAY_TEXT = false else HellOnEarth.DISPLAY_TEXT = true } function SetRespawnTimeAll(seconds) { //EntFire("respawnoverride", "Kill") -> THERE CAN BE ONLY 1 INSTANCE, SO KILL THEN CREATE A NEW ONE OR ELSE IT WONT WORK local respawnoverride = SpawnEntityFromTable("trigger_player_respawn_override", { targetname = "respawnoverride", RespawnTime = seconds, spawnflags = 1 }) function RespawnStartTouch() { return (activator == null) ? false : true; } function RespawnEndTouch() { return (activator == null) ? false : true; } respawnoverride.ValidateScriptScope(); respawnoverride.GetScriptScope().InputStartTouch <- RespawnStartTouch; respawnoverride.GetScriptScope().Inputstarttouch <- RespawnStartTouch; respawnoverride.GetScriptScope().InputEndTouch <- RespawnEndTouch; respawnoverride.GetScriptScope().Inputendtouch <- RespawnEndTouch for(local i = 1; i <= MAX_PLAYERS; i++) { local player = PlayerInstanceFromIndex(i) if(!player || player.IsFakeClient()) continue EntFireByHandle(respawnoverride, "StartTouch", "", -1, player, player); } } 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) && HellOnEarth.DISPLAY_TEXT) { hText.AcceptInput("Display", null, null, null) lastDisplayTime = Time() } return -1 } AddThinkToEnt(hPoints, "Think") } function GetBotKillDuration(health) { return health >= 10000 ? 75.0 : health <= 500 ? 15.0 : 15.0 + (35.0 * log10(1 + ((health - 200) / 9800) * 9)); } function CalculateRewardPoints(hp) { return (hp > 10000) ? 750 : (10 * pow(1.1, hp / 100) > 750 ? 750 : 10 * pow(1.1, hp / 100)); } function TimedPointRobot(hPlayer) { local hTimedScript = SpawnEntityFromTable("logic_script", {}) hTimedScript.ValidateScriptScope() local hTimedScript_scope = hTimedScript.GetScriptScope() hTimedScript_scope.timeRemaining <- GetBotKillDuration(hPlayer.GetMaxHealth()) hTimedScript_scope.timeStart <- 0 hTimedScript_scope.pointsGained <- CalculateRewardPoints(hPlayer.GetMaxHealth()) hTimedScript_scope.Think <- function () { local elapsed = timeStart ? (Time() - timeStart) : 0; if (elapsed == 0) { timeStart <- Time() elapsed = 0 } local duration = timeRemaining if (elapsed >= duration) { NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") return -1 } if (hPlayer && !hPlayer.IsAlive()) { PrecacheSound("#ptx/other/armor_pickup.wav") //HellOnEarth.playSoundFromEntity(self, "#ptx/other/armor_pickup.wav") NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") HellOnEarth.AddTeamPoints(floor(pointsGained * (1 - (elapsed / duration)))) return -1 } return -1 } AddThinkToEnt(hTimedScript, "Think") } function TimedBotSetup(hEntity) { local delay = 4 if (hEntity.HasBotTag("bot_posessed") || hEntity.GetMaxHealth() > 4000) { delay = 5 } if (hEntity.GetTeam() != 2) return EntFireByHandle(hEntity, "runscriptcode", "HellOnEarth.TimedPointRobot(self)", delay, null, null) } function BotTagsAndAttrs(hPlayer) { if (!hPlayer || !hPlayer.IsFakeClient()) return if (hPlayer.HasBotTag("bot_vip")) { hPlayer.AddCondEx(71, 5, null) ENGINEER_THINK_ADD.ValidateScriptScope() local ENGINEER_THINK_ADD_scope = ENGINEER_THINK_ADD.GetScriptScope() ENGINEER_THINK_ADD_scope.POINTS_TO_ADD <- 1 ENGINEER_THINK_ADD_scope.Think <- function () { HellOnEarth.AddTeamPoints(POINTS_TO_ADD) return 0.5 } AddThinkToEnt(ENGINEER_THINK_ADD, "Think") } if (hPlayer.HasBotTag("bot_posessed")) { HellOnEarth.hTriggerParticlePosessedEnt.AcceptInput("StartTouch", "", hPlayer, hPlayer) HellOnEarth.hTriggerParticlePosessedEnt.AcceptInput("StartTouch", "", hPlayer, hPlayer) HellOnEarth.hTriggerParticlePosessedEnt.AcceptInput("StartTouch", "", hPlayer, hPlayer) hPlayer.AddCustomAttribute("dmg from ranged reduced", 0.65, -1) hPlayer.AddCustomAttribute("dmg from melee increased", 0.65, -1) hPlayer.AddCustomAttribute("major move speed bonus",1.5 , -1) hPlayer.AddCustomAttribute("fire rate bonus", 0.7, -1) hPlayer.AddCustomAttribute("major increased jump height", 1.3, -1) hPlayer.AddCustomAttribute("mult stun resistance", 0, -1) hPlayer.AddCustomAttribute("damage force reduction", 0, -1) hPlayer.AddCustomAttribute("airblast vulnerability multiplier", 0, -1) hPlayer.AddCustomAttribute("airblast vertical vulnerability multiplier", 0, -1) } 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.BotModelThink <- function() { if (wearable.IsValid() && (player.IsTaunting() || wearable.GetMoveParent() != player)) EntFireByHandle(wearable, "SetParent", "!activator", -1, player, player) if(NetProps.GetPropInt(self, "m_lifeState") != 0) { wearable.Kill() AddThinkToEnt(self, null) NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") } return -1 } AddThinkToEnt(player, "BotModelThink") } function CreateBomb(vOrigin = Vector()) { PrecacheModel("models/bots/doom_bomb.mdl") local bomb = SpawnEntityFromTable("item_teamflag", { origin = vOrigin flag_model = "models/bots/doom_bomb.mdl" trail_effect = 1 GameType = 1 ReturnBetweenWaves = true TeamNum = Constants.ETFTeam.TF_TEAM_RED }) NetProps.SetPropInt(bomb, "m_nFlagStatus", 0x2) self.SetModelSimple("models/bots/doom_bomb.mdl") bomb.SetTeam(2) } 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 BFGShoot(self) { local hGreenCorrection = SpawnEntityFromTable("color_correction", { StartDisabled = 0, fadeInDuration = 0.0, fadeOutDuration = 3.0, maxfalloff = -1, minfalloff = 0, filename = "materials/colorcorrection/greenasfuck.raw" }) EntFireByHandle(hGreenCorrection, "Enable", null, -1, null, null) EntFireByHandle(hGreenCorrection, "Disable", null, 0.1, null, null) for(local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(hPlayer && !hPlayer.IsFakeClient()) EntFireByHandle(hClientCommand, "Command", "soundfade 80 1 3 0", 0, hPlayer, hPlayer); ScreenFade(null, 55, 255, 55, 100, 3, 0.1, 1) ScreenShake(self.GetOrigin(), 15, 15, 3, 9999, 0, true) PrecacheSound("ambient/explosions/exp1.wav") EntFire("player", "PlayVO", "ambient/explosions/exp1.wav") } } function ExecutorBuff(self) { self.ValidateScriptScope() local scope = self.GetScriptScope() if (!("buffstatus" in self.GetScriptScope())) { scope.buffstatus <- false scope.setfalse <- function () { buffstatus = false } } if (scope.buffstatus) return local particles_to_play if (RandomInt(0, 1) == 0) { self.AddCustomAttribute("CARD: move speed bonus", 1.7, 5) self.AddCustomAttribute("CARD: damage bonus", 4, 3) self.AddCustomAttribute("mult dmg vs giants", 25, 5) self.AddCustomAttribute("heal on kill", 1500, 5) self.AddCustomAttribute("fire rate bonus HIDDEN", 1.1, 5) self.AddCustomAttribute("CARD: dmg taken from bullets reduced", 0.8, 5) particles_to_play = ["utaunt_elebound_yellow_parent", "utaunt_elebound_yellow_glow"] } else { self.AddCustomAttribute("CARD: move speed bonus", 0.9, 5) self.AddCustomAttribute("CARD: damage bonus", 0.8, 5) self.AddCustomAttribute("CARD: health regen", 100, 5) self.AddCustomAttribute("fire rate bonus HIDDEN", 0.85, 5) self.AddCustomAttribute("dmg from ranged reduced", 0.25, 5) 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 }) PrecacheSound("ptx/other/demon_health_restored.wav") HellOnEarth.playSoundFromEntity(self, "ptx/other/demon_health_restored.wav") scope.buffstatus = true EntFireByHandle(self, "CallScriptFunction", "setfalse", 5, null, null) BuffIndicator.AcceptInput("SetParent", "!activator", self, null) BuffIndicatorGlow.AcceptInput("SetParent", "!activator", self, null) EntFireByHandle(BuffIndicator, "Stop", null, 5, null, null) EntFireByHandle(BuffIndicatorGlow, "Stop", null, 5, null, null) EntFireByHandle(BuffIndicator, "Kill", null, 5.7, null, null) EntFireByHandle(BuffIndicatorGlow, "Kill", null, 5.7, null, null) } function BFGProjectileLogic(self) { for (local hProj; hProj = Entities.FindByClassnameWithin(hProj, "tf_projectile_*", self.GetOrigin(), 200);) { if (hProj.GetOwner() == self && !hProj.IsEFlagSet(EFL_IS_BEING_LIFTED_BY_BARNACLE)) { hProj.ValidateScriptScope() hProj.KeyValueFromString("targetname", "bfg_projectile_core") hProj.GetScriptScope().BFGBallThink <- function() { for (local player; player = Entities.FindByClassname(player, "player");) { if (player.GetTeam() != self.GetTeam() && !player.IsEFlagSet(EFL_IS_BEING_LIFTED_BY_BARNACLE)) { local hBeam = CreateByClassname("env_laser") hBeam.KeyValueFromInt("ClipStyle", 1) hBeam.KeyValueFromInt("width", 3) hBeam.KeyValueFromInt("renderamt", 255) hBeam.KeyValueFromString("rendercolor", "55 255 55") hBeam.KeyValueFromInt("damage", 0) hBeam.KeyValueFromInt("NoiseAmplitude", 2) hBeam.KeyValueFromInt("dissolvetype", 1) hBeam.KeyValueFromString("texture", "sprites/laserbeam.spr") hBeam.KeyValueFromString("LaserTarget", "bignet") hBeam.DispatchSpawn() hBeam.SetOrigin(self.GetOrigin()) hBeam.AcceptInput("SetParent", "bfg_projectile_core", null, null) NetProps.SetPropEntityArray(hBeam, "m_hAttachEntity", player, 0) hBeam.AcceptInput("TurnOn", "", null, null) EntFireByHandle(hBeam, "Kill", "", 2, null, null) player.AddEFlags(EFL_IS_BEING_LIFTED_BY_BARNACLE) EntFireByHandle(player, "RunScriptCode", "self.RemoveEFlags(EFL_IS_BEING_LIFTED_BY_BARNACLE)", 2, null, null) } } return -1 } AddThinkToEnt(hProj, "BFGBallThink") hProj.AddEFlags(EFL_IS_BEING_LIFTED_BY_BARNACLE) } } } function engyParticle(building) { if (!building || !building.IsAlive() || !HellOnEarth.ENGINEER_SETUP) return 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 }) EntFire("spawnbot_allies_l", "Enable", null, 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", 35, 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([ ["scout_fan_giant", 6, MVM_CLASS_FLAG_MINIBOSS], ["soldier_spammer", 2, MVM_CLASS_FLAG_MINIBOSS], ["heavy_armored", 1, MVM_CLASS_FLAG_MINIBOSS], ["pyro_degreaser_axtinguisher", 2, MVM_CLASS_FLAG_MINIBOSS], ["shotgun_reserve_armored", 4, MVM_CLASS_FLAG_NORMAL], ["heavy_champ", 44, MVM_CLASS_FLAG_NORMAL], ["heavy_gru", 20, MVM_CLASS_FLAG_NORMAL], ["scout_bonk", 21, MVM_CLASS_FLAG_NORMAL], ["demo_burst_critcan", 12, MVM_CLASS_FLAG_NORMAL], ]) break } } function OnGameEvent_recalculate_holidays(_) { if(GetRoundState() == 3) { if(GetPropString(hObjectiveResource, "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) NetProps.SetPropString(hPlayer, "m_iszScriptThinkFunction", "") AddThinkToEnt(hPlayer, "") if(hPlayer.GetTeam() == 3) { hPlayer.ForceChangeTeam(2, true) hPlayer.ForceRespawn() } } delete ::HellOnEarth delete ::BFGBallThink } } 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 - blood swamps // 5 - reclaimed earth // 6 - break music // 7 - atone intro 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.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() } // by lite function SendAnnotationOn(hEnt, sText, flDuration, bVisibleToOthers = false, flDelay = -1) { if(flDelay < 0.033) flDelay = 0.033 local bPlayer = hEnt.IsPlayer() local bRealClient = bPlayer && !hEnt.IsFakeClient() local hAnnotationFollow if(bRealClient) { hAnnotationFollow = SpawnEntityFromTable("prop_dynamic", { model = "models/props_hydro/barrel_crate_half.mdl", origin = "400 0 60", disableshadows = 1 }) hAnnotationFollow.DisableDraw() SetAlwaysTransmit(hAnnotationFollow) SetPropEntity(hAnnotationFollow, "m_hMovePeer", hEnt.FirstMoveChild()) SetPropEntity(hEnt, "m_hMoveChild", hAnnotationFollow) SetPropEntity(hAnnotationFollow, "m_hMoveParent", hEnt) EntFireByHandle(hAnnotationFollow, "Kill", null, flDelay + flDuration + 0.2, null, null) SetPropBool(hAnnotationFollow, "m_bForcePurgeFixedupStrings", true) } EntFireByHandle(SetAlwaysTransmit(hEnt), "Kill", null, flDelay + flDuration + 0.2, null, null) DoEntFire("bignet", "RunScriptCode" format(@" local index = activator.entindex() 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 })} %s %s", sText, 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, 30, hPlayer) ClientPrint(hPlayer, 3, "\x07ff5b30You survived... \x07FFFFFFThe respawn system is back online!") } else { hPlayer.ForceRegenerateAndRespawn() hPlayer.Weapon_Switch(GetItemInSlot(hPlayer, 0)) 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() { EntFire("explanation_stuff", "Kill") 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)", -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 HellOnEarth.CreatePointThink() HellOnEarth.AddTeamPoints(-1) Convars.SetValue("sig_mvm_jointeam_blue_allow", 1) Convars.SetValue("sig_mvm_jointeam_blue_allow_max", 6) Convars.SetValue("tf_mvm_buybacks_method", 1) Convars.SetValue("tf_mvm_buybacks_per_wave", 0) for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if (!hPlayer || hPlayer.IsFakeClient() || hPlayer.GetTeam() == 1) continue HellOnEarth.ChangePlayerTeamMvM(hPlayer, 3) SetRespawnTimeAll(9999) EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.PlayerAttributes(self)", 0.1, null, null) 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) } } } local collectionradius = 0 hPlayer_scope.ThinkTable.ReverseMVMCurrencyThink <- function() { local origin = self.GetOrigin() self.GetPlayerClass() != TF_CLASS_SCOUT ? collectionradius = 72 : collectionradius = 288 for ( local moneypile; moneypile = FindByClassnameWithin(moneypile, "item_currencypack_*", origin, collectionradius); ) { // NEW COLLECTION METHOD (royal) local moneyOwner = GetPropEntity(moneypile, "m_hOwnerEntity") local objectiveResource = hObjectiveResource local moneyBefore = GetPropInt(hObjectiveResource, "m_nMvMWorldMoney") moneypile.SetAbsOrigin(Vector(-1000000, -1000000, -1000000)) moneypile.Kill() local moneyAfter = GetPropInt(hObjectiveResource, "m_nMvMWorldMoney") local moneyValue = moneyBefore - moneyAfter local CREDITS_ACQUIRED_PROP = "m_currentWaveStats.nCreditsAcquired" local mvmStatsEnt = FindByClassname(null, "tf_mann_vs_machine_stats") SetPropInt(mvmStatsEnt, CREDITS_ACQUIRED_PROP, GetPropInt(mvmStatsEnt, CREDITS_ACQUIRED_PROP) + moneyValue) for (local i = 1, player; i <= MAX_CLIENTS; i++) if (player = PlayerInstanceFromIndex(i), player && !IsPlayerABot(player)) player.AddCurrency(moneyValue) EmitSoundOn("MVM.MoneyPickup", self) if (self.GetPlayerClass() == TF_CLASS_SCOUT) { local curHealth = self.GetHealth() local maxHealth = self.GetMaxHealth() local healthAddition = curHealth < maxHealth ? 50 : 25 local healthCap = maxHealth * 4 if ( curHealth > healthCap ) { healthAddition = RemapValClamped( curHealth, healthCap, (healthCap * 1.5), 20, 5 ) } self.SetHealth(curHealth + healthAddition) } } // The money counters are fucked from what we did in the above loop, fix it here // SetPropInt(PopExtUtil.ObjectiveResource, "m_nMvMWorldMoney", money) // SetPropInt(PopExtUtil.MvMStatsEnt, "m_previousWaveStats.nCreditsDropped", prev_wave_money) // SetPropInt(PopExtUtil.MvMStatsEnt, "m_currentWaveStats.nCreditsDropped", current_wave_money) } } for (local x = -1600.211426; x <= 1386.814331; x += 450) { for (local y = 2326.353760; y >= -2788.551270; y -= 450) { SpawnEntityFromTable("info_particle_system", { targetname = "fire_rain", origin = Vector(x, y, -20), effect_name = "cauldron_embers", start_active = 1, angles = Vector(1, 0, 0), flag_as_weather = 1 }) DispatchParticleEffectObj("cauldron_embers", Vector(x, y, -20), Vector(1, 0, 0), "fire_rain"); } } HellOnEarth.ShowDiffImage(CURR_RANK_IMAGE) HellOnEarth.AlternateWavebars(0) } function ReinforcementsTimer() { IncludeScript("textualtimer_v3", getroottable()) TextualTimer.SetParams({ minutes = 3 seconds = 0 x = -1 y = 0.77 color = "75 131 255" 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 GameOverUtils() { local delay = 0 for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(!hPlayer || hPlayer.IsFakeClient()) continue ScreenFade(hPlayer, 0, 0, 0, 255, 10, 100, 2) } foreach (vec in telePoints_GIGA) { EntFire("bignet", "runscriptcode", format("HellOnEarth.CreateRocket(Vector(%i,%i,%i))", vec.x, vec.y, vec.z), RandomFloat(delay, delay + 1)) delay +=1.5 } } function LoseConditionTimer() { IncludeScript("textualtimer_v3", getroottable()) TextualTimer.SetParams({ minutes = 1 seconds = 0 x = -1 y = 0.77 color = "255 30 30" relayname = "gameover_relay" }) 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") EntFire("red_fade_timer", "Enable") EntFire("alarm_flash_long", "Enable") } "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") EntFire("red_fade_timer", "Disable") EntFire("alarm_flash_long", "Disable") } }) TextualTimer.bHideText = false 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, 40) } function bluRobotStun() { BOTS_PEACEFUL = true EntFire("intel", "ForceDrop", null, 0, null) EntFire("intel", "ForceResetSilent", null, 0.1, null) PrecacheScriptSound("TFPlayer.InvulnerableOn") 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) hPlayer.AddCondEx(52, 5.5, null) HellOnEarth.playSoundToEveryone("TFPlayer.InvulnerableOn") 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, 1500) } } } 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 MoveRocks() { for (local ent; ent = Entities.FindByName(ent, "rock");) { ent.ValidateScriptScope() local hPropScope = ent.GetScriptScope() hPropScope.MoveDuration <- RandomFloat(4.0, 10.0) hPropScope.StartTime <- Time() hPropScope.StartPos <- ent.GetOrigin() hPropScope.EndPos <- hPropScope.StartPos + Vector(0, 0, 1300) hPropScope.Think <- function() { local t = Time() - StartTime local progress = t / MoveDuration if (progress >= 1.0) { self.SetAbsOrigin(EndPos) NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") return -1 } local newPos = StartPos + Vector(0, 0, 1300 * progress) self.SetAbsOrigin(newPos) return -1 } AddThinkToEnt(ent, "Think") } } function CreateToxicGoo(hBot, vOrigin) { DispatchParticleEffect("railgun_explode_pulse4", vOrigin, Vector(0, 0, 0)) local Trace = { start = vOrigin, end = vOrigin - Vector(0, 0, 1000), mask = MASK_VISIBLE_AND_NPCS & ~(CONTENTS_MONSTER) } TraceLineEx(Trace) if (!Trace.hit) return local normal = Trace.plane_normal local hGoo = SpawnEntityFromTable("info_particle_system", { effect_name = "acid_ground", start_active = 1 }) local hFire = SpawnEntityFromTable("info_particle_system", { effect_name = "railgun_broken_fire", start_active = 1 }) local hFog = SpawnEntityFromTable("info_particle_system", { effect_name = "area_of_fog", start_active = 1 }) hGoo.SetAbsOrigin(Trace.pos + Vector(0, 0, 3)) hFire.SetAbsOrigin(Trace.pos + Vector(0, 0, 3)) hFog.SetAbsOrigin(Trace.pos + Vector(0, 0, 50)) PrecacheSound("ambient/fire/firebig.wav") EmitSoundOn("ambient/fire/firebig.wav", hFire) EntFireByHandle(hFire, "runscriptcode", "StopSoundOn(`ambient/fire/firebig.wav`,self)", 9.9, null, null) hFog.ValidateScriptScope() local hFogScope = hFog.GetScriptScope() local flDmgRampup = 1 local tTypesToDmg = [ "player", "obj_sentrygun", "obj_dispenser", "obj_teleporter" ] hFogScope.Think <- function() { for (local i = 0; i < tTypesToDmg.len(); i = i + 1) { for (local hEnt = null; hEnt = Entities.FindByClassnameWithin(hEnt, tTypesToDmg[i], Trace.pos, 300);) { if (!hEnt || !hEnt.IsValid()) {continue} if (0 != NetProps.GetPropInt(hEnt, "m_lifeState") || hEnt.GetTeam() == TEAM_SPECTATOR) {continue} if (hEnt.GetTeam() == TF_TEAM_PVE_DEFENDERS) { DispatchParticleEffect("healthgained_red_large", hEnt.EyePosition() + Vector(0, 0, hEnt.GetModelScale() * 10), Vector(0, 0, 0)) hEnt.AddCondEx(16, 1, null) hEnt.AddCondEx(32, 1, null) hEnt.SetHealth(hEnt.GetHealth() + 50 < hEnt.GetMaxHealth() + 25 ? hEnt.GetMaxHealth() + 50 : hEnt.GetHealth()) } else { DispatchParticleEffect("lava_playertouch_embers", hEnt.GetCenter(), Vector(0, 0, 0)) hEnt.TakeDamageEx(hBot, hBot, null, Vector(0, 0, 1), Vector(0, 0, 1), 10 * flDmgRampup, DMG_BURN) flDmgRampup *= 1.4 hEnt.AddCondEx(22 1, null) local flCurrSpeed = hEnt.GetCustomAttribute("major move speed bonus", 1) hEnt.AddCustomAttribute("major move speed bonus", flCurrSpeed - 0.15 > 0 ? flCurrSpeed - 0.15 : 0.01, 1) ScreenFade(null, 255, 25, 25, 80, 2, 0.1, 1) } } } return 0.5 } AddThinkToEnt(hFog, "Think") EntFireByHandle(hGoo, "Kill", null, 10, null, null) EntFireByHandle(hFog, "Kill", null, 10, null, null) EntFireByHandle(hFire, "Kill", null, 10, null, null) } function CreateRocket(hTarget, sfx = true) { local hSkyPosition = hTarget + Vector(RandomInt(-900, 900), RandomInt(-900, 900), 1400) local hRocket = SpawnEntityFromTable("prop_dynamic", { DisableBoneFollowers = "1", model = "models/props_combine/headcrabcannister01a.mdl", modelscale = "1", StartDisabled = "1", rendercolor = "125 0 0", }) hRocket.SetAbsOrigin(hSkyPosition) local dir = (hTarget - hSkyPosition) dir.Norm() hRocket.SetForwardVector(dir) if (sfx) HellOnEarth.playSoundFromEntity(hRocket, "misc/doomsday_missile_launch.wav") EntFire("tf_gamerules", "PlayVO", "ptx/cinematic/axe_warning_red.wav", 0, null) hRocket.ValidateScriptScope() local hRocketScope = hRocket.GetScriptScope() hRocketScope.hIndicator <- SpawnEntityFromTable("prop_dynamic", { model = "models/props_mvm/indicator/indicator_circle.mdl", modelscale = "5", DisableBoneFollowers = "1", skin = "5", DefaultAnim = "start", disableshadows = "1", StartDisabled = "0" }); hRocketScope.hIndicator.SetAbsOrigin(hTarget + Vector(0, 0, -15)) hRocketScope.hTrail2 <- SpawnEntityFromTable("info_particle_system", { effect_name = "rockettrail_doomsday" start_active = 0 }) hRocketScope.hTrail2.SetAbsOrigin(hSkyPosition + dir * 10) hRocketScope.hTrail2.SetForwardVector(dir) hRocketScope.hTrail2.AcceptInput("SetParent", "!activator", hRocket, null) hRocketScope.ROCKET_LAUNCH_TIME <- Time() + 3.75 hRocketScope.DO_ROCKET_LAUNCH <- true hRocketScope.LerpConst <- hTarget - hSkyPosition hRocketScope.rocketStarted <- false hRocketScope.ROCKET_HIT_TIME <- -1 hRocketScope.Think <- function() { if (Time() >= ROCKET_LAUNCH_TIME && DO_ROCKET_LAUNCH) { local t = (Time() - ROCKET_LAUNCH_TIME) / 1.25 if (t >= 1.0) { hRocket.SetAbsOrigin(hTarget) DO_ROCKET_LAUNCH = false hRocket.AcceptInput("Disable", null, null, null) hIndicator.Kill() ScreenShake(hTarget, 40, 16, 1, 0, 0, true) DispatchParticleEffect("fireSmoke_Collumn_mvmAcres", hTarget, Vector(-90, 0, 0)) DispatchParticleEffect("mvm_tank_destroy_embers", hTarget, Vector(0, 0, 0)) HellOnEarth.playSoundFromEntity(hRocket, "ptx/cinematic/asteroid_collision_02.wav") ROCKET_HIT_TIME = Time() for (local i = 0; i < enemy_types_to_damage.len(); i = i + 1) { for (local entity_to_damage = null; entity_to_damage = Entities.FindByClassnameWithin(entity_to_damage, enemy_types_to_damage[i], hTarget, 225);) { if (!entity_to_damage || !entity_to_damage.IsValid()) continue if (0 != NetProps.GetPropInt(entity_to_damage, "m_lifeState")) continue entity_to_damage.TakeDamage(250, DMG_BLAST, null) } } return -1 } else { local easedT = t * t local newPos = hSkyPosition + (LerpConst * easedT) hRocket.SetAbsOrigin(newPos) if (!rocketStarted) { rocketStarted = true hRocket.AcceptInput("Enable", null, null, null) hRocketScope.hTrail2.AcceptInput("Start", null, null, null) } } } if (ROCKET_HIT_TIME >= 0 && Time() >= ROCKET_HIT_TIME + 1.0) { hTrail2.Kill() hRocket.Kill() NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") } return -1 } AddThinkToEnt(hRocket, "Think") } function EternalWeapons(hPlayer) { if (!hPlayer || !hPlayer.IsValid() || !hPlayer.IsAlive()) return hPlayer.ValidateScriptScope() local hPlayer_scope = hPlayer.GetScriptScope() if (!("ThinkTable" in hPlayer_scope)) hPlayer_scope.ThinkTable<- {} hPlayer_scope.LastActiveWeapon <- hPlayer.GetActiveWeapon() hPlayer_scope.LastActiveWeaponAmmo <- hPlayer_scope.LastActiveWeapon.Clip1() hPlayer_scope.CurrentActiveWeapon <- hPlayer.GetActiveWeapon() hPlayer_scope.SWAP_COUNT <- 0 hPlayer_scope.HasFired <- false hPlayer_scope.ThinkTable.EternalThink <- function() { if (self.IsAlive()) { CurrentActiveWeapon = self.GetActiveWeapon() if (!CurrentActiveWeapon || !LastActiveWeapon || !CurrentActiveWeapon.IsValid() || !LastActiveWeapon.IsValid()) { CurrentActiveWeapon = self.GetActiveWeapon() LastActiveWeapon = self.GetActiveWeapon() } if (LastActiveWeapon.Clip1() < LastActiveWeaponAmmo) { LastActiveWeaponAmmo = LastActiveWeapon.Clip1() HasFired = true } else if (LastActiveWeapon.Clip1() > LastActiveWeaponAmmo) { LastActiveWeaponAmmo = LastActiveWeapon.Clip1() } if (CurrentActiveWeapon != LastActiveWeapon && HasFired) { SWAP_COUNT++ HasFired = false SetPropFloat(LastActiveWeapon, "m_flNextPrimaryAttack", 0) local ammo = GetPropIntArray(self, "m_iAmmo", LastActiveWeapon.GetPrimaryAmmoType()) if (LastActiveWeapon.Clip1() == 0 && ammo > 0) { LastActiveWeapon.SetClip1(1) SetPropIntArray(self, "m_iAmmo", ammo - 1, LastActiveWeapon.GetPrimaryAmmoType()) } LastActiveWeapon = CurrentActiveWeapon LastActiveWeaponAmmo = LastActiveWeapon.Clip1() } if (SWAP_COUNT == 5) { self.AddCondEx(TF_COND_SPEED_BOOST, 5, null) self.AddCustomAttribute("reload time increased hidden", 0.7, 5) SWAP_COUNT = 0 } } } } function ProcessButton(player, index) { switch (index) { case 1: if (player.GetFlags() & FL_DUCKING) return true return false break case 2: if (player.IsUsingActionSlot()) return true return false break default: return false break } } function ChangeDashButton(hPlayer) { hPlayer.ValidateScriptScope() local hPlayer_scope = hPlayer.GetScriptScope() hPlayer_scope.iDashButtonIndex = (hPlayer_scope.iDashButtonIndex % 2) + 1 switch (hPlayer_scope.iDashButtonIndex) { case 1: ClientPrint(hPlayer, 3, "\x07BEB9E0DASH BOUND TO: \x07FFFF00CROUCH") break case 2: ClientPrint(hPlayer, 3, "\x07BEB9E0DASH BOUND TO: \x07FFFF00ACTION SLOT") break default: ClientPrint(hPlayer, 3, "\x07FFFF00DASH NOT BOUND") } HellOnEarth.playSoundFromEntity(hPlayer, "buttons/button3.wav") DispatchParticleEffect("mvm_pow_smash", Vector(360, -3426, 140), Vector()) } 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.iDashButtonIndex <- 1 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 { if (HellOnEarth.DISPLAY_TEXT) hGameText.AcceptInput("Display", null, hPlayer, null) } catch(Exception) { local i = 1 } if (iDashesCount == 1 && HellOnEarth.ProcessButton(hPlayer, iDashButtonIndex)) { 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 = 2 switch (hPlayer.GetPlayerClass()) { case 1: // scout cooldown = 2 break case 2: // Sniper cooldown = 3 break case 3: // Soldier cooldown = 3 break case 4: // Demo cooldown = 3 case 5: // Medic cooldown = 3 break case 9: // Engy cooldown = 4 break case 6: // Heavy cooldown = 3 break case 7: // Pyro cooldown = 3 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("bot_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 local tab = {} hEntity.GetAllBotTags(tab) foreach(tag in tab) { if (tag.find("time_add") == 0) { hItem_scope.TIME_GLOW <- SpawnEntityFromTable("tf_glow", { GlowColor = "255 255 255 255" target = "bignet" }) } } hItem_scope.Think <- function() { if (hItem_scope.doParticle) { if (hEntity.HasBotTag("bot_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(1750 / 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(1500 / 36))).tointeger() EmitSoundEx({ sound_name = "#ptx/misc/demonic_spawn.wav" origin = hPos volume = 1 sound_level = snd_lvl }) if (hEntity.HasBotTag("bot_posessed")) { DispatchParticleEffect("eyeboss_tp_escape", hPos, Vector(0, 0, 50)) } else if (hEntity.GetMaxHealth() > 4000) { DispatchParticleEffect("halloween_boss_summon", hPos, Vector(0, 0, 120)) } else if (hEntity.GetMaxHealth() > 10000) { DispatchParticleEffect("doom_hellunit_spawn_large", hPos, Vector(0, 0, 0)) } HellOnEarth.resetTakenTelePoint(hEntity, RESET_INDEX) if ("TIME_GLOW" in self.GetScriptScope()) { SetPropEntity(TIME_GLOW, "m_hTarget", hEntity) } } 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 = 3) { 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 PlayerAttributes(hPlayer) { if (hPlayer.IsBotOfType(1337)) return hPlayer.AddCustomAttribute("crit mod disabled", 0, -1) hPlayer.AddCustomAttribute("is miniboss", 1, -1) hPlayer.AddCustomAttribute("ammo regen", 0, -1) hPlayer.AddCustomAttribute("can headshot", 1, -1) } function SlowBots() { for(local i = 1; i <= MAX_CLIENTS; i++) { local hEnt = PlayerInstanceFromIndex(i) if (hEnt && hEnt.IsAlive()) { if (hEnt.IsBotOfType(TF_BOT_TYPE)) { hEnt.AddCustomAttribute("CARD: move speed bonus", 0.01, 7.4) hEnt.AddCustomAttribute("no_attack", 1, 7.4) } else { // assuming this is a player hEnt.AddCondEx(51, 7.4, null) EntFireByHandle(hEnt, "runscriptcode", "self.AddCustomAttribute(`SET BONUS: health regen set bonus`, 20, 5)", 7.4, hEnt, hEnt) } } } } function MarauderProp() { local hProp = SpawnEntityFromTable("prop_dynamic", { targetname = "marauder_prop", DisableBoneFollowers = "1", model = "models/doom_eternal/demons/marauder_new.mdl", modelscale = "1.25", origin = "-92 270 65", angles = "0 -90 0", StartDisabled = 1, skin = 1 }) hProp.ValidateScriptScope() local propScope = hProp.GetScriptScope() propScope.Think <- function() { local origin = self.GetOrigin() local Trace = { start = origin end = origin - Vector(0, 0, 250) mask = MASK_VISIBLE_AND_NPCS & ~(CONTENTS_MONSTER) } TraceLineEx(Trace) self.SetAbsOrigin(Trace.pos) return -1 } AddThinkToEnt(hProp, "Think") } function EngyCanTeleport() { HellOnEarth.ENGINEER_SETUP = false HellOnEarth.engyParticle(HellOnEarth.ENGINEER_TELEPORTER) } function finalizeTeleportation(hPlayer) { if (hPlayer.HasBotTag("bot_rocketspawn")) { local o = PickRandomItem(telePoints_GIGA) HellOnEarth.CreateRocket(o) DispatchParticleEffect EntFireByHandle(hPlayer, "$SetLocalOrigin", format("%g %g %g", o.x, o.y, o.z), 5.1, hPlayer, hPlayer) EntFireByHandle(hPlayer, "RunScriptCode", format("DispatchParticleEffect(`doom_hellunit_spawn_large`, Vector(%g, %g, %g), Vector())",o.x, o.y, o.z), 5.1, hPlayer, hPlayer) DispatchParticleEffect("doom_hellunit_spawn_large", o, Vector(0, 0, 0)) } if (hPlayer.HasBotTag("bot_gorenest_spawn")) { EntFireByHandle(hPlayer, "$SetLocalOrigin", format("%g %g %g", -190, 1560, -60), -1, hPlayer, hPlayer) if (hPlayer.HasBotTag("bot_bombcarrier")) hPlayer.AcceptInput("$BotCommand", "switch_action FetchFlag", null, null) return } 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 AddToTime(seconds) { TextualTimer.Add(seconds) PrecacheSound("vo/announcer_time_added.mp3") PrecacheSound("ptx/other/armor_pickup.wav") HellOnEarth.playSoundToEveryone("vo/announcer_time_added.mp3") HellOnEarth.playSoundToEveryone("ptx/other/armor_pickup.wav") EntFire("red_fade_timer", "Disable") EntFire("alarm_flash_long", "Disable") } function Countdown(seconds) { local s for (local i = 0; i < seconds + 1; i++) { EntFire("bignet", "runscriptcode", (seconds - i).tostring(), i) } } // EVENTS --------------------------------- EVENTS function OnGameEvent_player_spawn(params) { local hPlayer = GetPlayerFromUserID(params.userid); EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.BotTagsAndAttrs(self)", 0.1, 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", "HellOnEarth.ChangePlayerTeamMvM(self,3)", -1, null, null) } else if (!RED_PLAYERS && !hPlayer.IsBotOfType(TF_BOT_TYPE)) { EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.PlayerAttributes(self)", 0.1, null, null) } if (hPlayer != null && hPlayer.IsBotOfType(TF_BOT_TYPE)) { if (MAIN_WAVE_ACTIVE) { EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.finalizeTeleportation(self)", 0.01, null, null) EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.TimedBotSetup(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) HellOnEarth.ENGINEER_TELEPORTER = building EntFireByHandle(building, "runscriptcode", "HellOnEarth.engyParticle(self)", 20, null, null) SetDestroyCallback(building, function() { EntFire("spawnbot_allies_l", "Disable") EntFire("engi_teleporter", "Stop") EntFire("engi_teleporter", "Kill", null, 1) }) } } } function OnScriptHook_OnTakeDamage(params) { local hVictim = params.const_entity if (!hVictim.IsPlayer()) return if(hVictim && hVictim.IsBotOfType(TF_BOT_TYPE)) { if(hVictim.HasBotTag("bot_metal")) DispatchParticleEffect("projectile_fireball_crit_red_sparks", 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)) if(hVictim.HasBotTag("bot_posessed_big")) DispatchParticleEffect("dskart_blade_hit", params.damage_position, Vector(0, 0, 1)) } local hPlayer = params.attacker local wep = params.weapon if ((hPlayer && !hPlayer.IsPlayer()) || !hVictim.IsPlayer()) return function CanHeadshot() { if (GetPropInt(hVictim, "m_LastHitGroup") == HITGROUP_HEAD || (params.damage_stats == TF_DMG_CUSTOM_HEADSHOT && !(params.damage_type & DMG_CRITICAL))) { if (hPlayer.GetPlayerClass() == TF_CLASS_SNIPER && wep && wep.GetSlot() != 1 && GetPropInt(wep, "m_AttributeManager.m_Item.m_iItemDefinitionIndex") != 230) return true if (GetPropFloat(wep, "m_flChargedDamage") >= 150.0 && GetPropInt(wep, "m_AttributeManager.m_Item.m_iItemDefinitionIndex") == 1098) return true if (GetPropInt(wep, "m_AttributeManager.m_Item.m_iItemDefinitionIndex") == 61 || GetPropInt(wep, "m_AttributeManager.m_Item.m_iItemDefinitionIndex") == 1006) return true if (hPlayer.GetCustomAttribute("can headshot", -1) != -1) return true if (!hVictim.InCond(TF_COND_BLEEDING) && !(GetPropInt(hVictim, "m_iStunFlags") & 1)) return true } return false } if (!CanHeadshot()) return params.damage_type = params.damage_type | DMG_CRITICAL //DMG_USE_HITLOCATIONS doesn't actually work here, no headshot icon. params.damage_stats = TF_DMG_CUSTOM_HEADSHOT } 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_fire")) DispatchParticleEffect("projectile_fireball", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_explode_death")) DispatchParticleEffect("railgun_single_explode", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_argent")) DispatchParticleEffect("spell_batball_impact_red", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_toxic")) DispatchParticleEffect("spore_splash", 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("dskart_blade_hit", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_posessed_big")) DispatchParticleEffect("halloween_boss_death_cloud", hPlayer.GetCenter(), Vector(0,0,0)) if (hPlayer.HasBotTag("bot_buff_goo")) CreateToxicGoo(hPlayer, hPlayer.GetCenter()) if (hPlayer.HasBotTag("bot_explode_death_damage")) { DispatchParticleEffect("doom_cyberdemon_missile_blast", hPlayer.GetCenter(), Vector(0,0,0)) local bomb = SpawnEntityFromTable("tf_generic_bomb", { sound = "ambient/levels/labs/electric_explosion2.wav", damage = 150, radius = 135, friendlyfire = "0", }); NetProps.SetPropEntity(bomb, "m_hOwner", hPlayer) bomb.DispatchSpawn() bomb.KeyValueFromString("classname", "megaton") bomb.AcceptInput("Detonate", null, hPlayer, hPlayer) EntFireByHandle(bomb, "Kill", "", 0.1, null, null); } if (hPlayer.HasBotTag("bot_vip")) { NetProps.SetPropString(ENGINEER_THINK_ADD, "m_iszScriptThinkFunction", "") PrecacheSound("misc/halloween/merasmus_death.wav") HellOnEarth.playSoundToEveryone("misc/halloween/merasmus_death.wav") ClientPrint(null, 3, "\x07FF0000//////WARNING//////") ClientPrint(null, 3, "\x07FF0000THE VIP HAS DIED") ClientPrint(null, 3, "\x07FF0000//////WARNING//////") ScreenShake(Vector(0, 0, 0), 25, 25, 2, 9999, 0, true) if (HellOnEarth.VIP_DEATH_LOSE_COND) { SpawnEntityFromTable("game_round_win", { teamnum = 2, force_map_reset = 1 }).AcceptInput("RoundWin", null, null, null) } } local tab = {} hPlayer.GetAllBotTags(tab) foreach(tag in tab) { if (tag.find("time_add") == 0) { local parts = split(tag, "_") if (parts.len() == 3 && TextualTimer) { // NOT TESTED local hItem for (local hChild = hPlayer.FirstMoveChild(); hChild; hChild = hChild.NextMovePeer()) { if(hChild.GetClassname() == "tf_weapon_spellbook") { hItem = hChild; break } } if (!hItem) return SetPropBool(hItem, "m_bForcePurgeFixedupStrings", true) hItem.ValidateScriptScope() if ("TIME_GLOW" in hItem.GetScriptScope()) { EntFireByHandle(hItem.GetScriptScope().TIME_GLOW, "Kill", "", -1, null, null) } TextualTimer.Add(parts[2].tointeger()) PrecacheSound("vo/announcer_time_added.mp3") PrecacheSound("ptx/other/armor_pickup.wav") HellOnEarth.playSoundToEveryone("vo/announcer_time_added.mp3") HellOnEarth.playSoundToEveryone("ptx/other/armor_pickup.wav") EntFire("red_fade_timer", "Disable") EntFire("alarm_flash_long", "Disable") break } } } } else { PrecacheSound("Halloween.Screams") HellOnEarth.playSoundToEveryone("Halloween.Screams") 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 (!hPlayer.IsBotOfType(TF_BOT_TYPE)) iAlivePlayers-- if(iAlivePlayers == 1 && !hPlayer.IsBotOfType(TF_BOT_TYPE)) { hPlayer.AddCondEx(97, -1, null) hPlayer.AddCondEx(16, -1, null) ScreenShake(Vector(0, 0, 0), 15, 15, 2, 9999, 0, true) for(local i = 1; i <= MAX_CLIENTS; i++) { local hBot = PlayerInstanceFromIndex(i) if (hBot && hBot.IsBotOfType(TF_BOT_TYPE) && hBot.GetTeam() != hPlayer.GetTeam()) { hPlayer.AddCondEx(32, -1, null) } } } if(iAlivePlayers == 0) { SpawnEntityFromTable("game_round_win", { teamnum = 2, force_map_reset = 1 }).AcceptInput("RoundWin", null, null, null) } } } } } for(local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(hPlayer && hPlayer.IsFakeClient()) AddThinkToEnt(hPlayer, null) NetProps.SetPropString(hPlayer, "m_iszScriptThinkFunction", "") } HellOnEarth.DistributeDash() EntFire("tf_objective_resource", "$SetClientProp$m_nMannVsMachineMaxWaveCount", "5", -1) __CollectGameEventCallbacks(HellOnEarth)