Oh goodness, let the bugs begin...

1) Fixed getting incorrect value of the entity index when using ClientUserInfoChanged via dllfunc
2) New hookable GameDLL funcs: UpdateClientData, AddToFullPack, CmdStart, CmdEnd (at28754)
3) New GameDLL funcs that can be called via dllfunc: UpdateClientData, AddToFullPack, CmdStart, CmdEnd
4) New natives to read/write special data structures associated with the above GameDLL funcs
This commit is contained in:
Scott Ehlert 2006-04-30 07:27:14 +00:00
parent 0555e7aa63
commit 0071d73e25
10 changed files with 1277 additions and 9 deletions

View File

@ -6,12 +6,15 @@ static cell AMX_NATIVE_CALL dllfunc(AMX *amx,cell *params)
int type;
int index;
int indexb;
unsigned char *pset;
char *temp = "";
char *temp2 = "";
char *temp3 = "";
vec3_t Vec1;
vec3_t Vec2;
int iparam1;
int iparam2;
int iparam3;
int len;
cell *cRet;
type = params[1];
@ -219,7 +222,7 @@ static cell AMX_NATIVE_CALL dllfunc(AMX *amx,cell *params)
case DLLFunc_pfnAllowLagCompensation: // int )( void );
return gpGamedllFuncs->dllapi_table->pfnAllowLagCompensation();
// I know this doesn't fit with dllfunc, but I dont want to create another native JUST for this.
// I know this doesn't fit with dllfunc, but I don't want to create another native JUST for this.
case MetaFunc_CallGameEntity: // bool (plid_t plid, const char *entStr,entvars_t *pev);
temp = MF_GetAmxString(amx,params[2],0,&len);
cRet = MF_GetAmxAddr(amx,params[3]);
@ -228,13 +231,100 @@ static cell AMX_NATIVE_CALL dllfunc(AMX *amx,cell *params)
iparam1 = gpMetaUtilFuncs->pfnCallGameEntity(PLID,STRING(ALLOC_STRING(temp)),VARS(INDEXENT2(index)));
return iparam1;
case DLLFunc_ClientUserInfoChanged: // void ) (edict_t *pEntity, char *infobuffer)
cRet = MF_GetAmxAddr(amx,params[1]);
cRet = MF_GetAmxAddr(amx,params[2]);
index = cRet[0];
CHECK_ENTITY(index);
gpGamedllFuncs->dllapi_table->pfnClientUserInfoChanged(INDEXENT2(index),(*g_engfuncs.pfnGetInfoKeyBuffer)(INDEXENT2(index)));
return 1;
case DLLFunc_UpdateClientData: // void ) (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd)
cRet = MF_GetAmxAddr(amx, params[2]);
index = cRet[0];
CHECK_ENTITY(index);
cRet = MF_GetAmxAddr(amx, params[3]);
iparam1 = cRet[0];
clientdata_t *cd;
if ((params[0] / sizeof(cell)) == 4)
{
cell *ptr = MF_GetAmxAddr(amx, params[4]);
if (*ptr == 0)
cd = &g_cd_glb;
else
cd = reinterpret_cast<clientdata_s *>(*ptr);
}
else
cd = &g_cd_glb;
gpGamedllFuncs->dllapi_table->pfnUpdateClientData(INDEXENT2(index), iparam1, cd);
return 1;
case DLLFunc_AddToFullPack: // int ) (struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet)
entity_state_t *es;
cRet = MF_GetAmxAddr(amx, params[2]);
if (*cRet == 0)
es = &g_es_glb;
else
es = reinterpret_cast<entity_state_t *>(*cRet);
// int e
cRet = MF_GetAmxAddr(amx, params[3]);
iparam1 = cRet[0];
// edict_t *ent
cRet = MF_GetAmxAddr(amx, params[4]);
index = cRet[0];
CHECK_ENTITY(index);
// edict_t *host
cRet = MF_GetAmxAddr(amx, params[5]);
indexb = cRet[0];
CHECK_ENTITY(indexb);
// int hostflags
cRet = MF_GetAmxAddr(amx, params[6]);
iparam2 = cRet[0];
// int player
cRet = MF_GetAmxAddr(amx, params[7]);
iparam3 = cRet[0];
// unsigned char *pSet
cRet = MF_GetAmxAddr(amx, params[8]);
pset = reinterpret_cast<unsigned char *>(*cRet);
return gpGamedllFuncs->dllapi_table->pfnAddToFullPack(es, iparam1, INDEXENT2(index), INDEXENT2(indexb), iparam2, iparam3, pset);
case DLLFunc_CmdStart: // void ) (const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed)
cRet = MF_GetAmxAddr(amx, params[2]);
index = cRet[0];
CHECK_ENTITY(index);
usercmd_t *uc;
cRet = MF_GetAmxAddr(amx, params[3]);
if (*cRet == 0)
uc = &g_uc_glb;
else
uc = reinterpret_cast<usercmd_t *>(*cRet);
cRet = MF_GetAmxAddr(amx, params[4]);
iparam1 = cRet[0];
gpGamedllFuncs->dllapi_table->pfnCmdStart(INDEXENT2(index), uc, iparam1);
return 1;
case DLLFunc_CmdEnd: // void ) (const edict_t *player)
cRet = MF_GetAmxAddr(amx, params[2]);
index = cRet[0];
CHECK_ENTITY(index);
gpGamedllFuncs->dllapi_table->pfnCmdEnd(INDEXENT2(index));
return 1;
default:
MF_LogError(amx, AMX_ERR_NATIVE, "Unknown dllfunc entry %d", type);
return 0;

