/* 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. */ /* Calls going from the engine to the game dll are handled here */ #include "sdk/amxxmodule.h" #include "ns.h" #include "utilfunctions.h" #include "SpawnManager.h" #include "GameManager.h" #include "CPlayer.h" #include "MessageHandler.h" #include "LocationManager.h" #include "ParticleManager.h" LocationManager LocationMan; GameManager GameMan; SpawnManager SpawnMan; extern edict_t* avhgameplay; CPlayer g_player[33]; extern void *GameRules; bool NEW_Initialized=false; edict_t *NEW_FirstEdict=NULL; /** * This is only called during the CountDown * This call will unhook itself with Metamod * when it is finished. */ void StartFrame() { GameMan.StartFrame(); RETURN_META(MRES_IGNORED); } /** * Check spawning for: * - Worldspawn * - Initialize NEW_Utilities * - Clear CPlayer / CSpawn data * - info_team_start (team spawn point) * - Save in list * - info_player_start (ready room spawn point) * - Save in list */ int DispatchSpawn(edict_t *pEntity) { if (!NEW_Initialized) { NEW_Initialize(pEntity); } if (ENTINDEX_NEW(pEntity)==0) // worldspawn { int i=0; while (i<=32) { GET_PLAYER_I(i++)->Reset(); } LocationMan.Clear(); SpawnMan.Clear(); } else if (FStrEq(STRING(pEntity->v.classname),"info_player_start")) { // Mark down the ready room spawn point. SpawnMan.InsertReadyRoom(pEntity); } else if (FStrEq(STRING(pEntity->v.classname),"info_team_start")) { // Mark down the team based spawn point. SpawnMan.Insert(pEntity); } else if (FStrEq(STRING(pEntity->v.classname),"env_particles_custom")) { ParticleMan.Add(STRING(pEntity->v.targetname),0); } RETURN_META_VALUE(MRES_IGNORED, 0); } void DispatchKeyValue(edict_t *pEntity,KeyValueData *pkvd) { if (strcmp(pkvd->szKeyName,"locationname")==0) { if (pkvd->szClassName && strcmp(pkvd->szClassName,"info_location")==0) { // this is a BSP model, so calling SetModel // will update the mins/maxs SET_MODEL(pEntity,STRING(pEntity->v.model)); // Add it to our list LocationMan.Add(pkvd->szValue,pEntity); RETURN_META(MRES_IGNORED); } } RETURN_META(MRES_IGNORED); } void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) { // Reset CPlayer classes (again?) for(int i = 1; i <= gpGlobals->maxClients;i++) { CPlayer *player=GET_PLAYER_I(i); player->FullReset(); player->SetEdict(pEdictList + i); } GameRules=NULL; RETURN_META(MRES_IGNORED); } void ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax) { Initialize_MessageHandler(); g_pFunctionTable_Post->pfnServerActivate=NULL; RETURN_META(MRES_IGNORED); } /** * PlayerPreThink, PlayerPreThink_Post and PlayerPostThink_Post * all disable their Metamod hook calls when they are no longer needed. * (Actually it is disabled in the native calls) */ void PlayerPreThink(edict_t *pEntity) { GET_PLAYER_E(pEntity)->PreThink(); RETURN_META(MRES_IGNORED); } void PlayerPreThink_Post(edict_t *pEntity) { GET_PLAYER_E(pEntity)->PreThink_Post(); RETURN_META(MRES_IGNORED); } void PlayerPostThink_Post(edict_t *pEntity) { GET_PLAYER_E(pEntity)->PostThink_Post(); RETURN_META(MRES_IGNORED); } // Map is changing/server is shutting down. // We do all cleanup routines here, since, as noted in metamod's dllapi // ServerDeactivate is the very last function called before the server loads up a new map. void ServerDeactivate(void) { for (int i=1;i<=gpGlobals->maxClients;i++) { GET_PLAYER_I(i)->Disconnect(); } GameRules = NULL; avhgameplay = NULL; RETURN_META(MRES_IGNORED); } // Reset player data here.. qboolean ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ]) { // Client's connecting. Freshen up his save data, and mark him as being connected. GET_PLAYER_E(pEntity)->Connect(); RETURN_META_VALUE(MRES_HANDLED,0); } void ClientDisconnect(edict_t *pEntity) { // Client is disconnecting, clear all his saved information. GET_PLAYER_E(pEntity)->Disconnect(1); RETURN_META(MRES_HANDLED); } /** * NS resets pev->fov every single frame, but this is called right before the data is sent to the client. * Reset FOV if we need to. * - * NOTE: This function is not called if no clients have FoV changed */ void UpdateClientData( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ) { GET_PLAYER_E(const_cast(static_cast(ent)))->UpdateFOV(); RETURN_META(MRES_HANDLED); }