//rewrite of braindawg_request.lua printl("Player Counter Loaded") local playercount = 0, playersalive = 0; local steamids = []; // local resource = FindByClassname(null, "tf_objective_resource"); // local gamerules = FindByClassname(null, "tf_gamerules"); // local playermanager = FindByClassname(null, "tf_player_manager"); local wavestart = false; ::ApplyBuffs <- function(playersalive) { // foreach(_,i in steamids) // ClientPrint(null, 3, format("player %s lifestate is %d", GetPropString(GetPlayerFromUserID(i), "m_szNetname"), GetPropInt(GetPlayerFromUserID(i), "m_lifeState"))); printl(format("Players Alive: %d", playersalive) ); ClientPrint(null, 3, format("Players Alive: %d", playersalive)); if (!wavestart) return; if (playersalive > 3) { for (local i = 0; i < steamids.len(); i++) { local player = GetPlayerFromUserID(steamids[i]); if (player.GetHealth() < 1) continue; player.RemoveCond(TF_COND_CRITBOOSTED_USER_BUFF); player.RemoveCond(TF_COND_CRITBOOSTED_CARD_EFFECT); player.RemoveCond(TF_COND_OFFENSEBUFF); player.RemoveCond(TF_COND_ENERGY_BUFF); } return; } if (playersalive <= 3) { for (local i = 0; i < steamids.len(); i++) { local player = GetPlayerFromUserID(steamids[i]); if (player.GetHealth() < 1) continue; EntFireByHandle(player, "RollRareSpell", "", 0.0, null, null); DoEntFire("tankboss_ghost", "SetSpeed", "55", 0.0, null, null); } } if (playersalive <= 2) { for (local i = 0; i < steamids.len(); i++) { local player = GetPlayerFromUserID(steamids[i]); if (player.GetHealth() < 1) continue; //we apply cola and banner minicrits to mitigate losing the effect //if a scout uses cola while under buff banner effect this might still get cleared //just don't do that lmao player.AddCond(TF_COND_OFFENSEBUFF); player.AddCond(TF_COND_ENERGY_BUFF); DoEntFire("tankboss_ghost", "SetSpeed", "55", 0.0, null, null) } } if (playersalive < 2) { for (local i = 0; i < steamids.len(); i++) { local player = GetPlayerFromUserID(steamids[i]); if (player.GetHealth() < 1) continue; //canteen crits give sentry firing speed //we apply 2 crit conds incase user uses a canteen player.AddCond(TF_COND_CRITBOOSTED_USER_BUFF); player.AddCond(TF_COND_CRITBOOSTED_CARD_EFFECT); DoEntFire("tankboss_ghost", "SetSpeed", "55", 0.0, null, null) } } } //start at max players, then decrement for every dead/disconnected player ::CountAlivePlayers <- function() { if (!wavestart) return; local playersalive = steamids.len(); for (local i = 0; i < steamids.len(); i++) { if (GetPlayerFromUserID(steamids[i]) == null) steamids.remove(i); local player = GetPlayerFromUserID(steamids[i]); // printl(i + " : " + player.GetHealth() + " : " + GetPropInt(player, "m_lifeState")) //bug or something //player.GetHealth() always returns 1 even if the player is dead? //we shitfix this by not allowing player to survive at 1hp in the player_hurt event lol if (GetPropInt(player, "m_lifeState") > 0 || player.GetHealth() < 2) { playersalive--; } } //fail the wave if everyone dies if (playersalive == 0) { DoEntFire("bots_win", "RoundWin", "", 0.0, null, null); return; } //give out buffs on low player count DoEntFire("tf_gamerules", "RunScriptCode","ApplyBuffs("+playersalive+")", 0.1, null, null); } function OnGameEvent_player_hurt(params) { if (IsPlayerABot(GetPlayerFromUserID(params.userid)) || GetPlayerFromUserID(params.userid).GetTeam() != TF_TEAM_PVE_DEFENDERS || params.health > 1) return; if (params.health == 1) GetPlayerFromUserID(params.userid).AddCustomAttribute("health drain", -1, 0.0) } function OnGameEvent_mvm_wave_complete(params) { wavestart = false; } function OnGameEvent_mvm_reset_stats(params) { wavestart = false; } function OnGameEvent_mvm_wave_failed(params) { wavestart = false; } function OnGameEvent_mvm_begin_wave(params) { wavestart = true; CountAlivePlayers(); } //add players to the array //this only checks the playercount, playersalive is handled in the CountAlivePlayers() function //we use post_inventory_application instead of player_spawn because this script is fired on wave init function OnGameEvent_post_inventory_application(params) { if (IsPlayerABot(GetPlayerFromUserID(params.userid) || GetPlayerFromUserID(params.userid).GetTeam() != TF_TEAM_PVE_DEFENDERS)) return; GetPlayerFromUserID(params.userid).RemoveCustomAttribute("health drain"); for (local i = 0; i < steamids.len(); i++) if (steamids[i] == params.userid) return; steamids.append(params.userid); playercount = steamids.len() printl(format("Players: %d", playercount)); } function OnGameEvent_player_disconnect(params) { local player = GetPlayerFromUserID(params.userid) if (IsPlayerABot(player) || player.GetTeam() != TF_TEAM_PVE_DEFENDERS) return; //idc enough to fix this correctly just force fail the wave when there's 0 players for (local i = 0; i <= steamids.len(); i++) if (steamids[i] == params.userid) steamids.remove(i); //wrong // foreach(_, v in steamids) if (v == params.userid) steamids.remove(v); playercount = steamids.len() printl(format("Players: %d", playercount) ); if (playercount < 1 && wavestart) { DoEntFire("bots_win", "RoundWin", "", 0.0, null, null); return; } CountAlivePlayers(); } function OnGameEvent_player_spawn(params) { local player = GetPlayerFromUserID(params.userid) //set normal blood for bots (does this work?) if (IsPlayerABot(player) || player.GetTeam() != TF_TEAM_PVE_DEFENDERS) SetPropInt(player, "m_bloodColor", 2); return; CountAlivePlayers(); } function OnGameEvent_player_death(params) { //ignore bots and dead ringer (dead ringer triggers this event but player health is still > 1) if (IsPlayerABot(GetPlayerFromUserID(params.userid)) || GetPlayerFromUserID(params.userid).GetTeam() != TF_TEAM_PVE_DEFENDERS || GetPlayerFromUserID(params.userid).GetHealth() > 1) return; //force respawn in pre-round to avoid fucking up the counter as soon as the wave starts //still technically possible, but harder to time if (!wavestart) { DoEntFire("tf_gamerules", "RunScriptCode", format("GetPlayerFromUserID(%d).ForceRespawn()", params.userid), 0.0, null, null); return; } // DoEntFire("tf_gamerules", "CallScriptFunction", "CountAlivePlayers", 1, null, null) CountAlivePlayers(); } __CollectGameEventCallbacks(this)