Move dlls/ to modules/

This commit is contained in:
xPaw
2015-03-13 15:18:47 +02:00
parent 54c978addb
commit e09f434ed8
365 changed files with 2233 additions and 2233 deletions

32
modules/ns/AMBuilder Normal file
View File

@ -0,0 +1,32 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os.path
binary = AMXX.MetaModule(builder, 'ns')
binary.compiler.defines += [
'HAVE_STDINT_H',
]
binary.sources = [
'../../public/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',
]
if builder.target_platform == 'windows':
binary.sources += ['version.rc']
AMXX.modules += [builder.Add(binary)]

100
modules/ns/AllocString.h Normal file
View File

@ -0,0 +1,100 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
/* This file 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 <am-string.h>
#include <am-linkedlist.h>
class StringManager
{
private:
ke::LinkedList<ke::AString *> 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)
{
ke::LinkedList<ke::AString *>::iterator end;
ke::LinkedList<ke::AString *>::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)
{
ke::LinkedList<ke::AString *>::iterator end;
ke::LinkedList<ke::AString *>::iterator iter;
iter=m_StringList.begin();
end=m_StringList.end();
while (iter!=end)
{
if (strcmp(str, (*iter)->chars()) == 0)
{
// String is already in the list, do not allocate it again
return MAKE_STRING((*iter)->chars());
}
++iter;
}
// Was not found in the linked list, allocate it and add it to the list
ke::AString *AllocStr = new ke::AString(str);
m_StringList.append(AllocStr);
return MAKE_STRING(AllocStr->chars());
};
};
extern StringManager AllocStringList;
/**
* Simple wrapper to make conversion easier
*/
inline int ALLOC_STRING2(const char *InputString)
{
return AllocStringList.Allocate(InputString);
}
#endif // ALLOCSTRING_H

418
modules/ns/CPlayer.h Normal file
View File

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

2108
modules/ns/FastDelegate.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,97 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
/* This holds the functions which determine which hooks I need forwareded */
#include "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;
}
};

296
modules/ns/GameManager.h Normal file
View File

