I figured I would post this, a generic way that I get/set info from the datamap.
Code:
/* ======== goldenadmin_mm ========
* Copyright (C) 2005 - 2006 PimpinJuice
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Anthony Iacono
* ============================
*/
#ifndef __linux__
#define ADDVFUNC 0
#else
#define ADDVFUNC 1
#endif
#define OFFSET_DATADESC 13
struct offset_map
{
int value;
const char *field;
};
offset_map GRAVITY_OFFSET_MAP;
offset_map HEALTH_OFFSET_MAP;
offset_map VELOCITY_OFFSET_MAP;
class VfuncEmptyClass {};
class GA_VFuncs
{
public:
static void Init_OffsetMap();
static datamap_t *GetDataDescMap(CBaseEntity *pThisPtr);
static typedescription_t *FindFieldByName(const char *fieldname, datamap_t *dmap);
};
void GA_VFuncs::Init_OffsetMap()
{
GRAVITY_OFFSET_MAP.field="m_flGravity";
HEALTH_OFFSET_MAP.field="m_iHealth";
VELOCITY_OFFSET_MAP.field="m_vecVelocity";
GRAVITY_OFFSET_MAP.value=0;
HEALTH_OFFSET_MAP.value=0;
VELOCITY_OFFSET_MAP.value=0;
}
datamap_t *GA_VFuncs::GetDataDescMap(CBaseEntity *pThisPtr)
{
void **this_ptr = *(void ***)&pThisPtr;
void **vtable = *(void ***)pThisPtr;
void *func = vtable[OFFSET_DATADESC+ADDVFUNC];
union {datamap_t *(VfuncEmptyClass::*mfpnew)();
#ifndef __linux__
void *addr; } u; u.addr = func;
#else
struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
#endif
return (datamap_t *) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)();
}
typedescription_t *GA_VFuncs::FindFieldByName(const char *fieldname, datamap_t *dmap)
{
int c = dmap->dataNumFields;
for(int i = 0; i < c; i++)
{
typedescription_t *td = &dmap->dataDesc[i];
if(td->fieldType == FIELD_VOID) continue;
if(td->fieldType == FIELD_EMBEDDED)
{
typedescription_t *ret = FindFieldByName(fieldname, td->td);
if(ret) return ret;
}
if(!stricmp(td->fieldName, fieldname)) return td;
}
if(dmap->baseMap) return FindFieldByName( fieldname, dmap->baseMap );
return NULL;
}
int UTIL_FindOffsetDMap(datamap_t *dmap, const char *fieldname)
{
typedescription_t *td = GA_VFuncs::FindFieldByName(fieldname, dmap);
if(td) return td->fieldOffset[0];
return 0;
}
template <class TheClass> bool UTIL_GetOffsetMap(edict_t *pEntity, offset_map *offmap, TheClass *Value)
{
if (offmap->value==0)
{
datamap_t *dmap = GA_VFuncs::GetDataDescMap(pEntity->GetUnknown()->GetBaseEntity());
if (dmap)
offmap->value = UTIL_FindOffsetDMap(dmap, offmap->field);
else
{
META_LOG(g_PLAPI,"Could not obtain datamap\n");
return false;
}
}
if (offmap->value!=0)
{
*Value=*(TheClass *)((char *)pEntity->GetUnknown()->GetBaseEntity() + offmap->value );
return true;
}
else
{
META_LOG(g_PLAPI,"Could not find %s\n",offmap->field);
return false;
}
}
template <class TheClass> bool UTIL_SetOffsetMap(edict_t *pEntity, offset_map *offmap, TheClass newValue)
{
if (offmap->value==0)
{
datamap_t *dmap = GA_VFuncs::GetDataDescMap(pEntity->GetUnknown()->GetBaseEntity());
if (dmap)
offmap->value = UTIL_FindOffsetDMap(dmap, offmap->field);
else
{
META_LOG(g_PLAPI,"Could not obtain datamap\n");
return false;
}
}
if (offmap->value!=0)
{
*(TheClass *)((char *)pEntity->GetUnknown()->GetBaseEntity() + offmap->value ) = newValue;
return true;
}
else
{
META_LOG(g_PLAPI,"Could not find %s\n",offmap->field);
return false;
}
}
Hope you find it useful.