class MinionData
{
array<EHandle> m_hMinions;
int GetMinionCount() { return m_hMinions.length(); }
array<EHandle>@ GetMinions() { return m_hMinions; }

MinionData() 
{
	@m_pMenu = BuyMenu(this);
}

void SpawnGonome(CBasePlayer@ pPlayer)
{
	Vector vecOrigin = pPlayer.pev.origin + g_Engine.v_forward * 64 + g_Engine.v_up * 12;
	string szClassname;
	dictionary keys;
	szClassname = "monster_gonome";
	keys["targetname"] = "_minion_" + pPlayer.entindex();
	keys["friendly"] = "1";
	keys["spawnflag"] = "32";
	keys["is_player_ally"] = "1";

	CBaseEntity@ pGonome = g_EntityFuncs.CreateEntity( szClassname, keys, true );
	cast<CBaseMonster@>(pGonome).m_FormattedName = string( pPlayer.pev.netname ) + '\'s Gonome';
	pGonome.pev.health = pGonome.pev.health * 2;
	pGonome.pev.velocity = g_Engine.v_up * 300;
	pGonome.pev.origin = vecOrigin;
	pGonome.pev.angles.z = 0;
	pGonome.pev.angles.x = 0;

	if(pGonome !is null)
	{
		g_EntityFuncs.DispatchSpawn(pGonome.edict());
		m_hMinions.insertLast(EHandle(pGonome));
		g_SoundSystem.EmitSound( pPlayer.edict(), CHAN_WEAPON, "debris/beamstart7.wav", VOL_NORM, 0.8 );
	}
}

void CheckEngineerMinions()
{   
	const int iMaxPlayers = g_Engine.maxClients;
	for(int i = 1; i <= iMaxPlayers; ++i)
	{
		CBasePlayer@ pPlayer = g_PlayerFuncs.FindPlayerByIndex(i);
		if(pPlayer !is null && pPlayer.IsConnected())
		{
			string steamID = g_EngineFuncs.GetPlayerAuthId(pPlayer.edict());
            
			// Initialize MinionData if it doesn't exist
			if(!g_PlayerMinions.exists(steamID))
			{
				MinionData data;
				@g_PlayerMinions[steamID] = data;
			}

			MinionData@ Minion = cast<MinionData@>(g_PlayerMinions[steamID]);
			if(Minion !is null)
			{
				// Normal update for active minions
				Minion.Update(pPlayer);
			}
		}
	}
}

void Update(CBasePlayer@ pPlayer)
{
	if( pPlayer is null )
		return;

	// Remove invalid Minions and check frags.
	for(int i = m_hMinions.length() - 1; i >= 0; i--)
	{
		CBaseEntity@ pExistingMinion = m_hMinions[i].GetEntity();
            
		// First get the name while minion still exists
		string name = pExistingMinion !is null ? string(pExistingMinion.pev.targetname) : "";
            
		// Then check if it's dead or invalid
		if(pExistingMinion is null || !pExistingMinion.IsAlive())
		{
			/* Find minion type and reduce pool before removing from array
			for(uint j = 0; j < MINION_NAMES.length(); j++)
			{
				if(name.Find(MINION_NAMES[j]) >= 0)
				{
					flMinionReservePool -= MINION_COSTS[j];
					break;
				}
			}
                
			m_hMinions.removeAt(i);
			g_PlayerFuncs.ClientPrint(pPlayer, HUD_PRINTCENTER, "Robot was destroyed!\n");*/
			continue;
		}

		// Check if minion has gained a frag.
		if(pExistingMinion.pev.frags > 0)
		{
			// Add frag to player.
			pPlayer.pev.frags += 1;
			// Reset minion's frag counter.
			pExistingMinion.pev.frags = 0;
		}
	}

	/*m_bActive = (m_hMinions.length() > 0);

	// Update stats reference for stat menu.
	if(m_pStats is null)
	{
		string steamID = g_EngineFuncs.GetPlayerAuthId(pPlayer.edict());
		if(g_PlayerRPGData.exists(steamID))
		{
			PlayerData@ data = cast<PlayerData@>(g_PlayerRPGData[steamID]);
			if(data !is null && data.GetCurrentClass() == PlayerClass::CLASS_ENGINEER)
			{
				@m_pStats = data.GetCurrentClassStats();
			}
		}
	}*/
}

}