@ -0,0 +1,296 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
/* This file includes game-related stuff, such as message IDs
* and forwards
*/
#ifndef GAMEMANAGER_H
#define GAMEMANAGER_H
#include <am-string.h>
class GameManager
{
private:
// Basic game variables
int m_IsCombat;
int m_HudText2; // Message IDS
int m_SetFOV;
// Forwards
int m_ChangeclassForward;
int m_BuiltForward;
int m_SpawnForward;
int m_TeamForward;
int m_RoundStartForward;
int m_RoundEndForward;
int m_MapResetForward;
REAL m_fRoundStartTime; // Time the match should start
int m_RoundInProgress; // Whether or not there is a match in progress
edict_t *m_SavedEdict; // saved edict for client_built
int m_iTitlesMap;
bool m_SendMapReset;
public:
GameManager()
{
m_SendMapReset = true;
m_IsCombat=0;
m_HudText2=0;
m_SetFOV=0;
m_SavedEdict=NULL;
m_RoundInProgress=0;
ResetForwards();
};
inline void CheckMap(void)
{
ke::AString MapName;
MapName = UTIL_ToLowerCase(STRING(gpGlobals->mapname));
m_iTitlesMap=0;
if (MapName.compare("ns_bast")==0 ||
MapName.compare("ns_bast_classic") == 0 ||
MapName.compare("ns_hera") == 0 ||
MapName.compare("ns_nothing") == 0 ||
MapName.compare("ns_caged") == 0 ||
MapName.compare("ns_tanith") == 0 ||
MapName.compare("ns_eclipse") == 0 ||
MapName.compare("ns_veil") == 0 ||
MapName.compare("ns_nancy") == 0)
{
m_iTitlesMap=1;
}
};
inline int &TitleMap(void)
{
return m_iTitlesMap;
};
inline void SetCombat(int value)
{
m_IsCombat=value;
};
inline int &IsCombat(void)
{
return m_IsCombat;
};
inline void UpdateHudText2(void)
{
if (!m_HudText2)
{
GetMessageIDs();
}
};
inline void UpdateSetFOV(void)
{
if (!m_SetFOV)
{
GetMessageIDs();
}
};
inline int &GetHudText2(void)
{
return m_HudText2;
};
inline int &GetSetFOV(void)
{
return m_SetFOV;
};
inline void GetMessageIDs(void)
{
m_HudText2=GET_USER_MSG_ID(&Plugin_info,"HudText2",NULL);
m_SetFOV=GET_USER_MSG_ID(&Plugin_info,"SetFOV",NULL);
};
inline void EvaluateCombat(void)
{
const char *Map=STRING(gpGlobals->mapname);
// if map starts with co_ it is combat
// otherwise it is classic gameplay
if ((Map[0]=='c' || Map[0]=='C') &&
(Map[1]=='o' || Map[1]=='O') &&
(Map[2]=='_'))
{
SetCombat(1);
return;
}
SetCombat(0);
};
inline void ResetForwards(void)
{
m_ChangeclassForward=-1;
m_BuiltForward=-1;
m_SpawnForward=-1;
m_TeamForward=-1;
m_RoundStartForward=-1;
m_RoundEndForward=-1;
m_MapResetForward=-1;
};
inline void RegisterForwards(void)
{
ResetForwards();
m_SpawnForward = MF_RegisterForward("client_spawn",ET_IGNORE,FP_CELL/*id*/,FP_DONE);
m_TeamForward = MF_RegisterForward("client_changeteam",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*new team*/,FP_CELL/*old team*/,FP_DONE);
m_ChangeclassForward = MF_RegisterForward("client_changeclass", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
m_RoundStartForward = MF_RegisterForward("round_start", ET_IGNORE, FP_DONE);
m_RoundEndForward = MF_RegisterForward("round_end", ET_IGNORE, FP_FLOAT, FP_DONE);
m_MapResetForward = MF_RegisterForward("map_reset", ET_IGNORE, FP_CELL, FP_DONE);
};
inline void StartFrame(void)
{
if (gpGlobals->time >= m_fRoundStartTime)
{
g_pFunctionTable->pfnStartFrame=NULL;
RoundStart();
}
};
/**
* This is called from MessageHandler's Countdown
* hook. It passes the only byte sent (time)
*/
inline void HandleCountdown(int &Time)
{
// Begin hooking start frame
g_pFunctionTable->pfnStartFrame=::StartFrame;
// set time of round start
m_fRoundStartTime=gpGlobals->time + Time;
m_SendMapReset = true;
};
/**
* This is called from MessageHandler's GameStatus
* hook. It passes the first byte sent.
* 2 = Round End
*/
inline void HandleGameStatus(int &FirstByte)
{
switch (FirstByte)
{
case 0:
if (m_SendMapReset)
{
MF_ExecuteForward(m_MapResetForward, 0);
}
m_SendMapReset = false;
break;
case 1:
MF_ExecuteForward(m_MapResetForward, 1);
break;
case 2:
RoundEnd();
break;
}
};
inline void RoundStart()
{
m_RoundInProgress=1;
MF_ExecuteForward(m_RoundStartForward);
};
inline void RoundEnd()
{
m_RoundInProgress=0;
MF_ExecuteForward(m_RoundEndForward,gpGlobals->time - m_fRoundStartTime);
};
inline int &RoundInProgress()
{
return m_RoundInProgress;
};
// no need to check -1 forwards in these
// amxmodx checks it anyway
inline void ExecuteClientBuilt(int &PlayerID, int StructureID, int &StructureType, int &Impulse)
{
MF_ExecuteForward(m_BuiltForward,PlayerID, StructureID, StructureType, Impulse);
};
inline void ExecuteClientSpawn(int &PlayerID)
{
MF_ExecuteForward(m_SpawnForward,PlayerID);
};
inline void ExecuteClientChangeTeam(int &PlayerID, int &NewTeam, int &OldTeam)
{
MF_ExecuteForward(m_TeamForward, PlayerID, NewTeam, OldTeam);
};
inline void ExecuteClientChangeClass(int &PlayerID, int &NewClass, int &OldClass)
{
MF_ExecuteForward(m_ChangeclassForward,PlayerID,NewClass,OldClass);
};
inline void ExecuteRoundStart(void)
{
MF_ExecuteForward(m_RoundStartForward);
};
inline void ExecuteRoundEnd(void)
{
MF_ExecuteForward(m_RoundEndForward);
};
/**
* The next few functions tell the module what metamod hooks
* i need. This tries to run-time optimize out what we
* do not need.
*/
void HookPreThink(void);
void HookPostThink_Post(void);
void HookPreThink_Post(void);
void HookUpdateClientData(void);
void HookLogs(void); // AlertMessage AND CreateNamedEntity
inline void CheckAllHooks(void)
{
HookPreThink();
HookPostThink_Post();
HookPreThink_Post();
HookUpdateClientData();
HookLogs();
};
inline void SetTemporaryEdict(edict_t *Edict)
{
m_SavedEdict=Edict;
};
inline edict_t *GetTemporaryEdict(void)
{
return m_SavedEdict;
};
};
extern GameManager GameMan;
#endif // GAMEMANAGER_H

178
modules/ns/Hash.h Normal file
View File

@ -0,0 +1,178 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#ifndef _HASH_H_
#define _HASH_H_
#include <am-vector.h>
#include <am-string.h>
// Just a very simple hash map, no iteration or anything of the like (not needed)
inline int HashFunction(const ke::AString& 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.length();
if (size == 0)
{
return 0;
}
int hasha = kHashNumTable[(*(name.chars() + (size - 1))) & 0x7F];
int hashb = kHashNumTable[size % 128];
unsigned char c = 0;
for (size_t i = 0; i < size; i++)
{
c = (*(name.chars() + (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 = ke::AString, typename D = ke::AString, int (*F)(const K&) = HashFunction, int B = 1024>
class Hash
{
protected:
ke::Vector<int> m_HashBuckets[B];
ke::Vector<K> m_KeyBuckets[B];
ke::Vector<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].append(hash);
m_KeyBuckets[bucketnum].append(key);
m_DataBuckets[bucketnum].append(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].append(hash);
m_KeyBuckets[bucketnum].append(key);
m_DataBuckets[bucketnum].append(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
ke::Vector<int>* hashbucket = &m_HashBuckets[bucketnum];
ke::Vector<K>* keybucket = &m_KeyBuckets[bucketnum];
size_t bucketsize = hashbucket->length();
for (size_t i = 0; i < bucketsize; i++)
{
if (hashbucket->at(i) == hash)
{
if (key.compare(keybucket->at(i).chars()) == 0)
{
return &(m_DataBuckets[bucketnum].at(i));
}
}
}
return NULL;
};
};
#endif

View File

@ -0,0 +1,98 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#ifndef LOCATIONMANAGER_H
#define LOCATIONMANAGER_H
#include <am-vector.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:
ke::Vector<location_data_t> m_LocationList;
public:
LocationManager()
{
Clear();
};
inline void Clear(void)
{
m_LocationList.clear();
m_LocationList.ensure(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);
ke::AString NameString(UTIL_ToLowerCase(Name));
Temp.titlelookup=TitleMan.Lookup(NameString);
m_LocationList.append(Temp);
};
inline const char *Lookup(vec3_t origin, cell titlelookup)
{
unsigned int i=0;
location_data_t Temp;
while (i<m_LocationList.length())
{
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

134
modules/ns/Makefile Normal file
View File

@ -0,0 +1,134 @@
# (C)2004-2013 AMX Mod X Development Team
# Makefile written by David "BAILOPAN" Anderson
###########################################
### EDIT THESE PATHS FOR YOUR OWN SETUP ###
###########################################
HLSDK = ../../../hlsdk
MM_ROOT = ../../../metamod/metamod
PUBLIC_ROOT = ../../public
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
PROJECT = ns
OBJECTS = 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
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -fomit-frame-pointer -pipe
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc
CPP_OSX = clang
LINK =
INCLUDE = -I. -I$(PUBLIC_ROOT) -I$(PUBLIC_ROOT)/sdk -I$(PUBLIC_ROOT)/amtl \
-I$(HLSDK) -I$(HLSDK)/public -I$(HLSDK)/common -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/pm_shared\
-I$(MM_ROOT)
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
################################################
OS := $(shell uname -s)
ifeq "$(OS)" "Darwin"
CPP = $(CPP_OSX)
LIB_EXT = dylib
LIB_SUFFIX = _amxx
CFLAGS += -DOSX
LINK += -dynamiclib -lstdc++ -mmacosx-version-min=10.5
else
LIB_EXT = so
LIB_SUFFIX = _amxx_i386
CFLAGS += -DLINUX
LINK += -shared
endif
LINK += -m32 -lm -ldl
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32 -DHAVE_STDINT_H -fno-strict-aliasing -m32 -Wall -Werror
CPPFLAGS += -fno-exceptions -fno-rtti
BINARY = $(PROJECT)$(LIB_SUFFIX).$(LIB_EXT)
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS += $(C_DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS += $(C_OPT_FLAGS)
LINK += -s
endif
IS_CLANG := $(shell $(CPP) --version | head -1 | grep clang > /dev/null && echo "1" || echo "0")
ifeq "$(IS_CLANG)" "1"
CPP_MAJOR := $(shell $(CPP) --version | grep clang | sed "s/.*version \([0-9]\)*\.[0-9]*.*/\1/")
CPP_MINOR := $(shell $(CPP) --version | grep clang | sed "s/.*version [0-9]*\.\([0-9]\)*.*/\1/")
else
CPP_MAJOR := $(shell $(CPP) -dumpversion >&1 | cut -b1)
CPP_MINOR := $(shell $(CPP) -dumpversion >&1 | cut -b3)
endif
# Clang || GCC >= 4
ifeq "$(shell expr $(IS_CLANG) \| $(CPP_MAJOR) \>= 4)" "1"
CFLAGS += $(C_GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS)
endif
# Clang >= 3 || GCC >= 4.7
ifeq "$(shell expr $(IS_CLANG) \& $(CPP_MAJOR) \>= 3 \| $(CPP_MAJOR) \>= 4 \& $(CPP_MINOR) \>= 7)" "1"
CPPFLAGS += -Wno-delete-non-virtual-dtor
endif
# GCC >= 4.8
ifeq "$(shell expr $(IS_CLANG) \= 0 \& \( \( $(CPP_MAJOR) \= 4 \& $(CPP_MINOR) \>= 8 \) \| $(CPP_MAJOR) \> 4 \))" "1"
CFLAGS += -Wno-unused-local-typedefs
endif
# OS is Linux and not using clang
ifeq "$(shell expr $(OS) \= Linux \& $(IS_CLANG) \= 0)" "1"
LINK += -static-libgcc
endif
OBJ_BIN := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
# This will break if we include other Makefiles, but is fine for now. It allows
# us to make a copy of this file that uses altered paths (ie. Makefile.mine)
# or other changes without mucking up the original.
MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)
mkdir -p $(BIN_DIR)/natives
ln -sf $(PUBLIC_ROOT)/sdk/amxxmodule.cpp
$(MAKE) -f $(MAKEFILE_NAME) $(PROJECT)
$(PROJECT): $(OBJ_BIN)
$(CPP) $(INCLUDE) $(OBJ_BIN) $(LINK) -o $(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f $(MAKEFILE_NAME) all DEBUG=true
default: all
clean:
rm -rf $(BIN_DIR)/*.o
rm -rf $(BIN_DIR)/natives/*.o
rm -f $(BIN_DIR)/$(BINARY)

View File

@ -0,0 +1,182 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
/* This file 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 "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);
};

158
modules/ns/MessageHandler.h Normal file
View File

@ -0,0 +1,158 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
/* 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

80
modules/ns/NEW_Util.h Normal file
View File

@ -0,0 +1,80 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
/* 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

View File

@ -0,0 +1,129 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include "amxxmodule.h"
#include "ns.h"
#include "ParticleManager.h"
void ParticleManager::ReadFile(void)
{
this->Prune();
if (m_iFileLoaded!=0)
{
return;
}
m_iFileLoaded=1;
char FileName[256];
UTIL_Format(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);
};

View File

@ -0,0 +1,124 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#ifndef PARTICLEMANAGER_H
#define PARTICLEMANAGER_H
#include <am-vector.h>
#include <am-string.h>
typedef struct psystem_s
{
ke::AString Name;
int id;
int IsStatic; // Set to 1 if the particle system is loaded from ns.ps
} ParticleSystem;
class ParticleManager
{
private:
ke::Vector<ParticleSystem *> Systems;
int m_iFileLoaded;
unsigned short m_iEventID;
public:
ParticleManager()
{
m_iFileLoaded=0;
m_iEventID=0;
Systems.ensure(64);
};
// Remove all non-static particle systems
inline void Prune()
{
for (size_t i = 0; i < Systems.length(); ++i)
{
if (Systems[i]->IsStatic)
{
break;
}
Systems.remove(i);
delete Systems.at(i);
if (!Systems.length())
{
break;
}
}
};
void ReadFile(void);
inline int Add(const char *Start, int Static)
{
ParticleSystem *ps=new ParticleSystem;
ps->id=Systems.length();
ps->IsStatic=Static;
ps->Name = Start;
Systems.append(ps);
return Systems.length()-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)
{
for (size_t i = 0; i < Systems.length(); ++i)
{
if (strcmp(Needle, Systems[i]->Name.chars()) == 0)
{
return Systems[i]->id;
}
}
return -1;
};
};
extern ParticleManager ParticleMan;
#endif // PARTICLEMANAGER_H

108
modules/ns/SpawnManager.h Normal file
View File

@ -0,0 +1,108 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#ifndef SPAWNMANAGER_H
#define SPAWNMANAGER_H
#include <am-vector.h>
typedef struct spawndata_s
{
REAL Location[3];
REAL Angle[3];
} SpawnData;
class SpawnManager
{
private:
ke::Vector<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].ensure(32);
TeamSpawns[1].ensure(16);
TeamSpawns[2].ensure(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].append(TemporaryData);
};
inline void InsertReadyRoom(const edict_t *Entity)
{
SpawnData TemporaryData;
Entity->v.origin.CopyToArray(TemporaryData.Location);
Entity->v.angles.CopyToArray(TemporaryData.Angle);
TeamSpawns[0].append(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]].length());
}
if (params[2]>=(int)TeamSpawns[params[1]].length())
{
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

153
modules/ns/TitleManager.cpp Normal file
View File

@ -0,0 +1,153 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include "amxxmodule.h"
#include "ns.h"
#include "TitleManager.h"
#include "utilfunctions.h"
void TitleManager::LoadTitles(void)
{
if (m_Loaded!=0) // already loaded?
{
return;
}
m_Loaded=1;
char FileName[128];
UTIL_Format(FileName, sizeof(FileName)-1, "%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
ke::AString key(UTIL_ToLowerCase(KeyName));
this->m_Hash.insert(key, new ke::AString(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);
};

58
modules/ns/TitleManager.h Normal file
View File

@ -0,0 +1,58 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#ifndef TITLEMANAGER_H
#define TITLEMANAGER_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <am-string.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<ke::AString, ke::AString*> m_Hash;
public:
TitleManager()
{
m_Loaded=0;
};
inline const char *Lookup(ke::AString &input)
{
ke::AString** ret = m_Hash.find(input);
if (ret == NULL || *ret == NULL)
{
// was not found
return NULL;
}
return (*ret)->chars();
};
void LoadTitles(void);
};
extern TitleManager TitleMan;
#endif // TITLEMANAGER_H

91
modules/ns/amxxapi.cpp Normal file
View File

@ -0,0 +1,91 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
/* Calls sent by AMX Mod X are handled here */
#include "sdk/amxxmodule.h"
#include "ns.h"
#include "utilfunctions.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();
}
int AmxxCheckGame(const char *game)
{
if (strcasecmp(game, "ns") == 0 ||
strcasecmp(game, "nsp") == 0)
{
return AMXX_GAME_OK;
}
return AMXX_GAME_BAD;
}
// Module is attaching to AMXX
void OnAmxxAttach()
{
AddNatives_MemberFunc();
AddNatives_Particles();
AddNatives_Player();
AddNatives_PlayerMemory();
AddNatives_Weapons();
AddNatives_Structure();
AddNatives_General();
MFuncs_Initialize();
}

214
modules/ns/dllapi.cpp Normal file
View File

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

292
modules/ns/engineapi.cpp Normal file
View File

@ -0,0 +1,292 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
/* Calls going from the game dll to the engine are handled here */
#include "amxxmodule.h"
#include "ns.h"
#include "utilfunctions.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, const 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);
}

510
modules/ns/moduleconfig.h Normal file
View File

@ -0,0 +1,510 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Module Config
//
#ifndef __MODULECONFIG_H__
#define __MODULECONFIG_H__
#include <amxmodx_version.h>
// Module info
#define MODULE_NAME "NS"
#define MODULE_VERSION AMXX_VERSION
#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
#ifdef __DATE__
#define MODULE_DATE __DATE__
#else // __DATE__
#define MODULE_DATE "Unknown"
#endif // __DATE__
// metamod plugin?
#define USE_METAMOD
// use memory manager/tester?
// note that if you use this, you cannot construct/allocate
// anything before the module attached (OnAmxxAttach).
// be careful of default constructors using new/malloc!
// #define MEMORY_TEST
// Unless you use STL or exceptions, keep this commented.
// It allows you to compile without libstdc++.so as a dependency
// #define NO_ALLOC_OVERRIDES
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself
// #define NO_MSVC8_AUTO_COMPAT
/**
* AMXX Init functions
* Also consider using FN_META_*
*/
/** AMXX query */
//#define FN_AMXX_QUERY OnAmxxQuery
/** AMXX Check Game - module API is NOT available here.
* Return AMXX_GAME_OK if this module can load on the game, AMXX_GAME_BAD if it cannot.
* syntax: int AmxxCheckGame(const char *game)
*/
#define FN_AMXX_CHECKGAME AmxxCheckGame
/** AMXX attach
* Do native functions init here (MF_AddNatives)
*/
#define FN_AMXX_ATTACH OnAmxxAttach
/** AMXX Detach (unload) */
//#define FN_AMXX_DETACH OnAmxxDetach
/** All plugins loaded
* Do forward functions init here (MF_RegisterForward)
*/
#define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
/** All plugins are about to be unloaded */
//#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
/** All plugins are now unloaded */
//#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
/**** METAMOD ****/
// If your module doesn't use metamod, you may close the file now :)
#ifdef USE_METAMOD
// ----
// Hook Functions
// Uncomment these to be called
// You can also change the function name
// - Metamod init functions
// Also consider using FN_AMXX_*
// Meta query
//#define FN_META_QUERY OnMetaQuery
// Meta attach
//#define FN_META_ATTACH OnMetaAttach
// Meta detach
//#define FN_META_DETACH OnMetaDetach
// (wd) are Will Day's notes
// - GetEntityAPI2 functions
// #define FN_GameDLLInit GameDLLInit /* pfnGameInit() */
#define FN_DispatchSpawn DispatchSpawn /* pfnSpawn() */
// #define FN_DispatchThink DispatchThink /* pfnThink() */
// #define FN_DispatchUse DispatchUse /* pfnUse() */
// #define FN_DispatchTouch DispatchTouch /* pfnTouch() */
// #define FN_DispatchBlocked DispatchBlocked /* pfnBlocked() */
#define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
// #define FN_DispatchSave DispatchSave /* pfnSave() */
// #define FN_DispatchRestore DispatchRestore /* pfnRestore() */
// #define FN_DispatchObjectCollsionBox DispatchObjectCollsionBox /* pfnSetAbsBox() */
// #define FN_SaveWriteFields SaveWriteFields /* pfnSaveWriteFields() */
// #define FN_SaveReadFields SaveReadFields /* pfnSaveReadFields() */
// #define FN_SaveGlobalState SaveGlobalState /* pfnSaveGlobalState() */
// #define FN_RestoreGlobalState RestoreGlobalState /* pfnRestoreGlobalState() */
// #define FN_ResetGlobalState ResetGlobalState /* pfnResetGlobalState() */
#define FN_ClientConnect ClientConnect /* pfnClientConnect() (wd) Client has connected */
#define FN_ClientDisconnect ClientDisconnect /* pfnClientDisconnect() (wd) Player has left the game */
// #define FN_ClientKill ClientKill /* pfnClientKill() (wd) Player has typed "kill" */
// #define FN_ClientPutInServer ClientPutInServer /* pfnClientPutInServer() (wd) Client is entering the game */
// #define FN_ClientCommand ClientCommand /* pfnClientCommand() (wd) Player has sent a command (typed or from a bind) */
// #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_PlayerPostThink PlayerPostThink /* pfnPlayerPostThink() */
// #define FN_StartFrame StartFrame /* pfnStartFrame() */
// #define FN_ParmsNewLevel ParmsNewLevel /* pfnParmsNewLevel() */
// #define FN_ParmsChangeLevel ParmsChangeLevel /* pfnParmsChangeLevel() */
// #define FN_GetGameDescription GetGameDescription /* pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2" "Half-Life" */
// #define FN_PlayerCustomization PlayerCustomization /* pfnPlayerCustomization() Notifies .dll of new customization for player. */
// #define FN_SpectatorConnect SpectatorConnect /* pfnSpectatorConnect() Called when spectator joins server */
// #define FN_SpectatorDisconnect SpectatorDisconnect /* pfnSpectatorDisconnect() Called when spectator leaves the server */
// #define FN_SpectatorThink SpectatorThink /* pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t) */
// #define FN_Sys_Error Sys_Error /* pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2 */
// #define FN_PM_Move PM_Move /* pfnPM_Move() (wd) SDK2 */
// #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_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 */
// #define FN_GetWeaponData GetWeaponData /* pfnGetWeaponData() (wd) SDK2 */
// #define FN_CmdStart CmdStart /* pfnCmdStart() (wd) SDK2 */
// #define FN_CmdEnd CmdEnd /* pfnCmdEnd() (wd) SDK2 */
// #define FN_ConnectionlessPacket ConnectionlessPacket /* pfnConnectionlessPacket() (wd) SDK2 */
// #define FN_GetHullBounds GetHullBounds /* pfnGetHullBounds() (wd) SDK2 */
// #define FN_CreateInstancedBaselines CreateInstancedBaselines /* pfnCreateInstancedBaselines() (wd) SDK2 */
// #define FN_InconsistentFile InconsistentFile /* pfnInconsistentFile() (wd) SDK2 */
// #define FN_AllowLagCompensation AllowLagCompensation /* pfnAllowLagCompensation() (wd) SDK2 */
// - GetEntityAPI2_Post functions
// #define FN_GameDLLInit_Post GameDLLInit_Post
// #define FN_DispatchSpawn_Post DispatchSpawn_Post
// #define FN_DispatchThink_Post DispatchThink_Post
// #define FN_DispatchUse_Post DispatchUse_Post
// #define FN_DispatchTouch_Post DispatchTouch_Post
// #define FN_DispatchBlocked_Post DispatchBlocked_Post
// #define FN_DispatchKeyValue_Post DispatchKeyValue_Post
// #define FN_DispatchSave_Post DispatchSave_Post
// #define FN_DispatchRestore_Post DispatchRestore_Post
// #define FN_DispatchObjectCollsionBox_Post DispatchObjectCollsionBox_Post
// #define FN_SaveWriteFields_Post SaveWriteFields_Post
// #define FN_SaveReadFields_Post SaveReadFields_Post
// #define FN_SaveGlobalState_Post SaveGlobalState_Post
// #define FN_RestoreGlobalState_Post RestoreGlobalState_Post
// #define FN_ResetGlobalState_Post ResetGlobalState_Post
// #define FN_ClientConnect_Post ClientConnect_Post
// #define FN_ClientDisconnect_Post ClientDisconnect_Post
// #define FN_ClientKill_Post ClientKill_Post
// #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_ServerDeactivate_Post ServerDeactivate_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
// #define FN_GetGameDescription_Post GetGameDescription_Post
// #define FN_PlayerCustomization_Post PlayerCustomization_Post
// #define FN_SpectatorConnect_Post SpectatorConnect_Post
// #define FN_SpectatorDisconnect_Post SpectatorDisconnect_Post
// #define FN_SpectatorThink_Post SpectatorThink_Post
// #define FN_Sys_Error_Post Sys_Error_Post
// #define FN_PM_Move_Post PM_Move_Post
// #define FN_PM_Init_Post PM_Init_Post
// #define FN_PM_FindTextureType_Post PM_FindTextureType_Post
// #define FN_SetupVisibility_Post SetupVisibility_Post
// #define FN_UpdateClientData_Post UpdateClientData_Post
// #define FN_AddToFullPack_Post AddToFullPack_Post
// #define FN_CreateBaseline_Post CreateBaseline_Post
// #define FN_RegisterEncoders_Post RegisterEncoders_Post
// #define FN_GetWeaponData_Post GetWeaponData_Post
// #define FN_CmdStart_Post CmdStart_Post
// #define FN_CmdEnd_Post CmdEnd_Post
// #define FN_ConnectionlessPacket_Post ConnectionlessPacket_Post
// #define FN_GetHullBounds_Post GetHullBounds_Post
// #define FN_CreateInstancedBaselines_Post CreateInstancedBaselines_Post
// #define FN_InconsistentFile_Post InconsistentFile_Post
// #define FN_AllowLagCompensation_Post AllowLagCompensation_Post
// - GetEngineAPI functions
// #define FN_PrecacheModel PrecacheModel
// #define FN_PrecacheSound PrecacheSound
// #define FN_SetModel SetModel
// #define FN_ModelIndex ModelIndex
// #define FN_ModelFrames ModelFrames
// #define FN_SetSize SetSize
// #define FN_ChangeLevel ChangeLevel
// #define FN_GetSpawnParms GetSpawnParms
// #define FN_SaveSpawnParms SaveSpawnParms
// #define FN_VecToYaw VecToYaw
// #define FN_VecToAngles VecToAngles
// #define FN_MoveToOrigin MoveToOrigin
// #define FN_ChangeYaw ChangeYaw
// #define FN_ChangePitch ChangePitch
// #define FN_FindEntityByString FindEntityByString
// #define FN_GetEntityIllum GetEntityIllum
// #define FN_FindEntityInSphere FindEntityInSphere
// #define FN_FindClientInPVS FindClientInPVS
// #define FN_EntitiesInPVS EntitiesInPVS
// #define FN_MakeVectors MakeVectors
// #define FN_AngleVectors AngleVectors
// #define FN_CreateEntity CreateEntity
// #define FN_RemoveEntity RemoveEntity
// #define FN_CreateNamedEntity CreateNamedEntity
// #define FN_MakeStatic MakeStatic
// #define FN_EntIsOnFloor EntIsOnFloor
// #define FN_DropToFloor DropToFloor
// #define FN_WalkMove WalkMove
// #define FN_SetOrigin SetOrigin
// #define FN_EmitSound EmitSound
// #define FN_EmitAmbientSound EmitAmbientSound
// #define FN_TraceLine TraceLine
// #define FN_TraceToss TraceToss
// #define FN_TraceMonsterHull TraceMonsterHull
// #define FN_TraceHull TraceHull
// #define FN_TraceModel TraceModel
// #define FN_TraceTexture TraceTexture
// #define FN_TraceSphere TraceSphere
// #define FN_GetAimVector GetAimVector
// #define FN_ServerCommand ServerCommand
// #define FN_ServerExecute ServerExecute
// #define FN_engClientCommand engClientCommand
// #define FN_ParticleEffect ParticleEffect
// #define FN_LightStyle LightStyle
// #define FN_DecalIndex DecalIndex
// #define FN_PointContents PointContents
// #define FN_MessageBegin MessageBegin
// #define FN_MessageEnd MessageEnd
// #define FN_WriteByte WriteByte
// #define FN_WriteChar WriteChar
// #define FN_WriteShort WriteShort
// #define FN_WriteLong WriteLong
// #define FN_WriteAngle WriteAngle
// #define FN_WriteCoord WriteCoord
// #define FN_WriteString WriteString
// #define FN_WriteEntity WriteEntity
// #define FN_CVarRegister CVarRegister
// #define FN_CVarGetFloat CVarGetFloat
// #define FN_CVarGetString CVarGetString
// #define FN_CVarSetFloat CVarSetFloat
// #define FN_CVarSetString CVarSetString
// #define FN_AlertMessage AlertMessage
// #define FN_EngineFprintf EngineFprintf
// #define FN_PvAllocEntPrivateData PvAllocEntPrivateData
// #define FN_PvEntPrivateData PvEntPrivateData
// #define FN_FreeEntPrivateData FreeEntPrivateData
// #define FN_SzFromIndex SzFromIndex
// #define FN_AllocString AllocString
// #define FN_GetVarsOfEnt GetVarsOfEnt
// #define FN_PEntityOfEntOffset PEntityOfEntOffset
// #define FN_EntOffsetOfPEntity EntOffsetOfPEntity
// #define FN_IndexOfEdict IndexOfEdict
// #define FN_PEntityOfEntIndex PEntityOfEntIndex
// #define FN_FindEntityByVars FindEntityByVars
// #define FN_GetModelPtr GetModelPtr
// #define FN_RegUserMsg RegUserMsg
// #define FN_AnimationAutomove AnimationAutomove
// #define FN_GetBonePosition GetBonePosition
// #define FN_FunctionFromName FunctionFromName
// #define FN_NameForFunction NameForFunction
// #define FN_ClientPrintf ClientPrintf
// #define FN_ServerPrint ServerPrint
// #define FN_Cmd_Args Cmd_Args
// #define FN_Cmd_Argv Cmd_Argv
// #define FN_Cmd_Argc Cmd_Argc
// #define FN_GetAttachment GetAttachment
// #define FN_CRC32_Init CRC32_Init
// #define FN_CRC32_ProcessBuffer CRC32_ProcessBuffer
// #define FN_CRC32_ProcessByte CRC32_ProcessByte
// #define FN_CRC32_Final CRC32_Final
// #define FN_RandomLong RandomLong
// #define FN_RandomFloat RandomFloat
// #define FN_SetView SetView
// #define FN_Time Time
// #define FN_CrosshairAngle CrosshairAngle
// #define FN_LoadFileForMe LoadFileForMe
// #define FN_FreeFile FreeFile
// #define FN_EndSection EndSection
// #define FN_CompareFileTime CompareFileTime
// #define FN_GetGameDir GetGameDir
// #define FN_Cvar_RegisterVariable Cvar_RegisterVariable
// #define FN_FadeClientVolume FadeClientVolume
// #define FN_SetClientMaxspeed SetClientMaxspeed
// #define FN_CreateFakeClient CreateFakeClient
// #define FN_RunPlayerMove RunPlayerMove
// #define FN_NumberOfEntities NumberOfEntities
// #define FN_GetInfoKeyBuffer GetInfoKeyBuffer
// #define FN_InfoKeyValue InfoKeyValue
// #define FN_SetKeyValue SetKeyValue
// #define FN_SetClientKeyValue SetClientKeyValue
// #define FN_IsMapValid IsMapValid
// #define FN_StaticDecal StaticDecal
// #define FN_PrecacheGeneric PrecacheGeneric
// #define FN_GetPlayerUserId GetPlayerUserId
// #define FN_BuildSoundMsg BuildSoundMsg
// #define FN_IsDedicatedServer IsDedicatedServer
// #define FN_CVarGetPointer CVarGetPointer
// #define FN_GetPlayerWONId GetPlayerWONId
// #define FN_Info_RemoveKey Info_RemoveKey
// #define FN_GetPhysicsKeyValue GetPhysicsKeyValue
// #define FN_SetPhysicsKeyValue SetPhysicsKeyValue
// #define FN_GetPhysicsInfoString GetPhysicsInfoString
// #define FN_PrecacheEvent PrecacheEvent
// #define FN_PlaybackEvent PlaybackEvent
// #define FN_SetFatPVS SetFatPVS
// #define FN_SetFatPAS SetFatPAS
// #define FN_CheckVisibility CheckVisibility
// #define FN_DeltaSetField DeltaSetField
// #define FN_DeltaUnsetField DeltaUnsetField
// #define FN_DeltaAddEncoder DeltaAddEncoder
// #define FN_GetCurrentPlayer GetCurrentPlayer
// #define FN_CanSkipPlayer CanSkipPlayer
// #define FN_DeltaFindField DeltaFindField
// #define FN_DeltaSetFieldByIndex DeltaSetFieldByIndex
// #define FN_DeltaUnsetFieldByIndex DeltaUnsetFieldByIndex
// #define FN_SetGroupMask SetGroupMask
// #define FN_engCreateInstancedBaseline engCreateInstancedBaseline
// #define FN_Cvar_DirectSet Cvar_DirectSet
// #define FN_ForceUnmodified ForceUnmodified
// #define FN_GetPlayerStats GetPlayerStats
// #define FN_AddServerCommand AddServerCommand
// #define FN_Voice_GetClientListening Voice_GetClientListening
// #define FN_Voice_SetClientListening Voice_SetClientListening
// #define FN_GetPlayerAuthId GetPlayerAuthId
// - GetEngineAPI_Post functions
// #define FN_PrecacheModel_Post PrecacheModel_Post
// #define FN_PrecacheSound_Post PrecacheSound_Post
// #define FN_SetModel_Post SetModel_Post
// #define FN_ModelIndex_Post ModelIndex_Post
// #define FN_ModelFrames_Post ModelFrames_Post
// #define FN_SetSize_Post SetSize_Post
// #define FN_ChangeLevel_Post ChangeLevel_Post
// #define FN_GetSpawnParms_Post GetSpawnParms_Post
// #define FN_SaveSpawnParms_Post SaveSpawnParms_Post
// #define FN_VecToYaw_Post VecToYaw_Post
// #define FN_VecToAngles_Post VecToAngles_Post
// #define FN_MoveToOrigin_Post MoveToOrigin_Post
// #define FN_ChangeYaw_Post ChangeYaw_Post
// #define FN_ChangePitch_Post ChangePitch_Post
// #define FN_FindEntityByString_Post FindEntityByString_Post
// #define FN_GetEntityIllum_Post GetEntityIllum_Post
// #define FN_FindEntityInSphere_Post FindEntityInSphere_Post
// #define FN_FindClientInPVS_Post FindClientInPVS_Post
// #define FN_EntitiesInPVS_Post EntitiesInPVS_Post
// #define FN_MakeVectors_Post MakeVectors_Post
// #define FN_AngleVectors_Post AngleVectors_Post
// #define FN_CreateEntity_Post CreateEntity_Post
// #define FN_RemoveEntity_Post RemoveEntity_Post
// #define FN_CreateNamedEntity_Post CreateNamedEntity_Post
// #define FN_MakeStatic_Post MakeStatic_Post
// #define FN_EntIsOnFloor_Post EntIsOnFloor_Post
// #define FN_DropToFloor_Post DropToFloor_Post
// #define FN_WalkMove_Post WalkMove_Post
// #define FN_SetOrigin_Post SetOrigin_Post
// #define FN_EmitSound_Post EmitSound_Post
// #define FN_EmitAmbientSound_Post EmitAmbientSound_Post
// #define FN_TraceLine_Post TraceLine_Post
// #define FN_TraceToss_Post TraceToss_Post
// #define FN_TraceMonsterHull_Post TraceMonsterHull_Post
// #define FN_TraceHull_Post TraceHull_Post
// #define FN_TraceModel_Post TraceModel_Post
// #define FN_TraceTexture_Post TraceTexture_Post
// #define FN_TraceSphere_Post TraceSphere_Post
// #define FN_GetAimVector_Post GetAimVector_Post
// #define FN_ServerCommand_Post ServerCommand_Post
// #define FN_ServerExecute_Post ServerExecute_Post
// #define FN_engClientCommand_Post engClientCommand_Post
// #define FN_ParticleEffect_Post ParticleEffect_Post
// #define FN_LightStyle_Post LightStyle_Post
// #define FN_DecalIndex_Post DecalIndex_Post
// #define FN_PointContents_Post PointContents_Post
// #define FN_MessageBegin_Post MessageBegin_Post
// #define FN_MessageEnd_Post MessageEnd_Post
// #define FN_WriteByte_Post WriteByte_Post
// #define FN_WriteChar_Post WriteChar_Post
// #define FN_WriteShort_Post WriteShort_Post
// #define FN_WriteLong_Post WriteLong_Post
// #define FN_WriteAngle_Post WriteAngle_Post
// #define FN_WriteCoord_Post WriteCoord_Post
// #define FN_WriteString_Post WriteString_Post
// #define FN_WriteEntity_Post WriteEntity_Post
// #define FN_CVarRegister_Post CVarRegister_Post
// #define FN_CVarGetFloat_Post CVarGetFloat_Post
// #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_EngineFprintf_Post EngineFprintf_Post
// #define FN_PvAllocEntPrivateData_Post PvAllocEntPrivateData_Post
// #define FN_PvEntPrivateData_Post PvEntPrivateData_Post
// #define FN_FreeEntPrivateData_Post FreeEntPrivateData_Post
// #define FN_SzFromIndex_Post SzFromIndex_Post
// #define FN_AllocString_Post AllocString_Post
// #define FN_GetVarsOfEnt_Post GetVarsOfEnt_Post
// #define FN_PEntityOfEntOffset_Post PEntityOfEntOffset_Post
// #define FN_EntOffsetOfPEntity_Post EntOffsetOfPEntity_Post
// #define FN_IndexOfEdict_Post IndexOfEdict_Post
// #define FN_PEntityOfEntIndex_Post PEntityOfEntIndex_Post
// #define FN_FindEntityByVars_Post FindEntityByVars_Post
// #define FN_GetModelPtr_Post GetModelPtr_Post
// #define FN_RegUserMsg_Post RegUserMsg_Post
// #define FN_AnimationAutomove_Post AnimationAutomove_Post
// #define FN_GetBonePosition_Post GetBonePosition_Post
// #define FN_FunctionFromName_Post FunctionFromName_Post
// #define FN_NameForFunction_Post NameForFunction_Post
// #define FN_ClientPrintf_Post ClientPrintf_Post
// #define FN_ServerPrint_Post ServerPrint_Post
// #define FN_Cmd_Args_Post Cmd_Args_Post
// #define FN_Cmd_Argv_Post Cmd_Argv_Post
// #define FN_Cmd_Argc_Post Cmd_Argc_Post
// #define FN_GetAttachment_Post GetAttachment_Post
// #define FN_CRC32_Init_Post CRC32_Init_Post
// #define FN_CRC32_ProcessBuffer_Post CRC32_ProcessBuffer_Post
// #define FN_CRC32_ProcessByte_Post CRC32_ProcessByte_Post
// #define FN_CRC32_Final_Post CRC32_Final_Post
// #define FN_RandomLong_Post RandomLong_Post
// #define FN_RandomFloat_Post RandomFloat_Post
// #define FN_SetView_Post SetView_Post
// #define FN_Time_Post Time_Post
// #define FN_CrosshairAngle_Post CrosshairAngle_Post
// #define FN_LoadFileForMe_Post LoadFileForMe_Post
// #define FN_FreeFile_Post FreeFile_Post
// #define FN_EndSection_Post EndSection_Post
// #define FN_CompareFileTime_Post CompareFileTime_Post
// #define FN_GetGameDir_Post GetGameDir_Post
// #define FN_Cvar_RegisterVariable_Post Cvar_RegisterVariable_Post
// #define FN_FadeClientVolume_Post FadeClientVolume_Post
// #define FN_SetClientMaxspeed_Post SetClientMaxspeed_Post
// #define FN_CreateFakeClient_Post CreateFakeClient_Post
// #define FN_RunPlayerMove_Post RunPlayerMove_Post
// #define FN_NumberOfEntities_Post NumberOfEntities_Post
// #define FN_GetInfoKeyBuffer_Post GetInfoKeyBuffer_Post
// #define FN_InfoKeyValue_Post InfoKeyValue_Post
// #define FN_SetKeyValue_Post SetKeyValue_Post
// #define FN_SetClientKeyValue_Post SetClientKeyValue_Post
// #define FN_IsMapValid_Post IsMapValid_Post
// #define FN_StaticDecal_Post StaticDecal_Post
// #define FN_PrecacheGeneric_Post PrecacheGeneric_Post
// #define FN_GetPlayerUserId_Post GetPlayerUserId_Post
// #define FN_BuildSoundMsg_Post BuildSoundMsg_Post
// #define FN_IsDedicatedServer_Post IsDedicatedServer_Post
// #define FN_CVarGetPointer_Post CVarGetPointer_Post
// #define FN_GetPlayerWONId_Post GetPlayerWONId_Post
// #define FN_Info_RemoveKey_Post Info_RemoveKey_Post
// #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_PlaybackEvent_Post PlaybackEvent_Post
// #define FN_SetFatPVS_Post SetFatPVS_Post
// #define FN_SetFatPAS_Post SetFatPAS_Post
// #define FN_CheckVisibility_Post CheckVisibility_Post
// #define FN_DeltaSetField_Post DeltaSetField_Post
// #define FN_DeltaUnsetField_Post DeltaUnsetField_Post
// #define FN_DeltaAddEncoder_Post DeltaAddEncoder_Post
// #define FN_GetCurrentPlayer_Post GetCurrentPlayer_Post
// #define FN_CanSkipPlayer_Post CanSkipPlayer_Post
// #define FN_DeltaFindField_Post DeltaFindField_Post
// #define FN_DeltaSetFieldByIndex_Post DeltaSetFieldByIndex_Post
// #define FN_DeltaUnsetFieldByIndex_Post DeltaUnsetFieldByIndex_Post
// #define FN_SetGroupMask_Post SetGroupMask_Post
// #define FN_engCreateInstancedBaseline_Post engCreateInstancedBaseline_Post
// #define FN_Cvar_DirectSet_Post Cvar_DirectSet_Post
// #define FN_ForceUnmodified_Post ForceUnmodified_Post
// #define FN_GetPlayerStats_Post GetPlayerStats_Post
// #define FN_AddServerCommand_Post AddServerCommand_Post
// #define FN_Voice_GetClientListening_Post Voice_GetClientListening_Post
// #define FN_Voice_SetClientListening_Post Voice_SetClientListening_Post
// #define FN_GetPlayerAuthId_Post GetPlayerAuthId_Post
// #define FN_OnFreeEntPrivateData OnFreeEntPrivateData
// #define FN_GameShutdown GameShutdown
// #define FN_ShouldCollide ShouldCollide
// #define FN_OnFreeEntPrivateData_Post OnFreeEntPrivateData_Post
// #define FN_GameShutdown_Post GameShutdown_Post
// #define FN_ShouldCollide_Post ShouldCollide_Post
#endif // USE_METAMOD
#endif // __MODULECONFIG_H__

20
modules/ns/msvc12/ns.sln Normal file
View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ns", "ns.vcxproj", "{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Debug|Win32.ActiveCfg = Debug|Win32
{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Debug|Win32.Build.0 = Debug|Win32
{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Release|Win32.ActiveCfg = Release|Win32
{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,186 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}</ProjectGuid>
<RootNamespace>ns</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)_amxx</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)_amxx</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/ns_amxx.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_STDINT_H;WIN32;NDEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/ns_amxx.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\Release/ns_amxx.pdb</ProgramDatabaseFile>
<ImportLibrary>.\Release/ns_amxx.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/ns_amxx.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_STDINT_H;WIN32;_DEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Debug/ns_amxx.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/ns_amxx.pdb</ProgramDatabaseFile>
<ImportLibrary>.\Debug/ns_amxx.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<SubSystem>Windows</SubSystem>
<IgnoreSpecificDefaultLibraries>LIBCMT;</IgnoreSpecificDefaultLibraries>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\amxxapi.cpp" />
<ClCompile Include="..\dllapi.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;ns_amxx_EXPORTS</PreprocessorDefinitions>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;ns_amxx_EXPORTS</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\engineapi.cpp" />
<ClCompile Include="..\GameManager.cpp" />
<ClCompile Include="..\MessageHandler.cpp" />
<ClCompile Include="..\ParticleManager.cpp" />
<ClCompile Include="..\TitleManager.cpp" />
<ClCompile Include="..\utils.cpp" />
<ClCompile Include="..\natives\general.cpp" />
<ClCompile Include="..\natives\memberfuncs.cpp" />
<ClCompile Include="..\natives\particles.cpp" />
<ClCompile Include="..\natives\player.cpp" />
<ClCompile Include="..\natives\player_memory.cpp" />
<ClCompile Include="..\natives\structure.cpp" />
<ClCompile Include="..\natives\weapons.cpp" />
<ClCompile Include="..\..\..\public\sdk\amxxmodule.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\AllocString.h" />
<ClInclude Include="..\CPlayer.h" />
<ClInclude Include="..\FastDelegate.h" />
<ClInclude Include="..\GameManager.h" />
<ClInclude Include="..\Hash.h" />
<ClInclude Include="..\LocationManager.h" />
<ClInclude Include="..\MessageHandler.h" />
<ClInclude Include="..\NEW_Util.h" />
<ClInclude Include="..\ns.h" />
<ClInclude Include="..\ns_const.h" />
<ClInclude Include="..\ParticleManager.h" />
<ClInclude Include="..\SpawnManager.h" />
<ClInclude Include="..\TitleManager.h" />
<ClInclude Include="..\utilfunctions.h" />
<ClInclude Include="..\..\..\public\sdk\amxxmodule.h" />
<ClInclude Include="..\moduleconfig.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{a09df8a4-fb19-4b63-b0ba-59083c7dfbce}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Source Files\Natives">
<UniqueIdentifier>{09c32fa1-30fa-482b-a470-1f9ac2904ffc}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{e619584d-fe78-4fa8-9b61-715f075c990c}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="Module SDK">
<UniqueIdentifier>{d6f08195-ccd3-49f9-be66-8064cf182a41}</UniqueIdentifier>
</Filter>
<Filter Include="Module SDK\SDK Base">
<UniqueIdentifier>{28f804b5-b177-4048-b0c6-36ba103593b9}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\amxxapi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\dllapi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\engineapi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\GameManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\MessageHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ParticleManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\TitleManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\natives\general.cpp">
<Filter>Source Files\Natives</Filter>
</ClCompile>
<ClCompile Include="..\natives\memberfuncs.cpp">
<Filter>Source Files\Natives</Filter>
</ClCompile>
<ClCompile Include="..\natives\particles.cpp">
<Filter>Source Files\Natives</Filter>
</ClCompile>
<ClCompile Include="..\natives\player.cpp">
<Filter>Source Files\Natives</Filter>
</ClCompile>
<ClCompile Include="..\natives\player_memory.cpp">
<Filter>Source Files\Natives</Filter>
</ClCompile>
<ClCompile Include="..\natives\structure.cpp">
<Filter>Source Files\Natives</Filter>
</ClCompile>
<ClCompile Include="..\natives\weapons.cpp">
<Filter>Source Files\Natives</Filter>
</ClCompile>
<ClCompile Include="..\..\..\public\sdk\amxxmodule.cpp">
<Filter>Module SDK\SDK Base</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\AllocString.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\CPlayer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\FastDelegate.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\GameManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Hash.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\LocationManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\MessageHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\NEW_Util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ns_const.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ParticleManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SpawnManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TitleManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\utilfunctions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\public\sdk\amxxmodule.h">
<Filter>Module SDK\SDK Base</Filter>
</ClInclude>
<ClInclude Include="..\moduleconfig.h">
<Filter>Module SDK</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,531 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include <string.h>
#include "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
ke::AString Input(UTIL_ToLowerCase(MF_GetAmxString(amx,params[1],0,NULL)));
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);
}

View File

@ -0,0 +1,288 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include <string.h>
#include "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__
UTIL_Format(FileName,sizeof(FileName)-1,"%s/dlls/ns_i386.so",MF_GetModname());
#else
UTIL_Format(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);
};

View File

@ -0,0 +1,255 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include "amxxmodule.h"
#include "ns.h"
#include "utilfunctions.h"
#include "NEW_Util.h"
#include "ParticleManager.h"
#include <am-vector.h>
#include <am-string.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(const 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];
UTIL_Format(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(const 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];
UTIL_Format(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(const 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);
}

View File

@ -0,0 +1,270 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include "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(&params[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;
}
static cell AMX_NATIVE_CALL ns_get_user_team(AMX* amx, cell* params)
{
CreatePlayerPointer(amx,params[1]);
if (!player->IsConnected())
{
return 0;
}
int team = player->GetPev()->team;
if (team > 4 || team < 0)
{
MF_SetAmxString(amx, params[2], "undefinedteam", params[3]);
return 0;
}
switch (team)
{
case 0:
{
// iuser1 means readyroom (I think!)
if (player->GetPev()->iuser1 == 0)
{
MF_SetAmxString(amx, params[2], "undefinedteam", params[3]);
return 0;
}
MF_SetAmxString(amx, params[2], "spectatorteam", params[3]);
return 0;
}
case 1:
{
MF_SetAmxString(amx, params[2], "marine1team", params[3]);
return 1;
}
case 2:
{
MF_SetAmxString(amx, params[2], "alien1team", params[3]);
return 2;
}
case 3:
{
MF_SetAmxString(amx, params[2], "marine2team", params[3]);
return 3;
}
case 4:
{
MF_SetAmxString(amx, params[2], "alien2team", params[3]);
return 4;
}
default:
{
break;
}
}
MF_SetAmxString(amx, params[2], "spectatorteam", params[3]);
return 0;
}
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 },
{ "ns_get_user_team", ns_get_user_team },
{ NULL, NULL }
};
void AddNatives_Player()
{
MF_AddNatives(player_natives);
}

View File

@ -0,0 +1,427 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include "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;
}
static cell AMX_NATIVE_CALL ns_remove_upgrade(AMX *amx, cell *params)
{
CreatePlayerPointer(amx, params[1]);
if (!GameMan.IsCombat())
{
return 0;
}
if (!player->IsConnected() || !player->HasPrivateData())
{
return 0;
}
// Upgrades are stored in a std::vector<int> in the player's private data
// The integer value represents the impulse for the offset
// std::vector's memory layout is:
// void *start
// void *lastobject
// void *lastreserved
struct upgradevector
{
int *start;
int *end;
int *allocated;
inline int size() { return static_cast<int>((reinterpret_cast<unsigned int>(end) - reinterpret_cast<unsigned int>(start)) / sizeof(int)); }
inline int at(int which) { return start[which]; }
inline void set(int which, int val) { start[which] = val; }
inline bool remove(int val)
{
for (int i = 0; i < this->size(); i++)
{
if (this->at(i) == val)
{
int last = this->size() - 1;
while (i < last)
{
this->set(i, this->at(i + 1));
i++;
}
this->end--;
return true;
}
}
return false;
}
inline void print()
{
printf("size: %d values: ", this->size());
for (int i = 0; i < this->size(); i++)
{
if (i != 0)
printf(", ");
printf("%d", this->at(i));
}
printf("\n");
}
};
upgradevector *bought = reinterpret_cast<upgradevector *>(reinterpret_cast<char *>(player->GetEdict()->pvPrivateData) + MAKE_OFFSET(UPGRADES_BOUGHT));
upgradevector *active = reinterpret_cast<upgradevector *>(reinterpret_cast<char *>(player->GetEdict()->pvPrivateData) + MAKE_OFFSET(UPGRADES_ACTIVE));
//bought->print();
//active->print();
bool bfound = bought->remove(params[2]);
bool afound = active->remove(params[2]);
if (bfound)
{
if (afound)
{
return 2;
}
return 1;
}
if (afound)
{
// shouldn't happen, but just incase
return 3;
}
return 0;
}
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 },
{ "ns_remove_upgrade", ns_remove_upgrade },
{ NULL, NULL }
};
void AddNatives_PlayerMemory()
{
MF_AddNatives(player_memory_natives);
}

