text: #ifndef GAME_SERVER_GAMECONTROLLER_H
  #define GAME_SERVER_GAMECONTROLLER_H
  
  #include <base/vmath.h>
  
  /*
  	Class: Game Controller
  		Controls the main game logic. Keeping track of team and player score,
  		winning conditions and specific game logic.
  */
  class IGameController
  {
  	vec2 m_aaSpawnPoints[3][64];
  	int m_aNumSpawnPoints[3];
  	
  	class CGameContext *m_pGameServer;
  	class IServer *m_pServer;
  	
  protected:
  	CGameContext *GameServer() const { return m_pGameServer; }
  	IServer *Server() const { return m_pServer; }
  
  	struct CSpawnEval
  	{
  		CSpawnEval()
  		{
  			m_Got = false;
  			m_FriendlyTeam = -1;
  			m_Pos = vec2(100,100);
  		}
  			
  		vec2 m_Pos;
  		bool m_Got;
  		int m_FriendlyTeam;
  		float m_Score;
  	};
  
  	float EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos);
  	void EvaluateSpawnType(CSpawnEval *pEval, int Type);
  	bool EvaluateSpawn(class CPlayer *pP, vec2 *pPos);
  
  	void CycleMap();
  	void ResetGame();
  	
  	char m_aMapWish[128];
  
  	
  	int m_RoundStartTick;
  	int m_GameOverTick;
  	int m_SuddenDeath;
  	
  	int m_aTeamscore[2];
  	
  	int m_Warmup;
  	int m_RoundCount;
  	
  	int m_GameFlags;
  	int m_UnbalancedTick;
  	bool m_ForceBalanced;
  	
  public:
  	const char *m_pGameType;
  
  	bool IsTeamplay() const;
  	
  	IGameController(class CGameContext *pGameServer);
  	virtual ~IGameController();
  
  	void DoTeamScoreWincheck();
  	void DoPlayerScoreWincheck();
  	
  	void DoWarmup(int Seconds);
  	
  	void StartRound();
  	void EndRound();
  	void ChangeMap(const char *pToMap);
  	
  	bool IsFriendlyFire(int Cid1, int Cid2);
  	
  	bool IsForceBalanced();
  
  	/*
  	
  	*/	
  	virtual bool CanBeMovedOnBalance(int Cid);
  
  	virtual void Tick();
  	
  	virtual void Snap(int SnappingClient);
  	
  	/*
  		Function: on_entity
  			Called when the map is loaded to process an entity
  			in the map.
  			
  		Arguments:
  			index - Entity index.
  			pos - Where the entity is located in the world.
  			
  		Returns:
  			bool?
  	*/
  	virtual bool OnEntity(int Index, vec2 Pos);
  	
  	/*
  		Function: on_CCharacter_spawn
  			Called when a CCharacter spawns into the game world.
  			
  		Arguments:
  			chr - The CCharacter that was spawned.
  	*/
  	virtual void OnCharacterSpawn(class CCharacter *pChr);
  	
  	/*
  		Function: on_CCharacter_death
  			Called when a CCharacter in the world dies.
  			
  		Arguments:
  			victim - The CCharacter that died.
  			killer - The player that killed it.
  			weapon - What weapon that killed it. Can be -1 for undefined
  				weapon when switching team or player suicides.
  	*/
  	virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
  
  
  	virtual void OnPlayerInfoChange(class CPlayer *pP);
  
  	//
  	virtual bool CanSpawn(class CPlayer *pP, vec2 *pPos);
  
  	/*
  	
  	*/	
  	virtual const char *GetTeamName(int Team);
  	virtual int GetAutoTeam(int NotThisId);
  	virtual bool CanJoinTeam(int Team, int NotThisId);
  	bool CheckTeamBalance();
  	bool CanChangeTeam(CPlayer *pPplayer, int JoinTeam);
  	int ClampTeam(int Team);
  
  	virtual void PostReset();
  };
  
  #endif
  