297 lines
6.5 KiB
C++
297 lines
6.5 KiB
C++
// vim: set ts=4 sw=4 tw=99 noet:
|
|
//
|
|
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
|
// Copyright (C) The AMX Mod X Development Team.
|
|
//
|
|
// This software is licensed under the GNU General Public License, version 3 or higher.
|
|
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
|
// https://alliedmods.net/amxmodx-license
|
|
|
|
//
|
|
// Natural Selection Module
|
|
//
|
|
|
|
/* This file includes game-related stuff, such as message IDs
|
|
* and forwards
|
|
*/
|
|
#ifndef GAMEMANAGER_H
|
|
#define GAMEMANAGER_H
|
|
|
|
#include <am-string.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)
|
|
{
|
|
ke::AString MapName;
|
|
|
|
MapName = UTIL_ToLowerCase(STRING(gpGlobals->mapname));
|
|
|
|
m_iTitlesMap=0;
|
|
|
|
if (MapName.compare("ns_bast")==0 ||
|
|
MapName.compare("ns_bast_classic") == 0 ||
|
|
MapName.compare("ns_hera") == 0 ||
|
|
MapName.compare("ns_nothing") == 0 ||
|
|
MapName.compare("ns_caged") == 0 ||
|
|
MapName.compare("ns_tanith") == 0 ||
|
|
MapName.compare("ns_eclipse") == 0 ||
|
|
MapName.compare("ns_veil") == 0 ||
|
|
MapName.compare("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, NewTeam, OldTeam);
|
|
};
|
|
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
|