View File

@ -0,0 +1,385 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include "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);
}

View File

@ -0,0 +1,459 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include "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);
}

74
modules/ns/ns.h Normal file
View File

@ -0,0 +1,74 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#ifndef NS_H
#define NS_H
#include "ns_const.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;
extern enginefuncs_t *g_pengfuncsTable;
extern enginefuncs_t *g_pengfuncsTable_Post;
extern NEW_DLL_FUNCTIONS *g_pNewFunctionsTable;
extern NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post;
extern class CPlayer g_player[33];
extern edict_t *player_edicts[33]; // Stupid INDEXENT() bug.
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, const 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

370
modules/ns/ns_const.h Normal file
View File

@ -0,0 +1,370 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#ifndef NS_CONST_H
#define NS_CONST_H
// Offsets (used in NPData.cpp)
#define NEED_TO_FIND 0
#define OFFSET_WIN_RESOURCES 1816
#define OFFSET_LIN_RESOURCES 1836
#define OFFSET_WIN_WEAPDMG 408
#define OFFSET_LIN_WEAPDMG 424
#define OFFSET_WIN_WEAPRANGE 404
#define OFFSET_LIN_WEAPRANGE 420
#define OFFSET_WIN_WEAPCLIP 364
#define OFFSET_LIN_WEAPCLIP 380
#define OFFSET_WIN_WEAPID 324
#define OFFSET_LIN_WEAPID 340
// Next weapon in the item linked list
#define OFFSET_WIN_WEAP_NEXT 320
#define OFFSET_LIN_WEAP_NEXT 336
#define OFFSET_WIN_HIVE_TRAIT 488
#define OFFSET_LIN_HIVE_TRAIT 504
#define OFFSET_WIN_SCORE 6588
#define OFFSET_LIN_SCORE 6608
#define OFFSET_WIN_EXP 6512
#define OFFSET_LIN_EXP 6532
#define OFFSET_WIN_POINTS 6520
#define OFFSET_LIN_POINTS 6540
#define OFFSET_WIN_AMMO_LMG 1116
#define OFFSET_LIN_AMMO_LMG 1136
#define OFFSET_WIN_AMMO_PISTOL 1120
#define OFFSET_LIN_AMMO_PISTOL 1140
#define OFFSET_WIN_AMMO_SHOTGUN 1124
#define OFFSET_LIN_AMMO_SHOTGUN 1144
#define OFFSET_WIN_AMMO_HMG 1128
#define OFFSET_LIN_AMMO_HMG 1148
#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
#define OFFSET_WIN_UPGRADES_BOUGHT 0x1980
#define OFFSET_LIN_UPGRADES_BOUGHT 0x1994
#define OFFSET_WIN_UPGRADES_ACTIVE 0x198C
#define OFFSET_LIN_UPGRADES_ACTIVE 0x19A0
// 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
{
MASK_NONE = 0,
MASK_SIGHTED = 1,
MASK_DETECTED = 2,
MASK_BUILDABLE = 4,
MASK_BASEBUILD0 = 8, // Base build slot #0
MASK_WEAPONS1 = 8, // Marine weapons 1
MASK_CARAPACE = 8, // Alien carapace
MASK_WEAPONS2 = 16, // Marines weapons 2
MASK_REGENERATION = 16, // Alien regeneration
MASK_BASEBUILD1 = 16, // Base build slot #1
MASK_WEAPONS3 = 32, // Marine weapons 3
MASK_REDEMPTION = 32, // Alien redemption
MASK_BASEBUILD2 = 32, // Base build slot #2
MASK_ARMOR1 = 64, // Marine armor 1
MASK_CELERITY = 64, // Alien celerity
MASK_BASEBUILD3 = 64, // Base build slot #3
MASK_ARMOR2 = 128, // Marine armor 2
MASK_ADRENALINE = 128, // Alien adrenaline
MASK_BASEBUILD4 = 128, // Base build slot #4
MASK_ARMOR3 = 256, // Marine armor 3
MASK_SILENCE = 256, // Alien silence
MASK_BASEBUILD5 = 256, // Base build slot #5
MASK_JETPACK = 512, // Marine jetpacks
MASK_CLOAKING = 512, // Alien cloaking
MASK_BASEBUILD6 = 512, // Base build slot #6
MASK_FOCUS = 1024, // Alien focus
MASK_MOTION = 1024, // Marine motion tracking
MASK_BASEBUILD7 = 1024, // Base build slot #7
MASK_SCENTOFFEAR = 2048, // Alien scent of fear
MASK_DEFENSE2 = 4096, // Defense level 2
MASK_DEFENSE3 = 8192, // Defense level 3
MASK_ELECTRICITY = 8192, // Electricy
MASK_MOVEMENT2 = 16384, // Movement level 2,
MASK_MOVEMENT3 = 32768, // Movement level 3
MASK_HEAVYARMOR = 32768, // Marine heavy armor
MASK_SENSORY2 = 65536, // Sensory level 2
MASK_SENSORY3 = 131072, // Sensory level 3
MASK_ALIEN_MOVEMENT = 262144, // Onos is charging
MASK_WALLSTICKING = 524288, // Flag for wall-sticking
MASK_PRIMALSCREAM = 1048576, // Alien is in range of active primal scream
MASK_UMBRA = 2097152, // In umbra
MASK_DIGESTING = 4194304, // When set on a visible player, player is digesting. When set on invisible player, player is being digested
MASK_RECYCLING = 8388608, // Building is recycling
MASK_TOPDOWN = 16777216, // Commander view
MASK_PLAYER_STUNNED = 33554432, // Player has been stunned by stomp
MASK_ENSNARED = 67108864, // Webbed
MASK_ALIEN_EMBRYO = 134217728, //268435456, // Gestating
MASK_SELECTABLE = 268435456, //536870912, // ???
MASK_PARASITED = 536870912, //1073741824, // Parasite flag
MASK_SENSORY_NEARBY = 1073741824 //2147483648 // Sensory chamber in range
};
typedef enum
{
AVH_USER3_NONE = 0,
AVH_USER3_MARINE_PLAYER,
AVH_USER3_COMMANDER_PLAYER,
AVH_USER3_ALIEN_PLAYER1,
AVH_USER3_ALIEN_PLAYER2,
AVH_USER3_ALIEN_PLAYER3,
AVH_USER3_ALIEN_PLAYER4,
AVH_USER3_ALIEN_PLAYER5,
AVH_USER3_ALIEN_EMBRYO,
AVH_USER3_SPAWN_TEAMONE,
AVH_USER3_SPAWN_TEAMTWO,
AVH_USER3_PARTICLE_ON, // only valid for AvHParticleEntity: entindex as int in fuser1, template index stored in fuser2
AVH_USER3_PARTICLE_OFF, // only valid for AvHParticleEntity: particle system handle in fuser1
AVH_USER3_WELD, // float progress (0 - 100) stored in fuser1
AVH_USER3_ALPHA, // fuser1 indicates how much alpha this entity toggles to in commander mode, fuser2 for players
AVH_USER3_MARINEITEM, // Something a friendly marine can pick up
AVH_USER3_WAYPOINT,
AVH_USER3_HIVE,
AVH_USER3_NOBUILD,
AVH_USER3_USEABLE,
AVH_USER3_AUDIO_ON,
AVH_USER3_AUDIO_OFF,
AVH_USER3_FUNC_RESOURCE,
AVH_USER3_COMMANDER_STATION,
AVH_USER3_TURRET_FACTORY,
AVH_USER3_ARMORY,
AVH_USER3_ADVANCED_ARMORY,
AVH_USER3_ARMSLAB,
AVH_USER3_PROTOTYPE_LAB,
AVH_USER3_OBSERVATORY,
AVH_USER3_CHEMLAB,
AVH_USER3_MEDLAB,
AVH_USER3_NUKEPLANT,
AVH_USER3_TURRET,
AVH_USER3_SIEGETURRET,
AVH_USER3_RESTOWER,
AVH_USER3_PLACEHOLDER,
AVH_USER3_INFANTRYPORTAL,
AVH_USER3_NUKE,
AVH_USER3_BREAKABLE,
AVH_USER3_UMBRA,
AVH_USER3_PHASEGATE,
AVH_USER3_DEFENSE_CHAMBER,
AVH_USER3_MOVEMENT_CHAMBER,
AVH_USER3_OFFENSE_CHAMBER,
AVH_USER3_SENSORY_CHAMBER,
AVH_USER3_ALIENRESTOWER,
AVH_USER3_HEAVY,
AVH_USER3_JETPACK,
AVH_USER3_ADVANCED_TURRET_FACTORY,
AVH_USER3_SPAWN_READYROOM,
AVH_USER3_CLIENT_COMMAND,
AVH_USER3_FUNC_ILLUSIONARY,
AVH_USER3_MENU_BUILD,
AVH_USER3_MENU_BUILD_ADVANCED,
AVH_USER3_MENU_ASSIST,
AVH_USER3_MENU_EQUIP,
AVH_USER3_MINE,
AVH_USER3_MAX
} AvHUser3;
enum
{
WEAPON_NONE = 0,
WEAPON_CLAWS,
WEAPON_SPIT,
WEAPON_SPORES,
WEAPON_SPIKE,
WEAPON_BITE,
WEAPON_BITE2,
WEAPON_SWIPE,
WEAPON_WEBSPINNER,
WEAPON_METABOLIZE,
WEAPON_PARASITE,
WEAPON_BLINK,
WEAPON_DIVINEWIND,
WEAPON_KNIFE,
WEAPON_PISTOL,
WEAPON_LMG,
WEAPON_SHOTGUN,
WEAPON_HMG,
WEAPON_WELDER,
WEAPON_MINE,
WEAPON_GRENADE_GUN,
WEAPON_LEAP,
WEAPON_CHARGE,
WEAPON_UMBRA,
WEAPON_PRIMALSCREAM,
WEAPON_BILEBOMB,
WEAPON_ACIDROCKET,
WEAPON_HEALINGSPRAY,
WEAPON_GRENADE,
WEAPON_STOMP,
WEAPON_DEVOUR,
WEAPON_MAX
};
enum
{
PLAYERCLASS_NONE = 0,
PLAYERCLASS_ALIVE_MARINE,
PLAYERCLASS_ALIVE_JETPACK,
PLAYERCLASS_ALIVE_HEAVY_MARINE,
PLAYERCLASS_ALIVE_LEVEL1,
PLAYERCLASS_ALIVE_LEVEL2,
PLAYERCLASS_ALIVE_LEVEL3,
PLAYERCLASS_ALIVE_LEVEL4,
PLAYERCLASS_ALIVE_LEVEL5,
PLAYERCLASS_ALIVE_DIGESTING,
PLAYERCLASS_ALIVE_GESTATING,
PLAYERCLASS_DEAD_MARINE,
PLAYERCLASS_DEAD_ALIEN,
PLAYERCLASS_COMMANDER,
PLAYERCLASS_REINFORCING,
PLAYERCLASS_SPECTATOR,
PLAYERCLASS_READY,
};
enum classes
{
CLASS_UNKNOWN = 0,
CLASS_SKULK,
CLASS_GORGE,
CLASS_LERK,
CLASS_FADE,
CLASS_ONOS,
CLASS_MARINE,
CLASS_JETPACK,
CLASS_HEAVY,
CLASS_COMMANDER,
CLASS_GESTATE,
CLASS_DEAD,
CLASS_NOTEAM
};
#endif

