diff --git a/modules/fakemeta/pdata_gc.cpp b/modules/fakemeta/pdata_gc.cpp index 1df45d48..e40b8ca5 100644 --- a/modules/fakemeta/pdata_gc.cpp +++ b/modules/fakemeta/pdata_gc.cpp @@ -112,6 +112,232 @@ static BaseFieldType GetBaseDataType(TypeDescription &data) return 0; \ } + +cell GetData(void *pObject, TypeDescription &data, int element) +{ + switch (data.fieldType) + { + case FieldType::FIELD_INTEGER: + case FieldType::FIELD_STRINGINT: + { + return get_pdata(pObject, data.fieldOffset, element); + } + case FieldType::FIELD_CLASS: + case FieldType::FIELD_STRUCTURE: + { + return get_pdata_direct(pObject, data.fieldOffset); + } + case FieldType::FIELD_POINTER: + case FieldType::FIELD_FUNCTION: + { + return reinterpret_cast(get_pdata(pObject, data.fieldOffset, element)); + } + case FieldType::FIELD_SHORT: + { + if (data.fieldUnsigned) + { + return get_pdata(pObject, data.fieldOffset, element); + } + else + { + return get_pdata(pObject, data.fieldOffset, element); + } + } + case FieldType::FIELD_CHARACTER: + { + if (data.fieldUnsigned) + { + return get_pdata(pObject, data.fieldOffset, element); + } + else + { + return get_pdata(pObject, data.fieldOffset, element); + } + } + case FieldType::FIELD_BOOLEAN: + { + return get_pdata(pObject, data.fieldOffset, element) ? 1 : 0; + } + } + + return 0; +} + +void SetData(void *pObject, TypeDescription &data, cell value, int element) +{ + switch (data.fieldType) + { + case FieldType::FIELD_INTEGER: + case FieldType::FIELD_STRINGINT: + { + set_pdata(pObject, data.fieldOffset, static_cast(value), element); + break; + } + case FieldType::FIELD_POINTER: + case FieldType::FIELD_FUNCTION: + { + set_pdata(pObject, data.fieldOffset, reinterpret_cast(value), element); + break; + } + case FieldType::FIELD_SHORT: + { + if (data.fieldUnsigned) + { + set_pdata(pObject, data.fieldOffset, static_cast(value), element); + } + else + { + set_pdata(pObject, data.fieldOffset, static_cast(value), element); + } + break; + } + case FieldType::FIELD_CHARACTER: + { + if (data.fieldUnsigned) + { + set_pdata(pObject, data.fieldOffset, static_cast(value), element); + } + else + { + set_pdata(pObject, data.fieldOffset, static_cast(value), element); + } + break; + } + case FieldType::FIELD_BOOLEAN: + { + set_pdata(pObject, data.fieldOffset, value != 0, element); + break; + } + } +} + +cell GetDataFloat(void *pObject, TypeDescription &data, int element) +{ + return amx_ftoc(get_pdata(pObject, data.fieldOffset, element)); +} + +void SetDataFloat(void *pObject, TypeDescription &data, float value, int element) +{ + set_pdata(pObject, data.fieldOffset, value, element); +} + +void GetDataVector(void *pObject, TypeDescription &data, cell *pVector, int element) +{ + auto vector = get_pdata(pObject, data.fieldOffset, element); + + pVector[0] = amx_ftoc(vector.x); + pVector[1] = amx_ftoc(vector.y); + pVector[2] = amx_ftoc(vector.z); +} + +void SetDataVector(void *pObject, TypeDescription &data, cell *pVector, int element) +{ + Vector vector(amx_ctof(pVector[0]), amx_ctof(pVector[1]), amx_ctof(pVector[2])); + + set_pdata(pObject, data.fieldOffset, vector, element); +} + +cell GetDataEntity(void *pObject, TypeDescription &data, int element) +{ + switch (data.fieldType) + { + case FieldType::FIELD_CLASSPTR: + { + return TypeConversion.cbase_to_id(get_pdata(pObject, data.fieldOffset, element)); + } + case FieldType::FIELD_ENTVARS: + { + return TypeConversion.entvars_to_id(get_pdata(pObject, data.fieldOffset, element)); + } + case FieldType::FIELD_EDICT: + { + return TypeConversion.edict_to_id(get_pdata(pObject, data.fieldOffset, element)); + } + case FieldType::FIELD_EHANDLE: + { + return TypeConversion.edict_to_id(get_pdata(pObject, data.fieldOffset, element).Get()); + } + } + + return 0; +} + +void SetDataEntity(void *pObject, TypeDescription &data, int value, int element) +{ + switch (data.fieldType) + { + case FieldType::FIELD_CLASSPTR: + { + set_pdata(pObject, data.fieldOffset, value != -1 ? TypeConversion.id_to_cbase(value) : nullptr, element); + break; + } + case FieldType::FIELD_ENTVARS: + { + set_pdata(pObject, data.fieldOffset, value != -1 ? TypeConversion.id_to_entvars(value) : nullptr, element); + break; + } + case FieldType::FIELD_EDICT: + { + set_pdata(pObject, data.fieldOffset, value != -1 ? TypeConversion.id_to_edict(value) : nullptr, element); + break; + } + case FieldType::FIELD_EHANDLE: + { + get_pdata(pObject, data.fieldOffset, element).Set(value != -1 ? TypeConversion.id_to_edict(value) : nullptr); + break; + } + } +} + +char* GetDataString(void *pObject, TypeDescription &data, int element) +{ + switch (data.fieldType) + { + case FieldType::FIELD_STRING: + { + return get_pdata_direct(pObject, data.fieldOffset, element, data.fieldSize); + } + case FieldType::FIELD_STRINGPTR: + { + return get_pdata(pObject, data.fieldOffset, element); + } + } + + return nullptr; +} + +cell SetDataString(void *pObject, TypeDescription &data, const char *value, int maxlen, int element) +{ + switch (data.fieldType) + { + case FieldType::FIELD_STRING: + { + auto buffer = get_pdata_direct(pObject, data.fieldOffset); + return strncopy(buffer, value, ke::Min(maxlen + 1, data.fieldSize)); + } + case FieldType::FIELD_STRINGPTR: + { + auto buffer = get_pdata(pObject, data.fieldOffset, element); + + if (!buffer || maxlen > static_cast(strlen(buffer))) + { + if (buffer) + { + free(buffer); + } + + buffer = reinterpret_cast(malloc(maxlen + 1)); + set_pdata(pObject, data.fieldOffset, buffer, element); + } + + return strncopy(buffer, value, maxlen + 1); + } + } + + return 0; +} + + // native any:get_ent_data(entity, const class[], const member[], element = 0); static cell AMX_NATIVE_CALL get_ent_data(AMX *amx, cell *params) { diff --git a/public/HLTypeConversion.h b/public/HLTypeConversion.h index 2c135b11..e99993ed 100644 --- a/public/HLTypeConversion.h +++ b/public/HLTypeConversion.h @@ -19,11 +19,17 @@ template static inline T& ref_pdata(void *pPrivateData, int offset, } +template inline T get_pdata_direct(void *pPrivateData, int offset, int element = 0, int size = 0) +{ + return reinterpret_cast(reinterpret_cast(pPrivateData) + offset + (element * size)); +} + template inline T get_pdata_direct(edict_t *pEntity, int offset, int element = 0, int size = 0) { - return reinterpret_cast((reinterpret_cast(pEntity->pvPrivateData) + offset + (element * size))); + return get_pdata_direct(pEntity->pvPrivateData, offset, element, size); } + template inline T& get_pdata(void *pPrivateData, int offset, int element = 0) { return ref_pdata(pPrivateData, offset, element);