215 lines
4.8 KiB
C++
215 lines
4.8 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
|
|
//
|
|
|
|
/* Calls going from the engine to the game dll are handled here */
|
|
|
|
#ifndef HAVE_STDINT_H
|
|
#define HAVE_STDINT_H
|
|
#endif
|
|
|
|
#include "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<edict_t *>(static_cast<const edict_t *>(ent)))->UpdateFOV();
|
|
|
|
RETURN_META(MRES_HANDLED);
|
|
|
|
}
|