161
modules/ns/res_plugin.rc Normal file
View File

@ -0,0 +1,161 @@
//Microsoft Developer Studio generated resource script.
//
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by res_plugin.rc
//
#define IDI_ICON1 102
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 105
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winver.h"
#ifndef VERS_PLUGIN_H
#define VERS_PLUGIN_H
#pragma message "If the next 2 lines say extdll.h and meta_api.h could not be found, don't worry about it"
#include "plugin.h"
#ifndef OPT_TYPE
# if defined(_MSC_VER) && defined(_DEBUG)
# define OPT_TYPE "msc debugging"
# elif defined(_MSC_VER) && defined(_NDEBUG)
# define OPT_TYPE "msc optimized"
# else
# define OPT_TYPE "default"
# endif /* _MSC_VER */
#endif /* not OPT_TYPE */
#define VDATE MY_DATE
#define VVERSION MY_VERSION
#define RC_VERS_DWORD MY_VERSION_DWORD // Version Windows DLL Resources in res_meta.rc
#define VNAME MY_NAME
#define VAUTHOR MY_AUTHOR
#define VURL MY_URL
#define VLOGTAG MY_LOGTAG
// Various strings for the Windows DLL Resources in res_plugin.rc
#define RC_COMMENTS MY_COMMENTS
#define RC_DESC MY_DESC
#define RC_FILENAME MY_FILENAME
#define RC_INTERNAL MY_INTERNAL
#define RC_COPYRIGHT MY_COPYRIGHT
#endif /* VERS_PLUGIN_H */
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION MY_VERS_DWORD
PRODUCTVERSION MY_VERS_DWORD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", RC_COMMENTS "\0"
VALUE "CompanyName", VAUTHOR "\0"
VALUE "FileDescription", RC_DESC "\0"
VALUE "FileVersion", VVERSION "\0"
VALUE "InternalName", RC_INTERNAL "\0"
VALUE "LegalCopyright", RC_COPYRIGHT "\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", RC_FILENAME "\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", VNAME "\0"
VALUE "ProductVersion", VVERSION "\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""winver.h""\r\n"
"#include ""plugin.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
#endif // English (U.S.) resources
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

