core/smn_entities.cpp
changeset 3997 59bcfc51eb79
parent 3961 0dc477c29792
child 4141 8ff66ae5ffcc
     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  };