/* AMX Mod X * Natural Selection Module * * by the AMX Mod X Development Team * * This file is part of AMX Mod X. * * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, the author gives permission to * link the code of this program with the Half-Life Game Engine ("HL * Engine") and Modified Game Libraries ("MODs") developed by Valve, * L.L.C ("Valve"). You must obey the GNU General Public License in all * respects for all of the code used other than the HL Engine and MODs * from Valve. If you modify this file, you may extend this exception * to your version of the file, but you are not obligated to do so. If * you do not wish to do so, delete this exception statement from your * version. */ /* This file includes game-related stuff, such as message IDs * and forwards */ #ifndef GAMEMANAGER_H #define GAMEMANAGER_H #include "CString.h" class GameManager { private: // Basic game variables int m_IsCombat; int m_HudText2; // Message IDS int m_SetFOV; // Forwards int m_ChangeclassForward; int m_BuiltForward; int m_SpawnForward; int m_TeamForward; int m_RoundStartForward; int m_RoundEndForward; int m_MapResetForward; REAL m_fRoundStartTime; // Time the match should start int m_RoundInProgress; // Whether or not there is a match in progress edict_t *m_SavedEdict; // saved edict for client_built int m_iTitlesMap; bool m_SendMapReset; public: GameManager() { m_SendMapReset = true; m_IsCombat=0; m_HudText2=0; m_SetFOV=0; m_SavedEdict=NULL; m_RoundInProgress=0; ResetForwards(); }; inline void CheckMap(void) { String MapName; MapName.assign(STRING(gpGlobals->mapname)); MapName.ToLower(); m_iTitlesMap=0; if (strcmp(MapName.c_str(),"ns_bast")==0 || strcmp(MapName.c_str(),"ns_bast_classic")==0 || strcmp(MapName.c_str(),"ns_hera")==0 || strcmp(MapName.c_str(),"ns_nothing")==0 || strcmp(MapName.c_str(),"ns_caged")==0 || strcmp(MapName.c_str(),"ns_tanith")==0 || strcmp(MapName.c_str(),"ns_eclipse")==0 || strcmp(MapName.c_str(),"ns_veil")==0 || strcmp(MapName.c_str(),"ns_nancy")==0) { m_iTitlesMap=1; } }; inline int &TitleMap(void) { return m_iTitlesMap; }; inline void SetCombat(int value) { m_IsCombat=value; }; inline int &IsCombat(void) { return m_IsCombat; }; inline void UpdateHudText2(void) { if (!m_HudText2) { GetMessageIDs(); } }; inline void UpdateSetFOV(void) { if (!m_SetFOV) { GetMessageIDs(); } }; inline int &GetHudText2(void) { return m_HudText2; }; inline int &GetSetFOV(void) { return m_SetFOV; }; inline void GetMessageIDs(void) { m_HudText2=GET_USER_MSG_ID(&Plugin_info,"HudText2",NULL); m_SetFOV=GET_USER_MSG_ID(&Plugin_info,"SetFOV",NULL); }; inline void EvaluateCombat(void) { const char *Map=STRING(gpGlobals->mapname); // if map starts with co_ it is combat // otherwise it is classic gameplay if ((Map[0]=='c' || Map[0]=='C') && (Map[1]=='o' || Map[1]=='O') && (Map[2]=='_')) { SetCombat(1); return; } SetCombat(0); }; inline void ResetForwards(void) { m_ChangeclassForward=-1; m_BuiltForward=-1; m_SpawnForward=-1; m_TeamForward=-1; m_RoundStartForward=-1; m_RoundEndForward=-1; m_MapResetForward=-1; }; inline void RegisterForwards(void) { ResetForwards(); m_SpawnForward = MF_RegisterForward("client_spawn",ET_IGNORE,FP_CELL/*id*/,FP_DONE); m_TeamForward = MF_RegisterForward("client_changeteam",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*new team*/,FP_CELL/*old team*/,FP_DONE); m_ChangeclassForward = MF_RegisterForward("client_changeclass", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE); m_RoundStartForward = MF_RegisterForward("round_start", ET_IGNORE, FP_DONE); m_RoundEndForward = MF_RegisterForward("round_end", ET_IGNORE, FP_FLOAT, FP_DONE); m_MapResetForward = MF_RegisterForward("map_reset", ET_IGNORE, FP_CELL, FP_DONE); }; inline void StartFrame(void) { if (gpGlobals->time >= m_fRoundStartTime) { g_pFunctionTable->pfnStartFrame=NULL; RoundStart(); } }; /** * This is called from MessageHandler's Countdown * hook. It passes the only byte sent (time) */ inline void HandleCountdown(int &Time) { // Begin hooking start frame g_pFunctionTable->pfnStartFrame=::StartFrame; // set time of round start m_fRoundStartTime=gpGlobals->time + Time; m_SendMapReset = true; }; /** * This is called from MessageHandler's GameStatus * hook. It passes the first byte sent. * 2 = Round End */ inline void HandleGameStatus(int &FirstByte) { switch (FirstByte) { case 0: if (m_SendMapReset) { MF_ExecuteForward(m_MapResetForward, 0); } m_SendMapReset = false; break; case 1: MF_ExecuteForward(m_MapResetForward, 1); break; case 2: RoundEnd(); break; } }; inline void RoundStart() { m_RoundInProgress=1; MF_ExecuteForward(m_RoundStartForward); }; inline void RoundEnd() { m_RoundInProgress=0; MF_ExecuteForward(m_RoundEndForward,gpGlobals->time - m_fRoundStartTime); }; inline int &RoundInProgress() { return m_RoundInProgress; }; // no need to check -1 forwards in these // amxmodx checks it anyway inline void ExecuteClientBuilt(int &PlayerID, int StructureID, int &StructureType, int &Impulse) { MF_ExecuteForward(m_BuiltForward,PlayerID, StructureID, StructureType, Impulse); }; inline void ExecuteClientSpawn(int &PlayerID) { MF_ExecuteForward(m_SpawnForward,PlayerID); }; inline void ExecuteClientChangeTeam(int &PlayerID, int &NewTeam, int &OldTeam) { MF_ExecuteForward(m_TeamForward,PlayerID,OldTeam,NewTeam); }; inline void ExecuteClientChangeClass(int &PlayerID, int &NewClass, int &OldClass) { MF_ExecuteForward(m_ChangeclassForward,PlayerID,NewClass,OldClass); }; inline void ExecuteRoundStart(void) { MF_ExecuteForward(m_RoundStartForward); }; inline void ExecuteRoundEnd(void) { MF_ExecuteForward(m_RoundEndForward); }; /** * The next few functions tell the module what metamod hooks * i need. This tries to run-time optimize out what we * do not need. */ void HookPreThink(void); void HookPostThink_Post(void); void HookPreThink_Post(void); void HookUpdateClientData(void); void HookLogs(void); // AlertMessage AND CreateNamedEntity inline void CheckAllHooks(void) { HookPreThink(); HookPostThink_Post(); HookPreThink_Post(); HookUpdateClientData(); HookLogs(); }; inline void SetTemporaryEdict(edict_t *Edict) { m_SavedEdict=Edict; }; inline edict_t *GetTemporaryEdict(void) { return m_SavedEdict; }; }; extern GameManager GameMan; #endif // GAMEMANAGER_H