View File

@ -50,9 +50,16 @@ enum
// Create baselines for certain "unplaced" items.
DLLFunc_CreateInstancedBaselines, // void ) ( void );
DLLFunc_pfnAllowLagCompensation, // int ) ( void );
// I know this does not fit with DLLFUNC(), but I dont want another native just for it.
// I know this does not fit with DLLFUNC(), but I don't want another native just for it.
MetaFunc_CallGameEntity, // bool ) (plid_t plid, const char *entStr,entvars_t *pev);
DLLFunc_ClientUserInfoChanged // void ) (idplayer)
DLLFunc_ClientUserInfoChanged, // void ) (idplayer)
// You can pass in 0 for global client data handle or another client data handle here
DLLFunc_UpdateClientData, // void ) (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd);
// You can pass in 0 for global entity state handle or another entity state handle here
DLLFunc_AddToFullPack, // int ) (struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet);
// You can pass in 0 for global usercmd handle or another usercmd handle here
DLLFunc_CmdStart, // void ) (const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed);
DLLFunc_CmdEnd // void ) (const edict_t *player);
};
#endif //_INCLUDE_DLLFUNC_H

View File

@ -28,6 +28,7 @@ static cell AMX_NATIVE_CALL engfunc(AMX *amx, cell *params)
float fparam3;
// float fTemp[3];
int index;
unsigned char *pset;
edict_t *pRet=NULL;
// Now start calling.. :/
switch (type)
@ -918,8 +919,9 @@ static cell AMX_NATIVE_CALL engfunc(AMX *amx, cell *params)
cRet = MF_GetAmxAddr(amx, params[2]);
index = cRet[0];
CHECK_ENTITY(index);
temp = MF_GetAmxString(amx,params[3],0,&len);
return (*g_engfuncs.pfnCheckVisibility)(INDEXENT2(index), (unsigned char *)STRING(ALLOC_STRING(temp)));
cRet = MF_GetAmxAddr(amx, params[3]);
pset = (unsigned char *)cRet[0];
return (*g_engfuncs.pfnCheckVisibility)(INDEXENT2(index), pset);
// pfnGetCurrentPlayer
case EngFunc_GetCurrentPlayer: // int ) ( void );

View File

@ -168,6 +168,10 @@ void FMH_ServerDeactivate()
RESETD(CreateInstancedBaselines);
RESETD(AllowLagCompensation);
RESETD(ClientUserInfoChanged);
RESETD(UpdateClientData);
RESETD(AddToFullPack);
RESETD(CmdStart);
RESETD(CmdEnd);
RESETN(OnFreeEntPrivateData);
RESETN(GameShutdown);

View File

@ -2,6 +2,8 @@
#define _FAKEMETA_INCLUDE_H
#include "sdk/amxxmodule.h"
#include <entity_state.h>
#include <usercmd.h>
#include "CVector.h"
#include "engfunc.h"
#include "dllfunc.h"

View File

@ -8,6 +8,12 @@ extern TraceResult *gfm_tr;
//these also don't fit in here but gaben does not care. GABEN DOES NOT CARE!!!
extern TraceResult g_tr_2;
extern KeyValueData g_kvd_2;
extern clientdata_t g_cd_glb;
extern clientdata_t *g_cd_hook;
extern entity_state_t g_es_glb;
extern entity_state_t *g_es_hook;
extern usercmd_t g_uc_glb;
extern usercmd_t *g_uc_hook;
struct KVD_Wrapper
{
@ -42,6 +48,165 @@ enum KeyValue
KV_fHandled
};
enum ClientData
{
CD_Origin,
CD_Velocity,
CD_ViewModel,
CD_PunchAngle,
CD_Flags,
CD_WaterLevel,
CD_WaterType,
CD_ViewOfs,
CD_Health,
CD_bInDuck,
CD_Weapons,
CD_flTimeStepSound,
CD_flDuckTime,
CD_flSwimTime,
CD_WaterJumpTime,
CD_MaxSpeed,
CD_FOV,
CD_WeaponAnim,
CD_ID,
CD_AmmoShells,
CD_AmmoNails,
CD_AmmoCells,
CD_AmmoRockets,
CD_flNextAttack,
CD_tfState,
CD_PushMsec,
CD_DeadFlag,
CD_PhysInfo,
CD_iUser1,
CD_iUser2,
CD_iUser3,
CD_iUser4,
CD_fUser1,
CD_fUser2,
CD_fUser3,
CD_fUser4,
CD_vUser1,
CD_vUser2,
CD_vUser3,
CD_vUser4
};
enum EntityState
{
// Fields which are filled in by routines outside of delta compression
ES_EntityType,
// Index into cl_entities array for this entity
ES_Number,
ES_MsgTime,
// Message number last time the player/entity state was updated
ES_MessageNum,
// Fields which can be transitted and reconstructed over the network stream
ES_Origin,
ES_Angles,
ES_ModelIndex,
ES_Sequence,
ES_Frame,
ES_ColorMap,
ES_Skin,
ES_Solid,
ES_Effects,
ES_Scale,
ES_eFlags,
// Render information
ES_RenderMode,
ES_RenderAmt,
ES_RenderColor,
ES_RenderFx,
ES_MoveType,
ES_AnimTime,
ES_FrameRate,
ES_Body,
ES_Controller,
ES_Blending,
ES_Velocity,
// Send bbox down to client for use during prediction
ES_Mins,
ES_Maxs,
ES_AimEnt,
// If owned by a player, the index of that player (for projectiles)
ES_Owner,
// Friction, for prediction
ES_Friction,
// Gravity multiplier
ES_Gravity,
// PLAYER SPECIFIC
ES_Team,
ES_PlayerClass,
ES_Health,
ES_Spectator,
ES_WeaponModel,
ES_GaitSequence,
// If standing on conveyor, e.g.
ES_BaseVelocity,
// Use the crouched hull, or the regular player hull
ES_UseHull,
// Latched buttons last time state updated
ES_OldButtons,
// -1 = in air, else pmove entity number
ES_OnGround,
ES_iStepLeft,
// How fast we are falling
ES_flFallVelocity,
ES_FOV,
ES_WeaponAnim,
// Parametric movement overrides
ES_StartPos,
ES_EndPos,
ES_ImpactTime,
ES_StartTime,
// For mods
ES_iUser1,
ES_iUser2,
ES_iUser3,
ES_iUser4,
ES_fUser1,
ES_fUser2,
ES_fUser3,
ES_fUser4,
ES_vUser1,
ES_vUser2,
ES_vUser3,
ES_vUser4
};
enum UserCmd
{
UC_LerpMsec, // Interpolation time on client
UC_Msec, // Duration in ms of command
UC_ViewAngles, // Command view angles
// Intended velocities
UC_ForwardMove, // Forward velocity
UC_SideMove, // Sideways velocity
UC_UpMove, // Upward velocity
UC_LightLevel, // Light level at spot where we are standing
UC_Buttons, // Attack buttons
UC_Impulse, // Impulse command issued
UC_WeaponSelect, // Current weapon id
// Experimental player impact stuff
UC_ImpactIndex,
UC_ImpactPosition
};
extern AMX_NATIVE_INFO tr_Natives[];
extern AMX_NATIVE_INFO ext2_natives[];

