Added register_message() functions.

This commit is contained in:
David Anderson 2004-02-07 08:31:44 +00:00
parent 024e70e119
commit 9c3bc0ab8c
3 changed files with 1259 additions and 280 deletions

View File

@ -96,6 +96,10 @@ LINK32=link.exe
SOURCE=.\meta_api.cpp
# End Source File
# Begin Source File
SOURCE=.\engine.h
# End Source File
# End Group
# Begin Group "Resource Files"

888
dlls/engine/engine.h Executable file
View File

@ -0,0 +1,888 @@
#define VERSION "0.73"
plugin_info_t Plugin_info = {
META_INTERFACE_VERSION, // ifvers
"ENGINE", // name
VERSION, // version
__DATE__, // date
"BAILOPAN", // author
"http://www.amxmod.info/", // url
"AMXXE", // logtag
PT_ANYTIME,// (when) loadable
PT_ANYTIME,// (when) unloadable
};
module_info_s module_info = {
"ENGINE", // name
"BAILOPAN", // author
VERSION, // version
AMX_INTERFACE_VERSION,
STATIC_MODULE,
};
class AmxCallList {
public:
struct AmxCall {
AMX *amx;
//void* code;
int iFunctionIdx;
AmxCall* next;
AmxCall( AMX *a , int i, AmxCall* n ) : amx(a), iFunctionIdx(i), next(n) {}
} *head;
AmxCallList() { head = 0; }
~AmxCallList() { clear(); }
void clear() {
while ( head ) {
AmxCall* a = head->next;
delete head;
head = a;
}
}
void put( AMX *a , int i )
{
head = new AmxCall( a, i , head );
}
};
AmxCallList pfnTouch;
AmxCallList serverFrame;
AmxCallList preThink;
AmxCallList postThink;
AmxCallList clientKill;
meta_globals_t *gpMetaGlobals;
gamedll_funcs_t *gpGamedllFuncs;
mutil_funcs_t *gpMetaUtilFuncs;
enginefuncs_t g_engfuncs;
globalvars_t *gpGlobals;
pfnamx_engine_g* g_engAmxFunc;
pfnmodule_engine_g* g_engModuleFunc;
extern AMX_NATIVE_INFO Engine_Natives[];
void (*function)(void*);
void (*endfunction)(void*);
#define AMS_OFFSET 0.01
#define SPEAK_NORMAL 0
#define SPEAK_MUTED 1
#define SPEAK_ALL 2
#define SPEAK_LISTENALL 4
#define CAMERA_NONE 0
#define CAMERA_3RDPERSON 1
#define CAMERA_UPLEFT 2
#define CAMERA_TOPDOWN 3
#define MAX_MESSAGES 255
#define BLOCK_NOT 0
#define BLOCK_ONCE 1
#define BLOCK_SET 2
enum {
gamestate,
oldbuttons,
groupinfo,
iuser1,
iuser2,
iuser3,
iuser4,
weaponanim,
pushmsec,
bInDuck,
flTimeStepSound,
flSwimTime,
flDuckTime,
iStepLeft,
movetype,
solid,
skin,
body,
effects,
light_level,
sequence,
gaitsequence,
modelindex,
playerclass,
waterlevel,
watertype,
spawnflags,
flags,
colormap,
team,
fixangle,
weapons,
rendermode,
renderfx,
button,
impulse,
deadflag,
};
enum {
impacttime,
starttime,
idealpitch,
pitch_speed,
ideal_yaw,
yaw_speed,
ltime,
nextthink,
gravity,
friction,
frame,
animtime,
framerate,
health,
frags,
takedamage,
max_health,
teleport_time,
armortype,
armorvalue,
dmg_take,
dmg_save,
dmg,
dmgtime,
speed,
air_finished,
pain_finished,
radsuit_finished,
scale,
renderamt,
maxspeed,
fov,
flFallVelocity,
fuser1,
fuser2,
fuser3,
fuser4,
};
enum {
origin,
oldorigin,
velocity,
basevelocity,
clbasevelocity,
movedir,
angles,
avelocity,
punchangle,
v_angle,
endpos,
startpos,
absmin,
absmax,
mins,
maxs,
size,
rendercolor,
view_ofs,
vuser1,
vuser2,
vuser3,
vuser4,
};
enum {
chain,
dmg_inflictor,
enemy,
aiment,
owner,
groundentity,
pContainingEntity,
euser1,
euser2,
euser3,
euser4,
};
enum {
classname,
globalname,
model,
target,
targetname,
netname,
message,
noise,
noise1,
noise2,
noise3,
viewmodel,
weaponmodel,
};
enum {
controller1,
controller2,
controller3,
controller4,
blending1,
blending2,
};
struct PlayerInfo {
bool bModeled;
char szModel[32];
float fModelSet;
int iSpeakFlags;
edict_t *pViewEnt;
int iViewType;
int iRenderMode;
float fRenderAmt;
};
PlayerInfo PlInfo[33];
struct GlobalInfo {
bool bLights;
float fNextLights;
char *szLastLights[128];
char *szRealLights[128];
int iMessageBlock[MAX_MESSAGES];
bool bBlocking;
};
enum {
arg_byte = 1,
arg_char,
arg_short,
arg_long,
arg_angle,
arg_coord,
arg_string,
arg_entity,
};
class argStack {
public:
argStack(argStack *p=NULL) //initialize with link to previous
{
next = p;
init();
}
void init()
{
writebyte = 0;
writechar = '\0';
writeshort = 0;
writelong = (long)0;
writeangle = 0.0;
writecoord = 0.0;
writestring = NULL;
writeentity = 0;
}
argStack* arg()
{
argStack *p;
p = new argStack(); //get the new pointer
next = p; //link this to the next pointer
return p;
}
argStack* link() //return link
{
return next;
}
void put(int arg_type, int i)
{
argtype = arg_type;
switch (argtype)
{
case arg_byte:
writebyte = i;
break;
case arg_char:
writechar = i;
break;
case arg_entity:
writeentity = i;
break;
case arg_short:
writeshort = i;
break;
case arg_long:
writelong = i;
break;
}
}
void put(int arg_type, float f)
{
argtype = arg_type;
switch (argtype)
{
case arg_angle:
writeangle = f;
break;
case arg_coord:
writecoord = f;
break;
}
}
void put(int arg_type, char *sz)
{
argtype = arg_type;
switch (argtype)
{
case arg_string:
writestring = sz;
break;
}
}
void write_arg()
{
switch (argtype)
{
case arg_byte:
WRITE_BYTE(writebyte);
break;
case arg_char:
WRITE_CHAR(writechar);
break;
case arg_short:
WRITE_SHORT(writeshort);
break;
case arg_long:
WRITE_LONG(writelong);
break;
case arg_angle:
WRITE_ANGLE(writeangle);
break;
case arg_coord:
WRITE_COORD(writecoord);
break;
case arg_string:
WRITE_STRING(writestring);
break;
case arg_entity:
WRITE_ENTITY(writeentity);
break;
}
}
int getarg_int(int arg_type)
{
switch (argtype)
{
case arg_byte:
return writebyte;
break;
case arg_char:
return writechar;
break;
case arg_short:
return writeshort;
break;
case arg_long:
return writelong;
break;
case arg_entity:
return writeentity;
break;
}
return 0;
}
float getarg_float(int arg_type)
{
switch (argtype)
{
case arg_angle:
return writeangle;
break;
case arg_coord:
return writecoord;
break;
}
return 0.0;
}
char *getarg_string(int arg_type)
{
switch (argtype)
{
case arg_string:
return writestring;
break;
}
return NULL;
}
int get_argtype()
{
return argtype;
}
bool is_arg(int arg_type)
{
switch (argtype)
{
case arg_byte:
{
switch (arg_type)
{
case arg_byte:
return true;
break;
case arg_char:
return true;
break;
case arg_short:
return true;
break;
case arg_long:
return true;
break;
case arg_entity:
return true;
break;
default:
return false;
break;
}
break;
}
case arg_char:
{
switch (arg_type)
{
case arg_byte:
return true;
break;
case arg_char:
return true;
break;
case arg_short:
return true;
break;
case arg_long:
return true;
break;
case arg_entity:
return true;
break;
default:
return false;
break;
}
break;
}
case arg_short:
{
switch (arg_type)
{
case arg_byte:
return true;
break;
case arg_char:
return true;
break;
case arg_short:
return true;
break;
case arg_long:
return true;
break;
case arg_entity:
return true;
break;
default:
return false;
break;
}
break;
}
case arg_long:
{
switch (arg_type)
{
case arg_byte:
return true;
break;
case arg_char:
return true;
break;
case arg_short:
return true;
break;
case arg_long:
return true;
break;
case arg_entity:
return true;
break;
default:
return false;
break;
}
break;
}
case arg_entity:
{
switch (arg_type)
{
case arg_byte:
return true;
break;
case arg_char:
return true;
break;
case arg_short:
return true;
break;
case arg_long:
return true;
break;
case arg_entity:
return true;
break;
default:
return false;
break;
}
break;
}
case arg_angle:
{
switch (arg_type)
{
case arg_angle:
return true;
break;
case arg_coord:
return true;
break;
default:
return false;
break;
}
break;
}
case arg_coord:
{
switch (arg_type)
{
case arg_angle:
return true;
break;
case arg_coord:
return true;
break;
default:
return false;
break;
}
break;
}
case arg_string:
{
switch (arg_type)
{
case arg_string:
return true;
break;
default:
return false;
break;
}
break;
}
default:
{
return false;
break;
}
}
}
private:
int argtype;
int writebyte;
int writechar;
int writeshort;
int writelong;
float writeangle;
float writecoord;
char *writestring;
int writeentity;
argStack *next;
};
class MessageInfo
{
public:
MessageInfo(int msgdest, int msg_id, const float *Origin, edict_t* ed)
{
msgID = msg_id;
msg_dest = msgdest;
pOrigin = Origin;
v = ed;
CHeadArg = new argStack();
CTailArg = NULL;
argcount = 0;
}
~MessageInfo()
{
Destroy();
}
void SendMsg()
{
//we are going to build a message =D yay! gather 'round and watch.
argStack *p;
MESSAGE_BEGIN(msg_dest, msgID, pOrigin, v);
for (p=CHeadArg->link(); p!=NULL; p=p->link()) {
p->write_arg();
}
MESSAGE_END();
Destroy(); //clean up old arguments
}
void AddArg(int i, int j)
{
argStack *p;
if (CTailArg == NULL) {
p = CHeadArg->arg();
CTailArg = p;
} else {
p = CTailArg->arg();
CTailArg = p;
}
CTailArg->put(i,j);
argcount++;
}
void AddArg(int i, float f)
{
argStack *p;
if (CTailArg == NULL) {
p = CHeadArg->arg();
CTailArg = p;
} else {
p = CTailArg->arg();
CTailArg = p;
}
CTailArg->put(i,f);
argcount++;
}
void AddArg(int i, char *sz)
{
argStack *p;
if (CTailArg == NULL) {
p = CHeadArg->arg();
CTailArg = p;
} else {
p = CTailArg->arg();
CTailArg = p;
}
CTailArg->put(i,sz);
argcount++;
}
void Destroy()
{
argStack *p;
p = CHeadArg->link();
while (p) {
argStack *n = p->link();
delete p;
p = n;
}
argcount = 0;
}
bool Set(int n, int arg_type, int data)
{
argStack *p;
int i=0;
if (n>argcount) {
return false;
} else {
for (p=CHeadArg->link(); p!=NULL; p=p->link()) {
i++;
if (i==n) {
p->put(arg_type, data);
return true;
}
}
}
return false;
}
bool Set(int n, int arg_type, float data)
{
argStack *p;
int i=0;
if (n>argcount) {
return false;
} else {
for (p=CHeadArg->link(); p!=NULL; p=p->link()) {
i++;
if (i==n) {
p->put(arg_type, data);
return true;
}
}
}
return false;
}
bool Set(int n, int arg_type, char* data)
{
argStack *p;
int i=0;
if (n>argcount) {
return false;
} else {
for (p=CHeadArg->link(); p!=NULL; p=p->link()) {
i++;
if (i==n) {
p->put(arg_type, data);
return true;
}
}
}
return false;
}
int RetArg_Int(int n)
{
argStack *p;
int i=0;
if (n>argcount) {
return -1;
} else {
for (p=CHeadArg->link(); p!=NULL; p=p->link()) {
i++;
if (i==n) {
return p->getarg_int(arg_short);
}
}
}
return 0;
}
float RetArg_Float(int n)
{
argStack *p;
int i=0;
if (n>argcount) {
return -1;
} else {
for (p=CHeadArg->link(); p!=NULL; p=p->link()) {
i++;
if (i==n) {
return p->getarg_float(arg_coord);
}
}
}
return 0.0;
}
char* RetArg_String(int n)
{
argStack *p;
int i=0;
if (n>argcount) {
return NULL;
} else {
for (p=CHeadArg->link(); p!=NULL; p=p->link()) {
i++;
if (i==n) {
return p->getarg_string(arg_string);
}
}
}
return NULL;
}
int ArgType(int n)
{
argStack *p;
int i=0;
if (n>argcount) {
return -1;
} else {
for (p=CHeadArg->link(); p!=NULL; p=p->link()) {
i++;
if (i==n) {
return p->get_argtype();
}
}
}
return 0;
}
int args()
{
return argcount;
}
private:
int argcount;
int msgID;
int msg_dest;
const float *pOrigin;
edict_t *v;
argStack *CHeadArg;
argStack *CTailArg;
};
struct MsgSets
{
bool isHooked;
bool isCalled;
int type;
MessageInfo *msg;
AmxCallList msgCalls;
};

