amxmodx/modules/ns/CPlayer.h

419 lines
6.4 KiB
C
Raw Normal View History

2014-08-04 14:35:12 +04:00
// 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 is the basic data stored for players */
#ifndef CPLAYER_H
#define CPLAYER_H
#include <string.h>
#include "GameManager.h"
class CPlayer
{
private:
edict_t *m_pEdict;
entvars_t *m_pev;
int m_iIndex;
int m_iIsBot;
int m_iIsConnected;
int m_iOldTeam;
int m_iOldImpulse;
int m_iOldDeadFlag;
int m_iSpeedChange;
REAL m_fMaxSpeed;
int m_iClass;
int m_iHasCustomModel;
int m_iHasCustomSkin;
int m_iHasCustomBody;
char m_szModel[128];
int m_iSkin;
int m_iBody;
int m_iHasFOV;
REAL m_fFOV;
int m_iInitialized;
public:
CPlayer()
{
memset(this,0x0,sizeof(*this));
}
inline void SetEdict(edict_t *Ent)
{
m_pEdict=Ent;
m_pev=&(Ent->v);
m_iIndex=ENTINDEX_NEW(Ent);
};
inline edict_t *GetEdict(void)
{
return m_pEdict;
};
inline entvars_t *GetPev(void)
{
return m_pev;
};
inline int IsBot(void)
{
return m_iIsBot;
};
inline void SetBot(int onoff)
{
m_iIsBot=onoff;
};
inline int IsConnected(void)
{
return m_iIsConnected;
};
inline BOOL HasPrivateData(void)
{
if (m_pEdict && m_pEdict->pvPrivateData != NULL)
{
return TRUE;
}
return FALSE;
};
inline int IsInitialized()
{
return m_iInitialized;
};
inline void Initialize()
{
if (!IsConnected())
{
// This usually means it's a bot...
// So just emulate connections
Connect();
SetBot(1);
}
m_iInitialized=1;
};
inline void PreThink()
{
if (!IsInitialized())
{
Initialize();
}
if (m_iOldTeam != m_pev->team)
{
GameMan.ExecuteClientChangeTeam(index(),m_pev->team,m_iOldTeam);
}
if (m_iOldDeadFlag && m_pev->deadflag == 0)
{
GameMan.ExecuteClientSpawn(index());
}
int tClass = GetClass();
if (tClass != m_iClass)
{
ChangeClass(tClass);
}
m_iOldImpulse=m_pev->impulse;
m_iOldDeadFlag=m_pev->deadflag;
m_iOldTeam=m_pev->team;
};
inline void PreThink_Post()
{
// Trying to incorperate this into PostThink_Post led to really *weird* results (i don't think it was propagated to the client properly).
// Change the users speed here
m_fMaxSpeed=m_pev->maxspeed;
m_pev->maxspeed+=m_iSpeedChange;
};
/**
* This is only hooked if at least 1
* player has custom skins/models/bodies
*/
inline void PostThink_Post()
{
if (m_iHasCustomModel)
{
SET_MODEL(m_pEdict,m_szModel);
}
if (m_iHasCustomSkin)
{
m_pev->skin=m_iSkin;
}
if (m_iHasCustomBody)
{
m_pev->body=m_iBody;
}
};
void ChangeClass(int newclass)
{
GameMan.ExecuteClientChangeClass(index(), newclass, m_iClass);
m_iClass=newclass;
}
void Connect()
{
m_iIsConnected=1;
m_iIsBot=0;
Reset();
}
void Disconnect(int scanhooks=0)
{
// If this client had any hooks upon disconnect
// then rescan the hooks to see if we can stop
// intercepting any of them.
if (scanhooks!=0)
{
if (this->NeedPreThink_Post())
{
GameMan.HookPreThink_Post();
}
if (this->NeedPostThink_Post())
{
GameMan.HookPostThink_Post();
}
if (this->NeedUpdateClientData())
{
GameMan.HookUpdateClientData();
}
}
m_iIsConnected=0;
m_iIsBot=0;
Reset();
}
void FullReset()
{
memset(this,0x0,sizeof(*this));
};
void Reset()
{
m_iHasCustomModel=0;
m_iHasCustomSkin=0;
m_iHasCustomBody=0;
m_iOldTeam=0;
m_iOldDeadFlag=0;
m_iSpeedChange=0;
m_iClass=0;
};
int GetClass()
{
if (m_pev->deadflag)
{
return CLASS_DEAD;
}
if (!m_pev->team)
{
return CLASS_NOTEAM;
}
switch (m_pev->iuser3)
{
case 1:
// Light armor marine..
if (m_pev->iuser4 & MASK_HEAVYARMOR)
{
return CLASS_HEAVY;
}
if (m_pev->iuser4 & MASK_JETPACK)
{
return CLASS_JETPACK;
}
return CLASS_MARINE;
case 2:
return CLASS_COMMANDER;
case 3:
return CLASS_SKULK;
case 4:
return CLASS_GORGE;
case 5:
return CLASS_LERK;
case 6:
return CLASS_FADE;
case 7:
return CLASS_ONOS;
case 8:
return CLASS_GESTATE;
}
return CLASS_UNKNOWN;
};
inline int &index()
{
return m_iIndex;
};
inline int &GetSpeedChange(void)
{
return m_iSpeedChange;
};
inline int GetMaxSpeed(void)
{
return (int)m_fMaxSpeed;
};
inline void SetSpeedChange(cell &SpeedChange)
{
m_iSpeedChange=SpeedChange;
};
inline void SetModel(char *Model)
{
if (strcmp(Model,"")!=0)
{
PRECACHE_MODEL(Model);
strncpy(m_szModel,Model,sizeof(m_szModel)-1);
m_iHasCustomModel=1;
}
else
{
m_iHasCustomModel=0;
}
};
inline void SetSkin(cell &skin)
{
if (skin<0)
{
m_iHasCustomSkin=0;
return;
}
m_iHasCustomSkin=1;
m_iSkin=skin;
};
inline void SetBody(cell &body)
{
if (body<0)
{
m_iHasCustomBody=0;
return;
}
m_iHasCustomBody=1;
m_iBody=body;
};
/**
* Called during pfnUpdateClientData()
* Sets the player's FOV continuously
*/
inline void UpdateFOV(void)
{
if (m_iHasFOV)
{
GetPev()->fov=m_fFOV;
}
};
/**
* Called from the native directly.
* Changes members, and gets the SetFOV
* message id if needed.
*/
inline int SetFOV(REAL &Amount)
{
GameMan.UpdateSetFOV();
if (Amount == 0.0)
{
m_iHasFOV=0;
m_fFOV=0.0;
MESSAGE_BEGIN(MSG_ONE,GameMan.GetSetFOV(),NULL,GetEdict());
WRITE_BYTE(0);
MESSAGE_END();
return 1;
}
if (Amount > 0)
{
m_iHasFOV=1;
m_fFOV=Amount;
MESSAGE_BEGIN(MSG_ONE,GameMan.GetSetFOV(),NULL,GetEdict());
WRITE_BYTE((int)Amount);
MESSAGE_END();
return 1;
}
return 0;
};
/**
* Returns 1 if this entity needs PreThink_Post hooked
* (eg: this entity has custom max speeds)
*/
inline int NeedPreThink_Post(void)
{
return m_iSpeedChange != 0;
};
/**
* Returns 1 if this entity needs PostThink_Post
* eg: This entity has a custom model/skin/body
*/
inline int NeedPostThink_Post(void)
{
return (m_iHasCustomModel != 0 || m_iHasCustomSkin != 0 || m_iHasCustomBody != 0);
};
/**
* Returns 1 if this entity needs UpdateClientData
* eg: This entity has a custom FOV set
*/
inline int NeedUpdateClientData(void)
{
return m_iHasFOV != 0;
};
};
#endif