/* * Author: Needles * https://steamcommunity.com/profiles/76561198026257137/ */ ::Debug.Print("*** PLAYERS"); ::Players <- {}; ::Players.playerManager <- Entities.FindByClassname(null, "tf_player_manager"); function Players::GetPlayerManager() { if (::Players.playerManager == null || !::Players.playerManager.IsValid()) ::Players.playerManager <- Entities.FindByClassname(null, "tf_player_manager"); return ::Players.playerManager; } function Players::Max() { return MaxClients().tointeger(); } function Players::GetPlayerUserID(player) { if (player == null) return null; return NetProps.GetPropIntArray(::Players.GetPlayerManager(), "m_iUserID", player.entindex()); } function Players::GetPlayerName(player) { return NetProps.GetPropString(player, "m_szNetname"); } function Players::GetPlayerSteamID(player) { return NetProps.GetPropString(player, "m_szNetworkIDString"); } function Players::GetPlayerFromSteamID(steamid) { for (local i = 1; i < ::Players.Max(); i++) { local player = PlayerInstanceFromIndex(i); if (player == null) continue; if (NetProps.GetPropString(player, "m_szNetworkIDString") == steamid) return player; } return null; } function Players::IsPlayerValid(player) { return (player != null && player.IsValid() && player.IsPlayer() && player.GetTeam() > Constants.ETFTeam.TEAM_SPECTATOR); } function Players::IsPlayerAlive(player) { return (NetProps.GetPropInt(player, "m_lifeState") == LIFE_STATE.ALIVE); } function Players::IsPlayerBot(player) { return (player.IsBotOfType(1337)); } function Players::FindBotByTag(tag) { local playerList = []; for (local i = 1; i <= ::Players.Max(); i++) { local player = PlayerInstanceFromIndex(i); if (player == null) continue; if (!PlayerIsBot(player)) continue; if (player.HasBotTag(tag)) playerList.append(player); } return playerList; } function Players::DualTrace(player, origin, mask, ignore) { local traceFeet = { start = origin, end = player.GetOrigin(), mask = mask, ignore = ignore, }; TraceLineEx(traceFeet); local traceEyes = { start = origin, end = player.EyePosition(), mask = mask, ignore = ignore, }; TraceLineEx(traceEyes); return (traceFeet.hit == true && traceEyes.hit == true); } // @TODO - Turn this into a generalized HighlightEntity function function Players::HighlightPlayer(player, color = null) { if (!::Players.IsPlayerValid(player)) { return; } local scope = player.GetScriptScope(); if (scope.ent_highlight != null && scope.ent_highlight.IsValid()) { return; } scope.ent_highlight = SpawnEntityFromTable("tf_glow", { origin = player.GetOrigin(), Target = player.GetName(), VisibilityMode = 0, // Always visible GlowColor = ::Color.GetTeamColor(player.GetTeam()).tostring(), }); EntFireByHandle(scope.ent_highlight, "SetParent", "!activator", -1.0, player, null); ::Debug.Print("*** PLAYERS - Applied highlight to player " + player); } function Players::HealPlayer(target, healer, amount) { // Create heal number on target world entity SendGlobalGameEvent("player_healed", { patient = ::Players.GetPlayerUserID(target), healer = ::Players.GetPlayerUserID(healer), amount = amount, priority = 1, }); // Create heal number on target HUD SendGlobalGameEvent("player_healonhit", { entindex = target.entindex(), amount = amount, }); // The healing in question: amount = ::MathN.Clamp(target.GetMaxHealth() - target.GetHealth(), 0.0, amount); target.SetHealth(target.GetHealth() + amount); } function Players::IsCritBoosted(player) { return ( player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED) // Kritzkrieg || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_USER_BUFF) // Crit canteen || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_PUMPKIN) // Crit pumpkin || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_ON_KILL) // Crit on kill || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_RAGE_BUFF) // Phlog || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_DEMO_CHARGE) // End of demoknight charge || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_BONUS_TIME) // Round win || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_CTF_CAPTURE) // Flag capture || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_FIRST_BLOOD) // Arena first blood || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_CARD_EFFECT) // Halloween || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_RUNE_TEMP) // Mannpower ); } function Players::IsMinicritBoosted(player) { return ( player.InCond(Constants.ETFCond.TF_COND_OFFENSEBUFF) // buff banner || player.InCond(Constants.ETFCond.TF_COND_ENERGY_BUFF) // crit-a-cola, steak, cleaner's carbine ) } function Players::IsOnFire(player) { return ( player.InCond(Constants.ETFCond.TF_COND_BURNING) // Burning || player.InCond(Constants.ETFCond.TF_COND_BURNING_PYRO) // Dragons fury vs pyro ); } function Players::IsUbered(player) { return ( player.InCond(Constants.ETFCond.TF_COND_INVULNERABLE) // medigun || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED) // kritzkreig || player.InCond(Constants.ETFCond.TF_COND_MEGAHEAL) // quickfix || player.InCond(Constants.ETFCond.TF_COND_MEDIGUN_UBER_BULLET_RESIST) // vacc bullet || player.InCond(Constants.ETFCond.TF_COND_MEDIGUN_UBER_BLAST_RESIST) // vacc blast || player.InCond(Constants.ETFCond.TF_COND_MEDIGUN_UBER_FIRE_RESIST) // vacc fire ); } function Players::IsUsingCanteen(player) { return ( player.InCond(Constants.ETFCond.TF_COND_INVULNERABLE_USER_BUFF) // uber canteen || player.InCond(Constants.ETFCond.TF_COND_CRITBOOSTED_USER_BUFF) // crit canteen ); } ::Events.GetGlobalEvent(EVENT.PLAYER_SPAWN).AddListener( function(params) { local player = GetPlayerFromUserID(params.userid); if (!::Players.IsPlayerValid(player)) { return; } player.ValidateScriptScope(); local scope = player.GetScriptScope(); if ("ent_highlight" in scope && scope.ent_highlight != null && scope.ent_highlight.IsValid()) { scope.ent_highlight.Destroy(); ::Debug.Print("*** PLAYERS - Removed highlight from player " + player); } scope.ent_highlight <- null; EntFireByHandle(player, "AddOutput", "targetname " + UniqueString(), -1.0, null, null); } );