1.1 --- a/core/smn_entities.cpp Mon Aug 12 00:45:29 2013 +0100
1.2 +++ b/core/smn_entities.cpp Mon Aug 12 00:54:21 2013 +0100
1.3 @@ -796,6 +796,82 @@
1.4 return info.actual_offset;
1.5 }
1.6
1.7 +static void GuessDataPropTypes(typedescription_t *td, cell_t * pSize, cell_t * pType)
1.8 +{
1.9 + switch (td->fieldType)
1.10 + {
1.11 + case FIELD_TICK:
1.12 + case FIELD_MODELINDEX:
1.13 + case FIELD_MATERIALINDEX:
1.14 + case FIELD_INTEGER:
1.15 + case FIELD_COLOR32:
1.16 + {
1.17 + *pType = PropField_Integer;
1.18 + *pSize = 32;
1.19 + break;
1.20 + }
1.21 + case FIELD_VECTOR:
1.22 + case FIELD_POSITION_VECTOR:
1.23 + {
1.24 + *pType = PropField_Vector;
1.25 + *pSize = 12;
1.26 + break;
1.27 + }
1.28 + case FIELD_SHORT:
1.29 + {
1.30 + *pType = PropField_Integer;
1.31 + *pSize = 16;
1.32 + break;
1.33 + }
1.34 + case FIELD_BOOLEAN:
1.35 + {
1.36 + *pType = PropField_Integer;
1.37 + *pSize = 1;
1.38 + break;
1.39 + }
1.40 + case FIELD_CHARACTER:
1.41 + {
1.42 + if (td->fieldSize == 1)
1.43 + {
1.44 + *pType = PropField_Integer;
1.45 + *pSize = 8;
1.46 + }
1.47 + else
1.48 + {
1.49 + *pType = PropField_String;
1.50 + *pSize = 8 * td->fieldSize;
1.51 + }
1.52 + break;
1.53 + }
1.54 + case FIELD_MODELNAME:
1.55 + case FIELD_SOUNDNAME:
1.56 + case FIELD_STRING:
1.57 + {
1.58 + *pSize = sizeof(string_t);
1.59 + *pType = PropField_String_T;
1.60 + break;
1.61 + }
1.62 + case FIELD_FLOAT:
1.63 + case FIELD_TIME:
1.64 + {
1.65 + *pType = PropField_Float;
1.66 + *pSize = 32;
1.67 + break;
1.68 + }
1.69 + case FIELD_EHANDLE:
1.70 + {
1.71 + *pType = PropField_Entity;
1.72 + *pSize = 32;
1.73 + break;
1.74 + }
1.75 + default:
1.76 + {
1.77 + *pType = PropField_Unsupported;
1.78 + *pSize = 0;
1.79 + }
1.80 + }
1.81 +}
1.82 +
1.83 static cell_t FindDataMapOffs(IPluginContext *pContext, const cell_t *params)
1.84 {
1.85 CBaseEntity *pEntity;
1.86 @@ -815,14 +891,13 @@
1.87 }
1.88
1.89 pContext->LocalToString(params[2], &offset);
1.90 - bool isNested = false;
1.91 - if ((td=g_HL2.FindInDataMap(pMap, offset, &isNested)) == NULL)
1.92 + sm_datatable_info_t info;
1.93 + if (!g_HL2.FindDataMapInfo(pMap, offset, &info))
1.94 {
1.95 - if (isNested)
1.96 - return pContext->ThrowNativeError("Property \"%s\" is not safe to access for entity %d", offset, params[1]);
1.97 - else
1.98 - return -1;
1.99 + return -1;
1.100 }
1.101 +
1.102 + td = info.prop;
1.103
1.104 if (params[0] == 4)
1.105 {
1.106 @@ -830,82 +905,60 @@
1.107
1.108 pContext->LocalToPhysAddr(params[3], &pType);
1.109 pContext->LocalToPhysAddr(params[4], &pSize);
1.110 +
1.111 + GuessDataPropTypes(td, pSize, pType);
1.112 + }
1.113
1.114 - switch (td->fieldType)
1.115 + return GetTypeDescOffs(td);
1.116 +}
1.117 +
1.118 +static cell_t FindDataMapInfo(IPluginContext *pContext, const cell_t *params)
1.119 +{
1.120 + CBaseEntity *pEntity;
1.121 + datamap_t *pMap;
1.122 + typedescription_t *td;
1.123 + char *offset;
1.124 + pEntity = GetEntity(params[1]);
1.125 +
1.126 + if (!pEntity)
1.127 + {
1.128 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
1.129 + }
1.130 +
1.131 + if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
1.132 + {
1.133 + return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
1.134 + }
1.135 +
1.136 + pContext->LocalToString(params[2], &offset);
1.137 + sm_datatable_info_t info;
1.138 + if (!g_HL2.FindDataMapInfo(pMap, offset, &info))
1.139 + {
1.140 + return -1;
1.141 + }
1.142 +
1.143 + td = info.prop;
1.144 +
1.145 + if (params[0] >= 4)
1.146 + {
1.147 + cell_t *pType, *pSize;
1.148 +
1.149 + pContext->LocalToPhysAddr(params[3], &pType);
1.150 + pContext->LocalToPhysAddr(params[4], &pSize);
1.151 +
1.152 + GuessDataPropTypes(td, pSize, pType);
1.153 +
1.154 + if (params[0] == 5)
1.155 {
1.156 - case FIELD_TICK:
1.157 - case FIELD_MODELINDEX:
1.158 - case FIELD_MATERIALINDEX:
1.159 - case FIELD_INTEGER:
1.160 - case FIELD_COLOR32:
1.161 - {
1.162 - *pType = PropField_Integer;
1.163 - *pSize = 32;
1.164 - break;
1.165 - }
1.166 - case FIELD_VECTOR:
1.167 - case FIELD_POSITION_VECTOR:
1.168 - {
1.169 - *pType = PropField_Vector;
1.170 - *pSize = 12;
1.171 - break;
1.172 - }
1.173 - case FIELD_SHORT:
1.174 - {
1.175 - *pType = PropField_Integer;
1.176 - *pSize = 16;
1.177 - break;
1.178 - }
1.179 - case FIELD_BOOLEAN:
1.180 - {
1.181 - *pType = PropField_Integer;
1.182 - *pSize = 1;
1.183 - break;
1.184 - }
1.185 - case FIELD_CHARACTER:
1.186 - {
1.187 - if (td->fieldSize == 1)
1.188 - {
1.189 - *pType = PropField_Integer;
1.190 - *pSize = 8;
1.191 - }
1.192 - else
1.193 - {
1.194 - *pType = PropField_String;
1.195 - *pSize = 8 * td->fieldSize;
1.196 - }
1.197 - break;
1.198 - }
1.199 - case FIELD_MODELNAME:
1.200 - case FIELD_SOUNDNAME:
1.201 - case FIELD_STRING:
1.202 - {
1.203 - *pSize = sizeof(string_t);
1.204 - *pType = PropField_String_T;
1.205 - break;
1.206 - }
1.207 - case FIELD_FLOAT:
1.208 - case FIELD_TIME:
1.209 - {
1.210 - *pType = PropField_Float;
1.211 - *pSize = 32;
1.212 - break;
1.213 - }
1.214 - case FIELD_EHANDLE:
1.215 - {
1.216 - *pType = PropField_Entity;
1.217 - *pSize = 32;
1.218 - break;
1.219 - }
1.220 - default:
1.221 - {
1.222 - *pType = PropField_Unsupported;
1.223 - *pSize = 0;
1.224 - }
1.225 + cell_t *pLocalOffs;
1.226 +
1.227 + pContext->LocalToPhysAddr(params[5], &pLocalOffs);
1.228 +
1.229 + *pLocalOffs = GetTypeDescOffs(info.prop);
1.230 }
1.231 }
1.232
1.233 - return GetTypeDescOffs(td);
1.234 + return info.actual_offset;
1.235 }
1.236
1.237 static cell_t GetEntDataString(IPluginContext *pContext, const cell_t *params)
1.238 @@ -966,23 +1019,16 @@
1.239 { \
1.240 return pContext->ThrowNativeError("Could not retrieve datamap"); \
1.241 } \
1.242 - bool isNested = false; \
1.243 - if ((td = g_HL2.FindInDataMap(pMap, prop, &isNested)) == NULL) \
1.244 + sm_datatable_info_t info; \
1.245 + if (!g_HL2.FindDataMapInfo(pMap, prop, &info)) \
1.246 { \
1.247 const char *class_name = g_HL2.GetEntityClassname(pEntity); \
1.248 - if (isNested) \
1.249 - { \
1.250 - return pContext->ThrowNativeError("Property \"%s\" not safe to access (entity %d/%s)", \
1.251 - prop, \
1.252 - params[1], \
1.253 - ((class_name) ? class_name : "")); \
1.254 - } else { \
1.255 - return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
1.256 - prop, \
1.257 - params[1], \
1.258 - ((class_name) ? class_name : "")); \
1.259 - } \
1.260 - }
1.261 + return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
1.262 + prop, \
1.263 + params[1], \
1.264 + ((class_name) ? class_name : "")); \
1.265 + } \
1.266 + td = info.prop;
1.267
1.268 #define CHECK_SET_PROP_DATA_OFFSET() \
1.269 if (element < 0 || element >= td->fieldSize) \
1.270 @@ -993,7 +1039,7 @@
1.271 td->fieldSize); \
1.272 } \
1.273 \
1.274 - offset = GetTypeDescOffs(td) + (element * (td->fieldSizeInBytes / td->fieldSize));
1.275 + offset = info.actual_offset + (element * (td->fieldSizeInBytes / td->fieldSize));
1.276
1.277 #define FIND_PROP_SEND(type, type_name) \
1.278 sm_sendprop_info_t info;\
1.279 @@ -1808,7 +1854,7 @@
1.280 element);
1.281 }
1.282
1.283 - offset = GetTypeDescOffs(td);
1.284 + offset = info.actual_offset;
1.285 if (bIsStringIndex)
1.286 {
1.287 offset += (element * (td->fieldSizeInBytes / td->fieldSize));
1.288 @@ -1896,25 +1942,23 @@
1.289 case Prop_Data:
1.290 {
1.291 datamap_t *pMap;
1.292 - typedescription_t *td;
1.293 if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
1.294 {
1.295 return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
1.296 }
1.297 pContext->LocalToString(params[3], &prop);
1.298 - bool isNested = false;
1.299 - if ((td=g_HL2.FindInDataMap(pMap, prop, &isNested)) == NULL)
1.300 + sm_datatable_info_t info;
1.301 + if (!g_HL2.FindDataMapInfo(pMap, prop, &info))
1.302 {
1.303 - if (isNested)
1.304 - return pContext->ThrowNativeError("Property \"%s\" is not safe to access for entity %d", prop, params[1]);
1.305 - else
1.306 - return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.307 + return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.308 }
1.309 +
1.310 + typedescription_t *td = info.prop;
1.311 if (td->fieldType != FIELD_CHARACTER)
1.312 {
1.313 return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.314 }
1.315 - offset = GetTypeDescOffs(td);
1.316 + offset = info.actual_offset;
1.317 maxlen = td->fieldSize;
1.318 break;
1.319 }
1.320 @@ -2138,14 +2182,16 @@
1.321 {
1.322 return pContext->ThrowNativeError("Could not retrieve datamap");
1.323 }
1.324 - if ((td = g_HL2.FindInDataMap(pMap, prop)) == NULL)
1.325 +
1.326 + sm_datatable_info_t info;
1.327 + if (!g_HL2.FindDataMapInfo(pMap, prop, &info))
1.328 {
1.329 return pContext->ThrowNativeError("Property \"%s\" not found (entity %d)",
1.330 prop,
1.331 params[1]);
1.332 }
1.333
1.334 - int offset = GetTypeDescOffs(td);
1.335 + int offset = info.actual_offset;
1.336
1.337 int32_t actual_flags = *(int32_t *)((uint8_t *)pEntity + offset);
1.338 int32_t sm_flags = 0;
1.339 @@ -2176,21 +2222,22 @@
1.340 return pContext->ThrowNativeError("Could not find m_fFlags prop in gamedata");
1.341 }
1.342
1.343 - typedescription_t *td;
1.344 datamap_t *pMap;
1.345
1.346 if ((pMap = CBaseEntity_GetDataDescMap(pEntity)) == NULL)
1.347 {
1.348 return pContext->ThrowNativeError("Could not retrieve datamap");
1.349 }
1.350 - if ((td = g_HL2.FindInDataMap(pMap, prop)) == NULL)
1.351 +
1.352 + sm_datatable_info_t info;
1.353 + if (!g_HL2.FindDataMapInfo(pMap, prop, &info))
1.354 {
1.355 return pContext->ThrowNativeError("Property \"%s\" not found (entity %d)",
1.356 prop,
1.357 params[1]);
1.358 }
1.359
1.360 - int offset = GetTypeDescOffs(td);
1.361 + int offset = info.actual_offset;
1.362
1.363 int32_t sm_flags = params[2];
1.364 int32_t actual_flags = 0;
1.365 @@ -2262,5 +2309,6 @@
1.366 {"SetEntPropString", SetEntPropString},
1.367 {"SetEntPropVector", SetEntPropVector},
1.368 {"GetEntityAddress", GetEntityAddress},
1.369 + {"FindDataMapInfo", FindDataMapInfo},
1.370 {NULL, NULL}
1.371 };