diff --git a/dlls/fakemeta/fakemeta_amxx.cpp b/dlls/fakemeta/fakemeta_amxx.cpp index ea63e73a..07b0aee6 100755 --- a/dlls/fakemeta/fakemeta_amxx.cpp +++ b/dlls/fakemeta/fakemeta_amxx.cpp @@ -4,6 +4,7 @@ edict_t *g_player_edicts[33]; // Used for INDEXENT() forward. void OnAmxxAttach() { + initialze_offsets(); MF_AddNatives(engfunc_natives); MF_AddNatives(dllfunc_natives); MF_AddNatives(pev_natives); diff --git a/dlls/fakemeta/fakemeta_amxx.h b/dlls/fakemeta/fakemeta_amxx.h index 0634c568..142cdd3d 100755 --- a/dlls/fakemeta/fakemeta_amxx.h +++ b/dlls/fakemeta/fakemeta_amxx.h @@ -14,8 +14,7 @@ extern edict_t *g_player_edicts[33]; inline edict_t* INDEXENT2( int iEdictNum ) { if (iEdictNum >= 1 && iEdictNum <= gpGlobals->maxClients) - return g_player_edicts[iEdictNum]; - + return MF_GetPlayerEdict(iEdictNum); else return (*g_engfuncs.pfnPEntityOfEntIndex)(iEdictNum); } diff --git a/dlls/fakemeta/forward.cpp b/dlls/fakemeta/forward.cpp index 9648f6d4..7f913651 100755 --- a/dlls/fakemeta/forward.cpp +++ b/dlls/fakemeta/forward.cpp @@ -564,7 +564,7 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params) dlltable = g_pFunctionTable; newdlltable = g_pNewFunctionsTable; } - + switch (func) { case FM_PrecacheModel: diff --git a/dlls/fakemeta/pev.cpp b/dlls/fakemeta/pev.cpp index 81ab91ef..da9e046b 100755 --- a/dlls/fakemeta/pev.cpp +++ b/dlls/fakemeta/pev.cpp @@ -1,604 +1,309 @@ #include "fakemeta_amxx.h" +/** Optimizations for Fakemeta. In the end we'll do this for other things too. + */ +static int g_offset_table[pev_vecarray_end] = {-1}; + +#define DO_OFFSET(offs) g_offset_table[offs] = offsetof(entvars_t, offs) +#define DO_OFFSET_R(named, real, offs) g_offset_table[named] = offsetof(entvars_t, real) + offs + +void initialze_offsets() +{ + DO_OFFSET(fixangle); + DO_OFFSET(modelindex); + DO_OFFSET(viewmodel); + DO_OFFSET(weaponmodel); + DO_OFFSET(movetype); + DO_OFFSET(solid); + DO_OFFSET(skin); + DO_OFFSET(body); + DO_OFFSET(effects); + DO_OFFSET(light_level); + DO_OFFSET(sequence); + DO_OFFSET(gaitsequence); + DO_OFFSET(rendermode); + DO_OFFSET(renderfx); + DO_OFFSET(weapons); + DO_OFFSET(deadflag); + DO_OFFSET(button); + DO_OFFSET(impulse); + DO_OFFSET(spawnflags); + DO_OFFSET(impulse); + DO_OFFSET(flags); + DO_OFFSET(colormap); + DO_OFFSET(team); + DO_OFFSET(waterlevel); + DO_OFFSET(watertype); + DO_OFFSET(playerclass); + DO_OFFSET(weaponanim); + DO_OFFSET(pushmsec); + DO_OFFSET(bInDuck); + DO_OFFSET(flTimeStepSound); + DO_OFFSET(flSwimTime); + DO_OFFSET(iStepLeft); + DO_OFFSET(gamestate); + DO_OFFSET(oldbuttons); + DO_OFFSET(groupinfo); + DO_OFFSET(iuser1); + DO_OFFSET(iuser2); + DO_OFFSET(iuser3); + DO_OFFSET(iuser4); + DO_OFFSET(impacttime); + DO_OFFSET(starttime); + DO_OFFSET(idealpitch); + DO_OFFSET(ideal_yaw); + DO_OFFSET(pitch_speed); + DO_OFFSET(yaw_speed); + DO_OFFSET(ltime); + DO_OFFSET(nextthink); + DO_OFFSET(gravity); + DO_OFFSET(friction); + DO_OFFSET(frame); + DO_OFFSET(animtime); + DO_OFFSET(framerate); + DO_OFFSET(scale); + DO_OFFSET(renderamt); + DO_OFFSET(health); + DO_OFFSET(frags); + DO_OFFSET(takedamage); + DO_OFFSET(max_health); + DO_OFFSET(teleport_time); + DO_OFFSET(armortype); + DO_OFFSET(armorvalue); + DO_OFFSET(dmg_take); + DO_OFFSET(dmg_save); + DO_OFFSET(dmg); + DO_OFFSET(dmgtime); + DO_OFFSET(speed); + DO_OFFSET(air_finished); + DO_OFFSET(pain_finished); + DO_OFFSET(radsuit_finished); + DO_OFFSET(maxspeed); + DO_OFFSET(fov); + DO_OFFSET(flFallVelocity); + DO_OFFSET(fuser1); + DO_OFFSET(fuser2); + DO_OFFSET(fuser3); + DO_OFFSET(fuser4); + DO_OFFSET(classname); + DO_OFFSET(globalname); + DO_OFFSET(model); + DO_OFFSET(target); + DO_OFFSET(targetname); + DO_OFFSET(netname); + DO_OFFSET(message); + DO_OFFSET(noise); + DO_OFFSET(noise1); + DO_OFFSET(noise2); + DO_OFFSET(noise3); + DO_OFFSET(chain); + DO_OFFSET(dmg_inflictor); + DO_OFFSET(enemy); + DO_OFFSET(aiment); + DO_OFFSET(owner); + DO_OFFSET(groundentity); + DO_OFFSET(euser1); + DO_OFFSET(euser2); + DO_OFFSET(euser3); + DO_OFFSET(euser4); + DO_OFFSET(origin); + DO_OFFSET(oldorigin); + DO_OFFSET(velocity); + DO_OFFSET(basevelocity); + DO_OFFSET(movedir); + DO_OFFSET(angles); + DO_OFFSET(avelocity); + DO_OFFSET(v_angle); + DO_OFFSET(endpos); + DO_OFFSET(startpos); + DO_OFFSET(absmin); + DO_OFFSET(absmax); + DO_OFFSET(mins); + DO_OFFSET(maxs); + DO_OFFSET(size); + DO_OFFSET(rendercolor); + DO_OFFSET(view_ofs); + DO_OFFSET(vuser1); + DO_OFFSET(vuser2); + DO_OFFSET(vuser3); + DO_OFFSET(vuser4); + DO_OFFSET(punchangle); + DO_OFFSET(controller); + DO_OFFSET_R(controller_0, controller, 0); + DO_OFFSET_R(controller_1, controller, 1); + DO_OFFSET_R(controller_2, controller, 2); + DO_OFFSET_R(controller_3, controller, 3); + DO_OFFSET(blending); + DO_OFFSET_R(blending_0, blending, 0); + DO_OFFSET_R(blending_1, blending, 1); +} + +#define EDICT_OFFS(v,o) ((char *)v + o) + // originally by mahnsawce static cell AMX_NATIVE_CALL amx_pev(AMX *amx,cell *params) { - int index=params[1]; + int index = params[1]; CHECK_ENTITY(index); - edict_t *pPlayer = INDEXENT2(index); - int returntype = *params/sizeof(cell); - int valuetype=0; - int iReturn=0; - float fReturn=0; - Vector vReturn=Vector(0,0,0); - byte bReturn[4]={0,0,0,0}; - int iSwitch = params[2]; - if (iSwitch > pev_int_start && iSwitch < pev_int_end) - valuetype=VALUETYPE_INT; - else if (iSwitch > pev_float_start && iSwitch < pev_float_end) - valuetype=VALUETYPE_FLOAT; - else if (iSwitch > pev_vecarray_start && iSwitch < pev_vecarray_end) - valuetype=VALUETYPE_VECTOR; - else if (iSwitch > pev_byte_start && iSwitch < pev_byte_end) - valuetype=VALUETYPE_BYTE; - else if (iSwitch > pev_string_start && iSwitch < pev_string_end) - valuetype=VALUETYPE_STRING; - else if (iSwitch > pev_edict_start && iSwitch < pev_edict_end) - valuetype=VALUETYPE_EDICT; - if (iSwitch > pev_int_start && iSwitch < pev_int_end) - { - valuetype=VALUETYPE_INT; - switch(iSwitch) - { - case fixangle: - iReturn = pPlayer->v.fixangle; - break; - case modelindex: - iReturn = pPlayer->v.modelindex; - break; - case viewmodel: - iReturn = pPlayer->v.viewmodel; - break; - case weaponmodel: - iReturn = pPlayer->v.weaponmodel; - break; - case movetype: - iReturn = pPlayer->v.movetype; - break; - case solid: - iReturn = pPlayer->v.solid; - break; - case skin: - iReturn = pPlayer->v.skin; - break; - case body: - iReturn = pPlayer->v.body; - break; - case effects: - iReturn = pPlayer->v.effects; - break; - case light_level: - iReturn = pPlayer->v.light_level; - break; - case sequence: - iReturn = pPlayer->v.sequence; - break; - case gaitsequence: - iReturn = pPlayer->v.gaitsequence; - break; - case rendermode: - iReturn = pPlayer->v.rendermode; - break; - case renderfx: - iReturn = pPlayer->v.renderfx; - break; - case weapons: - iReturn = pPlayer->v.weapons; - break; - case deadflag: - iReturn = pPlayer->v.deadflag; - break; - case button: - iReturn = pPlayer->v.button; - break; - case impulse: - iReturn = pPlayer->v.impulse; - break; - case spawnflags: - iReturn = pPlayer->v.spawnflags; - break; - case flags: - iReturn = pPlayer->v.flags; - break; - case colormap: - iReturn = pPlayer->v.colormap; - break; - case team: - iReturn = pPlayer->v.team; - break; - case waterlevel: - iReturn = pPlayer->v.waterlevel; - break; - case watertype: - iReturn = pPlayer->v.watertype; - break; - case playerclass: - iReturn = pPlayer->v.playerclass; - break; - case weaponanim: - iReturn = pPlayer->v.weaponanim; - break; - case pushmsec: - iReturn = pPlayer->v.pushmsec; - break; - case bInDuck: - iReturn = pPlayer->v.bInDuck; - break; - case flTimeStepSound: - iReturn = pPlayer->v.flTimeStepSound; - break; - case flSwimTime: - iReturn = pPlayer->v.flSwimTime; - break; - case flDuckTime: - iReturn = pPlayer->v.flDuckTime; - break; - case iStepLeft: - iReturn = pPlayer->v.iStepLeft; - break; - case gamestate: - iReturn = pPlayer->v.gamestate; - break; - case oldbuttons: - iReturn = pPlayer->v.oldbuttons; - break; - case groupinfo: - iReturn = pPlayer->v.groupinfo; - break; - case iuser1: - iReturn = pPlayer->v.iuser1; - break; - case iuser2: - iReturn = pPlayer->v.iuser2; - break; - case iuser3: - iReturn = pPlayer->v.iuser3; - break; - case iuser4: - iReturn = pPlayer->v.iuser4; - break; - default: - return 0; - } - } - else if (iSwitch > pev_float_start && iSwitch < pev_float_end) - { - valuetype=VALUETYPE_FLOAT; - switch(iSwitch) - { - case impacttime: - fReturn = pPlayer->v.impacttime; - break; - case starttime: - fReturn = pPlayer->v.starttime; - break; - case idealpitch: - fReturn = pPlayer->v.idealpitch; - break; - case ideal_yaw: - fReturn = pPlayer->v.ideal_yaw; - break; - case pitch_speed: - fReturn = pPlayer->v.pitch_speed; - break; - case yaw_speed: - fReturn = pPlayer->v.yaw_speed; - break; - case ltime: - fReturn = pPlayer->v.ltime; - break; - case nextthink: - fReturn = pPlayer->v.nextthink; - break; - case gravity: - fReturn = pPlayer->v.gravity; - break; - case friction: - fReturn = pPlayer->v.friction; - break; - case frame: - fReturn = pPlayer->v.frame; - break; - case animtime: - fReturn = pPlayer->v.animtime; - break; - case framerate: - fReturn = pPlayer->v.framerate; - break; - case scale: - fReturn = pPlayer->v.scale; - break; - case renderamt: - fReturn = pPlayer->v.renderamt; - break; - case health: - fReturn = pPlayer->v.health; - break; - case frags: - fReturn = pPlayer->v.frags; - break; - case takedamage: - fReturn = pPlayer->v.takedamage; - break; - case max_health: - fReturn = pPlayer->v.max_health; - break; - case teleport_time: - fReturn = pPlayer->v.teleport_time; - break; - case armortype: - fReturn = pPlayer->v.armortype; - break; - case armorvalue: - fReturn = pPlayer->v.armorvalue; - break; - case dmg_take: - fReturn = pPlayer->v.dmg_take; - break; - case dmg_save: - fReturn = pPlayer->v.dmg_save; - break; - case dmg: - fReturn = pPlayer->v.dmg; - break; - case dmgtime: - fReturn = pPlayer->v.dmgtime; - break; - case speed: - fReturn = pPlayer->v.speed; - break; - case air_finished: - fReturn = pPlayer->v.air_finished; - break; - case pain_finished: - fReturn = pPlayer->v.pain_finished; - break; - case radsuit_finished: - fReturn = pPlayer->v.radsuit_finished; - break; - case maxspeed: - fReturn = pPlayer->v.maxspeed; - break; - case fov: - fReturn = pPlayer->v.fov; - break; - case flFallVelocity: - fReturn = pPlayer->v.flFallVelocity; - break; - case fuser1: - fReturn = pPlayer->v.fuser1; - break; - case fuser2: - fReturn = pPlayer->v.fuser2; - break; - case fuser3: - fReturn = pPlayer->v.fuser3; - break; - case fuser4: - fReturn = pPlayer->v.fuser4; - break; - default: - return 0; - break; - } - } - else if (iSwitch > pev_string_start && iSwitch < pev_string_end) - { - valuetype=VALUETYPE_STRING; - switch (iSwitch) - { - case classname: - iReturn = pPlayer->v.classname; - break; - case globalname: - iReturn = pPlayer->v.globalname; - break; - case model: - iReturn = pPlayer->v.model; - break; - case target: - iReturn = pPlayer->v.target; - break; - case targetname: - iReturn = pPlayer->v.targetname; - break; - case netname: - iReturn = pPlayer->v.netname; - break; - case message: - iReturn = pPlayer->v.message; - break; - case noise: - iReturn = pPlayer->v.noise; - break; - case noise1: - iReturn = pPlayer->v.noise1; - break; - case noise2: - iReturn = pPlayer->v.noise2; - break; - case noise3: - iReturn = pPlayer->v.noise3; - break; - default: - return 0; - } + edict_t *pEdict = INDEXENT2(index); + int iSwitch = params[2]; - } - else if (iSwitch > pev_edict_start && iSwitch < pev_edict_end) + //onto normal cases - sanity check + if (iSwitch <= pev_string_start || iSwitch >= pev_vecarray_end) { - valuetype=VALUETYPE_EDICT; - switch (iSwitch) - { - case chain: - iReturn = ENTINDEX(pPlayer->v.chain); - break; - case dmg_inflictor: - iReturn = ENTINDEX(pPlayer->v.dmg_inflictor); - break; - case enemy: - iReturn = ENTINDEX(pPlayer->v.enemy); - break; - case aiment: - iReturn = ENTINDEX(pPlayer->v.aiment); - break; - case owner: - iReturn = ENTINDEX(pPlayer->v.owner); - break; - case groundentity: - iReturn = ENTINDEX(pPlayer->v.groundentity); - break; - case euser1: - iReturn = ENTINDEX(pPlayer->v.euser1); - break; - case euser2: - iReturn = ENTINDEX(pPlayer->v.euser2); - break; - case euser3: - iReturn = ENTINDEX(pPlayer->v.euser3); - break; - case euser4: - iReturn = ENTINDEX(pPlayer->v.euser4); - break; - default: - return 0; - } - } - else if (iSwitch > pev_vecarray_start && iSwitch < pev_vecarray_end) - { - valuetype=VALUETYPE_VECTOR; - switch(iSwitch) - { - case origin: - vReturn = pPlayer->v.origin; - break; - case oldorigin: - vReturn = pPlayer->v.oldorigin; - break; - case velocity: - vReturn = pPlayer->v.velocity; - break; - case basevelocity: - vReturn = pPlayer->v.basevelocity; - break; - case movedir: - vReturn = pPlayer->v.movedir; - break; - case angles: - vReturn = pPlayer->v.angles; - break; - case avelocity: - vReturn = pPlayer->v.avelocity; - break; - case v_angle: - vReturn = pPlayer->v.v_angle; - break; - case endpos: - vReturn = pPlayer->v.endpos; - break; - case startpos: - vReturn = pPlayer->v.startpos; - break; - case absmin: - vReturn = pPlayer->v.absmin; - break; - case absmax: - vReturn = pPlayer->v.absmax; - break; - case mins: - vReturn = pPlayer->v.mins; - break; - case maxs: - vReturn = pPlayer->v.maxs; - break; - case size: - vReturn = pPlayer->v.size; - break; - case rendercolor: - vReturn = pPlayer->v.rendercolor; - break; - case view_ofs: - vReturn = pPlayer->v.view_ofs; - break; - case vuser1: - vReturn = pPlayer->v.vuser1; - break; - case vuser2: - vReturn = pPlayer->v.vuser2; - break; - case vuser3: - vReturn = pPlayer->v.vuser3; - break; - case vuser4: - vReturn = pPlayer->v.vuser4; - break; - case punchangle: - vReturn = pPlayer->v.punchangle; - break; - default: - return 0; - } - } - else if ((iSwitch > pev_byte_start && iSwitch < pev_byte_end) || (iSwitch > pev_bytearray_start && iSwitch < pev_bytearray_end)) - { - if (iSwitch > pev_byte_start && iSwitch < pev_byte_end) - valuetype=VALUETYPE_INT; - else - valuetype=VALUETYPE_BYTE; - switch(iSwitch) - { - case controller: - { - bReturn[0] = pPlayer->v.controller[0]; - bReturn[1] = pPlayer->v.controller[1]; - bReturn[2] = pPlayer->v.controller[2]; - bReturn[3] = pPlayer->v.controller[3]; - break; - } - case controller_0: - iReturn = pPlayer->v.controller[0]; - break; - case controller_1: - iReturn = pPlayer->v.controller[1]; - break; - case controller_2: - iReturn = pPlayer->v.controller[2]; - break; - case controller_3: - iReturn = pPlayer->v.controller[3]; - break; - case blending: - { - bReturn[0] = pPlayer->v.blending[0]; - bReturn[1] = pPlayer->v.blending[1]; - bReturn[2]=0; - bReturn[3]=0; - break; - } - case blending_0: - iReturn = pPlayer->v.blending[0]; - break; - case blending_1: - iReturn = pPlayer->v.blending[1]; - break; - default: - return 0; - } - } - if (returntype == RETURNTYPE_INT) - { - // We are only returning an integer here. - // If the returned value is a string, return make_string value. - // If the returned value is a float, round it down. - // If the returned value is int, just return it. - // Otherwise, print a warning. - if (valuetype == VALUETYPE_INT || valuetype == VALUETYPE_EDICT) - { - return iReturn; - } - else if (valuetype == VALUETYPE_FLOAT) - { - return (int)fReturn; - } - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid return valuetype for pev()."); + MF_LogError(amx, AMX_ERR_NATIVE, "Undefined pev index: %d", iSwitch); return 0; } - else if (returntype == RETURNTYPE_FLOAT) - { - // We are setting a variable as a float here. - // If it's a float, just set it. - // If it's an integer, convert and set it. - // Otherwise, return an error. - if (valuetype == VALUETYPE_INT) - { - float fTemp = (float)iReturn; - cell *cRet = MF_GetAmxAddr(amx,params[3]); - *cRet = amx_ftoc(fTemp); - return 1; - } - else if (valuetype == VALUETYPE_FLOAT) - { - cell *cRet = MF_GetAmxAddr(amx,params[3]); - *cRet = amx_ftoc(fReturn); - return 1; - } - else if (valuetype == VALUETYPE_VECTOR) - { - cell *cRet = MF_GetAmxAddr(amx,params[3]); - cRet[0] = amx_ftoc(vReturn.x); - cRet[1] = amx_ftoc(vReturn.y); - cRet[2] = amx_ftoc(vReturn.z); - return 1; - } - else if (valuetype == VALUETYPE_BYTE) - { - cell *cRet = MF_GetAmxAddr(amx,params[3]); - if (iSwitch == blending) - { - // Only 2 for blending. - cRet[0]=bReturn[0]; - cRet[1]=bReturn[1]; - return 1; - } - else - { - // There's 4 for controller. - cRet[0]=bReturn[0]; - cRet[1]=bReturn[1]; - cRet[2]=bReturn[2]; - cRet[3]=bReturn[3]; - return 1; - } - } - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid return valuetype for pev()."); - } - else if (returntype == RETURNTYPE_STRING) - { - // Here is a string value that was requested. - // If the returned value is an integer or float, then sprintf() it to string. - // If the returned is a string, then string() it. - cell *cBlah = MF_GetAmxAddr(amx,params[4]); - int size = cBlah[0]; - if (valuetype == VALUETYPE_INT || valuetype == VALUETYPE_STRING || valuetype == VALUETYPE_EDICT) - { - if (valuetype == VALUETYPE_STRING) - { - MF_SetAmxString(amx, params[3], STRING(iReturn), size); - return 1; - } - else - { - char blah[64]; - sprintf(blah,"%i",iReturn); - MF_SetAmxString(amx, params[3], blah, size); - return 1; - } + int offs = g_offset_table[iSwitch]; - } - if (valuetype == VALUETYPE_FLOAT) - { - char blah[64]; - sprintf(blah,"%f",fReturn); - MF_SetAmxString(amx, params[3], blah, size); - return 1; - } - if (valuetype == VALUETYPE_VECTOR) - { - char blah[256]; - sprintf(blah,"%f %f %f",vReturn.x,vReturn.y,vReturn.z); - MF_SetAmxString(amx, params[3], blah, size); - return 1; - } - if (valuetype == VALUETYPE_BYTE) - { - if (iSwitch == controller) - { - char blah[128]; - sprintf(blah,"%i %i",bReturn[0],bReturn[1]); - MF_SetAmxString(amx,params[3],blah,size); - return 1; - } - else - { - char blah[256]; - sprintf(blah,"%i %i %i %i",bReturn[0],bReturn[1],bReturn[2],bReturn[3]); - MF_SetAmxString(amx,params[3],blah,size); - return 1; - } - } - MF_LogError(amx, AMX_ERR_NATIVE, "Invalid return valuetype for pev()."); + //sanity check #2 + if (offs == -1) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Undefined pev index: %d", iSwitch); + return 0; } + + enum + { + Ret_Int = (1<<0), + Ret_Float = (1<<1), + Ret_Vec = (1<<2), + Ret_ByteArray = (1<<3), + Ret_String = (1<<4), + Ret_Edict = (1<<5), + Ret_Bytes2 = (1<<6), + Ret_Bytes4 = (1<<7) + }; + + union + { + int i; + float f; + byte b; + string_t s; + byte ba[4]; + } rets; + Vector vr; + + int ValType = 0; + + entvars_t *v = &(pEdict->v); + + //get primitive data types + if (iSwitch > pev_int_start && iSwitch < pev_int_end) + { + rets.i = *(int *)EDICT_OFFS(v, offs); + ValType = Ret_Int; + } else if (iSwitch > pev_float_start && iSwitch < pev_float_end) { + rets.f = *(float *)EDICT_OFFS(v, offs); + ValType = Ret_Float; + } else if (iSwitch > pev_vecarray_start && iSwitch < pev_vecarray_end) { + vr = *(vec3_t *)EDICT_OFFS(v, offs); + ValType = Ret_Vec; + } else if (iSwitch > pev_bytearray_start && iSwitch < pev_bytearray_end) { + if (iSwitch == controller) + { + rets.ba[0] = v->controller[0]; + rets.ba[1] = v->controller[1]; + rets.ba[2] = v->controller[2]; + rets.ba[3] = v->controller[3]; + ValType = Ret_Bytes4; + } else { + rets.ba[0] = v->blending[0]; + rets.ba[1] = v->blending[1]; + ValType = Ret_Bytes2; + } + } else if (iSwitch > pev_byte_start && iSwitch < pev_byte_end) { + rets.b = *(byte *)EDICT_OFFS(v, offs); + ValType = Ret_Int; + } else if (iSwitch > pev_string_start && iSwitch < pev_string_end) { + rets.s = *(string_t *)EDICT_OFFS(v, offs); + ValType = Ret_String; + } else if (iSwitch > pev_edict_start && iSwitch < pev_edict_end) { + edict_t *e = *(edict_t **)EDICT_OFFS(v, offs); + rets.i = ENTINDEX(e); + ValType = Ret_Int; + ValType |= Ret_Edict; + } + + size_t count = params[0] / sizeof(cell) - 2; + + if (count == 0) + { + //return an int + if (ValType & Ret_Int) + { + return rets.i; + } else if (ValType == Ret_Float) { + return (cell)rets.f; + } else { + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid return type"); + return 0; + } + } else if (count == 1) { + //return a byref float - usually + cell *addr = MF_GetAmxAddr(amx, params[3]); + if (ValType == Ret_Float) + { + *addr = amx_ftoc(rets.f); + } else if (ValType == Ret_Int) { + REAL f = (REAL)rets.i; + *addr = amx_ftoc(f); + } else if (ValType == Ret_Vec) { + addr[0] = amx_ftoc(vr.x); + addr[1] = amx_ftoc(vr.y); + addr[2] = amx_ftoc(vr.z); + } else if (ValType == Ret_Bytes2) { + addr[0] = rets.ba[0]; + addr[1] = rets.ba[1]; + } else if (ValType == Ret_Bytes4) { + addr[0] = rets.ba[0]; + addr[1] = rets.ba[1]; + addr[2] = rets.ba[2]; + addr[3] = rets.ba[3]; + } else { + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid return type"); + return 0; + } + return 1; + } else if (count == 2) { + cell size = *(MF_GetAmxAddr(amx, params[4])); + if (ValType == Ret_String) + { + const char *str = STRING(rets.s); + if (!str) + str = ""; + int num = MF_SetAmxString(amx, params[3], str, size); + return num; + } else if (ValType & Ret_Int) { + char temp[32]; + snprintf(temp, 31, "%d", rets.i); + return MF_SetAmxString(amx, params[3], temp, size); + } else if (ValType == Ret_Float) { + char temp[32]; + snprintf(temp, 31, "%f", rets.f); + return MF_SetAmxString(amx, params[3], temp, size); + } else if (ValType == Ret_Vec) { + char temp[32]; + snprintf(temp, 31, "%f %f %f", vr.x, vr.y, vr.z); + return MF_SetAmxString(amx, params[3], temp, size); + } else if (ValType == Ret_Bytes2) { + char temp[32]; + snprintf(temp, 31, "%d %d", rets.ba[0], rets.ba[1]); + return MF_SetAmxString(amx, params[3], temp, size); + } else if (ValType == Ret_Bytes4) { + char temp[32]; + snprintf(temp, 31, "%d %d %d %d", rets.ba[0], rets.ba[1], rets.ba[2], rets.ba[3]); + return MF_SetAmxString(amx, params[3], temp, size); + } + + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid return type"); + } + + //if we got here, something happened + MF_LogError(amx, AMX_ERR_NATIVE, "Unknown pev index or return combination %d", iSwitch); + return 0; } @@ -607,465 +312,66 @@ static cell AMX_NATIVE_CALL amx_set_pev(AMX *amx, cell *params) // index, pevdata int index = params[1]; CHECK_ENTITY(index); - edict_t *pPlayer = INDEXENT2(index); + edict_t *pEdict = INDEXENT2(index); int iSwitch = params[2]; + + //onto normal cases - sanity check + if (iSwitch <= pev_string_start || iSwitch >= pev_vecarray_end) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Undefined pev index: %d", iSwitch); + return 0; + } + + int offs = g_offset_table[iSwitch]; + + //sanity check #2 + if (offs == -1) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Undefined pev index: %d", iSwitch); + return 0; + } + cell *blah = MF_GetAmxAddr(amx,params[3]); + entvars_t *v = &(pEdict->v); + if (iSwitch > pev_int_start && iSwitch < pev_int_end) { - // Grrr... - int iValue = blah[0]; - switch(iSwitch) - { - case fixangle: - pPlayer->v.fixangle = iValue; - return 1; - case modelindex: - pPlayer->v.modelindex = iValue; - return 1; - case viewmodel: - pPlayer->v.viewmodel = iValue; - return 1; - case weaponmodel: - pPlayer->v.weaponmodel = iValue; - return 1; - case movetype: - pPlayer->v.movetype = iValue; - return 1; - case solid: - pPlayer->v.solid = iValue; - return 1; - case skin: - pPlayer->v.skin = iValue; - return 1; - case body: - pPlayer->v.body = iValue; - return 1; - case effects: - pPlayer->v.effects = iValue; - return 1; - case light_level: - pPlayer->v.light_level = iValue; - return 1; - case sequence: - pPlayer->v.sequence = iValue; - return 1; - case gaitsequence: - pPlayer->v.gaitsequence = iValue; - return 1; - case rendermode: - pPlayer->v.rendermode = iValue; - return 1; - case renderfx: - pPlayer->v.renderfx = iValue; - return 1; - case weapons: - pPlayer->v.weapons = iValue; - return 1; - case deadflag: - pPlayer->v.deadflag = iValue; - return 1; - case button: - pPlayer->v.button = iValue; - return 1; - case impulse: - pPlayer->v.impulse = iValue; - return 1; - case spawnflags: - pPlayer->v.spawnflags = iValue; - return 1; - case flags: - pPlayer->v.flags = iValue; - return 1; - case colormap: - pPlayer->v.colormap = iValue; - return 1; - case team: - pPlayer->v.team = iValue; - return 1; - case waterlevel: - pPlayer->v.waterlevel = iValue; - return 1; - case watertype: - pPlayer->v.watertype = iValue; - return 1; - case playerclass: - pPlayer->v.playerclass = iValue; - return 1; - case weaponanim: - pPlayer->v.weaponanim = iValue; - return 1; - case pushmsec: - pPlayer->v.pushmsec = iValue; - return 1; - case bInDuck: - pPlayer->v.bInDuck = iValue; - return 1; - case flTimeStepSound: - pPlayer->v.flTimeStepSound = iValue; - return 1; - case flSwimTime: - pPlayer->v.flSwimTime = iValue; - return 1; - case flDuckTime: - pPlayer->v.flDuckTime = iValue; - return 1; - case iStepLeft: - pPlayer->v.iStepLeft = iValue; - return 1; - case gamestate: - pPlayer->v.gamestate = iValue; - return 1; - case oldbuttons: - pPlayer->v.oldbuttons = iValue; - return 1; - case groupinfo: - pPlayer->v.groupinfo = iValue; - return 1; - case iuser1: - pPlayer->v.iuser1 = iValue; - return 1; - case iuser2: - pPlayer->v.iuser2 = iValue; - return 1; - case iuser3: - pPlayer->v.iuser3 = iValue; - return 1; - case iuser4: - pPlayer->v.iuser4 = iValue; - return 1; - default: - return 0; - } - } - else if (iSwitch > pev_float_start && iSwitch < pev_float_end) - { - float fValue = amx_ctof(blah[0]); - switch(iSwitch) - { - case impacttime: - pPlayer->v.impacttime = fValue; - return 1; - case starttime: - pPlayer->v.starttime = fValue; - return 1; - case idealpitch: - pPlayer->v.idealpitch = fValue; - return 1; - case ideal_yaw: - pPlayer->v.ideal_yaw = fValue; - case pitch_speed: - pPlayer->v.pitch_speed = fValue; - return 1; - case yaw_speed: - pPlayer->v.yaw_speed = fValue; - return 1; - case ltime: - pPlayer->v.ltime = fValue; - return 1; - case nextthink: - pPlayer->v.nextthink = fValue; - return 1; - case gravity: - pPlayer->v.gravity = fValue; - return 1; - case friction: - pPlayer->v.friction = fValue; - return 1; - case frame: - pPlayer->v.frame = fValue; - return 1; - case animtime: - pPlayer->v.animtime = fValue; - return 1; - case framerate: - pPlayer->v.framerate = fValue; - return 1; - case scale: - pPlayer->v.scale = fValue; - return 1; - case renderamt: - pPlayer->v.renderamt = fValue; - return 1; - case health: - pPlayer->v.health = fValue; - return 1; - case frags: - pPlayer->v.frags = fValue; - return 1; - case takedamage: - pPlayer->v.takedamage = fValue; - return 1; - case max_health: - pPlayer->v.max_health = fValue; - return 1; - case teleport_time: - pPlayer->v.teleport_time = fValue; - return 1; - case armortype: - pPlayer->v.armortype = fValue; - return 1; - case armorvalue: - pPlayer->v.armorvalue = fValue; - return 1; - case dmg_take: - pPlayer->v.dmg_take = fValue; - return 1; - case dmg_save: - pPlayer->v.dmg_save = fValue; - return 1; - case dmg: - pPlayer->v.dmg = fValue; - return 1; - case dmgtime: - pPlayer->v.dmgtime = fValue; - return 1; - case speed: - pPlayer->v.speed = fValue; - return 1; - case air_finished: - pPlayer->v.air_finished = fValue; - return 1; - case pain_finished: - pPlayer->v.pain_finished = fValue; - return 1; - case radsuit_finished: - pPlayer->v.radsuit_finished = fValue; - return 1; - case maxspeed: - pPlayer->v.maxspeed = fValue; - return 1; - case fov: - pPlayer->v.fov = fValue; - return 1; - case flFallVelocity: - pPlayer->v.flFallVelocity = fValue; - return 1; - case fuser1: - pPlayer->v.fuser1 = fValue; - return 1; - case fuser2: - pPlayer->v.fuser2 = fValue; - return 1; - case fuser3: - pPlayer->v.fuser3 = fValue; - return 1; - case fuser4: - pPlayer->v.fuser4 = fValue; - return 1; - default: - return 0; - } - } - else if (iSwitch > pev_string_start && iSwitch < pev_string_end) - { + *(int *)EDICT_OFFS(v, offs) = (int)*blah; + } else if (iSwitch > pev_float_start && iSwitch < pev_float_end) { + *(float *)EDICT_OFFS(v, offs) = (float)amx_ctof(blah[0]); + } else if (iSwitch > pev_string_start && iSwitch < pev_string_end) { int len; char *string = MF_GetAmxString(amx, params[3], 0, &len); - int iValue = ALLOC_STRING(string); - switch (iSwitch) - { - case classname: - pPlayer->v.classname = iValue; - return 1; - case globalname: - pPlayer->v.globalname = iValue; - return 1; - case model: - pPlayer->v.model = iValue; - return 1; - case target: - pPlayer->v.target = iValue; - return 1; - case targetname: - pPlayer->v.targetname = iValue; - return 1; - case netname: - pPlayer->v.netname = iValue; - return 1; - case message: - pPlayer->v.message = iValue; - return 1; - case noise: - pPlayer->v.noise = iValue; - return 1; - case noise1: - pPlayer->v.noise1 = iValue; - return 1; - case noise2: - pPlayer->v.noise2 = iValue; - return 1; - case noise3: - pPlayer->v.noise3 = iValue; - return 1; - default: - return 0; - } - - } - else if (iSwitch > pev_edict_start && iSwitch < pev_edict_end) - { - int iValue = blah[0]; - switch (iSwitch) - { - case chain: - pPlayer->v.chain = INDEXENT2(iValue); - return 1; - case dmg_inflictor: - pPlayer->v.dmg_inflictor = INDEXENT2(iValue); - return 1; - case enemy: - pPlayer->v.enemy = INDEXENT2(iValue); - return 1; - case aiment: - pPlayer->v.aiment = INDEXENT2(iValue); - return 1; - case owner: - pPlayer->v.owner = INDEXENT2(iValue); - return 1; - case groundentity: - pPlayer->v.groundentity = INDEXENT2(iValue); - return 1; - case euser1: - pPlayer->v.euser1 = INDEXENT2(iValue); - return 1; - case euser2: - pPlayer->v.euser2 = INDEXENT2(iValue); - return 1; - case euser3: - pPlayer->v.euser3 = INDEXENT2(iValue); - return 1; - case euser4: - pPlayer->v.euser4 = INDEXENT2(iValue); - return 1; - default: - return 0; - } - } - else if (iSwitch > pev_vecarray_start && iSwitch < pev_vecarray_end) - { - Vector vValue; - vValue.x = amx_ctof(blah[0]); - vValue.y = amx_ctof(blah[1]); - vValue.z = amx_ctof(blah[2]); - switch(iSwitch) - { - case origin: - pPlayer->v.origin = vValue; - return 1; - case oldorigin: - pPlayer->v.oldorigin = vValue; - return 1; - case velocity: - pPlayer->v.velocity = vValue; - return 1; - case basevelocity: - pPlayer->v.basevelocity = vValue; - return 1; - case clbasevelocity: - pPlayer->v.clbasevelocity = vValue; - return 1; - case movedir: - pPlayer->v.movedir = vValue; - return 1; - case angles: - pPlayer->v.angles = vValue; - return 1; - case avelocity: - pPlayer->v.avelocity = vValue; - return 1; - case v_angle: - pPlayer->v.v_angle = vValue; - return 1; - case endpos: - pPlayer->v.endpos = vValue; - return 1; - case startpos: - pPlayer->v.startpos = vValue; - return 1; - case absmin: - pPlayer->v.absmin = vValue; - return 1; - case absmax: - pPlayer->v.absmax = vValue; - return 1; - case mins: - pPlayer->v.mins = vValue; - return 1; - case maxs: - pPlayer->v.maxs = vValue; - return 1; - case size: - pPlayer->v.size = vValue; - return 1; - case rendercolor: - pPlayer->v.rendercolor = vValue; - return 1; - case view_ofs: - pPlayer->v.view_ofs = vValue; - return 1; - case vuser1: - pPlayer->v.vuser1 = vValue; - return 1; - case vuser2: - pPlayer->v.vuser2 = vValue; - return 1; - case vuser3: - pPlayer->v.vuser3 = vValue; - return 1; - case vuser4: - pPlayer->v.vuser4 = vValue; - return 1; - case punchangle: - pPlayer->v.punchangle = vValue; - return 1; - default: - return 0; - } - } - else if (iSwitch > pev_byte_start && iSwitch < pev_byte_end) - { - int iValue = blah[0]; - switch(iSwitch) - { - case controller_0: - pPlayer->v.controller[0]=iValue; - return 1; - case controller_1: - pPlayer->v.controller[1]=iValue; - return 1; - case controller_2: - pPlayer->v.controller[2]=iValue; - return 1; - case controller_3: - pPlayer->v.controller[3]=iValue; - return 1; - case blending_0: - pPlayer->v.blending[0]=iValue; - return 1; - case blending_1: - pPlayer->v.blending[1]=iValue; - return 1; - default: - return 0; - } - } - else if (iSwitch > pev_bytearray_start && iSwitch < pev_bytearray_end) - { - switch(iSwitch) + string_t value = ALLOC_STRING(string); + *(string_t *)EDICT_OFFS(v, offs) = value; + } else if (iSwitch > pev_edict_start && iSwitch < pev_edict_end) { + edict_t *e = INDEXENT((int)*blah); + *(edict_t **)EDICT_OFFS(v, offs) = e; + } else if (iSwitch > pev_vecarray_start && iSwitch < pev_vecarray_end) { + vec3_t vec; + vec[0] = amx_ctof(blah[0]); + vec[1] = amx_ctof(blah[1]); + vec[2] = amx_ctof(blah[2]); + *(vec3_t *)EDICT_OFFS(v, offs) = vec; + } else if (iSwitch > pev_byte_start && iSwitch < pev_byte_end) { + byte b = static_cast(blah[0]); + *(byte *)EDICT_OFFS(v, offs) = b; + } else if (iSwitch > pev_bytearray_start && iSwitch < pev_bytearray_end) { + switch(iSwitch) { case controller: - pPlayer->v.controller[0]=blah[0]; - pPlayer->v.controller[1]=blah[1]; - pPlayer->v.controller[2]=blah[2]; - pPlayer->v.controller[3]=blah[3]; + pEdict->v.controller[0]=blah[0]; + pEdict->v.controller[1]=blah[1]; + pEdict->v.controller[2]=blah[2]; + pEdict->v.controller[3]=blah[3]; return 1; case blending: - pPlayer->v.controller[0]=blah[0]; - pPlayer->v.controller[1]=blah[1]; + pEdict->v.controller[0]=blah[0]; + pEdict->v.controller[1]=blah[1]; return 1; - default: - return 0; } } + return 0; } diff --git a/dlls/fakemeta/pev.h b/dlls/fakemeta/pev.h index efc472f7..6bbdbb5e 100755 --- a/dlls/fakemeta/pev.h +++ b/dlls/fakemeta/pev.h @@ -1,17 +1,6 @@ #ifndef _INCLUDE_PEV_H #define _INCLUDE_PEV_H -#define RETURNTYPE_INT 2 -#define RETURNTYPE_FLOAT 3 -#define RETURNTYPE_VECTOR 3 -#define RETURNTYPE_STRING 4 -#define VALUETYPE_INT 1 -#define VALUETYPE_FLOAT 2 -#define VALUETYPE_VECTOR 3 -#define VALUETYPE_EDICT 4 -#define VALUETYPE_STRING 5 -#define VALUETYPE_BYTE 6 - enum pev_pointers { pev_string_start = 0, @@ -158,5 +147,7 @@ enum pev_pointers pev_vecarray_end }; +void initialze_offsets(); + #endif //_INCLUDE_PEV_H diff --git a/dlls/fakemeta/sdk/moduleconfig.h b/dlls/fakemeta/sdk/moduleconfig.h index d21c20b9..8f6624bb 100755 --- a/dlls/fakemeta/sdk/moduleconfig.h +++ b/dlls/fakemeta/sdk/moduleconfig.h @@ -5,7 +5,7 @@ // Module info #define MODULE_NAME "FakeMeta" -#define MODULE_VERSION "1.65" +#define MODULE_VERSION "1.70" #define MODULE_AUTHOR "AMX Mod X Dev Team" #define MODULE_URL "http://www.amxmodx.org" #define MODULE_LOGTAG "FAKEMETA"