View File

@ -5,6 +5,10 @@ KeyValueData g_kvd_2;
KVD_Wrapper g_kvd_glb;
clientdata_t g_cd_glb;
entity_state_t g_es_glb;
usercmd_t g_uc_glb;
static cell AMX_NATIVE_CALL set_tr2(AMX *amx, cell *params)
{
TraceResult *tr;
@ -298,12 +302,925 @@ static cell AMX_NATIVE_CALL set_kvd(AMX *amx, cell *params)
return 0;
}
static cell AMX_NATIVE_CALL get_cd(AMX *amx, cell *params)
{
clientdata_s *cd;
if (params[1] == 0)
cd = &g_cd_glb;
else
cd = reinterpret_cast<clientdata_t *>(params[1]);
cell *ptr;
switch(params[2])
{
case CD_Origin:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(cd->origin.x);
ptr[1] = amx_ftoc(cd->origin.y);
ptr[2] = amx_ftoc(cd->origin.z);
return 1;
case CD_Velocity:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(cd->velocity.x);
ptr[1] = amx_ftoc(cd->velocity.y);
ptr[2] = amx_ftoc(cd->velocity.z);
return 1;
case CD_ViewModel:
return cd->viewmodel;
case CD_PunchAngle:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(cd->punchangle.x);
ptr[1] = amx_ftoc(cd->punchangle.y);
ptr[2] = amx_ftoc(cd->punchangle.z);
return 1;
case CD_Flags:
return cd->flags;
case CD_WaterLevel:
return cd->waterlevel;
case CD_WaterType:
return cd->watertype;
case CD_ViewOfs:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(cd->view_ofs.x);
ptr[1] = amx_ftoc(cd->view_ofs.y);
ptr[2] = amx_ftoc(cd->view_ofs.z);
return 1;
case CD_Health:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(cd->health);
return 1;
case CD_bInDuck:
return cd->bInDuck;
case CD_Weapons:
return cd->weapons;
case CD_flTimeStepSound:
return cd->flTimeStepSound;
case CD_flDuckTime:
return cd->flDuckTime;
case CD_flSwimTime:
return cd->flSwimTime;
case CD_WaterJumpTime:
return cd->waterjumptime;
case CD_MaxSpeed:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(cd->maxspeed);
return 1;
case CD_FOV:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(cd->fov);
return 1;
case CD_WeaponAnim:
return cd->weaponanim;
case CD_ID:
return cd->m_iId;
case CD_AmmoShells:
return cd->ammo_shells;
case CD_AmmoNails:
return cd->ammo_nails;
case CD_AmmoCells:
return cd->ammo_cells;
case CD_AmmoRockets:
return cd->ammo_rockets;
case CD_flNextAttack:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(cd->m_flNextAttack);
return 1;
case CD_tfState:
return cd->tfstate;
case CD_PushMsec:
return cd->pushmsec;
case CD_DeadFlag:
return cd->deadflag;
case CD_PhysInfo:
ptr = MF_GetAmxAddr(amx, params[4]);
return MF_SetAmxString(amx, params[3], cd->physinfo, (int)*ptr);
case CD_iUser1:
return cd->iuser1;
case CD_iUser2:
return cd->iuser2;
case CD_iUser3:
return cd->iuser3;
case CD_iUser4:
return cd->iuser4;
case CD_fUser1:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(cd->fuser1);
return 1;
case CD_fUser2:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(cd->fuser2);
return 1;
case CD_fUser3:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(cd->fuser3);
return 1;
case CD_fUser4:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(cd->fuser4);
return 1;
case CD_vUser1:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(cd->vuser1.x);
ptr[1] = amx_ftoc(cd->vuser1.y);
ptr[2] = amx_ftoc(cd->vuser1.z);
return 1;
case CD_vUser2:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(cd->vuser2.x);
ptr[1] = amx_ftoc(cd->vuser2.y);
ptr[2] = amx_ftoc(cd->vuser2.z);
return 1;
case CD_vUser3:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(cd->vuser3.x);
ptr[1] = amx_ftoc(cd->vuser3.y);
ptr[2] = amx_ftoc(cd->vuser3.z);
return 1;
case CD_vUser4:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(cd->vuser4.x);
ptr[1] = amx_ftoc(cd->vuser4.y);
ptr[2] = amx_ftoc(cd->vuser4.z);
return 1;
}
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid ClientData member: %d", params[2]);
return 0;
}
static cell AMX_NATIVE_CALL set_cd(AMX *amx, cell *params)
{
if (*params / sizeof(cell) < 3)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No data passed");
return 0;
}
clientdata_s *cd;
if (params[1] == 0)
cd = &g_cd_glb;
else
cd = reinterpret_cast<clientdata_t *>(params[1]);
cell *ptr = MF_GetAmxAddr(amx, params[3]);
char *phys;
switch(params[2])
{
case CD_Origin:
cd->origin.x = amx_ctof(ptr[0]);
cd->origin.y = amx_ctof(ptr[1]);
cd->origin.z = amx_ctof(ptr[2]);
return 1;
case CD_Velocity:
cd->velocity.x = amx_ctof(ptr[0]);
cd->velocity.y = amx_ctof(ptr[1]);
cd->velocity.z = amx_ctof(ptr[2]);
return 1;
case CD_ViewModel:
cd->viewmodel = *ptr;
return 1;
case CD_PunchAngle:
cd->punchangle.x = amx_ctof(ptr[0]);
cd->punchangle.y = amx_ctof(ptr[1]);
cd->punchangle.z = amx_ctof(ptr[2]);
return 1;
case CD_Flags:
cd->flags = *ptr;
return 1;
case CD_WaterLevel:
cd->waterlevel = *ptr;
return 1;
case CD_WaterType:
cd->watertype = *ptr;
return 1;
case CD_ViewOfs:
cd->view_ofs.x = amx_ctof(ptr[0]);
cd->view_ofs.y = amx_ctof(ptr[1]);
cd->view_ofs.z = amx_ctof(ptr[2]);
return 1;
case CD_Health:
cd->health = amx_ctof(*ptr);
return 1;
case CD_bInDuck:
cd->bInDuck = *ptr;
return 1;
case CD_Weapons:
cd->weapons = *ptr;
return 1;
case CD_flTimeStepSound:
cd->flTimeStepSound = *ptr;
return 1;
case CD_flDuckTime:
cd->flDuckTime = *ptr;
return 1;
case CD_flSwimTime:
cd->flSwimTime = *ptr;
return 1;
case CD_WaterJumpTime:
cd->waterjumptime = *ptr;
return 1;
case CD_MaxSpeed:
cd->maxspeed = amx_ctof(*ptr);
return 1;
case CD_FOV:
cd->fov = amx_ctof(*ptr);
return 1;
case CD_WeaponAnim:
cd->weaponanim = *ptr;
return 1;
case CD_ID:
cd->m_iId = *ptr;
return 1;
case CD_AmmoShells:
cd->ammo_shells = *ptr;
return 1;
case CD_AmmoNails:
cd->ammo_nails = *ptr;
return 1;
case CD_AmmoCells:
cd->ammo_cells = *ptr;
return 1;
case CD_AmmoRockets:
cd->ammo_rockets = *ptr;
return 1;
case CD_flNextAttack:
cd->m_flNextAttack = amx_ctof(*ptr);
return 1;
case CD_tfState:
cd->tfstate = *ptr;
return 1;
case CD_PushMsec:
cd->pushmsec = *ptr;
return 1;
case CD_DeadFlag:
cd->deadflag = *ptr;
return 1;
case CD_PhysInfo:
int len;
phys = MF_GetAmxString(amx, params[3], 0, &len);
strncpy(cd->physinfo, phys, len);
return 1;
case CD_iUser1:
cd->iuser1 = *ptr;
return 1;
case CD_iUser2:
cd->iuser2 = *ptr;
return 1;
case CD_iUser3:
cd->iuser3 = *ptr;
return 1;
case CD_iUser4:
cd->iuser4 = *ptr;
return 1;
case CD_fUser1:
cd->fuser1 = amx_ctof(*ptr);
return 1;
case CD_fUser2:
cd->fuser2 = amx_ctof(*ptr);
return 1;
case CD_fUser3:
cd->fuser3 = amx_ctof(*ptr);
return 1;
case CD_fUser4:
cd->fuser4 = amx_ctof(*ptr);
return 1;
case CD_vUser1:
cd->vuser1.x = amx_ctof(ptr[0]);
cd->vuser1.y = amx_ctof(ptr[1]);
cd->vuser1.z = amx_ctof(ptr[2]);
return 1;
case CD_vUser2:
cd->vuser2.x = amx_ctof(ptr[0]);
cd->vuser2.y = amx_ctof(ptr[1]);
cd->vuser2.z = amx_ctof(ptr[2]);
return 1;
case CD_vUser3:
cd->vuser3.x = amx_ctof(ptr[0]);
cd->vuser3.y = amx_ctof(ptr[1]);
cd->vuser3.z = amx_ctof(ptr[2]);
return 1;
case CD_vUser4:
cd->vuser4.x = amx_ctof(ptr[0]);
cd->vuser4.y = amx_ctof(ptr[1]);
cd->vuser4.z = amx_ctof(ptr[2]);
return 1;
}
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid ClientData member: %d", params[2]);
return 0;
}
static cell AMX_NATIVE_CALL get_es(AMX *amx, cell *params)
{
entity_state_t *es;
if (params[1] == 0)
es = &g_es_glb;
else
es = reinterpret_cast<entity_state_t *>(params[1]);
cell *ptr;
switch(params[2])
{
case ES_EntityType:
return es->entityType;
case ES_Number:
return es->number;
case ES_MsgTime:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->msg_time);
return 1;
case ES_MessageNum:
return es->messagenum;
case ES_Origin:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->origin.x);
ptr[1] = amx_ftoc(es->origin.y);
ptr[2] = amx_ftoc(es->origin.z);
return 1;
case ES_Angles:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->angles.x);
ptr[1] = amx_ftoc(es->angles.y);
ptr[2] = amx_ftoc(es->angles.z);
return 1;
case ES_ModelIndex:
return es->modelindex;
case ES_Sequence:
return es->sequence;
case ES_Frame:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->frame);
return 1;
case ES_ColorMap:
return es->colormap;
case ES_Skin:
return es->skin;
case ES_Solid:
return es->solid;
case ES_Effects:
return es->effects;
case ES_Scale:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->scale);
return 1;
case ES_eFlags:
return es->eflags;
case ES_RenderMode:
return es->rendermode;
case ES_RenderAmt:
return es->renderamt;
case ES_RenderColor:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = es->rendercolor.r;
ptr[1] = es->rendercolor.b;
ptr[2] = es->rendercolor.g;
return 1;
case ES_RenderFx:
return es->renderfx;
case ES_MoveType:
return es->movetype;
case ES_AnimTime:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->animtime);
return 1;
case ES_FrameRate:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->framerate);
return 1;
case ES_Controller:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = es->controller[0];
ptr[1] = es->controller[1];
ptr[2] = es->controller[2];
ptr[3] = es->controller[3];
return 1;
case ES_Blending:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = es->blending[0];
ptr[1] = es->blending[1];
ptr[2] = es->blending[2];
ptr[3] = es->blending[3];
return 1;
case ES_Velocity:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->velocity.x);
ptr[1] = amx_ftoc(es->velocity.y);
ptr[2] = amx_ftoc(es->velocity.z);
return 1;
case ES_Mins:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->mins.x);
ptr[1] = amx_ftoc(es->mins.y);
ptr[2] = amx_ftoc(es->mins.z);
return 1;
case ES_Maxs:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->maxs.x);
ptr[1] = amx_ftoc(es->maxs.y);
ptr[2] = amx_ftoc(es->maxs.z);
return 1;
case ES_AimEnt:
return es->aiment;
case ES_Owner:
return es->owner;
case ES_Friction:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->friction);
return 1;
case ES_Gravity:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->gravity);
return 1;
case ES_Team:
return es->team;
case ES_PlayerClass:
return es->playerclass;
case ES_Health:
return es->health;
case ES_Spectator:
return es->spectator;
case ES_WeaponModel:
return es->weaponmodel;
case ES_GaitSequence:
return es->gaitsequence;
case ES_BaseVelocity:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->basevelocity.x);
ptr[1] = amx_ftoc(es->basevelocity.y);
ptr[2] = amx_ftoc(es->basevelocity.z);
return 1;
case ES_UseHull:
return es->usehull;
case ES_OldButtons:
return es->oldbuttons;
case ES_OnGround:
return es->onground;
case ES_iStepLeft:
return es->iStepLeft;
case ES_flFallVelocity:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->flFallVelocity);
return 1;
case ES_FOV:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->fov);
return 1;
case ES_WeaponAnim:
return es->weaponanim;
case ES_StartPos:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->startpos.x);
ptr[1] = amx_ftoc(es->startpos.y);
ptr[2] = amx_ftoc(es->startpos.z);
return 1;
case ES_EndPos:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->endpos.x);
ptr[1] = amx_ftoc(es->endpos.y);
ptr[2] = amx_ftoc(es->endpos.z);
return 1;
case ES_ImpactTime:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->impacttime);
return 1;
case ES_StartTime:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->starttime);
return 1;
case ES_iUser1:
return es->iuser1;
case ES_iUser2:
return es->iuser2;
case ES_iUser3:
return es->iuser3;
case ES_iUser4:
return es->iuser4;
case ES_fUser1:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->fuser1);
return 1;
case ES_fUser2:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->fuser2);
return 1;
case ES_fUser3:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->fuser3);
return 1;
case ES_fUser4:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(es->fuser4);
return 1;
case ES_vUser1:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->vuser1.x);
ptr[1] = amx_ftoc(es->vuser1.y);
ptr[2] = amx_ftoc(es->vuser1.z);
return 1;
case ES_vUser2:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->vuser2.x);
ptr[1] = amx_ftoc(es->vuser2.y);
ptr[2] = amx_ftoc(es->vuser2.z);
return 1;
case ES_vUser3:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->vuser3.x);
ptr[1] = amx_ftoc(es->vuser3.y);
ptr[2] = amx_ftoc(es->vuser3.z);
return 1;
case ES_vUser4:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(es->vuser4.x);
ptr[1] = amx_ftoc(es->vuser4.y);
ptr[2] = amx_ftoc(es->vuser4.z);
return 1;
}
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid EntityState member: %d", params[2]);
return 0;
}
static cell AMX_NATIVE_CALL set_es(AMX *amx, cell *params)
{
if (*params / sizeof(cell) < 3)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No data passed");
return 0;
}
entity_state_t *es;
if (params[1] == 0)
es = &g_es_glb;
else
es = reinterpret_cast<entity_state_t *>(params[1]);
cell *ptr = MF_GetAmxAddr(amx, params[3]);
switch(params[2])
{
case ES_EntityType:
es->entityType = *ptr;
return 1;
case ES_Number:
es->number = *ptr;
return 1;
case ES_MsgTime:
es->msg_time = amx_ctof(*ptr);
return 1;
case ES_MessageNum:
es->messagenum = *ptr;
return 1;
case ES_Origin:
es->origin.x = amx_ctof(ptr[0]);
es->origin.y = amx_ctof(ptr[1]);
es->origin.z = amx_ctof(ptr[2]);
return 1;
case ES_Angles:
es->angles.x = amx_ctof(ptr[0]);
es->angles.y = amx_ctof(ptr[1]);
es->angles.z = amx_ctof(ptr[2]);
return 1;
case ES_ModelIndex:
es->modelindex = *ptr;
return 1;
case ES_Sequence:
es->sequence = *ptr;
return 1;
case ES_Frame:
es->frame = amx_ctof(*ptr);
return 1;
case ES_ColorMap:
es->colormap = *ptr;
return 1;
case ES_Skin:
es->skin = *ptr;
return 1;
case ES_Solid:
es->solid = *ptr;
return 1;
case ES_Effects:
es->effects = *ptr;
return 1;
case ES_Scale:
es->scale = amx_ctof(*ptr);
return 1;
case ES_eFlags:
es->eflags = *ptr;
return 1;
case ES_RenderMode:
es->rendermode = *ptr;
return 1;
case ES_RenderAmt:
es->renderamt = *ptr;
return 1;
case ES_RenderColor:
es->rendercolor.r = ptr[0];
es->rendercolor.g = ptr[1];
es->rendercolor.b = ptr[2];
return 1;
case ES_RenderFx:
es->renderfx = *ptr;
return 1;
case ES_MoveType:
es->movetype = *ptr;
return 1;
case ES_AnimTime:
es->animtime = amx_ctof(*ptr);
return 1;
case ES_FrameRate:
es->framerate = amx_ctof(*ptr);
return 1;
case ES_Controller:
es->controller[0] = ptr[0];
es->controller[1] = ptr[1];
es->controller[2] = ptr[2];
es->controller[3] = ptr[3];
return 1;
case ES_Blending:
es->blending[0] = ptr[0];
es->blending[1] = ptr[1];
es->blending[2] = ptr[2];
es->blending[3] = ptr[3];
return 1;
case ES_Velocity:
es->velocity.x = amx_ctof(ptr[0]);
es->velocity.y = amx_ctof(ptr[1]);
es->velocity.z = amx_ctof(ptr[2]);
return 1;
case ES_Mins:
es->mins.x = amx_ctof(ptr[0]);
es->mins.y = amx_ctof(ptr[1]);
es->mins.z = amx_ctof(ptr[2]);
return 1;
case ES_Maxs:
es->maxs.x = amx_ctof(ptr[0]);
es->maxs.y = amx_ctof(ptr[1]);
es->maxs.z = amx_ctof(ptr[2]);
return 1;
case ES_AimEnt:
es->aiment = *ptr;
return 1;
case ES_Owner:
es->owner = *ptr;
return 1;
case ES_Friction:
es->friction = amx_ctof(*ptr);
return 1;
case ES_Gravity:
es->gravity = amx_ctof(*ptr);
return 1;
case ES_Team:
es->team = *ptr;
return 1;
case ES_PlayerClass:
es->playerclass = *ptr;
return 1;
case ES_Health:
es->health = *ptr;
return 1;
case ES_Spectator:
es->spectator = *ptr;
return 1;
case ES_WeaponModel:
es->weaponmodel = *ptr;
return 1;
case ES_GaitSequence:
es->gaitsequence = *ptr;
return 1;
case ES_BaseVelocity:
es->basevelocity.x = amx_ctof(ptr[0]);
es->basevelocity.y = amx_ctof(ptr[1]);
es->basevelocity.z = amx_ctof(ptr[2]);
return 1;
case ES_UseHull:
es->usehull = *ptr;
return 1;
case ES_OldButtons:
es->oldbuttons = *ptr;
return 1;
case ES_OnGround:
es->onground = *ptr;
return 1;
case ES_iStepLeft:
es->iStepLeft = *ptr;
return 1;
case ES_flFallVelocity:
es->flFallVelocity = amx_ctof(*ptr);
return 1;
case ES_FOV:
es->fov = amx_ctof(*ptr);
return 1;
case ES_WeaponAnim:
es->weaponanim = *ptr;
return 1;
case ES_StartPos:
es->startpos.x = amx_ctof(ptr[0]);
es->startpos.y = amx_ctof(ptr[1]);
es->startpos.z = amx_ctof(ptr[2]);
return 1;
case ES_EndPos:
es->endpos.x = amx_ctof(ptr[0]);
es->endpos.y = amx_ctof(ptr[1]);
es->endpos.z = amx_ctof(ptr[2]);
return 1;
case ES_ImpactTime:
es->impacttime= amx_ctof(*ptr);
return 1;
case ES_StartTime:
es->starttime = amx_ctof(*ptr);
return 1;
case ES_iUser1:
es->iuser1 = *ptr;
return 1;
case ES_iUser2:
es->iuser2 = *ptr;
return 1;
case ES_iUser3:
es->iuser3 = *ptr;
return 1;
case ES_iUser4:
es->iuser4 = *ptr;
return 1;
case ES_fUser1:
es->fuser1 = amx_ctof(*ptr);
return 1;
case ES_fUser2:
es->fuser2 = amx_ctof(*ptr);
return 1;
case ES_fUser3:
es->fuser3 = amx_ctof(*ptr);
return 1;
case ES_fUser4:
es->fuser4 = amx_ctof(*ptr);
return 1;
case ES_vUser1:
es->vuser1.x = amx_ctof(ptr[0]);
es->vuser1.y = amx_ctof(ptr[1]);
es->vuser1.z = amx_ctof(ptr[2]);
return 1;
case ES_vUser2:
es->vuser2.x = amx_ctof(ptr[0]);
es->vuser2.y = amx_ctof(ptr[1]);
es->vuser2.z = amx_ctof(ptr[2]);
return 1;
case ES_vUser3:
es->vuser3.x = amx_ctof(ptr[0]);
es->vuser3.y = amx_ctof(ptr[1]);
es->vuser3.z = amx_ctof(ptr[2]);
return 1;
case ES_vUser4:
es->vuser3.x = amx_ctof(ptr[0]);
es->vuser3.y = amx_ctof(ptr[1]);
es->vuser3.z = amx_ctof(ptr[2]);
return 1;
}
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid EntityState member: %d", params[2]);
return 0;
}
static cell AMX_NATIVE_CALL get_uc(AMX *amx, cell *params)
{
usercmd_t *uc;
if (params[1] == 0)
uc = &g_uc_glb;
else
uc = reinterpret_cast<usercmd_t *>(params[1]);
cell *ptr;
switch(params[2])
{
case UC_LerpMsec:
return uc->lerp_msec;
case UC_Msec:
return uc->msec;
case UC_ViewAngles:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(uc->viewangles.x);
ptr[1] = amx_ftoc(uc->viewangles.y);
ptr[2] = amx_ftoc(uc->viewangles.z);
return 1;
case UC_ForwardMove:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(uc->forwardmove);
return 1;
case UC_SideMove:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(uc->sidemove);
return 1;
case UC_UpMove:
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(uc->upmove);
return 1;
case UC_LightLevel:
return uc->lightlevel;
case UC_Buttons:
return uc->buttons;
case UC_Impulse:
return uc->impulse;
case UC_WeaponSelect:
return uc->weaponselect;
case UC_ImpactIndex:
return uc->impact_index;
case UC_ImpactPosition:
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(uc->impact_position.x);
ptr[1] = amx_ftoc(uc->impact_position.y);
ptr[2] = amx_ftoc(uc->impact_position.z);
return 1;
}
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid UserCmd member: %d", params[2]);
return 0;
}
static cell AMX_NATIVE_CALL set_uc(AMX *amx, cell *params)
{
if (*params / sizeof(cell) < 3)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No data passed");
return 0;
}
usercmd_t *uc;
if (params[1] == 0)
uc = &g_uc_glb;
else
uc = reinterpret_cast<usercmd_t *>(params[1]);
cell *ptr = MF_GetAmxAddr(amx, params[3]);
switch(params[2])
{
case UC_LerpMsec:
uc->lerp_msec = *ptr;
return 1;
case UC_Msec:
uc->msec = *ptr;
return 1;
case UC_ViewAngles:
uc->viewangles.x = amx_ctof(ptr[0]);
uc->viewangles.y = amx_ctof(ptr[1]);
uc->viewangles.z = amx_ctof(ptr[2]);
return 1;
case UC_ForwardMove:
uc->forwardmove = amx_ctof(*ptr);
return 1;
case UC_SideMove:
uc->sidemove = amx_ctof(*ptr);
return 1;
case UC_UpMove:
uc->upmove = amx_ctof(*ptr);
return 1;
case UC_LightLevel:
uc->lightlevel = *ptr;
return 1;
case UC_Buttons:
uc->buttons = *ptr;
return 1;
case UC_Impulse:
uc->impulse = *ptr;
return 1;
case UC_WeaponSelect:
uc->weaponselect = *ptr;
return 1;
case UC_ImpactIndex:
uc->impact_index = *ptr;
return 1;
case UC_ImpactPosition:
uc->impact_position.x = amx_ctof(ptr[0]);
uc->impact_position.y = amx_ctof(ptr[1]);
uc->impact_position.z = amx_ctof(ptr[2]);
return 1;
}
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid UserCmd member: %d", params[2]);
return 0;
}
AMX_NATIVE_INFO ext2_natives[] =
{
{"get_tr2", get_tr2},
{"set_tr2", set_tr2},
{"get_kvd", get_kvd},
{"set_kvd", set_kvd},
{"get_cd", get_cd},
{"set_cd", set_cd},
{"get_es", get_es},
{"set_es", set_es},
{"get_uc", get_uc},
{"set_uc", set_uc},
{NULL, NULL},
};

