amxmodx/dlls/hamsandwich/natives.cpp

186 lines
5.0 KiB
C++
Raw Normal View History

/* 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<int>(
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++<Last)
{
// If this entity's private data matches the CBase pointer requested, return
if (((int *)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);
}