View File

@ -36,286 +36,18 @@
#include <modules.h>
#include <vector>
#include <limits.h>
#include "engine.h"
#define VERSION "0.5"
plugin_info_t Plugin_info = {
META_INTERFACE_VERSION, // ifvers
"ENGINE", // name
VERSION, // version
__DATE__, // date
"BAILOPAN", // author
"http://www.amxmod.info/", // url
"AMXXE", // logtag
PT_ANYTIME,// (when) loadable
PT_ANYTIME,// (when) unloadable
};
module_info_s module_info = {
"ENGINE", // name
"BAILOPAN", // author
VERSION, // version
AMX_INTERFACE_VERSION,
STATIC_MODULE,
};
class AmxCallList {
public:
struct AmxCall {
AMX *amx;
//void* code;
int iFunctionIdx;
AmxCall* next;
AmxCall( AMX *a , int i, AmxCall* n ) : amx(a), iFunctionIdx(i), next(n) {}
} *head;
AmxCallList() { head = 0; }
~AmxCallList() { clear(); }
void clear() {
while ( head ) {
AmxCall* a = head->next;
delete head;
head = a;
}
}
void put( AMX *a , int i )
{
head = new AmxCall( a, i , head );
}
};
AmxCallList pfnTouch;
AmxCallList serverFrame;
AmxCallList preThink;
AmxCallList postThink;
AmxCallList clientKill;
meta_globals_t *gpMetaGlobals;
gamedll_funcs_t *gpGamedllFuncs;
mutil_funcs_t *gpMetaUtilFuncs;
enginefuncs_t g_engfuncs;
globalvars_t *gpGlobals;
pfnamx_engine_g* g_engAmxFunc;
pfnmodule_engine_g* g_engModuleFunc;
extern AMX_NATIVE_INFO Engine_Natives[];
void (*function)(void*);
void (*endfunction)(void*);
#define AMS_OFFSET 0.01
#define SPEAK_NORMAL 0
#define SPEAK_MUTED 1
#define SPEAK_ALL 2
#define SPEAK_LISTENALL 4
#define CAMERA_NONE 0
#define CAMERA_3RDPERSON 1
#define CAMERA_UPLEFT 2
#define CAMERA_TOPDOWN 3
#define MAX_MESSAGES 255
#define BLOCK_NOT 0
#define BLOCK_ONCE 1
#define BLOCK_SET 2
enum {
gamestate,
oldbuttons,
groupinfo,
iuser1,
iuser2,
iuser3,
iuser4,
weaponanim,
pushmsec,
bInDuck,
flTimeStepSound,
flSwimTime,
flDuckTime,
iStepLeft,
movetype,
solid,
skin,
body,
effects,
light_level,
sequence,
gaitsequence,
modelindex,
playerclass,
waterlevel,
watertype,
spawnflags,
flags,
colormap,
team,
fixangle,
weapons,
rendermode,
renderfx,
button,
impulse,
deadflag,
};
enum {
impacttime,
starttime,
idealpitch,
pitch_speed,
ideal_yaw,
yaw_speed,
ltime,
nextthink,
gravity,
friction,
frame,
animtime,
framerate,
health,
frags,
takedamage,
max_health,
teleport_time,
armortype,
armorvalue,
dmg_take,
dmg_save,
dmg,
dmgtime,
speed,
air_finished,
pain_finished,
radsuit_finished,
scale,
renderamt,
maxspeed,
fov,
flFallVelocity,
fuser1,
fuser2,
fuser3,
fuser4,
};
enum {
origin,
oldorigin,
velocity,
basevelocity,
clbasevelocity,
movedir,
angles,
avelocity,
punchangle,
v_angle,
endpos,
startpos,
absmin,
absmax,
mins,
maxs,
size,
rendercolor,
view_ofs,
vuser1,
vuser2,
vuser3,
vuser4,
};
enum {
chain,
dmg_inflictor,
enemy,
aiment,
owner,
groundentity,
pContainingEntity,
euser1,
euser2,
euser3,
euser4,
};
enum {
classname,
globalname,
model,
target,
targetname,
netname,
message,
noise,
noise1,
noise2,
noise3,
viewmodel,
weaponmodel,
};
enum {
controller1,
controller2,
controller3,
controller4,
blending1,
blending2,
};
struct PlayerInfo {
bool bModeled;
char szModel[32];
float fModelSet;
int iSpeakFlags;
edict_t *pViewEnt;
int iViewType;
int iRenderMode;
float fRenderAmt;
};
PlayerInfo PlInfo[33];
struct GlobalInfo {
bool bLights;
float fNextLights;
char *szLastLights[128];
char *szRealLights[128];
int iMessageBlock[MAX_MESSAGES];
bool bBlocking;
};
extern "C" void destroy(MessageInfo* p) {
delete p;
}
GlobalInfo GlInfo;
MsgSets Msg[MAX_MESSAGES];
int LastMessage;
cvar_t amxxe_version = {"amxxe_version", VERSION, FCVAR_SERVER, 0};
/********************************************************
vexd's utility funcs
******************************************************/
@ -356,6 +88,254 @@ char *AMX_GET_STRING(AMX *oPlugin, cell tParam, int &iLength) {
exported functions
******************************************************/
//(BAILOPAN)
//Hooks a register_message()
static cell AMX_NATIVE_CALL register_message(AMX *amx, cell *params)
{
int iLen;
int iFunctionIndex;
int iMessage = params[1];
char *szFunction = AMX_GET_STRING(amx, params[2], iLen);
if (iMessage > 0 && iMessage < MAX_MESSAGES) {
if (AMX_FINDPUBLIC(amx, szFunction, &iFunctionIndex) == AMX_ERR_NONE) {
Msg[iMessage].isHooked = true;
Msg[iMessage].type = iMessage;
Msg[iMessage].msgCalls.put(amx, iFunctionIndex);
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
return 1;
}
//(BAILOPAN)
//Gets the argument type of a message argument
static cell AMX_NATIVE_CALL get_msg_argtype(AMX *amx, cell *params)
{
int msg_type = params[1];
int argn = params[2];
if (msg_type < 0 || msg_type > MAX_MESSAGES) {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
} else {
if ((Msg[msg_type].isHooked) && (Msg[msg_type].msg != NULL)) {
return Msg[msg_type].msg->ArgType(argn);
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
}
return 1;
}
//(BAILOPAN)
//Gets the argument count for a message.
static cell AMX_NATIVE_CALL get_msg_args(AMX *amx, cell *params)
{
int msg_type = params[1];
if (msg_type < 0 || msg_type > MAX_MESSAGES) {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
} else {
if ((Msg[msg_type].isHooked) && (Msg[msg_type].msg != NULL)) {
return Msg[msg_type].msg->args();
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
}
}
//(BAILOPAN)
//gets a message argument as an integer
static cell AMX_NATIVE_CALL get_msg_arg_int(AMX *amx, cell *params)
{
int msg_type = params[1];
int argn = params[2];
if (msg_type < 0 || msg_type > MAX_MESSAGES) {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
} else {
if (Msg[msg_type].isHooked && Msg[msg_type].msg!=NULL) {
if (argn < Msg[msg_type].msg->args() && argn > 0) {
return Msg[msg_type].msg->RetArg_Int(argn);
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
}
return 1;
}
//(BAILOPAN)
//gets a message argument as a float
static cell AMX_NATIVE_CALL get_msg_arg_float(AMX *amx, cell *params)
{
int msg_type = params[1];
int argn = params[2];
float retVal;
if (msg_type < 0 || msg_type > MAX_MESSAGES) {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
} else {
if (Msg[msg_type].isHooked && Msg[msg_type].msg!=NULL) {
if (argn < Msg[msg_type].msg->args() && argn > 0) {
retVal = Msg[msg_type].msg->RetArg_Float(argn);
return *(cell*)((void *)&retVal);
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
}
return 1;
}
//(BAILOPAN)
//gets a message argument as an string
static cell AMX_NATIVE_CALL get_msg_arg_string(AMX *amx, cell *params)
{
int msg_type = params[1];
int argn = params[2];
char *szValue;
if (msg_type < 0 || msg_type > MAX_MESSAGES) {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
} else {
if (Msg[msg_type].isHooked && Msg[msg_type].msg!=NULL) {
if (argn < Msg[msg_type].msg->args() && argn > 0) {
szValue = Msg[msg_type].msg->RetArg_String(argn);
return SET_AMXSTRING(amx, params[3], szValue, params[4]);
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
}
return 1;
}
//(BAILOPAN)
static cell AMX_NATIVE_CALL set_msg_arg_string(AMX *amx, cell *params)
{
int msg_type = params[1];
int argn = params[2];
int iLen;
char *szData = AMX_GET_STRING(amx, params[3], iLen);
if (msg_type < 0 || msg_type > MAX_MESSAGES) {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
} else {
if (Msg[msg_type].isHooked && Msg[msg_type].msg!=NULL) {
if (argn < Msg[msg_type].msg->args() && argn > 0) {
if (Msg[msg_type].msg->Set(argn, arg_string, szData)) {
return 1;
} else {
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
}
return 1;
}
//(BAILOPAN)
static cell AMX_NATIVE_CALL set_msg_arg_float(AMX *amx, cell *params)
{
int msg_type = params[1];
int argn = params[2];
int argtype = params[3];
if (msg_type < 0 || msg_type > MAX_MESSAGES) {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
} else {
if (Msg[msg_type].isHooked && Msg[msg_type].msg!=NULL) {
if (argn < Msg[msg_type].msg->args() && argn > 0) {
if (Msg[msg_type].msg->Set(argn, argtype, params[4])) {
return 1;
} else {
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
}
return 1;
}
//(BAILOPAN)
static cell AMX_NATIVE_CALL set_msg_arg_int(AMX *amx, cell *params)
{
int msg_type = params[1];
int argn = params[2];
int argtype = params[3];
int iData = params[4];
if (msg_type < 0 || msg_type > MAX_MESSAGES) {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
} else {
if (Msg[msg_type].isHooked && Msg[msg_type].msg!=NULL) {
if (argn < Msg[msg_type].msg->args() && argn > 0) {
if (Msg[msg_type].msg->Set(argn, argtype, iData)) {
return 1;
} else {
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
} else {
AMX_RAISEERROR(amx, AMX_ERR_NATIVE);
return 0;
}
}
return 1;
}
//(BAILOPAN)
//Sets a pvPrivateData offset for a player (player, offset, val, float=0)
static cell AMX_NATIVE_CALL set_offset_short(AMX *amx, cell *params)
@ -2467,6 +2447,14 @@ static cell AMX_NATIVE_CALL attach_view(AMX *amx, cell *params) {
return 1;
}
static cell AMX_NATIVE_CALL precache_generic(AMX *amx, cell *params)
{
int len;
char* szPreCache = GET_AMXSTRING(amx,params[1],0,len);
PRECACHE_GENERIC((char*)STRING(ALLOC_STRING(szPreCache)));
return 1;
}
/********************************************
METAMOD HOOKED FUNCTIONS
*****************************************/
@ -2619,12 +2607,18 @@ void ClientDisconnect(edict_t *pEntity) {
// pfnTouch, this is a forward that is called whenever 2 entities collide.
void Touch(edict_t *pToucher, edict_t *pTouched) {
cell iResult;
META_RES result = MRES_IGNORED;
for (AmxCallList::AmxCall* i = pfnTouch.head; i; i = i->next) {
AMX_EXEC(i->amx, NULL, i->iFunctionIdx, 2, pToucher, pTouched);
AMX_EXEC(i->amx, &iResult, i->iFunctionIdx, 2, pToucher, pTouched);
if (iResult & 2) {
RETURN_META(MRES_SUPERCEDE);
} else if (iResult & 1) {
result = MRES_SUPERCEDE;
}
}
RETURN_META(MRES_IGNORED);
RETURN_META(result);
}
// ClientConnect, reinitialize player info here as well.
@ -2680,23 +2674,58 @@ void MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
}
RETURN_META(MRES_SUPERCEDE);
} else {
if (Msg[msg_type].isHooked && !Msg[msg_type].isCalled) {
LastMessage = msg_type;
Msg[msg_type].msg = new MessageInfo(msg_dest, msg_type, pOrigin, ed);
Msg[msg_type].isCalled = true;
RETURN_META(MRES_SUPERCEDE);
}
}
RETURN_META(MRES_IGNORED);
}
void MessageEnd(void) {
cell iResult;
META_RES result = MRES_IGNORED;
if(GlInfo.bBlocking) {
GlInfo.bBlocking = false;
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
int msg_type = LastMessage;
if (Msg[msg_type].isHooked && Msg[msg_type].isCalled) {
for (AmxCallList::AmxCall* i = Msg[msg_type].msgCalls.head; i; i = i->next) {
AMX_EXEC(i->amx, &iResult, i->iFunctionIdx, 1, msg_type);
if (iResult & 2) {
RETURN_META(MRES_SUPERCEDE);
} else if (iResult & 1) {
result = MRES_SUPERCEDE;
}
}
Msg[msg_type].isCalled = false;
if (result != MRES_SUPERCEDE) { //supercede the message ANYWAY
Msg[msg_type].msg->SendMsg();
result = MRES_SUPERCEDE;
}
//destroy(Msg[msg_type].msg);
}
RETURN_META(result);
}
void WriteByte(int iValue) {
if(GlInfo.bBlocking) {
RETURN_META(MRES_SUPERCEDE);
}
int msg_type = LastMessage;
if (msg_type && Msg[msg_type].isCalled && Msg[msg_type].isHooked) {
Msg[msg_type].msg->AddArg(arg_byte, iValue);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
@ -2704,6 +2733,11 @@ void WriteChar(int iValue) {
if(GlInfo.bBlocking) {
RETURN_META(MRES_SUPERCEDE);
}
int msg_type = LastMessage;
if (msg_type && Msg[msg_type].isCalled && Msg[msg_type].isHooked) {
Msg[msg_type].msg->AddArg(arg_char, iValue);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
@ -2711,6 +2745,11 @@ void WriteShort(int iValue) {
if(GlInfo.bBlocking) {
RETURN_META(MRES_SUPERCEDE);
}
int msg_type = LastMessage;
if (msg_type && Msg[msg_type].isCalled && Msg[msg_type].isHooked) {
Msg[msg_type].msg->AddArg(arg_short, iValue);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
@ -2718,6 +2757,11 @@ void WriteLong(int iValue) {
if(GlInfo.bBlocking) {
RETURN_META(MRES_SUPERCEDE);
}
int msg_type = LastMessage;
if (msg_type && Msg[msg_type].isCalled && Msg[msg_type].isHooked) {
Msg[msg_type].msg->AddArg(arg_long, iValue);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
@ -2725,6 +2769,11 @@ void WriteAngle(float flValue) {
if(GlInfo.bBlocking) {
RETURN_META(MRES_SUPERCEDE);
}
int msg_type = LastMessage;
if (msg_type && Msg[msg_type].isCalled && Msg[msg_type].isHooked) {
Msg[msg_type].msg->AddArg(arg_angle, flValue);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
@ -2732,6 +2781,11 @@ void WriteCoord(float flValue) {
if(GlInfo.bBlocking) {
RETURN_META(MRES_SUPERCEDE);
}
int msg_type = LastMessage;
if (msg_type && Msg[msg_type].isCalled && Msg[msg_type].isHooked) {
Msg[msg_type].msg->AddArg(arg_coord, flValue);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
@ -2739,6 +2793,11 @@ void WriteString(const char *sz) {
if(GlInfo.bBlocking) {
RETURN_META(MRES_SUPERCEDE);
}
int msg_type = LastMessage;
if (msg_type && Msg[msg_type].isCalled && Msg[msg_type].isHooked) {
Msg[msg_type].msg->AddArg(arg_string, (char*)sz);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
@ -2746,6 +2805,11 @@ void WriteEntity(int iValue) {
if(GlInfo.bBlocking) {
RETURN_META(MRES_SUPERCEDE);
}
int msg_type = LastMessage;
if (msg_type && Msg[msg_type].isCalled && Msg[msg_type].isHooked) {
Msg[msg_type].msg->AddArg(arg_entity, iValue);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
@ -2779,6 +2843,13 @@ void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ){
}
}
for (i=0; i<MAX_MESSAGES; i++) {
Msg[i].isHooked = false;
Msg[i].isCalled = false;
Msg[i].msg = NULL;
Msg[i].type = 0;
}
RETURN_META(MRES_IGNORED);
}
@ -2794,9 +2865,14 @@ void ServerDeactivate() {
preThink.clear();
clientKill.clear();
int i;
// Reset message blocks.
for(int i = 0; i < MAX_MESSAGES; i++) {
for(i = 0; i < MAX_MESSAGES; i++) {
GlInfo.iMessageBlock[i] = BLOCK_NOT;
if (Msg[i].msg != NULL) {
destroy(Msg[i].msg);
Msg[i].msgCalls.clear();
}
}
RETURN_META(MRES_IGNORED);
@ -3048,6 +3124,17 @@ AMX_NATIVE_INFO Engine_Natives[] = {
{"set_view", set_view},
{"attach_view", attach_view},
{"precache_generic", precache_generic},
{"register_message", register_message},
{"set_msg_arg_float", set_msg_arg_float},
{"set_msg_arg_int", set_msg_arg_int},
{"set_msg_arg_string", set_msg_arg_string},
{"get_msg_arg_float", get_msg_arg_float},
{"get_msg_arg_int", get_msg_arg_int},
{"get_msg_arg_string", get_msg_arg_string},
{"get_msg_args", get_msg_args},
{"get_msg_argtype", get_msg_argtype},
{ NULL, NULL }
};