View File

@ -1,6 +1,5 @@
#include "fakemeta_amxx.h"
CVector<int> Engine[ENGFUNC_NUM+10];
CVector<int> EnginePost[ENGFUNC_NUM+10];
cell mCellResult;
@ -12,6 +11,9 @@ const char *mlStringResult;
int retType = 0;
int lastFmRes = FMRES_IGNORED;
KVD_Wrapper g_kvd_hook;
clientdata_t *g_cd_hook;
entity_state_t *g_es_hook;
usercmd_t *g_uc_hook;
cell origCellRet;
float origFloatRet;
@ -690,6 +692,51 @@ SIMPLE_VOID_HOOK_VOID(CreateInstancedBaselines);
// pfnAllowLagCompensation
SIMPLE_INT_HOOK_VOID(AllowLagCompensation);
void UpdateClientData(const struct edict_s *ent, int sendweapons, struct clientdata_s *cd)
{
g_cd_hook = cd;
FM_ENG_HANDLE(FM_UpdateClientData, (Engine[FM_UpdateClientData].at(i), (cell)ENTINDEX(ent), (cell)sendweapons, (cell)cd));
RETURN_META(mswi(lastFmRes));
}
void UpdateClientData_post(const struct edict_s *ent, int sendweapons, struct clientdata_s *cd)
{
g_cd_hook = cd;
FM_ENG_HANDLE_POST(FM_UpdateClientData, (EnginePost[FM_UpdateClientData].at(i), (cell)ENTINDEX(ent), (cell)sendweapons, (cell)cd));
RETURN_META(MRES_IGNORED);
}
int AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet)
{
g_es_hook = state;
FM_ENG_HANDLE(FM_AddToFullPack, (Engine[FM_AddToFullPack].at(i), (cell)state, (cell)e, (cell)ENTINDEX(ent), (cell)ENTINDEX(host), (cell)hostflags, (cell)player, (cell)pSet));
RETURN_META_VALUE(mswi(lastFmRes), (int)mlCellResult);
}
int AddToFullPack_post(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet)
{
g_es_hook = state;
origCellRet = META_RESULT_ORIG_RET(int);
FM_ENG_HANDLE_POST(FM_AddToFullPack, (EnginePost[FM_AddToFullPack].at(i), (cell)state, (cell)e, (cell)ENTINDEX(ent), (cell)ENTINDEX(host), (cell)hostflags, (cell)player, (cell)pSet));
RETURN_META_VALUE(MRES_IGNORED, (int)mlCellResult);
}
void CmdStart(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed)
{
g_uc_hook = const_cast<usercmd_t *>(cmd);
FM_ENG_HANDLE(FM_CmdStart, (Engine[FM_CmdStart].at(i), (cell)ENTINDEX(player), (cell)cmd, (cell)random_seed));
RETURN_META(mswi(lastFmRes));
}
void CmdStart_post(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed)
{
g_uc_hook = const_cast<usercmd_t *>(cmd);
FM_ENG_HANDLE_POST(FM_CmdStart, (EnginePost[FM_CmdStart].at(i), (cell)ENTINDEX(player), (cell)cmd, (cell)random_seed));
RETURN_META(MRES_IGNORED);
}
// pfnCmdEnd
SIMPLE_VOID_HOOK_CONSTEDICT(CmdEnd);
/*
* NEW_DLL_FUNCTIONS
@ -1116,7 +1163,7 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
break;
//EngFunc_CheckVisibility, //) ( const edict_t *entity, unsigned char *pset );
case FM_CheckVisibility:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_STRING, FP_DONE);
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_DONE);
ENGHOOK(CheckVisibility);
break;
@ -1336,6 +1383,22 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(ClientUserInfoChanged);
break;
case FM_UpdateClientData:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
DLLHOOK(UpdateClientData);
break;
case FM_AddToFullPack:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
DLLHOOK(AddToFullPack);
break;
case FM_CmdStart:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
DLLHOOK(CmdStart);
break;
case FM_CmdEnd:
fId = MF_RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
DLLHOOK(CmdEnd);
break;
#if 0
// I know this does not fit with DLLFUNC(), but I dont want another native just for it.

View File

@ -1,7 +1,7 @@
#ifndef _INCLUDE_FORWARD_H
#define _INCLUDE_FORWARD_H
#define ENGFUNC_NUM FM_LAST_DONT_USE_ME // 118
#define ENGFUNC_NUM FM_LAST_DONT_USE_ME // 127
#define FMV_STRING 1
#define FMV_FLOAT 2
@ -153,7 +153,13 @@ enum {
FM_OnFreeEntPrivateData,
FM_GameShutdown,
FM_ShouldCollide,
FM_ClientUserInfoChanged, //passes id only
FM_UpdateClientData,
FM_AddToFullPack,
FM_CmdStart,
FM_CmdEnd,
FM_LAST_DONT_USE_ME
};

View File

@ -298,6 +298,18 @@
RETURN_META(MRES_IGNORED); \
}
#define SIMPLE_VOID_HOOK_CONSTEDICT(call) \
void call (const edict_t *ent) \
{ \
FM_ENG_HANDLE(FM_##call, (Engine[FM_##call].at(i), (cell)ENTINDEX(ent))); \
RETURN_META(mswi(lastFmRes)); \
} \
void call##_post (const edict_t *ent) \
{ \
FM_ENG_HANDLE_POST(FM_##call, (EnginePost[FM_##call].at(i), (cell)ENTINDEX(ent))); \
RETURN_META(MRES_IGNORED); \
}
#define SIMPLE_VOID_HOOK_CONSTEDICT_FLOAT(call) \
void call (const edict_t *ent, float blah) \
{ \