::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("vo/announcer_time_added.mp3") PrecacheSound("ptx/other/armor_pickup.wav") PrecacheSound("ptx/cinematic/axe_warning_red.wav") PrecacheSound("ptx/cinematic/asteroid_collision_02.wav") PrecacheSound("ptx/other/mod_pickup.wav") PrecacheSound("ptx/weapons/hammer_slam.wav") PrecacheSound("ptx/weapons/hammer_slam_setup.wav") PrecacheSound("weapons/mortar/mortar_shell_incomming1.wav") PrecacheSound("ambient/machines/aircraft_distant_flyby1.wav") PrecacheSound("ambient/machines/aircraft_distant_flyby3.wav") PrecacheSound("ptx/other/amored_activate.wav") PrecacheScriptSound("Halloween.Screams") PrecacheScriptSound("MeteorFlyby") PrecacheSound("misc/doomsday_lift_warning.wav") PrecacheSound("ambient/levels/citadel/zapper_ambient_loop1.wav") PrecacheModel("models/flags/scrap_metal_flag.mdl") PrecacheModel("models/kirillian/infected/hoomer_v4.mdl") PrecacheModel("models/doom_eternal/demons/cacodemon.mdl") PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "mvm_wood_boards_splinters"}) 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"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "utaunt_merasmus_fire"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "full_explode"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "teleporter_mvm_bot_persist_red"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "fluidSmokeExpl_ring"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "railgun_charged_live"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "teleportedin_blue"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "spell_overheal_flash_blue"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "eyeboss_tp_escape"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "wrenchmotron_teleport_beam"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "drg_wrenchmotron_teleport"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "h_fireball_mega_"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "buildingdamage_fire1"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "hcea_hunter_shade_cannon_explode_ground_flame_ring_b"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "manmelter_muzzleflash_flare"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "drg_cow_explosion_coreflash_blue"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "drg_cow_explosioncore_charged_blue"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "[1]_thunder_strike_r"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "[2]_flamestrike"}) PrecacheEntityFromTable({ classname = "info_particle_system", effect_name = "FX_green_eyeflash_flash"}) 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/baron_intro.mp3") PrecacheSound("#ptx/ost/hell_on_earth.mp3") PrecacheSound("#ptx/ost/reclaimed_earth_full.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/baron_intro.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_full.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 meteor_models = [ { "scale": 1.25, "model": "models/props_moonbase/moon_rock_small001.mdl" }, { "scale": 1, "model": "models/props_moonbase/moon_rock002_medium.mdl" }, { "scale": 0.75, "model": "models/props_moonbase/moon_rock_large001.mdl" }, { "scale": 1, "model": "models/props_moonbase/moon_rock_medium001.mdl" } ]; 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(-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), Vector(38 -2950 132) ]; // 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 = NetProps.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 SetAlwaysTransmit(hEnt) { local hEdict = SpawnEntityFromTable("info_target", {targetname = "target_alwaystransmit"}) hEdict.AddEFlags(EFL_IN_SKYBOX | EFL_FORCE_CHECK_TRANSMIT) hEdict.AcceptInput("SetParent", "!activator", hEnt, null) hEdict.SetLocalOrigin(Vector()) return hEdict } 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 VIP_DEATH_LOSE_COND = true DISPLAY_TEXT = true ENGINEER_SETUP = true ENGINEER_TELEPORTER = null ENGINEER_THINK_ADD = SpawnEntityFromTable("logic_script", {}) LOGIC_BOMB_MANAGER = null TELEPORT_LOGIC_RADIUS = 400 LAST_PLAYER_BUFF_ACTIVE = false NIGHTMARE_BUFF_ACTIVE = false ULTRA_NIGHTMARE_BUFF_ACTIVE = false LAST_CENTRAL_POS = Vector() LAST_UPDATE_TIME = 0 CACHE_DURATION = 1 TELE_CACHE = { NORMAL = null, BIG = null, GIGA = null } TELE_CACHE_TIME = { NORMAL = 0, BIG = 0, GIGA = 0 } 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 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 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" HellOnEarth.ULTRA_NIGHTMARE_BUFF_ACTIVE = true HellOnEarth.NIGHTMARE_BUFF_ACTIVE = false newImage = 4; } else if (TOTAL_TEAM_POINTS > 5000) { threshold = 9999; message = "Nightmare" HellOnEarth.ULTRA_NIGHTMARE_BUFF_ACTIVE = false HellOnEarth.NIGHTMARE_BUFF_ACTIVE = true newImage = 3; } else if (TOTAL_TEAM_POINTS > 1000) { threshold = 5000; message = "Ultra Violence" HellOnEarth.ULTRA_NIGHTMARE_BUFF_ACTIVE = false HellOnEarth.NIGHTMARE_BUFF_ACTIVE = false 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 SpawnScrapPackAt(vOrigin, sTargetName) { local hPack = CreateByClassname("item_ammopack_full") hPack.KeyValueFromString("targetname", sTargetName) hPack.KeyValueFromString("automaterialize", "false") hPack.KeyValueFromString("powerup_model", "models/flags/scrap_metal_flag.mdl") hPack.KeyValueFromInt("teamnum", 3) hPack.DispatchSpawn() hPack.ValidateScriptScope() local hPackScope = hPack.GetScriptScope() hPackScope.hGlow <- SpawnEntityFromTable("tf_glow", { GlowColor = "0 175 200 255" target = "bignet" targetname = sTargetName }) SetPropEntity(hPackScope.hGlow, "m_hTarget", hPack) hPack.SetModelScale(3, 0) hPack.SetAbsOrigin(vOrigin) } function ClearKillZone() { for (local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i); if (hPlayer && !hPlayer.IsFakeClient() && hPlayer.GetTeam() != Constants.ETFTeam.TEAM_SPECTATOR) { hClientCommand.AcceptInput("Command", "r_screenoverlay off", hPlayer, null); SetPropEntity(hPlayer, "m_Local.m_PlayerFog.m_hCtrl", null) } } } function CreateKillZone(iRadius = 1250, vOrigin = Vector(0, -700, 0)) { local hKillZone = SpawnEntityFromTable("logic_script", {targetname="KILLZONE"}) hKillZone.ValidateScriptScope() local hKillZone_scope = hKillZone.GetScriptScope() hKillZone_scope.curPoints <- HellOnEarth.TOTAL_TEAM_POINTS hKillZone_scope.baseDamage <- 3.0 hKillZone_scope.baseInterval <- 0.25 hKillZone_scope.factor <- 1.45 hKillZone_scope.maxDmg <- 200 hKillZone_scope.safeRadius <- iRadius hKillZone_scope.buildingDamage <- 100 hKillZone_scope.center <- vOrigin hKillZone_scope.exposureTable <- {} hKillZone_scope.nextDamageTime <- 0.0; hKillZone_scope.CalcOverlay <- function(hPlayer) { local suffix = floor((Time() % 10.0) / 0.2 + 0.5).tointeger() * 20; if (suffix > 980) suffix = 980; PointClientCom.AcceptInput("Command", "r_screenoverlay hoe/ebc_" + suffix.tostring(), hPlayer, null); } hKillZone_scope.PointClientCom <- CreateByClassname("point_clientcommand") hKillZone_scope.Fog <- SpawnEntityFromTable("env_fog_controller", { fogenable = true, fogcolor = "200 60 0", fogcolor2 = "200 20 20", fogstart = 100, fogend = 484, fogmaxdensity = 0.85, fogRadial = true, }) hKillZone_scope.GetKillZoneDamage <- @(t) baseDamage * pow(factor, floor(t)); hKillZone_scope.Think <- function () { local now = Time(); for (local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i); if (hPlayer && !hPlayer.IsFakeClient() && hPlayer.GetTeam() != Constants.ETFTeam.TEAM_SPECTATOR) { local id = hPlayer.entindex(); if (!hPlayer.IsAlive()) { if ((id in exposureTable) && exposureTable[id] != null && exposureTable[id].overlay != "") { PointClientCom.AcceptInput("Command", "r_screenoverlay off", hPlayer, null); SetPropEntity(hPlayer, "m_Local.m_PlayerFog.m_hCtrl", null) } exposureTable[id].enterTime = null; exposureTable[id].exitTime = null; exposureTable[id].overlay = ""; continue; } local playerPos = hPlayer.GetOrigin(); local dx = playerPos.x - center.x; local dy = playerPos.y - center.y; local dist = sqrt(dx*dx + dy*dy); if (!(id in exposureTable) || exposureTable[id] == null) exposureTable[id] <- { enterTime = null, exitTime = null, overlay = "", totalExposureTime = 1.0 }; local data = exposureTable[id]; //ClientPrint(hPlayer, 3, "Kill Zone Distance: " + dist.tostring() + ", Safe Radius: " + safeRadius.tostring()); if (dist <= safeRadius) { if (data.exitTime == null) data.exitTime = now; else if (now - data.exitTime >= 0.1) { if (data.overlay != "") PointClientCom.AcceptInput("Command", "r_screenoverlay off", hPlayer, null); SetPropEntity(hPlayer, "m_Local.m_PlayerFog.m_hCtrl", null) data.enterTime = null; data.exitTime = now; data.overlay = ""; } continue; } if (data.enterTime == null) { data.enterTime = now; if (data.overlay != "creeping") { CalcOverlay(hPlayer) SetPropEntity(hPlayer, "m_Local.m_PlayerFog.m_hCtrl", Fog) EntFireByHandle(hClientCommand, "Command", "soundfade 50 3 3 0.5", 0, hPlayer, hPlayer); data.overlay = "creeping"; } } else if (now - data.enterTime >= 4.0 && data.overlay != "constant") { PointClientCom.AcceptInput("Command", "r_screenoverlay hoe/electric_border", hPlayer, null); hPlayer.AddCustomAttribute("major move speed bonus", 0.7, 5) data.overlay = "constant"; } local exposedFor = now - data.enterTime; if (now >= nextDamageTime) { local dmg = GetKillZoneDamage.call(this, exposedFor) * data.totalExposureTime hPlayer.TakeDamage(dmg, Constants.FDmgType.DMG_PLASMA, null); EntFireByHandle(hClientCommand, "Command", "soundfade 80 2 3 0", 0, hPlayer, hPlayer); data.totalExposureTime += 0.075 } } } for (local b = null; b = Entities.FindByClassname(b, "obj*");) { if (!b.IsValid()) continue; local team = b.GetTeam(); if (team != TF_TEAM_RED && team != TF_TEAM_BLUE) continue; if (NetProps.GetPropInt(b, "m_lifeState") != 0) continue; b.TakeDamage(buildingDamage, Constants.FDmgType.DMG_PLASMA, null); } if (now >= nextDamageTime) nextDamageTime = now + 1.0; return baseInterval; } AddThinkToEnt(hKillZone, "Think") } 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", "") EntFireByHandle(hTimedScript, "Kill", "", 0.1, null, null) return -1 } if (hPlayer && !hPlayer.IsAlive()) { PrecacheSound("#ptx/other/armor_pickup.wav") NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") HellOnEarth.AddTeamPoints(floor(pointsGained * (1 - (elapsed / duration)))) EntFireByHandle(hTimedScript, "Kill", "", 0.1, null, null) 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 ResetEngineer() { local engi = ENGINEER_THINK_ADD.GetScriptScope().BOT_HANDLE engi.AcceptInput("$BotCommand", "stop interrupt action", engi, engi) engi.AcceptInput("$BotCommand", "interrupt_action -posent __MARKER__ -distance 100 -waituntildone -duration 9999", engi, engi) } function BotTagsAndAttrs(hPlayer) { if (!hPlayer || !hPlayer.IsFakeClient()) return if (HellOnEarth.LAST_PLAYER_BUFF_ACTIVE) { hPlayer.AddCondEx(32, -1, null) hPlayer.AddCondEx(19, -1, null) } else if (HellOnEarth.NIGHTMARE_BUFF_ACTIVE) { hPlayer.AddCustomAttribute("SET BONUS: move speed set bonus", 1.2 , -1) hPlayer.AddCustomAttribute("damage bonus HIDDEN", 1.3 , -1) hPlayer.AddCustomAttribute("Reload time decreased", 0.85 , -1) hPlayer.AddCustomAttribute("fire rate bonus HIDDEN", 0.85 , -1) } else if (HellOnEarth.ULTRA_NIGHTMARE_BUFF_ACTIVE) { hPlayer.AddCustomAttribute("SET BONUS: move speed set bonus", 1.4 , -1) hPlayer.AddCustomAttribute("damage bonus HIDDEN", 1.5 , -1) hPlayer.AddCustomAttribute("Reload time decreased", 0.7 , -1) hPlayer.AddCustomAttribute("fire rate bonus HIDDEN", 0.7 , -1) hPlayer.AddCustomAttribute("mult_item_meter_charge_rate", 0.7 , -1) } if (hPlayer.HasBotTag("bot_imp")) { HellOnEarth.DispatchParticleAttached(hPlayer, "scorchshot_trail_crit_red", "effect_hand_R") HellOnEarth.DispatchParticleAttached(hPlayer, "scorchshot_trail_crit_red", "effect_hand_L") return } if (hPlayer.HasBotTag("bot_green_eye_flash")) { hPlayer.ValidateScriptScope() local hScope = hPlayer.GetScriptScope() if (!("IS_VURNEABLE" in hScope)) hScope.IS_VURNEABLE <- false } 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.BOT_HANDLE <- hPlayer ENGINEER_THINK_ADD_scope.CURRENT_TARGET <- null ENGINEER_THINK_ADD_scope.CURRENT_TARGET_SCORE <- 0 ENGINEER_THINK_ADD_scope.SEEK_TARGET <- false ENGINEER_THINK_ADD_scope.Think <- function () { if (!BOT_HANDLE || !BOT_HANDLE.IsAlive() || BOT_HANDLE.GetTeam() != Constants.ETFTeam.TF_TEAM_BLUE || !SEEK_TARGET) return 0.5 for(local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if (hPlayer && !hPlayer.IsFakeClient() && hPlayer.IsAlive()) { local score = GetPropIntArray(PlayerManager, "m_iTotalScore", hPlayer.entindex()) // WARNING: NEEDS TO BE TESTED WITH MULTIPLE PLAYERS if (!CURRENT_TARGET) { CURRENT_TARGET = hPlayer CURRENT_TARGET_SCORE = score hPlayer.KeyValueFromString("targetname", "__MARKER__") BOT_HANDLE.AcceptInput("$BotCommand", "stop interrupt action", BOT_HANDLE, BOT_HANDLE) BOT_HANDLE.AcceptInput("$BotCommand", "interrupt_action -posent __MARKER__ -distance 100 -waituntildone -duration 9999", BOT_HANDLE, BOT_HANDLE) ClientPrint(null, 3, format("\x0799CCFFVIP is now following: \x07FBECCB%s", GetPropString(hPlayer, "m_szNetname"))) } else if (!CURRENT_TARGET.IsAlive() || (hPlayer.entindex() != CURRENT_TARGET.entindex() && CURRENT_TARGET_SCORE < score)) { CURRENT_TARGET.KeyValueFromString("targetname", "player") CURRENT_TARGET = hPlayer CURRENT_TARGET_SCORE = score hPlayer.KeyValueFromString("targetname", "__MARKER__") BOT_HANDLE.AcceptInput("$BotCommand", "stop interrupt action", BOT_HANDLE, BOT_HANDLE) BOT_HANDLE.AcceptInput("$BotCommand", "interrupt_action -posent __MARKER__ -distance 100 -waituntildone -duration 9999", BOT_HANDLE, BOT_HANDLE) ClientPrint(null, 3, format("\x0799CCFFVIP is now following \x07FBECCB%s", GetPropString(hPlayer, "m_szNetname"))) } } } HellOnEarth.AddTeamPoints(POINTS_TO_ADD) return 0.5 } AddThinkToEnt(ENGINEER_THINK_ADD, "Think") // Second think for the bot itself hPlayer.ValidateScriptScope() local hBotScope = hPlayer.GetScriptScope() hBotScope.ALARM_ACTIVE <- false hBotScope.hGlow <- SpawnEntityFromTable("tf_glow", { GlowColor = "153 204 255 255" target = "bignet" }) SetPropEntity(hBotScope.hGlow, "m_hTarget", hPlayer) hBotScope.Think <- function () { if (!HellOnEarth.VIP_DEATH_LOSE_COND) { EntFireByHandle(hGlow, "Kill", "", -1.0, null, null) NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") } if (!hGlow || !hGlow.IsValid()) { NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") return 0.25 } local p = (hPlayer.GetHealth() * 1.0) / hPlayer.GetMaxHealth(); if (p < 0.0) p = 0.0; if (p > 1.0) p = 1.0; local t = 1.0 - p; local r = 153.0 + (255.0 - 153.0) * t; local g = 204.0 + ( 0.0 - 204.0) * t; local b = 255.0 + ( 0.0 - 255.0) * t; local ri = floor(r + 0.5); local gi = floor(g + 0.5); local bi = floor(b + 0.5); if (hGlow && hGlow.IsValid()) hGlow.AcceptInput("SetGlowColor", format("%d %d %d 255", ri, gi, bi), null, null) local alarmOn = (p < 0.30) if (alarmOn != ALARM_ACTIVE) { EntFire("red_fade_timer", alarmOn ? "Enable" : "Disable"); ALARM_ACTIVE = alarmOn; } return 0.25; } AddThinkToEnt(hPlayer, "Think") return } if (hPlayer.HasBotTag("bot_shield_unbreakable")) // WARNING THIS MIGHT NOT DIE { hPlayer.ValidateScriptScope() local scope = hPlayer.GetScriptScope() scope.hShield <- SpawnEntityFromTable("tf_wearable", {}) NetProps.SetPropInt(scope.hShield, "m_nModelIndex", PrecacheModel("models/doom_eternal/shield_uac/shield_uac.mdl")) NetProps.SetPropBool(scope.hShield, "m_bValidatedAttachedEntity", true) scope.hShield.SetSkin(1) scope.hShield.SetModelScale(1.2,0) NetProps.SetPropEntity(scope.hShield, "m_hOwnerEntity", hPlayer) NetProps.SetPropInt(scope.hShield, "m_fEffects", NetProps.GetPropInt(scope.hShield, "m_fEffects") & ~129) scope.hShield.AcceptInput("SetParent", "!activator", hPlayer, hPlayer) scope.hShield.AcceptInput("SetParentAttachment", "flag", hPlayer, hPlayer) scope.hShield.SetLocalAngles(QAngle(5,0,62.5)) scope.hShield.SetLocalOrigin(Vector(12,-5,-32)) } else if (hPlayer.HasBotTag("bot_shield_breakable")) { hPlayer.ValidateScriptScope() local scope = hPlayer.GetScriptScope() scope.hShield <- SpawnEntityFromTable("tf_wearable", {}) scope.iShieldDamage <- 0 NetProps.SetPropInt(scope.hShield, "m_nModelIndex", PrecacheModel("models/doom_eternal/shield_uac/shield_uac_blue.mdl")) NetProps.SetPropBool(scope.hShield, "m_bValidatedAttachedEntity", true) scope.hShield.SetSkin(2) scope.hShield.SetModelScale(1,0) NetProps.SetPropEntity(scope.hShield, "m_hOwnerEntity", hPlayer) NetProps.SetPropInt(scope.hShield, "m_fEffects", NetProps.GetPropInt(scope.hShield, "m_fEffects") & ~129) scope.hShield.AcceptInput("SetParent", "!activator", hPlayer, hPlayer) scope.hShield.AcceptInput("SetParentAttachment", "flag", hPlayer, hPlayer) scope.hShield.SetLocalAngles(QAngle(5,0,62.5)) scope.hShield.SetLocalOrigin(Vector(12,-5,-25)) } 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) return } 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 CreateBombLogic() { ClientPrint(null,3,"CREATING BOMB LOGIC") Entities.FindByClassname(null, "func_capturezone").SetTeam(Constants.ETFTeam.TF_TEAM_RED) if (!HellOnEarth.LOGIC_BOMB_MANAGER) { HellOnEarth.LOGIC_BOMB_MANAGER = SpawnEntityFromTable("logic_script", {}) HellOnEarth.CreateBomb() } HellOnEarth.LOGIC_BOMB_MANAGER.ValidateScriptScope() local scope = HellOnEarth.LOGIC_BOMB_MANAGER.GetScriptScope() scope.MAX_ESCORT <- 4 scope.HATCH_POS <- Vector(3, -2370, 97) scope.ACTIVE_BOMBS <- [] scope.DEBUG <- true scope.Think <- function() { local hasBot = false for (local i = 1; i <= MAX_CLIENTS; i++) { local p = PlayerInstanceFromIndex(i) if (p && p.IsFakeClient() && p.GetTeam() == Constants.ETFTeam.TF_TEAM_RED) { hasBot = true break } } if (!hasBot) { return 0.25 } local bombEnt = null while ((bombEnt = Entities.FindByName(bombEnt, "mvm_bomb_red")) != null) { local already = false foreach (entry in ACTIVE_BOMBS) { if (entry.ent == bombEnt) { already = true break } } if (!already) { ACTIVE_BOMBS.append({ ent = bombEnt, origPos = bombEnt.GetOrigin(), lastStatus = -1 }) if (DEBUG) { ClientPrint(null, 3, format("New bomb tracked (%d total)", ACTIVE_BOMBS.len())) } } } for (local idx = ACTIVE_BOMBS.len() - 1; idx >= 0; idx--) { local entry = ACTIVE_BOMBS[idx] local bomb = entry.ent if (!bomb) { ACTIVE_BOMBS.remove(idx) continue } local status = NetProps.GetPropInt(bomb, "m_nFlagStatus") printl(status) if (status == 0 && entry.lastStatus != -1) { if (DEBUG) { ClientPrint(null, 3, "Bomb reset, removing from list") } ACTIVE_BOMBS.remove(idx) continue } if (status == 1 && entry.lastStatus != 1) { local carriers = [] foreach (e in ACTIVE_BOMBS) { if (NetProps.GetPropInt(e.ent, "m_nFlagStatus") == 1) { local c = e.ent.GetMoveParent() if (c) { carriers.append(c) } } } for (local i = 1; i <= MAX_CLIENTS; i++) { local bot = PlayerInstanceFromIndex(i) if (bot && bot.IsFakeClient() && bot.GetTeam() == Constants.ETFTeam.TF_TEAM_RED) { local isCarrier = false foreach (c in carriers) { if (bot == c) { isCarrier = true break } } if (!isCarrier) { ClientPrint(null, 3, format("BOT IS STOPPING INTERRUPT ACTION: %s", GetPropString(bot, "m_szNetname"))) bot.AcceptInput("$BotCommand", "stop interrupt action", bot, bot) } } } foreach (c in carriers) { ClientPrint(null, 3, format("BOMB PICKED UP BY: %s", GetPropString(c, "m_szNetname"))) c.AcceptInput("$BotCommand", "stop interrupt action", c, c) c.AcceptInput("$BotCommand", format("interrupt_action -pos %s -waituntildone -duration 9999", HATCH_POS.ToKVString()), c, c) } } if (status == 2 && entry.lastStatus != 2) { if (DEBUG) { ClientPrint(null, 3, "Bomb dropped, directing bots") } } if (status == 2) { local currPos = bomb.GetOrigin() local distMoved = (currPos - entry.origPos).Length() if (distMoved > 5.0) { for (local i = 1; i <= MAX_CLIENTS; i++) { local bot = PlayerInstanceFromIndex(i) if (bot && bot.IsFakeClient() && bot.GetTeam() == Constants.ETFTeam.TF_TEAM_RED && !bot.IsInASquad()) { local closest = null local bestD = 1e6 foreach (b in ACTIVE_BOMBS) { local d = (bot.GetOrigin() - b.ent.GetOrigin()).Length() if (d < bestD) { bestD = d closest = b.ent } } if (closest) { bot.AcceptInput("$BotCommand", "stop interrupt action", bot, bot) bot.AcceptInput("$BotCommand", format("interrupt_action -pos %s -waituntildone -duration 9999", closest.GetOrigin().ToKVString()), null, null) } } } entry.origPos = currPos } } entry.lastStatus = status } return 0.25 } AddThinkToEnt(HellOnEarth.LOGIC_BOMB_MANAGER, "Think") } function CreateBomb(origin = null) { PrecacheModel("models/bots/doom_bomb.mdl") local bomb = SpawnEntityFromTable("item_teamflag", { flag_model = "models/props_td/atom_bomb.mdl" trail_effect = 1 GameType = 1 ReturnBetweenWaves = true TeamNum = Constants.ETFTeam.TF_TEAM_RED targetname = "mvm_bomb_red" }) bomb.SetModelSimple("models/bots/doom_bomb.mdl") bomb.SetTeam(2) NetProps.SetPropInt(bomb, "m_nFlagStatus", 0x2) NetProps.SetPropFloat(bomb, "m_flResetTime", 120) if (origin) { bomb.SetAbsOrigin(origin) return } for (local i = 1; i <= MAX_CLIENTS; i++) { local p = PlayerInstanceFromIndex(i) if (p && p.IsFakeClient() && p.GetTeam() == Constants.ETFTeam.TF_TEAM_RED) { bomb.SetAbsOrigin(p.GetCenter()) break } } } 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) { EntFireByHandle(wearable, "Kill", null, -1, null, null) AddThinkToEnt(self, null) NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") } return -1 } AddThinkToEnt(player, "BotModelThink") } 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 VecToAngles(v) { local pitch = -atan2(v.z, sqrt(v.x * v.x + v.y * v.y)) * (180.0 / PI); local yaw = atan2(v.y, v.x) * (180.0 / PI); return QAngle(pitch, yaw, 0); } function FunnyProjectile(self) { self.ValidateScriptScope(); local s = self.GetScriptScope(); s._homingStrength <- 0.0; s._tick <- 0; s._bounced <- false; s._phase <- "bounce"; s._target <- null; s.checkBounce <- function() { if (_tick % 3 != 0 || _bounced) return false; local trace = { start = self.GetOrigin(), end = self.GetOrigin() + self.GetAbsVelocity() * 0.15, hullmin = Vector(-10, -10, -10), hullmax = Vector(10, 10, 10), ignore = self }; TraceHull(trace); if ("enthit" in trace) return trace; return false; }; s.checkImpact <- function() { local trace = { start = self.GetOrigin(), end = self.GetOrigin() + self.GetAbsVelocity() * 0.15, hullmin = Vector(-4, -4, -4), hullmax = Vector(4, 4, 4), ignore = self }; TraceHull(trace); if ("enthit" in trace && trace.enthit != null) { self.Kill(); } }; s.doBounce <- function(trace) { local v = self.GetAbsVelocity(); v.z = 300; v.x *= 0.3; v.y *= 0.3; self.SetAbsVelocity(v); self.SetAbsAngles(HellOnEarth.VecToAngles(v)); _bounced = true; _phase = "rising"; }; s.findTarget <- function(ownerTeam) { local nearest = null; local closestDistSqr = 2048 * 2048; for (local i = 1; i <= MaxClients(); i++) { local ply = PlayerInstanceFromIndex(i); if (ply && ply.IsAlive()) { // ownerTeam != ply.GetTeam() local d = (ply.GetOrigin() - self.GetOrigin()).LengthSqr(); if (d < closestDistSqr) { closestDistSqr = d; nearest = ply; } } } return nearest; }; s.updateTrajectory <- function() { local v = self.GetAbsVelocity(); if (_phase == "rising") { v.z -= 2.0; if (v.z <= 0) { _phase = "falling"; } self.SetAbsVelocity(v); self.SetAbsAngles(HellOnEarth.VecToAngles(v)); } else if (_phase == "falling") { v.z -= 4.0; if (v.z < -400) v.z = -400; self.SetAbsVelocity(v); self.SetAbsAngles(HellOnEarth.VecToAngles(v)); _target = findTarget(self.GetTeam()); if (_target) { _phase = "homing"; _homingStrength = 0.1; } } else if (_phase == "homing") { if (_target && _target.IsAlive()) { if (_homingStrength < 1.0) _homingStrength += 0.025; local to = _target.GetCenter() - self.GetOrigin(); local dir = to; dir.Norm(); local speed = 100 + (_homingStrength * 600); local newVel = dir * speed; self.SetAbsVelocity(newVel); self.SetAbsAngles(HellOnEarth.VecToAngles(newVel)); } } }; s.Think <- function() { _tick++; if (!_bounced) { local t = checkBounce(); if (t) doBounce(t); } else { updateTrajectory(); //checkImpact(); } return -1; }; self.SetMoveType(8, 0); AddThinkToEnt(self, "Think"); } function StrikeAt(player) { local pos = player.GetOrigin() DispatchParticleEffect("[1]_thunder_strike_r", pos, Vector(0,90,0)) HellOnEarth.playSoundFromEntity(player, "misc/halloween/spell_lightning_ball_cast.wav") local bomb = SpawnEntityFromTable("tf_generic_bomb", { damage = 450, radius = 300, friendlyfire = 0, classname = "megaton" }) ScreenShake(pos, 20, 16, 1.5, 0, 0, true) bomb.SetTeam(2) bomb.SetAbsOrigin(pos) DispatchParticleEffect("full_explode", pos, Vector(90, 0, 0)) EntFireByHandle(bomb, "RunScriptCode", "self.SetHealth(1); self.TakeDamage(1, 0, activator)", 0.1, bomb, bomb) } function AOEHammerSlam(self) { // Note: to be used in a fire input on attack self.RemoveCondEx(Constants.ETFCond.TF_COND_RUNE_REFLECT, true) DispatchParticleEffect("FX_green_eyeflash_flash", self.EyePosition() + self.EyeAngles().Forward() * 25, Vector()) HellOnEarth.playSoundFromEntity(self, "ptx/sfx/demons/marauder/marauder_vurneable.mp3") self.AddCustomAttribute("major move speed bonus", 0.01, 1.5) self.AddCustomAttribute("hand scale", 1.5, 1) self.AcceptInput("$WeaponSwitchSlot", "2", self, null) self.AddCustomAttribute("disable weapon switch", 2, 2) self.ValidateScriptScope() self.GetScriptScope().vAngles <- self.EyeAngles().Forward() self.GetScriptScope().IS_VURNEABLE = true EntFireByHandle(self, "runscriptcode", @" self.GetScriptScope().IS_VURNEABLE = false if (self.InCond(71)) { EntFireByHandle(self, `runscriptcode`, `self.AddCond(Constants.ETFCond.TF_COND_RUNE_REFLECT)`, 6, null, null) return } else { self.AddCond(Constants.ETFCond.TF_COND_RUNE_REFLECT) } HellOnEarth.playSoundFromEntity(self, `ptx/weapons/hammer_slam.wav`) local forward = self.EyeAngles().Forward(); forward.z = 0; forward.Norm(); local vHitPos = self.GetOrigin() + (forward * (72 * self.GetModelScale())); local Trace = { start = vHitPos, end = vHitPos - Vector(0, 0, 1000), mask = 33579137 } TraceLineEx(Trace) if (!Trace.hit) return vHitPos = Trace.pos ScreenShake(vHitPos, 10, 15, 1, 9999, 0, true) DispatchParticleEffect(`taunt_yeti_fistslam`, vHitPos + Vector(0,0,25), Vector(0, 0, 0)) local hBomb = Entities.CreateByClassname(`tf_generic_bomb`) hBomb.KeyValueFromInt(`damage`, 100) hBomb.KeyValueFromInt(`radius`, 75) hBomb.KeyValueFromInt(`friendlyfire`, 0) hBomb.KeyValueFromString(`classname`, `necro_smasher`) hBomb.DispatchSpawn() hBomb.SetAbsOrigin(vHitPos) hBomb.SetTeam(self.GetTeam()) hBomb.SetOwner(self) hBomb.AcceptInput(`Detonate`, null, self, self) ", 0.6, null, null) for (local i = 1; i <= 3; i++) { EntFireByHandle(self, "runscriptcode", format(@" local hScope = self.GetScriptScope(); if (self.InCond(71)) return local vTarget = self.EyePosition() + hScope.vAngles * %f; local trace = { start = vTarget + Vector(0,0,100), end = vTarget - Vector(0,0,250), mask = MASK_VISIBLE_AND_NPCS & ~(CONTENTS_MONSTER) } TraceLineEx(trace); hScope.hIndicator <- SpawnEntityFromTable(`prop_dynamic`, { model = `models/props_mvm/indicator/indicator_circle.mdl`, modelscale = `3.5`, DisableBoneFollowers = `1`, skin = `5`, DefaultAnim = `start`, disableshadows = `1`, StartDisabled = `0` }); hScope.hIndicator.SetAbsOrigin(trace.pos + Vector(0,0,15)) EntFireByHandle(hScope.hIndicator, `runscriptcode`, @` HellOnEarth.StrikeAt(self) self.Kill() `, 1.5, null, null) ", i * 250), 0.4 * i + 0.2, null, null) } } function ExecutorAlt(self) { self.AddCustomAttribute("major move speed bonus", 0.01, 4) self.AcceptInput("$WeaponSwitchSlot", "2", self, null) self.AddCustomAttribute("disable weapon switch", 13.5, 4) self.ValidateScriptScope() local hExecutorScope = self.GetScriptScope() hExecutorScope.hIndicator <- SpawnEntityFromTable("prop_dynamic", { model = "models/props_mvm/indicator/indicator_circle.mdl", modelscale = "5", DisableBoneFollowers = "1", skin = "5", DefaultAnim = "start", disableshadows = "1", StartDisabled = "0" }) hExecutorScope.hIndicator.SetAbsOrigin(self.GetOrigin() + Vector(0, 0, 5)) HellOnEarth.playSoundFromEntity(self, "ambient/alarms/klaxon1.wav") EntFireByHandle(self, "runscriptcode", @"HellOnEarth.playSoundFromEntity(self, `vo/mvm/mght/pyro_mvm_m_laughevil01.mp3`)", 2, null, null) EntFireByHandle(self, "runscriptcode", @" local weapon = Entities.CreateByClassname(`tf_weapon_bat`) local active_weapon = self.GetActiveWeapon() self.StopTaunt(true) self.RemoveCond(7) weapon.DispatchSpawn() NetProps.SetPropInt(weapon, `m_AttributeManager.m_Item.m_iItemDefinitionIndex`, 739) NetProps.SetPropBool(weapon, `m_AttributeManager.m_Item.m_bInitialized`, true) NetProps.SetPropBool(weapon, `m_bForcePurgeFixedupStrings`, true) NetProps.SetPropEntity(self, `m_hActiveWeapon`, weapon) NetProps.SetPropInt(self, `m_iFOV`, 0) self.HandleTauntCommand(0) NetProps.SetPropEntity(self, `m_hActiveWeapon`, active_weapon) weapon.Kill() self.AddCustomAttribute(`gesture speed increase`, 0.9, 3) ", 1, null, null) EntFireByHandle(self, "runscriptcode", @" DispatchParticleEffect(`[1]_thunder_strike_r`, self.GetOrigin(), Vector(0,90,0)) HellOnEarth.playSoundFromEntity(self, `ambient/medieval_thunder2.wav`) ", 3, null, null) EntFireByHandle(self, "runscriptcode", @" self.AddCustomAttribute(`major move speed bonus`, 0.5, 3) self.GetScriptScope().hGlow.AcceptInput(`SetGlowColor`, `255 25 25 0`, null, null) ", 13.5, null, null) EntFireByHandle(self, "runscriptcode", @" DispatchParticleEffect(`[1]_thunder_strike_r`, self.GetOrigin(), Vector(0,90,0)) DispatchParticleEffect(`[2]_flamestrike`, self.GetOrigin() + Vector(0,0,5), Vector(0,90,0)) HellOnEarth.playSoundFromEntity(self, `misc/halloween/spell_lightning_ball_cast.wav`) self.SetAbsVelocity(Vector(0,0,350)) local scope = self.GetScriptScope() scope.hIndicator.Kill() scope.BuffIndicator <- SpawnEntityFromTable(`info_particle_system`, { effect_name = `utaunt_elebound_yellow_parent` start_active = 1 }) scope.BuffIndicatorGlow <- SpawnEntityFromTable(`info_particle_system`, { effect_name = `utaunt_elebound_yellow_glow` start_active = 1 }) scope.BuffIndicator.SetAbsOrigin(self.GetCenter() - Vector(0,0,15)) scope.BuffIndicatorGlow.SetAbsOrigin(self.GetCenter() - Vector(0,0,15)) 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) self.AddCondEx(52, 1.5, null) self.AddCustomAttribute(`CARD: move speed bonus`, 2.0, 10) self.AddCondEx(11, 10, null) self.AddCustomAttribute(`mult dmg vs giants`, 25, 10) self.AddCustomAttribute(`heal on kill`, 500, 10) EntFireByHandle(self, `CallScriptFunction`, `setfalse`, 10, null, null) ScreenShake(self.GetCenter(), 40, 16, 2, 0, 0, true) local bomb = SpawnEntityFromTable(`tf_generic_bomb`, { damage = 300, radius = 250, friendlyfire = 0, classname = `megaton` }) bomb.SetTeam(2) bomb.SetAbsOrigin(self.GetCenter()) EntFireByHandle(bomb, `RunScriptCode`, `self.SetHealth(1); self.TakeDamage(1, 0, activator)`, 0.1, self, self) ", 3.5, null, null) } function ExecutorState(self) { self.ValidateScriptScope() local scope = self.GetScriptScope() if (!("buffstatus" in self.GetScriptScope())) { scope.buffstatus <- false scope.accumulatedHits <- 0 scope.setfalse <- function () { buffstatus = false accumulatedHits = 0 } scope.hGlow <- SpawnEntityFromTable("tf_glow", { GlowColor = "0 0 0 0" target = "bignet" targetname = "executor_glow" }) SetPropEntity(scope.hGlow, "m_hTarget", self.GetActiveWeapon()) } if (scope.buffstatus) return printl(scope.accumulatedHits) scope.accumulatedHits++ PrecacheSound("ptx/other/demon_health_restored.wav") HellOnEarth.playSoundFromEntity(self, "ptx/other/demon_health_restored.wav") scope.hGlow.AcceptInput("SetGlowColor", format("255 25 25 %d", 80 * scope.accumulatedHits + 15), null, null) if (scope.accumulatedHits >= 3) { SetPropFloat(self.GetActiveWeapon(), "m_flNextPrimaryAttack", Time() + 5) scope.accumulatedHits = 0 scope.buffstatus = true EntFireByHandle(self, "runscriptcode","HellOnEarth.ExecutorAlt(self)", 1, null,null) } } function GigaFlameThrower(hOwner) { local hWeapon = GetItemInSlot(hOwner, 0) if (hWeapon.GetName() != "tf_weapon_flamethrower") return hWeapon.AddAttribute("airblast disabled", 1, -1) hWeapon.AddAttribute("flame_lifetime", 5, -1) hWeapon.AddAttribute("flame_speed", 4000, -1) hWeapon.AddAttribute("flame_drag", 3, -1) hWeapon.AddAttribute("flame_spread_degree", 8, -1) hWeapon.AddAttribute("flame_speed", 5500, -1) hWeapon.AddAttribute("damage bonus", 5, -1) hWeapon.ValidateScriptScope() local hWepScope = hWeapon.GetScriptScope() hWepScope.iParentButtons <- NetProps.GetPropInt(hOwner, "m_nButtons") hWepScope.bFlameActive <- false hWepScope.hFlameParticle <- SpawnEntityFromTable("info_particle_system", { start_active = 0 effect_name = "h_fireball_mega_" }) hWepScope.Think <- function() { iParentButtons = NetProps.GetPropInt(hOwner, "m_nButtons") hFlameParticle.SetAbsOrigin(hOwner.GetCenter() + (hOwner.GetForwardVector() * 250)) hFlameParticle.SetAbsAngles(hOwner.EyeAngles()) local firePressed = (iParentButtons & Constants.FButtons.IN_ATTACK) != 0; if (firePressed && !bFlameActive) { hFlameParticle.AcceptInput("Start", null, null, null); bFlameActive = true; } else if (!firePressed && bFlameActive) { hFlameParticle.AcceptInput("Stop", null, null, null); bFlameActive = false; } return -1 } AddThinkToEnt(hWeapon, "Think") } function ScreecherBuff(hBot) { local vOrigin = hBot.GetCenter() local iBuffCount = 0 local iBuffDuration = 30 ScreenShake(vOrigin, 60, 16, 1, 0, 0, true) DispatchParticleEffect("hcea_hunter_shade_cannon_explode_ground_flame_ring_b", vOrigin, Vector()) for (local hEnt = null; hEnt = Entities.FindByClassnameWithin(hEnt, "player", vOrigin, 650);) { if (!hEnt || !hEnt.IsValid()) {continue} if (0 != NetProps.GetPropInt(hEnt, "m_lifeState") || hEnt.GetTeam() == TEAM_SPECTATOR) continue if (hEnt.GetTeam() == 2) { iBuffCount++ local sOldName = GetPropString(hEnt, "m_szNetname") HellOnEarth.DispatchParticleEffectOn(hEnt, "utaunt_elebound_purple_parent", 1) hEnt.AddCustomAttribute("CARD: move speed bonus", 1.3, iBuffDuration) hEnt.AddCustomAttribute("CARD: health regen", 25, iBuffDuration) hEnt.AddCustomAttribute("fire rate bonus HIDDEN", 0.7, iBuffDuration) hEnt.AddCustomAttribute("dmg from ranged reduced", 0.5, iBuffDuration) hEnt.AddCustomAttribute("faster reload rate", 0.65, iBuffDuration) SetPropString(hEnt, "m_szNetname", format("%s (Override)", sOldName)) hEnt.ValidateScriptScope() local hEntScope = hEnt.GetScriptScope() hEntScope.hBuffGlow <- SpawnEntityFromTable("tf_glow", { GlowColor = "215 10 255 255" target = "bignet" }) SetPropEntity(hEntScope.hBuffGlow, "m_hTarget", hEnt) EntFireByHandle(hEnt, "runscriptcode", format("SetPropString(self, `m_szNetname`, `%s`)", sOldName), iBuffDuration, hEnt, hEnt) EntFireByHandle(hEnt, "runscriptcode", "HellOnEarth.DispatchParticleEffectOn(self, null)", iBuffDuration, hEnt, hEnt) EntFireByHandle(hEntScope.hBuffGlow, "Kill", "", iBuffDuration, null,null) } } if (iBuffCount > 0) { ClientPrint(null, HUD_PRINTCENTER, format("SCREECHER BUFF ACTIVE, %d ENEMIES BUFFED", iBuffCount)) } return } function CombustorDeath(hBot) { local Trace = { start = hBot.GetOrigin(), end = hBot.GetOrigin() - Vector(0, 0, 1000), mask = MASK_VISIBLE_AND_NPCS & ~(CONTENTS_MONSTER) } TraceLineEx(Trace) if (!Trace.hit) return local vOrigin = Trace.pos if ((Trace.pos - hBot.GetOrigin()).Length() > 35) { local vCenter = hBot.GetCenter() ScreenShake(vCenter, 60, 16, 1, 0, 0, true) DispatchParticleEffect("fluidSmokeExpl_ring_mvm", vCenter, Vector(0, 0, -90)) local bomb = SpawnEntityFromTable("tf_generic_bomb", { sound = "npc/env_headcrabcanister/explosion.wav", damage = 150, radius = 250, friendlyfire = 0, teamnum = 2, classname = "megaton" }); bomb.SetAbsOrigin(vCenter) bomb.AcceptInput("Detonate", "", bomb, bomb); EntFireByHandle(bomb, "RunScriptCode", "self.SetHealth(1); self.TakeDamage(1, 0, activator)", 0.1, hBot, hBot) for (local hEnt = null; hEnt = Entities.FindByClassnameWithin(hEnt, "player", vCenter, 175);) { if (!hEnt || !hEnt.IsValid()) {continue} if (0 != NetProps.GetPropInt(hEnt, "m_lifeState") || hEnt.GetTeam() == TEAM_SPECTATOR) continue if (hEnt.GetTeam() == 3) { DispatchParticleEffect("blood_impact_backscatter", hEnt.GetCenter(), Vector(0, 0, 0)) hEnt.AddCondEx(25, 8, null) hEnt.AddCondEx(15, 8, null) hEnt.AddCondEx(123, 8, null) ScreenFade(hEnt, 200, 55, 55, 50, 2, 1, 1) } } return } local QAngles = hBot.GetAbsAngles() local hProp = SpawnEntityFromTable("prop_dynamic", { model = "models/kirillian/infected/hoomer_v4.mdl", defaultanim = "Flinch_01", disableshadows = 1, disablebonefollowers = 1, onanimationbegun = "!self,setplaybackrate,0.25,0,-1", rendermode = 1, solid = 6, }) hProp.SetModelScale(1.5, 0) hProp.SetAbsOrigin(vOrigin) hProp.SetAbsAngles(QAngles) hProp.AcceptInput("SetAnimation", "taunt_laugh", hBot, hBot) local hChargeParticle = SpawnEntityFromTable("info_particle_system", { effect_name = "charge_up", start_active = 1, }) hChargeParticle.SetAbsOrigin(hBot.GetCenter()) EntFireByHandle(hChargeParticle, "Kill", "", 3, null, null) hProp.ValidateScriptScope() hProp.GetScriptScope().DelayedMethods <- function() { self.AcceptInput("SetAnimation", "deathpose_crouch_back", self, self) local vCenter = self.GetCenter() ScreenShake(vCenter, 60, 16, 1, 0, 0, true) DispatchParticleEffect("fluidSmokeExpl_ring", vCenter, Vector(0, 0, -90)) EntFireByHandle(hProp, "Kill", "", 0.3, null, null) local bomb = SpawnEntityFromTable("tf_generic_bomb", { sound = "npc/env_headcrabcanister/explosion.wav", damage = 1000, radius = 250, friendlyfire = 0, teamnum = 2, classname = "megaton" }); bomb.SetAbsOrigin(vCenter) bomb.AcceptInput("Detonate", "", bomb, bomb); EntFireByHandle(bomb, "Kill", "", 0.1, null, null) for (local hEnt = null; hEnt = Entities.FindByClassnameWithin(hEnt, "player", vCenter, 175);) { if (!hEnt || !hEnt.IsValid()) {continue} if (0 != NetProps.GetPropInt(hEnt, "m_lifeState") || hEnt.GetTeam() == TEAM_SPECTATOR) continue if (hEnt.GetTeam() == 3) { DispatchParticleEffect("blood_impact_backscatter", hEnt.GetCenter(), Vector(0, 0, 0)) hEnt.AddCondEx(25, 8, null) hEnt.AddCondEx(15, 8, null) hEnt.AddCondEx(123, 8, null) ScreenFade(hEnt, 200, 55, 55, 50, 2, 1, 1) } } } EntFireByHandle(hProp, "runscriptcode", "DelayedMethods()", 3.375, hProp, hProp) } function EngineerSwap(bot) { EntFireByHandle(bot.GetScriptScope().hGlow, "Kill", "", -1.0, null, null); local health = bot.GetHealth() local pos = bot.GetOrigin() HellOnEarth.VIP_DEATH_LOSE_COND = false NetProps.SetPropString(ENGINEER_THINK_ADD, "m_iszScriptThinkFunction", "") SetPropBool(bot, "m_bUseBossHealthBar", false) bot.ForceChangeTeam(1, true) EntFire("spawnbot_engineer_dummy", "Enable") EntFire("bignet", "runscriptcode", format("HellOnEarth.FinishEngineerSwap(%d, %f, %f, %f)", health, pos.x, pos.y, pos.z), 0.1) EntFire("spawnbot_engineer_dummy", "Disable", null, 0.2) EntFire("spawnbot_engineer_dummy", "Kill", null, 0.2) } function FinishEngineerSwap(health, x, y, z) { local pos = Vector(x, y, z) for (local i = 1; i <= MAX_CLIENTS; i++) { local hEnt = PlayerInstanceFromIndex(i) if (hEnt && hEnt.IsAlive() && hEnt.IsBotOfType(TF_BOT_TYPE) && hEnt.HasBotTag("bot_vip")) { hEnt.SetAbsOrigin(pos) hEnt.SetHealth(health) ENGINEER_THINK_ADD.GetScriptScope().BOT_HANDLE = hEnt } } HellOnEarth.VIP_DEATH_LOSE_COND = true } function engyParticle(building) { if (!building || !building.IsValid() || !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("logic_script", { targetname = "alternate_wavebar_script" }) 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.25) NEXT_FLICKER_TIME = Time() + RandomInt(12, 17) } if (DO_FLICK) { if (Time() < NEXT_FLICKER_DURATION) { HellOnEarth.AlternateWavebars(0) } else { HellOnEarth.AlternateWavebars(-1) DO_FLICK = false } } return 0.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([ ["heavy_champ_giant", 1, MVM_CLASS_FLAG_MINIBOSS | MVM_CLASS_FLAG_ALWAYSCRIT], ["heavy_steelfist_giant", 1, MVM_CLASS_FLAG_MINIBOSS | MVM_CLASS_FLAG_ALWAYSCRIT], ["soldier_burstfire", 2, MVM_CLASS_FLAG_MINIBOSS], ["pyro_degreaser_axtinguisher", 1, MVM_CLASS_FLAG_MINIBOSS], ["soldier_dh_lite_armored", 4, MVM_CLASS_FLAG_NORMAL], ["pyro_powerjack", 45, MVM_CLASS_FLAG_NORMAL], ["soldier", 16, MVM_CLASS_FLAG_NORMAL], ["heavy_champ", 22, MVM_CLASS_FLAG_NORMAL], ["demoknight_samurai", 6, MVM_CLASS_FLAG_NORMAL], ["scout", 24, MVM_CLASS_FLAG_NORMAL], ]) break case 1: AlternateWaves.AddWaveIcons([ ["heavy_zombie_lite", 83, MVM_CLASS_FLAG_NORMAL], ["heavy_zombie_arm1_lite", 4, MVM_CLASS_FLAG_MINIBOSS], ["heavy_zombie_breach_lite", 9, MVM_CLASS_FLAG_NORMAL], ["cacodemon", 6, MVM_CLASS_FLAG_MINIBOSS], ["soldier_pickaxe_equalize",24, MVM_CLASS_FLAG_NORMAL], ["soldier_blue", 42, MVM_CLASS_FLAG_NORMAL], ["soldier_airstrike_lite_burstfire", 31, MVM_CLASS_FLAG_NORMAL], ["heavy_shotgun_red_burst", 2, MVM_CLASS_FLAG_MINIBOSS], ["soldier_yellow", 5, MVM_CLASS_FLAG_NORMAL], ["soldier_rocketrain_hyper", 1, MVM_CLASS_FLAG_MINIBOSS], ["pyro_reaper", 1, MVM_CLASS_FLAG_MINIBOSS], ["soldier_barrage_incendiary_nys", 1, MVM_CLASS_FLAG_MINIBOSS], ["final_boss_titanium_terror", 1, MVM_CLASS_FLAG_SUPPORT], ]) break case 2: AlternateWaves.AddWaveIcons([ ["heavy_zombie_arm2_lite", 3, MVM_CLASS_FLAG_MINIBOSS], ["heavy_zombie_lite", 20, MVM_CLASS_FLAG_MINIBOSS], ["heavy_zombie_breach_lite", 5, MVM_CLASS_FLAG_MINIBOSS], ["dead_bleed_lite", 5, MVM_CLASS_FLAG_MINIBOSS], ["pyro_membrain_lite", 20, MVM_CLASS_FLAG_MINIBOSS], ["heavy_armored_natasha_mort", 1, MVM_CLASS_FLAG_MINIBOSS], ["demo_burst_redbarrier_spin_giant", 4, MVM_CLASS_FLAG_MINIBOSS], ["soldier_pickaxe_equalize", 35, MVM_CLASS_FLAG_MINIBOSS], ["dead_heat_red_nys", 20, MVM_CLASS_FLAG_MINIBOSS], ["soldier_bazooka_accel", 3, MVM_CLASS_FLAG_MINIBOSS], ["soldier_bazooka_accel", 1, MVM_CLASS_FLAG_MINIBOSS | MVM_CLASS_FLAG_ALWAYSCRIT], ["heavy_zombie_breach_lite", 5, MVM_CLASS_FLAG_MINIBOSS], ["heavy_head_red_nys", 1, MVM_CLASS_FLAG_MINIBOSS], ["tank_black", 1, MVM_CLASS_FLAG_MINIBOSS], ]) break case 3: AlternateWaves.AddWaveIcons([ ["soldier_barrage_incendiary_nys", 2, MVM_CLASS_FLAG_MINIBOSS | MVM_CLASS_FLAG_ALWAYSCRIT], ["medic_boost", 6, MVM_CLASS_FLAG_MINIBOSS], ["heavy_zombie_lite", 20, MVM_CLASS_FLAG_MINIBOSS], ["heavy_shotgun_red_burst", 3, MVM_CLASS_FLAG_MINIBOSS], ["soldier_pickaxe_equalize", 24, MVM_CLASS_FLAG_MINIBOSS], ["robo_extremethreat", 3, MVM_CLASS_FLAG_MINIBOSS], ["soldier_incendiary_spammer", 1, MVM_CLASS_FLAG_MINIBOSS], ["shotgun_lite", 3, MVM_CLASS_FLAG_MINIBOSS], ["dead_flame_lite", 30, MVM_CLASS_FLAG_MINIBOSS], ["dead_heat_red_nys", 14, MVM_CLASS_FLAG_MINIBOSS], ["baron_ptyx", 1, MVM_CLASS_FLAG_MINIBOSS], ["baron_ptyx", 2, MVM_CLASS_FLAG_MINIBOSS], ]) break } } function OnGameEvent_mvm_wave_failed(params) { for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if(!hPlayer) continue if(!hPlayer.IsFakeClient()) continue hPlayer.ValidateScriptScope() local scope = hPlayer.GetScriptScope() if ("hShield" in scope && scope.hShield.IsValid()) scope.hShield.Kill() } } function OnGameEvent_recalculate_holidays(_) { if(GetRoundState() == 3) { if(GetPropString(hObjectiveResource, "m_iszMvMPopfileName").find("HellOnEarth") == null) Convars.SetValue("sig_etc_unintended_class_weapon_display_meters", 1) Convars.SetValue("sig_mvm_jointeam_blue_allow", 0) Convars.SetValue("sig_mvm_jointeam_blue_allow_max", 0) Convars.SetValue("sig_robot_building_stomp_contact_nodamage", 0) Convars.SetValue("tf_mvm_defenders_team_size", 6) Convars.SetValue("tf_mvm_buybacks_method", 0) Convars.SetValue("tf_mvm_buybacks_per_wave", 0) Convars.SetValue("sig_mvm_set_credit_team", 2) 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, delay = 0,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 - ptx/ost/baron_intro.mp3 // 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, delay) } function SetMusicState(play, sound, sVolume = 1, delay_time = 0) { 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 delay = delay_time }) } } // 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 DispatchParticleEffectOn(entity, name, attach_type = 6) { 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", attach_type) 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 ------ // LUA PROCESSING CHANNEL function ProcessChatMessage(chatString, iUserId) { local hPlayer = PlayerInstanceFromIndex(i) if (!hPlayer || hPlayer.IsFakeClient()) { ClientPrint(null,3,"SOMEONE HAS SAID SOMETHING") } } // 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) continue if (hPlayer.IsFakeClient()) { hPlayer.RemoveCondEx(19, true) hPlayer.RemoveCondEx(32, true) } if (hPlayer.IsAlive()) { hPlayer.AddCondEx(32, 15, hPlayer) ClientPrint(hPlayer, 3, "\x07ff5b30You survived... \x07FFFFFFThe respawn system is back online!") hPlayer.RemoveCondEx(16, true) hPlayer.RemoveCondEx(11, true) } 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("alternate_wavebar_script","Kill") EntFire("explanation_stuff", "Kill") local delayBeforeStarting = RandomInt(30, 60)// 30, 60 EntFire("first_warning", "Trigger", null, delayBeforeStarting - 5) EntFire("second_warning", "Trigger", null, delayBeforeStarting + 30) EntFire("final_warning", "Trigger", null, delayBeforeStarting + 5) // 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 TeamSwap() { 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) Convars.SetValue("sig_mvm_set_credit_team", 3) Convars.SetValue("sig_robot_building_stomp_contact_nodamage", 1) local class_to_sound = { [0] = "", [1] = "vo/mvm/mght/scout_mvm_m_helpmedefend01.mp3", // Scout [2] = "vo/mvm/norm/sniper_mvm_helpmedefend02.mp3", // Sniper [3] = function() { return RandomInt(0, 1) == 0 ? "vo/mvm/norm/soldier_mvm_battlecry03.mp3" : "vo/mvm/norm/soldier_mvm_battlecry04.mp3"; }, // Soldier [4] = "vo/mvm/norm/demoman_mvm_helpmedefend01.mp3", // Demo [5] = "vo/mvm/norm/medic_mvm_battlecry03.mp3", // Medic [6] = "vo/mvm/mght/heavy_mvm_m_helpmedefend02.mp3", // Heavy [7] = "vo/mvm/mght/pyro_mvm_m_battlecry01.mp3", // Pyro [9] = "vo/mvm/norm/engineer_mvm_incoming03.mp3",// Engineer }; for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if (!hPlayer) continue if (!hPlayer.IsFakeClient() && hPlayer.GetTeam() == 2) { HellOnEarth.ChangePlayerTeamMvM(hPlayer, 3) local loc = hPlayer.GetOrigin() local ang = hPlayer.GetAbsAngles() hPlayer.ForceRegenerateAndRespawn() DispatchParticleEffect("teleportedin_blue", loc, Vector(90, 0, 0)) EntFireByHandle(hPlayer, "$SetLocalOrigin", loc.ToKVString(), -1, null, null) EntFireByHandle(hPlayer, "runscriptcode", format("self.SnapEyeAngles(QAngle(%d, %d, %d))", ang.x, ang.y, ang.z), -1, null, null) for (local i = 0.1; i < 0.4; i++) EntFireByHandle(hPlayer, "$TauntFromItem2", "31288|-0.5",i, null, null) EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.PlayerAttributes(self)", 0.1, null, null) } else if (hPlayer.IsBotOfType(TF_BOT_TYPE) && hPlayer.GetTeam() == 3) { local string_to_play = "#" + class_to_sound[hPlayer.GetPlayerClass()] if (string_to_play == "") string_to_play += "vo/mvm/norm/soldier_mvm_paincrticialdeath02.mp3" PrecacheSound(string_to_play) EntFireByHandle(hPlayer, "runscriptcode", format("HellOnEarth.playSoundFromEntity(self, `%s`)", string_to_play), RandomInt(1, 35), hPlayer, hPlayer) } } EntFire("bignet", "runscriptcode", "Convars.SetValue(`tf_mvm_defenders_team_size`, 0)", -1) } function mapTransformationUtil() { local barnPositions = [ Vector(-658, -620, 320), Vector(296, -304, 320), Vector(-214, -347, 320), Vector(380, -715, 65), Vector(65, -414, 65), Vector(-621, -722, 65), Vector(-49, -964, 128), Vector(-207, -996, 320), Vector(473, -688, 65), Vector(-972, -951, 298), Vector(-480, -1238, 320) ] BOTS_PEACEFUL = false MAIN_WAVE_ACTIVE = true WAVE_ACTIVE = true RED_PLAYERS = false TEAM_WIPE_ACTIVE = true HellOnEarth.CreatePointThink() HellOnEarth.AddTeamPoints(-1) SetRespawnTimeAll(9999) for(local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if (hPlayer) { if (!hPlayer.IsFakeClient()) EntFireByHandle(hPlayer, "$SetLocalOrigin", PickRandomItem([Vector(-61, 162, 65), Vector(131, 106, 65), Vector(-218, -300, 3), Vector(290, -302, 320)]).ToKVString(), 0, hPlayer, hPlayer); else { hPlayer.AcceptInput("$BotCommand", format("interrupt_action_queue -pos %s -waituntildone -duration 120", PickRandomItem(barnPositions).ToKVString()), null, null) } } } for (local x = -1600; x <= 1386; x += 450) { for (local y = 2326; y >= -2788; 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(1) } 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.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) EntFire("tf_gamerules", "PlayVO", "TFPlayer.InvulnerableOn") for (local hPlayer; hPlayer = Entities.FindByClassname(hPlayer, "player");) { if (hPlayer.IsBotOfType(1337) && hPlayer.GetTeam() == 3) { DispatchParticleEffect("spell_overheal_flash_blue", hPlayer.GetOrigin() + Vector(0, 0, (40 * (hPlayer.GetModelScale() + 0.2))), Vector(0, 0, 0)) 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, 7, null) HellOnEarth.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, 4, null, null) local class_to_sound = { [1] = "vo/mvm/norm/scout_mvm_paincrticialdeath02.mp3", // Scout [2] = "vo/mvm/norm/sniper_mvm_paincrticialdeath01.mp3", // Sniper [3] = "vo/mvm/norm/soldier_mvm_paincrticialdeath02.mp3", // Soldier [4] = "vo/mvm/norm/demoman_mvm_paincrticialdeath05.mp3", // Demo [5] = "vo/mvm/norm/medic_mvm_paincrticialdeath01.mp3", // Medic [6] = "vo/mvm/norm/heavy_mvm_paincrticialdeath01.mp3", // Heavy [7] = "vo/mvm/norm/pyro_mvm_paincrticialdeath01.mp3", // Pyro [9] = "vo/mvm/norm/engineer_mvm_paincriticaldeath01.mp3", // Engineer }; string_to_play = class_to_sound[hPlayer.GetPlayerClass()]; if (string_to_play == "") string_to_play = "vo/mvm/norm/soldier_mvm_paincrticialdeath02.mp3"; PrecacheSound("#" + string_to_play) playSoundFromEntity(hPlayer, "#" + string_to_play, 2500) } } } 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 CreateRocket(hTarget, sfx = true, danger_annotation = false) { 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 if (danger_annotation) { HellOnEarth.SendAnnotationOn(hRocketScope.hIndicator, "Danger!", 5, true) } 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, 250);) { if (!entity_to_damage || !entity_to_damage.IsValid()) continue if (0 != NetProps.GetPropInt(entity_to_damage, "m_lifeState")) continue entity_to_damage.TakeDamage(500, 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 CreateMeteor(hTarget, sfx = true) { local hSkyPosition = hTarget + Vector(RandomInt(-900, 900), RandomInt(-900, 900), 2000) local dict_model = meteor_models[RandomInt(0, meteor_models.len() - 1)] local hMeteor = SpawnEntityFromTable("prop_dynamic", { DisableBoneFollowers = "1", model = dict_model.model, StartDisabled = "1", rendercolor = "125 0 0", }) hMeteor.SetModelScale(dict_model.scale, 0) hMeteor.SetAbsOrigin(hSkyPosition) local dir = (hTarget - hSkyPosition) dir.Norm() hMeteor.SetForwardVector(dir) HellOnEarth.playSoundFromEntity(hMeteor, RandomInt(0, 1) == 0 ? "ambient/machines/aircraft_distant_flyby1.wav" : "ambient/machines/aircraft_distant_flyby3.wav") hMeteor.ValidateScriptScope() local hMeteorScope = hMeteor.GetScriptScope() hMeteorScope.hIndicator <- SpawnEntityFromTable("prop_dynamic", { model = "models/props_mvm/indicator/indicator_circle.mdl", DisableBoneFollowers = "1", skin = "5", DefaultAnim = "start", disableshadows = "1", StartDisabled = "0" }); hMeteorScope.hIndicator.SetModelScale(2, 0) if (sfx) HellOnEarth.playSoundFromEntity(hMeteorScope.hIndicator, "ptx/other/amored_activate.wav") hMeteorScope.hIndicator.SetAbsOrigin(hTarget + Vector(0, 0, 5)) hMeteorScope.hTrail2 <- SpawnEntityFromTable("info_particle_system", { effect_name = "railgun_charged_live" start_active = 0 }) hMeteorScope.hTrail2.SetAbsOrigin(hSkyPosition + dir * 10) hMeteorScope.hTrail2.SetForwardVector(dir) hMeteorScope.hTrail2.AcceptInput("SetParent", "!activator", hMeteor, null) hMeteorScope.ROCKET_LAUNCH_TIME <- Time() + 3.75 hMeteorScope.DO_ROCKET_LAUNCH <- true hMeteorScope.LerpConst <- hTarget - hSkyPosition hMeteorScope.rocketStarted <- false hMeteorScope.ROCKET_HIT_TIME <- -1 hMeteorScope.Think <- function() { if (Time() >= ROCKET_LAUNCH_TIME && DO_ROCKET_LAUNCH) { local t = (Time() - ROCKET_LAUNCH_TIME) / 1.25 if (t >= 1.0) { hMeteor.SetAbsOrigin(hTarget) DO_ROCKET_LAUNCH = false hMeteor.AcceptInput("Disable", null, null, null) hIndicator.Kill() ScreenShake(hTarget, 40, 16, 1, 0, 0, true) DispatchParticleEffect("full_explode", hTarget, Vector(90, 0, 0)) HellOnEarth.playSoundFromEntity(hMeteor, "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, 175);) { if (!entity_to_damage || !entity_to_damage.IsValid()) continue if (0 != NetProps.GetPropInt(entity_to_damage, "m_lifeState")) continue entity_to_damage.TakeDamage(300, DMG_BLAST, null) } } return -1 } else { local easedT = t * t local newPos = hSkyPosition + (LerpConst * easedT) hMeteor.SetAbsOrigin(newPos) local rotationSpeed = 360 * easedT; hMeteor.SetAbsAngles(QAngle(rotationSpeed * 0.5, rotationSpeed, rotationSpeed * 0.2)); if (!rocketStarted) { rocketStarted = true hMeteor.AcceptInput("Enable", null, null, null) hMeteorScope.hTrail2.AcceptInput("Start", null, null, null) EntFireByHandle(hMeteor, "runscriptcode", "HellOnEarth.playSoundFromEntity(self, `MeteorFlyby`)", 0.5, null, null) } } } if (ROCKET_HIT_TIME >= 0 && Time() >= ROCKET_HIT_TIME + 1.0) { hTrail2.Kill() hMeteor.Kill() NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") } return -1 } AddThinkToEnt(hMeteor, "Think") } function meteorTimes(total_count, total_time) { local time_spots = []; for (local i = 0; i < total_count; i++) { time_spots.append(RandomFloat(0, total_time)); } return time_spots; } function MeteorShower(count, total_setup_time = 2) { local strike_spots = [] local minareasize = 1500; local spots = [] local total_origin = Vector(0, 0, 0) local player_count = 0 for (local player; player = FindByClassname(player, "player");) { if (player.GetTeam() != TEAM_SPECTATOR) { total_origin += player.GetOrigin() player_count += 1 } } local average_origin_x = null local average_origin_y = null local average_origin_z = null if (player_count > 0) { average_origin_x = total_origin.x / player_count average_origin_y = total_origin.y / player_count average_origin_z = total_origin.z / player_count } local average = Vector(average_origin_x, average_origin_y, average_origin_z) local nav_table_average = {} NavMesh.GetNavAreasInRadius(average, 2000, nav_table_average) foreach(id, nav in nav_table_average) { if (nav.GetSizeX() * nav.GetSizeY() > minareasize && !nav.HasAttributeTF(TF_NAV_SPAWN_ROOM_RED) && !nav.HasAttributeTF(TF_NAV_SPAWN_ROOM_BLUE) && nav.IsReachableByTeam(2)) { spots.append(nav) } } for (local i = 0; i < count; i++) { if (spots.len() == 0) break; local random_index = RandomInt(0, spots.len() - 1); local nav = spots[random_index]; strike_spots.append(nav.FindRandomSpot()) } local times = meteorTimes(count, total_setup_time) for (local i = 0; i < times.len(); i++) { local loc = strike_spots[i]; local time = times[i]; local string_to_run = format("HellOnEarth.CreateMeteor(Vector(%d,%d,%d),false)", loc.x, loc.y, loc.z) EntFire("bignet", "runscriptcode", string_to_run, time) } } function ProcessButton(player, index) { switch (index) { case 1: if (GetPropInt(player, "m_nButtons") & IN_RELOAD) return true return false break case 2: if (player.IsUsingActionSlot()) return true return false break case 3: if (player.GetFlags() & FL_DUCKING) return true return false break default: return false break } // (GetPropInt(player, "m_nButtons") & FLAG) - https://developer.valvesoftware.com/wiki/Team_Fortress_2/Scripting/Script_Functions/Constants#FButtons } function ChangeDashButton(hPlayer) { hPlayer.ValidateScriptScope() local hPlayer_scope = hPlayer.GetScriptScope() hPlayer_scope.iDashButtonIndex = (hPlayer_scope.iDashButtonIndex % 3) + 1 switch (hPlayer_scope.iDashButtonIndex) { case 1: ClientPrint(hPlayer, 3, "\x07BEB9E0DASH BOUND TO: \x07FFFF00RELOAD (R)") break case 2: ClientPrint(hPlayer, 3, "\x07BEB9E0DASH BOUND TO: \x07FFFF00ACTION SLOT") break case 3: ClientPrint(hPlayer, 3, "\x07BEB9E0DASH BOUND TO: \x07FFFF00CROUCH") break default: ClientPrint(hPlayer, 3, "\x07FFFF00DASH NOT BOUND") } HellOnEarth.playSoundFromEntity(hPlayer, "buttons/button3.wav") DispatchParticleEffect("mvm_pow_smash", Vector(360, -3426, 140), Vector()) } function KillSupportRobots(check_tags = true) { for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if (!hPlayer || !hPlayer.IsFakeClient() || hPlayer.GetTeam() != 2 || !hPlayer.IsAlive()) continue; if (check_tags) { if (hPlayer.HasBotTag("bot_support")) hPlayer.TakeDamage(99999, 0, hPlayer) } else hPlayer.TakeDamage(99999, 0, hPlayer) } } function GetAttemptedMoveDirection(p){ local b=NetProps.GetPropInt(p,"m_nButtons"),F=Constants.FButtons; local x=(b&F.IN_MOVELEFT?1:0)-(b&F.IN_MOVERIGHT?1:0), y=(b&F.IN_FORWARD?1:0)-(b&F.IN_BACK?1:0), l2=x*x+y*y; if(l2<1e-6) return p.EyeAngles().Forward(); local inv=1/sqrt(l2),a=p.GetAbsAngles().y*PI/180; x*=inv; y*=inv; return Vector(y*cos(a)-x*sin(a), y*sin(a)+x*cos(a), 0); } 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 }) if (!("iDashButtonIndex" in hPlayer_scope)) {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 = HellOnEarth.GetAttemptedMoveDirection(hPlayer) dashDirection.z = 0.1 hPlayer.SetVelocity(dashDirection * 1200) hPlayer.SetGravity(0.000001) hPlayer.AddCondEx(TF_COND_LOST_FOOTING, 0.35,null) 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) //self.SetMoveType(MOVETYPE_WALK, MOVECOLLIDE_DEFAULT) ", 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) } } // RANDOM SPAWN LOGIC // 1. Particle Pre function DispatchParticleEffectObjAlt(name, vOrigin, QAngles = QAngle(), sTarget = null) { local hParticle = CreateByClassname("info_particle_system") hParticle.KeyValueFromString("effect_name", name) hParticle.KeyValueFromInt("start_active", 1) if (sTarget) hParticle.KeyValueFromString("targetname", sTarget) hParticle.DispatchSpawn() hParticle.SetAbsOrigin(vOrigin) hParticle.SetAbsAngles(QAngles) hParticle.AcceptInput("start", null, null, null) return hParticle } 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_TOXIC(hPos) // TIME FOR TOXIC: 4 SECONDS { local hFirst = DispatchParticleEffectObj("utaunt_merasmus_fire", hPos) local hSecond = DispatchParticleEffectObj("utaunt_poweraura_green_parent", hPos) 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("teleporter_mvm_bot_persist_red", hPos + Vector(0, 0, 40)); // mannpower_imbalance_red 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.HasBotTag("bot_toxic")) { HellOnEarth.TeleporterParticleSequence_TOXIC(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.HasBotTag("bot_toxic")) { DispatchParticleEffect("merasmus_dazed_explosion", 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 GetCentralVector() { local currentTime = Time() if (currentTime - LAST_UPDATE_TIME < CACHE_DURATION) return LAST_CENTRAL_POS local sumX = 0.0, sumY = 0.0, count = 0 for (local i = 1; i <= MAX_CLIENTS; ++i) { local hEnt = PlayerInstanceFromIndex(i) if (!hEnt || !hEnt.IsAlive() || hEnt.IsBotOfType(TF_BOT_TYPE)) continue local pos = hEnt.GetOrigin() sumX += pos.x sumY += pos.y ++count } if (count > 0) { LAST_CENTRAL_POS = Vector(sumX / count, sumY / count, 0.0) LAST_UPDATE_TIME = currentTime } return LAST_CENTRAL_POS } function getTelePoint(hEntity) { local health = hEntity.GetMaxHealth() local tier, telePoints, taken, cache, cacheTime if (health < 750) { tier = "NORMAL" telePoints= telePoints_NORMAL taken = takenTelePoints_NORMAL } else if (health < 10000) { tier = "BIG" telePoints= telePoints_BIG taken = takenTelePoints_BIG } else { tier = "GIGA" telePoints= telePoints_GIGA taken = takenTelePoints_GIGA } local now = Time() local radius = HellOnEarth.TELEPORT_LOGIC_RADIUS local rsq = radius * radius local center = HellOnEarth.GetCentralVector() if (hEntity.HasBotTag("teleport_pick_random")) { local avail = [] for (local i = 0; i < telePoints.len(); ++i) { if (taken[i] == null) { local d2 = (telePoints[i] - center).LengthSqr() if (d2 >= rsq) avail.append(i) } } if (avail.len() == 0) { for (local i = 0; i < telePoints.len(); ++i) if (taken[i] == null) avail.append(i) } local idx = PickRandomItem(avail) taken[idx] = 1 return [idx, telePoints[idx]] } local tab = [] hEntity.GetAllBotTags(tab) foreach(tag in tab) { if (tag.find("bot_custom_spawn_") == 0) { local parts = split(tag, "_") if (parts.len() == 6) { local x = parts[3].tofloat() local y = parts[4].tofloat() local z = parts[5].tofloat() return [-1, Vector(x, y, z)] } } } cache = TELE_CACHE[tier] cacheTime = TELE_CACHE_TIME[tier] if (cache == null || now - cacheTime >= CACHE_DURATION) { local sorted = [] for (local i = 0; i < telePoints.len(); ++i) { if (taken[i] == null) { local d2 = (telePoints[i] - center).LengthSqr() if (d2 >= rsq) sorted.append([i, telePoints[i], d2]) } } if (sorted.len() == 0) { for (local i = 0; i < telePoints.len(); ++i) { if (taken[i] == null) { local d2 = (telePoints[i] - center).LengthSqr() sorted.append([i, telePoints[i], d2]) } } } sorted.sort(function(a,b) { return a[2] - b[2] }) TELE_CACHE[tier] = sorted TELE_CACHE_TIME[tier] = now cache = sorted } if (cache.len() == 0) return null local entry = cache[0] cache.remove(0) taken[entry[0]] = 1 return [entry[0], entry[1]] } function resetTakenTelePoint(hEntity, index) { local health = hEntity.GetMaxHealth() local tier if (health < 750) tier = "NORMAL" else if (health < 10000) tier = "BIG" else tier = "GIGA" if (tier == "NORMAL") takenTelePoints_NORMAL[index] = null else if (tier == "BIG") takenTelePoints_BIG[index] = null else takenTelePoints_GIGA[index] = null TELE_CACHE[tier] = null TELE_CACHE_TIME[tier] = 0 } 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 BaronProp() { local hProp = SpawnEntityFromTable("prop_dynamic", { targetname = "baron_prop", DisableBoneFollowers = "1", model = "models/doom_eternal/demons/unarmoredbaron_new.mdl", modelscale = "1.7", origin = "0 -758 1230", angles = "0 -90 0", skin = 1, DefaultAnim = "idle" }) SetPropInt(hProp, "m_clrRender", 0x00000000) SetPropInt(hProp, "m_fEffects", GetPropInt(hProp, "m_fEffects") | 0x20) EntFireByHandle(hProp, "runscriptcode", @" foreach (blade in [`lblade1`,`lblade3`,`lblade4`,`rblade1`,`rblade3`,`rblade4`,]) { HellOnEarth.DispatchParticleAttached(self, `buildingdamage_dispenser_fire0`, blade) } HellOnEarth.DispatchParticleAttached(self, `doom_caco_nade`, `lblade2`) HellOnEarth.DispatchParticleAttached(self, `doom_caco_nade`, `rblade2`) ", 1, hProp, hProp) hProp.ResetSequence(8) hProp.SetPlaybackRate(0.9) hProp.ValidateScriptScope() local propScope = hProp.GetScriptScope() local startPos = hProp.GetOrigin() local groundPos = Vector(0, -758, 0) propScope.acceleration <- 980 propScope.velocity <- 0 propScope.dt <- 0.03 propScope.targetPos <- groundPos propScope.delay <- 2.35 propScope.Think <- function() { if(delay > 0) { delay -= dt return -1 } SetPropInt(hProp, "m_clrRender", 0xFFFFFFFF) SetPropInt(hProp, "m_fEffects", GetPropInt(hProp, "m_fEffects") & ~0x20) local currentPos = hProp.GetOrigin() velocity = velocity + acceleration * dt local newPos = currentPos - Vector(0, 0, velocity * dt) if(newPos.z <= targetPos.z) { newPos.z = targetPos.z hProp.SetAbsOrigin(newPos) EntFireByHandle(hProp, "SetAnimation", "groundpound_150_single", 9, hProp, hProp) EntFireByHandle(hProp, "SetPlaybackRate", "0.65", 9, hProp, hProp) NetProps.SetPropString(self, "m_iszScriptThinkFunction", "") } hProp.SetAbsOrigin(newPos) return -1 } AddThinkToEnt(hProp, "Think") } function BaronCam1( startOrigin = Vector(1043, -2113, 262), endOrigin = Vector(-780, -2151, 283), focus1 = Vector(0, -758, 1264), focus2 = Vector(0, -758, 600), duration = 10, curveOffset = 400 ) { local hVC = SpawnEntityFromTable("point_viewcontrol", { origin = startOrigin.ToKVString(), angles = Vector().ToKVString(), fov = 90 }) hVC.ValidateScriptScope() local scope = hVC.GetScriptScope() scope.self <- hVC scope.start <- startOrigin scope.end_ <- endOrigin scope.focus1 <- focus1 scope.focus2 <- focus2 scope.duration<- duration scope.dt <- 0.03 scope.t <- 0 scope.PI <- 3.14159265 local mid = (startOrigin + endOrigin) * 0.5 local dir = endOrigin - startOrigin local perp = Vector(-dir.y, dir.x, 0) local len2d = sqrt(perp.x * perp.x + perp.y * perp.y) if (len2d > 0) { perp *= (curveOffset / len2d) } scope.control <- mid + perp scope.Think <- function() { if (scope.t > scope.duration) { NetProps.SetPropString(scope.self, "m_iszScriptThinkFunction", "") scope.self.Kill() return 0 } local u = scope.t / scope.duration local inv = 1 - u local pos = scope.start * (inv * inv) + scope.control * (2 * inv * u) + scope.end_ * (u * u) scope.self.SetAbsOrigin(pos) local fRaw = (u - 0.5) * 2 if (fRaw < 0) { fRaw = 0 } else if (fRaw > 1) { fRaw = 1 } local easeFocus = (1 - cos(fRaw * scope.PI)) * 0.5 local target = scope.focus1 * (1 - easeFocus) + scope.focus2 * easeFocus local d = target - pos local flatLen = sqrt(d.x * d.x + d.y * d.y) local yaw = atan2(d.y, d.x) * 180 / scope.PI local pitch = -atan2(d.z, flatLen) * 180 / scope.PI scope.self.SetAbsAngles(QAngle(pitch, yaw, 0)) scope.t += scope.dt return scope.dt } AddThinkToEnt(hVC, "Think") EntFireByHandle(hVC, "$EnableAll", "", 0, hVC, hVC) } function BaronCam2( startOrigin = Vector(90, -2576, 619), startAngles = QAngle(3, 90, 0), curvePos = Vector(90, -1809, 610), endOrigin = Vector(30, -1077, 175), lookPos = Vector(0, -758, 0), duration = 12 ) { local hVC = SpawnEntityFromTable("point_viewcontrol", { origin = startOrigin.ToKVString(), angles = startAngles.ToKVString(), fov = 90 }) hVC.ValidateScriptScope() local scope = hVC.GetScriptScope() scope.self <- hVC scope.start <- startOrigin scope.control <- curvePos scope.end_ <- Vector(endOrigin.x, endOrigin.y, endOrigin.z - 30) scope.look <- lookPos scope.startAng <- startAngles scope.duration <- duration scope.dt <- 0.03 scope.t <- 0 scope.PI <- 3.14159265 local dir = scope.end_ - scope.start local perp = Vector(-dir.y, dir.x, 0) local len2d = sqrt(perp.x*perp.x + perp.y*perp.y) if (len2d > 0) { perp *= (150/len2d) } scope.perp <- perp scope.Think <- function() { if (scope.t > scope.duration) { NetProps.SetPropString(scope.self, "m_iszScriptThinkFunction", "") scope.self.Kill() return 0 } local u = scope.t / scope.duration local b = pow(u, 0.4) local easeU = (1 - cos(b * scope.PI)) * 0.5 local invE = 1 - easeU local pos = scope.start * (invE * invE) + scope.control * (2 * invE * easeU) + scope.end_ * (easeU * easeU) local off = scope.perp * (sin(u * scope.PI) * easeU) pos += off scope.self.SetAbsOrigin(pos) local d = scope.look - pos local flat = sqrt(d.x*d.x + d.y*d.y) local yawT = atan2(d.y, d.x) * 180 / scope.PI local pitchT = -atan2(d.z, flat) * 180 / scope.PI local ang = QAngle( scope.startAng.x * (1 - easeU) + pitchT * easeU, scope.startAng.y * (1 - easeU) + yawT * easeU, 0 ) scope.self.SetAbsAngles(ang) scope.t += scope.dt return scope.dt } AddThinkToEnt(hVC, "Think") EntFireByHandle(hVC, "$EnableAll", "", 0, hVC, hVC) } function BaronCam3( startOrigin = Vector(53, -950, 8), lookPos = Vector(0, -758, 64), upHeight = 128, upDuration = 5, zoomOutDist = 30, lookStartFrac = 0.75 ) { local tiltDuration = upDuration * (1 - lookStartFrac) local totalD = upDuration + tiltDuration local hVC = SpawnEntityFromTable("point_viewcontrol", { origin = startOrigin.ToKVString(), angles = QAngle(0,0,0).ToKVString(), fov = 90 }) hVC.ValidateScriptScope() local scope = hVC.GetScriptScope() scope.self <- hVC scope.start <- startOrigin scope.look <- lookPos scope.upHeight <- upHeight scope.upDuration <- upDuration scope.lookStart <- upDuration * lookStartFrac scope.tiltDuration <- tiltDuration scope.zoomOutDist <- zoomOutDist scope.totalD <- totalD scope.dt <- 0.03 scope.t <- 0 scope.PI <- 3.14159265 local dx = startOrigin.x - lookPos.x local dy = startOrigin.y - lookPos.y local dirH = Vector(dx, dy, 0) local lenH = sqrt(dx*dx + dy*dy) if (lenH > 0) { dirH *= (1/lenH) } scope.zoomDir <- dirH * zoomOutDist scope.Think <- function() { if (scope.t > scope.totalD) { NetProps.SetPropString(scope.self, "m_iszScriptThinkFunction", "") scope.self.Kill() return 0 } local pos if (scope.t <= scope.upDuration) { local u = scope.t / scope.upDuration local e = (1 - cos(u * scope.PI)) * 0.5 pos = Vector(scope.start.x, scope.start.y, scope.start.z + scope.upHeight * e) local yaw = atan2(scope.look.y - pos.y, scope.look.x - pos.x) * 180 / scope.PI scope.self.SetAbsOrigin(pos) scope.self.SetAbsAngles(QAngle(0, yaw, 0)) } else { local u2 = (scope.t - scope.lookStart) / scope.tiltDuration if (u2 < 0) { u2 = 0 } else if (u2 > 1) { u2 = 1 } local e2 = (1 - cos(u2 * scope.PI)) * 0.5 pos = Vector(scope.start.x, scope.start.y, scope.start.z + scope.upHeight) pos += scope.zoomDir * e2 scope.self.SetAbsOrigin(pos) local d = scope.look - pos local flat = sqrt(d.x*d.x + d.y*d.y) local yaw = atan2(d.y, d.x) * 180 / scope.PI local pitch = -atan2(d.z, flat) * 180 / scope.PI scope.self.SetAbsAngles(QAngle(pitch, yaw, 0)) } scope.t += scope.dt return scope.dt } AddThinkToEnt(hVC, "Think") EntFireByHandle(hVC, "$EnableAll", "", 0, hVC, hVC) return hVC } 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_ignore")) { local tab = {} hPlayer.GetAllBotTags(tab) foreach(tag in tab) { if (tag.find("time_add") == 0) { local parts = split(tag, "_") if (parts.len() == 3 && TextualTimer) { hPlayer.ValidateScriptScope() local hPlayerScope = hPlayer.GetScriptScope() hPlayerScope.TIME_GLOW <- SpawnEntityFromTable("tf_glow", { GlowColor = "255 255 255 255" target = "bignet" }) SetPropEntity(hPlayerScope.TIME_GLOW, "m_hTarget", hPlayer) } } } return } if (hPlayer.HasBotTag("bot_rocketspawn")) { local tab = {} hPlayer.GetAllBotTags(tab) foreach(tag in tab) { if (tag.find("time_add") == 0) { local parts = split(tag, "_") if (parts.len() == 3 && TextualTimer) { hPlayer.ValidateScriptScope() local hPlayerScope = hPlayer.GetScriptScope() hPlayerScope.TIME_GLOW <- SpawnEntityFromTable("tf_glow", { GlowColor = "255 255 255 255" target = "bignet" }) EntFireByHandle(hPlayer, "runscriptcode", "SetPropEntity(self.GetScriptScope().TIME_GLOW, `m_hTarget`, self)", 5.1, hPlayer, hPlayer) } } } hPlayer.AddCustomAttribute("dmg taken mult from special damage type 1", 0.1, -5) hPlayer.AddCustomAttribute("special damage type", 2, 7.5) hPlayer.AddCustomAttribute("mult_player_movespeed_active", 0.01, 5) local o = PickRandomItem(telePoints_GIGA) HellOnEarth.CreateRocket(o, true, true) 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) return } 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 } hPlayer.AddCustomAttribute("dmg taken mult from special damage type 1", 0.1, -1) hPlayer.AddCustomAttribute("special damage type", 2, -1) hPlayer.AddCond(TF_COND_REPROGRAMMED) 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) 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", format("ClientPrint(null,4,`%s`)", (seconds - i).tostring()), i) } } function SetEntityColor(entity, r, g, b, a) { local color = r | (g << 8) | (b << 16) | (a << 24) NetProps.SetPropInt(entity, "m_clrRender", color) } // 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)", 0.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.1, null, null) EntFireByHandle(hPlayer, "runscriptcode", "HellOnEarth.TimedBotSetup(self)", 0.1, 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.SendAnnotationOn(building, "protect the teleporter to keep the reinforcements coming", 5) 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_shield_unbreakable")) { local tovictim = hVictim.GetOrigin() - params.damage_position if (tovictim.Length() <= 512) { tovictim.z = 0 tovictim.Norm() local victimforward = hVictim.GetForwardVector() victimforward.z = 0 victimforward.Norm() local threshold = -0.445 if (tovictim.Dot(victimforward) > threshold) { return } params.damage = 0 DispatchParticleEffect("manmelter_muzzleflash_flare", params.damage_position, Vector(0, 0, 1)) HellOnEarth.playSoundFromEntity(hVictim, "ptx/weapons/unmaykry_fire_2.wav") return } } else if (hVictim.HasBotTag("bot_shield_breakable")) { local tovictim = hVictim.GetOrigin() - params.damage_position if (tovictim.Length() <= 512) { tovictim.z = 0 tovictim.Norm() local victimforward = hVictim.GetForwardVector() victimforward.z = 0 victimforward.Norm() local threshold = -0.445 if (tovictim.Dot(victimforward) > threshold) { return } local hBotScope = hVictim.GetScriptScope() hBotScope.iShieldDamage += params.damage if (hBotScope.iShieldDamage >= 1000) { EntFireByHandle(hBotScope.hShield, "Kill", null, -1, null, null) local center = hVictim.GetCenter() DispatchParticleEffect("drg_cow_explosioncore_charged_blue", center, Vector(0,0,0)) local bomb = SpawnEntityFromTable("tf_generic_bomb", { sound = "ambient/levels/labs/electric_explosion2.wav", damage = 50, radius = 100, friendlyfire = 0, classname = "megaton" }) bomb.SetTeam(2) bomb.SetAbsOrigin(center) EntFireByHandle(bomb, "RunScriptCode", "self.SetHealth(1); self.TakeDamage(1, 0, activator)", 0.1, hVictim, hVictim) ScreenShake(center, 60, 16, 1, 0, 0, true) return } params.damage = 0 DispatchParticleEffect("drg_cow_explosion_coreflash_blue", params.damage_position, Vector(0,0,1)) HellOnEarth.playSoundFromEntity(hVictim, "ptx/weapons/unmaykry_fire_2.wav", 1000) return } } else if (hVictim.HasBotTag("bot_green_eye_flash")) { // Note: must add the eyeflash manually: FX_green_eyeflash_flash hVictim.ValidateScriptScope() local hScope = hVictim.GetScriptScope() if (!("IS_VURNEABLE" in hScope)) return if (hScope.IS_VURNEABLE) { hScope.IS_VURNEABLE = false hVictim.AddCondEx(71, 5, null) HellOnEarth.playSoundFromEntity(hVictim, "ptx/sfx/demons/marauder/marauder_dazed.wav") local hHalo = HellOnEarth.DispatchParticleEffectObj("merasmus_dazed", hVictim.EyePosition() + Vector(0,0, 25 * hVictim.GetModelScale())) EntFireByHandle(hHalo, "Kill", null, 5, null, null) for (local i = 1; i < 3; i++) { SetPropFloat(GetPropEntityArray(hVictim, "m_hMyWeapons", i), "m_flNextPrimaryAttack", Time() + 8) } } } 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_posessed_big")) DispatchParticleEffect("dskart_blade_hit", params.damage_position, Vector(0, 0, 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.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.MAIN_WAVE_ACTIVE) { if (isBot) { HellOnEarth.DispatchParticleEffectOn(hPlayer, null) local scope = hPlayer.GetScriptScope() if ("hShield" in scope && scope.hShield.IsValid()) scope.hShield.Kill() 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_blood_small")) DispatchParticleEffect("env_sawblood", 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_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")) { local center = hPlayer.GetCenter() DispatchParticleEffect("doom_cyberdemon_missile_blast", center, Vector(0,0,0)) local bomb = SpawnEntityFromTable("tf_generic_bomb", { sound = "ambient/levels/labs/electric_explosion2.wav", damage = 500, radius = 250, friendlyfire = 0, classname = "megaton" }); bomb.SetTeam(2) bomb.SetAbsOrigin(center) EntFireByHandle(bomb, "RunScriptCode", "self.SetHealth(1); self.TakeDamage(1, 0, activator)", 0.1, hPlayer, hPlayer) ScreenShake(center, 60, 16, 1, 0, 0, true) return } 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//////") EntFire("red_fade_timer", "Disable") if ("hGlow" in hPlayer.GetScriptScope()) EntFireByHandle(hPlayer.GetScriptScope().hGlow, "Kill", "", -1, null, null) 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) { local hItem for (local hChild = hPlayer.FirstMoveChild(); hChild; hChild = hChild.NextMovePeer()) { if(hChild.GetClassname() == "tf_weapon_spellbook") { hItem = hChild; break } } if ("TIME_GLOW" in hPlayer.GetScriptScope()) { EntFireByHandle(hPlayer.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") return } 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") return } } } } else { HellOnEarth.AddTeamPoints(-1 * hPlayer.GetMaxHealth()) } if (HellOnEarth.TEAM_WIPE_ACTIVE && !isBot) // TEST THIS { HellOnEarth.playSoundFromEntity(hPlayer, "Halloween.Screams") local alivePlayers = []; for(local i = 1; i <= MAX_CLIENTS; i++) { local hEnt = PlayerInstanceFromIndex(i); if(hEnt && hEnt.IsAlive() && !hEnt.IsBotOfType(TF_BOT_TYPE)) { alivePlayers.append(hEnt); } } printl(alivePlayers.len() - 1) if(alivePlayers.len() - 1 == 2) { foreach(player in alivePlayers) { player.AddCondEx(16, -1, null) } EntFire("two_remaining", "ForceSpawn") HellOnEarth.LAST_PLAYER_BUFF_ACTIVE = true for(local i = 1; i <= MAX_CLIENTS; i++) { local hBot = PlayerInstanceFromIndex(i); if(hBot && hBot.IsBotOfType(TF_BOT_TYPE) && hBot.GetTeam() != alivePlayers[0].GetTeam()) { hPlayer.AddCondEx(32, -1, null) } } return } if(alivePlayers.len() - 1 == 1) { EntFire("one_remaining", "ForceSpawn") HellOnEarth.LAST_PLAYER_BUFF_ACTIVE = true alivePlayers[0].RemoveCondEx(16, true) alivePlayers[0].AddCondEx(11, -1, null) for(local i = 1; i <= MAX_CLIENTS; i++) { local hBot = PlayerInstanceFromIndex(i); if(hBot && hBot.IsBotOfType(TF_BOT_TYPE) && hBot.GetTeam() != alivePlayers[0].GetTeam()) { hPlayer.AddCondEx(32, -1, null) hPlayer.AddCondEx(19, -1, null) } } return } if (alivePlayers.len() - 1 == 0) { SpawnEntityFromTable("game_round_win", { teamnum = 2, force_map_reset = 1 }) .AcceptInput("RoundWin", null, null, null); return } } } } } for(local i = 1; i <= MAX_CLIENTS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if (hPlayer && hPlayer.IsValid()) AddThinkToEnt(hPlayer, null) NetProps.SetPropString(hPlayer, "m_iszScriptThinkFunction", "") } HellOnEarth.DistributeDash() HellOnEarth.flickerBetweenWaves() EntFire("tf_objective_resource", "$SetClientProp$m_nMannVsMachineMaxWaveCount", "5", -1) EntFire("bignet", "runscriptcode", @" for(local i = 1; i <= MAX_PLAYERS; i++) { local hPlayer = PlayerInstanceFromIndex(i) if (!hPlayer || hPlayer.IsFakeClient()) continue HellOnEarth.ChangePlayerTeamMvM(hPlayer, 2) } ",-1) __CollectGameEventCallbacks(HellOnEarth)