1.1 --- a/core/smn_entities.cpp Sun Jan 13 02:08:40 2008 +0000
1.2 +++ b/core/smn_entities.cpp Sun Jan 13 08:10:25 2008 +0000
1.3 @@ -44,6 +44,16 @@
1.4 Prop_Data
1.5 };
1.6
1.7 +enum PropFieldType
1.8 +{
1.9 + PropField_Unsupported, /**< The type is unsupported. */
1.10 + PropField_Integer, /**< Valid for SendProp and Data fields */
1.11 + PropField_Float, /**< Valid for SendProp and Data fields */
1.12 + PropField_Entity, /**< Valid for Data fields only (SendProp shows as int) */
1.13 + PropField_Vector, /**< Valid for SendProp and Data fields */
1.14 + PropField_String, /**< Valid for SendProp and Data fields */
1.15 +};
1.16 +
1.17 inline edict_t *GetEdict(cell_t num)
1.18 {
1.19 edict_t *pEdict = engine->PEntityOfEntIndex(num);
1.20 @@ -292,7 +302,7 @@
1.21 }
1.22
1.23 int offset = params[2];
1.24 - if (offset < 0 || offset > 32768)
1.25 + if (offset <= 0 || offset > 32768)
1.26 {
1.27 return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.28 }
1.29 @@ -321,7 +331,7 @@
1.30 }
1.31
1.32 int offset = params[2];
1.33 - if (offset < 0 || offset > 32768)
1.34 + if (offset <= 0 || offset > 32768)
1.35 {
1.36 return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.37 }
1.38 @@ -366,7 +376,7 @@
1.39 }
1.40
1.41 int offset = params[2];
1.42 - if (offset < 0 || offset > 32768)
1.43 + if (offset <= 0 || offset > 32768)
1.44 {
1.45 return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.46 }
1.47 @@ -387,7 +397,7 @@
1.48 }
1.49
1.50 int offset = params[2];
1.51 - if (offset < 0 || offset > 32768)
1.52 + if (offset <= 0 || offset > 32768)
1.53 {
1.54 return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.55 }
1.56 @@ -413,7 +423,7 @@
1.57 }
1.58
1.59 int offset = params[2];
1.60 - if (offset < 0 || offset > 32768)
1.61 + if (offset <= 0 || offset > 32768)
1.62 {
1.63 return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.64 }
1.65 @@ -441,7 +451,7 @@
1.66 }
1.67
1.68 int offset = params[2];
1.69 - if (offset < 0 || offset > 32768)
1.70 + if (offset <= 0 || offset > 32768)
1.71 {
1.72 return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.73 }
1.74 @@ -463,6 +473,7 @@
1.75 return 1;
1.76 }
1.77
1.78 +/* THIS GUY IS DEPRECATED. */
1.79 static cell_t GetEntDataEnt(IPluginContext *pContext, const cell_t *params)
1.80 {
1.81 CBaseEntity *pEntity;
1.82 @@ -474,7 +485,7 @@
1.83 }
1.84
1.85 int offset = params[2];
1.86 - if (offset < 0 || offset > 32768)
1.87 + if (offset <= 0 || offset > 32768)
1.88 {
1.89 return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.90 }
1.91 @@ -486,11 +497,65 @@
1.92 return 0;
1.93 }
1.94
1.95 - /* :TODO: check serial no.? */
1.96 -
1.97 return hndl.GetEntryIndex();
1.98 }
1.99
1.100 +int CheckBaseHandle(CBaseHandle &hndl)
1.101 +{
1.102 + if (!hndl.IsValid())
1.103 + {
1.104 + return -1;
1.105 + }
1.106 +
1.107 + int index = hndl.GetEntryIndex();
1.108 +
1.109 + edict_t *pStoredEdict;
1.110 + CBaseEntity *pStoredEntity;
1.111 +
1.112 + pStoredEdict = GetEntity(index, &pStoredEntity);
1.113 +
1.114 + if (pStoredEdict == NULL || pStoredEntity == NULL)
1.115 + {
1.116 + return -1;
1.117 + }
1.118 +
1.119 + IServerEntity *pSE = pStoredEdict->GetIServerEntity();
1.120 +
1.121 + if (pSE == NULL)
1.122 + {
1.123 + return -1;
1.124 + }
1.125 +
1.126 + if (pSE->GetRefEHandle() != hndl)
1.127 + {
1.128 + return -1;
1.129 + }
1.130 +
1.131 + return index;
1.132 +}
1.133 +
1.134 +static cell_t GetEntDataEnt2(IPluginContext *pContext, const cell_t *params)
1.135 +{
1.136 + CBaseEntity *pEntity;
1.137 + edict_t *pEdict = GetEntity(params[1], &pEntity);
1.138 +
1.139 + if (pEdict == NULL || pEntity == NULL)
1.140 + {
1.141 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.142 + }
1.143 +
1.144 + int offset = params[2];
1.145 + if (offset <= 0 || offset > 32768)
1.146 + {
1.147 + return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.148 + }
1.149 +
1.150 + CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
1.151 +
1.152 + return CheckBaseHandle(hndl);
1.153 +}
1.154 +
1.155 +/* THIS GUY IS DEPRECATED. */
1.156 static cell_t SetEntDataEnt(IPluginContext *pContext, const cell_t *params)
1.157 {
1.158 CBaseEntity *pEntity;
1.159 @@ -502,7 +567,7 @@
1.160 }
1.161
1.162 int offset = params[2];
1.163 - if (offset < 0 || offset > 32768)
1.164 + if (offset <= 0 || offset > 32768)
1.165 {
1.166 return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.167 }
1.168 @@ -530,6 +595,47 @@
1.169 return 1;
1.170 }
1.171
1.172 +static cell_t SetEntDataEnt2(IPluginContext *pContext, const cell_t *params)
1.173 +{
1.174 + CBaseEntity *pEntity;
1.175 + edict_t *pEdict = GetEntity(params[1], &pEntity);
1.176 +
1.177 + if (!pEdict || !pEntity)
1.178 + {
1.179 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.180 + }
1.181 +
1.182 + int offset = params[2];
1.183 + if (offset <= 0 || offset > 32768)
1.184 + {
1.185 + return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.186 + }
1.187 +
1.188 + CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
1.189 +
1.190 + if (params[3] == -1)
1.191 + {
1.192 + hndl.Set(NULL);
1.193 + }
1.194 + else
1.195 + {
1.196 + edict_t *pEdict = GetEdict(params[3]);
1.197 + if (!pEdict)
1.198 + {
1.199 + return pContext->ThrowNativeError("Entity %d is invalid", params[3]);
1.200 + }
1.201 + IServerEntity *pEntOther = pEdict->GetIServerEntity();
1.202 + hndl.Set(pEntOther);
1.203 + }
1.204 +
1.205 + if (params[4])
1.206 + {
1.207 + g_HL2.SetEdictStateChanged(pEdict, offset);
1.208 + }
1.209 +
1.210 + return 1;
1.211 +}
1.212 +
1.213 static cell_t ChangeEdictState(IPluginContext *pContext, const cell_t *params)
1.214 {
1.215 edict_t *pEdict = GetEdict(params[1]);
1.216 @@ -560,6 +666,59 @@
1.217 return pSend->GetOffset();
1.218 }
1.219
1.220 +static cell_t FindSendPropInfo(IPluginContext *pContext, const cell_t *params)
1.221 +{
1.222 + char *cls, *prop;
1.223 + sm_sendprop_info_t info;
1.224 + cell_t *pType, *pBits, *pLocal;
1.225 +
1.226 + pContext->LocalToString(params[1], &cls);
1.227 + pContext->LocalToString(params[2], &prop);
1.228 +
1.229 + if (!g_HL2.FindSendPropInfo(cls, prop, &info))
1.230 + {
1.231 + return -1;
1.232 + }
1.233 +
1.234 + pContext->LocalToPhysAddr(params[3], &pType);
1.235 + pContext->LocalToPhysAddr(params[4], &pBits);
1.236 + pContext->LocalToPhysAddr(params[5], &pLocal);
1.237 +
1.238 + switch (info.prop->GetType())
1.239 + {
1.240 + case DPT_Int:
1.241 + {
1.242 + *pType = PropField_Integer;
1.243 + break;
1.244 + }
1.245 + case DPT_Float:
1.246 + {
1.247 + *pType = PropField_Float;
1.248 + break;
1.249 + }
1.250 + case DPT_String:
1.251 + {
1.252 + *pType = PropField_String;
1.253 + break;
1.254 + }
1.255 + case DPT_Vector:
1.256 + {
1.257 + *pType = PropField_Vector;
1.258 + break;
1.259 + }
1.260 + default:
1.261 + {
1.262 + *pType = PropField_Unsupported;
1.263 + break;
1.264 + }
1.265 + }
1.266 +
1.267 + *pBits = info.prop->m_nBits;
1.268 + *pLocal = info.prop->GetOffset();
1.269 +
1.270 + return info.actual_offset;
1.271 +}
1.272 +
1.273 static cell_t FindDataMapOffs(IPluginContext *pContext, const cell_t *params)
1.274 {
1.275 CBaseEntity *pEntity;
1.276 @@ -584,6 +743,79 @@
1.277 return -1;
1.278 }
1.279
1.280 + if (params[0] == 4)
1.281 + {
1.282 + cell_t *pType, *pSize;
1.283 +
1.284 + pContext->LocalToPhysAddr(params[3], &pType);
1.285 + pContext->LocalToPhysAddr(params[4], &pSize);
1.286 +
1.287 + switch (td->fieldType)
1.288 + {
1.289 + case FIELD_TICK:
1.290 + case FIELD_MODELINDEX:
1.291 + case FIELD_MATERIALINDEX:
1.292 + case FIELD_INTEGER:
1.293 + case FIELD_COLOR32:
1.294 + {
1.295 + *pType = PropField_Integer;
1.296 + *pSize = 32;
1.297 + break;
1.298 + }
1.299 + case FIELD_VECTOR:
1.300 + case FIELD_POSITION_VECTOR:
1.301 + {
1.302 + *pType = PropField_Vector;
1.303 + *pSize = 12;
1.304 + break;
1.305 + }
1.306 + case FIELD_SHORT:
1.307 + {
1.308 + *pType = PropField_Integer;
1.309 + *pSize = 16;
1.310 + break;
1.311 + }
1.312 + case FIELD_BOOLEAN:
1.313 + {
1.314 + *pType = PropField_Integer;
1.315 + *pSize = 1;
1.316 + break;
1.317 + }
1.318 + case FIELD_CHARACTER:
1.319 + {
1.320 + if (td->fieldSize == 1)
1.321 + {
1.322 + *pType = PropField_Integer;
1.323 + *pSize = 8;
1.324 + }
1.325 + else
1.326 + {
1.327 + *pType = PropField_String;
1.328 + *pSize = 8 * td->fieldSize;
1.329 + }
1.330 + break;
1.331 + }
1.332 + case FIELD_FLOAT:
1.333 + case FIELD_TIME:
1.334 + {
1.335 + *pType = PropField_Float;
1.336 + *pSize = 32;
1.337 + break;
1.338 + }
1.339 + case FIELD_EHANDLE:
1.340 + {
1.341 + *pType = PropField_Entity;
1.342 + *pSize = 32;
1.343 + break;
1.344 + }
1.345 + default:
1.346 + {
1.347 + *pType = PropField_Unsupported;
1.348 + *pSize = 0;
1.349 + }
1.350 + }
1.351 + }
1.352 +
1.353 return td->fieldOffset[TD_OFFSET_NORMAL];
1.354 }
1.355
1.356 @@ -640,59 +872,764 @@
1.357 return len;
1.358 }
1.359
1.360 -static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
1.361 +#define FIND_PROP_DATA(td) \
1.362 + datamap_t *pMap; \
1.363 + if ((pMap = CBaseEntity_GetDataDescMap(pEntity)) == NULL) \
1.364 + { \
1.365 + return pContext->ThrowNativeError("Could not retrieve datamap"); \
1.366 + } \
1.367 + if ((td = g_HL2.FindInDataMap(pMap, prop)) == NULL) \
1.368 + { \
1.369 + return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
1.370 + prop, \
1.371 + params[1], \
1.372 + class_name); \
1.373 + }
1.374 +
1.375 +#define FIND_PROP_SEND(pProp) \
1.376 + IServerNetworkable *pNet = pEdict->GetNetworkable(); \
1.377 + if (!pNet) \
1.378 + { \
1.379 + return pContext->ThrowNativeError("Edict %d is not networkable", params[1]); \
1.380 + } \
1.381 + if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, pProp)) \
1.382 + { \
1.383 + return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
1.384 + prop, \
1.385 + params[1], \
1.386 + class_name); \
1.387 + }
1.388 +
1.389 +inline int MatchFieldAsInteger(int field_type)
1.390 +{
1.391 + switch (field_type)
1.392 + {
1.393 + case FIELD_TICK:
1.394 + case FIELD_MODELINDEX:
1.395 + case FIELD_MATERIALINDEX:
1.396 + case FIELD_INTEGER:
1.397 + case FIELD_COLOR32:
1.398 + return 32;
1.399 + case FIELD_SHORT:
1.400 + return 16;
1.401 + case FIELD_CHARACTER:
1.402 + return 8;
1.403 + case FIELD_BOOLEAN:
1.404 + return 1;
1.405 + default:
1.406 + return 0;
1.407 + }
1.408 +
1.409 + return 0;
1.410 +}
1.411 +
1.412 +static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
1.413 +{
1.414 + CBaseEntity *pEntity;
1.415 + char *prop;
1.416 + int offset;
1.417 + const char *class_name;
1.418 + edict_t *pEdict;
1.419 + int bit_count;
1.420 +
1.421 + pEdict = GetEntity(params[1], &pEntity);
1.422 +
1.423 + if (!pEdict || !pEntity)
1.424 + {
1.425 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.426 + }
1.427 +
1.428 + if ((class_name = pEdict->GetClassName()) == NULL)
1.429 + {
1.430 + class_name = "";
1.431 + }
1.432 +
1.433 + pContext->LocalToString(params[3], &prop);
1.434 +
1.435 + switch (params[2])
1.436 + {
1.437 + case Prop_Data:
1.438 + {
1.439 + typedescription_t *td;
1.440 +
1.441 + FIND_PROP_DATA(td);
1.442 +
1.443 + if ((bit_count = MatchFieldAsInteger(td->fieldType)) == 0)
1.444 + {
1.445 + return pContext->ThrowNativeError("Data field %s is not an integer (%d)",
1.446 + prop,
1.447 + td->fieldType);
1.448 + }
1.449 +
1.450 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.451 + break;
1.452 + }
1.453 + case Prop_Send:
1.454 + {
1.455 + sm_sendprop_info_t info;
1.456 +
1.457 + FIND_PROP_SEND(&info);
1.458 +
1.459 + if (info.prop->GetType() != DPT_Int)
1.460 + {
1.461 + return pContext->ThrowNativeError("SendProp %s is not an integer ([%d,%d] != %d)",
1.462 + prop,
1.463 + info.prop->GetType(),
1.464 + info.prop->m_nBits,
1.465 + DPT_Int);
1.466 + }
1.467 +
1.468 + bit_count = info.prop->m_nBits;
1.469 + offset = info.actual_offset;
1.470 + break;
1.471 + }
1.472 + default:
1.473 + {
1.474 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.475 + }
1.476 + }
1.477 +
1.478 + if (bit_count < 1)
1.479 + {
1.480 + bit_count = params[4] * 8;
1.481 + }
1.482 +
1.483 + if (bit_count >= 17)
1.484 + {
1.485 + return *(int32_t *)((uint8_t *)pEntity + offset);
1.486 + }
1.487 + else if (bit_count >= 9)
1.488 + {
1.489 + return *(int16_t *)((uint8_t *)pEntity + offset);
1.490 + }
1.491 + else if (bit_count >= 2)
1.492 + {
1.493 + return *(int8_t *)((uint8_t *)pEntity + offset);
1.494 + }
1.495 + else
1.496 + {
1.497 + return *(bool *)((uint8_t *)pEntity + offset) ? 1 : 0;
1.498 + }
1.499 +
1.500 + return 0;
1.501 +}
1.502 +
1.503 +static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
1.504 {
1.505 CBaseEntity *pEntity;
1.506 char *prop;
1.507 int offset;
1.508 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.509 + const char *class_name;
1.510 + edict_t *pEdict;
1.511 + int bit_count;
1.512 +
1.513 + pEdict = GetEntity(params[1], &pEntity);
1.514 +
1.515 + if (!pEdict || !pEntity)
1.516 + {
1.517 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.518 + }
1.519 +
1.520 + if ((class_name = pEdict->GetClassName()) == NULL)
1.521 + {
1.522 + class_name = "";
1.523 + }
1.524 +
1.525 + pContext->LocalToString(params[3], &prop);
1.526 +
1.527 + switch (params[2])
1.528 + {
1.529 + case Prop_Data:
1.530 + {
1.531 + typedescription_t *td;
1.532 +
1.533 + FIND_PROP_DATA(td);
1.534 +
1.535 + if ((bit_count = MatchFieldAsInteger(td->fieldType)) == 0)
1.536 + {
1.537 + return pContext->ThrowNativeError("Data field %s is not an integer (%d)",
1.538 + prop,
1.539 + td->fieldType);
1.540 + }
1.541 +
1.542 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.543 + break;
1.544 + }
1.545 + case Prop_Send:
1.546 + {
1.547 + sm_sendprop_info_t info;
1.548 +
1.549 + FIND_PROP_SEND(&info);
1.550 +
1.551 + if (info.prop->GetType() != DPT_Int)
1.552 + {
1.553 + return pContext->ThrowNativeError("SendProp %s is not an integer ([%d,%d] != %d)",
1.554 + prop,
1.555 + info.prop->GetType(),
1.556 + info.prop->m_nBits,
1.557 + DPT_Int);
1.558 + }
1.559 +
1.560 + bit_count = info.prop->m_nBits;
1.561 + offset = info.actual_offset;
1.562 + break;
1.563 + }
1.564 + default:
1.565 + {
1.566 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.567 + }
1.568 + }
1.569 +
1.570 + if (bit_count < 1)
1.571 + {
1.572 + bit_count = params[5] * 8;
1.573 + }
1.574 +
1.575 + if (bit_count >= 17)
1.576 + {
1.577 + *(int32_t *)((uint8_t *)pEntity + offset) = params[4];
1.578 + }
1.579 + else if (bit_count >= 9)
1.580 + {
1.581 + *(int16_t *)((uint8_t *)pEntity + offset) = (int16_t)params[4];
1.582 + }
1.583 + else if (bit_count >= 2)
1.584 + {
1.585 + *(int8_t *)((uint8_t *)pEntity + offset) = (int8_t)params[4];
1.586 + }
1.587 + else
1.588 + {
1.589 + *(bool *)((uint8_t *)pEntity + offset) = params[4] ? true : false;
1.590 + }
1.591 +
1.592 + return 0;
1.593 +}
1.594 +
1.595 +static cell_t GetEntPropFloat(IPluginContext *pContext, const cell_t *params)
1.596 +{
1.597 + CBaseEntity *pEntity;
1.598 + char *prop;
1.599 + int offset;
1.600 + const char *class_name;
1.601 + edict_t *pEdict;
1.602 +
1.603 + pEdict = GetEntity(params[1], &pEntity);
1.604 +
1.605 + if (!pEdict || !pEntity)
1.606 + {
1.607 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.608 + }
1.609 +
1.610 + if ((class_name = pEdict->GetClassName()) == NULL)
1.611 + {
1.612 + class_name = "";
1.613 + }
1.614 +
1.615 + pContext->LocalToString(params[3], &prop);
1.616 +
1.617 + switch (params[2])
1.618 + {
1.619 + case Prop_Data:
1.620 + {
1.621 + typedescription_t *td;
1.622 +
1.623 + FIND_PROP_DATA(td);
1.624 +
1.625 + if (td->fieldType != FIELD_FLOAT
1.626 + && td->fieldType != FIELD_TIME)
1.627 + {
1.628 + return pContext->ThrowNativeError("Data field %s is not a float (%d != [%d,%d])",
1.629 + prop,
1.630 + td->fieldType,
1.631 + FIELD_FLOAT,
1.632 + FIELD_TIME);
1.633 + }
1.634 +
1.635 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.636 + break;
1.637 + }
1.638 + case Prop_Send:
1.639 + {
1.640 + sm_sendprop_info_t info;
1.641 +
1.642 + FIND_PROP_SEND(&info);
1.643 +
1.644 + if (info.prop->GetType() != DPT_Float)
1.645 + {
1.646 + return pContext->ThrowNativeError("SendProp %s is not a float (%d != %d)",
1.647 + prop,
1.648 + info.prop->GetType(),
1.649 + DPT_Float);
1.650 + }
1.651 +
1.652 + offset = info.actual_offset;
1.653 + break;
1.654 + }
1.655 + default:
1.656 + {
1.657 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.658 + }
1.659 + }
1.660 +
1.661 + float val = *(float *)((uint8_t *)pEntity + offset);
1.662 +
1.663 + return sp_ftoc(val);
1.664 +}
1.665 +
1.666 +static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
1.667 +{
1.668 + CBaseEntity *pEntity;
1.669 + char *prop;
1.670 + int offset;
1.671 + const char *class_name;
1.672 + edict_t *pEdict;
1.673 +
1.674 + pEdict = GetEntity(params[1], &pEntity);
1.675
1.676 if (!pEdict || !pEntity)
1.677 {
1.678 return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.679 }
1.680
1.681 + if ((class_name = pEdict->GetClassName()) == NULL)
1.682 + {
1.683 + class_name = "";
1.684 + }
1.685 +
1.686 + pContext->LocalToString(params[3], &prop);
1.687 +
1.688 switch (params[2])
1.689 {
1.690 case Prop_Data:
1.691 {
1.692 - datamap_t *pMap;
1.693 typedescription_t *td;
1.694 - if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
1.695 +
1.696 + FIND_PROP_DATA(td);
1.697 +
1.698 + if (td->fieldType != FIELD_FLOAT
1.699 + && td->fieldType != FIELD_TIME)
1.700 {
1.701 - return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
1.702 + return pContext->ThrowNativeError("Data field %s is not a float (%d != [%d,%d])",
1.703 + prop,
1.704 + td->fieldType,
1.705 + FIELD_FLOAT,
1.706 + FIELD_TIME);
1.707 + }
1.708 +
1.709 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.710 + break;
1.711 + }
1.712 + case Prop_Send:
1.713 + {
1.714 + sm_sendprop_info_t info;
1.715 +
1.716 + FIND_PROP_SEND(&info);
1.717 +
1.718 + if (info.prop->GetType() != DPT_Float)
1.719 + {
1.720 + return pContext->ThrowNativeError("SendProp %s is not a float (%d != %d)",
1.721 + prop,
1.722 + info.prop->GetType(),
1.723 + DPT_Float);
1.724 }
1.725 - pContext->LocalToString(params[3], &prop);
1.726 - if ((td=g_HL2.FindInDataMap(pMap, prop)) == NULL)
1.727 +
1.728 + offset = info.actual_offset;
1.729 + break;
1.730 + }
1.731 + default:
1.732 + {
1.733 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.734 + }
1.735 + }
1.736 +
1.737 + *(float *)((uint8_t *)pEntity + offset) = sp_ctof(params[4]);
1.738 +
1.739 + if (params[2] == Prop_Send)
1.740 + {
1.741 + g_HL2.SetEdictStateChanged(pEdict, offset);
1.742 + }
1.743 +
1.744 + return 1;
1.745 +}
1.746 +
1.747 +static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
1.748 +{
1.749 + CBaseEntity *pEntity;
1.750 + char *prop;
1.751 + int offset;
1.752 + const char *class_name;
1.753 + edict_t *pEdict;
1.754 +
1.755 + pEdict = GetEntity(params[1], &pEntity);
1.756 +
1.757 + if (!pEdict || !pEntity)
1.758 + {
1.759 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.760 + }
1.761 +
1.762 + if ((class_name = pEdict->GetClassName()) == NULL)
1.763 + {
1.764 + class_name = "";
1.765 + }
1.766 +
1.767 + pContext->LocalToString(params[3], &prop);
1.768 +
1.769 + switch (params[2])
1.770 + {
1.771 + case Prop_Data:
1.772 + {
1.773 + typedescription_t *td;
1.774 +
1.775 + FIND_PROP_DATA(td);
1.776 +
1.777 + if (td->fieldType != FIELD_EHANDLE)
1.778 {
1.779 - return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.780 + return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)",
1.781 + prop,
1.782 + td->fieldType,
1.783 + FIELD_EHANDLE);
1.784 }
1.785 - if (td->fieldType != FIELD_CHARACTER)
1.786 +
1.787 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.788 + break;
1.789 + }
1.790 + case Prop_Send:
1.791 + {
1.792 + sm_sendprop_info_t info;
1.793 +
1.794 + FIND_PROP_SEND(&info);
1.795 +
1.796 + if (info.prop->GetType() != DPT_Int)
1.797 {
1.798 - return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.799 + return pContext->ThrowNativeError("SendProp %s is not an integer (%d != %d)",
1.800 + prop,
1.801 + info.prop->GetType(),
1.802 + DPT_Int);
1.803 }
1.804 +
1.805 + offset = info.actual_offset;
1.806 + break;
1.807 + }
1.808 + default:
1.809 + {
1.810 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.811 + }
1.812 + }
1.813 +
1.814 + CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
1.815 +
1.816 + return CheckBaseHandle(hndl);
1.817 +}
1.818 +
1.819 +static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
1.820 +{
1.821 + CBaseEntity *pEntity;
1.822 + char *prop;
1.823 + int offset;
1.824 + const char *class_name;
1.825 + edict_t *pEdict;
1.826 +
1.827 + pEdict = GetEntity(params[1], &pEntity);
1.828 +
1.829 + if (!pEdict || !pEntity)
1.830 + {
1.831 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.832 + }
1.833 +
1.834 + if ((class_name = pEdict->GetClassName()) == NULL)
1.835 + {
1.836 + class_name = "";
1.837 + }
1.838 +
1.839 + pContext->LocalToString(params[3], &prop);
1.840 +
1.841 + switch (params[2])
1.842 + {
1.843 + case Prop_Data:
1.844 + {
1.845 + typedescription_t *td;
1.846 +
1.847 + FIND_PROP_DATA(td);
1.848 +
1.849 + if (td->fieldType != FIELD_EHANDLE)
1.850 + {
1.851 + return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)",
1.852 + prop,
1.853 + td->fieldType,
1.854 + FIELD_EHANDLE);
1.855 + }
1.856 +
1.857 offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.858 break;
1.859 }
1.860 case Prop_Send:
1.861 {
1.862 - char *prop;
1.863 - IServerNetworkable *pNet = pEdict->GetNetworkable();
1.864 - if (!pNet)
1.865 + sm_sendprop_info_t info;
1.866 +
1.867 + FIND_PROP_SEND(&info);
1.868 +
1.869 + if (info.prop->GetType() != DPT_Int)
1.870 {
1.871 - return pContext->ThrowNativeError("The edict is not networkable");
1.872 + return pContext->ThrowNativeError("SendProp %s is not an integer (%d != %d)",
1.873 + prop,
1.874 + info.prop->GetType(),
1.875 + DPT_Int);
1.876 + }
1.877 +
1.878 + offset = info.actual_offset;
1.879 + break;
1.880 + }
1.881 + default:
1.882 + {
1.883 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.884 + }
1.885 + }
1.886 +
1.887 + CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
1.888 +
1.889 + if (params[4] == -1)
1.890 + {
1.891 + hndl.Set(NULL);
1.892 + }
1.893 + else
1.894 + {
1.895 + edict_t *pOther;
1.896 + CBaseEntity *pOtherEnt;
1.897 +
1.898 + if ((pOther = GetEntity(params[4], &pOtherEnt)) == NULL)
1.899 + {
1.900 + return pContext->ThrowNativeError("Invalid entity %d", params[4]);
1.901 + }
1.902 +
1.903 + hndl.Set(pOther->GetIServerEntity());
1.904 + }
1.905 +
1.906 + if (params[2] == Prop_Send)
1.907 + {
1.908 + g_HL2.SetEdictStateChanged(pEdict, offset);
1.909 + }
1.910 +
1.911 + return 1;
1.912 +}
1.913 +
1.914 +static cell_t GetEntPropVector(IPluginContext *pContext, const cell_t *params)
1.915 +{
1.916 + CBaseEntity *pEntity;
1.917 + char *prop;
1.918 + int offset;
1.919 + const char *class_name;
1.920 + edict_t *pEdict;
1.921 +
1.922 + pEdict = GetEntity(params[1], &pEntity);
1.923 +
1.924 + if (!pEdict || !pEntity)
1.925 + {
1.926 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.927 + }
1.928 +
1.929 + if ((class_name = pEdict->GetClassName()) == NULL)
1.930 + {
1.931 + class_name = "";
1.932 + }
1.933 +
1.934 + pContext->LocalToString(params[3], &prop);
1.935 +
1.936 + switch (params[2])
1.937 + {
1.938 + case Prop_Data:
1.939 + {
1.940 + typedescription_t *td;
1.941 +
1.942 + FIND_PROP_DATA(td);
1.943 +
1.944 + if (td->fieldType != FIELD_VECTOR
1.945 + && td->fieldType != FIELD_POSITION_VECTOR)
1.946 + {
1.947 + return pContext->ThrowNativeError("Data field %s is not a vector (%d != [%d,%d])",
1.948 + prop,
1.949 + td->fieldType,
1.950 + FIELD_VECTOR,
1.951 + FIELD_POSITION_VECTOR);
1.952 + }
1.953 +
1.954 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.955 + break;
1.956 + }
1.957 + case Prop_Send:
1.958 + {
1.959 + sm_sendprop_info_t info;
1.960 +
1.961 + FIND_PROP_SEND(&info);
1.962 +
1.963 + if (info.prop->GetType() != DPT_Vector)
1.964 + {
1.965 + return pContext->ThrowNativeError("SendProp %s is not a vector (%d != %d)",
1.966 + prop,
1.967 + info.prop->GetType(),
1.968 + DPT_Vector);
1.969 }
1.970 - pContext->LocalToString(params[3], &prop);
1.971 - SendProp *pSend = g_HL2.FindInSendTable(pNet->GetServerClass()->GetName(), prop);
1.972 - if (!pSend)
1.973 +
1.974 + offset = info.actual_offset;
1.975 + break;
1.976 + }
1.977 + default:
1.978 + {
1.979 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.980 + }
1.981 + }
1.982 +
1.983 + Vector *v = (Vector *)((uint8_t *)pEntity + offset);
1.984 +
1.985 + cell_t *vec;
1.986 + pContext->LocalToPhysAddr(params[4], &vec);
1.987 +
1.988 + vec[0] = sp_ftoc(v->x);
1.989 + vec[1] = sp_ftoc(v->y);
1.990 + vec[2] = sp_ftoc(v->z);
1.991 +
1.992 + return 1;
1.993 +}
1.994 +
1.995 +static cell_t SetEntPropVector(IPluginContext *pContext, const cell_t *params)
1.996 +{
1.997 + CBaseEntity *pEntity;
1.998 + char *prop;
1.999 + int offset;
1.1000 + const char *class_name;
1.1001 + edict_t *pEdict;
1.1002 +
1.1003 + pEdict = GetEntity(params[1], &pEntity);
1.1004 +
1.1005 + if (!pEdict || !pEntity)
1.1006 + {
1.1007 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.1008 + }
1.1009 +
1.1010 + if ((class_name = pEdict->GetClassName()) == NULL)
1.1011 + {
1.1012 + class_name = "";
1.1013 + }
1.1014 +
1.1015 + pContext->LocalToString(params[3], &prop);
1.1016 +
1.1017 + switch (params[2])
1.1018 + {
1.1019 + case Prop_Data:
1.1020 + {
1.1021 + typedescription_t *td;
1.1022 +
1.1023 + FIND_PROP_DATA(td);
1.1024 +
1.1025 + if (td->fieldType != FIELD_VECTOR
1.1026 + && td->fieldType != FIELD_POSITION_VECTOR)
1.1027 {
1.1028 - return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.1029 + return pContext->ThrowNativeError("Data field %s is not a vector (%d != [%d,%d])",
1.1030 + prop,
1.1031 + td->fieldType,
1.1032 + FIELD_VECTOR,
1.1033 + FIELD_POSITION_VECTOR);
1.1034 + }
1.1035 +
1.1036 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.1037 + break;
1.1038 + }
1.1039 + case Prop_Send:
1.1040 + {
1.1041 + sm_sendprop_info_t info;
1.1042 +
1.1043 + FIND_PROP_SEND(&info);
1.1044 +
1.1045 + if (info.prop->GetType() != DPT_Vector)
1.1046 + {
1.1047 + return pContext->ThrowNativeError("SendProp %s is not a vector (%d != %d)",
1.1048 + prop,
1.1049 + info.prop->GetType(),
1.1050 + DPT_Vector);
1.1051 }
1.1052 - if (pSend->GetType() != DPT_String)
1.1053 +
1.1054 + offset = info.actual_offset;
1.1055 + break;
1.1056 + }
1.1057 + default:
1.1058 + {
1.1059 + return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.1060 + }
1.1061 + }
1.1062 +
1.1063 + Vector *v = (Vector *)((uint8_t *)pEntity + offset);
1.1064 +
1.1065 + cell_t *vec;
1.1066 + pContext->LocalToPhysAddr(params[4], &vec);
1.1067 +
1.1068 + v->x = sp_ctof(vec[0]);
1.1069 + v->y = sp_ctof(vec[1]);
1.1070 + v->z = sp_ctof(vec[2]);
1.1071 +
1.1072 + if (params[2] == Prop_Send)
1.1073 + {
1.1074 + g_HL2.SetEdictStateChanged(pEdict, offset);
1.1075 + }
1.1076 +
1.1077 + return 1;
1.1078 +}
1.1079 +
1.1080 +static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
1.1081 +{
1.1082 + CBaseEntity *pEntity;
1.1083 + char *prop;
1.1084 + int offset;
1.1085 + const char *class_name;
1.1086 + edict_t *pEdict;
1.1087 +
1.1088 + pEdict = GetEntity(params[1], &pEntity);
1.1089 +
1.1090 + if (!pEdict || !pEntity)
1.1091 + {
1.1092 + return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.1093 + }
1.1094 +
1.1095 + if ((class_name = pEdict->GetClassName()) == NULL)
1.1096 + {
1.1097 + class_name = "";
1.1098 + }
1.1099 +
1.1100 + pContext->LocalToString(params[3], &prop);
1.1101 +
1.1102 + switch (params[2])
1.1103 + {
1.1104 + case Prop_Data:
1.1105 + {
1.1106 + typedescription_t *td;
1.1107 +
1.1108 + FIND_PROP_DATA(td);
1.1109 +
1.1110 + if (td->fieldType != FIELD_CHARACTER)
1.1111 {
1.1112 - return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.1113 + return pContext->ThrowNativeError("Data field %s is not a string (%d != %d)",
1.1114 + prop,
1.1115 + td->fieldType,
1.1116 + FIELD_CHARACTER);
1.1117 }
1.1118 - offset = pSend->GetOffset();
1.1119 +
1.1120 + offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.1121 + break;
1.1122 + }
1.1123 + case Prop_Send:
1.1124 + {
1.1125 + sm_sendprop_info_t info;
1.1126 +
1.1127 + FIND_PROP_SEND(&info);
1.1128 +
1.1129 + if (info.prop->GetType() != DPT_String)
1.1130 + {
1.1131 + return pContext->ThrowNativeError("SendProp %s is not a string (%d != %d)",
1.1132 + prop,
1.1133 + info.prop->GetType(),
1.1134 + DPT_String);
1.1135 + }
1.1136 +
1.1137 + offset = info.actual_offset;
1.1138 + break;
1.1139 break;
1.1140 }
1.1141 default:
1.1142 @@ -714,7 +1651,6 @@
1.1143 char *prop;
1.1144 int offset;
1.1145 int maxlen;
1.1146 - bool is_sendprop = false;
1.1147 edict_t *pEdict = GetEntity(params[1], &pEntity);
1.1148
1.1149 if (!pEdict || !pEntity)
1.1150 @@ -765,7 +1701,6 @@
1.1151 }
1.1152 offset = pSend->GetOffset();
1.1153 maxlen = DT_MAX_STRING_BUFFERSIZE;
1.1154 - is_sendprop = true;
1.1155 break;
1.1156 }
1.1157 default:
1.1158 @@ -780,7 +1715,7 @@
1.1159 pContext->LocalToString(params[4], &src);
1.1160 size_t len = strncopy(dest, src, maxlen);
1.1161
1.1162 - if (is_sendprop)
1.1163 + if (params[2] == Prop_Send)
1.1164 {
1.1165 g_HL2.SetEdictStateChanged(pEdict, offset);
1.1166 }
1.1167 @@ -792,13 +1727,22 @@
1.1168 {
1.1169 {"ChangeEdictState", ChangeEdictState},
1.1170 {"CreateEdict", CreateEdict},
1.1171 + {"FindDataMapOffs", FindDataMapOffs},
1.1172 + {"FindSendPropInfo", FindSendPropInfo},
1.1173 {"FindSendPropOffs", FindSendPropOffs},
1.1174 {"GetEdictClassname", GetEdictClassname},
1.1175 {"GetEdictFlags", GetEdictFlags},
1.1176 {"GetEntData", GetEntData},
1.1177 - {"GetEntDataEnt", GetEntDataEnt},
1.1178 + {"GetEntDataEnt", GetEntDataEnt}, /** DEPRECATED */
1.1179 + {"GetEntDataEnt2", GetEntDataEnt2},
1.1180 {"GetEntDataFloat", GetEntDataFloat},
1.1181 + {"GetEntDataString", GetEntDataString},
1.1182 {"GetEntDataVector", GetEntDataVector},
1.1183 + {"GetEntProp", GetEntProp},
1.1184 + {"GetEntPropEnt", GetEntPropEnt},
1.1185 + {"GetEntPropFloat", GetEntPropFloat},
1.1186 + {"GetEntPropString", GetEntPropString},
1.1187 + {"GetEntPropVector", GetEntPropVector},
1.1188 {"GetEntityCount", GetEntityCount},
1.1189 {"GetEntityNetClass", GetEntityNetClass},
1.1190 {"GetMaxEntities", GetMaxEntities},
1.1191 @@ -808,13 +1752,15 @@
1.1192 {"RemoveEdict", RemoveEdict},
1.1193 {"SetEdictFlags", SetEdictFlags},
1.1194 {"SetEntData", SetEntData},
1.1195 - {"SetEntDataEnt", SetEntDataEnt},
1.1196 + {"SetEntDataEnt", SetEntDataEnt}, /** DEPRECATED */
1.1197 + {"SetEntDataEnt2", SetEntDataEnt2},
1.1198 {"SetEntDataFloat", SetEntDataFloat},
1.1199 {"SetEntDataVector", SetEntDataVector},
1.1200 - {"FindDataMapOffs", FindDataMapOffs},
1.1201 - {"GetEntDataString", GetEntDataString},
1.1202 {"SetEntDataString", SetEntDataString},
1.1203 - {"GetEntPropString", GetEntPropString},
1.1204 + {"SetEntProp", SetEntProp},
1.1205 + {"SetEntPropEnt", SetEntPropEnt},
1.1206 + {"SetEntPropFloat", SetEntPropFloat},
1.1207 {"SetEntPropString", SetEntPropString},
1.1208 + {"SetEntPropVector", SetEntPropVector},
1.1209 {NULL, NULL}
1.1210 };