amxmodx/dlls/engine/entity.cpp
David Anderson 9a3e53478e Added better error reporting
Added new SDK version
2004-08-29 17:55:11 +00:00

1808 lines
36 KiB
C++
Executable File

#include "entity.h"
int is_ent_valid(int iEnt)
{
if (iEnt < 1 || iEnt > gpGlobals->maxEntities)
return 0;
if (iEnt >= 1 && iEnt <= gpGlobals->maxClients)
if (!MF_IsPlayerIngame(iEnt))
return 0;
edict_t *pEnt = INDEXENT2(iEnt);
if (FNullEnt(pEnt))
return 0;
return 1;
}
/***********
Basic stuff
***********/
static cell AMX_NATIVE_CALL entity_range(AMX *amx, cell *params)
{
int idxa = params[1];
int idxb = params[2];
if (!is_ent_valid(idxa) || !is_ent_valid(idxb)) {
EngineError(amx, "Invalid Entity");
return 0;
}
edict_t *pEntA = INDEXENT2(idxa);
edict_t *pEntB = INDEXENT2(idxb);
REAL fRet = (pEntA->v.origin - pEntB->v.origin).Length();
return amx_ftoc(fRet);
}
/*********************
Entity control stuff
********************/
static cell AMX_NATIVE_CALL call_think(AMX *amx, cell *params)
{
int iEnt = params[1];
if (is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
MDLL_Think(pEnt);
return 1;
}
static cell AMX_NATIVE_CALL fake_touch(AMX *amx, cell *params)
{
int iPtr = params[1];
int iPtd = params[2];
if (!is_ent_valid(iPtr) || !is_ent_valid(iPtd)) {
EngineError(amx, "Invalid Entity");
return 0;
}
edict_t *pToucher = INDEXENT2(iPtr);
edict_t *pTouched = INDEXENT2(iPtd);
MDLL_Touch(pToucher, pTouched);
return 1;
}
static cell AMX_NATIVE_CALL force_use(AMX *amx, cell *params)
{
int iPtr = params[1];
int iPtd = params[2];
if (!is_ent_valid(iPtr) || !is_ent_valid(iPtd)) {
EngineError(amx, "Invalid Entity");
return 0;
}
edict_t *pUser = INDEXENT2(iPtr);
edict_t *pUsed = INDEXENT2(iPtd);
MDLL_Use(pUsed, pUser);
return 1;
}
static cell AMX_NATIVE_CALL create_entity(AMX *amx, cell *params)
{
int len;
int iszClass = AmxStringToEngine(amx, params[1], len);
edict_t *pEnt = CREATE_NAMED_ENTITY(iszClass);
if (FNullEnt(pEnt))
return 0;
return ENTINDEX(pEnt);
}
static cell AMX_NATIVE_CALL remove_entity(AMX *amx, cell *params)
{
int id = params[1];
edict_t *pEnt = INDEXENT2(id);
if (FNullEnt(pEnt))
return 0;
REMOVE_ENTITY(pEnt);
return 1;
}
static cell AMX_NATIVE_CALL entity_count(AMX *amx, cell *params)
{
return NUMBER_OF_ENTITIES();
}
static cell AMX_NATIVE_CALL is_valid_ent(AMX *amx, cell *params)
{
return is_ent_valid(params[1]);
}
//uses mahnsawce's version now
static cell AMX_NATIVE_CALL DispatchKeyValue(AMX *amx, cell *params)
{
int count = *params/sizeof(cell);
if (count == 3) {
cell *cVal = MF_GetAmxAddr(amx, params[1]);
int iValue = *cVal;
if (!is_ent_valid(iValue)) {
EngineError(amx, "Invalid Entity %d", iValue);
return 0;
}
edict_t *pEntity = INDEXENT2(iValue);
KeyValueData kvd;
int iLength=0;
char *char1 = MF_GetAmxString(amx, params[2], 0, &iLength);
char *char2 = MF_GetAmxString(amx, params[3], 1, &iLength);
kvd.szClassName = (char*)STRING(pEntity->v.classname);
kvd.szKeyName = char1;
kvd.szValue = char2;
kvd.fHandled = 0;
MDLL_KeyValue(pEntity, &kvd);
}
else
{
int iLength;
char *char1 = MF_GetAmxString(amx, params[1], 0, &iLength);
char *char2 = MF_GetAmxString(amx, params[2], 1, &iLength);
char *charA = new char[strlen(char1)+1];
char *charB = new char[strlen(char2)+1];
strcpy(charA, char1);
strcpy(charB, char2);
g_pkvd->szKeyName = charA;
g_pkvd->szValue = charB;
}
return 1;
}
static cell AMX_NATIVE_CALL get_keyvalue(AMX *amx, cell *params)
{
int idx = params[1];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEntity = INDEXENT2(idx);
char *test = INFO_KEY_BUFFER(pEntity);
int iLength=0;
char *char1 = MF_GetAmxString(amx, params[2], 1, &iLength);
return MF_SetAmxString(amx, params[3], INFO_KEY_VALUE(INFO_KEY_BUFFER(pEntity),char1), params[4]);
}
static cell AMX_NATIVE_CALL copy_keyvalue(AMX *amx, cell *params)
{
if (!g_inKeyValue)
return 0;
if (g_pkvd->szClassName)
MF_SetAmxString(amx, params[1], g_pkvd->szClassName, params[2]);
if (g_pkvd->szKeyName)
MF_SetAmxString(amx, params[3], g_pkvd->szKeyName, params[4]);
if (g_pkvd->szValue)
MF_SetAmxString(amx, params[5], g_pkvd->szValue, params[6]);
return 1;
}
static cell AMX_NATIVE_CALL DispatchSpawn(AMX *amx, cell *params)
{
int iEnt = params[1];
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
MDLL_Spawn(pEnt);
return 1;
}
/***************************
Entity modification stuff
***************************/
static cell AMX_NATIVE_CALL entity_get_float(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
REAL fVal = 0;
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case impacttime:
fVal = pEnt->v.impacttime;
break;
case starttime:
fVal = pEnt->v.starttime;
break;
case idealpitch:
fVal = pEnt->v.idealpitch;
break;
case pitch_speed:
fVal = pEnt->v.pitch_speed;
break;
case ideal_yaw:
fVal = pEnt->v.ideal_yaw;
break;
case yaw_speed:
fVal = pEnt->v.yaw_speed;
break;
case ltime:
fVal = pEnt->v.ltime;
break;
case nextthink:
fVal = pEnt->v.nextthink;
break;
case gravity:
fVal = pEnt->v.gravity;
break;
case friction:
fVal = pEnt->v.friction;
break;
case frame:
fVal = pEnt->v.frame;
break;
case animtime:
fVal = pEnt->v.animtime;
break;
case framerate:
fVal = pEnt->v.framerate;
break;
case health:
fVal = pEnt->v.health;
break;
case frags:
fVal = pEnt->v.frags;
break;
case takedamage:
fVal = pEnt->v.takedamage;
break;
case max_health:
fVal = pEnt->v.max_health;
break;
case teleport_time:
fVal = pEnt->v.teleport_time;
break;
case armortype:
fVal = pEnt->v.armortype;
break;
case armorvalue:
fVal = pEnt->v.armorvalue;
break;
case dmg_take:
fVal = pEnt->v.dmg_take;
break;
case dmg_save:
fVal = pEnt->v.dmg_save;
break;
case dmg:
fVal = pEnt->v.dmg;
break;
case dmgtime:
fVal = pEnt->v.dmgtime;
break;
case speed:
fVal = pEnt->v.speed;
break;
case air_finished:
fVal = pEnt->v.air_finished;
break;
case pain_finished:
fVal = pEnt->v.pain_finished;
break;
case radsuit_finished:
fVal = pEnt->v.radsuit_finished;
break;
case scale:
fVal = pEnt->v.scale;
break;
case renderamt:
fVal = pEnt->v.renderamt;
break;
case maxspeed:
fVal = pEnt->v.maxspeed;
break;
case fov:
fVal = pEnt->v.fov;
break;
case flFallVelocity:
fVal = pEnt->v.flFallVelocity;
break;
case fuser1:
fVal = pEnt->v.fuser1;
break;
case fuser2:
fVal = pEnt->v.fuser2;
break;
case fuser3:
fVal = pEnt->v.fuser3;
break;
case fuser4:
fVal = pEnt->v.fuser4;
break;
default:
return 0;
break;
}
return amx_ftoc(fVal);
}
static cell AMX_NATIVE_CALL entity_set_float(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
REAL fVal = amx_ctof(params[3]);
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case impacttime:
pEnt->v.impacttime = fVal;
break;
case starttime:
pEnt->v.starttime = fVal;
break;
case idealpitch:
pEnt->v.idealpitch = fVal;
break;
case pitch_speed:
pEnt->v.pitch_speed = fVal;
break;
case ideal_yaw:
pEnt->v.ideal_yaw = fVal;
break;
case yaw_speed:
pEnt->v.yaw_speed = fVal;
break;
case ltime:
pEnt->v.ltime = fVal;
break;
case nextthink:
pEnt->v.nextthink = fVal;
break;
case gravity:
pEnt->v.gravity = fVal;
break;
case friction:
pEnt->v.friction = fVal;
break;
case frame:
pEnt->v.frame = fVal;
break;
case animtime:
pEnt->v.animtime = fVal;
break;
case framerate:
pEnt->v.framerate = fVal;
break;
case health:
pEnt->v.health = fVal;
break;
case frags:
pEnt->v.frags = fVal;
break;
case takedamage:
pEnt->v.takedamage = fVal;
break;
case max_health:
pEnt->v.max_health = fVal;
break;
case teleport_time:
pEnt->v.teleport_time = fVal;
break;
case armortype:
pEnt->v.armortype = fVal;
break;
case armorvalue:
pEnt->v.armorvalue = fVal;
break;
case dmg_take:
pEnt->v.dmg_take = fVal;
break;
case dmg_save:
pEnt->v.dmg_save = fVal;
break;
case dmg:
pEnt->v.dmg = fVal;
break;
case dmgtime:
pEnt->v.dmgtime = fVal;
break;
case speed:
pEnt->v.speed = fVal;
break;
case air_finished:
pEnt->v.air_finished = fVal;
break;
case pain_finished:
pEnt->v.pain_finished = fVal;
break;
case radsuit_finished:
pEnt->v.radsuit_finished = fVal;
break;
case scale:
pEnt->v.scale = fVal;
break;
case renderamt:
pEnt->v.renderamt = fVal;
break;
case maxspeed:
pEnt->v.maxspeed = fVal;
break;
case fov:
pEnt->v.fov = fVal;
break;
case flFallVelocity:
pEnt->v.flFallVelocity = fVal;
break;
case fuser1:
pEnt->v.fuser1 = fVal;
break;
case fuser2:
pEnt->v.fuser2 = fVal;
break;
case fuser3:
pEnt->v.fuser3 = fVal;
break;
case fuser4:
pEnt->v.fuser4 = fVal;
break;
default:
return 0;
break;
}
return 1;
}
static cell AMX_NATIVE_CALL entity_get_int(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
int iRetValue = 0;
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case gamestate:
iRetValue = pEnt->v.gamestate;
break;
case oldbuttons:
iRetValue = pEnt->v.oldbuttons;
break;
case groupinfo:
iRetValue = pEnt->v.groupinfo;
break;
case iuser1:
iRetValue = pEnt->v.iuser1;
break;
case iuser2:
iRetValue = pEnt->v.iuser2;
break;
case iuser3:
iRetValue = pEnt->v.iuser3;
break;
case iuser4:
iRetValue = pEnt->v.iuser4;
break;
case weaponanim:
iRetValue = pEnt->v.weaponanim;
break;
case pushmsec:
iRetValue = pEnt->v.pushmsec;
break;
case bInDuck:
iRetValue = pEnt->v.bInDuck;
break;
case flTimeStepSound:
iRetValue = pEnt->v.flTimeStepSound;
break;
case flSwimTime:
iRetValue = pEnt->v.flSwimTime;
break;
case flDuckTime:
iRetValue = pEnt->v.flDuckTime;
break;
case iStepLeft:
iRetValue = pEnt->v.iStepLeft;
break;
case movetype:
iRetValue = pEnt->v.movetype;
break;
case solid:
iRetValue = pEnt->v.solid;
break;
case skin:
iRetValue = pEnt->v.skin;
break;
case body:
iRetValue = pEnt->v.body;
break;
case effects:
iRetValue = pEnt->v.effects;
break;
case light_level:
iRetValue = pEnt->v.light_level;
break;
case sequence:
iRetValue = pEnt->v.sequence;
break;
case gaitsequence:
iRetValue = pEnt->v.gaitsequence;
break;
case modelindex:
iRetValue = pEnt->v.modelindex;
break;
case playerclass:
iRetValue = pEnt->v.playerclass;
break;
case waterlevel:
iRetValue = pEnt->v.waterlevel;
break;
case watertype:
iRetValue = pEnt->v.watertype;
break;
case spawnflags:
iRetValue = pEnt->v.spawnflags;
break;
case flags:
iRetValue = pEnt->v.flags;
break;
case colormap:
iRetValue = pEnt->v.colormap;
break;
case team:
iRetValue = pEnt->v.team;
break;
case fixangle:
iRetValue = pEnt->v.fixangle;
break;
case weapons:
iRetValue = pEnt->v.weapons;
break;
case rendermode:
iRetValue = pEnt->v.rendermode;
break;
case renderfx:
iRetValue = pEnt->v.renderfx;
break;
case button:
iRetValue = pEnt->v.button;
break;
case impulse:
iRetValue = pEnt->v.impulse;
break;
case deadflag:
iRetValue = pEnt->v.deadflag;
break;
default:
EngineError(amx, "Invalid property %d", iEnt);
return 0;
break;
}
return iRetValue;
}
static cell AMX_NATIVE_CALL entity_set_int(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
int iNewValue = params[3];
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case gamestate:
pEnt->v.gamestate = iNewValue;
break;
case oldbuttons:
pEnt->v.oldbuttons = iNewValue;
break;
case groupinfo:
pEnt->v.groupinfo = iNewValue;
break;
case iuser1:
pEnt->v.iuser1 = iNewValue;
break;
case iuser2:
pEnt->v.iuser2 = iNewValue;
break;
case iuser3:
pEnt->v.iuser3 = iNewValue;
break;
case iuser4:
pEnt->v.iuser4 = iNewValue;
break;
case weaponanim:
pEnt->v.weaponanim = iNewValue;
break;
case pushmsec:
pEnt->v.pushmsec = iNewValue;
break;
case bInDuck:
pEnt->v.bInDuck = iNewValue;
break;
case flTimeStepSound:
pEnt->v.flTimeStepSound = iNewValue;
break;
case flSwimTime:
pEnt->v.flSwimTime = iNewValue;
break;
case flDuckTime:
pEnt->v.flDuckTime = iNewValue;
break;
case iStepLeft:
pEnt->v.iStepLeft = iNewValue;
break;
case movetype:
pEnt->v.movetype = iNewValue;
break;
case solid:
pEnt->v.solid = iNewValue;
break;
case skin:
pEnt->v.skin = iNewValue;
break;
case body:
pEnt->v.body = iNewValue;
break;
case effects:
pEnt->v.effects = iNewValue;
break;
case light_level:
pEnt->v.light_level = iNewValue;
break;
case sequence:
pEnt->v.sequence = iNewValue;
break;
case gaitsequence:
pEnt->v.gaitsequence = iNewValue;
break;
case modelindex:
pEnt->v.modelindex = iNewValue;
break;
case playerclass:
pEnt->v.playerclass = iNewValue;
break;
case waterlevel:
pEnt->v.waterlevel = iNewValue;
break;
case watertype:
pEnt->v.watertype = iNewValue;
break;
case spawnflags:
pEnt->v.spawnflags = iNewValue;
break;
case flags:
pEnt->v.flags = iNewValue;
break;
case colormap:
pEnt->v.colormap = iNewValue;
break;
case team:
pEnt->v.team = iNewValue;
break;
case fixangle:
pEnt->v.fixangle = iNewValue;
break;
case weapons:
pEnt->v.weapons = iNewValue;
break;
case rendermode:
pEnt->v.rendermode = iNewValue;
break;
case renderfx:
pEnt->v.renderfx = iNewValue;
break;
case button:
pEnt->v.button = iNewValue;
break;
case impulse:
pEnt->v.impulse = iNewValue;
break;
case deadflag:
pEnt->v.deadflag = iNewValue;
break;
default:
return 0;
break;
}
return 1;
}
static cell AMX_NATIVE_CALL entity_get_vector(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
cell *vRet = MF_GetAmxAddr(amx, params[3]);
Vector vRetValue = Vector(0, 0, 0);
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case origin:
vRetValue = pEnt->v.origin;
break;
case oldorigin:
vRetValue = pEnt->v.oldorigin;
break;
case velocity:
vRetValue = pEnt->v.velocity;
break;
case basevelocity:
vRetValue = pEnt->v.basevelocity;
break;
case clbasevelocity:
vRetValue = pEnt->v.clbasevelocity;
break;
case movedir:
vRetValue = pEnt->v.movedir;
break;
case angles:
vRetValue = pEnt->v.angles;
break;
case avelocity:
vRetValue = pEnt->v.avelocity;
break;
case punchangle:
vRetValue = pEnt->v.punchangle;
break;
case v_angle:
vRetValue = pEnt->v.v_angle;
break;
case endpos:
vRetValue = pEnt->v.endpos;
break;
case startpos:
vRetValue = pEnt->v.startpos;
break;
case absmin:
vRetValue = pEnt->v.absmin;
break;
case absmax:
vRetValue = pEnt->v.absmax;
break;
case mins:
vRetValue = pEnt->v.mins;
break;
case maxs:
vRetValue = pEnt->v.maxs;
break;
case size:
vRetValue = pEnt->v.size;
break;
case rendercolor:
vRetValue = pEnt->v.rendercolor;
break;
case view_ofs:
vRetValue = pEnt->v.view_ofs;
break;
case vuser1:
vRetValue = pEnt->v.vuser1;
break;
case vuser2:
vRetValue = pEnt->v.vuser2;
break;
case vuser3:
vRetValue = pEnt->v.vuser3;
break;
case vuser4:
vRetValue = pEnt->v.vuser4;
break;
default:
return 0;
break;
}
vRet[0] = amx_ftoc(vRetValue.x);
vRet[1] = amx_ftoc(vRetValue.y);
vRet[2] = amx_ftoc(vRetValue.z);
return 1;
}
static cell AMX_NATIVE_CALL entity_set_vector(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
cell *vAmx = MF_GetAmxAddr(amx, params[3]);
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
REAL fX = amx_ctof(vAmx[0]);
REAL fY = amx_ctof(vAmx[1]);
REAL fZ = amx_ctof(vAmx[2]);
Vector vSet = Vector(fX, fY, fZ);
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case origin:
pEnt->v.origin = vSet;
break;
case oldorigin:
pEnt->v.oldorigin = vSet;
break;
case velocity:
pEnt->v.velocity = vSet;
break;
case basevelocity:
pEnt->v.basevelocity = vSet;
break;
case clbasevelocity:
pEnt->v.clbasevelocity = vSet;
break;
case movedir:
pEnt->v.movedir = vSet;
break;
case angles:
pEnt->v.angles = vSet;
break;
case avelocity:
pEnt->v.avelocity = vSet;
break;
case punchangle:
pEnt->v.punchangle = vSet;
break;
case v_angle:
pEnt->v.v_angle = vSet;
break;
case endpos:
pEnt->v.endpos = vSet;
break;
case startpos:
pEnt->v.startpos = vSet;
break;
case absmin:
pEnt->v.absmin = vSet;
break;
case absmax:
pEnt->v.absmax = vSet;
break;
case mins:
pEnt->v.mins = vSet;
break;
case maxs:
pEnt->v.maxs = vSet;
break;
case size:
pEnt->v.size = vSet;
break;
case rendercolor:
pEnt->v.rendercolor = vSet;
break;
case view_ofs:
pEnt->v.view_ofs = vSet;
break;
case vuser1:
pEnt->v.vuser1 = vSet;
break;
case vuser2:
pEnt->v.vuser2 = vSet;
break;
case vuser3:
pEnt->v.vuser3 = vSet;
break;
case vuser4:
pEnt->v.vuser4 = vSet;
break;
default:
return 0;
break;
}
return 1;
}
static cell AMX_NATIVE_CALL entity_get_string(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
int iszString = 0;
const char *szRet = NULL;
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case classname:
iszString = pEnt->v.classname;
break;
case globalname:
iszString = pEnt->v.globalname;
break;
case model:
iszString = pEnt->v.model;
break;
case target:
iszString = pEnt->v.target;
break;
case targetname:
iszString = pEnt->v.targetname;
break;
case netname:
iszString = pEnt->v.netname;
break;
case message:
iszString = pEnt->v.message;
break;
case noise:
iszString = pEnt->v.noise;
break;
case noise1:
iszString = pEnt->v.noise1;
break;
case noise2:
iszString = pEnt->v.noise2;
break;
case noise3:
iszString = pEnt->v.noise3;
break;
case viewmodel:
iszString = pEnt->v.viewmodel;
break;
case weaponmodel:
iszString = pEnt->v.weaponmodel;
break;
default:
return 0;
break;
}
szRet = STRING(iszString);
return MF_SetAmxString(amx, params[3], szRet, params[4]);
}
static cell AMX_NATIVE_CALL entity_set_string(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
int iLen;
int iszString = AmxStringToEngine(amx, params[3], iLen);
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case classname:
pEnt->v.classname = iszString;
break;
case globalname:
pEnt->v.globalname = iszString;
break;
case model:
pEnt->v.model = iszString;
break;
case target:
pEnt->v.target = iszString;
break;
case targetname:
pEnt->v.targetname = iszString;
break;
case netname:
pEnt->v.netname = iszString;
break;
case message:
pEnt->v.message = iszString;
break;
case noise:
pEnt->v.noise = iszString;
break;
case noise1:
pEnt->v.noise1 = iszString;
break;
case noise2:
pEnt->v.noise2 = iszString;
break;
case noise3:
pEnt->v.noise3 = iszString;
break;
case viewmodel:
pEnt->v.viewmodel = iszString;
break;
case weaponmodel:
pEnt->v.weaponmodel = iszString;
break;
default:
return 0;
break;
}
return 1;
}
static cell AMX_NATIVE_CALL entity_get_edict(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
edict_t *pRet;
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case chain:
pRet = pEnt->v.chain;
break;
case dmg_inflictor:
pRet = pEnt->v.dmg_inflictor;
break;
case enemy:
pRet = pEnt->v.enemy;
break;
case aiment:
pRet = pEnt->v.aiment;
break;
case owner:
pRet = pEnt->v.owner;
break;
case groundentity:
pRet = pEnt->v.groundentity;
break;
case pContainingEntity:
pRet = pEnt->v.pContainingEntity;
break;
case euser1:
pRet = pEnt->v.euser1;
break;
case euser2:
pRet = pEnt->v.euser2;
break;
case euser3:
pRet = pEnt->v.euser3;
break;
case euser4:
pRet = pEnt->v.euser4;
break;
default:
return 0;
break;
}
if (FNullEnt(pRet))
return 0;
return ENTINDEX(pRet);
}
static cell AMX_NATIVE_CALL entity_set_edict(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
int iSetEnt = params[3];
if (!is_ent_valid(iEnt) || !is_ent_valid(iSetEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
edict_t *pSetEnt = INDEXENT2(iSetEnt);
switch (idx)
{
case chain:
pEnt->v.chain = pSetEnt;
break;
case dmg_inflictor:
pEnt->v.dmg_inflictor = pSetEnt;
break;
case enemy:
pEnt->v.enemy = pSetEnt;
break;
case aiment:
pEnt->v.aiment = pSetEnt;
break;
case owner:
pEnt->v.owner = pSetEnt;
break;
case groundentity:
pEnt->v.groundentity = pSetEnt;
break;
case pContainingEntity:
pEnt->v.pContainingEntity = pSetEnt;
break;
case euser1:
pEnt->v.euser1 = pSetEnt;
break;
case euser2:
pEnt->v.euser2 = pSetEnt;
break;
case euser3:
pEnt->v.euser3 = pSetEnt;
break;
case euser4:
pEnt->v.euser4 = pSetEnt;
break;
default:
return 0;
break;
}
return 1;
}
static cell AMX_NATIVE_CALL entity_get_byte(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
int iRetValue = 0;
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case controller1:
iRetValue = pEnt->v.controller[0];
break;
case controller2:
iRetValue = pEnt->v.controller[1];
break;
case controller3:
iRetValue = pEnt->v.controller[2];
break;
case controller4:
iRetValue = pEnt->v.controller[3];
break;
case blending1:
iRetValue = pEnt->v.blending[0];
break;
case blending2:
iRetValue = pEnt->v.blending[1];
break;
default:
return 0;
break;
}
return iRetValue;
}
static cell AMX_NATIVE_CALL entity_set_byte(AMX *amx, cell *params)
{
int iEnt = params[1];
int idx = params[2];
int iNewValue = params[3];
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
if(iNewValue > 255)
iNewValue = 255;
if(iNewValue < 0)
iNewValue = 0;
edict_t *pEnt = INDEXENT2(iEnt);
switch (idx)
{
case controller1:
pEnt->v.controller[1] = iNewValue;
break;
case controller2:
pEnt->v.controller[2] = iNewValue;
break;
case controller3:
pEnt->v.controller[3] = iNewValue;
break;
case controller4:
pEnt->v.controller[4] = iNewValue;
break;
case blending1:
pEnt->v.blending[1] = iNewValue;
break;
case blending2:
pEnt->v.blending[2] = iNewValue;
break;
default:
return 0;
break;
}
return 1;
}
static cell AMX_NATIVE_CALL entity_set_origin(AMX *amx, cell *params)
{
int iEnt = params[1];
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
cell *vVector = MF_GetAmxAddr(amx, params[2]);
REAL fX = amx_ctof(vVector[0]);
REAL fY = amx_ctof(vVector[1]);
REAL fZ = amx_ctof(vVector[2]);
Vector vOrigin = Vector(fX, fY, fZ);
SET_SIZE(pEnt, pEnt->v.mins, pEnt->v.maxs);
SET_ORIGIN(pEnt, vOrigin);
return 1;
}
static cell AMX_NATIVE_CALL entity_set_model(AMX *amx, cell *params)
{
int iEnt = params[1];
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
int iLen;
char *szModel = MF_GetAmxString(amx, params[2], 0, &iLen);
char *szStatic = new char[iLen+1];
memset(szStatic, 0, iLen+1);
strcpy(szStatic, szModel);
SET_MODEL(pEnt, szStatic);
return 1;
}
static cell AMX_NATIVE_CALL entity_set_size(AMX *amx, cell *params)
{
int iEnt = params[1];
if (!is_ent_valid(iEnt)) {
EngineError(amx, "Invalid Entity %d", iEnt);
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
cell *cMin = MF_GetAmxAddr(amx, params[2]);
REAL x1 = amx_ctof(cMin[0]);
REAL y1 = amx_ctof(cMin[1]);
REAL z1 = amx_ctof(cMin[2]);
Vector vMin = Vector(x1, y1, z1);
cell *cMax = MF_GetAmxAddr(amx, params[3]);
REAL x2 = amx_ctof(cMax[0]);
REAL y2 = amx_ctof(cMax[1]);
REAL z2 = amx_ctof(cMax[2]);
Vector vMax = Vector(x2, y2, z2);
UTIL_SetSize(pEnt, vMin, vMax);
return 1;
}
/***********************
Offset control natives
***********************/
static cell AMX_NATIVE_CALL get_offset_short(AMX *amx, cell *params)
{
int idx = params[1];
int off = params[2];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEnt = INDEXENT2(idx);
#ifdef __linux__
off += params[3];
#endif
return *((short *)pEnt->pvPrivateData + off);
}
static cell AMX_NATIVE_CALL set_offset_short(AMX *amx, cell *params)
{
int idx = params[1];
int off = params[2];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEnt = INDEXENT2(idx);
#ifdef __linux__
off += params[3];
#endif
*((short *)pEnt->pvPrivateData + off) = (short)params[3];
return 1;
}
static cell AMX_NATIVE_CALL get_offset_char(AMX *amx, cell *params)
{
int idx = params[1];
int off = params[2];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEnt = INDEXENT2(idx);
#ifdef __linux__
off += params[3];
#endif
char r = *((char *)pEnt->pvPrivateData + off);
return r;
}
static cell AMX_NATIVE_CALL set_offset_char(AMX *amx, cell *params)
{
int idx = params[1];
int off = params[2];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEnt = INDEXENT2(idx);
#ifdef __linux__
off += params[3];
#endif
char data = params[3];
*((char *)pEnt->pvPrivateData + off) = data;
return 1;
}
static cell AMX_NATIVE_CALL get_offset_int(AMX *amx, cell *params)
{
int idx = params[1];
int off = params[2];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEnt = INDEXENT2(idx);
#ifdef __linux__
off += params[3];
#endif
return *((int *)pEnt->pvPrivateData + off);
}
static cell AMX_NATIVE_CALL set_offset_int(AMX *amx, cell *params)
{
int idx = params[1];
int off = params[2];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEnt = INDEXENT2(idx);
#ifdef __linux__
off += params[3];
#endif
*((int *)pEnt->pvPrivateData + off) = params[3];
return 1;
}
static cell AMX_NATIVE_CALL get_offset_float(AMX *amx, cell *params)
{
int idx = params[1];
int off = params[2];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEnt = INDEXENT2(idx);
#ifdef __linux__
off += params[3];
#endif
REAL fRet = (REAL)(*((REAL*)pEnt->pvPrivateData + off));
return amx_ftoc(fRet);
}
static cell AMX_NATIVE_CALL set_offset_float(AMX *amx, cell *params)
{
int idx = params[1];
int off = params[2];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEnt = INDEXENT2(idx);
#ifdef __linux__
off += params[3];
#endif
REAL fVal = amx_ctof(params[3]);
*((float *)pEnt->pvPrivateData + off) = fVal;
return 1;
}
static cell AMX_NATIVE_CALL get_entity_pointer(AMX *amx, cell *params) // get_entity_pointer(index, pointer[], len); = 3 params
{
return 0;
}
/************************
Entity finding functions
************************/
static cell AMX_NATIVE_CALL find_ent_in_sphere(AMX *amx, cell *params)
{
int idx = params[1];
if (!is_ent_valid(idx)) {
EngineError(amx, "Invalid Entity %d", idx);
return 0;
}
edict_t *pEnt = INDEXENT2(idx);
cell *cAddr = MF_GetAmxAddr(amx, params[2]);
REAL origin[3] = {
amx_ctof(cAddr[0]),
amx_ctof(cAddr[1]),
amx_ctof(cAddr[2])
};
REAL radius = amx_ctof(params[3]);
int returnEnt = ENTINDEX(FIND_ENTITY_IN_SPHERE(pEnt, origin, radius));
if (FNullEnt(returnEnt))
return 0;
return returnEnt;
}
static cell AMX_NATIVE_CALL find_ent_by_class(AMX *amx, cell *params) /* 3 param */
{
edict_t *pEnt = INDEXENT2(params[1]);
int len;
char* sValue = MF_GetAmxString(amx, params[2], 0, &len);
pEnt = FIND_ENTITY_BY_STRING(pEnt, "classname", sValue);
if (FNullEnt(pEnt))
return 0;
return ENTINDEX(pEnt);
}
static cell AMX_NATIVE_CALL find_sphere_class(AMX *amx, cell *params) // find_sphere_class(aroundent, _lookforclassname[], Float:radius, entlist[], maxents, Float:origin[3] = {0.0, 0.0, 0.0}); // 6 params
{
// params[1] = index to find around, if this is less than 1 then use around origin in last parameter.
// params[2] = classname to find
int len;
char* classToFind = MF_GetAmxString(amx, params[2], 0, &len);
// params[3] = radius, float...
REAL radius =amx_ctof(params[3]);
// params[4] = store ents in this list
cell *entList = MF_GetAmxAddr(amx, params[4]);
// params[5] = maximum ents to store in entlist[] in params[4]
// params[6] = origin, use this if params[1] is less than 1
vec3_t vecOrigin;
if (params[1] > 0) {
if (!is_ent_valid(params[1])) {
EngineError(amx, "Invalid Entity %d", params[1]);
return 0;
}
edict_t* pEntity = INDEXENT2(params[1]);
vecOrigin = pEntity->v.origin;
} else {
cell *cAddr = MF_GetAmxAddr(amx, params[6]);
vecOrigin = Vector(amx_ctof(cAddr[0]), amx_ctof(cAddr[1]), amx_ctof(cAddr[2]));
}
int entsFound = 0;
edict_t* pSearchEnt = INDEXENT2(0);
while (entsFound < params[5]) {
pSearchEnt = FIND_ENTITY_IN_SPHERE(pSearchEnt, vecOrigin, radius); // takes const float origin
if (FNullEnt(pSearchEnt))
break;
else {
if (strcmp(STRING(pSearchEnt->v.classname), classToFind) == 0) {
// Add to entlist (params[4])
entList[entsFound++] = ENTINDEX(pSearchEnt); // raise entsFound
}
}
}
return entsFound;
}
static cell AMX_NATIVE_CALL find_ent_by_target(AMX *amx, cell *params)
{
int iStart = params[1];
int iLength;
char *szValue = MF_GetAmxString(amx, params[2], 0, &iLength);
edict_t *pStart;
if (iStart == -1) {
pStart = NULL;
} else {
if (!is_ent_valid(iStart))
pStart = NULL;
else
pStart = INDEXENT2(iStart);
}
int iReturnEnt = ENTINDEX(FIND_ENTITY_BY_TARGET(pStart, szValue));
return iReturnEnt;
}
static cell AMX_NATIVE_CALL find_ent_by_model(AMX *amx, cell *params) {
int iStart = params[1];
int iLength, iLength2;
char *szClass = MF_GetAmxString(amx, params[2], 0, &iLength);
char *szModel = MF_GetAmxString(amx, params[3], 1, &iLength2);
edict_t *pStart;
if (iStart == -1) {
pStart = NULL;
} else {
if (!is_ent_valid(iStart))
pStart = NULL;
else
pStart = INDEXENT2(iStart);
}
int checkEnt = ENTINDEX(FIND_ENTITY_BY_STRING(pStart, "classname", szClass));
const char *CheckModel = "";
while (!FNullEnt(checkEnt)) {
CheckModel = STRING(pStart->v.model);
if (strcmp(CheckModel, szModel)==0) {
return checkEnt;
} else {
pStart = INDEXENT2(checkEnt);
checkEnt = ENTINDEX(FIND_ENTITY_BY_STRING(pStart, "classname", szClass));
}
}
return checkEnt;
}
static cell AMX_NATIVE_CALL find_ent_by_tname(AMX *amx, cell *params) {
int iStart = params[1];
int iLength;
char *szValue = MF_GetAmxString(amx, params[2], 0, &iLength);
edict_t *pStart;
if (iStart == -1) {
pStart = NULL;
} else {
if (!is_ent_valid(iStart))
pStart = NULL;
else
pStart = INDEXENT2(iStart);
}
int iReturnEnt = ENTINDEX(FIND_ENTITY_BY_TARGETNAME(pStart, szValue));
return iReturnEnt;
}
static cell AMX_NATIVE_CALL find_ent_by_owner(AMX *amx, cell *params) // native find_ent_by_owner(start_from_ent, classname[], owner_index); = 3 params
{
int iEnt = params[1];
int oEnt = params[3];
// Check index to start searching at, 0 must be possible.
if (!is_ent_valid(iEnt) || !is_ent_valid(oEnt)) {
EngineError(amx, "Invalid Entity");
return 0;
}
edict_t *pEnt = INDEXENT2(iEnt);
edict_t *entOwner = INDEXENT2(oEnt);
//optional fourth parameter is for jghg2 compatibility
char* sCategory = NULL;
switch(params[4]){
case 1: sCategory = "target"; break;
case 2: sCategory = "targetname"; break;
default: sCategory = "classname";
}
// No need to check if there is a real ent where entOwner points at since we don't access it anyway.
int len;
char* classname = MF_GetAmxString(amx, params[2], 0, &len);
while (true) {
pEnt = FIND_ENTITY_BY_STRING(pEnt, sCategory, classname);
if (FNullEnt(pEnt)) // break and return 0 if bad
break;
else if (pEnt->v.owner == entOwner) // compare pointers
return ENTINDEX(pEnt);
}
// If it comes here, the while loop ended because an ent failed (FNullEnt() == true)
return 0;
}
static cell AMX_NATIVE_CALL get_grenade_id(AMX *amx, cell *params) /* 4 param */
{
int index = params[1];
char* szModel;
if (!is_ent_valid(index)) {
EngineError(amx, "Invalid Entity %d", index);
return 0;
}
edict_t* pentFind = INDEXENT2(params[4]);
edict_t* pentOwner = INDEXENT2(index);
pentFind = FIND_ENTITY_BY_CLASSNAME( pentFind, "grenade" );
while (!FNullEnt(pentFind)) {
if (pentFind->v.owner == pentOwner) {
if (params[3]>0) {
szModel = new char[params[3]];
szModel = (char*)STRING(pentFind->v.model);
MF_SetAmxString(amx, params[2], szModel, params[3]);
delete [] szModel;
return ENTINDEX(pentFind);
}
}
pentFind = FIND_ENTITY_BY_CLASSNAME( pentFind, "grenade" );
}
return 0;
}
AMX_NATIVE_INFO ent_Natives[] = {
{"create_entity", create_entity},
{"remove_entity", remove_entity},
{"entity_count", entity_count},
{"is_valid_ent", is_valid_ent},
{"entity_range", entity_range},
{"entity_get_float", entity_get_float},
{"entity_set_float", entity_set_float},
{"entity_set_int", entity_set_int},
{"entity_get_int", entity_get_int},
{"entity_get_vector", entity_get_vector},
{"entity_set_vector", entity_set_vector},
{"entity_get_string", entity_get_string},
{"entity_set_string", entity_set_string},
{"entity_get_edict", entity_get_edict},
{"entity_set_edict", entity_set_edict},
{"entity_get_byte", entity_get_byte},
{"entity_set_byte", entity_set_byte},
{"entity_set_origin", entity_set_origin},
{"entity_set_model", entity_set_model},
{"entity_set_size", entity_set_size},
{"DispatchKeyValue", DispatchKeyValue},
{"DispatchSpawn", DispatchSpawn},
{"call_think", call_think},
{"fake_touch", fake_touch},
{"force_use", force_use},
{"get_offset_short", get_offset_short},
{"set_offset_short", set_offset_short},
{"get_offset_char", get_offset_char},
{"set_offset_char", set_offset_char},
{"get_offset", get_offset_int},
{"set_offset", set_offset_int},
{"get_offset_int", get_offset_int},
{"set_offset_int", set_offset_int},
{"get_offset_float", get_offset_float},
{"set_offset_float", set_offset_float},
{"get_entity_pointer", get_entity_pointer},
{"find_ent_in_sphere", find_ent_in_sphere},
{"find_ent_by_class", find_ent_by_class},
{"find_sphere_class", find_sphere_class},
{"find_ent_by_model", find_ent_by_model},
{"find_ent_by_target", find_ent_by_target},
{"find_ent_by_tname", find_ent_by_tname},
{"find_ent_by_owner", find_ent_by_owner},
{"get_grenade_id", get_grenade_id},
{"copy_keyvalue", copy_keyvalue},
{NULL, NULL},
///////////////////
};