/* Ham Sandwich * * by sawce * * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, the author gives permission to * link the code of this program with the Half-Life Game Engine ("HL * Engine") and Modified Game Libraries ("MODs") developed by Valve, * L.L.C ("Valve"). You must obey the GNU General Public License in all * respects for all of the code used other than the HL Engine and MODs * from Valve. If you modify this file, you may extend this exception * to your version of the file, but you are not obligated to do so. If * you do not wish to do so, delete this exception statement from your * version. */ #include "sdk/amxxmodule.h" #include "hamsandwich.h" #include "NEW_Util.h" #include "vfunc_msvc.h" #include "vfunc_gcc295.h" static cell AMX_NATIVE_CALL hs_takedamage(AMX *amx, cell *params) { return VCall4( INDEXENT_NEW(params[1])->pvPrivateData, /*this*/ HAM_Takedamage, /*vtable entry*/ HAM_Classbase, /*size of class*/ &(INDEXENT_NEW(params[2])->v), /*inflictor*/ &(INDEXENT_NEW(params[3])->v), /*attacker*/ amx_ctof2(params[4]), /*damage*/ (int)params[5]); /*dmgtype*/ }; static cell AMX_NATIVE_CALL hs_use(AMX *amx, cell *params) { VoidVCall4( INDEXENT_NEW(params[1])->pvPrivateData, /*this*/ HAM_Use, /*vtable entry*/ HAM_Classbase, /*size of class*/ INDEXENT_NEW(params[2])->pvPrivateData, /*activator*/ INDEXENT_NEW(params[3])->pvPrivateData, /*caller*/ params[4], /*use type*/ amx_ctof2(params[5])); /*value*/ return 1; } /** * Very fast, but potentially unsafe (if you use the wrong index/offset) * method of converting a CBaseEntity pointer into a usable entity index */ static cell AMX_NATIVE_CALL hs_pdata_cbase(AMX *amx, cell *params) { // Get the offset of the private data int Offset=params[2]; // If this is a linux server increase the offset #ifdef __linux__ Offset+=params[3]; #endif // Get the CBase pointer int *ent=*((int **)INDEXENT_NEW(params[1])->pvPrivateData + Offset); // Null pointer; get out if (ent==NULL) { return 0; } // Now move up HAM_Pev bytes char *bent=*(char**)&ent; bent+=HAM_Pev; entvars_t *pev=*(entvars_t **)&bent; // Null pointer, get out if (pev==NULL) { return 0; } return ENTINDEX_NEW(pev->pContainingEntity); } /** * Slow, but very safe replacement for hs_pdata_cbase * - * This will scan through all entities to check their private * data against the requested offset's data. * It will never reference the requested PData, so unless * the plugin author is way off with the offset it should * never crash. * - * This should only be used for offset searching; NEVER * in a release quality script. */ static cell AMX_NATIVE_CALL hs_pdata_cbase_safe(AMX *amx, cell *params) { // Get the offset of the private data int Offset=params[2]; // If this is a linux server increase the offset #ifdef __linux__ Offset+=params[3]; #endif // Get the CBase pointer int *data=*((int **)INDEXENT_NEW(params[1])->pvPrivateData + Offset); // Get the first entity edict_t *Entity=INDEXENT_NEW(0); // Get the last entity edict_t *Last=INDEXENT_NEW(gpGlobals->maxEntities); // Scan through all of the entities (excluding 0, because no other module allows for worldspawn) while (Entity++pvPrivateData)==data) { return ENTINDEX_NEW(Entity); } } // Not found return 0; } static AMX_NATIVE_INFO reg_takedamage[] = { { "hs_takedamage", hs_takedamage }, { NULL, NULL } }; static AMX_NATIVE_INFO reg_use[] = { { "hs_use", hs_use }, { NULL, NULL } }; static AMX_NATIVE_INFO reg_cbase_fast[] = { { "hs_pdata_cbase", hs_pdata_cbase }, { NULL, NULL } }; static AMX_NATIVE_INFO reg_cbase_safe[] = { { "hs_pdata_cbase_safe", hs_pdata_cbase_safe }, { NULL, NULL } }; void HAM_RegisterTakeDamage() { MF_AddNatives(reg_takedamage); } void HAM_RegisterUse() { MF_AddNatives(reg_use); } void HAM_RegisterCbaseFast() { MF_AddNatives(reg_cbase_fast); } void HAM_RegisterCbaseSafe() { MF_AddNatives(reg_cbase_safe); }