238
modules/ns/utilfunctions.h Normal file
View File

@ -0,0 +1,238 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#ifndef UTILFUNCTIONS_H
#define UTILFUNCTIONS_H
#include "NEW_Util.h" // include my experimental INDEXENT / ENTINDEX replacements
#define GET_PLAYER_E(x) (&g_player[ENTINDEX_NEW(x)])
#define GET_PLAYER_I(x) (&g_player[x])
/**
* 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__]
/**
* 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__)
/**
* 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__)
/**
* 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)
{
return *((cell *)&x);
};
inline REAL amx_ctof2(cell x)
{
return *((REAL *)&x);
};
inline BOOL isValidEntity(int x)
{
if (x < 0)
return FALSE;
if (x >= 0 || x <= gpGlobals->maxClients)
return TRUE;
if (x > gpGlobals->maxEntities)
return FALSE;
if (FNullEnt(x))
return FALSE;
return TRUE;
}
#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);
char *UTIL_ToLowerCase(const char *str);
class CPlayer;
CPlayer *UTIL_PlayerByCID(int CID);
// Converts something such as RESOURCES into OFFSET_WIN_RESOURCES or OFFSET_LIN_RESOURCES
#if defined(__linux__) || defined(__APPLE__)
#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

183
modules/ns/utils.cpp Normal file
View File

@ -0,0 +1,183 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Natural Selection Module
//
#include "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;
}
char *UTIL_ToLowerCase(const char *str)
{
size_t len = strlen(str);
char *buffer = new char[len + 1];
for (size_t i = 0; i < len; i++)
{
if (str[i] >= 'A' && str[i] <= 'Z')
buffer[i] = tolower(str[i]);
else
buffer[i] = str[i];
}
buffer[len] = '\0';
return buffer;
}

101
modules/ns/version.rc Normal file
View File

@ -0,0 +1,101 @@
// Microsoft Visual C++ generated resource script.
//
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include <winresrc.h>
#include <moduleconfig.h>
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION AMXX_VERSION_FILE
PRODUCTVERSION AMXX_VERSION_FILE
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "Comments", "AMX Mod X"
VALUE "FileDescription", "AMX Mod X"
VALUE "FileVersion", AMXX_VERSION
VALUE "InternalName", MODULE_LIBRARY
VALUE "LegalCopyright", "Copyright (c) AMX Mod X Dev Team"
VALUE "OriginalFilename", MODULE_LIBRARY "_amxx.dll"
VALUE "ProductName", MODULE_NAME
VALUE "ProductVersion", AMXX_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED