amxmodx/modules/fakemeta/fm_tr2.cpp
Vincent Herbet f1f95425b6
Fix a crash with set_tr/2 when -1 is passed in TR_pHit + allow worldspawn (0) in set_tr/2 (#601)
* Fix a crash with set_ptr2 when -1 is passed in TR_pHit

* Allow wordspawn in set_tr|2(TR_pHit, ...)
2018-09-28 16:39:03 +02:00

1335 lines
28 KiB
C++

// 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
//
// Fakemeta Module
//
#include "fakemeta_amxx.h"
#include "sh_stack.h"
TraceResult g_tr_2;
KVD_Wrapper g_kvd_glb;
KVD_Wrapper g_kvd_ext;
ke::Vector<KVD_Wrapper *>g_KVDWs;
ke::Vector<KVD_Wrapper *>g_FreeKVDWs;
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;
if (params[1] == 0)
tr = &g_tr_2;
else
tr = reinterpret_cast<TraceResult *>(params[1]);
if (*params / sizeof(cell) < 3)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No data passed");
return 0;
}
cell *ptr = MF_GetAmxAddr(amx, params[3]);
switch (params[2])
{
case TR_AllSolid:
{
tr->fAllSolid = *ptr;
return 1;
break;
}
case TR_InOpen:
{
tr->fInOpen = *ptr;
return 1;
break;
}
case TR_StartSolid:
{
tr->fStartSolid = *ptr;
return 1;
break;
}
case TR_InWater:
{
tr->fInWater = *ptr;
return 1;
break;
}
case TR_flFraction:
{
tr->flFraction = amx_ctof(*ptr);
return 1;
break;
}
case TR_vecEndPos:
{
tr->vecEndPos.x = amx_ctof(ptr[0]);
tr->vecEndPos.y = amx_ctof(ptr[1]);
tr->vecEndPos.z = amx_ctof(ptr[2]);
return 1;
break;
}
case TR_flPlaneDist:
{
tr->flPlaneDist = amx_ctof(*ptr);
return 1;
break;
}
case TR_vecPlaneNormal:
{
tr->vecPlaneNormal.x = amx_ctof(ptr[0]);
tr->vecPlaneNormal.y = amx_ctof(ptr[1]);
tr->vecPlaneNormal.z = amx_ctof(ptr[2]);
return 1;
break;
}
case TR_pHit:
{
const auto pEdict = TypeConversion.id_to_edict(*ptr);
if (pEdict == nullptr)
{
return 0;
}
tr->pHit = pEdict;
return 1;
}
case TR_iHitgroup:
{
tr->iHitgroup = *ptr;
return 1;
break;
}
default:
{
MF_LogError(amx, AMX_ERR_NATIVE, "Unknown TraceResult member %d", params[2]);
return 0;
}
}
return 0;
}
static cell AMX_NATIVE_CALL get_tr2(AMX *amx, cell *params)
{
TraceResult *tr;
if (params[1] == 0)
tr = &g_tr_2;
else
tr = reinterpret_cast<TraceResult *>(params[1]);
cell *ptr;
switch (params[2])
{
case TR_AllSolid:
{
return tr->fAllSolid;
break;
}
case TR_InOpen:
{
return tr->fInOpen;
break;
}
case TR_StartSolid:
{
return tr->fStartSolid;
break;
}
case TR_InWater:
{
return tr->fInWater;
break;
}
case TR_flFraction:
{
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(tr->flFraction);
return 1;
break;
}
case TR_vecEndPos:
{
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(tr->vecEndPos.x);
ptr[1] = amx_ftoc(tr->vecEndPos.y);
ptr[2] = amx_ftoc(tr->vecEndPos.z);
return 1;
break;
}
case TR_flPlaneDist:
{
ptr = MF_GetAmxAddr(amx, params[3]);
*ptr = amx_ftoc(tr->flPlaneDist);
return 1;
break;
}
case TR_vecPlaneNormal:
{
ptr = MF_GetAmxAddr(amx, params[3]);
ptr[0] = amx_ftoc(tr->vecPlaneNormal.x);
ptr[1] = amx_ftoc(tr->vecPlaneNormal.y);
ptr[2] = amx_ftoc(tr->vecPlaneNormal.z);
return 1;
break;
}
case TR_pHit:
{
if (FNullEnt(tr->pHit))
return -1;
return ENTINDEX(tr->pHit);
break;
}
case TR_iHitgroup:
{
return tr->iHitgroup;
break;
}
default:
{
MF_LogError(amx, AMX_ERR_NATIVE, "Unknown TraceResult member %d", params[2]);
return 0;
}
}
return 0;
}
static cell AMX_NATIVE_CALL get_kvd(AMX *amx, cell *params)
{
KeyValueData *kvd;
if (params[1] == 0)
kvd = &(g_kvd_glb.kvd);
else
kvd = reinterpret_cast<KeyValueData *>(params[1]);
switch (params[2])
{
case KV_fHandled:
{
return kvd->fHandled;
break;
}
case KV_ClassName:
{
if (params[0] / sizeof(cell) != 4)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
cell *ptr = MF_GetAmxAddr(amx, params[4]);
return MF_SetAmxString(amx, params[3], kvd->szClassName, (int)*ptr);
break;
}
case KV_KeyName:
{
if (params[0] / sizeof(cell) != 4)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
cell *ptr = MF_GetAmxAddr(amx, params[4]);
return MF_SetAmxString(amx, params[3], kvd->szKeyName, (int)*ptr);
break;
}
case KV_Value:
{
if (params[0] / sizeof(cell) != 4)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
cell *ptr = MF_GetAmxAddr(amx, params[4]);
return MF_SetAmxString(amx, params[3], kvd->szValue, (int)*ptr);
break;
}
}
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid KeyValueData member: %d", params[2]);
return 0;
}
static cell AMX_NATIVE_CALL set_kvd(AMX *amx, cell *params)
{
KVD_Wrapper *kvdw = nullptr;
KeyValueData *kvd = nullptr;
KVD_Wrapper *tmpw = reinterpret_cast<KVD_Wrapper *>(params[1]);
if (params[1] == 0 || tmpw == &g_kvd_glb) {
kvdw = &g_kvd_glb;
kvd = &(kvdw->kvd);
} else {
for (size_t i = 0; i < g_KVDWs.length(); ++i) {
if (g_KVDWs[i] == tmpw) {
kvdw = tmpw;
kvd = &(kvdw->kvd);
}
}
if (kvdw == nullptr) {
kvdw = &g_kvd_ext;
kvd = reinterpret_cast<KeyValueData *>(tmpw);
}
}
if (*params / sizeof(cell) < 3)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No data passed");
return 0;
}
cell *ptr = MF_GetAmxAddr(amx, params[3]);
int len;
switch (params[2])
{
case KV_fHandled:
{
kvd->fHandled = (int)*ptr;
return 1;
break;
}
case KV_ClassName:
{
kvdw->cls = MF_GetAmxString(amx, params[3], 0, &len);
kvd->szClassName = const_cast<char *>(kvdw->cls.chars());
return 1;
break;
}
case KV_KeyName:
{
kvdw->key = MF_GetAmxString(amx, params[3], 0, &len);
kvd->szKeyName = const_cast<char *>(kvdw->key.chars());
return 1;
break;
}
case KV_Value:
{
kvdw->val = MF_GetAmxString(amx, params[3], 0, &len);
kvd->szValue = const_cast<char *>(kvdw->val.chars());
return 1;
break;
}
}
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid KeyValueData member: %d", params[2]);
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_Body:
return es->body;
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_Body:
es->body = *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;
}
CStack<TraceResult *> g_FreeTRs;
static cell AMX_NATIVE_CALL create_tr2(AMX *amx, cell *params)
{
TraceResult *tr;
if (g_FreeTRs.empty())
{
tr = new TraceResult;
} else {
tr = g_FreeTRs.front();
g_FreeTRs.pop();
}
memset(tr, 0, sizeof(TraceResult));
return reinterpret_cast<cell>(tr);
}
static cell AMX_NATIVE_CALL free_tr2(AMX *amx, cell *params)
{
TraceResult *tr = reinterpret_cast<TraceResult *>(params[1]);
if (!tr)
{
return 0;
}
g_FreeTRs.push(tr);
return 1;
}
static cell AMX_NATIVE_CALL create_kvd(AMX *amx, cell *params)
{
KVD_Wrapper *kvdw;
if (g_FreeKVDWs.empty()) {
kvdw = new KVD_Wrapper;
} else {
kvdw = g_FreeKVDWs.popCopy();
}
kvdw->cls = "";
kvdw->kvd.szClassName = const_cast<char*>(kvdw->cls.chars());
kvdw->key = "";
kvdw->kvd.szKeyName = const_cast<char*>(kvdw->key.chars());
kvdw->val = "";
kvdw->kvd.szValue = const_cast<char*>(kvdw->val.chars());
kvdw->kvd.fHandled = 0;
g_KVDWs.append(kvdw);
return reinterpret_cast<cell>(kvdw);
}
static cell AMX_NATIVE_CALL free_kvd(AMX *amx, cell *params) {
if (params[1] == 0) {
return 0;
}
KVD_Wrapper *kvdw = reinterpret_cast<KVD_Wrapper *>(params[1]);
for (size_t i = 0; i < g_KVDWs.length(); ++i) {
if (g_KVDWs[i] == kvdw) {
g_KVDWs.remove(i);
g_FreeKVDWs.append(kvdw);
return 1;
}
}
return 0;
}
AMX_NATIVE_INFO ext2_natives[] =
{
{"create_tr2", create_tr2},
{"free_tr2", free_tr2},
{"get_tr2", get_tr2},
{"set_tr2", set_tr2},
{"create_kvd", create_kvd},
{"free_kvd", free_kvd},
{"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},
};