#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 = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEntA = INDEXENT(idxa); edict_t *pEntB = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pToucher = INDEXENT(iPtr); edict_t *pTouched = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pUser = INDEXENT(iPtr); edict_t *pUsed = INDEXENT(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 = INDEXENT(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) { int iValue = params[1]; if (!is_ent_valid(iValue)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEntity = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEntity = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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: MF_RaiseAmxError(amx, AMX_ERR_NATIVE); 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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); 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 = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(iEnt); edict_t *pSetEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } if(iNewValue > 255) iNewValue = 255; if(iNewValue < 0) iNewValue = 0; edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(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 = INDEXENT(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])) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t* pEntity = INDEXENT(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 = INDEXENT(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 = INDEXENT(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 = INDEXENT(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 = INDEXENT(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 = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t *pEnt = INDEXENT(iEnt); edict_t *entOwner = INDEXENT(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)) { MF_RaiseAmxError(amx, AMX_ERR_NATIVE); return 0; } edict_t* pentFind = INDEXENT(params[4]); edict_t* pentOwner = INDEXENT(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}, /////////////////// };