mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-24 13:55:36 +03:00
Merge of rewritten NS module into trunk
This commit is contained in:
parent
48022d3c5c
commit
c604eefde0
122
dlls/ns/AllocString.h
Normal file
122
dlls/ns/AllocString.h
Normal file
@ -0,0 +1,122 @@
|
||||
/* 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 is a replacement for the engine call of ALLOC_STRING
|
||||
* The main difference is that a string will not be allocated twice
|
||||
* as to try to avoid wasting the HL zone space.
|
||||
*
|
||||
* NOTE: The lookup uses strcmp() in a linked list! It is not fast
|
||||
* Its implementation in the NS module is on rarely used
|
||||
* natives.
|
||||
*/
|
||||
|
||||
#ifndef ALLOCSTRING_H
|
||||
#define ALLOCSTRING_H
|
||||
|
||||
#include "CString.h"
|
||||
#include "sh_list.h"
|
||||
|
||||
class StringManager
|
||||
{
|
||||
private:
|
||||
List<String *> m_StringList;
|
||||
|
||||
public:
|
||||
/**
|
||||
* sh_list.h does not delete objects put into
|
||||
* the list, so I need to delete those and clear()
|
||||
*/
|
||||
inline void Clear(void)
|
||||
{
|
||||
List<String *>::iterator end;
|
||||
List<String *>::iterator iter;
|
||||
|
||||
iter=m_StringList.begin();
|
||||
end=m_StringList.end();
|
||||
|
||||
while (iter!=end)
|
||||
{
|
||||
delete (*iter++);
|
||||
}
|
||||
|
||||
m_StringList.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate the list to see if the string exists
|
||||
* This is slow and not very ideal, however
|
||||
* this is *very* rarely used so it won't matter
|
||||
*/
|
||||
inline int Allocate(const char *str)
|
||||
{
|
||||
List<String *>::iterator end;
|
||||
List<String *>::iterator iter;
|
||||
|
||||
iter=m_StringList.begin();
|
||||
end=m_StringList.end();
|
||||
|
||||
while (iter!=end)
|
||||
{
|
||||
if (strcmp(str,(*iter)->c_str()))
|
||||
{
|
||||
// String is already in the list, do not allocate it again
|
||||
return MAKE_STRING((*iter)->c_str());
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
// Was not found in the linked list, allocate it and add it to the list
|
||||
String *AllocStr = new String;
|
||||
|
||||
AllocStr->assign(str);
|
||||
|
||||
m_StringList.push_back(AllocStr);
|
||||
|
||||
return MAKE_STRING(AllocStr->c_str());
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
extern StringManager AllocStringList;
|
||||
|
||||
/**
|
||||
* Simple wrapper to make conversion easier
|
||||
*/
|
||||
inline int ALLOC_STRING2(const char *InputString)
|
||||
{
|
||||
return AllocStringList.Allocate(InputString);
|
||||
}
|
||||
|
||||
|
||||
#endif // ALLOCSTRING_H
|
@ -1,111 +0,0 @@
|
||||
#include "ns.h"
|
||||
|
||||
void CPlayer::PreThink()
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
// This usually means it's a bot...
|
||||
// So just emulate connections
|
||||
Connect();
|
||||
bot=true;
|
||||
}
|
||||
if (olddeadflag && pev->deadflag == 0 && SpawnForward != -1)
|
||||
MF_ExecuteForward(SpawnForward,index());
|
||||
|
||||
if (oldteam != pev->team && TeamForward != -1)
|
||||
MF_ExecuteForward(TeamForward,index(),pev->team,oldteam);
|
||||
|
||||
int tClass = GetClass();
|
||||
if (tClass != iclass)
|
||||
ChangeClass(tClass);
|
||||
oldimpulse=pev->impulse;
|
||||
olddeadflag = pev->deadflag;
|
||||
oldteam = pev->team;
|
||||
}
|
||||
void CPlayer::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
|
||||
maxspeed=(int)pev->maxspeed;
|
||||
pev->maxspeed+=speedchange;
|
||||
}
|
||||
|
||||
void CPlayer::PostThink_Post()
|
||||
{
|
||||
// Change the player's models...
|
||||
if (custommodel)
|
||||
SET_MODEL(edict,model);
|
||||
if (customskin)
|
||||
pev->skin=skin;
|
||||
if (custombody)
|
||||
pev->body=body;
|
||||
}
|
||||
void CPlayer::ChangeClass(int newclass)
|
||||
{
|
||||
if (ChangeclassForward != -1)
|
||||
MF_ExecuteForward(ChangeclassForward, index(), newclass, iclass, oldimpulse);
|
||||
iclass=newclass;
|
||||
}
|
||||
|
||||
int CPlayer::GetClass()
|
||||
{
|
||||
if (pev->deadflag)
|
||||
return CLASS_DEAD;
|
||||
if (!pev->team)
|
||||
return CLASS_NOTEAM;
|
||||
switch (pev->iuser3)
|
||||
{
|
||||
case 1:
|
||||
// Light armor marine..
|
||||
if (pev->iuser4 & MASK_HEAVYARMOR)
|
||||
return CLASS_HEAVY;
|
||||
if (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;
|
||||
|
||||
}
|
||||
void CPlayer::Connect()
|
||||
{
|
||||
connected=true;
|
||||
bot=false;
|
||||
|
||||
Reset();
|
||||
}
|
||||
void CPlayer::Disconnect()
|
||||
{
|
||||
connected=false;
|
||||
bot=false;
|
||||
Reset();
|
||||
}
|
||||
void CPlayer::Reset()
|
||||
{
|
||||
this->custombody=false;
|
||||
this->custommodel=false;
|
||||
this->customskin=false;
|
||||
this->maxspeed=0;
|
||||
this->speedchange=0;
|
||||
this->model[0]='\0';
|
||||
this->skin=0;
|
||||
this->body=0;
|
||||
this->fov=0.0;
|
||||
this->foved=false;
|
||||
olddeadflag=0;
|
||||
oldteam=0;
|
||||
|
||||
}
|
@ -1,44 +1,438 @@
|
||||
/* 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 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:
|
||||
void PreThink();
|
||||
void PreThink_Post();
|
||||
void PostThink_Post();
|
||||
void Spawn();
|
||||
void ChangeTeam();
|
||||
void ChangeClass(int newclass);
|
||||
void Connect();
|
||||
void Disconnect();
|
||||
void Reset();
|
||||
void Die();
|
||||
int GetClass();
|
||||
bool bot;
|
||||
// Basic engine stuff.
|
||||
edict_t *edict;
|
||||
entvars_t *pev;
|
||||
int oldimpulse; // Store the previous impulse.
|
||||
int olddeadflag;
|
||||
int oldteam;
|
||||
int index() { return ENTINDEX(pev->pContainingEntity); };
|
||||
|
||||
bool connected;
|
||||
REAL fov;
|
||||
bool foved;
|
||||
// Custom model/body/skin
|
||||
bool custommodel;
|
||||
bool customskin;
|
||||
bool custombody;
|
||||
char model[128];
|
||||
int skin;
|
||||
int body;
|
||||
CPlayer()
|
||||
{
|
||||
memset(this,0x0,sizeof(*this));
|
||||
}
|
||||
|
||||
// Speed change
|
||||
int speedchange;
|
||||
int maxspeed;
|
||||
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;
|
||||
};
|
||||
|
||||
int iclass;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
#include "ns.h"
|
||||
|
||||
void CSpawn::clear()
|
||||
{
|
||||
while (spawnpointinfo)
|
||||
{
|
||||
spawnpointInfo* a = spawnpointinfo->next;
|
||||
delete spawnpointinfo;
|
||||
spawnpointinfo = a;
|
||||
}
|
||||
|
||||
}
|
||||
void CSpawn::put(int type, vec3_t location)
|
||||
{
|
||||
spawnpointinfo = new spawnpointInfo(type, location, spawnpointinfo);
|
||||
}
|
||||
float CSpawn::getnum(int type)
|
||||
{
|
||||
float iTemp=0.0;
|
||||
spawnpointInfo *a = spawnpointinfo;
|
||||
while (a)
|
||||
{
|
||||
if (a->type == type)
|
||||
iTemp+=1.0;
|
||||
a = a->next;
|
||||
}
|
||||
return iTemp;
|
||||
}
|
||||
vec3_t CSpawn::getpoint(int type, int num)
|
||||
{
|
||||
int iTemp=0;
|
||||
spawnpointInfo *a = spawnpointinfo;
|
||||
while (a)
|
||||
{
|
||||
if (a->type == type)
|
||||
{
|
||||
iTemp++;
|
||||
if (iTemp == num)
|
||||
{
|
||||
return a->location;
|
||||
}
|
||||
}
|
||||
a=a->next;
|
||||
}
|
||||
return Vector(0.0,0.0,0.0);
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#ifndef CSPAWN_H
|
||||
#define CSPAWN_H
|
||||
class CSpawn
|
||||
{
|
||||
struct spawnpointInfo
|
||||
{
|
||||
int type; // 0 = Ready room, 1 = Marine, 2 = Alien
|
||||
vec3_t location;
|
||||
spawnpointInfo* next;
|
||||
spawnpointInfo(int type, vec3_t location, spawnpointInfo* next): type(type), location(location), next(next) {}
|
||||
} *spawnpointinfo;
|
||||
public:
|
||||
CSpawn() { spawnpointinfo = 0; }
|
||||
~CSpawn() { clear(); }
|
||||
void clear();
|
||||
void put(int type, vec3_t location);
|
||||
float getnum(int type);
|
||||
vec3_t getpoint(int type, int num);
|
||||
};
|
||||
#endif
|
||||
|
428
dlls/ns/CString.h
Normal file
428
dlls/ns/CString.h
Normal file
@ -0,0 +1,428 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_CSTRING_H
|
||||
#define _INCLUDE_CSTRING_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
//by David "BAILOPAN" Anderson
|
||||
class String
|
||||
{
|
||||
public:
|
||||
String()
|
||||
{
|
||||
v = new char[33];
|
||||
v[0]='\0';
|
||||
a_size = 0;
|
||||
//assign("");
|
||||
}
|
||||
|
||||
~String()
|
||||
{
|
||||
delete [] v;
|
||||
}
|
||||
|
||||
String(const char *src)
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
assign(src);
|
||||
}
|
||||
|
||||
const char * _fread(FILE *fp)
|
||||
{
|
||||
Grow(512, false);
|
||||
char *ret = fgets(v, 511, fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String(const String &src)
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
assign(src.c_str());
|
||||
}
|
||||
|
||||
const char *c_str() { return v?v:""; }
|
||||
|
||||
const char *c_str() const { return v?v:""; }
|
||||
|
||||
void append(const char *t)
|
||||
{
|
||||
Grow(size() + strlen(t) + 1);
|
||||
strcat(v, t);
|
||||
}
|
||||
|
||||
void append(const char c)
|
||||
{
|
||||
size_t len = size();
|
||||
Grow(len + 2);
|
||||
v[len] = c;
|
||||
v[len + 1] = '\0';
|
||||
}
|
||||
|
||||
void append(String &d)
|
||||
{
|
||||
append(d.c_str());
|
||||
}
|
||||
|
||||
void assign(const String &src)
|
||||
{
|
||||
assign(src.c_str());
|
||||
}
|
||||
|
||||
void assign(const char *d)
|
||||
{
|
||||
if (!d)
|
||||
{
|
||||
clear();
|
||||
} else {
|
||||
size_t len = strlen(d);
|
||||
Grow(len + 1, false);
|
||||
memcpy(v, d, len);
|
||||
v[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
if (v)
|
||||
v[0] = '\0';
|
||||
}
|
||||
|
||||
int compare (const char *d) const
|
||||
{
|
||||
if (!v)
|
||||
return strcmp("", d);
|
||||
else
|
||||
return strcmp(v, d);
|
||||
}
|
||||
|
||||
//Added this for amxx inclusion
|
||||
bool empty() const
|
||||
{
|
||||
if (!v)
|
||||
return true;
|
||||
|
||||
if (v[0] == '\0')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
if (v)
|
||||
return strlen(v);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int find(const char c, int index = 0)
|
||||
{
|
||||
int len = static_cast<int>(size());
|
||||
if (len < 1)
|
||||
return npos;
|
||||
if (index >= len || index < 0)
|
||||
return npos;
|
||||
int i = 0;
|
||||
for (i=index; i<len; i++)
|
||||
{
|
||||
if (v[i] == c)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
bool is_space(int c)
|
||||
{
|
||||
if (c == '\f' || c == '\n' ||
|
||||
c == '\t' || c == '\r' ||
|
||||
c == '\v' || c == ' ')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void reparse_newlines()
|
||||
{
|
||||
size_t len = size();
|
||||
int offs = 0;
|
||||
char c;
|
||||
if (!len)
|
||||
return;
|
||||
for (size_t i=0; i<len; i++)
|
||||
{
|
||||
c = v[i];
|
||||
if (c == '^' && (i != len-1))
|
||||
{
|
||||
c = v[++i];
|
||||
if (c == 'n')
|
||||
c = '\n';
|
||||
else if (c == 't')
|
||||
c = '\t';
|
||||
offs++;
|
||||
}
|
||||
v[i-offs] = c;
|
||||
}
|
||||
v[len-offs] = '\0';
|
||||
}
|
||||
|
||||
void trim()
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
|
||||
unsigned int i = 0;
|
||||
unsigned int j = 0;
|
||||
size_t len = strlen(v);
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
if (is_space(v[i]))
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char c0 = v[0];
|
||||
|
||||
if (is_space(c0))
|
||||
{
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
|
||||
{
|
||||
erase(0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len = strlen(v);
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_space(v[len-1]))
|
||||
{
|
||||
for (i=len-1; i>=0; i--)
|
||||
{
|
||||
if (!is_space(v[i])
|
||||
|| (is_space(v[i]) && i==0))
|
||||
{
|
||||
erase(i+1, j);
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
if (is_space(v[0]))
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void erase(unsigned int start, int num = npos)
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
unsigned int i = 0;
|
||||
size_t len = size();
|
||||
//check for bounds
|
||||
if (num == npos || start+num > len-start)
|
||||
num = len - start;
|
||||
//do the erasing
|
||||
bool copyflag = false;
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (i>=start && i<start+num)
|
||||
{
|
||||
if (i+num < len)
|
||||
{
|
||||
v[i] = v[i+num];
|
||||
} else {
|
||||
v[i] = 0;
|
||||
}
|
||||
copyflag = true;
|
||||
} else if (copyflag) {
|
||||
if (i+num < len)
|
||||
{
|
||||
v[i] = v[i+num];
|
||||
} else {
|
||||
v[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
len -= num;
|
||||
v[len] = 0;
|
||||
}
|
||||
|
||||
String substr(unsigned int index, int num = npos)
|
||||
{
|
||||
if (!v)
|
||||
{
|
||||
String b("");
|
||||
return b;
|
||||
}
|
||||
|
||||
String ns;
|
||||
|
||||
size_t len = size();
|
||||
|
||||
if (index >= len || !v)
|
||||
return ns;
|
||||
|
||||
if (num == npos)
|
||||
{
|
||||
num = len - index;
|
||||
} else if (index+num >= len) {
|
||||
num = len - index;
|
||||
}
|
||||
|
||||
unsigned int i = 0;
|
||||
unsigned int nslen = num + 2;
|
||||
|
||||
ns.Grow(nslen);
|
||||
|
||||
for (i=index; i<index+num; i++)
|
||||
ns.append(v[i]);
|
||||
|
||||
return ns;
|
||||
}
|
||||
|
||||
void ToLower(void)
|
||||
{
|
||||
if (v==NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char *iter=v+a_size;
|
||||
|
||||
while (iter--!=v)
|
||||
{
|
||||
*iter=tolower(*iter);
|
||||
}
|
||||
};
|
||||
void toLower()
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
unsigned int i = 0;
|
||||
size_t len = strlen(v);
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (v[i] >= 65 && v[i] <= 90)
|
||||
v[i] &= ~(1<<5);
|
||||
}
|
||||
}
|
||||
|
||||
String & operator = (const String &src)
|
||||
{
|
||||
assign(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & operator = (const char *src)
|
||||
{
|
||||
assign(src);
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
char operator [] (unsigned int index)
|
||||
{
|
||||
if (index > size() || !v)
|
||||
{
|
||||
return -1;
|
||||
} else {
|
||||
return v[index];
|
||||
}
|
||||
}
|
||||
|
||||
int at(int a)
|
||||
{
|
||||
if (a < 0 || a >= (int)size() || !v)
|
||||
return -1;
|
||||
|
||||
return v[a];
|
||||
}
|
||||
|
||||
bool at(int at, char c)
|
||||
{
|
||||
if (at < 0 || at >= (int)size() || !v)
|
||||
return false;
|
||||
|
||||
v[at] = c;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void Grow(unsigned int d, bool copy=true)
|
||||
{
|
||||
if (d <= a_size)
|
||||
return;
|
||||
char *n = new char[d + 1];
|
||||
if (copy && v)
|
||||
strcpy(n, v);
|
||||
if (v)
|
||||
delete [] v;
|
||||
else
|
||||
strcpy(n, "");
|
||||
v = n;
|
||||
a_size = d + 1;
|
||||
}
|
||||
|
||||
char *v;
|
||||
unsigned int a_size;
|
||||
public:
|
||||
static const int npos = -1;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_CSTRING_H
|
491
dlls/ns/CVector.h
Normal file
491
dlls/ns/CVector.h
Normal file
@ -0,0 +1,491 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __CVECTOR_H__
|
||||
#define __CVECTOR_H__
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// Vector
|
||||
template <class T> class CVector
|
||||
{
|
||||
bool Grow()
|
||||
{
|
||||
// automatic grow
|
||||
size_t newSize = m_Size * 2;
|
||||
if (newSize == 0)
|
||||
newSize = 8; // a good init value
|
||||
T *newData = new T[newSize];
|
||||
if (!newData)
|
||||
return false;
|
||||
if (m_Data)
|
||||
{
|
||||
for (size_t i=0; i<m_CurrentUsedSize; i++)
|
||||
newData[i] = m_Data[i];
|
||||
delete [] m_Data;
|
||||
}
|
||||
m_Data = newData;
|
||||
m_Size = newSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrowIfNeeded()
|
||||
{
|
||||
if (m_CurrentUsedSize >= m_Size)
|
||||
return Grow();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChangeSize(size_t size)
|
||||
{
|
||||
// change size
|
||||
if (size == m_Size)
|
||||
return true;
|
||||
|
||||
if (!size)
|
||||
{
|
||||
if (m_Data)
|
||||
{
|
||||
delete [] m_Data;
|
||||
m_Data = NULL;
|
||||
m_Size = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
T *newData = new T[size];
|
||||
if (!newData)
|
||||
return false;
|
||||
if (m_Data)
|
||||
{
|
||||
size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size;
|
||||
for (size_t i=0; i<end; i++)
|
||||
newData[i] = m_Data[i];
|
||||
delete [] m_Data;
|
||||
}
|
||||
m_Data = newData;
|
||||
m_Size = size;
|
||||
if (m_CurrentUsedSize > m_Size)
|
||||
m_CurrentUsedSize = m_Size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeMemIfPossible()
|
||||
{
|
||||
if (!m_Data)
|
||||
return;
|
||||
|
||||
if (!m_CurrentUsedSize)
|
||||
{
|
||||
ChangeSize(0);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t newSize = m_Size;
|
||||
while (m_CurrentUsedSize <= newSize / 2)
|
||||
newSize /= 2;
|
||||
|
||||
if (newSize != m_Size)
|
||||
ChangeSize(newSize);
|
||||
}
|
||||
protected:
|
||||
T *m_Data;
|
||||
size_t m_Size;
|
||||
size_t m_CurrentUsedSize;
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
protected:
|
||||
T *m_Ptr;
|
||||
public:
|
||||
// constructors / destructors
|
||||
iterator()
|
||||
{
|
||||
m_Ptr = NULL;
|
||||
}
|
||||
|
||||
iterator(T * ptr)
|
||||
{
|
||||
m_Ptr = ptr;
|
||||
}
|
||||
|
||||
// member functions
|
||||
T * base()
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
const T * base() const
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
// operators
|
||||
T & operator*()
|
||||
{
|
||||
return *m_Ptr;
|
||||
}
|
||||
|
||||
T * operator->()
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
iterator & operator++() // preincrement
|
||||
{
|
||||
++m_Ptr;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator++(int) // postincrement
|
||||
{
|
||||
iterator tmp = *this;
|
||||
++m_Ptr;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
iterator & operator--() // predecrement
|
||||
{
|
||||
--m_Ptr;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator--(int) // postdecrememnt
|
||||
{
|
||||
iterator tmp = *this;
|
||||
--m_Ptr;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(T * right) const
|
||||
{
|
||||
return (m_Ptr == right);
|
||||
}
|
||||
|
||||
bool operator==(const iterator & right) const
|
||||
{
|
||||
return (m_Ptr == right.m_Ptr);
|
||||
}
|
||||
|
||||
bool operator!=(T * right) const
|
||||
{
|
||||
return (m_Ptr != right);
|
||||
}
|
||||
|
||||
bool operator!=(const iterator & right) const
|
||||
{
|
||||
return (m_Ptr != right.m_Ptr);
|
||||
}
|
||||
|
||||
iterator & operator+=(size_t offset)
|
||||
{
|
||||
m_Ptr += offset;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator & operator-=(size_t offset)
|
||||
{
|
||||
m_Ptr -= offset;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator+(size_t offset) const
|
||||
{
|
||||
iterator tmp(*this);
|
||||
tmp.m_Ptr += offset;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
iterator operator-(size_t offset) const
|
||||
{
|
||||
iterator tmp(*this);
|
||||
tmp.m_Ptr -= offset;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T & operator[](size_t offset)
|
||||
{
|
||||
return (*(*this + offset));
|
||||
}
|
||||
|
||||
const T & operator[](size_t offset) const
|
||||
{
|
||||
return (*(*this + offset));
|
||||
}
|
||||
|
||||
bool operator<(const iterator & right) const
|
||||
{
|
||||
return m_Ptr < right.m_Ptr;
|
||||
}
|
||||
|
||||
bool operator>(const iterator & right) const
|
||||
{
|
||||
return m_Ptr > right.m_Ptr;
|
||||
}
|
||||
|
||||
bool operator<=(const iterator & right) const
|
||||
{
|
||||
return m_Ptr <= right.m_Ptr;
|
||||
}
|
||||
|
||||
bool operator>=(const iterator & right) const
|
||||
{
|
||||
return m_Ptr >= right.m_Ptr;
|
||||
}
|
||||
|
||||
size_t operator-(const iterator & right) const
|
||||
{
|
||||
return m_Ptr - right.m_Ptr;
|
||||
}
|
||||
};
|
||||
|
||||
// constructors / destructors
|
||||
CVector<T>()
|
||||
{
|
||||
m_Size = 0;
|
||||
m_CurrentUsedSize = 0;
|
||||
m_Data = NULL;
|
||||
}
|
||||
|
||||
CVector<T>(const CVector<T> & other)
|
||||
{
|
||||
// copy data
|
||||
m_Data = new T [other.m_CurrentUsedSize];
|
||||
m_Size = other.m_CurrentUsedSize;
|
||||
m_CurrentUsedSize = other.m_CurrentUsedSize;
|
||||
for (size_t i=0; i<other.m_CurrentUsedSize; i++)
|
||||
m_Data[i] = other.m_Data[i];
|
||||
}
|
||||
|
||||
~CVector<T>()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// interface
|
||||
size_t size() const
|
||||
{
|
||||
return m_CurrentUsedSize;
|
||||
}
|
||||
|
||||
size_t capacity() const
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
iterator begin() const
|
||||
{
|
||||
return iterator(m_Data);
|
||||
}
|
||||
|
||||
iterator end() const
|
||||
{
|
||||
return iterator(m_Data + m_CurrentUsedSize);
|
||||
}
|
||||
|
||||
iterator iterAt(size_t pos)
|
||||
{
|
||||
if (pos > m_CurrentUsedSize)
|
||||
assert(0);
|
||||
return iterator(m_Data + pos);
|
||||
}
|
||||
|
||||
bool reserve(size_t newSize)
|
||||
{
|
||||
if (newSize > m_Size)
|
||||
return ChangeSize(newSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool push_back(const T & elem)
|
||||
{
|
||||
++m_CurrentUsedSize;
|
||||
if (!GrowIfNeeded())
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data[m_CurrentUsedSize - 1] = elem;
|
||||
return true;
|
||||
}
|
||||
|
||||
void pop_back()
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
if (m_CurrentUsedSize < 0)
|
||||
m_CurrentUsedSize = 0;
|
||||
|
||||
FreeMemIfPossible();
|
||||
}
|
||||
|
||||
bool resize(size_t newSize)
|
||||
{
|
||||
if (!ChangeSize(newSize))
|
||||
return false;
|
||||
m_CurrentUsedSize = newSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return (m_CurrentUsedSize == 0);
|
||||
}
|
||||
|
||||
T & at(size_t pos)
|
||||
{
|
||||
if (pos > m_CurrentUsedSize)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[pos];
|
||||
}
|
||||
|
||||
const T & at(size_t pos) const
|
||||
{
|
||||
if (pos > m_CurrentUsedSize)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[pos];
|
||||
}
|
||||
|
||||
T & operator[](size_t pos)
|
||||
{
|
||||
return at(pos);
|
||||
}
|
||||
|
||||
const T & operator[](size_t pos) const
|
||||
{
|
||||
return at(pos);
|
||||
}
|
||||
|
||||
T & front()
|
||||
{
|
||||
if (m_CurrentUsedSize < 1)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[0];
|
||||
}
|
||||
|
||||
const T & front() const
|
||||
{
|
||||
if (m_CurrentUsedSize < 1)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[0];
|
||||
}
|
||||
|
||||
T & back()
|
||||
{
|
||||
if (m_CurrentUsedSize < 1)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[m_CurrentUsedSize - 1];
|
||||
}
|
||||
|
||||
const T & back() const
|
||||
{
|
||||
if (m_CurrentUsedSize < 1)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[m_CurrentUsedSize - 1];
|
||||
}
|
||||
|
||||
iterator insert(iterator where, const T & value)
|
||||
{
|
||||
// validate iter
|
||||
if (where < m_Data || where > (m_Data + m_CurrentUsedSize))
|
||||
return iterator(0);
|
||||
|
||||
size_t ofs = where - begin();
|
||||
|
||||
++m_CurrentUsedSize;
|
||||
if (!GrowIfNeeded())
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
where = begin() + ofs;
|
||||
|
||||
// Move subsequent entries
|
||||
for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr)
|
||||
*(ptr + 1) = *ptr;
|
||||
|
||||
*where.base() = value;
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
iterator erase(iterator where)
|
||||
{
|
||||
// validate iter
|
||||
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
||||
return iterator(0);
|
||||
|
||||
size_t ofs = where - begin();
|
||||
|
||||
if (m_CurrentUsedSize > 1)
|
||||
{
|
||||
// move
|
||||
T *theend = m_Data + m_CurrentUsedSize;
|
||||
for (T *ptr = where.base() + 1; ptr < theend; ++ptr)
|
||||
*(ptr - 1) = *ptr;
|
||||
}
|
||||
|
||||
--m_CurrentUsedSize;
|
||||
|
||||
FreeMemIfPossible();
|
||||
|
||||
return begin() + ofs;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_Size = 0;
|
||||
m_CurrentUsedSize = 0;
|
||||
if (m_Data)
|
||||
{
|
||||
delete [] m_Data;
|
||||
m_Data = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __CVECTOR_H__
|
||||
|
120
dlls/ns/GameManager.cpp
Normal file
120
dlls/ns/GameManager.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/* 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 holds the functions which determine which hooks I need forwareded */
|
||||
|
||||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "ns.h"
|
||||
|
||||
#include "utilfunctions.h"
|
||||
|
||||
#include "GameManager.h"
|
||||
#include "CPlayer.h"
|
||||
|
||||
void GameManager::HookPreThink(void)
|
||||
{
|
||||
// Only need to hook prethink if at least 1 plugins has any of these forwards:
|
||||
// client_spawn, client_changeteam, client_changeclass
|
||||
|
||||
if (UTIL_CheckForPublic("client_spawn") ||
|
||||
UTIL_CheckForPublic("client_changeteam") ||
|
||||
UTIL_CheckForPublic("client_changeclass"))
|
||||
{
|
||||
g_pFunctionTable->pfnPlayerPreThink=PlayerPreThink;
|
||||
return;
|
||||
}
|
||||
|
||||
g_pFunctionTable->pfnPlayerPreThink=NULL;
|
||||
};
|
||||
|
||||
void GameManager::HookPostThink_Post(void)
|
||||
{
|
||||
int i=0;
|
||||
while (i++<gpGlobals->maxClients)
|
||||
{
|
||||
if (GET_PLAYER_I(i)->NeedPostThink_Post())
|
||||
{
|
||||
g_pFunctionTable_Post->pfnPlayerPostThink=PlayerPostThink_Post;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_pFunctionTable_Post->pfnPlayerPostThink=NULL;
|
||||
};
|
||||
void GameManager::HookPreThink_Post(void)
|
||||
{
|
||||
int i=1;
|
||||
while (i<gpGlobals->maxClients)
|
||||
{
|
||||
if (GET_PLAYER_I(i++)->NeedPreThink_Post())
|
||||
{
|
||||
g_pFunctionTable_Post->pfnPlayerPreThink=PlayerPreThink_Post;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_pFunctionTable_Post->pfnPlayerPreThink=NULL;
|
||||
};
|
||||
void GameManager::HookUpdateClientData(void)
|
||||
{
|
||||
int i=1;
|
||||
while (i<gpGlobals->maxClients)
|
||||
{
|
||||
if (GET_PLAYER_I(i++)->NeedUpdateClientData())
|
||||
{
|
||||
g_pFunctionTable->pfnUpdateClientData=UpdateClientData;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_pFunctionTable->pfnUpdateClientData=NULL;
|
||||
};
|
||||
void GameManager::HookLogs()
|
||||
{
|
||||
// These forwards only are needed in classic NS
|
||||
if (!IsCombat() && UTIL_CheckForPublic("client_built"))
|
||||
{
|
||||
// Only hook if this public exists (wasteful otherwise)
|
||||
m_BuiltForward = MF_RegisterForward("client_built", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
g_pengfuncsTable_Post->pfnAlertMessage=AlertMessage_Post;
|
||||
g_pengfuncsTable_Post->pfnCreateNamedEntity=CreateNamedEntity_Post;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no need for these hooks in co
|
||||
g_pengfuncsTable_Post->pfnAlertMessage=NULL;
|
||||
g_pengfuncsTable_Post->pfnCreateNamedEntity=NULL;
|
||||
}
|
||||
|
||||
};
|
318
dlls/ns/GameManager.h
Normal file
318
dlls/ns/GameManager.h
Normal file
@ -0,0 +1,318 @@
|
||||
/* 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
|
164
dlls/ns/Hash.h
Normal file
164
dlls/ns/Hash.h
Normal file
@ -0,0 +1,164 @@
|
||||
#ifndef _HASH_H_
|
||||
#define _HASH_H_
|
||||
|
||||
#include "CVector.h"
|
||||
|
||||
|
||||
// Just a very simple hash map, no iteration or anything of the like (not needed)
|
||||
|
||||
|
||||
inline int HashFunction(const String& name)
|
||||
{
|
||||
static const int kHashNumTable[128] =
|
||||
{
|
||||
0x1148FC3E, 0x0577C975, 0x3BED3AED, 0x62FBBD5F, 0x07DE2DA0, 0x6555C5E5, 0x24DB841A, 0x2AF3F568,
|
||||
0x01EA1B65, 0x46F7D976, 0x18172B99, 0x394B2A58, 0x1ED39AA8, 0x1214E706, 0x5DD47295, 0x53574932,
|
||||
0x2CE25D5C, 0x7A2E5BB4, 0x0F2F0153, 0x33888669, 0x729AC55F, 0x2A7BCA9E, 0x36C60816, 0x40F9A7E3,
|
||||
0x2A37DF30, 0x3D81BB17, 0x6450B311, 0x75FA2DC9, 0x2A2678A5, 0x4C5E3675, 0x743F4486, 0x3B6F74E3,
|
||||
0x51D5FFEA, 0x302C7F74, 0x1E6B3243, 0x59B42D8A, 0x15824559, 0x4346B65D, 0x04A822F2, 0x176C60BF,
|
||||
0x0A3E8FD3, 0x1CBF4E8B, 0x50B78B17, 0x29122A7B, 0x2ED43591, 0x2E8BFDAC, 0x7C6973AE, 0x5BB692EE,
|
||||
0x28BA5960, 0x0B987501, 0x0F3F1957, 0x1B551EBF, 0x36143F9F, 0x4605216D, 0x5C4EC6A2, 0x604C1ECF,
|
||||
0x0386DC84, 0x409F79B4, 0x56464C99, 0x2DAD5529, 0x0CFDB029, 0x4A85911F, 0x691CCA0D, 0x5ED3B013,
|
||||
0x7AB21093, 0x0787FC50, 0x3887DD9D, 0x103455ED, 0x4ACEB2AD, 0x3D30008F, 0x27A0B6AC, 0x550D4280,
|
||||
0x59EF4F1B, 0x785841C3, 0x7E1F6CFC, 0x08C384AC, 0x26E43F70, 0x7A88E0AA, 0x647A179A, 0x4F9E98D0,
|
||||
0x062155AB, 0x73B930F1, 0x6AF3B790, 0x3C35954B, 0x39BE525E, 0x47427E32, 0x1C81B41A, 0x3D452EE2,
|
||||
0x07E1F7E6, 0x72C800B3, 0x6AF2840C, 0x14DFA80F, 0x3D4D91D3, 0x540F4E19, 0x73B35822, 0x37FFA266,
|
||||
0x5B974A69, 0x2C3B35BF, 0x4833F853, 0x2665FD16, 0x696B364F, 0x6FD4AEFF, 0x7B733F96, 0x435A856A,
|
||||
0x682CF0C3, 0x7992AC92, 0x4C1E0A16, 0x0F113033, 0x741B8D3C, 0x309821B1, 0x5EAFC903, 0x7A3CE2E8,
|
||||
0x245152A2, 0x49A38093, 0x36727833, 0x5E0FA501, 0x10E5FEC6, 0x52F42C4D, 0x1B54D3E3, 0x18C7F6AC,
|
||||
0x45BC2D01, 0x064757EF, 0x2DA79EBC, 0x0309BED4, 0x5A56A608, 0x215AF6DE, 0x3B09613A, 0x35EDF071
|
||||
};
|
||||
size_t size = name.size();
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hasha = kHashNumTable[(*(name.c_str() + (size - 1))) & 0x7F];
|
||||
int hashb = kHashNumTable[size % 128];
|
||||
|
||||
|
||||
unsigned char c = 0;
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
c = (*(name.c_str() + (size - 1))) & 0x7F;
|
||||
|
||||
hasha = (hasha + hashb) ^ kHashNumTable[c];
|
||||
hashb = hasha + hashb + c + (hasha << 8) + (hashb & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
return hasha;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param K Key type.
|
||||
* @param D Data type.
|
||||
* @param F Hash function.
|
||||
* @param B Bucket count.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
template <typename K = String, typename D = String, int (*F)(const K&) = HashFunction, int B = 1024>
|
||||
class Hash
|
||||
{
|
||||
protected:
|
||||
CVector<int> m_HashBuckets[B];
|
||||
CVector<K> m_KeyBuckets[B];
|
||||
CVector<D> m_DataBuckets[B];
|
||||
|
||||
inline int GetBucket(int hash)
|
||||
{
|
||||
return (*reinterpret_cast<unsigned int*>(&hash)) % B;
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// prints bucket distribution
|
||||
inline void printbuckets() const
|
||||
{
|
||||
for (int i = 0; i < B; i++)
|
||||
{
|
||||
if (i % 32 == 0 && i != 0)
|
||||
{
|
||||
printf("\n");
|
||||
}
|
||||
printf("%d ", m_HashBuckets[i].size());
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
inline void insert(const K& key, const D& value)
|
||||
{
|
||||
D* ptr;
|
||||
if ((ptr = this->find(key)) != NULL)
|
||||
{
|
||||
*ptr = value;
|
||||
return;
|
||||
}
|
||||
|
||||
int hash = F(key);
|
||||
|
||||
int bucketnum = GetBucket(hash);
|
||||
|
||||
m_HashBuckets[bucketnum].push_back(hash);
|
||||
m_KeyBuckets[bucketnum].push_back(key);
|
||||
m_DataBuckets[bucketnum].push_back(value);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
inline D& lookup_or_add(const K& key)
|
||||
{
|
||||
D* ptr;
|
||||
if ((ptr = this->find(key)) != NULL)
|
||||
{
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
int hash = F(key);
|
||||
|
||||
int bucketnum = GetBucket(hash);
|
||||
|
||||
m_HashBuckets[bucketnum].push_back(hash);
|
||||
m_KeyBuckets[bucketnum].push_back(key);
|
||||
m_DataBuckets[bucketnum].push_back(D());
|
||||
|
||||
return m_DataBuckets[bucketnum].at(m_DataBuckets[bucketnum].size() - 1);
|
||||
|
||||
}
|
||||
inline bool exists(const K& key)
|
||||
{
|
||||
return this->find(key) != NULL;
|
||||
}
|
||||
inline D* find(const K& key)
|
||||
{
|
||||
int hash = F(key);
|
||||
|
||||
int bucketnum = GetBucket(hash);
|
||||
|
||||
// TODO: Possibly make this binary search?
|
||||
// insertion would be annoying, don't think it is worth it
|
||||
CVector<int>* hashbucket = &m_HashBuckets[bucketnum];
|
||||
CVector<K>* keybucket = &m_KeyBuckets[bucketnum];
|
||||
|
||||
size_t bucketsize = hashbucket->size();
|
||||
|
||||
for (size_t i = 0; i < bucketsize; i++)
|
||||
{
|
||||
if (hashbucket->at(i) == hash)
|
||||
{
|
||||
if (key.compare(keybucket->at(i).c_str()) == 0)
|
||||
{
|
||||
return &(m_DataBuckets[bucketnum].at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
121
dlls/ns/LocationManager.h
Normal file
121
dlls/ns/LocationManager.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef LOCATIONMANAGER_H
|
||||
#define LOCATIONMANAGER_H
|
||||
|
||||
#include "CVector.h"
|
||||
#include "GameManager.h"
|
||||
#include "TitleManager.h"
|
||||
|
||||
|
||||
typedef struct location_data_s
|
||||
{
|
||||
char name[128];
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
|
||||
const char *titlelookup;
|
||||
} location_data_t;
|
||||
|
||||
|
||||
class LocationManager
|
||||
{
|
||||
private:
|
||||
CVector<location_data_t> m_LocationList;
|
||||
|
||||
public:
|
||||
LocationManager()
|
||||
{
|
||||
Clear();
|
||||
};
|
||||
|
||||
inline void Clear(void)
|
||||
{
|
||||
m_LocationList.clear();
|
||||
m_LocationList.reserve(32);
|
||||
};
|
||||
|
||||
inline void Add(const char *Name, edict_t *Entity)
|
||||
{
|
||||
location_data_t Temp;
|
||||
|
||||
Temp.mins=Entity->v.mins;
|
||||
Temp.maxs=Entity->v.maxs;
|
||||
|
||||
strncpy(Temp.name,Name,sizeof(Temp.name)-1);
|
||||
|
||||
String NameString(Name);
|
||||
|
||||
NameString.toLower();
|
||||
|
||||
Temp.titlelookup=TitleMan.Lookup(NameString);
|
||||
|
||||
m_LocationList.push_back(Temp);
|
||||
};
|
||||
inline const char *Lookup(vec3_t origin, cell titlelookup)
|
||||
{
|
||||
unsigned int i=0;
|
||||
location_data_t Temp;
|
||||
while (i<m_LocationList.size())
|
||||
{
|
||||
Temp=m_LocationList[i++];
|
||||
|
||||
if (origin.x <= Temp.maxs.x &&
|
||||
origin.y <= Temp.maxs.y &&
|
||||
origin.x >= Temp.mins.x &&
|
||||
origin.y >= Temp.mins.y)
|
||||
{
|
||||
if (titlelookup==0)
|
||||
{
|
||||
return &(m_LocationList[i-1].name[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_LocationList[i-1].titlelookup!=NULL)
|
||||
{
|
||||
return m_LocationList[i-1].titlelookup;
|
||||
}
|
||||
|
||||
return &(m_LocationList[i-1].name[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
extern LocationManager LocationMan;
|
||||
|
||||
#endif // LOCATIONMANAGER_H
|
@ -1,40 +1,60 @@
|
||||
#(C)2004-2005 AMX Mod X Development Team
|
||||
# Makefile written by David "BAILOPAN" Anderson
|
||||
|
||||
HLSDK = ../../../hlsdk
|
||||
MM_ROOT = ../../metamod/metamod
|
||||
HLSDK = ../../../../hlsdk
|
||||
MM_ROOT = ../../../metamod/metamod
|
||||
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
|
||||
OPT_FLAGS = -O3 -funroll-loops -s -pipe -fomit-frame-pointer -fno-strict-aliasing
|
||||
|
||||
CRAZY_OPT_FLAGS = -DCRAZY_OPTS -O3 -funroll-loops -ffast-math -s -pipe -fomit-frame-pointer -fno-strict-aliasing -DNDEBUG -fmerge-all-constants -fmodulo-sched -fgcse-sm -fgcse-las -fgcse-after-reload -floop-optimize2 -funsafe-loop-optimizations -ftree-loop-linear -ftree-loop-im -ftree-loop-ivcanon -fivopts -ftree-vectorize -fvariable-expansion-in-unroller -funsafe-math-optimizations -ffinite-math-only -fpeel-loops -funswitch-loops -fvisibility=hidden -fvisibility-inlines-hidden -fPIC -Wall -Wno-unknown-pragmas -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H -static-libgcc -fno-rtti -Wpointer-arith -Wcast-qual -Wcast-align -Wconversion -Wsign-compare -Wmissing-noreturn -Winline -Wlong-long -Wunsafe-loop-optimizations -Wctor-dtor-privacy -Wno-non-virtual-dtor -Wreorder -Woverloaded-virtual -Wsign-promo -Wsynth -shared
|
||||
|
||||
CRAZY_LINK_FLAGS =
|
||||
#-fwhole-program
|
||||
#-fwhole-program -combine
|
||||
|
||||
SANE_OPT_FLAGS = -O3 -funroll-loops -s -pipe -fomit-frame-pointer -fno-strict-aliasing -DNDEBUG
|
||||
|
||||
OPT_FLAGS =
|
||||
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = gcc-4.1
|
||||
NAME = ns
|
||||
|
||||
BIN_SUFFIX = amxx_i386.so
|
||||
|
||||
OBJECTS = sdk/amxxmodule.cpp CPlayer.cpp CSpawn.cpp NMisc.cpp NPData.cpp hookedfunctions.cpp
|
||||
OBJECTS = sdk/amxxmodule.cpp dllapi.cpp utils.cpp amxxapi.cpp engineapi.cpp \
|
||||
TitleManager.cpp ParticleManager.cpp MessageHandler.cpp GameManager.cpp \
|
||||
natives/general.cpp natives/player.cpp natives/player_memory.cpp \
|
||||
natives/structure.cpp natives/weapons.cpp natives/particles.cpp \
|
||||
natives/memberfuncs.cpp
|
||||
|
||||
LINK =
|
||||
|
||||
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
|
||||
-I$(MM_ROOT) -I$(HLSDK)/common -I$(HLSDK)/pm_shared -Isdk
|
||||
-I$(MM_ROOT) -I$(HLSDK)/common -I$(HLSDK)/pm_shared
|
||||
|
||||
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
|
||||
|
||||
ifeq "$(GCC_VERSION)" "4"
|
||||
OPT_FLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
|
||||
endif
|
||||
|
||||
ifeq "$(DEBUG)" "true"
|
||||
BIN_DIR = Debug
|
||||
CFLAGS = $(DEBUG_FLAGS)
|
||||
else
|
||||
ifeq "$(CRAZY)" "true"
|
||||
BIN_DIR = Optimized
|
||||
OPT_FLAGS = $(CRAZY_OPT_FLAGS)
|
||||
LINK = $(CRAZY_LINK_FLAGS)
|
||||
else
|
||||
BIN_DIR = Release
|
||||
OPT_FLAGS = $(SANE_OPT_FLAGS)
|
||||
endif
|
||||
ifeq "$(GCC_VERSION)" "4"
|
||||
OPT_FLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
|
||||
endif
|
||||
CFLAGS = $(OPT_FLAGS)
|
||||
endif
|
||||
|
||||
CFLAGS += -DNDEBUG -fPIC -Wall -Wno-non-virtual-dtor -Werror -fno-exceptions -DHAVE_STDINT_H -static-libgcc -fno-rtti
|
||||
CFLAGS += -fPIC -Wall -Wno-non-virtual-dtor -Werror -fno-exceptions -DHAVE_STDINT_H -static-libgcc -fno-rtti
|
||||
|
||||
BINARY = $(NAME)_$(BIN_SUFFIX)
|
||||
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
|
||||
@ -48,6 +68,7 @@ $(BIN_DIR)/%.o: %.cpp
|
||||
all:
|
||||
mkdir -p $(BIN_DIR)
|
||||
mkdir -p $(BIN_DIR)/sdk
|
||||
mkdir -p $(BIN_DIR)/natives
|
||||
$(MAKE) ns
|
||||
|
||||
ns: $(OBJ_LINUX)
|
||||
@ -58,11 +79,20 @@ debug:
|
||||
|
||||
default: all
|
||||
|
||||
clean:
|
||||
rm -rf Release/sdk/*.o
|
||||
rm -rf Release/*.o
|
||||
rm -rf Release/$(NAME)_$(BIN_SUFFIX)
|
||||
rm -rf Debug/sdk/*.o
|
||||
rm -rf Debug/*.o
|
||||
rm -rf Debug/$(NAME)_$(BIN_SUFFIX)
|
||||
crazy:
|
||||
$(MAKE) all CRAZY=true
|
||||
|
||||
clean:
|
||||
rm -rf Release/*.o
|
||||
rm -rf Release/sdk/*.o
|
||||
rm -rf Release/natives/*.o
|
||||
rm -rf Release/$(NAME)_$(BIN_SUFFIX)
|
||||
rm -rf Debug/*.o
|
||||
rm -rf Debug/sdk/*.o
|
||||
rm -rf Debug/natives/*.o
|
||||
rm -rf Debug/$(NAME)_$(BIN_SUFFIX)
|
||||
rm -rf Optimized/*.o
|
||||
rm -rf Optimized/sdk/*.o
|
||||
rm -rf Optimized/natives/*.o
|
||||
rm -rf Optimized/$(NAME)_$(BIN_SUFFIX)
|
||||
|
||||
|
204
dlls/ns/MessageHandler.cpp
Normal file
204
dlls/ns/MessageHandler.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
/* 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 contains the initialization routine and message hooks
|
||||
* for the message handler. Note that all of the message hooks
|
||||
* except for MessageBegin_Post are NOT hooked unless the gameDLL
|
||||
* is sending a message we care about.
|
||||
*/
|
||||
|
||||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "ns.h"
|
||||
#include "utilfunctions.h"
|
||||
|
||||
#include "GameManager.h"
|
||||
#include "MessageHandler.h"
|
||||
|
||||
MessageHandler *MessageLists[256];
|
||||
|
||||
MessageHandler *HookedMessage;
|
||||
|
||||
bool MessageHandler_Initialized=false;
|
||||
|
||||
// This is called through ServerActivate_Post
|
||||
void Initialize_MessageHandler(void)
|
||||
{
|
||||
if (MessageHandler_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MessageHandler_Initialized=true;
|
||||
|
||||
int i=0;
|
||||
|
||||
while (i<255)
|
||||
{
|
||||
MessageLists[i++]=NULL;
|
||||
};
|
||||
|
||||
// Hook our messages
|
||||
int index;
|
||||
|
||||
index=GET_USER_MSG_ID(&Plugin_info,"Countdown",NULL);
|
||||
|
||||
if (index)
|
||||
{
|
||||
MessageLists[index]=new MessageCountDown;
|
||||
}
|
||||
|
||||
index=GET_USER_MSG_ID(&Plugin_info,"GameStatus",NULL);
|
||||
|
||||
if (index)
|
||||
{
|
||||
MessageLists[index]=new MessageGameStatus;
|
||||
}
|
||||
|
||||
#if 0
|
||||
index=GET_USER_MSG_ID(&Plugin_info,"Particles",NULL);
|
||||
|
||||
if (index)
|
||||
{
|
||||
MessageLists[index]=new MessageDebug;
|
||||
}
|
||||
#endif
|
||||
// Start hooking messagebegin_post
|
||||
g_pengfuncsTable_Post->pfnMessageBegin=MessageBegin_Post;
|
||||
|
||||
};
|
||||
|
||||
void MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
|
||||
{
|
||||
// Sanity check, should never matter
|
||||
if (msg_type < 0 || msg_type > 255)
|
||||
{
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
// Has a hooked message?
|
||||
if (MessageLists[msg_type]!=NULL)
|
||||
{
|
||||
// Should this message be hooked?
|
||||
if (MessageLists[msg_type]->Begin(msg_dest,msg_type,pOrigin,ed)==1)
|
||||
{
|
||||
// This message is going to all be hooked
|
||||
|
||||
// save pointer to our class
|
||||
HookedMessage=MessageLists[msg_type];
|
||||
|
||||
// Tell metamod to forward
|
||||
g_pengfuncsTable_Post->pfnWriteByte=WriteByte_Post;
|
||||
g_pengfuncsTable_Post->pfnWriteChar=WriteChar_Post;
|
||||
g_pengfuncsTable_Post->pfnWriteShort=WriteShort_Post;
|
||||
g_pengfuncsTable_Post->pfnWriteLong=WriteLong_Post;
|
||||
g_pengfuncsTable_Post->pfnWriteAngle=WriteAngle_Post;
|
||||
g_pengfuncsTable_Post->pfnWriteCoord=WriteCoord_Post;
|
||||
g_pengfuncsTable_Post->pfnWriteString=WriteString_Post;
|
||||
g_pengfuncsTable_Post->pfnWriteEntity=WriteEntity_Post;
|
||||
g_pengfuncsTable_Post->pfnMessageEnd=MessageEnd_Post;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void MessageEnd_Post(void)
|
||||
{
|
||||
HookedMessage->End();
|
||||
|
||||
HookedMessage=NULL;
|
||||
|
||||
// Stop metamod forwarding
|
||||
g_pengfuncsTable_Post->pfnWriteByte=NULL;
|
||||
g_pengfuncsTable_Post->pfnWriteChar=NULL;
|
||||
g_pengfuncsTable_Post->pfnWriteShort=NULL;
|
||||
g_pengfuncsTable_Post->pfnWriteLong=NULL;
|
||||
g_pengfuncsTable_Post->pfnWriteAngle=NULL;
|
||||
g_pengfuncsTable_Post->pfnWriteCoord=NULL;
|
||||
g_pengfuncsTable_Post->pfnWriteString=NULL;
|
||||
g_pengfuncsTable_Post->pfnWriteEntity=NULL;
|
||||
g_pengfuncsTable_Post->pfnMessageEnd=NULL;
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
};
|
||||
|
||||
void WriteByte_Post(int iValue)
|
||||
{
|
||||
HookedMessage->WriteByte(iValue);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
};
|
||||
|
||||
void WriteChar_Post(int iValue)
|
||||
{
|
||||
HookedMessage->WriteChar(iValue);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
};
|
||||
|
||||
void WriteShort_Post(int iValue)
|
||||
{
|
||||
HookedMessage->WriteShort(iValue);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
};
|
||||
|
||||
void WriteLong_Post(int iValue)
|
||||
{
|
||||
HookedMessage->WriteLong(iValue);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
};
|
||||
|
||||
void WriteAngle_Post(float flValue)
|
||||
{
|
||||
HookedMessage->WriteAngle(flValue);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
};
|
||||
|
||||
void WriteCoord_Post(float flValue)
|
||||
{
|
||||
HookedMessage->WriteCoord(flValue);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
};
|
||||
|
||||
void WriteString_Post(const char *sz)
|
||||
{
|
||||
HookedMessage->WriteString(sz);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
};
|
||||
|
||||
void WriteEntity_Post(int iValue)
|
||||
{
|
||||
HookedMessage->WriteEntity(iValue);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
};
|
||||
|
178
dlls/ns/MessageHandler.h
Normal file
178
dlls/ns/MessageHandler.h
Normal file
@ -0,0 +1,178 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/* Class with virtual members for easy message handling
|
||||
* Don't forget to add new messages to "Initialize_MessageHandler()"
|
||||
*/
|
||||
#ifndef MESSAGEHANDLER_H
|
||||
#define MESSAGEHANDLER_H
|
||||
|
||||
#include "utilfunctions.h"
|
||||
|
||||
class MessageHandler
|
||||
{
|
||||
public:
|
||||
unsigned int m_Count;
|
||||
int m_Target;
|
||||
float m_Origin[3];
|
||||
edict_t *m_Entity;
|
||||
int m_Msg;
|
||||
|
||||
|
||||
/**
|
||||
* Return 1 to hook the rest of this message, 0 otherwise
|
||||
*/
|
||||
virtual int Begin(int Target, int Msg, const float *Origin, edict_t *Entity)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
virtual void End(void)
|
||||
{
|
||||
return;
|
||||
};
|
||||
|
||||
virtual void WriteByte(int Data)
|
||||
{
|
||||
++m_Count;
|
||||
};
|
||||
|
||||
virtual void WriteChar(int Data)
|
||||
{
|
||||
++m_Count;
|
||||
};
|
||||
|
||||
virtual void WriteShort(int Data)
|
||||
{
|
||||
++m_Count;
|
||||
};
|
||||
|
||||
virtual void WriteLong(int Data)
|
||||
{
|
||||
++m_Count;
|
||||
};
|
||||
|
||||
virtual void WriteAngle(REAL Data)
|
||||
{
|
||||
++m_Count;
|
||||
};
|
||||
|
||||
virtual void WriteCoord(REAL Data)
|
||||
{
|
||||
++m_Count;
|
||||
};
|
||||
|
||||
virtual void WriteString(const char *Data)
|
||||
{
|
||||
++m_Count;
|
||||
};
|
||||
|
||||
virtual void WriteEntity(int Data)
|
||||
{
|
||||
++m_Count;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
class MessageCountDown : public MessageHandler
|
||||
{
|
||||
public:
|
||||
int m_CountDownTime;
|
||||
|
||||
virtual int Begin(int Target, int Msg, const float *Origin, edict_t *Entity)
|
||||
{
|
||||
m_Count=0;
|
||||
return 1;
|
||||
};
|
||||
|
||||
virtual void End(void)
|
||||
{
|
||||
if (m_Count!=1) // invalid message?
|
||||
{
|
||||
MF_Log("[NS] Invalid Countdown message received! Got %d args, expected 1.",m_Count);
|
||||
return;
|
||||
}
|
||||
|
||||
GameMan.HandleCountdown(m_CountDownTime);
|
||||
};
|
||||
|
||||
virtual void WriteByte(int Data)
|
||||
{
|
||||
++m_Count;
|
||||
m_CountDownTime=Data;
|
||||
};
|
||||
};
|
||||
|
||||
class MessageGameStatus : public MessageHandler
|
||||
{
|
||||
public:
|
||||
int FirstByte;
|
||||
|
||||
virtual int Begin(int Target, int Msg, const float *Origin, edict_t *Entity)
|
||||
{
|
||||
m_Count=0;
|
||||
return 1;
|
||||
};
|
||||
|
||||
virtual void End(void)
|
||||
{
|
||||
GameMan.HandleGameStatus(FirstByte);
|
||||
};
|
||||
|
||||
virtual void WriteByte(int iValue)
|
||||
{
|
||||
if (m_Count==0)
|
||||
{
|
||||
FirstByte=iValue;
|
||||
};
|
||||
++m_Count;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
void Initialize_MessageHandler(void);
|
||||
|
||||
void MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
|
||||
void MessageEnd_Post(void);
|
||||
void WriteByte_Post(int iValue);
|
||||
void WriteChar_Post(int iValue);
|
||||
void WriteShort_Post(int iValue);
|
||||
void WriteLong_Post(int iValue);
|
||||
void WriteAngle_Post(float flValue);
|
||||
void WriteCoord_Post(float flValue);
|
||||
void WriteString_Post(const char *sz);
|
||||
void WriteEntity_Post(int iValue);
|
||||
|
||||
|
||||
#endif // MESSAGEHANDLER_H
|
100
dlls/ns/NEW_Util.h
Normal file
100
dlls/ns/NEW_Util.h
Normal file
@ -0,0 +1,100 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/* Inlined replacements for INDEXENT/ENTINDEX
|
||||
* It only really removes the overhead of the push/jump
|
||||
* but since INDEXENT/ENTINDEX are used a lot with amxx
|
||||
* it might be beneficial to include.
|
||||
* NOTE: Bad stuff will happen if you call these before
|
||||
* NEW_Initialize()
|
||||
* NOTE: No bounds checking is done because natives
|
||||
* should use their own bounds checking!
|
||||
*/
|
||||
|
||||
#ifndef NEW_UTIL_H
|
||||
#define NEW_UTIL_H
|
||||
|
||||
|
||||
extern edict_t *NEW_FirstEdict;
|
||||
extern bool NEW_Initialized;
|
||||
|
||||
/**
|
||||
* This is called on the first Spawn() ever hooked. This would be worldspawn (index 0)
|
||||
*/
|
||||
inline void NEW_Initialize(edict_t *Entity)
|
||||
{
|
||||
// call the HL Engine ENTINDEX to make sure this is index 0
|
||||
|
||||
int index=ENTINDEX(Entity);
|
||||
|
||||
if (index==0)
|
||||
{
|
||||
NEW_FirstEdict=Entity;
|
||||
NEW_Initialized=true;
|
||||
return;
|
||||
}
|
||||
|
||||
// This is not worldspawn?
|
||||
// compensate
|
||||
NEW_FirstEdict=Entity - index;
|
||||
NEW_Initialized=true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an integer index into an edict pointer
|
||||
*/
|
||||
inline edict_t *INDEXENT_NEW(const int Index)
|
||||
{
|
||||
return (edict_t *)(NEW_FirstEdict + Index);
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts an edict pointer into an integer index
|
||||
*/
|
||||
inline int ENTINDEX_NEW(const edict_t *Ent)
|
||||
{
|
||||
return (int)(Ent - NEW_FirstEdict);
|
||||
};
|
||||
|
||||
// Inlined replacement of MF_GetAmxAddr
|
||||
|
||||
|
||||
// straight from amxmodx's string.cpp; no need for this to be an api call
|
||||
inline cell *MF_GetAmxAddr_NEW(AMX *amx, cell amx_addr)
|
||||
{
|
||||
return (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
|
||||
};
|
||||
|
||||
|
||||
#endif // NEW_UTIL_H
|
@ -1,496 +0,0 @@
|
||||
#include "ns.h"
|
||||
|
||||
// These are natives directly from NS2AMX
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_has_weapon(AMX *amx,cell *params)
|
||||
{
|
||||
CHECK_ENTITY(params[1]);
|
||||
edict_t *pEntity = NULL;
|
||||
pEntity = INDEXENT2(params[1]);
|
||||
if (params[3] == -1)
|
||||
{
|
||||
if ((pEntity->v.weapons & (1<<params[2])) > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((pEntity->v.weapons & (1<<params[2])) > 0)
|
||||
{
|
||||
if (params[3] == 0)
|
||||
{
|
||||
pEntity->v.weapons &= ~(1<<params[2]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (params[3] == 1)
|
||||
{
|
||||
pEntity->v.weapons |= (1<<params[2]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_spawnpoints(AMX *amx, cell *params)
|
||||
{
|
||||
vec3_t vRet;
|
||||
if (params[2] == 0)
|
||||
{
|
||||
return (int)ns_spawnpoints.getnum(params[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
vRet=ns_spawnpoints.getpoint(params[1],params[2]);
|
||||
cell *vCell = MF_GetAmxAddr(amx,params[3]);
|
||||
vCell[0] = FLOAT_TO_CELL(vRet.x);
|
||||
vCell[1] = FLOAT_TO_CELL(vRet.y);
|
||||
vCell[2] = FLOAT_TO_CELL(vRet.z);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define MASK_ELECTRICITY 8192
|
||||
static cell AMX_NATIVE_CALL ns_get_build(AMX *amx, cell *params)
|
||||
{
|
||||
int iLength;
|
||||
char *buildtype = MF_GetAmxString(amx,params[1],0,&iLength);
|
||||
int iBuiltOnly = params[2];
|
||||
int iNumber = params[3];
|
||||
edict_t* pBuild = NULL;
|
||||
int iCount=0;
|
||||
|
||||
while ((pBuild = UTIL_FindEntityByString(pBuild,"classname",buildtype)) != NULL)
|
||||
{
|
||||
if (iBuiltOnly > 0)
|
||||
{
|
||||
if (FStrEq("team_advarmory",buildtype) || FStrEq("team_advturretfactory",buildtype))
|
||||
{
|
||||
iCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pBuild->v.fuser1 >= 1000 || pBuild->v.iuser4 & MASK_ELECTRICITY)
|
||||
{
|
||||
iCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iCount++;
|
||||
}
|
||||
if (iNumber > 0 && iCount == iNumber)
|
||||
return ENTINDEX(pBuild);
|
||||
}
|
||||
return iCount++;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_speedchange(AMX *amx, cell *params)
|
||||
{
|
||||
// Params: get_speedchange(index)
|
||||
int index=params[1];
|
||||
if (!(index>0 && index<=gpGlobals->maxClients))
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
return player->speedchange;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_speedchange(AMX *amx, cell *params)
|
||||
{
|
||||
// Params: set_speedchange(index,speedchange=0)
|
||||
if (!(params[1]>0&¶ms[1]<=32))
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
player->speedchange=params[2];
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_maxspeed(AMX *amx, cell *params)
|
||||
{
|
||||
// Params: get_maxspeed(index) (returns the max speed of the player BEFORE speed change is factored in.)
|
||||
if (!(params[1]>0 && params[1]<=32))
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
return player->maxspeed;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_player_model(AMX *amx, cell *params)
|
||||
{
|
||||
// Params: set_player_model(id,szModel[])
|
||||
if (!(params[1] > 0 && params[1] <= gpGlobals->maxClients))
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Can't set player model for a non-player entity");
|
||||
return 0;
|
||||
}
|
||||
int len;
|
||||
char *temp = MF_GetAmxString(amx,params[2],0,&len);
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
if (!FStrEq(temp,""))
|
||||
{
|
||||
PRECACHE_MODEL(temp);
|
||||
snprintf(player->model,127,"%s",temp);
|
||||
player->custommodel=true;
|
||||
|
||||
}
|
||||
else
|
||||
player->custommodel=false;
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_player_skin(AMX *amx, cell *params)
|
||||
{
|
||||
// Params: set_player_skin(id,skin=-1)
|
||||
if (!(params[1] > 0 && params[1] <= gpGlobals->maxClients))
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Can't set player skin for a non-player entity");
|
||||
return 0;
|
||||
}
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
if (params[2] < 0)
|
||||
{
|
||||
// Reset skin.
|
||||
player->skin=0;
|
||||
player->customskin=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->customskin=true;
|
||||
player->skin=params[2];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_player_body(AMX *amx, cell *params)
|
||||
{
|
||||
// Params: set_player_body(id,body=-1)
|
||||
if (!(params[1] > 0 && params[1] <= gpGlobals->maxClients))
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Can't set player body for a non-player entity");
|
||||
return 0;
|
||||
}
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
if (params[2] < 0)
|
||||
{
|
||||
// Reset body.
|
||||
player->body=0;
|
||||
player->custombody=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->custombody=true;
|
||||
player->body=params[2];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_class(AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
|
||||
return player->GetClass();
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_jpfuel(AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
return FLOAT_TO_CELL(player->pev->fuser3 / 10.0);
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_jpfuel(AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
REAL fuel = CELL_TO_FLOAT(params[2]);
|
||||
if (fuel > 100.0)
|
||||
fuel = 100.0;
|
||||
if (fuel < 0.0)
|
||||
fuel = 0.0;
|
||||
player->pev->fuser3 = fuel * 10.0;
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_is_combat(AMX *amx, cell *params)
|
||||
{
|
||||
return iscombat;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_mask(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxEntities)
|
||||
return -1;
|
||||
edict_t *pEntity = INDEXENT2(params[1]);
|
||||
if (pEntity->v.iuser4 & params[2])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_mask(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxEntities)
|
||||
return -1;
|
||||
edict_t *pEntity = INDEXENT2(params[1]);
|
||||
if (params[3] > 0)
|
||||
{
|
||||
if (pEntity->v.iuser4 & params[2])
|
||||
return 0;
|
||||
pEntity->v.iuser4 |= params[2];
|
||||
return 1;
|
||||
}
|
||||
if (pEntity->v.iuser4 & params[2])
|
||||
{
|
||||
pEntity->v.iuser4 &= ~params[2];
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_popup(AMX *amx, cell *params)
|
||||
{
|
||||
if (!gmsgHudText2)
|
||||
gmsgHudText2 = GET_USER_MSG_ID(PLID, "HudText2", NULL);
|
||||
if (params[1])
|
||||
{
|
||||
if (params[1] > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
MESSAGE_BEGIN(MSG_ONE,gmsgHudText2,NULL,player->edict);
|
||||
}
|
||||
else
|
||||
MESSAGE_BEGIN(MSG_ALL,gmsgHudText2);
|
||||
int len;
|
||||
char *blah = MF_GetAmxString(amx,params[2],0,&len);
|
||||
char msg[190];
|
||||
strncpy(msg,blah,188);
|
||||
WRITE_STRING(msg);
|
||||
WRITE_BYTE(params[3]);
|
||||
MESSAGE_END();
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_fov(AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(params[1]);
|
||||
REAL fov = CELL_TO_FLOAT(params[2]);
|
||||
LOG_CONSOLE(PLID,"Got fov. fov=%f",fov);
|
||||
int gmsgSetFov = GET_USER_MSG_ID(PLID, "SetFOV", NULL);
|
||||
if (fov == 0.0)
|
||||
{
|
||||
player->foved=false;
|
||||
player->fov=0.0;
|
||||
MESSAGE_BEGIN(MSG_ONE,gmsgSetFov,NULL,player->edict);
|
||||
WRITE_BYTE(0);
|
||||
MESSAGE_END();
|
||||
return 1;
|
||||
}
|
||||
if (fov > 0)
|
||||
{
|
||||
player->foved=true;
|
||||
player->fov=fov;
|
||||
MESSAGE_BEGIN(MSG_ONE,gmsgSetFov,NULL,player->edict);
|
||||
WRITE_BYTE((int)fov);
|
||||
MESSAGE_END();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_giveitem(AMX *amx, cell *params)
|
||||
{
|
||||
int index=params[1];
|
||||
int len;
|
||||
char *classname = MF_GetAmxString(amx,params[2],0,&len);
|
||||
if (index<1 || index>gpGlobals->maxClients)
|
||||
return 0;
|
||||
edict_t *player=INDEXENT2(index);
|
||||
if (player->v.deadflag > 0)
|
||||
return 0;
|
||||
edict_t *object=CREATE_NAMED_ENTITY(ALLOC_STRING(classname)); //create
|
||||
if (!object)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Error creating entity \"%s\"", classname);
|
||||
return 0;
|
||||
}
|
||||
SET_ORIGIN(object,player->v.origin); // move to player
|
||||
gpGamedllFuncs->dllapi_table->pfnSpawn(object); // emulate spawn
|
||||
object->v.flags |= FL_ONGROUND; // make it think it's touched the ground
|
||||
gpGamedllFuncs->dllapi_table->pfnThink(object); //
|
||||
gpGamedllFuncs->dllapi_table->pfnTouch(object,player); // give it to the player
|
||||
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_user_kill(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
if (index<1||index>gpGlobals->maxClients)
|
||||
return 0;
|
||||
|
||||
edict_t *e=INDEXENT2(index);
|
||||
if (e->v.iuser3 == 2 /* Commander class*/)
|
||||
return 0;
|
||||
|
||||
if (MF_IsPlayerIngame(index) && MF_IsPlayerAlive(index))
|
||||
{
|
||||
float bef = e->v.frags;
|
||||
edict_t *pEntity = CREATE_NAMED_ENTITY(MAKE_STRING("trigger_hurt"));
|
||||
if (pEntity)
|
||||
{
|
||||
KeyValueData kvd;
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="classname";
|
||||
kvd.szValue="trigger_hurt";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="dmg";
|
||||
kvd.szValue="20000.0";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="damagetype";
|
||||
kvd.szValue="1";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="origin";
|
||||
kvd.szValue="8192 8192 8192";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
MDLL_Spawn(pEntity);
|
||||
pEntity->v.classname=MAKE_STRING("slay");
|
||||
MDLL_Touch(pEntity,e);
|
||||
REMOVE_ENTITY(pEntity);
|
||||
}
|
||||
if (params[2]) e->v.frags = bef;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#define ANGLEVECTORS (*g_engfuncs.pfnAngleVectors)
|
||||
static cell AMX_NATIVE_CALL ns_user_slap(AMX *amx, cell *params) /* 2 param */
|
||||
{
|
||||
int index = params[1];
|
||||
if (index<1||index>gpGlobals->maxClients)
|
||||
return 0;
|
||||
int power = abs((int)params[2]);
|
||||
edict_t *e=INDEXENT2(index);
|
||||
if (e->v.iuser3 == 2 /* Commander class*/)
|
||||
return 0;
|
||||
|
||||
if (MF_IsPlayerIngame(index) && MF_IsPlayerAlive(index)) {
|
||||
if (e->v.health <= power) {
|
||||
float bef = e->v.frags;
|
||||
/*MDLL_ClientKill(pPlayer->pEdict);*/
|
||||
edict_t *pEntity = CREATE_NAMED_ENTITY(MAKE_STRING("trigger_hurt"));
|
||||
if (pEntity)
|
||||
{
|
||||
KeyValueData kvd;
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="classname";
|
||||
kvd.szValue="trigger_hurt";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="dmg";
|
||||
kvd.szValue="20000.0";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="damagetype";
|
||||
kvd.szValue="1";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="origin";
|
||||
kvd.szValue="8192 8192 8192";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
MDLL_Spawn(pEntity);
|
||||
pEntity->v.classname=MAKE_STRING("slap");
|
||||
MDLL_Touch(pEntity,e);
|
||||
REMOVE_ENTITY(pEntity);
|
||||
}
|
||||
|
||||
e->v.frags = bef;
|
||||
}
|
||||
else {
|
||||
edict_t *pEdict = e;
|
||||
int numparam = *params/sizeof(cell);
|
||||
if (numparam<3 || params[3]) {
|
||||
pEdict->v.velocity.x += RANDOM_LONG(-600,600);
|
||||
pEdict->v.velocity.y += RANDOM_LONG(-180,180);
|
||||
pEdict->v.velocity.z += RANDOM_LONG(100,200);
|
||||
}
|
||||
else {
|
||||
vec3_t v_forward, v_right;
|
||||
vec3_t vang = pEdict->v.angles;
|
||||
float fang[3];
|
||||
fang[0] = vang.x;
|
||||
fang[1] = vang.y;
|
||||
fang[2] = vang.z;
|
||||
ANGLEVECTORS( fang, v_forward, v_right, NULL );
|
||||
pEdict->v.velocity = pEdict->v.velocity + v_forward * 220 + Vector(0,0,200);
|
||||
}
|
||||
pEdict->v.punchangle.x = RANDOM_LONG(-10,10);
|
||||
pEdict->v.punchangle.y = RANDOM_LONG(-10,10);
|
||||
pEdict->v.health -= power;
|
||||
int armor = (int)pEdict->v.armorvalue;
|
||||
armor -= power;
|
||||
if (armor < 0) armor = 0;
|
||||
pEdict->v.armorvalue = armor;
|
||||
pEdict->v.dmg_inflictor = pEdict;
|
||||
static const char *bit_sound[3] = {
|
||||
"weapons/cbar_hitbod1.wav",
|
||||
"weapons/cbar_hitbod2.wav",
|
||||
"weapons/cbar_hitbod3.wav" };
|
||||
EMIT_SOUND_DYN2(pEdict, CHAN_VOICE, bit_sound[RANDOM_LONG(0,2)], 1.0, ATTN_NORM, 0, PITCH_NORM);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
AMX_NATIVE_INFO ns_misc_natives[] = {
|
||||
///////////////////
|
||||
{ "user_kill", ns_user_kill },
|
||||
{ "user_slap", ns_user_slap },
|
||||
|
||||
{ "ns_get_build", ns_get_build },
|
||||
|
||||
{ "ns_set_player_model", ns_set_player_model },
|
||||
{ "ns_set_player_skin", ns_set_player_skin },
|
||||
{ "ns_set_player_body", ns_set_player_body },
|
||||
|
||||
{ "ns_has_weapon", ns_has_weapon },
|
||||
|
||||
{ "ns_get_spawn", ns_get_spawnpoints },
|
||||
|
||||
{ "ns_get_speedchange", ns_get_speedchange },
|
||||
{ "ns_set_speedchange", ns_set_speedchange },
|
||||
{ "ns_get_maxspeed", ns_get_maxspeed },
|
||||
|
||||
{ "ns_get_class", ns_get_class },
|
||||
|
||||
{ "ns_get_jpfuel", ns_get_jpfuel },
|
||||
{ "ns_set_jpfuel", ns_set_jpfuel },
|
||||
|
||||
{ "ns_get_energy", ns_get_jpfuel }, // They do the same thing...
|
||||
{ "ns_set_energy", ns_set_jpfuel }, //
|
||||
{ "ns_is_combat", ns_is_combat },
|
||||
|
||||
{ "ns_get_mask", ns_get_mask },
|
||||
{ "ns_set_mask", ns_set_mask },
|
||||
|
||||
{ "ns_popup", ns_popup },
|
||||
|
||||
{ "ns_set_fov", ns_set_fov },
|
||||
|
||||
{ "ns_give_item", ns_giveitem },
|
||||
|
||||
///////////////////
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
@ -1,389 +0,0 @@
|
||||
#include "ns.h"
|
||||
|
||||
int get_private(edict_t *pEntity, int woffset,int loffset)
|
||||
{
|
||||
#ifdef __linux__
|
||||
return *(int*)((char*)(pEntity->pvPrivateData)+loffset);
|
||||
#else
|
||||
return *(int*)((char*)(pEntity->pvPrivateData)+woffset);
|
||||
#endif
|
||||
}
|
||||
REAL get_private_f(edict_t *pEntity, int woffset, int loffset)
|
||||
{
|
||||
#ifdef __linux__
|
||||
return *(REAL*)((char*)(pEntity->pvPrivateData)+loffset);
|
||||
#else
|
||||
return *(REAL*)((char*)(pEntity->pvPrivateData)+woffset);
|
||||
#endif
|
||||
}
|
||||
void set_private(edict_t *pEntity, int woffset, int loffset, int value)
|
||||
{
|
||||
#ifdef __linux__
|
||||
*(int*)((char*)(pEntity->pvPrivateData)+loffset) = value;
|
||||
#else
|
||||
*(int*)((char*)(pEntity->pvPrivateData)+woffset) = value;
|
||||
#endif
|
||||
}
|
||||
void set_private(edict_t *pEntity, int woffset, int loffset, REAL value)
|
||||
{
|
||||
#ifdef __linux__
|
||||
*(REAL*)((char*)(pEntity->pvPrivateData)+loffset) = value;
|
||||
#else
|
||||
*(REAL*)((char*)(pEntity->pvPrivateData)+woffset) = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_res(AMX *amx, cell *params)
|
||||
{
|
||||
if (iscombat)
|
||||
return 0;
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
|
||||
if (!player->connected)
|
||||
return 0;
|
||||
if (player->edict->pvPrivateData == NULL) // Worth a shot to make sure it's initialized.
|
||||
return 0;
|
||||
REAL res = get_private_f(player->edict,OFFSET_WIN_RESOURCES,OFFSET_LIN_RESOURCES);
|
||||
return FLOAT_TO_CELL(res);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_set_res(AMX *amx, cell *params)
|
||||
{
|
||||
if (iscombat)
|
||||
return 0;
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
if (!player->connected || player->edict->pvPrivateData == NULL)
|
||||
return 0;
|
||||
REAL res = CELL_TO_FLOAT(params[2]);
|
||||
set_private(player->edict,OFFSET_WIN_RESOURCES,OFFSET_LIN_RESOURCES,res);
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_exp(AMX *amx, cell *params)
|
||||
{
|
||||
if (!iscombat)
|
||||
return 0;
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
|
||||
if (!player->connected)
|
||||
return 0;
|
||||
if (player->edict->pvPrivateData == NULL) // Worth a shot to make sure it's initialized.
|
||||
return 0;
|
||||
REAL res = get_private_f(player->edict,OFFSET_WIN_EXP,OFFSET_LIN_EXP);
|
||||
return FLOAT_TO_CELL(res);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_set_exp(AMX *amx, cell *params)
|
||||
{
|
||||
if (!iscombat)
|
||||
return 0;
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
if (!player->connected || player->edict->pvPrivateData == NULL)
|
||||
return 0;
|
||||
REAL res = CELL_TO_FLOAT(params[2]);
|
||||
set_private(player->edict,OFFSET_WIN_EXP,OFFSET_LIN_EXP,res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_points(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
if (!player->connected || player->edict->pvPrivateData == NULL)
|
||||
return 0;
|
||||
return get_private(player->edict,OFFSET_WIN_POINTS,OFFSET_LIN_POINTS);
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_points(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
if (!player->connected || player->edict->pvPrivateData == NULL)
|
||||
return 0;
|
||||
set_private(player->edict,OFFSET_WIN_POINTS,OFFSET_LIN_POINTS,(int)params[2]);
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_weapon_dmg(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id <= gpGlobals->maxClients || id > gpGlobals->maxEntities)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
REAL dmg = CELL_TO_FLOAT(params[2]);
|
||||
set_private(pEntity,OFFSET_WIN_WEAPDMG,OFFSET_LIN_WEAPDMG,dmg);
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon_dmg(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id <= gpGlobals->maxClients || id > gpGlobals->maxEntities)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
return FLOAT_TO_CELL(get_private_f(pEntity,OFFSET_WIN_WEAPDMG,OFFSET_LIN_WEAPDMG));
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_set_weapon_range(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id <= gpGlobals->maxClients || id > gpGlobals->maxEntities)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
REAL dmg = CELL_TO_FLOAT(params[2]);
|
||||
set_private(pEntity,OFFSET_WIN_WEAPRANGE,OFFSET_LIN_WEAPRANGE,dmg);
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon_range(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id <= gpGlobals->maxClients || id > gpGlobals->maxEntities)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
return FLOAT_TO_CELL(get_private_f(pEntity,OFFSET_WIN_WEAPRANGE,OFFSET_LIN_WEAPRANGE));
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_weapon_ammo(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id <= gpGlobals->maxClients || id > gpGlobals->maxEntities)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
set_private(pEntity,OFFSET_WIN_WEAPCLIP,OFFSET_LIN_WEAPCLIP,(int)params[2]);
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon_ammo(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id <= gpGlobals->maxClients || id > gpGlobals->maxEntities)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
return get_private(pEntity,OFFSET_WIN_WEAPCLIP,OFFSET_LIN_WEAPCLIP);
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_weap_reserve(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
if (!player->connected || player->edict->pvPrivateData == NULL)
|
||||
return 0;
|
||||
switch (params[2])
|
||||
{
|
||||
case WEAPON_PISTOL:
|
||||
return get_private(player->edict,OFFSET_WIN_AMMO_PISTOL,OFFSET_LIN_AMMO_PISTOL);
|
||||
case WEAPON_LMG:
|
||||
return get_private(player->edict,OFFSET_WIN_AMMO_LMG,OFFSET_LIN_AMMO_LMG);
|
||||
case WEAPON_SHOTGUN:
|
||||
return get_private(player->edict,OFFSET_WIN_AMMO_SHOTGUN,OFFSET_LIN_AMMO_SHOTGUN);
|
||||
case WEAPON_HMG:
|
||||
return get_private(player->edict,OFFSET_WIN_AMMO_HMG,OFFSET_LIN_AMMO_HMG);
|
||||
case WEAPON_GRENADE_GUN:
|
||||
return get_private(player->edict,OFFSET_WIN_AMMO_GL,OFFSET_LIN_AMMO_GL);
|
||||
case WEAPON_GRENADE:
|
||||
return get_private(player->edict,OFFSET_WIN_AMMO_HG,OFFSET_LIN_AMMO_HG);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_weap_reserve(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
if (!player->connected || player->edict->pvPrivateData == NULL)
|
||||
return 0;
|
||||
switch (params[2])
|
||||
{
|
||||
case WEAPON_PISTOL:
|
||||
set_private(player->edict,OFFSET_WIN_AMMO_PISTOL,OFFSET_LIN_AMMO_PISTOL,(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_LMG:
|
||||
set_private(player->edict,OFFSET_WIN_AMMO_LMG,OFFSET_LIN_AMMO_LMG,(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_SHOTGUN:
|
||||
set_private(player->edict,OFFSET_WIN_AMMO_SHOTGUN,OFFSET_LIN_AMMO_SHOTGUN,(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_HMG:
|
||||
set_private(player->edict,OFFSET_WIN_AMMO_HMG,OFFSET_LIN_AMMO_HMG,(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_GRENADE_GUN:
|
||||
set_private(player->edict,OFFSET_WIN_AMMO_GL,OFFSET_LIN_AMMO_GL,(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_GRENADE:
|
||||
set_private(player->edict,OFFSET_WIN_AMMO_HG,OFFSET_LIN_AMMO_HG,(int)params[3]);
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_score(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
if (!player->connected || player->edict->pvPrivateData == NULL)
|
||||
return 0;
|
||||
return get_private(player->edict,OFFSET_WIN_SCORE,OFFSET_LIN_SCORE);
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_score(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
if (!player->connected || player->edict->pvPrivateData == NULL)
|
||||
return 0;
|
||||
set_private(player->edict,OFFSET_WIN_SCORE,OFFSET_LIN_SCORE,(int)params[2]);
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_hive_trait(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id <= gpGlobals->maxClients || id > gpGlobals->maxEntities)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
set_private(pEntity,OFFSET_WIN_HIVE_TRAIT,OFFSET_LIN_HIVE_TRAIT,(int)params[2]);
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_hive_trait(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id <= gpGlobals->maxClients || id > gpGlobals->maxEntities)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
return get_private(pEntity,OFFSET_WIN_HIVE_TRAIT,OFFSET_LIN_HIVE_TRAIT);
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
return get_private(player->edict,OFFSET_WIN_DEATHS,OFFSET_LIN_DEATHS);
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
set_private(player->edict,OFFSET_WIN_DEATHS,OFFSET_LIN_DEATHS,(int)params[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_struct_owner(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id <= gpGlobals->maxClients || id >= gpGlobals->maxEntities)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (!pEntity)
|
||||
return 0;
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
return get_private(pEntity,OFFSET_WIN_STRUCTOWNER,OFFSET_LIN_STRUCTOWNER);
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_struct_owner(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
int ido = params[2];
|
||||
if (id <= gpGlobals->maxClients || id >= gpGlobals->maxEntities)
|
||||
return 0;
|
||||
if (ido > gpGlobals->maxClients || ido < -1)
|
||||
return 0;
|
||||
edict_t *pEntity = INDEXENT2(id);
|
||||
if (!pEntity)
|
||||
return 0;
|
||||
if (pEntity->pvPrivateData == NULL)
|
||||
return 0;
|
||||
set_private(pEntity,OFFSET_WIN_STRUCTOWNER,OFFSET_LIN_STRUCTOWNER,ido);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_hive_ability(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
int abilitynum = params[2];
|
||||
if (id < 1 || id > gpGlobals->maxClients)
|
||||
return 0;
|
||||
|
||||
CPlayer *player = GET_PLAYER_I(id);
|
||||
int result = get_private(player->edict, OFFSET_WIN_HIVEABILITY, OFFSET_LIN_HIVEABILITY);
|
||||
|
||||
return (abilitynum > 0) ? (result >= abilitynum - 1) : result;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO ns_pdata_natives[] = {
|
||||
/*****************/
|
||||
{ "ns_get_res", ns_get_res },
|
||||
{ "ns_set_res", ns_set_res },
|
||||
|
||||
{ "ns_get_exp", ns_get_exp },
|
||||
{ "ns_set_exp", ns_set_exp },
|
||||
|
||||
{ "ns_get_points", ns_get_points },
|
||||
{ "ns_set_points", ns_set_points },
|
||||
|
||||
{ "ns_set_weap_dmg", ns_set_weapon_dmg },
|
||||
{ "ns_get_weap_dmg", ns_get_weapon_dmg },
|
||||
|
||||
{ "ns_set_weap_range", ns_set_weapon_range },
|
||||
{ "ns_get_weap_range", ns_get_weapon_range },
|
||||
|
||||
{ "ns_set_weap_clip", ns_set_weapon_ammo },
|
||||
{ "ns_get_weap_clip", ns_get_weapon_ammo },
|
||||
|
||||
{ "ns_set_weap_reserve", ns_set_weap_reserve },
|
||||
{ "ns_get_weap_reserve", ns_get_weap_reserve },
|
||||
|
||||
{ "ns_set_score", ns_set_score },
|
||||
{ "ns_get_score", ns_get_score },
|
||||
|
||||
{ "ns_get_deaths", ns_get_deaths },
|
||||
{ "ns_set_deaths", ns_set_deaths },
|
||||
|
||||
{ "ns_get_hive_trait", ns_get_hive_trait },
|
||||
{ "ns_set_hive_trait", ns_set_hive_trait },
|
||||
|
||||
{ "ns_get_struct_owner", ns_get_struct_owner },
|
||||
{ "ns_set_struct_owner", ns_set_struct_owner },
|
||||
|
||||
{ "ns_get_hive_ability", ns_get_hive_ability},
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
121
dlls/ns/ParticleManager.cpp
Normal file
121
dlls/ns/ParticleManager.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
#include "sdk/amxxmodule.h"
|
||||
#include "ns.h"
|
||||
|
||||
#include "CVector.h"
|
||||
#include "CString.h"
|
||||
|
||||
#include "ParticleManager.h"
|
||||
|
||||
|
||||
void ParticleManager::ReadFile(void)
|
||||
{
|
||||
this->Prune();
|
||||
if (m_iFileLoaded!=0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_iFileLoaded=1;
|
||||
|
||||
char FileName[256];
|
||||
|
||||
snprintf(FileName,sizeof(FileName)-1,"%s/ns.ps",MF_GetModname());
|
||||
FILE *fp=fopen(FileName,"r");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
MF_Log("ParticleManager: Cannot open \"%s\" for reading!",FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
// Since I don't care about the actual parameters of each
|
||||
// particle system, just their order and name
|
||||
// I only have to scan for "start pSystemName NAME"
|
||||
|
||||
char Buffer[1024];
|
||||
|
||||
char *Start;
|
||||
char *End;
|
||||
|
||||
int Count=0;
|
||||
|
||||
memset(&Buffer[0],0x0,sizeof(Buffer));
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
Buffer[0]='\0';
|
||||
|
||||
fgets(Buffer,1023,fp);
|
||||
|
||||
Start=&Buffer[0];
|
||||
|
||||
// strip whitespace from the front
|
||||
while (*Start==' ' ||
|
||||
*Start=='\t')
|
||||
{
|
||||
++Start;
|
||||
}
|
||||
|
||||
// if the first character is ' ignore it
|
||||
if (*Start=='\'')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the first word is "start" then this is a line we want
|
||||
|
||||
if (strncmp("start ",Start,6)!=0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Move up past 2 space blocks
|
||||
|
||||
while (*Start!='\0' &&
|
||||
*Start!=' ' &&
|
||||
*Start!='\t')
|
||||
{
|
||||
++Start;
|
||||
}
|
||||
while (*Start==' ' ||
|
||||
*Start=='\t')
|
||||
{
|
||||
++Start;
|
||||
}
|
||||
|
||||
while (*Start!='\0' &&
|
||||
*Start!=' ' &&
|
||||
*Start!='\t')
|
||||
{
|
||||
++Start;
|
||||
}
|
||||
while (*Start==' ' ||
|
||||
*Start=='\t')
|
||||
{
|
||||
++Start;
|
||||
}
|
||||
|
||||
// now strip whitespace from the end
|
||||
|
||||
End=Start+strlen(Start)-1;
|
||||
|
||||
while (*End=='\n' ||
|
||||
*End=='\r' ||
|
||||
*End==' ' ||
|
||||
*End=='\t')
|
||||
{
|
||||
*End--='\0';
|
||||
}
|
||||
|
||||
// "Start" should now point to the name of this particle system
|
||||
|
||||
//printf("Particle system %d = \"%s\"\n",Count,Start);
|
||||
|
||||
|
||||
this->Add(Start,1);
|
||||
|
||||
|
||||
++Count;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
};
|
152
dlls/ns/ParticleManager.h
Normal file
152
dlls/ns/ParticleManager.h
Normal file
@ -0,0 +1,152 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef PARTICLEMANAGER_H
|
||||
#define PARTICLEMANAGER_H
|
||||
|
||||
typedef struct psystem_s
|
||||
{
|
||||
String Name;
|
||||
int id;
|
||||
int IsStatic; // Set to 1 if the particle system is loaded from ns.ps
|
||||
|
||||
} ParticleSystem;
|
||||
|
||||
class ParticleManager
|
||||
{
|
||||
private:
|
||||
CVector<ParticleSystem *> Systems;
|
||||
int m_iFileLoaded;
|
||||
unsigned short m_iEventID;
|
||||
|
||||
public:
|
||||
ParticleManager()
|
||||
{
|
||||
m_iFileLoaded=0;
|
||||
m_iEventID=0;
|
||||
Systems.reserve(64);
|
||||
};
|
||||
|
||||
// Remove all non-static particle systems
|
||||
inline void Prune()
|
||||
{
|
||||
if (Systems.size()==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CVector<ParticleSystem *>::iterator iter;
|
||||
while (1)
|
||||
{
|
||||
if (Systems.size()==0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
iter=Systems.end();
|
||||
iter--;
|
||||
|
||||
if ((*iter)->IsStatic)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
delete (*iter);
|
||||
Systems.pop_back();
|
||||
};
|
||||
};
|
||||
|
||||
void ReadFile(void);
|
||||
|
||||
inline int Add(const char *Start, int Static)
|
||||
{
|
||||
ParticleSystem *ps=new ParticleSystem;
|
||||
|
||||
ps->id=Systems.size();
|
||||
ps->IsStatic=Static;
|
||||
ps->Name.assign(Start);
|
||||
|
||||
Systems.push_back(ps);
|
||||
|
||||
return Systems.size()-1;
|
||||
};
|
||||
inline void FireSystem(int id, float *Origin, float *Angles, int flags)
|
||||
{
|
||||
PLAYBACK_EVENT_FULL(flags, /*flags*/
|
||||
NULL, /*pInvoker*/
|
||||
m_iEventID, /*eventid*/
|
||||
0.0, /*delay*/
|
||||
Origin, /*origin*/
|
||||
Angles, /*angles*/
|
||||
0.0, /*fparam1*/
|
||||
0.0, /*fparam2*/
|
||||
id, /*iparam1 - particle system id*/
|
||||
0, /*iparam2*/
|
||||
0, /*bparam1*/
|
||||
0); /*bparam2*/
|
||||
};
|
||||
inline void PrecacheEvent(const char *file)
|
||||
{
|
||||
if (strcmp(file,"events/Particle.sc")==0)
|
||||
{
|
||||
if (META_RESULT_STATUS >= MRES_OVERRIDE)
|
||||
{
|
||||
m_iEventID=META_RESULT_OVERRIDE_RET(unsigned short);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iEventID=META_RESULT_ORIG_RET(unsigned short);
|
||||
}
|
||||
//printf("EVENT=%d\n",m_iEventID);
|
||||
}
|
||||
};
|
||||
inline int Find(const char *Needle)
|
||||
{
|
||||
CVector<ParticleSystem *>::iterator iter=Systems.begin();
|
||||
CVector<ParticleSystem *>::iterator end=Systems.end();
|
||||
|
||||
while (iter!=end)
|
||||
{
|
||||
if (strcmp(Needle,(*iter)->Name.c_str())==0)
|
||||
{
|
||||
return (*iter)->id;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
extern ParticleManager ParticleMan;
|
||||
|
||||
#endif // PARTICLEMANAGER_H
|
128
dlls/ns/SpawnManager.h
Normal file
128
dlls/ns/SpawnManager.h
Normal file
@ -0,0 +1,128 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef SPAWNMANAGER_H
|
||||
#define SPAWNMANAGER_H
|
||||
|
||||
#include "CVector.h"
|
||||
|
||||
typedef struct spawndata_s
|
||||
{
|
||||
REAL Location[3];
|
||||
REAL Angle[3];
|
||||
} SpawnData;
|
||||
|
||||
class SpawnManager
|
||||
{
|
||||
private:
|
||||
CVector<SpawnData> TeamSpawns[5];
|
||||
|
||||
public:
|
||||
SpawnManager()
|
||||
{
|
||||
this->Clear();
|
||||
};
|
||||
|
||||
inline void Clear(void)
|
||||
{
|
||||
TeamSpawns[0].clear();
|
||||
TeamSpawns[1].clear();
|
||||
TeamSpawns[2].clear();
|
||||
TeamSpawns[3].clear();
|
||||
TeamSpawns[4].clear();
|
||||
|
||||
// Reserve data for a "typical" map layout
|
||||
// makes data entry faster on map load
|
||||
TeamSpawns[0].reserve(32);
|
||||
TeamSpawns[1].reserve(16);
|
||||
TeamSpawns[2].reserve(48);
|
||||
};
|
||||
|
||||
inline void Insert(const edict_t *Entity)
|
||||
{
|
||||
// Bounds check team
|
||||
if (Entity->v.team<0 || Entity->v.team > 4)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnData TemporaryData;
|
||||
|
||||
Entity->v.origin.CopyToArray(TemporaryData.Location);
|
||||
Entity->v.angles.CopyToArray(TemporaryData.Angle);
|
||||
|
||||
TeamSpawns[Entity->v.team].push_back(TemporaryData);
|
||||
};
|
||||
inline void InsertReadyRoom(const edict_t *Entity)
|
||||
{
|
||||
SpawnData TemporaryData;
|
||||
|
||||
Entity->v.origin.CopyToArray(TemporaryData.Location);
|
||||
Entity->v.angles.CopyToArray(TemporaryData.Angle);
|
||||
|
||||
TeamSpawns[0].push_back(TemporaryData);
|
||||
};
|
||||
|
||||
// ns_get_spawn(team,number=0,Float:ret[3]);
|
||||
inline cell Lookup(AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1] < 0 || params[1] > 4)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (params[2]==0)
|
||||
{
|
||||
return static_cast<int>(TeamSpawns[params[1]].size());
|
||||
}
|
||||
|
||||
if (params[2]>=(int)TeamSpawns[params[1]].size())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell *Return=MF_GetAmxAddr(amx,params[3]);
|
||||
|
||||
SpawnData SpawnRet=TeamSpawns[params[1]][params[2]];
|
||||
|
||||
Return[0]=amx_ftoc2(SpawnRet.Location[0]);
|
||||
Return[1]=amx_ftoc2(SpawnRet.Location[1]);
|
||||
Return[2]=amx_ftoc2(SpawnRet.Location[2]);
|
||||
|
||||
return 1;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
extern SpawnManager SpawnMan;
|
||||
|
||||
#endif // SPAWNMANAGER_H
|
142
dlls/ns/TitleManager.cpp
Normal file
142
dlls/ns/TitleManager.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "sdk/amxxmodule.h"
|
||||
#include "ns.h"
|
||||
#include "TitleManager.h"
|
||||
|
||||
|
||||
|
||||
void TitleManager::LoadTitles(void)
|
||||
{
|
||||
if (m_Loaded!=0) // already loaded?
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Loaded=1;
|
||||
|
||||
char FileName[128];
|
||||
|
||||
snprintf(FileName,127,"%s/titles.txt",MF_GetModname());
|
||||
|
||||
FILE *fp=fopen(FileName,"r");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
MF_Log("Unable to load \"%s\": TitleManager will not work!",FileName);
|
||||
return;
|
||||
};
|
||||
|
||||
//MF_Log("TitleManager Loading titles from \"%s\"",FileName);
|
||||
char KeyName[512]; // last known good keyname
|
||||
char Data[2048]; // data for the key
|
||||
// does not support multi line data, but for
|
||||
// location namesthat is acceptable.
|
||||
char TempBuffer[2048]; // currently read data
|
||||
char *TempPointer;
|
||||
char *TempPointerEnd;
|
||||
|
||||
unsigned int Line=0;
|
||||
scan_for_key:
|
||||
KeyName[0]='\0';
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
Line++;
|
||||
fgets(TempBuffer,2047,fp);
|
||||
TempPointer=&TempBuffer[0];
|
||||
|
||||
// get rid of white space at the front
|
||||
while (*TempPointer=='\0' || // terminator
|
||||
*TempPointer==' ' || // space
|
||||
*TempPointer=='\t') // tab
|
||||
{
|
||||
++TempPointer;
|
||||
}
|
||||
if (*TempPointer=='\0' || // terminator
|
||||
*TempPointer=='/') // comment
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// get rid of \r\n at the end
|
||||
TempPointerEnd=TempPointer+strlen(TempPointer)-1;
|
||||
while (*TempPointerEnd=='\r' ||
|
||||
*TempPointerEnd=='\n' ||
|
||||
*TempPointerEnd=='\t' ||
|
||||
*TempPointerEnd==' ')
|
||||
{
|
||||
*TempPointerEnd--='\0';
|
||||
}
|
||||
|
||||
if (*TempPointer=='{') // start of data
|
||||
{
|
||||
if (KeyName[0]!='\0') // do we have a keyname
|
||||
{
|
||||
goto scan_for_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
MF_Log("TitleManager: titles.txt line %u: began a data section with no key name in use!",Line);
|
||||
goto scan_for_key;
|
||||
}
|
||||
}
|
||||
|
||||
// have a valid key name here
|
||||
strncpy(KeyName,TempBuffer,sizeof(KeyName)-1);
|
||||
|
||||
// keep looping (until we hit a '{')
|
||||
};
|
||||
|
||||
// if we're out here then !feof() failed
|
||||
goto end_of_file;
|
||||
scan_for_data:
|
||||
Data[0]='\0';
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
Line++;
|
||||
fgets(TempBuffer,2047,fp);
|
||||
TempPointer=&TempBuffer[0];
|
||||
|
||||
// get rid of white space at the front
|
||||
while (*TempPointer=='\0' || // terminator
|
||||
*TempPointer==' ' || // space
|
||||
*TempPointer=='\t') // tab
|
||||
{
|
||||
++TempPointer;
|
||||
}
|
||||
if (*TempPointer=='\0' || // terminator
|
||||
*TempPointer=='/') // comment
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// get rid of trailing whitespace
|
||||
TempPointerEnd=TempPointer+strlen(TempPointer)-1;
|
||||
while (*TempPointerEnd=='\r' ||
|
||||
*TempPointerEnd=='\n' ||
|
||||
*TempPointerEnd=='\t' ||
|
||||
*TempPointerEnd==' ')
|
||||
{
|
||||
*TempPointerEnd--='\0';
|
||||
}
|
||||
|
||||
if (*TempPointer=='}') // end of data
|
||||
{
|
||||
// insert KeyName & Data into the hash
|
||||
String key(KeyName);
|
||||
|
||||
key.toLower();
|
||||
this->m_Hash.insert(key, new String(Data));
|
||||
|
||||
goto scan_for_key;
|
||||
}
|
||||
|
||||
// have valid data here
|
||||
strncpy(Data,TempBuffer,sizeof(Data)-1);
|
||||
};
|
||||
end_of_file:
|
||||
|
||||
fclose(fp);
|
||||
|
||||
//MF_Log("TitleManager loaded %u entries from titles.txt (%u lines parsed)",m_List.size(),Line);
|
||||
};
|
79
dlls/ns/TitleManager.h
Normal file
79
dlls/ns/TitleManager.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef TITLEMANAGER_H
|
||||
#define TITLEMANAGER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "CString.h"
|
||||
#include "Hash.h"
|
||||
|
||||
|
||||
class TitleManager
|
||||
{
|
||||
private:
|
||||
int m_Loaded;
|
||||
|
||||
// Use a string pointer for the data type because the location manager
|
||||
// stores a direct pointer to the c_str() of the title
|
||||
Hash<String, String*> m_Hash;
|
||||
|
||||
public:
|
||||
|
||||
TitleManager()
|
||||
{
|
||||
m_Loaded=0;
|
||||
};
|
||||
|
||||
inline const char *Lookup(String &input)
|
||||
{
|
||||
String** ret = m_Hash.find(input);
|
||||
|
||||
if (ret == NULL || *ret == NULL)
|
||||
{
|
||||
// was not found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return (*ret)->c_str();
|
||||
};
|
||||
void LoadTitles(void);
|
||||
};
|
||||
|
||||
extern TitleManager TitleMan;
|
||||
|
||||
#endif // TITLEMANAGER_H
|
107
dlls/ns/amxxapi.cpp
Normal file
107
dlls/ns/amxxapi.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/* 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 sent by AMX Mod X are handled here */
|
||||
|
||||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "ns.h"
|
||||
#include "utilfunctions.h"
|
||||
|
||||
#include "CVector.h"
|
||||
#include "CString.h"
|
||||
|
||||
#include "GameManager.h"
|
||||
#include "TitleManager.h"
|
||||
#include "MessageHandler.h"
|
||||
#include "ParticleManager.h"
|
||||
|
||||
#include "AllocString.h"
|
||||
|
||||
extern int gmsgHudText2;
|
||||
extern BOOL iscombat;
|
||||
|
||||
TitleManager TitleMan;
|
||||
ParticleManager ParticleMan;
|
||||
|
||||
void MFuncs_Initialize(void);
|
||||
|
||||
// Native register calls here
|
||||
void AddNatives_MemberFunc();
|
||||
void AddNatives_Particles();
|
||||
void AddNatives_Player();
|
||||
void AddNatives_PlayerMemory();
|
||||
void AddNatives_Weapons();
|
||||
void AddNatives_Structure();
|
||||
void AddNatives_General();
|
||||
|
||||
// All plugins have loaded (called during spawning worldspawn)
|
||||
void OnPluginsLoaded()
|
||||
{
|
||||
|
||||
// This message is used for the ns_popup native
|
||||
GameMan.GetMessageIDs();
|
||||
|
||||
// Check the map name and see if it's combat or not.
|
||||
GameMan.EvaluateCombat();
|
||||
|
||||
GameMan.RegisterForwards();
|
||||
|
||||
GameMan.CheckAllHooks();
|
||||
|
||||
AllocStringList.Clear();
|
||||
|
||||
TitleMan.LoadTitles();
|
||||
|
||||
GameMan.CheckMap();
|
||||
|
||||
ParticleMan.ReadFile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Module is attaching to AMXX
|
||||
void OnAmxxAttach()
|
||||
{
|
||||
AddNatives_MemberFunc();
|
||||
AddNatives_Particles();
|
||||
AddNatives_Player();
|
||||
AddNatives_PlayerMemory();
|
||||
AddNatives_Weapons();
|
||||
AddNatives_Structure();
|
||||
AddNatives_General();
|
||||
|
||||
MFuncs_Initialize();
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
#ifndef _INCLUDE_AMXXAPI_H
|
||||
#define _INCLUDE_AMXXAPI_H
|
||||
|
||||
extern int ChangeclassForward;
|
||||
extern int BuiltForward;
|
||||
|
||||
#endif //_INCLUDE_AMXXAPI_H
|
234
dlls/ns/dllapi.cpp
Normal file
234
dlls/ns/dllapi.cpp
Normal file
@ -0,0 +1,234 @@
|
||||
/* 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<edict_t *>(static_cast<const edict_t *>(ent)))->UpdateFOV();
|
||||
|
||||
RETURN_META(MRES_HANDLED);
|
||||
|
||||
}
|
317
dlls/ns/engineapi.cpp
Normal file
317
dlls/ns/engineapi.cpp
Normal file
@ -0,0 +1,317 @@
|
||||
/* 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 game dll to the engine are handled here */
|
||||
|
||||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "ns.h"
|
||||
|
||||
#include "utilfunctions.h"
|
||||
#include "CVector.h"
|
||||
#include "CString.h"
|
||||
|
||||
#include "GameManager.h"
|
||||
#include "ParticleManager.h"
|
||||
#include "CPlayer.h"
|
||||
|
||||
|
||||
// Parse log messages here for any desired information (structure_built, etc.)
|
||||
// The following logs are needed:
|
||||
// "sawce<1><STEAM_0:1:4560311><alien1team>" triggered "structure_built" (type "defensechamber")`
|
||||
void AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...)
|
||||
{
|
||||
if (atype != at_logged)
|
||||
{
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
char *MessageStart; // original pointer to start of the message
|
||||
char *TypePointer; // pointer to the structure type
|
||||
char *CIDPointer; // pointer to the name text
|
||||
|
||||
int CID; // connection ID of the player
|
||||
|
||||
va_list LogArgs;
|
||||
|
||||
va_start(LogArgs,szFmt);
|
||||
MessageStart=va_arg(LogArgs,char *);
|
||||
va_end(LogArgs);
|
||||
|
||||
if (MessageStart==NULL) // Somehow got a null pointer, get out of here now
|
||||
{
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
|
||||
if ((TypePointer=strstr(MessageStart,"\"structure_built\""))==NULL) // was not found
|
||||
{
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
if (*(TypePointer - 2) != 'd') // If this is not from a 'triggered "structure_built"', then ignore the message
|
||||
{
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
// If we got here, then for all we can tell this message is good
|
||||
|
||||
// Move up a few spaces
|
||||
TypePointer+=25; // strlen("\"structure_built\" (type \"")=25
|
||||
|
||||
// Now get the player's CID
|
||||
CIDPointer=MessageStart+1; // skip over the very first quotation mark
|
||||
|
||||
while (*CIDPointer++ != '"') /*do nothing*/;
|
||||
|
||||
--CIDPointer;
|
||||
|
||||
// Move back past three <
|
||||
|
||||
while (*CIDPointer-- != '<') /* do nothing*/;
|
||||
while (*CIDPointer-- != '<') /* do nothing*/;
|
||||
while (*CIDPointer-- != '<') /* do nothing*/;
|
||||
|
||||
++CIDPointer;
|
||||
|
||||
// now skip past the <
|
||||
++CIDPointer;
|
||||
|
||||
// We now point to the CID string, atoi will stop at the > so just atoi it for the CID
|
||||
CID=atoi(CIDPointer);
|
||||
|
||||
CPlayer *Player;
|
||||
|
||||
if ((Player=UTIL_PlayerByCID(CID))==NULL)
|
||||
{
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
// list of what impulses represent what type of structure building
|
||||
// use
|
||||
// 0 for unknown (shouldn't be used ever)
|
||||
// 1 for marine
|
||||
// 2 for alien
|
||||
|
||||
// I'm marking the upgrades as marine structures just incase
|
||||
// they should never be used though!
|
||||
static int StructureTypes[128] =
|
||||
{
|
||||
|
||||
0, // 0 = unknown
|
||||
0, // 1 = next weapon
|
||||
0, // 2 = reload
|
||||
0, // 3 = drop weapon
|
||||
0, // 4 = unknown
|
||||
0, // 5 = unknown
|
||||
0, // 6 = unknown
|
||||
0, // 7 = radio comm
|
||||
0, // 8 = radio comm
|
||||
0, // 9 = radio comm
|
||||
|
||||
0, // 10 = radio comm
|
||||
0, // 11 = radio comm
|
||||
0, // 12 = radio comm
|
||||
0, // 13 = radio comm
|
||||
0, // 14 = radio comm
|
||||
0, // 15 = radio comm
|
||||
0, // 16 = unknown
|
||||
0, // 17 = unknown
|
||||
0, // 18 = unknown
|
||||
0, // 19 = unknown
|
||||
|
||||
1, // 20 = armor 1
|
||||
1, // 21 = armor 2
|
||||
1, // 22 = armor 3
|
||||
1, // 23 = weapons 1
|
||||
1, // 24 = weapons 2
|
||||
1, // 25 = weapons 3
|
||||
1, // 26 = siege upgrade
|
||||
1, // 27 = drop catalyst
|
||||
1, // 28 = research jp
|
||||
1, // 29 = research ha
|
||||
|
||||
1, // 30 = distress beacon
|
||||
1, // 31 = resupply (combat)
|
||||
0, // 32 = unknown
|
||||
1, // 33 = motion tracking
|
||||
1, // 34 = phase gates upgrade
|
||||
0, // 35 = unknown
|
||||
1, // 36 = electricity upgrade
|
||||
1, // 37 = handgrenades upgrade
|
||||
1, // 38 = drop jetpack
|
||||
1, // 39 = drop heavy armor
|
||||
|
||||
1, // 40 = infantry portal
|
||||
1, // 41 = marine RT
|
||||
0, // 42 = unused
|
||||
1, // 43 = turret factory
|
||||
0, // 44 = unused
|
||||
1, // 45 = arms lab
|
||||
1, // 46 = proto lab
|
||||
1, // 47 = upgrade
|
||||
1, // 48 = armory
|
||||
1, // 49 = advanced armory
|
||||
|
||||
0, // 50 = unknown
|
||||
1, // 51 = observatory
|
||||
0, // 52 = unknown
|
||||
1, // 53 = scanner sweep
|
||||
0, // 54 = unknown
|
||||
1, // 55 = build phase gate
|
||||
1, // 56 = build turret
|
||||
1, // 57 = build siege turret
|
||||
1, // 58 = build command chair
|
||||
1, // 59 = drop health pack
|
||||
|
||||
1, // 60 = drop ammo pack
|
||||
1, // 61 = drop mine pack
|
||||
1, // 62 = drop welder
|
||||
0, // 63 = unknown
|
||||
1, // 64 = drop shotgun
|
||||
1, // 65 = drop heavymachinegun
|
||||
1, // 66 = drop grenadelauncher
|
||||
0, // 67 = unknown
|
||||
0, // 68 = unknown
|
||||
0, // 69 = unknown
|
||||
|
||||
0, // 70 = unknown
|
||||
0, // 71 = unknown
|
||||
0, // 72 = unknown
|
||||
0, // 73 = unknown
|
||||
0, // 74 = unknown
|
||||
0, // 75 = unknown
|
||||
0, // 76 = unknown
|
||||
0, // 77 = unknown
|
||||
0, // 78 = unknown
|
||||
0, // 79 = unknown
|
||||
|
||||
0, // 80 = radio comm
|
||||
0, // 81 = radio comm
|
||||
1, // 82 = commander message
|
||||
0, // 83 = commander message
|
||||
0, // 84 = commander message
|
||||
0, // 85 = unknown
|
||||
0, // 86 = unknown
|
||||
0, // 87 = unknown
|
||||
0, // 88 = unknown
|
||||
0, // 89 = unknown
|
||||
|
||||
2, // 90 = alienresourcetower
|
||||
2, // 91 = offensechamber
|
||||
2, // 92 = defensechamber
|
||||
2, // 93 = sensorychamber
|
||||
2, // 94 = movementchamber
|
||||
2, // 95 = team_hive
|
||||
0, // 96 = unknown
|
||||
0, // 97 = unknown
|
||||
0, // 98 = unknown
|
||||
0, // 99 = unknown
|
||||
|
||||
0, // 100 = unknown
|
||||
2, // 101 = carapace
|
||||
2, // 102 = regeneration
|
||||
2, // 103 = redemption
|
||||
0, // 104 = unknown
|
||||
1, // 105 = select all marines
|
||||
0, // 106 = unknown
|
||||
2, // 107 = celerity
|
||||
2, // 108 = adrenaline
|
||||
2, // 109 = silence
|
||||
|
||||
2, // 110 = cloaking
|
||||
2, // 111 = focus
|
||||
2, // 112 = scent of fear
|
||||
2, // 113 = skulk
|
||||
2, // 114 = gorge
|
||||
2, // 115 = lerk
|
||||
2, // 116 = fade
|
||||
2, // 117 = onos
|
||||
2, // 118 = unlock next ability (combat)
|
||||
0, // 119 = unknown
|
||||
|
||||
0, // 120 = unknown
|
||||
0, // 121 = unknown
|
||||
0, // 122 = unknown
|
||||
0, // 123 = unknown
|
||||
0, // 124 = unknown
|
||||
0, // 125 = unknown
|
||||
2, // 126 = unlock next ability (combat)
|
||||
0 // 127 = unknown
|
||||
};
|
||||
|
||||
int impulse=Player->GetPev()->impulse;
|
||||
if (impulse < 0 || impulse > 127)
|
||||
{
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
if (impulse==95/*hive*/)
|
||||
{
|
||||
GameMan.ExecuteClientBuilt(Player->index(), UTIL_FindBuildingHive(), StructureTypes[impulse], impulse);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMan.ExecuteClientBuilt(Player->index(), ENTINDEX_NEW(GameMan.GetTemporaryEdict()), StructureTypes[impulse], impulse);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
// We hook newly created entities here.
|
||||
// This is where we check for client_built created entities.
|
||||
edict_t* CreateNamedEntity_Post(int className)
|
||||
{
|
||||
if (GameMan.IsCombat()) // this shouldn't be called during co, just incase
|
||||
{
|
||||
RETURN_META_VALUE(MRES_IGNORED,0);
|
||||
}
|
||||
|
||||
// Incase another plugin supercedes/overrides, use their returned value here.
|
||||
// (Untested).
|
||||
if (gpMetaGlobals->status >= MRES_OVERRIDE)
|
||||
{
|
||||
GameMan.SetTemporaryEdict(META_RESULT_OVERRIDE_RET(edict_t *));
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMan.SetTemporaryEdict(META_RESULT_ORIG_RET(edict_t *));
|
||||
}
|
||||
RETURN_META_VALUE(MRES_IGNORED,0);
|
||||
}
|
||||
|
||||
unsigned short PrecacheEvent_Post(int type, const char *psz)
|
||||
{
|
||||
ParticleMan.PrecacheEvent(psz);
|
||||
RETURN_META_VALUE(MRES_IGNORED,0);
|
||||
}
|
@ -1,487 +0,0 @@
|
||||
#include "ns.h"
|
||||
|
||||
|
||||
#include <sdk_util.h> //useful almost everywhere
|
||||
#include <usercmd.h>
|
||||
#include <entity_state.h>
|
||||
|
||||
CSpawn ns_spawnpoints;
|
||||
CPlayer g_player[33];
|
||||
edict_t *player_edicts[33];
|
||||
|
||||
BOOL CheckForPublic(const char *publicname);
|
||||
|
||||
int gmsgHudText2=0;
|
||||
int ChangeclassForward = -1;
|
||||
int BuiltForward = -1;
|
||||
int SpawnForward = -1;
|
||||
int TeamForward = -1;
|
||||
// Index of last entity hooked in CreateNamedEntity
|
||||
int iCreateEntityIndex;
|
||||
BOOL iscombat;
|
||||
int gmsgScoreInfo=0;
|
||||
|
||||
// Module is attaching to AMXX
|
||||
void OnAmxxAttach()
|
||||
{
|
||||
MF_AddNatives(ns_misc_natives);
|
||||
MF_AddNatives(ns_pdata_natives);
|
||||
}
|
||||
|
||||
// All plugins have loaded (probably around Spawning worldspawn..
|
||||
void OnPluginsLoaded()
|
||||
{
|
||||
|
||||
gmsgHudText2 = GET_USER_MSG_ID(&Plugin_info,"HudText2",NULL);
|
||||
// Check the map name and see if it's combat or not.
|
||||
iscombat=FALSE;
|
||||
char mapname[255];
|
||||
strcpy(mapname,STRING(gpGlobals->mapname));
|
||||
if ((mapname[0]=='c' || mapname[0]=='C') && (mapname[1]=='o' || mapname[1]=='O') && mapname[2]=='_')
|
||||
iscombat=TRUE;
|
||||
|
||||
ChangeclassForward = MF_RegisterForward("client_changeclass", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
// No sense in this if it's combat..
|
||||
if (!iscombat) {
|
||||
if (CheckForPublic("client_built")) {
|
||||
BuiltForward = MF_RegisterForward("client_built", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
g_pengfuncsTable_Post->pfnAlertMessage=AlertMessage_Post;
|
||||
g_pengfuncsTable->pfnCreateNamedEntity=CreateNamedEntity;
|
||||
} else {
|
||||
g_pengfuncsTable_Post->pfnAlertMessage=NULL;
|
||||
g_pengfuncsTable->pfnCreateNamedEntity=NULL;
|
||||
}
|
||||
} else {
|
||||
// no need for these hooks in co
|
||||
g_pengfuncsTable_Post->pfnAlertMessage=NULL;
|
||||
g_pengfuncsTable->pfnCreateNamedEntity=NULL;
|
||||
}
|
||||
SpawnForward = MF_RegisterForward("client_spawn",ET_IGNORE,FP_CELL/*id*/,FP_DONE);
|
||||
TeamForward = MF_RegisterForward("client_changeteam",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*new team*/,FP_CELL/*old team*/,FP_DONE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int DispatchSpawn(edict_t *pEntity)
|
||||
{
|
||||
// Everything starting up:
|
||||
// - Reset CPlayer classes
|
||||
// - Reset CSpawn classes
|
||||
if (FStrEq(STRING(pEntity->v.classname),"worldspawn"))
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<=32;i++)
|
||||
{
|
||||
CPlayer *player = GET_PLAYER_I(i);
|
||||
player->Reset();
|
||||
}
|
||||
ns_spawnpoints.clear();
|
||||
}
|
||||
else if (FStrEq(STRING(pEntity->v.classname),"info_player_start"))
|
||||
{
|
||||
// Mark down the ready room spawn point.
|
||||
ns_spawnpoints.put(0,pEntity->v.origin);
|
||||
}
|
||||
else if (FStrEq(STRING(pEntity->v.classname),"info_team_start"))
|
||||
{
|
||||
// Mark down the team based spawn point.
|
||||
ns_spawnpoints.put(pEntity->v.team,pEntity->v.origin);
|
||||
}
|
||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||
}
|
||||
|
||||
|
||||
void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
|
||||
{
|
||||
// Mark down proper edicts (fixes INDEXENT() bug).
|
||||
// Reset CPlayer classes (again?)
|
||||
for(int i = 1; i <= gpGlobals->maxClients;i++)
|
||||
{
|
||||
player_edicts[i]=pEdictList + i;
|
||||
CPlayer *player = GET_PLAYER_I(i);
|
||||
player->edict=pEdictList + i;
|
||||
//player->index=i;
|
||||
player->pev=&player->edict->v;
|
||||
player->oldimpulse=0;
|
||||
player->Reset();
|
||||
player->connected=false;
|
||||
}
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
void PlayerPreThink(edict_t *pEntity)
|
||||
{
|
||||
CPlayer *player = GET_PLAYER_E(pEntity);
|
||||
player->PreThink();
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
void PlayerPreThink_Post(edict_t *pEntity)
|
||||
{
|
||||
CPlayer *player = GET_PLAYER_E(pEntity);
|
||||
player->PreThink_Post();
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
void PlayerPostThink_Post(edict_t *pEntity)
|
||||
{
|
||||
CPlayer *player = GET_PLAYER_E(pEntity);
|
||||
player->PostThink_Post();
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
|
||||
// Parse log messages here for any desired information (structure_built, etc.)
|
||||
// The following logs are needed:
|
||||
// name<CID><AUTHID><TEAM> triggered "structure_built" (type "type") -- client_built
|
||||
// name<CID><AUTHID><TEAM> changed role to "class" -- client_changeclass
|
||||
void AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...)
|
||||
{
|
||||
if (atype != at_logged)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
va_list LogArg;
|
||||
char *sz, *message;
|
||||
const char *b;
|
||||
char szParm[5][128];
|
||||
int argc,len;
|
||||
va_start(LogArg, szFmt);
|
||||
sz = va_arg(LogArg, char *);
|
||||
va_end(LogArg);
|
||||
message = sz;
|
||||
b=message;
|
||||
argc=0;
|
||||
// Parse the damn message
|
||||
while (*b && *b!='\0' && argc<5)
|
||||
{
|
||||
|
||||
len=0;
|
||||
if (*b == '"')
|
||||
{
|
||||
b++; // Skip over the "
|
||||
while (*b && *b != '"' && len < 127)
|
||||
{
|
||||
szParm[argc][len]=*b;
|
||||
b++;
|
||||
len++;
|
||||
}
|
||||
//*szParm='\0';
|
||||
szParm[argc][len]='\0';
|
||||
if (*b && *b == '"' && *b+1 != '\0' && *b+2 != '\0')
|
||||
{
|
||||
b+=2;
|
||||
argc++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argc++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (*b == '(')
|
||||
{
|
||||
b++; // Skip over the (
|
||||
while (*b && *b != ')' && len < 127)
|
||||
{
|
||||
szParm[argc][len]=*b;
|
||||
b++;
|
||||
len++;
|
||||
}
|
||||
szParm[argc][len]='\0';
|
||||
if (*b && *b == ')' && *b+1 != '\0' && *b+2 != '\0')
|
||||
{
|
||||
b+=2;
|
||||
argc++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argc++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*b && *b != '"' && *b != '(' && len < 127)
|
||||
{
|
||||
szParm[argc][len]=*b;
|
||||
b++;
|
||||
len++;
|
||||
}
|
||||
szParm[argc][len]='\0';
|
||||
if (*b != '"' && *b != '(' && *b != '\0' && *b+1 != '\0' && *b+2 != '\0')
|
||||
{
|
||||
b+=2;
|
||||
argc++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argc++;
|
||||
if (*b == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
if (argc == 3) // changed role to = 3 long
|
||||
{
|
||||
if (FStrEq((const char *)szParm[1],"changed role to "))
|
||||
{
|
||||
int index=LogToIndex(szParm[0]);
|
||||
if (!index)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
CPlayer *player = GET_PLAYER_I(index);
|
||||
int iImpulse=0;
|
||||
int iClass=1;
|
||||
if (INDEXENT2(index)->v.team != 0)
|
||||
{
|
||||
if (FStrEq((const char *)szParm[2],"gestate"))
|
||||
{
|
||||
iImpulse = player->oldpev.impulse;
|
||||
}
|
||||
if (FStrEq((const char *)szParm[2],"none"))
|
||||
iClass=0;
|
||||
if (iClass > 0)
|
||||
{
|
||||
ns2amx_changeclass.execute(index,player->oldpev.iuser3,player->pev->iuser3,iImpulse);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else */
|
||||
if (argc == 4) // structure_built / structure_destroyed are 4 long
|
||||
{
|
||||
//"NAME<CID><AUTH><TEAM>" triggered "structure_built" (type "TYPE")
|
||||
if (FStrEq((const char *)szParm[2],"structure_built"))
|
||||
{
|
||||
int index=LogToIndex(szParm[0]);
|
||||
if (!index)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
CPlayer *player = GET_PLAYER_I(index);
|
||||
|
||||
int iForward=0;
|
||||
int iType=player->pev->impulse;
|
||||
if (FStrEq((const char *)szParm[3],"type \"team_hive\""))
|
||||
{
|
||||
iForward=2;
|
||||
iCreateEntityIndex=Find_Building_Hive();
|
||||
}
|
||||
else if (FStrEq((const char *)szParm[3],"type \"offensechamber\""))
|
||||
{
|
||||
iForward=2;
|
||||
}
|
||||
else if (FStrEq((const char *)szParm[3],"type \"movementchamber\""))
|
||||
{
|
||||
iForward=2;
|
||||
}
|
||||
else if (FStrEq((const char *)szParm[3],"type \"sensorychamber\""))
|
||||
{
|
||||
iForward=2;
|
||||
}
|
||||
else if (FStrEq((const char *)szParm[3],"type \"defensechamber\""))
|
||||
{
|
||||
iForward=2;
|
||||
}
|
||||
else if (FStrEq((const char *)szParm[3],"type \"alienresourcetower\""))
|
||||
{
|
||||
iForward=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
iForward = 1;
|
||||
}
|
||||
// ns2amx_built.execute(index,iCreateEntityIndex,iForward,iType);
|
||||
if (BuiltForward != -1) {
|
||||
MF_ExecuteForward(BuiltForward, index, FStrEq((const char *)szParm[3],"type \"weapon_mine\"") ? 0 : iCreateEntityIndex, iForward, iType);
|
||||
}
|
||||
iCreateEntityIndex=0;
|
||||
}
|
||||
}
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
// We hook newly created entities here.
|
||||
// This is where we check for client_built created entities.
|
||||
edict_t* CreateNamedEntity(int className)
|
||||
{
|
||||
if (iscombat)
|
||||
RETURN_META_VALUE(MRES_IGNORED,0);
|
||||
edict_t *pEntity;
|
||||
// Incase another plugin supercedes/overrides, use their returned value here.
|
||||
// (Untested).
|
||||
if (gpMetaGlobals->status >= MRES_OVERRIDE)
|
||||
{
|
||||
pEntity=META_RESULT_OVERRIDE_RET(edict_t *);
|
||||
iCreateEntityIndex=ENTINDEX(pEntity);
|
||||
RETURN_META_VALUE(MRES_IGNORED, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
pEntity=CREATE_NAMED_ENTITY(className);
|
||||
if (!FNullEnt(pEntity))
|
||||
{
|
||||
iCreateEntityIndex=ENTINDEX(pEntity);
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE,pEntity);
|
||||
}
|
||||
RETURN_META_VALUE(MRES_SUPERCEDE,pEntity);
|
||||
}
|
||||
RETURN_META_VALUE(MRES_IGNORED,false);
|
||||
}
|
||||
|
||||
// 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++)
|
||||
{
|
||||
CPlayer *player = GET_PLAYER_I(i);
|
||||
if (player->connected)
|
||||
player->Disconnect();
|
||||
}
|
||||
ns_spawnpoints.clear();
|
||||
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.
|
||||
CPlayer *player = GET_PLAYER_E(pEntity);
|
||||
player->Connect();
|
||||
RETURN_META_VALUE(MRES_HANDLED,0);
|
||||
}
|
||||
void ClientDisconnect(edict_t *pEntity)
|
||||
{
|
||||
// Client is disconnecting, clear all his saved information.
|
||||
CPlayer *player = GET_PLAYER_E(pEntity);
|
||||
player->Disconnect();
|
||||
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.
|
||||
void UpdateClientData( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd )
|
||||
{
|
||||
edict_t *pEntity = (edict_t*)ent;
|
||||
CPlayer *player = GET_PLAYER_E(pEntity);
|
||||
if (player->foved)
|
||||
pEntity->v.fov = player->fov;
|
||||
|
||||
RETURN_META(MRES_HANDLED);
|
||||
|
||||
}
|
||||
int LogToIndex(char logline[128])
|
||||
{
|
||||
char *cname;
|
||||
// Format of log line:
|
||||
// name<CID><auth><team>
|
||||
// We need to find their ID from their name...
|
||||
int x,y=0;
|
||||
char cindex[64];
|
||||
// first we find the location of the start of the index
|
||||
// Name can contain <>'s, so we go from the end up.
|
||||
for (x=strlen(logline);x>=0;x--)
|
||||
{
|
||||
if (logline[x]=='<')
|
||||
{
|
||||
y++;
|
||||
if (y==3)
|
||||
{
|
||||
y=x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// We found the end of the name, now copy the rest down.
|
||||
y--;
|
||||
x=0;
|
||||
while (x<=y)
|
||||
{
|
||||
cindex[x]=logline[x];
|
||||
x++;
|
||||
}
|
||||
cindex[x]='\0';
|
||||
// Now we have their name, now cycle through all players to find which index it is
|
||||
for (x=1;x<=gpGlobals->maxClients;x++)
|
||||
{
|
||||
cname=strdup(cindex);
|
||||
if (!FNullEnt(INDEXENT2(x)))
|
||||
{
|
||||
if (FStrEq(cname,STRING(INDEXENT2(x)->v.netname)))
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int Find_Building_Hive(void)
|
||||
{
|
||||
edict_t *pEntity=NULL;
|
||||
while ((pEntity = UTIL_FindEntityByString(pEntity,"classname","team_hive")))
|
||||
{
|
||||
if (pEntity->v.health > 0 && pEntity->v.solid > 0 && pEntity->v.fuser1 < 1000)
|
||||
{
|
||||
return ENTINDEX(pEntity);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int AMX_MAKE_STRING(AMX *oPlugin, cell tParam, int &iLength)
|
||||
{
|
||||
char *szNewValue = MF_GetAmxString(oPlugin, tParam, 0, &iLength);
|
||||
return ALLOC_STRING(szNewValue);
|
||||
}
|
||||
|
||||
// Makes a char pointer out of an AMX cell.
|
||||
char *AMX_GET_STRING(AMX *oPlugin, cell tParam, int &iLength)
|
||||
{
|
||||
char *szNewValue = MF_GetAmxString(oPlugin, tParam, 0, &iLength);
|
||||
return (char*)STRING(ALLOC_STRING(szNewValue));
|
||||
}
|
||||
edict_t *UTIL_PlayerByIndexE( int playerIndex )
|
||||
{
|
||||
|
||||
if ( playerIndex > 0 && playerIndex <= gpGlobals->maxClients )
|
||||
{
|
||||
edict_t *pPlayerEdict = INDEXENT2( playerIndex );
|
||||
if ( pPlayerEdict && !pPlayerEdict->free )
|
||||
{
|
||||
return pPlayerEdict;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
edict_t *UTIL_FindEntityByString(edict_t *pentStart, const char *szKeyword, const char *szValue)
|
||||
{
|
||||
edict_t *pentEntity;
|
||||
pentEntity=FIND_ENTITY_BY_STRING(pentStart, szKeyword, szValue);
|
||||
if(!FNullEnt(pentEntity))
|
||||
return pentEntity;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL CheckForPublic(const char *publicname)
|
||||
{
|
||||
AMX* amx;
|
||||
char blah[64];
|
||||
strncpy(blah,publicname,63);
|
||||
int iFunctionIndex;
|
||||
int i=0;
|
||||
// Loop through all running scripts
|
||||
while((amx=MF_GetScriptAmx(i++))!=NULL)
|
||||
{
|
||||
// Scan for public
|
||||
if (MF_AmxFindPublic(amx, blah, &iFunctionIndex) == AMX_ERR_NONE)
|
||||
{
|
||||
// Public was found.
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE; // no public found in any loaded script
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
# Visual C++ Express 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ns", "ns.vcproj", "{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}"
|
||||
EndProject
|
||||
Global
|
||||
|
@ -49,7 +49,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="..\;..\sdk"
|
||||
AdditionalIncludeDirectories="z:\metamod\metamod;z:\hlsdk\common;z:\hlsdk\engine;z:\hlsdk\dlls;z:\hlsdk\pm_shared"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
@ -142,9 +142,8 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/I "
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\;..\sdk"
|
||||
AdditionalIncludeDirectories="z:\metamod\metamod;z:\hlsdk\common;z:\hlsdk\engine;z:\hlsdk\dlls;z:\hlsdk\pm_shared"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
@ -214,36 +213,133 @@
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\CPlayer.cpp"
|
||||
RelativePath="..\amxxapi.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CSpawn.cpp"
|
||||
RelativePath="..\dllapi.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ns_amxx_EXPORTS;$(NoInherit)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ns_amxx_EXPORTS;$(NoInherit)"
|
||||
BasicRuntimeChecks="3"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\engineapi.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\hookedfunctions.cpp"
|
||||
RelativePath="..\GameManager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\NMisc.cpp"
|
||||
RelativePath="..\MessageHandler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\NPData.cpp"
|
||||
RelativePath="..\ParticleManager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\TitleManager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\utils.cpp"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Natives"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\natives\general.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives\memberfuncs.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives\particles.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives\player.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives\player_memory.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives\structure.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives\weapons.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\AllocString.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CPlayer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CSpawn.h"
|
||||
RelativePath="..\CString.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVector.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\FastDelegate.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\GameManager.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Hash.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\LocationManager.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\MessageHandler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\NEW_Util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -255,11 +351,19 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\plugin.h"
|
||||
RelativePath="..\ParticleManager.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\svn_version.h"
|
||||
RelativePath="..\sh_list.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\SpawnManager.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\TitleManager.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -268,14 +372,7 @@
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Module SDK"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\sdk\moduleconfig.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="SDK Base"
|
||||
Name="sdk"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\sdk\amxxmodule.cpp"
|
||||
@ -285,22 +382,8 @@
|
||||
RelativePath="..\sdk\amxxmodule.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Pawn Includes"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\plugins\include\ns.inc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\plugins\include\ns2amx.inc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\plugins\include\ns_const.inc"
|
||||
RelativePath="..\sdk\moduleconfig.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
|
553
dlls/ns/natives/general.cpp
Normal file
553
dlls/ns/natives/general.cpp
Normal file
@ -0,0 +1,553 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "cbase.h" // TakeDamage
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../GameManager.h"
|
||||
#include "../SpawnManager.h"
|
||||
#include "../LocationManager.h"
|
||||
#include "../TitleManager.h"
|
||||
|
||||
#include "../CPlayer.h"
|
||||
|
||||
|
||||
edict_t* avhgameplay=NULL;
|
||||
|
||||
// drop-in replacement for user_kill
|
||||
static cell AMX_NATIVE_CALL ns_user_kill(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
// 2 is commander, never slay commander
|
||||
if (player->GetPev()->iuser3 == 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (MF_IsPlayerIngame(params[1]) && MF_IsPlayerAlive(params[1]))
|
||||
{
|
||||
REAL bef = player->GetPev()->frags;
|
||||
|
||||
edict_t *pEntity = CREATE_NAMED_ENTITY(MAKE_STRING("trigger_hurt"));
|
||||
|
||||
if (pEntity)
|
||||
{
|
||||
KeyValueData kvd;
|
||||
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="classname";
|
||||
kvd.szValue="trigger_hurt";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="dmg";
|
||||
kvd.szValue="50000.0";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="damagetype";
|
||||
kvd.szValue="1";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="origin";
|
||||
kvd.szValue="8192 8192 8192";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
|
||||
MDLL_Spawn(pEntity);
|
||||
|
||||
pEntity->v.classname=MAKE_STRING("slay");
|
||||
|
||||
MDLL_Touch(pEntity,player->GetEdict());
|
||||
|
||||
REMOVE_ENTITY(pEntity);
|
||||
}
|
||||
|
||||
// If the optional parameter is 1, restore the frag count
|
||||
if (params[2])
|
||||
{
|
||||
player->GetPev()->frags = bef;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// drop-in replacement for user_slap
|
||||
#define ANGLEVECTORS (*g_engfuncs.pfnAngleVectors)
|
||||
static cell AMX_NATIVE_CALL ns_user_slap(AMX *amx, cell *params) /* 2 param */
|
||||
{
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
int power = abs((int)params[2]);
|
||||
|
||||
// Check if commander, if player is comm then stop
|
||||
if (player->GetPev()->iuser3 == 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (MF_IsPlayerIngame(player->index()) && MF_IsPlayerAlive(player->index()))
|
||||
{
|
||||
if (player->GetPev()->health <= power)
|
||||
{
|
||||
float bef = player->GetPev()->frags;
|
||||
/*MDLL_ClientKill(pPlayer->pEdict);*/
|
||||
edict_t *pEntity = CREATE_NAMED_ENTITY(MAKE_STRING("trigger_hurt"));
|
||||
if (pEntity)
|
||||
{
|
||||
KeyValueData kvd;
|
||||
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="classname";
|
||||
kvd.szValue="trigger_hurt";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="dmg";
|
||||
kvd.szValue="20000.0";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="damagetype";
|
||||
kvd.szValue="1";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
|
||||
kvd.szClassName="trigger_hurt";
|
||||
kvd.szKeyName="origin";
|
||||
kvd.szValue="8192 8192 8192";
|
||||
kvd.fHandled=0;
|
||||
MDLL_KeyValue(pEntity,&kvd);
|
||||
|
||||
MDLL_Spawn(pEntity);
|
||||
|
||||
pEntity->v.classname=MAKE_STRING("slap");
|
||||
|
||||
MDLL_Touch(pEntity,player->GetEdict());
|
||||
|
||||
REMOVE_ENTITY(pEntity);
|
||||
}
|
||||
|
||||
player->GetPev()->frags = bef;
|
||||
}
|
||||
else
|
||||
{
|
||||
int numparam = *params/sizeof(cell);
|
||||
if (numparam<3 || params[3])
|
||||
{
|
||||
player->GetPev()->velocity.x += RANDOM_LONG(-600,600);
|
||||
player->GetPev()->velocity.y += RANDOM_LONG(-180,180);
|
||||
player->GetPev()->velocity.z += RANDOM_LONG(100,200);
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3_t v_forward, v_right;
|
||||
vec3_t vang = player->GetPev()->angles;
|
||||
float fang[3];
|
||||
fang[0] = vang.x;
|
||||
fang[1] = vang.y;
|
||||
fang[2] = vang.z;
|
||||
ANGLEVECTORS( fang, v_forward, v_right, NULL );
|
||||
player->GetPev()->velocity = player->GetPev()->velocity + v_forward * 220 + Vector(0,0,200);
|
||||
}
|
||||
player->GetPev()->punchangle.x = RANDOM_LONG(-10,10);
|
||||
player->GetPev()->punchangle.y = RANDOM_LONG(-10,10);
|
||||
|
||||
player->GetPev()->health -= power;
|
||||
|
||||
int armor = (int)player->GetPev()->armorvalue;
|
||||
armor -= power;
|
||||
|
||||
if (armor < 0)
|
||||
{
|
||||
armor = 0;
|
||||
}
|
||||
|
||||
player->GetPev()->armorvalue = armor;
|
||||
|
||||
player->GetPev()->dmg_inflictor = player->GetEdict();
|
||||
|
||||
static const char *bit_sound[3] = {
|
||||
"weapons/cbar_hitbod1.wav",
|
||||
"weapons/cbar_hitbod2.wav",
|
||||
"weapons/cbar_hitbod3.wav"
|
||||
};
|
||||
|
||||
EMIT_SOUND_DYN2(player->GetEdict(), CHAN_VOICE, bit_sound[RANDOM_LONG(0,2)], 1.0, ATTN_NORM, 0, PITCH_NORM);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// native ns_get_locationname(Float:x, Float:y, name[], len, lookup=0);
|
||||
static cell AMX_NATIVE_CALL ns_get_locationname(AMX *amx, cell *params)
|
||||
{
|
||||
vec3_t location;
|
||||
|
||||
|
||||
location.x=amx_ctof2(params[1]);
|
||||
location.y=amx_ctof2(params[2]);
|
||||
|
||||
if ((params[0] / sizeof(cell)) >= 5)
|
||||
{
|
||||
return MF_SetAmxString(amx,params[3],LocationMan.Lookup(location,params[5]),params[4]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MF_SetAmxString(amx,params[3],LocationMan.Lookup(location,0),params[4]);
|
||||
}
|
||||
}
|
||||
// ns_lookup_title(const Key[], Output[], Size)
|
||||
static cell AMX_NATIVE_CALL ns_lookup_title(AMX *amx, cell *params)
|
||||
{
|
||||
// FIX: some keys have upper case characters; to fix i store all keys as lower case
|
||||
String Input(MF_GetAmxString(amx,params[1],0,NULL));
|
||||
|
||||
Input.toLower();
|
||||
|
||||
const char *Output=TitleMan.Lookup(Input);
|
||||
|
||||
if (Output==NULL) // not found
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return MF_SetAmxString(amx,params[2],Output,params[3]);
|
||||
};
|
||||
// ns_round_in_progress()
|
||||
static cell AMX_NATIVE_CALL ns_round_in_progress(AMX *amx, cell *params)
|
||||
{
|
||||
return GameMan.RoundInProgress();
|
||||
}
|
||||
// ns_get_spawn(team,number=0,Float:ret[3])
|
||||
static cell AMX_NATIVE_CALL ns_get_spawn(AMX *amx, cell *params)
|
||||
{
|
||||
return SpawnMan.Lookup(amx,params);
|
||||
}
|
||||
// ns_get_mask(id,MASK_*)
|
||||
static cell AMX_NATIVE_CALL ns_get_mask(AMX *amx, cell *params)
|
||||
{
|
||||
CreateEdict(amx,params[1],-1);
|
||||
|
||||
if (Entity->v.iuser4 & static_cast<int>(params[2]))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// ns_set_mask(id,MASK_*,1 or 0)
|
||||
static cell AMX_NATIVE_CALL ns_set_mask(AMX *amx, cell *params)
|
||||
{
|
||||
CreateEdict(amx,params[1],-1);
|
||||
|
||||
if (static_cast<int>(params[3]) > 0)
|
||||
{
|
||||
if (Entity->v.iuser4 & static_cast<int>(params[2]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Entity->v.iuser4 |= static_cast<int>(params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Entity->v.iuser4 & static_cast<int>(params[2]))
|
||||
{
|
||||
Entity->v.iuser4 &= ~static_cast<int>(params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// ns_popup(id (0 for all),"text",OnlyShowWithCLHelpOn=0)
|
||||
static cell AMX_NATIVE_CALL ns_popup(AMX *amx, cell *params)
|
||||
{
|
||||
GameMan.UpdateHudText2();
|
||||
|
||||
if (params[1])
|
||||
{
|
||||
CreatePlayerPointer(amx, params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE,GameMan.GetHudText2(),NULL,player->GetEdict());
|
||||
}
|
||||
else
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ALL,GameMan.GetHudText2());
|
||||
}
|
||||
|
||||
char msg[190];
|
||||
strncpy(&msg[0],MF_GetAmxString(amx,params[2],0,NULL),188);
|
||||
|
||||
WRITE_STRING(msg);
|
||||
WRITE_BYTE(params[3]);
|
||||
|
||||
MESSAGE_END();
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ns_is_combat()
|
||||
static cell AMX_NATIVE_CALL ns_is_combat(AMX *amx, cell *params)
|
||||
{
|
||||
return GameMan.IsCombat();
|
||||
}
|
||||
/**
|
||||
* Pretty much a direct port of CheezyPeteza's unstick routine
|
||||
* from the old unstuck.amxx plugin. This is included here
|
||||
* to remove the engine requirement.
|
||||
* -
|
||||
* Return values:
|
||||
* 1 success
|
||||
* 0 no spot to move to
|
||||
* -1 invalid state (stunned/webbed)
|
||||
* -2 invalid class (commander/gorge)
|
||||
* -3 player is dead or a spectator
|
||||
* -4 player is invalid (unknown)
|
||||
* -5 player is invalid (disconnected)
|
||||
*/
|
||||
|
||||
inline int GetPlayerHullSize(CPlayer *Player, int PlayerClass)
|
||||
{
|
||||
switch (PlayerClass)
|
||||
{
|
||||
case CLASS_SKULK:
|
||||
case CLASS_GORGE:
|
||||
case CLASS_LERK:
|
||||
return static_cast<int>(head_hull);
|
||||
|
||||
case CLASS_FADE:
|
||||
case CLASS_JETPACK:
|
||||
case CLASS_HEAVY:
|
||||
case CLASS_MARINE:
|
||||
if (Player->GetPev()->button & IN_DUCK || Player->GetPev()->flags & FL_DUCKING)
|
||||
{
|
||||
return static_cast<int>(head_hull);
|
||||
}
|
||||
|
||||
return static_cast<int>(human_hull);
|
||||
|
||||
case CLASS_ONOS:
|
||||
if (Player->GetPev()->button & IN_DUCK || Player->GetPev()->flags & FL_DUCKING)
|
||||
{
|
||||
return static_cast<int>(human_hull);
|
||||
}
|
||||
|
||||
return static_cast<int>(large_hull);
|
||||
|
||||
default:
|
||||
return -1;
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_unstick_player(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (player->GetPev()->iuser4 & (MASK_ENSNARED | MASK_PLAYER_STUNNED))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int PlayerClass=player->GetClass();
|
||||
if (PlayerClass == CLASS_GESTATE || PlayerClass == CLASS_COMMANDER)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (PlayerClass == CLASS_DEAD || PlayerClass == CLASS_NOTEAM || PlayerClass == CLASS_UNKNOWN)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
|
||||
int HullSize=GetPlayerHullSize(player, PlayerClass);
|
||||
|
||||
|
||||
if (HullSize==-1)
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
|
||||
Vector OriginalOrigin=player->GetPev()->origin;
|
||||
|
||||
Vector NewOrigin;
|
||||
int Distance=params[2];
|
||||
int Attempts;
|
||||
TraceResult Result;
|
||||
|
||||
while (Distance < 1000)
|
||||
{
|
||||
Attempts=params[3];
|
||||
|
||||
while (Attempts--)
|
||||
{
|
||||
NewOrigin.x = RANDOM_FLOAT(OriginalOrigin.x - Distance,OriginalOrigin.x + Distance);
|
||||
NewOrigin.y = RANDOM_FLOAT(OriginalOrigin.y - Distance,OriginalOrigin.y + Distance);
|
||||
NewOrigin.z = RANDOM_FLOAT(OriginalOrigin.z - Distance,OriginalOrigin.z + Distance);
|
||||
|
||||
// (const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr);
|
||||
TRACE_HULL(NewOrigin, NewOrigin, 0, HullSize, player->GetEdict(), &Result);
|
||||
|
||||
if (Result.fInOpen && !Result.fAllSolid && !Result.fStartSolid)
|
||||
{
|
||||
SET_ORIGIN(player->GetEdict(),NewOrigin);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Distance += params[2];
|
||||
}
|
||||
|
||||
|
||||
return 0; // Couldn't be found
|
||||
}
|
||||
// Type: 131072 = DoT
|
||||
// ns_takedamage
|
||||
static cell AMX_NATIVE_CALL ns_takedamage(AMX *amx, cell *params)
|
||||
{
|
||||
// NASTY
|
||||
// Reinterprets pvPrivateData as CBaseEntity, then calls TakeDamage with the entvar of Inflictor, and Attacker, with the float value and damage type
|
||||
// The NS offset of TakeDamage hasn't changed from the HLSDK fortunately, so no offset digging is necessary
|
||||
return (reinterpret_cast<CBaseEntity *>(INDEXENT_NEW(params[1])->pvPrivateData))->TakeDamage(&(INDEXENT_NEW(params[2])->v),&(INDEXENT_NEW(params[3])->v),amx_ctof2(params[4]),static_cast<int>(params[5]));
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_gameplay(AMX* amx, cell* params)
|
||||
{
|
||||
if (avhgameplay == NULL)
|
||||
{
|
||||
avhgameplay = FIND_ENTITY_BY_CLASSNAME(NULL, "avhgameplay");
|
||||
}
|
||||
if (avhgameplay == NULL ||
|
||||
avhgameplay->pvPrivateData == NULL) // Still null? Get out of here
|
||||
{
|
||||
return NSGame_CantTell;
|
||||
}
|
||||
|
||||
int ATeam /* i pity da foo */ = *reinterpret_cast<int*>(reinterpret_cast<char*>(avhgameplay->pvPrivateData) + MAKE_OFFSET(GAMEPLAY_TEAMA));
|
||||
int BTeam = *reinterpret_cast<int*>(reinterpret_cast<char*>(avhgameplay->pvPrivateData) + MAKE_OFFSET(GAMEPLAY_TEAMB));
|
||||
|
||||
if (ATeam == 2 && // alien
|
||||
BTeam == 2) // alien
|
||||
{
|
||||
return NSGame_AlienVAlien;
|
||||
}
|
||||
if (ATeam == 1 && // marine
|
||||
BTeam == 1) // marine
|
||||
{
|
||||
return NSGame_MarineVMarine;
|
||||
}
|
||||
if (ATeam == 1 && // marine
|
||||
BTeam == 2) // alien
|
||||
{
|
||||
return NSGame_MarineVAlien;
|
||||
}
|
||||
return NSGame_Unknown;
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEVELOPER_BUILD
|
||||
static cell AMX_NATIVE_CALL refmem(AMX *amx, cell *params)
|
||||
{
|
||||
return *(reinterpret_cast<int *>(params[1]));
|
||||
};
|
||||
static cell AMX_NATIVE_CALL setmem(AMX *amx, cell *params)
|
||||
{
|
||||
int *ptr=reinterpret_cast<int *>(params[1]);
|
||||
|
||||
*ptr=params[2];
|
||||
|
||||
return 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
AMX_NATIVE_INFO general_natives[] = {
|
||||
|
||||
{ "user_kill", ns_user_kill }, // replacement natives
|
||||
{ "user_slap", ns_user_slap }, // since ClientKill is changed in NS
|
||||
|
||||
{ "ns_get_locationname", ns_get_locationname },
|
||||
{ "ns_lookup_title", ns_lookup_title },
|
||||
{ "ns_round_in_progress", ns_round_in_progress },
|
||||
{ "ns_get_spawn", ns_get_spawn },
|
||||
{ "ns_get_mask", ns_get_mask },
|
||||
{ "ns_set_mask", ns_set_mask },
|
||||
{ "ns_is_combat", ns_is_combat },
|
||||
{ "ns_unstick_player", ns_unstick_player },
|
||||
|
||||
{ "ns_popup", ns_popup },
|
||||
|
||||
{ "ns_takedamage", ns_takedamage},
|
||||
|
||||
{ "ns_get_gameplay", ns_get_gameplay },
|
||||
|
||||
#ifdef DEVELOPER_BUILD
|
||||
{ "refmem", refmem },
|
||||
{ "setmem", setmem },
|
||||
#endif
|
||||
|
||||
{ NULL, NULL }
|
||||
|
||||
};
|
||||
void AddNatives_General()
|
||||
{
|
||||
MF_AddNatives(general_natives);
|
||||
}
|
275
dlls/ns/natives/memberfuncs.cpp
Normal file
275
dlls/ns/natives/memberfuncs.cpp
Normal file
@ -0,0 +1,275 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
#include "../ns_const.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
|
||||
#include "../FastDelegate.h"
|
||||
#include "../GameManager.h"
|
||||
|
||||
extern int IsValidBuilding[AVH_USER3_MAX + 1];
|
||||
|
||||
using namespace fastdelegate::detail;
|
||||
|
||||
|
||||
void *GameRules=NULL;
|
||||
|
||||
|
||||
mBOOL dlclose_handle_invalid; // Linking errors with metamod
|
||||
|
||||
// void AvHBaseBuildable::StartRecycle()
|
||||
static void (GenericClass::*MFP_Recycle)();
|
||||
|
||||
// void AvHWeldable::AddBuildTime(float)
|
||||
static void (GenericClass::*MFP_WeldFinished)(float);
|
||||
|
||||
// AvHGameRules *GetGameRules(void)
|
||||
static void *(*FP_GetGameRules)();
|
||||
|
||||
|
||||
char *FuncBase;
|
||||
|
||||
/**
|
||||
* sizeof(void (detail::GenericClass::*fptr)())
|
||||
* is 8 in GCC. Add an empty void * pointer at
|
||||
* the end to compensate.
|
||||
* Layout in GCC:
|
||||
* union {
|
||||
* void *address; // When this is an address it will always be positive
|
||||
* int vtable_index; // When it is a vtable index it will always be odd = (vindex*2)+1
|
||||
* };
|
||||
* int delta;
|
||||
* -
|
||||
* Delta is the adjustment to the this pointer
|
||||
* For my implementations I will only need it to 0
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
template <typename OutType>
|
||||
inline void set_mfp(OutType &out, void *in)
|
||||
{
|
||||
union
|
||||
{
|
||||
void *in[2];
|
||||
OutType out;
|
||||
} mfpu;
|
||||
|
||||
mfpu.in[0]=in;
|
||||
mfpu.in[1]=NULL;
|
||||
out=mfpu.out;
|
||||
};
|
||||
#else
|
||||
template <typename OutType>
|
||||
inline void set_mfp(OutType &out, void *in)
|
||||
{
|
||||
out=horrible_cast<OutType>(in);
|
||||
};
|
||||
#endif
|
||||
|
||||
void MFuncs_Initialize(void)
|
||||
{
|
||||
char FileName[256];
|
||||
DLHANDLE DLLBase;
|
||||
#ifdef __linux__
|
||||
snprintf(FileName,sizeof(FileName)-1,"%s/dlls/ns_i386.so",MF_GetModname());
|
||||
#else
|
||||
snprintf(FileName,sizeof(FileName)-1,"%s\\dlls\\ns.dll",MF_GetModname());
|
||||
#endif
|
||||
|
||||
DLLBase=DLOPEN(FileName);
|
||||
FuncBase=(char *)DLSYM(DLLBase, MAKE_OFFSET(BASE));
|
||||
DLCLOSE(DLLBase);
|
||||
|
||||
#define MFP(Offs) (((void *)(((char *)FuncBase)+MAKE_OFFSET(Offs))))
|
||||
|
||||
set_mfp(MFP_Recycle,MFP(MEMBER_RECYCLE));
|
||||
|
||||
set_mfp(MFP_WeldFinished,MFP(MEMBER_TRIGGER_WELDABLE));
|
||||
|
||||
// This is not a member function pointer, but use MFP since it
|
||||
// uses the same address conversion as MFPs do
|
||||
FP_GetGameRules=horrible_cast<void *(*)()>(MFP(GETGAMERULES));
|
||||
};
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_recycle(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->free || Entity->pvPrivateData==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Entity->v.iuser3 <= AVH_USER3_NONE || Entity->v.iuser3 >= AVH_USER3_MAX)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (IsValidBuilding[Entity->v.iuser3]!=1) // Not a marine structure?
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make sure it's a marine building, undefined stuff happens on alien structures
|
||||
(reinterpret_cast<GenericClass *>(Entity->pvPrivateData)->*(MFP_Recycle))();
|
||||
|
||||
|
||||
return 1;
|
||||
};
|
||||
static cell AMX_NATIVE_CALL ns_finish_weldable(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->free || Entity->pvPrivateData==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// verify the classname since this will crash if it's the wrong class!
|
||||
if (strcmp(STRING(Entity->v.classname),"avhweldable")!=0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// First need to set the weldable to 100% complete
|
||||
set_private_f(Entity,MAKE_OFFSET(WELD_DONE),get_private_f(Entity,MAKE_OFFSET(WELD_TIME)));
|
||||
|
||||
// Now make NS think the weldable has been welded again
|
||||
// This has to call AvHWeldable::AddBuildTime(float)
|
||||
// because AvHWeldable::TriggerFinished() does not work properly
|
||||
(reinterpret_cast<GenericClass *>(Entity->pvPrivateData)->*(MFP_WeldFinished))(100.0);
|
||||
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_teamres(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (GameRules==NULL) // GameRules not initialized yet
|
||||
{
|
||||
GameRules=(*(FP_GetGameRules))();
|
||||
}
|
||||
if (GameRules==NULL) // Still null? Get out of here
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
switch(params[1])
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
return amx_ftoc2(*(REAL *)((char *)GameRules+GAMERULES_TEAMA_RESOURCES));
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return amx_ftoc2(*(REAL *)((char *)GameRules+GAMERULES_TEAMB_RESOURCES));
|
||||
}
|
||||
default:
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "ns_get_teamres: Expected 1 for team a or 2 for team b, got %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_teamres(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (GameRules==NULL) // GameRules not initialized yet
|
||||
{
|
||||
GameRules=(*(FP_GetGameRules))();
|
||||
}
|
||||
if (GameRules==NULL) // Still null? Get out of here
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
switch(params[1])
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
*(REAL *)((char *)GameRules+GAMERULES_TEAMA_RESOURCES)=amx_ctof2(params[2]);
|
||||
return 1;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
*(REAL *)((char *)GameRules+GAMERULES_TEAMB_RESOURCES)=amx_ctof2(params[2]);
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "ns_set_teamres: Expected 1 for team a or 2 for team b, got %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_teamres(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (GameRules==NULL) // GameRules not initialized yet
|
||||
{
|
||||
GameRules=(*(FP_GetGameRules))();
|
||||
}
|
||||
if (GameRules==NULL) // Still null? Get out of here
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
switch(params[1])
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
return amx_ftoc2(*(REAL *)((char *)GameRules+GAMERULES_TEAMA_RESOURCES)+=amx_ctof2(params[2]));
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return amx_ftoc2(*(REAL *)((char *)GameRules+GAMERULES_TEAMB_RESOURCES)+=amx_ctof2(params[2]));
|
||||
}
|
||||
default:
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "ns_add_teamres: Expected 1 for team a or 2 for team b, got %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEVELOPER_BUILD
|
||||
static cell AMX_NATIVE_CALL findgameinfo(AMX *amx, cell *params)
|
||||
{
|
||||
void *Ret=(*(FP_GetGameRules))();
|
||||
union
|
||||
{
|
||||
void *v;
|
||||
int i;
|
||||
}vi;
|
||||
vi.v=Ret;
|
||||
|
||||
printf("GameRules=%d\n",vi.i);
|
||||
return 1;
|
||||
};
|
||||
#endif
|
||||
AMX_NATIVE_INFO memberfunc_natives[] = {
|
||||
#ifdef DEVELOPER_BUILD
|
||||
{ "getgameinfo", findgameinfo },
|
||||
#endif
|
||||
{ "ns_recycle", ns_recycle },
|
||||
{ "ns_finish_weldable", ns_finish_weldable },
|
||||
{ "ns_get_teamres", ns_get_teamres },
|
||||
{ "ns_set_teamres", ns_set_teamres },
|
||||
{ "ns_add_teamres", ns_add_teamres },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void AddNatives_MemberFunc()
|
||||
{
|
||||
MF_AddNatives(memberfunc_natives);
|
||||
};
|
276
dlls/ns/natives/particles.cpp
Normal file
276
dlls/ns/natives/particles.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../CVector.h"
|
||||
#include "../CString.h"
|
||||
#include "../ParticleManager.h"
|
||||
|
||||
#define KVI(__KEY) PSKeyValueI(__KEY,amx,params)
|
||||
#define KVF(__KEY) PSKeyValueF(__KEY,amx,params)
|
||||
#define KVS(__KEY) PSKeyValueS(__KEY,amx,params)
|
||||
#define NEXT params[__pcount++]
|
||||
|
||||
typedef enum partsystype_e
|
||||
{
|
||||
PSYS_TYPE_INT,
|
||||
PSYS_TYPE_FLOAT,
|
||||
PSYS_TYPE_STRING
|
||||
}partsystype;
|
||||
typedef struct partsyskey_s
|
||||
{
|
||||
const char *Name;
|
||||
partsystype type;
|
||||
}partsyskey;
|
||||
|
||||
cell PSKeyValueI(char *name, AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1]==0)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Invalid particle system handle provided!");
|
||||
return 0;
|
||||
}
|
||||
KeyValueData kvd;
|
||||
|
||||
char StrData[1024];
|
||||
|
||||
snprintf(StrData,sizeof(StrData)-1,"%d",params[2]);
|
||||
|
||||
kvd.szClassName=const_cast<char *>(STRING(reinterpret_cast<edict_t *>(params[1])->v.classname));
|
||||
kvd.szKeyName=name;
|
||||
kvd.szValue=&StrData[0];
|
||||
kvd.fHandled=0;
|
||||
//printf("\"%s\" \"%s\"\n",kvd.szKeyName,kvd.szValue);
|
||||
|
||||
MDLL_KeyValue(reinterpret_cast<edict_t *>(params[1]),&kvd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
cell PSKeyValueF(char *name, AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1]==0)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Invalid particle system handle provided!");
|
||||
return 0;
|
||||
}
|
||||
KeyValueData kvd;
|
||||
|
||||
char StrData[1024];
|
||||
|
||||
snprintf(StrData,sizeof(StrData)-1,"%f",amx_ctof2(params[2]));
|
||||
|
||||
kvd.szClassName=const_cast<char *>(STRING(reinterpret_cast<edict_t *>(params[1])->v.classname));
|
||||
kvd.szKeyName=name;
|
||||
kvd.szValue=&StrData[0];
|
||||
kvd.fHandled=0;
|
||||
|
||||
//printf("\"%s\" \"%s\"\n",kvd.szKeyName,kvd.szValue);
|
||||
|
||||
MDLL_KeyValue(reinterpret_cast<edict_t *>(params[1]),&kvd);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
cell PSKeyValueS(char *name, AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1]==0)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Invalid particle system handle provided!");
|
||||
return 0;
|
||||
}
|
||||
KeyValueData kvd;
|
||||
|
||||
kvd.szClassName=const_cast<char *>(STRING(reinterpret_cast<edict_t *>(params[1])->v.classname));
|
||||
kvd.szKeyName=name;
|
||||
kvd.szValue=MF_GetAmxString(amx,params[2],0,NULL);
|
||||
kvd.fHandled=0;
|
||||
//printf("\"%s\" \"%s\"\n",kvd.szKeyName,kvd.szValue);
|
||||
|
||||
MDLL_KeyValue(reinterpret_cast<edict_t *>(params[1]),&kvd);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_name(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("targetname");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_sprite(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pSprite");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_genrate(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pGenRate");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_genshape(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pGenShape");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_genshape_params(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pGenShapeParams");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_spriteframes(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pSpriteNumFrames");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_numparticles(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pNumParticles");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_size(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pSize");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_vel_params(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pVelParams");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_vel_shape(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pVelShape");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_sys_life(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pSystemLifetime");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_particle_life(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pLifetime");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_rendermode(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pRenderMode");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_to_gen(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pPSToGen");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_anim_speed(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pAnimationSpeed");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_spawn_flags(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("spawnflags");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_base_color(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pBaseColor");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_scale(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pScale");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_max_alpha(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pMaxAlpha");
|
||||
}
|
||||
// ns_create_partsys(const name[], pGenShape, const pGenShapeParams[], pGenRate, const pSprite[],
|
||||
// pSpriteFrames, pNumParticles, Float:pSize, const pVelParams[], pVelShape,
|
||||
// Float:pSystemLifetime, Float:pParticleLifetime, pRenderMode, const pPSToGen[], pAnimationSpeed, pSpawnFlags)
|
||||
static cell AMX_NATIVE_CALL ns_create_partsys(AMX *amx, cell *params)
|
||||
{
|
||||
return (cell)CREATE_NAMED_ENTITY(MAKE_STRING("env_particles_custom"));
|
||||
};
|
||||
static cell AMX_NATIVE_CALL ns_spawn_ps(AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1]==0)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid particle system handle");
|
||||
return 0;
|
||||
}
|
||||
|
||||
edict_t *Ent=reinterpret_cast<edict_t *>(params[1]);
|
||||
MDLL_Spawn(Ent);
|
||||
|
||||
if (!Ent->free)
|
||||
{
|
||||
REMOVE_ENTITY(Ent);
|
||||
}
|
||||
return ParticleMan.Add(STRING(Ent->v.targetname),0);
|
||||
}
|
||||
// ns_fire_ps(Particle:id,Float:origin[3],Float:angles[3],flags=0)
|
||||
static cell AMX_NATIVE_CALL ns_fire_partsys(AMX *amx, cell *params)
|
||||
{
|
||||
float *origin=(float*)MF_GetAmxAddr(amx,params[2]);
|
||||
float *angles=(float*)MF_GetAmxAddr(amx,params[3]);
|
||||
|
||||
ParticleMan.FireSystem(static_cast<int>(params[1]),origin,angles,static_cast<int>(params[4]));
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_partsys_id(AMX *amx, cell *params)
|
||||
{
|
||||
return ParticleMan.Find(MF_GetAmxString(amx,params[1],0,NULL));;
|
||||
};
|
||||
|
||||
AMX_NATIVE_INFO particle_natives[] = {
|
||||
{ "ns_create_ps", ns_create_partsys },
|
||||
{ "ns_set_ps_name", ns_set_ps_name },
|
||||
{ "ns_set_ps_sprite", ns_set_ps_sprite },
|
||||
{ "ns_set_ps_genrate", ns_set_ps_genrate },
|
||||
{ "ns_set_ps_genshape", ns_set_ps_genshape },
|
||||
{ "ns_set_ps_genshape_params", ns_set_ps_genshape_params },
|
||||
{ "ns_set_ps_spriteframes", ns_set_ps_spriteframes },
|
||||
{ "ns_set_ps_numparticles", ns_set_ps_numparticles },
|
||||
{ "ns_set_ps_size", ns_set_ps_size },
|
||||
{ "ns_set_ps_vel_params", ns_set_ps_vel_params },
|
||||
{ "ns_set_ps_vel_shape", ns_set_ps_vel_shape },
|
||||
{ "ns_set_ps_sys_life", ns_set_ps_sys_life },
|
||||
{ "ns_set_ps_particle_life", ns_set_ps_particle_life },
|
||||
{ "ns_set_ps_rendermode", ns_set_ps_rendermode },
|
||||
{ "ns_set_ps_to_gen", ns_set_ps_to_gen },
|
||||
{ "ns_set_ps_anim_speed", ns_set_ps_anim_speed },
|
||||
{ "ns_set_ps_spawn_flags", ns_set_ps_spawn_flags },
|
||||
{ "ns_set_ps_base_color", ns_set_ps_base_color },
|
||||
{ "ns_set_ps_scale", ns_set_ps_scale },
|
||||
{ "ns_set_ps_max_alpha", ns_set_ps_max_alpha },
|
||||
{ "ns_spawn_ps", ns_spawn_ps },
|
||||
|
||||
{ "ns_fire_ps", ns_fire_partsys },
|
||||
{ "ns_get_ps_id", ns_get_partsys_id },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_Particles()
|
||||
{
|
||||
MF_AddNatives(particle_natives);
|
||||
}
|
222
dlls/ns/natives/player.cpp
Normal file
222
dlls/ns/natives/player.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../GameManager.h"
|
||||
#include "../CPlayer.h"
|
||||
|
||||
#include "../AllocString.h"
|
||||
|
||||
StringManager AllocStringList;
|
||||
|
||||
// ns_set_player_model(id,const Model[]="")
|
||||
static cell AMX_NATIVE_CALL ns_set_player_model(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
player->SetModel(MF_GetAmxString(amx,params[2],0,NULL));
|
||||
|
||||
GameMan.HookPostThink_Post();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ns_set_player_skin(id,skin=-1)
|
||||
static cell AMX_NATIVE_CALL ns_set_player_skin(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
player->SetSkin(params[2]);
|
||||
|
||||
GameMan.HookPostThink_Post();
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ns_set_player_body(id,body=-1)
|
||||
static cell AMX_NATIVE_CALL ns_set_player_body(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
player->SetBody(params[2]);
|
||||
|
||||
GameMan.HookPostThink_Post();
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ns_get_class(id)
|
||||
static cell AMX_NATIVE_CALL ns_get_class(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
return player->GetClass();
|
||||
}
|
||||
// ns_get_jpfuel(id)
|
||||
static cell AMX_NATIVE_CALL ns_get_jpfuel(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
REAL ret=(player->GetPev()->fuser3) / 10.0;
|
||||
|
||||
return amx_ftoc2(ret);
|
||||
}
|
||||
// ns_set_jpfuel(id,Float:fuelpercent)
|
||||
static cell AMX_NATIVE_CALL ns_set_jpfuel(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
REAL fuel = amx_ctof2(params[2]);
|
||||
if (fuel > 100.0)
|
||||
{
|
||||
fuel = 100.0;
|
||||
}
|
||||
if (fuel < 0.0)
|
||||
{
|
||||
fuel = 0.0;
|
||||
}
|
||||
|
||||
player->GetPev()->fuser3 = fuel * 10.0;
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_jpfuel(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
REAL fuel = clamp(amx_ctof2(params[2]),0.0,100.0);
|
||||
|
||||
return amx_ftoc2(player->GetPev()->fuser3 = clamp(static_cast<float>(player->GetPev()->fuser3 + (fuel * 10.0)),static_cast<float>(0.0)));
|
||||
};
|
||||
// ns_get_speedchange(index)
|
||||
static cell AMX_NATIVE_CALL ns_get_speedchange(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
return player->GetSpeedChange();
|
||||
}
|
||||
|
||||
// ns_set_speedchange(index,speedchange=0)
|
||||
static cell AMX_NATIVE_CALL ns_set_speedchange(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
player->SetSpeedChange(params[2]);
|
||||
|
||||
// Update PreThink_Post if we need to
|
||||
GameMan.HookPreThink_Post();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ns_get_maxspeed(index) (returns the max speed of the player BEFORE speed change is factored in.)
|
||||
static cell AMX_NATIVE_CALL ns_get_maxspeed(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
return player->GetMaxSpeed();
|
||||
}
|
||||
// ns_set_fov(id,Float:fov);
|
||||
static cell AMX_NATIVE_CALL ns_set_fov(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
return player->SetFOV(amx_ctof3(¶ms[2]));
|
||||
}
|
||||
// ns_giveiteM(id,"item");
|
||||
static cell AMX_NATIVE_CALL ns_giveitem(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
char *classname = MF_GetAmxString(amx,params[2],0,NULL);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (player->GetPev()->deadflag > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
edict_t *object=CREATE_NAMED_ENTITY(ALLOC_STRING2(classname));
|
||||
|
||||
if (!object)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Error creating entity \"%s\"", classname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SET_ORIGIN(object,player->GetPev()->origin); // move to player
|
||||
gpGamedllFuncs->dllapi_table->pfnSpawn(object); // emulate spawn
|
||||
object->v.flags |= FL_ONGROUND; // make it think it's touched the ground
|
||||
gpGamedllFuncs->dllapi_table->pfnThink(object); //
|
||||
gpGamedllFuncs->dllapi_table->pfnTouch(object,player->GetEdict()); // give it to the player
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
AMX_NATIVE_INFO player_natives[] = {
|
||||
|
||||
{ "ns_set_player_model", ns_set_player_model },
|
||||
{ "ns_set_player_skin", ns_set_player_skin },
|
||||
{ "ns_set_player_body", ns_set_player_body },
|
||||
|
||||
{ "ns_get_class", ns_get_class },
|
||||
|
||||
{ "ns_get_jpfuel", ns_get_jpfuel },
|
||||
{ "ns_set_jpfuel", ns_set_jpfuel },
|
||||
{ "ns_add_jpfuel", ns_add_jpfuel },
|
||||
|
||||
{ "ns_get_energy", ns_get_jpfuel }, // They do the same thing...
|
||||
{ "ns_set_energy", ns_set_jpfuel }, //
|
||||
{ "ns_add_energy", ns_add_jpfuel },
|
||||
|
||||
{ "ns_get_speedchange", ns_get_speedchange },
|
||||
{ "ns_set_speedchange", ns_set_speedchange },
|
||||
{ "ns_get_maxspeed", ns_get_maxspeed },
|
||||
|
||||
{ "ns_set_fov", ns_set_fov },
|
||||
|
||||
{ "ns_give_item", ns_giveitem },
|
||||
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_Player()
|
||||
{
|
||||
MF_AddNatives(player_natives);
|
||||
}
|
355
dlls/ns/natives/player_memory.cpp
Normal file
355
dlls/ns/natives/player_memory.cpp
Normal file
@ -0,0 +1,355 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../GameManager.h"
|
||||
#include "../CPlayer.h"
|
||||
|
||||
// Float:ns_get_res(Player)
|
||||
static cell AMX_NATIVE_CALL ns_get_res(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private_f(player->GetEdict(),MAKE_OFFSET(RESOURCES)));
|
||||
}
|
||||
|
||||
// ns_set_res(Player,Float:res)
|
||||
static cell AMX_NATIVE_CALL ns_set_res(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(player->GetEdict(),MAKE_OFFSET(RESOURCES),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// Float:ns_add_res(Player,Float:res)
|
||||
static cell AMX_NATIVE_CALL ns_add_res(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(player->GetEdict(),MAKE_OFFSET(RESOURCES),amx_ctof2(params[2]),0.0,100.0));
|
||||
}
|
||||
// Float:ns_get_exp(Player)
|
||||
static cell AMX_NATIVE_CALL ns_get_exp(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private_f(player->GetEdict(),MAKE_OFFSET(EXP)));
|
||||
}
|
||||
|
||||
// ns_set_exp(Player,Float:exp)
|
||||
static cell AMX_NATIVE_CALL ns_set_exp(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(player->GetEdict(),MAKE_OFFSET(EXP),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// Float:ns_add_exp(Player,Float:exp)
|
||||
static cell AMX_NATIVE_CALL ns_add_exp(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(player->GetEdict(),MAKE_OFFSET(EXP),amx_ctof2(params[2]),0.0));
|
||||
}
|
||||
|
||||
// ns_get_points(Player)
|
||||
static cell AMX_NATIVE_CALL ns_get_points(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(POINTS));
|
||||
}
|
||||
|
||||
// ns_set_points(Player,points)
|
||||
static cell AMX_NATIVE_CALL ns_set_points(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx, params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(POINTS),static_cast<int>(params[2]));
|
||||
return 1;
|
||||
}
|
||||
// ns_add_points(Player,points)
|
||||
static cell AMX_NATIVE_CALL ns_add_points(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx, params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(POINTS),static_cast<int>(params[2]),0,9);
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_score(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(SCORE));
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_score(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(SCORE),static_cast<int>(params[2]));
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_score(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(SCORE),static_cast<int>(params[2]));
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(DEATHS));
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(DEATHS),static_cast<int>(params[2]));
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(DEATHS),static_cast<int>(params[2]));
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_hive_ability(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
int result = get_private(player->GetEdict(), MAKE_OFFSET(HIVEABILITY));
|
||||
|
||||
return (params[2] > 0) ? (result >= params[2] - 1) : result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AMX_NATIVE_INFO player_memory_natives[] = {
|
||||
|
||||
{ "ns_get_res", ns_get_res },
|
||||
{ "ns_set_res", ns_set_res },
|
||||
{ "ns_add_res", ns_add_res },
|
||||
|
||||
{ "ns_get_exp", ns_get_exp },
|
||||
{ "ns_set_exp", ns_set_exp },
|
||||
{ "ns_add_exp", ns_add_exp },
|
||||
|
||||
{ "ns_get_points", ns_get_points },
|
||||
{ "ns_set_points", ns_set_points },
|
||||
{ "ns_add_points", ns_add_points },
|
||||
|
||||
{ "ns_set_score", ns_set_score },
|
||||
{ "ns_get_score", ns_get_score },
|
||||
{ "ns_add_score", ns_add_score },
|
||||
|
||||
{ "ns_get_deaths", ns_get_deaths },
|
||||
{ "ns_set_deaths", ns_set_deaths },
|
||||
{ "ns_add_deaths", ns_add_deaths },
|
||||
|
||||
{ "ns_get_hive_ability", ns_get_hive_ability},
|
||||
|
||||
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_PlayerMemory()
|
||||
{
|
||||
MF_AddNatives(player_memory_natives);
|
||||
}
|
405
dlls/ns/natives/structure.cpp
Normal file
405
dlls/ns/natives/structure.cpp
Normal file
@ -0,0 +1,405 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
int IsValidBuilding[AVH_USER3_MAX + 1] = {
|
||||
0, // AVH_USER3_NONE = 0,
|
||||
0, // AVH_USER3_MARINE_PLAYER,
|
||||
0, // AVH_USER3_COMMANDER_PLAYER,
|
||||
0, // AVH_USER3_ALIEN_PLAYER1,
|
||||
0, // AVH_USER3_ALIEN_PLAYER2,
|
||||
0, // AVH_USER3_ALIEN_PLAYER3,
|
||||
0, // AVH_USER3_ALIEN_PLAYER4,
|
||||
0, // AVH_USER3_ALIEN_PLAYER5,
|
||||
0, // AVH_USER3_ALIEN_EMBRYO,
|
||||
0, // AVH_USER3_SPAWN_TEAMONE,
|
||||
0, // AVH_USER3_SPAWN_TEAMTWO,
|
||||
0, // AVH_USER3_PARTICLE_ON, // only valid for AvHParticleEntity: entindex as int in fuser1, template index stored in fuser2
|
||||
0, // AVH_USER3_PARTICLE_OFF, // only valid for AvHParticleEntity: particle system handle in fuser1
|
||||
0, // AVH_USER3_WELD, // float progress (0 - 100) stored in fuser1
|
||||
0, // AVH_USER3_ALPHA, // fuser1 indicates how much alpha this entity toggles to in commander mode, fuser2 for players
|
||||
0, // AVH_USER3_MARINEITEM, // Something a friendly marine can pick up
|
||||
0, // AVH_USER3_WAYPOINT,
|
||||
2, // AVH_USER3_HIVE,
|
||||
0, // AVH_USER3_NOBUILD,
|
||||
0, // AVH_USER3_USEABLE,
|
||||
0, // AVH_USER3_AUDIO_ON,
|
||||
0, // AVH_USER3_AUDIO_OFF,
|
||||
0, // AVH_USER3_FUNC_RESOURCE,
|
||||
1, // AVH_USER3_COMMANDER_STATION,
|
||||
1, // AVH_USER3_TURRET_FACTORY,
|
||||
1, // AVH_USER3_ARMORY,
|
||||
1, // AVH_USER3_ADVANCED_ARMORY,
|
||||
1, // AVH_USER3_ARMSLAB,
|
||||
1, // AVH_USER3_PROTOTYPE_LAB,
|
||||
1, // AVH_USER3_OBSERVATORY,
|
||||
0, // AVH_USER3_CHEMLAB,
|
||||
0, // AVH_USER3_MEDLAB,
|
||||
0, // AVH_USER3_NUKEPLANT,
|
||||
1, // AVH_USER3_TURRET,
|
||||
1, // AVH_USER3_SIEGETURRET,
|
||||
1, // AVH_USER3_RESTOWER,
|
||||
0, // AVH_USER3_PLACEHOLDER,
|
||||
1, // AVH_USER3_INFANTRYPORTAL,
|
||||
0, // AVH_USER3_NUKE,
|
||||
0, // AVH_USER3_BREAKABLE,
|
||||
0, // AVH_USER3_UMBRA,
|
||||
1, // AVH_USER3_PHASEGATE,
|
||||
2, // AVH_USER3_DEFENSE_CHAMBER,
|
||||
2, // AVH_USER3_MOVEMENT_CHAMBER,
|
||||
2, // AVH_USER3_OFFENSE_CHAMBER,
|
||||
2, // AVH_USER3_SENSORY_CHAMBER,
|
||||
2, // AVH_USER3_ALIENRESTOWER,
|
||||
0, // AVH_USER3_HEAVY,
|
||||
0, // AVH_USER3_JETPACK,
|
||||
1, // AVH_USER3_ADVANCED_TURRET_FACTORY,
|
||||
0, // AVH_USER3_SPAWN_READYROOM,
|
||||
0, // AVH_USER3_CLIENT_COMMAND,
|
||||
0, // AVH_USER3_FUNC_ILLUSIONARY,
|
||||
0, // AVH_USER3_MENU_BUILD,
|
||||
0, // AVH_USER3_MENU_BUILD_ADVANCED,
|
||||
0, // AVH_USER3_MENU_ASSIST,
|
||||
0, // AVH_USER3_MENU_EQUIP,
|
||||
0, // AVH_USER3_MINE,
|
||||
0 // AVH_USER3_MAX
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ns_build_structure(idStructure);
|
||||
static cell AMX_NATIVE_CALL ns_build_structure(AMX *amx, cell *params)
|
||||
{
|
||||
// Trick NS into thinking that this structure is being spawned from the map
|
||||
// set the "startbuilt" setting to 1, then remove it.
|
||||
// "startbuilt" is set as "spawnflag" "1" in the ns.fgd
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->free)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
if (Entity->v.iuser3 <= AVH_USER3_NONE || Entity->v.iuser3 >= AVH_USER3_MAX)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int StructureType=IsValidBuilding[Entity->v.iuser3];
|
||||
if (StructureType==0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Entity->v.iuser3==AVH_USER3_HIVE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Already set?
|
||||
if (Entity->v.spawnflags & 1)
|
||||
{
|
||||
MDLL_Spawn(Entity);
|
||||
|
||||
goto undo_ghost;
|
||||
}
|
||||
|
||||
Entity->v.spawnflags |= 1;
|
||||
|
||||
MDLL_Spawn(Entity);
|
||||
|
||||
Entity->v.spawnflags &= ~1;
|
||||
|
||||
undo_ghost:
|
||||
if (StructureType==1) // marine, remove "ghost" appearance
|
||||
{
|
||||
if (get_private(Entity,MAKE_OFFSET(GHOST_STRUCTURE))!=0)
|
||||
{
|
||||
set_private(Entity,MAKE_OFFSET(GHOST_STRUCTURE),0);
|
||||
|
||||
Entity->v.rendermode=kRenderNormal;
|
||||
Entity->v.renderamt=100.0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
#define MASK_ELECTRICITY 8192
|
||||
static cell AMX_NATIVE_CALL ns_get_build(AMX *amx, cell *params)
|
||||
{
|
||||
int iLength;
|
||||
char *buildtype = MF_GetAmxString(amx,params[1],0,&iLength);
|
||||
int iBuiltOnly = params[2];
|
||||
int iNumber = params[3];
|
||||
edict_t* pBuild = NULL;
|
||||
int iCount=0;
|
||||
|
||||
while ((pBuild = UTIL_FindEntityByString(pBuild,"classname",buildtype)) != NULL)
|
||||
{
|
||||
if (iBuiltOnly > 0)
|
||||
{
|
||||
if (FStrEq("team_advarmory",buildtype) || FStrEq("team_advturretfactory",buildtype))
|
||||
{
|
||||
iCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pBuild->v.fuser1 >= 1000 || pBuild->v.iuser4 & MASK_ELECTRICITY)
|
||||
{
|
||||
iCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iCount++;
|
||||
}
|
||||
if (iNumber > 0 && iCount == iNumber)
|
||||
return ENTINDEX_NEW(pBuild);
|
||||
}
|
||||
return iCount++;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_hive_trait(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(Entity,MAKE_OFFSET(HIVE_TRAIT),static_cast<int>(params[2]));
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_hive_trait(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_private(Entity,MAKE_OFFSET(HIVE_TRAIT));
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_struct_owner(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_private(Entity,MAKE_OFFSET(STRUCTOWNER));
|
||||
}
|
||||
// ns_set_struct_owner(idStructure,idPlayer) - -1 means no owner
|
||||
static cell AMX_NATIVE_CALL ns_set_struct_owner(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (params[2] > gpGlobals->maxClients || params[2] < -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
set_private(Entity,MAKE_OFFSET(STRUCTOWNER),params[2]);
|
||||
return 1;
|
||||
}
|
||||
// Float:ns_get_obs_energy(id);
|
||||
static cell AMX_NATIVE_CALL ns_get_obs_energy(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private(Entity,MAKE_OFFSET(OBS_ENERGY)));
|
||||
};
|
||||
// Float:ns_set_obs_energy(id,Float:energy);
|
||||
static cell AMX_NATIVE_CALL ns_set_obs_energy(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(OBS_ENERGY),amx_ctof2(params[2]));
|
||||
return 1;
|
||||
};
|
||||
|
||||
// Float:ns_add_obs_energy(id,Float:energy);
|
||||
static cell AMX_NATIVE_CALL ns_add_obs_energy(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(Entity,MAKE_OFFSET(OBS_ENERGY),amx_ctof2(params[2]),0.0,100.0));
|
||||
};
|
||||
|
||||
// Float:ns_get_weld_time(idWeldable);
|
||||
static cell AMX_NATIVE_CALL ns_get_weld_time(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private_f(Entity,MAKE_OFFSET(WELD_TIME)));
|
||||
};
|
||||
// ns_set_weld_time(idWeldable,Float:value);
|
||||
static cell AMX_NATIVE_CALL ns_set_weld_time(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(WELD_TIME),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
};
|
||||
// Float:ns_add_weld_time(idWeldable,Float:value);
|
||||
static cell AMX_NATIVE_CALL ns_add_weld_time(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(Entity,MAKE_OFFSET(WELD_TIME),amx_ctof2(params[2]),0.0));
|
||||
};
|
||||
// Float:ns_get_weld_done(idWeldable);
|
||||
static cell AMX_NATIVE_CALL ns_get_weld_done(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private_f(Entity,MAKE_OFFSET(WELD_DONE)));
|
||||
};
|
||||
// ns_set_weld_done(idWeldable,Float:value);
|
||||
static cell AMX_NATIVE_CALL ns_set_weld_done(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(WELD_DONE),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
};
|
||||
// Float:ns_add_weld_done(idWeldable,Float:value);
|
||||
static cell AMX_NATIVE_CALL ns_add_weld_done(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(Entity,MAKE_OFFSET(WELD_DONE),amx_ctof2(params[2]),0.0));
|
||||
};
|
||||
|
||||
|
||||
AMX_NATIVE_INFO structure_natives[] = {
|
||||
{ "ns_build_structure", ns_build_structure },
|
||||
|
||||
{ "ns_get_build", ns_get_build },
|
||||
|
||||
{ "ns_get_hive_trait", ns_get_hive_trait },
|
||||
{ "ns_set_hive_trait", ns_set_hive_trait },
|
||||
|
||||
{ "ns_get_struct_owner", ns_get_struct_owner },
|
||||
{ "ns_set_struct_owner", ns_set_struct_owner },
|
||||
|
||||
{ "ns_get_obs_energy", ns_get_obs_energy },
|
||||
{ "ns_set_obs_energy", ns_set_obs_energy },
|
||||
{ "ns_add_obs_energy", ns_add_obs_energy },
|
||||
|
||||
{ "ns_get_weld_time", ns_get_weld_time },
|
||||
{ "ns_set_weld_time", ns_set_weld_time },
|
||||
{ "ns_add_weld_time", ns_add_weld_time },
|
||||
|
||||
{ "ns_get_weld_done", ns_get_weld_done },
|
||||
{ "ns_set_weld_done", ns_set_weld_done },
|
||||
{ "ns_add_weld_done", ns_add_weld_done },
|
||||
|
||||
/* prototypes for natives i have planned */
|
||||
//{ "ns_get_phase_target", ns_get_phase_target },
|
||||
//{ "ns_set_phase_target", ns_set_phase_target },
|
||||
|
||||
//{ "ns_set_phase_nextuse", ns_set_phase_nextuse },
|
||||
//{ "ns_get_phase_nextuse", ns_get_phase_nextuse },
|
||||
//{ "ns_add_phase_nextuse", ns_add_phase_nextuse },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_Structure()
|
||||
{
|
||||
MF_AddNatives(structure_natives);
|
||||
}
|
479
dlls/ns/natives/weapons.cpp
Normal file
479
dlls/ns/natives/weapons.cpp
Normal file
@ -0,0 +1,479 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../GameManager.h"
|
||||
#include "../CPlayer.h"
|
||||
|
||||
// ns_has_weapon(idPlayer,NsWeapon,set=0)
|
||||
static cell AMX_NATIVE_CALL ns_has_weapon(AMX *amx,cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (params[3] == -1)
|
||||
{
|
||||
if ((player->GetPev()->weapons & (1<<params[2])) > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((player->GetPev()->weapons & (1<<params[2])) > 0)
|
||||
{
|
||||
if (params[3] == 0)
|
||||
{
|
||||
player->GetPev()->weapons &= ~(1<<params[2]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (params[3] == 1)
|
||||
{
|
||||
player->GetPev()->weapons |= (1<<params[2]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// ns_set_weap_dmg(WeaponID,Float:damage)
|
||||
static cell AMX_NATIVE_CALL ns_set_weapon_dmg(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(WEAPDMG),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Float:ns_get_weap_dmg(WeaponID)
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon_dmg(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
REAL ret=get_private_f(Entity,MAKE_OFFSET(WEAPDMG));
|
||||
return amx_ftoc2(ret);
|
||||
}
|
||||
|
||||
// ns_set_weap_range(WeaponID,Float:range)
|
||||
static cell AMX_NATIVE_CALL ns_set_weapon_range(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(WEAPRANGE),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// Float:ns_get_weap_range(WeaponID)
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon_range(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
REAL ret=get_private_f(Entity,MAKE_OFFSET(WEAPRANGE));
|
||||
return amx_ftoc2(ret);
|
||||
}
|
||||
// ns_get_weap_ammo(WeaponID)
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon_clip(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_private(Entity,MAKE_OFFSET(WEAPCLIP));
|
||||
}
|
||||
// ns_set_weap_ammo(WeaponID,ammo)
|
||||
static cell AMX_NATIVE_CALL ns_set_weapon_clip(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(Entity,MAKE_OFFSET(WEAPCLIP),params[2]);
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_weapon_clip(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inc_private(Entity,MAKE_OFFSET(WEAPCLIP),static_cast<int>(params[2]),0);
|
||||
}
|
||||
// ns_get_weap_reserve(PlayerID,WeaponType)
|
||||
static cell AMX_NATIVE_CALL ns_get_weap_reserve(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case WEAPON_PISTOL:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_PISTOL));
|
||||
case WEAPON_LMG:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_LMG));
|
||||
case WEAPON_SHOTGUN:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_SHOTGUN));
|
||||
case WEAPON_HMG:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_HMG));
|
||||
case WEAPON_GRENADE_GUN:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_GL));
|
||||
case WEAPON_GRENADE:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_HG));
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_weap_reserve(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case WEAPON_PISTOL:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_PISTOL),params[3]);
|
||||
return 1;
|
||||
case WEAPON_LMG:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_LMG),(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_SHOTGUN:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_SHOTGUN),(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_HMG:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_HMG),(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_GRENADE_GUN:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_GL),(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_GRENADE:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_HG),(int)params[3]);
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_weap_reserve(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case WEAPON_PISTOL:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_PISTOL),params[3],0);
|
||||
case WEAPON_LMG:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_LMG),(int)params[3],0);
|
||||
case WEAPON_SHOTGUN:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_SHOTGUN),(int)params[3],0);
|
||||
case WEAPON_HMG:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_HMG),(int)params[3],0);
|
||||
case WEAPON_GRENADE_GUN:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_GL),(int)params[3],0);
|
||||
case WEAPON_GRENADE:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_HG),(int)params[3],0);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// ns_get_weapon(idPlayer,weaponid,&weapontype=0)
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon(AMX *amx, cell *params)
|
||||
{
|
||||
// Peachy did it like this:
|
||||
// if weapontype is 0, return the primary weapon index of the player
|
||||
// if weapontype is < 0, return the last inventory weapon index of the player
|
||||
// otherwise, scan the player's inventory and look for a weapon of the given type
|
||||
// such as WEAPON_KNIFE, etc, etc
|
||||
// I added the last parameter, which will byref the weapontype of the weapon found
|
||||
// returns 0 on failure
|
||||
// last param default value added to not conflict with his version
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (params[2]<0) // find lastinv weapon
|
||||
{
|
||||
edict_t *Weapon=private_to_edict(get_private_p<void *>(player->GetEdict(),MAKE_OFFSET(LAST_WEAPON)));
|
||||
|
||||
if (Weapon==NULL) // no weapon
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((params[0] / sizeof(cell))>2) // If this plugin was compiled with peachy's .inc then don't byref
|
||||
{
|
||||
*MF_GetAmxAddr_NEW(amx,params[3])=get_private(Weapon,MAKE_OFFSET(WEAPID));
|
||||
}
|
||||
|
||||
return ENTINDEX_NEW(Weapon);
|
||||
|
||||
}
|
||||
if (params[2]==0) // find current weapon
|
||||
{
|
||||
edict_t *Weapon=private_to_edict(get_private_p<void *>(player->GetEdict(),MAKE_OFFSET(CURRENT_WEAPON)));
|
||||
|
||||
if (Weapon==NULL) // no weapon
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((params[0] / sizeof(cell))>2) // If this plugin was compiled with peachy's .inc then don't byref
|
||||
{
|
||||
*MF_GetAmxAddr_NEW(amx,params[3])=get_private(Weapon,MAKE_OFFSET(WEAPID));
|
||||
}
|
||||
|
||||
return ENTINDEX_NEW(Weapon);
|
||||
}
|
||||
|
||||
// Finding weapon by ID
|
||||
|
||||
char **pPlayerItems = reinterpret_cast<char**>(static_cast<char*>(player->GetEdict()->pvPrivateData) + MAKE_OFFSET(PLAYER_ITEMS));
|
||||
char *pItem;
|
||||
int weapon=params[2];
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
pItem = pPlayerItems[i];
|
||||
while (pItem)
|
||||
{
|
||||
if (*(int *)(pItem + MAKE_OFFSET(WEAPID)) == weapon)
|
||||
{
|
||||
return ENTINDEX_NEW(private_to_edict(pItem));
|
||||
}
|
||||
else
|
||||
{
|
||||
pItem = *(char **)(pItem + MAKE_OFFSET(WEAP_NEXT));
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEVELOPER_BUILD
|
||||
// ns_find_weapon_offset(idPlayer,"primweapon","lastinvweapon")
|
||||
static cell AMX_NATIVE_CALL ns_find_weapon_offset(AMX *amx, cell *params)
|
||||
{
|
||||
char *SPrimWeapon=MF_GetAmxString(amx,params[2],0,NULL);
|
||||
char *SLastInv=MF_GetAmxString(amx,params[3],1,NULL);
|
||||
edict_t *ePlayer=INDEXENT_NEW(params[1]);
|
||||
|
||||
// Locate entities by name
|
||||
edict_t *PrimWeapon=NULL;
|
||||
edict_t *LastInv=NULL;
|
||||
|
||||
edict_t *Temp=NULL;
|
||||
|
||||
while ((Temp=UTIL_FindEntityByString(Temp,"classname",SPrimWeapon))!=NULL)
|
||||
{
|
||||
if (Temp->v.owner==ePlayer)
|
||||
{
|
||||
PrimWeapon=Temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Temp=NULL;
|
||||
while ((Temp=UTIL_FindEntityByString(Temp,"classname",SLastInv))!=NULL)
|
||||
{
|
||||
if (Temp->v.owner==ePlayer)
|
||||
{
|
||||
LastInv=Temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (LastInv == NULL || PrimWeapon == NULL)
|
||||
{
|
||||
if (LastInv==NULL)
|
||||
{
|
||||
MF_Log("LastInv==NULL");
|
||||
}
|
||||
if (PrimWeapon==NULL)
|
||||
{
|
||||
MF_Log("PrimWeapon=NULL");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// now iterate through the client's private data until we find the pointer to PrimWeapon/LastInv's offset
|
||||
unsigned int *Ptr=(unsigned int*)ePlayer->pvPrivateData;
|
||||
|
||||
int FoundLastInv=0;
|
||||
int FoundPrim=0;
|
||||
size_t count=0;
|
||||
unsigned int iPrim;
|
||||
unsigned int iLast;
|
||||
|
||||
// so nasty D: this is basically horrible_cast
|
||||
union bleh
|
||||
{
|
||||
void *ptr;
|
||||
unsigned int ival;
|
||||
}blah;
|
||||
|
||||
blah.ptr=PrimWeapon->pvPrivateData;
|
||||
iPrim=blah.ival;
|
||||
|
||||
blah.ptr=LastInv->pvPrivateData;
|
||||
iLast=blah.ival;
|
||||
|
||||
while (count<4000)
|
||||
{
|
||||
if (*Ptr==iLast)
|
||||
{
|
||||
MF_Log("Found LastInv: %d",count);
|
||||
FoundLastInv=1;
|
||||
}
|
||||
if (*Ptr==iPrim)
|
||||
{
|
||||
MF_Log("Found Primary: %d",count);
|
||||
FoundPrim=1;
|
||||
}
|
||||
|
||||
if (FoundLastInv && FoundPrim)
|
||||
{
|
||||
//break;
|
||||
}
|
||||
count+=4;
|
||||
Ptr++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
AMX_NATIVE_INFO weapon_natives[] = {
|
||||
|
||||
{ "ns_has_weapon", ns_has_weapon },
|
||||
|
||||
{ "ns_set_weap_dmg", ns_set_weapon_dmg },
|
||||
{ "ns_get_weap_dmg", ns_get_weapon_dmg },
|
||||
|
||||
{ "ns_set_weap_range", ns_set_weapon_range },
|
||||
{ "ns_get_weap_range", ns_get_weapon_range },
|
||||
|
||||
{ "ns_set_weap_clip", ns_set_weapon_clip },
|
||||
{ "ns_get_weap_clip", ns_get_weapon_clip },
|
||||
{ "ns_add_weap_clip", ns_add_weapon_clip },
|
||||
|
||||
{ "ns_set_weap_reserve", ns_set_weap_reserve },
|
||||
{ "ns_get_weap_reserve", ns_get_weap_reserve },
|
||||
{ "ns_add_weap_reserve", ns_add_weap_reserve },
|
||||
|
||||
{ "ns_get_weapon", ns_get_weapon},
|
||||
|
||||
#ifdef DEVELOPER_BUILD
|
||||
{ "ns_find_weapon_offset", ns_find_weapon_offset},
|
||||
#endif
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_Weapons()
|
||||
{
|
||||
MF_AddNatives(weapon_natives);
|
||||
}
|
88
dlls/ns/ns.h
88
dlls/ns/ns.h
@ -1,14 +1,46 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef NS_H
|
||||
#define NS_H
|
||||
|
||||
|
||||
#include <extdll.h>
|
||||
#include <string.h>
|
||||
#include "amxxmodule.h"
|
||||
#include "ns_const.h"
|
||||
#include "CPlayer.h"
|
||||
#include "CSpawn.h"
|
||||
#include "utilfunctions.h"
|
||||
|
||||
#if defined CRAZY_OPTS
|
||||
#define EXTERN_VIS __attribute__((externally_visible))
|
||||
#else
|
||||
#define EXTERN_VIS
|
||||
#endif
|
||||
|
||||
extern DLL_FUNCTIONS *g_pFunctionTable;
|
||||
extern DLL_FUNCTIONS *g_pFunctionTable_Post;
|
||||
@ -18,28 +50,44 @@ extern NEW_DLL_FUNCTIONS *g_pNewFunctionsTable;
|
||||
extern NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post;
|
||||
|
||||
|
||||
extern CSpawn ns_spawnpoints;
|
||||
|
||||
|
||||
extern BOOL iscombat;
|
||||
extern CPlayer g_player[33];
|
||||
extern class CPlayer g_player[33];
|
||||
extern edict_t *player_edicts[33]; // Stupid INDEXENT() bug.
|
||||
|
||||
extern int gmsgHudText2;
|
||||
|
||||
|
||||
extern AMX_NATIVE_INFO ns_misc_natives[];
|
||||
extern AMX_NATIVE_INFO ns_pdata_natives[];
|
||||
|
||||
extern int SpawnForward;
|
||||
extern int TeamForward;
|
||||
|
||||
extern int ChangeclassForward;
|
||||
extern int BuiltForward;
|
||||
void PlayerPreThink(edict_t *pEntity);
|
||||
void PlayerPreThink_Post(edict_t *pEntity);
|
||||
void PlayerPostThink_Post(edict_t *pEntity);
|
||||
void UpdateClientData( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd );
|
||||
void StartFrame(void);
|
||||
edict_t* CreateNamedEntity_Post(int className);
|
||||
void AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...);
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
typedef struct tagAMX_HEADER {
|
||||
int32_t size PACKED; /* size of the "file" */
|
||||
uint16_t magic PACKED; /* signature */
|
||||
char file_version; /* file format version */
|
||||
char amx_version; /* required version of the AMX */
|
||||
int16_t flags PACKED;
|
||||
int16_t defsize PACKED; /* size of a definition record */
|
||||
int32_t cod PACKED; /* initial value of COD - code block */
|
||||
int32_t dat PACKED; /* initial value of DAT - data block */
|
||||
int32_t hea PACKED; /* initial value of HEA - start of the heap */
|
||||
int32_t stp PACKED; /* initial value of STP - stack top */
|
||||
int32_t cip PACKED; /* initial value of CIP - the instruction pointer */
|
||||
int32_t publics PACKED; /* offset to the "public functions" table */
|
||||
int32_t natives PACKED; /* offset to the "native functions" table */
|
||||
int32_t libraries PACKED; /* offset to the table of libraries */
|
||||
int32_t pubvars PACKED; /* the "public variables" table */
|
||||
int32_t tags PACKED; /* the "public tagnames" table */
|
||||
int32_t nametable PACKED; /* name table */
|
||||
} PACKED AMX_HEADER;
|
||||
|
||||
// Don't enable this, it just adds some offset finding natives
|
||||
#define DEVELOPER_BUILD
|
||||
|
||||
|
||||
#endif // NS_H
|
||||
|
@ -1,3 +1,36 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NS_CONST_H
|
||||
#define NS_CONST_H
|
||||
@ -6,56 +39,156 @@
|
||||
|
||||
// Offsets (used in NPData.cpp)
|
||||
|
||||
#define OFFSET_WIN_RESOURCES 1816 //454 * 4 // est: 454 // CONFIRMED
|
||||
#define OFFSET_LIN_RESOURCES 1836 //459 * 4 // no change
|
||||
#define NEED_TO_FIND 0
|
||||
|
||||
#define OFFSET_WIN_WEAPDMG 408 //100 * 4 // est: 102 // CONFIRMED
|
||||
#define OFFSET_LIN_WEAPDMG 424 //106 * 4 // Changed + 8 Bytes
|
||||
|
||||
#define OFFSET_WIN_WEAPRANGE 404 //99 * 4 // est: 101 // CONFIRMED
|
||||
#define OFFSET_LIN_WEAPRANGE 420 //105 * 4 // Changed + 8 Bytes
|
||||
#define OFFSET_WIN_RESOURCES 1816
|
||||
#define OFFSET_LIN_RESOURCES 1836
|
||||
|
||||
#define OFFSET_WIN_WEAPCLIP 364 //91 * 4 // est: 91 // CONFIRMED
|
||||
#define OFFSET_LIN_WEAPCLIP 380 //95 * 4 // no change
|
||||
#define OFFSET_WIN_WEAPDMG 408
|
||||
#define OFFSET_LIN_WEAPDMG 424
|
||||
|
||||
#define OFFSET_WIN_HIVE_TRAIT 488 //121 * 4 // est: 122 // CONFIRMED
|
||||
#define OFFSET_LIN_HIVE_TRAIT 504 //126 * 4 // Changed + 4 bytes
|
||||
#define OFFSET_WIN_WEAPRANGE 404
|
||||
#define OFFSET_LIN_WEAPRANGE 420
|
||||
|
||||
#define OFFSET_WIN_SCORE 6588 //1639 * 4 // est: 1647 // CONFIRMED
|
||||
#define OFFSET_LIN_SCORE 6608 //1644 * 4 // Changed + 32 bytes
|
||||
#define OFFSET_WIN_WEAPCLIP 364
|
||||
#define OFFSET_LIN_WEAPCLIP 380
|
||||
|
||||
#define OFFSET_WIN_EXP 6512 //1620 * 4 // est: 1628 // CONFIRMED
|
||||
#define OFFSET_LIN_EXP 6532 //1633 * 4 // Changed + 32 bytes
|
||||
#define OFFSET_WIN_WEAPID 324
|
||||
#define OFFSET_LIN_WEAPID 340
|
||||
|
||||
#define OFFSET_WIN_POINTS 6520 //1622 * 4 // est: 1630 // CONFIRMED
|
||||
#define OFFSET_LIN_POINTS 6540 //1635 * 4 // Changed + 32 bytes
|
||||
// Next weapon in the item linked list
|
||||
#define OFFSET_WIN_WEAP_NEXT 320
|
||||
#define OFFSET_LIN_WEAP_NEXT 336
|
||||
|
||||
#define OFFSET_WIN_AMMO_LMG 1116 //279 * 4 // est: 279 // CONFIRMED
|
||||
#define OFFSET_LIN_AMMO_LMG 1136 //284 * 4 // no change
|
||||
#define OFFSET_WIN_HIVE_TRAIT 488
|
||||
#define OFFSET_LIN_HIVE_TRAIT 504
|
||||
|
||||
#define OFFSET_WIN_AMMO_PISTOL 1120 //280 * 4 // est: 280 // CONFIRMED
|
||||
#define OFFSET_LIN_AMMO_PISTOL 1140 //285 * 4 // no change
|
||||
#define OFFSET_WIN_SCORE 6588
|
||||
#define OFFSET_LIN_SCORE 6608
|
||||
|
||||
#define OFFSET_WIN_AMMO_SHOTGUN 1124 //281 * 4 // est: 281 // CONFIRMED
|
||||
#define OFFSET_LIN_AMMO_SHOTGUN 1144 //286 * 4 // no change
|
||||
#define OFFSET_WIN_EXP 6512
|
||||
#define OFFSET_LIN_EXP 6532
|
||||
|
||||
#define OFFSET_WIN_AMMO_HMG 1128 //282 * 4 // est: 282 // CONFIRMED
|
||||
#define OFFSET_LIN_AMMO_HMG 1148 //287 * 4 // no change
|
||||
#define OFFSET_WIN_POINTS 6520
|
||||
#define OFFSET_LIN_POINTS 6540
|
||||
|
||||
#define OFFSET_WIN_AMMO_GL 1132 //283 * 4 // est: 283 // CONFIRMED
|
||||
#define OFFSET_LIN_AMMO_GL 1152 //288 * 4 // no change
|
||||
#define OFFSET_WIN_AMMO_LMG 1116
|
||||
#define OFFSET_LIN_AMMO_LMG 1136
|
||||
|
||||
#define OFFSET_WIN_AMMO_HG 1136 //284 * 4 // est: 284 // CONFIRMED
|
||||
#define OFFSET_LIN_AMMO_HG 1156 //289 * 4 // no change
|
||||
#define OFFSET_WIN_AMMO_PISTOL 1120
|
||||
#define OFFSET_LIN_AMMO_PISTOL 1140
|
||||
|
||||
#define OFFSET_WIN_DEATHS 1380 //345 * 4 // est: 345 // CONFIRMED
|
||||
#define OFFSET_LIN_DEATHS 1400 //350 * 4 // no change
|
||||
#define OFFSET_WIN_AMMO_SHOTGUN 1124
|
||||
#define OFFSET_LIN_AMMO_SHOTGUN 1144
|
||||
|
||||
#define OFFSET_WIN_STRUCTOWNER 324 //81 * 4 // est: 81 // CONFIRMED
|
||||
#define OFFSET_LIN_STRUCTOWNER 340 //85 * 4 // no change
|
||||
#define OFFSET_WIN_AMMO_HMG 1128
|
||||
#define OFFSET_LIN_AMMO_HMG 1148
|
||||
|
||||
#define OFFSET_WIN_HIVEABILITY 6248 //1555 * 4 // est: 1562 // CONFIRMED
|
||||
#define OFFSET_LIN_HIVEABILITY 6268 //1567 * 4 // Changed + 28 bytes
|
||||
#define OFFSET_WIN_AMMO_GL 1132
|
||||
#define OFFSET_LIN_AMMO_GL 1152
|
||||
|
||||
#define OFFSET_WIN_AMMO_HG 1136
|
||||
#define OFFSET_LIN_AMMO_HG 1156
|
||||
|
||||
#define OFFSET_WIN_DEATHS 1380
|
||||
#define OFFSET_LIN_DEATHS 1400
|
||||
|
||||
#define OFFSET_WIN_STRUCTOWNER 324
|
||||
#define OFFSET_LIN_STRUCTOWNER 340
|
||||
|
||||
#define OFFSET_WIN_HIVEABILITY 6248
|
||||
#define OFFSET_LIN_HIVEABILITY 6268
|
||||
|
||||
#define OFFSET_WIN_PLAYER_ITEMS 1068
|
||||
#define OFFSET_LIN_PLAYER_ITEMS 1088
|
||||
|
||||
#define OFFSET_WIN_NEXT_WEAPON 1280
|
||||
#define OFFSET_LIN_NEXT_WEAPON 1300
|
||||
|
||||
#define OFFSET_WIN_CURRENT_WEAPON 1092
|
||||
#define OFFSET_LIN_CURRENT_WEAPON 1112 // +4 is the client known weapon if it's ever needed
|
||||
|
||||
#define OFFSET_WIN_LAST_WEAPON 1100
|
||||
#define OFFSET_LIN_LAST_WEAPON 1120
|
||||
|
||||
|
||||
|
||||
#define OFFSET_WIN_ENTVAR 4
|
||||
#define OFFSET_LIN_ENTVAR 4 // first entry in the virtual class (vtable is 0)
|
||||
|
||||
#define OFFSET_WIN_OBS_ENERGY 476
|
||||
#define OFFSET_LIN_OBS_ENERGY 492
|
||||
|
||||
#define OFFSET_WIN_WELD_DONE 128
|
||||
#define OFFSET_LIN_WELD_DONE 144
|
||||
|
||||
#define OFFSET_WIN_WELD_TIME 132
|
||||
#define OFFSET_LIN_WELD_TIME 148
|
||||
|
||||
#define OFFSET_WIN_GHOST_STRUCTURE 472
|
||||
#define OFFSET_LIN_GHOST_STRUCTURE 488
|
||||
|
||||
// The teamnumber for the specified team
|
||||
#define OFFSET_WIN_GAMEPLAY_TEAMA 0x54
|
||||
#define OFFSET_LIN_GAMEPLAY_TEAMA 0x64
|
||||
|
||||
#define OFFSET_WIN_GAMEPLAY_TEAMB 0x58
|
||||
#define OFFSET_LIN_GAMEPLAY_TEAMB 0x68
|
||||
|
||||
|
||||
// TODO: Symbols / signatures instead
|
||||
// Not actually offsets, but easier to use MAKE_OFFSET stuff for this :o
|
||||
// First functions listed in the disassembler
|
||||
#define OFFSET_WIN_BASE "?SUB_CallUseToggle@CBaseEntity@@QAEXXZ"
|
||||
#define OFFSET_LIN_BASE "_init"
|
||||
|
||||
#define OFFSET_LIN_MEMBERFUNCSTART 0x000EDBE8 // The location of _init in the binary
|
||||
#define OFFSET_WIN_MEMBERFUNCSTART 0x00001000 // The location of CBaseEntity::SUB_CallUseToggle
|
||||
|
||||
// NOTE: These addresses are raw offsets, not including the
|
||||
// base addresses! These are the exact offsets that
|
||||
// the disassembler provides.
|
||||
// MAKE_MEMBER_OFFSET will compensate for the base address
|
||||
|
||||
|
||||
// Recycle: void AvHBaseBuildable::StartRecycle(void)
|
||||
#define OFFSET_WIN_MEMBER_RECYCLE MAKE_MEMBER_OFFSET(0x00053950)
|
||||
#define OFFSET_LIN_MEMBER_RECYCLE MAKE_MEMBER_OFFSET(0x00180800)
|
||||
|
||||
|
||||
// Weldable: void AvHWeldable::AddWeldTime(float Time)
|
||||
#define OFFSET_WIN_MEMBER_TRIGGER_WELDABLE MAKE_MEMBER_OFFSET(0x000A0E20)
|
||||
#define OFFSET_LIN_MEMBER_TRIGGER_WELDABLE MAKE_MEMBER_OFFSET(0x00232840)
|
||||
|
||||
|
||||
|
||||
// Game Rules: AvHGameRules *GetGameRules(void)
|
||||
#define OFFSET_WIN_GETGAMERULES MAKE_MEMBER_OFFSET(0x00068000)
|
||||
#define OFFSET_LIN_GETGAMERULES MAKE_MEMBER_OFFSET(0x0019F930)
|
||||
|
||||
// Offset into the gamerules pointer to the TeamA / TeamB class
|
||||
#define GAMERULES_TEAMA_OFFSET 0xCC
|
||||
#define GAMERULES_TEAMB_OFFSET 0x2A8
|
||||
|
||||
#define AVHTEAM_RESOURCES_OFFSET 0x94
|
||||
|
||||
#define GAMERULES_TEAMA_RESOURCES GAMERULES_TEAMA_OFFSET + AVHTEAM_RESOURCES_OFFSET
|
||||
#define GAMERULES_TEAMB_RESOURCES GAMERULES_TEAMB_OFFSET + AVHTEAM_RESOURCES_OFFSET
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
NSGame_CantTell, /**< It is too soon to tell (can't find avhgameplay
|
||||
entity or it doesn't have private data) */
|
||||
|
||||
NSGame_MarineVAlien, /**< Marine vs Aliens (standard) gameplay */
|
||||
NSGame_MarineVMarine, /**< Marine vs Marine */
|
||||
NSGame_AlienVAlien, /**< Alien vs Alien */
|
||||
|
||||
NSGame_Unknown, /**< Can find the gameplay entity, but can't
|
||||
determine gameplay type. */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -2284,7 +2284,7 @@ C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_
|
||||
}
|
||||
|
||||
#ifdef FN_META_QUERY
|
||||
FN_META_QUERY();
|
||||
return FN_META_QUERY();
|
||||
#endif // FN_META_QUERY
|
||||
|
||||
return 1;
|
||||
@ -2327,7 +2327,7 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
||||
}
|
||||
|
||||
#ifdef FN_META_DETACH
|
||||
FN_META_DETACH();
|
||||
return FN_META_DETACH();
|
||||
#endif // FN_META_DETACH
|
||||
return TRUE;
|
||||
}
|
||||
@ -2374,7 +2374,7 @@ C_DLLEXPORT void __stdcall GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine,
|
||||
gpGlobals = pGlobals;
|
||||
// NOTE! Have to call logging function _after_ copying into g_engfuncs, so
|
||||
// that g_engfuncs.pfnAlertMessage() can be resolved properly, heh. :)
|
||||
// UTIL_LogPrintf("[%s] dev: called: GiveFnptrsToDll\n", Plugin_info.logtag);
|
||||
UTIL_LogPrintf("[%s] dev: called: GiveFnptrsToDll\n", Plugin_info.logtag);
|
||||
// --> ** Function core
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -1077,7 +1077,7 @@ void FN_AlertMessage(ALERT_TYPE atype, char *szFmt, ...);
|
||||
#endif // FN_AlertMessage
|
||||
|
||||
#ifdef FN_EngineFprintf
|
||||
void FN_EngineFprintf(void *pfile, char *szFmt, ...);
|
||||
void FN_EngineFprintf(FILE *pfile, char *szFmt, ...);
|
||||
#endif // FN_EngineFprintf
|
||||
|
||||
#ifdef FN_PvAllocEntPrivateData
|
||||
@ -1141,11 +1141,11 @@ void FN_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, flo
|
||||
#endif // FN_GetBonePosition
|
||||
|
||||
#ifdef FN_FunctionFromName
|
||||
uint32 FN_FunctionFromName(const char *pName);
|
||||
unsigned long FN_FunctionFromName(const char *pName);
|
||||
#endif // FN_FunctionFromName
|
||||
|
||||
#ifdef FN_NameForFunction
|
||||
const char *FN_NameForFunction(uint32);
|
||||
const char *FN_NameForFunction(unsigned long function);
|
||||
#endif // FN_NameForFunction
|
||||
|
||||
#ifdef FN_ClientPrintf
|
||||
@ -1189,7 +1189,7 @@ CRC32_t FN_CRC32_Final(CRC32_t pulCRC);
|
||||
#endif // FN_CRC32_Final
|
||||
|
||||
#ifdef FN_RandomLong
|
||||
int32 FN_RandomLong(int32 lLow, int32 lHigh);
|
||||
long FN_RandomLong(long lLow, long lHigh);
|
||||
#endif // FN_RandomLong
|
||||
|
||||
#ifdef FN_RandomFloat
|
||||
@ -1658,11 +1658,11 @@ void FN_AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...);
|
||||
#endif // FN_AlertMessage_Post
|
||||
|
||||
#ifdef FN_EngineFprintf_Post
|
||||
void FN_EngineFprintf_Post(void *pfile, char *szFmt, ...);
|
||||
void FN_EngineFprintf_Post(FILE *pfile, char *szFmt, ...);
|
||||
#endif // FN_EngineFprintf_Post
|
||||
|
||||
#ifdef FN_PvAllocEntPrivateData_Post
|
||||
void *FN_PvAllocEntPrivateData_Post(edict_t *pEdict, int32 cb);
|
||||
void *FN_PvAllocEntPrivateData_Post(edict_t *pEdict, long cb);
|
||||
#endif // FN_PvAllocEntPrivateData_Post
|
||||
|
||||
#ifdef FN_PvEntPrivateData_Post
|
||||
@ -1722,11 +1722,11 @@ void FN_GetBonePosition_Post(const edict_t *pEdict, int iBone, float *rgflOrigin
|
||||
#endif // FN_GetBonePosition_Post
|
||||
|
||||
#ifdef FN_FunctionFromName_Post
|
||||
uint32 FN_FunctionFromName_Post(const char *pName);
|
||||
unsigned long FN_FunctionFromName_Post(const char *pName);
|
||||
#endif // FN_FunctionFromName_Post
|
||||
|
||||
#ifdef FN_NameForFunction_Post
|
||||
const char *FN_NameForFunction_Post(uint32);
|
||||
const char *FN_NameForFunction_Post(unsigned long function);
|
||||
#endif // FN_NameForFunction_Post
|
||||
|
||||
#ifdef FN_ClientPrintf_Post
|
||||
@ -1770,7 +1770,7 @@ CRC32_t FN_CRC32_Final_Post(CRC32_t pulCRC);
|
||||
#endif // FN_CRC32_Final_Post
|
||||
|
||||
#ifdef FN_RandomLong_Post
|
||||
int32 FN_RandomLong_Post(int32 lLow, int32 lHigh);
|
||||
long FN_RandomLong_Post(long lLow, long lHigh);
|
||||
#endif // FN_RandomLong_Post
|
||||
|
||||
#ifdef FN_RandomFloat_Post
|
||||
|
@ -3,18 +3,16 @@
|
||||
#ifndef __MODULECONFIG_H__
|
||||
#define __MODULECONFIG_H__
|
||||
|
||||
#include "svn_version.h"
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "NS"
|
||||
#define MODULE_VERSION SVN_VERSION
|
||||
#define MODULE_AUTHOR "Steve Dudenhoeffer"
|
||||
#define MODULE_VERSION "1.8"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org/"
|
||||
#define MODULE_LOGTAG "NS"
|
||||
#define MODULE_LIBRARY "ns"
|
||||
#define MODULE_LIBCLASS ""
|
||||
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
|
||||
#define MODULE_RELOAD_ON_MAPCHANGE
|
||||
// #define MODULE_RELOAD_ON_MAPCHANGE
|
||||
|
||||
#ifdef __DATE__
|
||||
#define MODULE_DATE __DATE__
|
||||
@ -90,7 +88,7 @@
|
||||
// #define FN_DispatchUse DispatchUse /* pfnUse() */
|
||||
// #define FN_DispatchTouch DispatchTouch /* pfnTouch() */
|
||||
// #define FN_DispatchBlocked DispatchBlocked /* pfnBlocked() */
|
||||
// #define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
|
||||
#define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
|
||||
// #define FN_DispatchSave DispatchSave /* pfnSave() */
|
||||
// #define FN_DispatchRestore DispatchRestore /* pfnRestore() */
|
||||
// #define FN_DispatchObjectCollsionBox DispatchObjectCollsionBox /* pfnSetAbsBox() */
|
||||
@ -107,7 +105,7 @@
|
||||
// #define FN_ClientUserInfoChanged ClientUserInfoChanged /* pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure */
|
||||
#define FN_ServerActivate ServerActivate /* pfnServerActivate() (wd) Server is starting a new map */
|
||||
#define FN_ServerDeactivate ServerDeactivate /* pfnServerDeactivate() (wd) Server is leaving the map (shutdown or changelevel); SDK2 */
|
||||
#define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */
|
||||
// #define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */
|
||||
// #define FN_PlayerPostThink PlayerPostThink /* pfnPlayerPostThink() */
|
||||
// #define FN_StartFrame StartFrame /* pfnStartFrame() */
|
||||
// #define FN_ParmsNewLevel ParmsNewLevel /* pfnParmsNewLevel() */
|
||||
@ -122,7 +120,7 @@
|
||||
// #define FN_PM_Init PM_Init /* pfnPM_Init() Server version of player movement initialization; (wd) SDK2 */
|
||||
// #define FN_PM_FindTextureType PM_FindTextureType /* pfnPM_FindTextureType() (wd) SDK2 */
|
||||
// #define FN_SetupVisibility SetupVisibility /* pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2 */
|
||||
#define FN_UpdateClientData UpdateClientData /* pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2 */
|
||||
// #define FN_UpdateClientData UpdateClientData /* pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2 */
|
||||
// #define FN_AddToFullPack AddToFullPack /* pfnAddToFullPack() (wd) SDK2 */
|
||||
// #define FN_CreateBaseline CreateBaseline /* pfnCreateBaseline() Tweak entity baseline for network encoding allows setup of player baselines too.; (wd) SDK2 */
|
||||
// #define FN_RegisterEncoders RegisterEncoders /* pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2 */
|
||||
@ -157,10 +155,10 @@
|
||||
// #define FN_ClientPutInServer_Post ClientPutInServer_Post
|
||||
// #define FN_ClientCommand_Post ClientCommand_Post
|
||||
// #define FN_ClientUserInfoChanged_Post ClientUserInfoChanged_Post
|
||||
// #define FN_ServerActivate_Post ServerActivate_Post
|
||||
#define FN_ServerActivate_Post ServerActivate_Post
|
||||
// #define FN_ServerDeactivate_Post ServerDeactivate_Post
|
||||
#define FN_PlayerPreThink_Post PlayerPreThink_Post
|
||||
#define FN_PlayerPostThink_Post PlayerPostThink_Post
|
||||
// #define FN_PlayerPreThink_Post PlayerPreThink_Post
|
||||
// #define FN_PlayerPostThink_Post PlayerPostThink_Post
|
||||
// #define FN_StartFrame_Post StartFrame_Post
|
||||
// #define FN_ParmsNewLevel_Post ParmsNewLevel_Post
|
||||
// #define FN_ParmsChangeLevel_Post ParmsChangeLevel_Post
|
||||
@ -211,7 +209,7 @@
|
||||
// #define FN_AngleVectors AngleVectors
|
||||
// #define FN_CreateEntity CreateEntity
|
||||
// #define FN_RemoveEntity RemoveEntity
|
||||
#define FN_CreateNamedEntity CreateNamedEntity
|
||||
// #define FN_CreateNamedEntity CreateNamedEntity
|
||||
// #define FN_MakeStatic MakeStatic
|
||||
// #define FN_EntIsOnFloor EntIsOnFloor
|
||||
// #define FN_DropToFloor DropToFloor
|
||||
@ -395,7 +393,7 @@
|
||||
// #define FN_CVarGetString_Post CVarGetString_Post
|
||||
// #define FN_CVarSetFloat_Post CVarSetFloat_Post
|
||||
// #define FN_CVarSetString_Post CVarSetString_Post
|
||||
#define FN_AlertMessage_Post AlertMessage_Post
|
||||
// #define FN_AlertMessage_Post AlertMessage_Post
|
||||
// #define FN_EngineFprintf_Post EngineFprintf_Post
|
||||
// #define FN_PvAllocEntPrivateData_Post PvAllocEntPrivateData_Post
|
||||
// #define FN_PvEntPrivateData_Post PvEntPrivateData_Post
|
||||
@ -456,7 +454,7 @@
|
||||
// #define FN_GetPhysicsKeyValue_Post GetPhysicsKeyValue_Post
|
||||
// #define FN_SetPhysicsKeyValue_Post SetPhysicsKeyValue_Post
|
||||
// #define FN_GetPhysicsInfoString_Post GetPhysicsInfoString_Post
|
||||
// #define FN_PrecacheEvent_Post PrecacheEvent_Post
|
||||
#define FN_PrecacheEvent_Post PrecacheEvent_Post
|
||||
// #define FN_PlaybackEvent_Post PlaybackEvent_Post
|
||||
// #define FN_SetFatPVS_Post SetFatPVS_Post
|
||||
// #define FN_SetFatPAS_Post SetFatPAS_Post
|
||||
|
297
dlls/ns/sh_list.h
Normal file
297
dlls/ns/sh_list.h
Normal file
@ -0,0 +1,297 @@
|
||||
/* ======== SourceMM ========
|
||||
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): David "BAILOPAN" Anderson
|
||||
* ============================
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SMM_LIST_H
|
||||
#define _INCLUDE_SMM_LIST_H
|
||||
|
||||
// MSVC8 fix for offsetof macro redefition warnings
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1400
|
||||
#undef offsetof
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <new>
|
||||
#include <malloc.h>
|
||||
|
||||
//namespace SourceHook
|
||||
//{
|
||||
//This class is from CSDM for AMX Mod X
|
||||
/*
|
||||
A circular, doubly-linked list with one sentinel node
|
||||
|
||||
Empty:
|
||||
m_Head = sentinel
|
||||
m_Head->next = m_Head;
|
||||
m_Head->prev = m_Head;
|
||||
One element:
|
||||
m_Head = sentinel
|
||||
m_Head->next = node1
|
||||
m_Head->prev = node1
|
||||
node1->next = m_Head
|
||||
node1->prev = m_Head
|
||||
Two elements:
|
||||
m_Head = sentinel
|
||||
m_Head->next = node1
|
||||
m_Head->prev = node2
|
||||
node1->next = node2
|
||||
node1->prev = m_Head
|
||||
node2->next = m_Head
|
||||
node2->prev = node1
|
||||
*/
|
||||
template <class T>
|
||||
class List
|
||||
{
|
||||
public:
|
||||
class iterator;
|
||||
friend class iterator;
|
||||
class ListNode
|
||||
{
|
||||
public:
|
||||
ListNode(const T & o) : obj(o) { };
|
||||
ListNode() { };
|
||||
T obj;
|
||||
ListNode *next;
|
||||
ListNode *prev;
|
||||
};
|
||||
private:
|
||||
// Initializes the sentinel node.
|
||||
// BAIL used malloc instead of new in order to bypass the need for a constructor.
|
||||
ListNode *_Initialize()
|
||||
{
|
||||
ListNode *n = (ListNode *)malloc(sizeof(ListNode));
|
||||
n->next = n;
|
||||
n->prev = n;
|
||||
return n;
|
||||
}
|
||||
public:
|
||||
List() : m_Head(_Initialize()), m_Size(0)
|
||||
{
|
||||
}
|
||||
List(const List &src) : m_Head(_Initialize()), m_Size(0)
|
||||
{
|
||||
iterator iter;
|
||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
||||
push_back( (*iter) );
|
||||
}
|
||||
~List()
|
||||
{
|
||||
clear();
|
||||
|
||||
// Don't forget to free the sentinel
|
||||
if (m_Head)
|
||||
{
|
||||
free(m_Head);
|
||||
m_Head = NULL;
|
||||
}
|
||||
}
|
||||
void push_back(const T &obj)
|
||||
{
|
||||
ListNode *node = new ListNode(obj);
|
||||
|
||||
node->prev = m_Head->prev;
|
||||
node->next = m_Head;
|
||||
m_Head->prev->next = node;
|
||||
m_Head->prev = node;
|
||||
|
||||
m_Size++;
|
||||
}
|
||||
size_t size()
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
ListNode *node = m_Head->next;
|
||||
ListNode *temp;
|
||||
m_Head->next = m_Head;
|
||||
m_Head->prev = m_Head;
|
||||
|
||||
// Iterate through the nodes until we find g_Head (the sentinel) again
|
||||
while (node != m_Head)
|
||||
{
|
||||
temp = node->next;
|
||||
delete node;
|
||||
node = temp;
|
||||
}
|
||||
m_Size = 0;
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
return (m_Size == 0);
|
||||
}
|
||||
T & back()
|
||||
{
|
||||
return m_Head->prev->obj;
|
||||
}
|
||||
private:
|
||||
ListNode *m_Head;
|
||||
size_t m_Size;
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
friend class List;
|
||||
public:
|
||||
iterator()
|
||||
{
|
||||
m_This = NULL;
|
||||
}
|
||||
iterator(const List &src)
|
||||
{
|
||||
m_This = src.m_Head;
|
||||
}
|
||||
iterator(ListNode *n) : m_This(n)
|
||||
{
|
||||
}
|
||||
iterator(const iterator &where)
|
||||
{
|
||||
m_This = where.m_This;
|
||||
}
|
||||
//pre decrement
|
||||
iterator & operator--()
|
||||
{
|
||||
if (m_This)
|
||||
m_This = m_This->prev;
|
||||
return *this;
|
||||
}
|
||||
//post decrement
|
||||
iterator operator--(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
if (m_This)
|
||||
m_This = m_This->prev;
|
||||
return old;
|
||||
}
|
||||
|
||||
//pre increment
|
||||
iterator & operator++()
|
||||
{
|
||||
if (m_This)
|
||||
m_This = m_This->next;
|
||||
return *this;
|
||||
}
|
||||
//post increment
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
if (m_This)
|
||||
m_This = m_This->next;
|
||||
return old;
|
||||
}
|
||||
|
||||
const T & operator * () const
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
T & operator * ()
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
|
||||
T * operator -> ()
|
||||
{
|
||||
return &(m_This->obj);
|
||||
}
|
||||
const T * operator -> () const
|
||||
{
|
||||
return &(m_This->obj);
|
||||
}
|
||||
|
||||
bool operator != (const iterator &where) const
|
||||
{
|
||||
return (m_This != where.m_This);
|
||||
}
|
||||
bool operator ==(const iterator &where) const
|
||||
{
|
||||
return (m_This == where.m_This);
|
||||
}
|
||||
private:
|
||||
ListNode *m_This;
|
||||
};
|
||||
public:
|
||||
iterator begin() const
|
||||
{
|
||||
return iterator(m_Head->next);
|
||||
}
|
||||
iterator end() const
|
||||
{
|
||||
return iterator(m_Head);
|
||||
}
|
||||
iterator erase(iterator &where)
|
||||
{
|
||||
ListNode *pNode = where.m_This;
|
||||
iterator iter(where);
|
||||
iter++;
|
||||
|
||||
|
||||
// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
|
||||
pNode->prev->next = pNode->next;
|
||||
pNode->next->prev = pNode->prev;
|
||||
|
||||
delete pNode;
|
||||
m_Size--;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
iterator insert(iterator where, const T &obj)
|
||||
{
|
||||
// Insert obj right before where
|
||||
|
||||
ListNode *node = new ListNode(obj);
|
||||
ListNode *pWhereNode = where.m_This;
|
||||
|
||||
pWhereNode->prev->next = node;
|
||||
node->prev = pWhereNode->prev;
|
||||
pWhereNode->prev = node;
|
||||
node->next = pWhereNode;
|
||||
|
||||
m_Size++;
|
||||
|
||||
return iterator(node);
|
||||
}
|
||||
|
||||
public:
|
||||
void remove(const T & obj)
|
||||
{
|
||||
iterator b;
|
||||
for (b=begin(); b!=end(); b++)
|
||||
{
|
||||
if ( (*b) == obj )
|
||||
{
|
||||
erase( b );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename U>
|
||||
iterator find(const U & equ)
|
||||
{
|
||||
iterator iter;
|
||||
for (iter=begin(); iter!=end(); iter++)
|
||||
{
|
||||
if ( (*iter) == equ )
|
||||
return iter;
|
||||
}
|
||||
return end();
|
||||
}
|
||||
List & operator =(const List &src)
|
||||
{
|
||||
clear();
|
||||
iterator iter;
|
||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
||||
push_back( (*iter) );
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
//}; //NAMESPACE
|
||||
|
||||
#endif //_INCLUDE_CSDM_LIST_H
|
@ -1,57 +1,99 @@
|
||||
//======================================================================
|
||||
// Forward declarations for functions that deal directly with the engine
|
||||
//======================================================================
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef UTILFUNCTIONS_H
|
||||
#define UTILFUNCTIONS_H
|
||||
|
||||
#include "CPlayer.h"
|
||||
extern CPlayer g_player[33];
|
||||
|
||||
#define GET_PLAYER_E(x) (&g_player[ENTINDEX(x)]);
|
||||
#define GET_PLAYER_I(x) (&g_player[x]);
|
||||
|
||||
/*
|
||||
#define FLOAT_TO_CELL(x) *(cell*)&x
|
||||
#define CELL_TO_FLOAT(x) *(float*)&x
|
||||
*/
|
||||
#define FLOAT_TO_CELL amx_ftoc
|
||||
#define CELL_TO_FLOAT amx_ctof
|
||||
#include "NEW_Util.h" // include my experimental INDEXENT / ENTINDEX replacements
|
||||
|
||||
|
||||
|
||||
#define ABSOLUTE_VALUE_EASY(x) (((x) < 0) ? (-(x)) : (x)) //very useful for gpGlobals->time comparisons
|
||||
#define GetEdictModel(edict) ( (g_engfuncs.pfnInfoKeyValue((*g_engfuncs.pfnGetInfoKeyBuffer)(edict), "model")) )
|
||||
//#define INFO_KEY_VALUE(entity,keyname) (*g_engfuncs.pfnGetInfoKeyBuffer)(entity),keyname)
|
||||
#define GetKeyValue(edict,key) ( (g_engfuncs.pfnInfoKeyValue((*g_engfuncs.pfnGetInfoKeyBuffer)(edict), key)) )
|
||||
#define INFO_KEY_BUFFER (*g_engfuncs.pfnGetInfoKeyBuffer)
|
||||
#define INFO_KEY_VALUE (*g_engfuncs.pfnInfoKeyValue)
|
||||
#define GET_PLAYER_E(x) (&g_player[ENTINDEX_NEW(x)])
|
||||
#define GET_PLAYER_I(x) (&g_player[x])
|
||||
|
||||
|
||||
//just declare extra helper functions you need here
|
||||
edict_t *UTIL_FindEntityByString(edict_t *pentStart, const char *szKeyword, const char *szValue);
|
||||
edict_t *UTIL_PlayerByIndexE( int playerIndex );
|
||||
int LogToIndex(char logline[128]);
|
||||
int Find_Building_Hive(void);
|
||||
/**
|
||||
* Like GET_PLAYER_I, but this handles the invalid player index
|
||||
* as well as setting the CPlayer pointer.
|
||||
* NOTE: This declares CPlayer *player for you
|
||||
*/
|
||||
#define CreatePlayerPointer(AMX__, INDEX__) \
|
||||
if (INDEX__ < 1 || INDEX__ > gpGlobals->maxClients) \
|
||||
{ \
|
||||
return 0; \
|
||||
} \
|
||||
CPlayer *player = &g_player[INDEX__]
|
||||
|
||||
void GiveItem(edict_t *pEntity,char *szname);
|
||||
/**
|
||||
* Declares an edict (Entity) and verify it's not a player
|
||||
*/
|
||||
#define CreateNonPlayerEdict(AMX__, INDEX__) \
|
||||
if (INDEX__ <= gpGlobals->maxClients || INDEX__ > gpGlobals->maxEntities) \
|
||||
{ \
|
||||
return 0; \
|
||||
} \
|
||||
edict_t *Entity=INDEXENT_NEW(INDEX__)
|
||||
|
||||
void HudMessage(int index, const hudtextparms_t &textparms, const char *pMessage);
|
||||
void ClearHudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage);
|
||||
void UTIL_EmptyMenu(edict_t *pEntity, int keys, int time);
|
||||
void UTIL_FakeClientCmd(edict_t *pEntity, char *cmd);
|
||||
/**
|
||||
* Declares an edict (Entity) does not care if it is a player
|
||||
*/
|
||||
#define CreateEdict(AMX__, INDEX__, INVALIDRET__) \
|
||||
if (INDEX__ < 1 || INDEX__ > gpGlobals->maxEntities) \
|
||||
{ \
|
||||
return INVALIDRET__; \
|
||||
} \
|
||||
edict_t *Entity=INDEXENT_NEW(INDEX__)
|
||||
|
||||
inline edict_t* INDEXENT2( int iEdictNum )
|
||||
|
||||
/**
|
||||
* There is no need to use the AMXx provided calls as
|
||||
* they do an api call to recast, seems like overkill
|
||||
*/
|
||||
//#define amx_ftoc2(x) *((cell *)&x)
|
||||
//#define amx_ctof2(x) *((REAL *)&x)
|
||||
#define amx_ftoc3(x) *((cell *)x)
|
||||
#define amx_ctof3(x) *((REAL *)x)
|
||||
inline cell amx_ftoc2(REAL x)
|
||||
{
|
||||
if (iEdictNum >= 1 && iEdictNum <= gpGlobals->maxClients)
|
||||
{
|
||||
CPlayer *player = GET_PLAYER_I(iEdictNum);
|
||||
return player->edict;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (*g_engfuncs.pfnPEntityOfEntIndex)(iEdictNum);
|
||||
}
|
||||
}
|
||||
return *((cell *)&x);
|
||||
};
|
||||
inline REAL amx_ctof2(cell x)
|
||||
{
|
||||
return *((REAL *)&x);
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline BOOL isValidEntity(int x)
|
||||
{
|
||||
if (x < 0)
|
||||
@ -64,9 +106,151 @@ inline BOOL isValidEntity(int x)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
#define CHECK_ENTITY(x) if (x != 0 && (FNullEnt(INDEXENT2(x)) || x < 0 || x > gpGlobals->maxEntities)) return 0;
|
||||
#define CHECK_ENTITY(x) if (x != 0 && (FNullEnt(INDEXENT_NEW(x)) || x < 0 || x > gpGlobals->maxEntities)) return 0;
|
||||
#define CHECK_PARAMS(x) if (*params/sizeof(cell) < x) return 0;
|
||||
|
||||
|
||||
// Stuff in utils.cpp
|
||||
|
||||
edict_t *UTIL_FindEntityByString(edict_t *Start, const char *Keyword, const char *Value);
|
||||
|
||||
int UTIL_FindBuildingHive(void);
|
||||
|
||||
BOOL UTIL_CheckForPublic(const char *publicname);
|
||||
BOOL UTIL_CheckForNative(const char *NativeName);
|
||||
|
||||
class CPlayer;
|
||||
|
||||
CPlayer *UTIL_PlayerByCID(int CID);
|
||||
|
||||
// Converts something such as RESOURCES into OFFSET_WIN_RESOURCES or OFFSET_LIN_RESOURCES
|
||||
#ifdef __linux__
|
||||
#define MAKE_OFFSET(Offset) OFFSET_LIN_##Offset
|
||||
#define MAKE_MEMBER_OFFSET(Offs) (Offs - OFFSET_LIN_MEMBERFUNCSTART)
|
||||
#else
|
||||
#define MAKE_OFFSET(Offset) OFFSET_WIN_##Offset
|
||||
#define MAKE_MEMBER_OFFSET(Offs) (Offs - OFFSET_WIN_MEMBERFUNCSTART)
|
||||
#endif // __linux__
|
||||
|
||||
template <typename Output>
|
||||
inline Output get_private_p(edict_t *pEntity, int offset)
|
||||
{
|
||||
return (Output)(*(void**)((char*)(pEntity->pvPrivateData)+offset));
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts the private data pointer into an edict by
|
||||
* looking up the entvar pointer (first entry in cbaseentity)
|
||||
* and then getting pContainingEntity from that
|
||||
*/
|
||||
inline edict_t *private_to_edict(void *PrivateData)
|
||||
{
|
||||
if (PrivateData==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return (*((entvars_t **)((char *)PrivateData + MAKE_OFFSET(ENTVAR))))->pContainingEntity;
|
||||
};
|
||||
inline int clamp(int value, int min, int max)
|
||||
{
|
||||
if (value < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
if (value > max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
inline REAL clamp(REAL value, REAL min, REAL max)
|
||||
{
|
||||
if (value < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
if (value > max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
inline int clamp(int value, int min)
|
||||
{
|
||||
if (value < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline REAL clamp(REAL value, REAL min)
|
||||
{
|
||||
if (value < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int get_private(edict_t *pEntity, int offset)
|
||||
{
|
||||
return *(int*)((char*)(pEntity->pvPrivateData)+offset);
|
||||
}
|
||||
|
||||
inline REAL get_private_f(edict_t *pEntity, int offset)
|
||||
{
|
||||
return *(REAL*)((char*)(pEntity->pvPrivateData)+offset);
|
||||
}
|
||||
|
||||
inline void set_private(edict_t *pEntity, int offset, int value)
|
||||
{
|
||||
*(int*)((char*)(pEntity->pvPrivateData)+offset) = value;
|
||||
}
|
||||
inline int inc_private(edict_t *pEntity, int offset, int value)
|
||||
{
|
||||
return *(int*)((char*)(pEntity->pvPrivateData)+offset) = *(int*)((char*)(pEntity->pvPrivateData)+offset) + value;
|
||||
}
|
||||
inline int inc_private(edict_t *pEntity, int offset, int value, int min)
|
||||
{
|
||||
return *(int*)((char*)(pEntity->pvPrivateData)+offset) = clamp(*(int*)((char*)(pEntity->pvPrivateData)+offset) + value, min);
|
||||
}
|
||||
inline int inc_private(edict_t *pEntity, int offset, int value, int min, int max)
|
||||
{
|
||||
return *(int*)((char*)(pEntity->pvPrivateData)+offset) = clamp(*(int*)((char*)(pEntity->pvPrivateData)+offset) + value, min, max);
|
||||
}
|
||||
|
||||
inline void set_private_f(edict_t *pEntity, int offset, REAL value)
|
||||
{
|
||||
*(REAL*)((char*)(pEntity->pvPrivateData)+offset) = value;
|
||||
}
|
||||
inline REAL inc_private_f(edict_t *pEntity, int offset, REAL value)
|
||||
{
|
||||
return *(REAL*)((char*)(pEntity->pvPrivateData)+offset) = *(REAL*)((char*)(pEntity->pvPrivateData)+offset) + value;
|
||||
}
|
||||
inline REAL inc_private_f(edict_t *pEntity, int offset, REAL value, REAL min)
|
||||
{
|
||||
return *(REAL*)((char*)(pEntity->pvPrivateData)+offset) = clamp(*(REAL*)((char*)(pEntity->pvPrivateData)+offset) + value, min);
|
||||
}
|
||||
inline REAL inc_private_f(edict_t *pEntity, int offset, REAL value, REAL min, REAL max)
|
||||
{
|
||||
return *(REAL*)((char*)(pEntity->pvPrivateData)+offset) = clamp(*(REAL*)((char*)(pEntity->pvPrivateData)+offset) + value, min, max);
|
||||
}
|
||||
|
||||
inline unsigned char get_private_b(edict_t *pEntity, int offset)
|
||||
{
|
||||
return *(((unsigned char*)pEntity->pvPrivateData)+offset);
|
||||
};
|
||||
inline unsigned char set_private_b(edict_t *pEntity, int offset, unsigned char value)
|
||||
{
|
||||
return *(((unsigned char*)pEntity->pvPrivateData)+offset)=value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // UTILFUNCTIONS_H
|
||||
|
||||
|
192
dlls/ns/utils.cpp
Normal file
192
dlls/ns/utils.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "sdk/amxxmodule.h"
|
||||
|
||||
|
||||
#include "ns.h"
|
||||
#include "utilfunctions.h"
|
||||
|
||||
#include "CPlayer.h"
|
||||
|
||||
|
||||
/**
|
||||
* Scans through all hives and finds the one currently building
|
||||
*/
|
||||
int UTIL_FindBuildingHive(void)
|
||||
{
|
||||
edict_t *Entity=NULL;
|
||||
|
||||
while ((Entity = UTIL_FindEntityByString(Entity,"classname","team_hive")))
|
||||
{
|
||||
// is alive active not fully built
|
||||
if (Entity->v.health > 0 && Entity->v.solid > 0 && Entity->v.fuser1 < 1000)
|
||||
{
|
||||
return ENTINDEX_NEW(Entity);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
edict_t *UTIL_FindEntityByString(edict_t *Start, const char *Keyword, const char *Value)
|
||||
{
|
||||
edict_t *Entity;
|
||||
|
||||
Entity=FIND_ENTITY_BY_STRING(Start, Keyword, Value);
|
||||
|
||||
if(!FNullEnt(Entity))
|
||||
{
|
||||
return Entity;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the provided native is used in a loaded plugin
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
BOOL UTIL_CheckForNative(const char *NativeName)
|
||||
{
|
||||
AMX *amx;
|
||||
char blah[64];
|
||||
int FunctionIndex;
|
||||
int i=0;
|
||||
|
||||
strncpy(blah,NativeName,63);
|
||||
|
||||
// Loop through all running scripts
|
||||
while((amx=MF_GetScriptAmx(i++))!=NULL)
|
||||
{
|
||||
// Scan for native
|
||||
if (MF_AmxFindNative(amx, blah, &FunctionIndex) == AMX_ERR_NONE)
|
||||
{
|
||||
// Native was found.
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE; // no native found in any loaded script
|
||||
}
|
||||
/**
|
||||
* Scans an amxx plugin for a public
|
||||
* returns whether or not that public exists
|
||||
*/
|
||||
BOOL UTIL_CheckForPublic(const char *publicname)
|
||||
{
|
||||
AMX *amx;
|
||||
char blah[64];
|
||||
int FunctionIndex;
|
||||
int i=0;
|
||||
|
||||
strncpy(blah,publicname,63);
|
||||
|
||||
// Loop through all running scripts
|
||||
while((amx=MF_GetScriptAmx(i++))!=NULL)
|
||||
{
|
||||
// Scan for public
|
||||
if (MF_AmxFindPublic(amx, blah, &FunctionIndex) == AMX_ERR_NONE)
|
||||
{
|
||||
// Public was found.
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE; // no public found in any loaded script
|
||||
}
|
||||
|
||||
CPlayer *UTIL_PlayerByCID(int CID)
|
||||
{
|
||||
int i=0;
|
||||
while (i++<gpGlobals->maxClients)
|
||||
{
|
||||
if (GETPLAYERUSERID(g_player[i].GetEdict())==CID)
|
||||
{
|
||||
return &g_player[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a log string (eg: "sawce<1><STEAM_0:1:4560311><marine1team>")
|
||||
* into a player index
|
||||
*/
|
||||
int UTIL_LogToIndex(const char *LogLine)
|
||||
{
|
||||
char NameBuffer[33] ; // Temporary buffer to store the CID String
|
||||
char *StrLocation; // Location in the LogLine pointer
|
||||
unsigned int Count=0; // Count for how many <'s we've passed
|
||||
size_t Length; // Length of LogLine
|
||||
|
||||
Length=strlen(LogLine);
|
||||
StrLocation=const_cast<char *>(LogLine) + Length; // Should now point to the last >
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
if (*StrLocation--=='<')
|
||||
{
|
||||
if (++Count==3) // 3rd match is end of CID
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Count!=3) // Invalid name somehow??
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Length > 32) // The name is too long somehow? stop here...
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
strncpy(NameBuffer,LogLine,Length);
|
||||
|
||||
Count=0;
|
||||
|
||||
while ((int)Count++<gpGlobals->maxClients)
|
||||
{
|
||||
if (strcmp(NameBuffer,STRING(INDEXENT_NEW(Count)->v.netname))==0)
|
||||
{
|
||||
return Count;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user