/*
* 玩家数量怪物生命值调整器 / Monster health scaler based on player count
* 作者(Author): Ice Box
* Steam: https://steamcommunity.com/id/ibox666/
* 如需使用此脚本请联系作者 / If you need to use this script, please contact the author
*/

namespace PointMonsterHealthScaler
{

const int SF_START_OFF = 1 << 0;
const int SF_PASS_ACTIVATOR = 1 << 1;
const int SF_TRIGGER_ONCE = 1 << 2;
const int SF_REMOVE_ON_USE = 1 << 3;

class CPointMonsterHealthScaler : ScriptBaseEntity
{
	private bool m_bEnabled = true;
	private bool m_bHasTriggered = false;
	private float m_flDelay = 0.0;
	private string m_szMonsterTargetname = "";
	private string m_szKillTarget = "";
	private float m_flBaseHealth = 1000.0;
	private int m_iMaxPlayers = 0;
	private EHandle m_hActivator;

	bool KeyValue(const string& in szKey, const string& in szValue)
	{
		if(szKey == "monster_targetname")
		{
			m_szMonsterTargetname = szValue;
			return true;
		}
		else if(szKey == "base_health")
		{
			m_flBaseHealth = atof(szValue);
			if(m_flBaseHealth < 0)
				m_flBaseHealth = 1000.0;
			return true;
		}
		else if(szKey == "max_players")
		{
			m_iMaxPlayers = atoi(szValue);
			if(m_iMaxPlayers < 0)
				m_iMaxPlayers = 0;
			return true;
		}
		else if(szKey == "delay")
		{
			m_flDelay = atof(szValue);
			if(m_flDelay < 0)
				m_flDelay = 0.0;
			return true;
		}
		else if(szKey == "killtarget")
		{
			m_szKillTarget = szValue;
			return true;
		}

		return BaseClass.KeyValue(szKey, szValue);
	}

	void Spawn()
	{
		self.pev.solid = SOLID_NOT;
		self.pev.movetype = MOVETYPE_NONE;
		self.pev.effects |= EF_NODRAW;

		g_EntityFuncs.SetOrigin(self, self.pev.origin);

		if(self.pev.SpawnFlagBitSet(SF_START_OFF))
		{
			m_bEnabled = false;
		}
	}

	void Use(CBaseEntity@ pActivator, CBaseEntity@ pCaller, USE_TYPE useType, float flValue)
	{
		switch(useType)
		{
			case USE_ON:
			{
				m_bEnabled = true;
				return;
			}
			case USE_OFF:
			{
				m_bEnabled = false;
				return;
			}
			case USE_KILL:
			{
				g_EntityFuncs.Remove(self);
				return;
			}
		}

		if(!m_bEnabled)
		{
			return;
		}

		if(self.pev.SpawnFlagBitSet(SF_TRIGGER_ONCE) && m_bHasTriggered)
		{
			return;
		}

		if(pActivator is null)
		{
			return;
		}

		m_bHasTriggered = true;

		m_hActivator = EHandle(pActivator);

		if(m_flDelay > 0)
		{
			g_Scheduler.SetTimeout(this, "DelayedScaleHealth", m_flDelay);
		}
		else
		{
			ScaleMonsterHealth();
		}
	}

	void DelayedScaleHealth()
	{
		ScaleMonsterHealth();
	}

	int GetPlayerCount()
	{
		int playerCount = 0;
		
		for(int i = 1; i <= g_Engine.maxClients; i++)
		{
			CBasePlayer@ pPlayer = g_PlayerFuncs.FindPlayerByIndex(i);
			
			if(pPlayer !is null && pPlayer.IsConnected() && pPlayer.IsAlive())
			{
				playerCount++;
			}
		}
		
		return playerCount;
	}

	void ScaleMonsterHealth()
	{
		CBaseEntity@ pMonster = null;
		int monsterCount = 0;
		
		int playerCount = GetPlayerCount();
		
		if(m_iMaxPlayers > 0 && playerCount > m_iMaxPlayers)
		{
			playerCount = m_iMaxPlayers;
		}

		float newHealth = m_flBaseHealth * playerCount;

		while((@pMonster = g_EntityFuncs.FindEntityByTargetname(pMonster, m_szMonsterTargetname)) !is null)
		{
			pMonster.pev.health = newHealth;
			pMonster.pev.max_health = newHealth;
			
			monsterCount++;
		}
		
		if(monsterCount == 0)
		{
			return;
		}

		if(m_szKillTarget != "")
		{
			CBaseEntity@ pKillEntity = null;

			while((@pKillEntity = g_EntityFuncs.FindEntityByTargetname(pKillEntity, m_szKillTarget)) !is null)
			{
				g_EntityFuncs.Remove(pKillEntity);
			}
		}

		if(self.pev.target != "" && self.pev.target != self.GetTargetname())
		{
			CBaseEntity@ pActivator = null;

			if(self.pev.SpawnFlagBitSet(SF_PASS_ACTIVATOR))
			{
				@pActivator = m_hActivator.GetEntity();
			}

			g_EntityFuncs.FireTargets(self.pev.target, pActivator, self, USE_TOGGLE, 0.0f);
		}

		if(self.pev.SpawnFlagBitSet(SF_REMOVE_ON_USE))
		{
			g_EntityFuncs.Remove(self);
		}
	}

	void UpdateOnRemove()
	{
		m_bEnabled = false;

		BaseClass.UpdateOnRemove();
	}
}

void Register()
{
	g_CustomEntityFuncs.RegisterCustomEntity("PointMonsterHealthScaler::CPointMonsterHealthScaler", "point_monster_health_scaler");
}

}