AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Coding MM:S Plugins & SM Extensions (https://forums.alliedmods.net/forumdisplay.php?f=75)
-   -   My Way of Setting/Getting from DataMap (https://forums.alliedmods.net/showthread.php?t=46561)

API 10-28-2006 22:59

My Way of Setting/Getting from DataMap
 
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.

CoolPeter 10-29-2006 08:36

Re: My Way of Setting/Getting from DataMap
 
actually the same as here :)

API 10-29-2006 10:04

Re: My Way of Setting/Getting from DataMap
 
Look at the template functions. Thats what I kind of ment.

TommyV 10-30-2006 03:29

Re: My Way of Setting/Getting from DataMap
 
This is really interesting pimpinjuice, as I'm just trying to figure out how to set a players health.

Could you give an example of how to use this to the set the health of an edict_t?

I dont really understand what it's doing and I cant seem to call the functions.


All times are GMT -4. The time now is 00:38.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.