1.1 --- a/core/smn_entities.cpp Fri Mar 28 06:21:34 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,820 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include "sm_globals.h"
1.36 -#include "sourcemod.h"
1.37 -#include "sourcemm_api.h"
1.38 -#include "server_class.h"
1.39 -#include "PlayerManager.h"
1.40 -#include "HalfLife2.h"
1.41 -#include "GameConfigs.h"
1.42 -#include "sm_stringutil.h"
1.43 -
1.44 -enum PropType
1.45 -{
1.46 - Prop_Send = 0,
1.47 - Prop_Data
1.48 -};
1.49 -
1.50 -inline edict_t *GetEdict(cell_t num)
1.51 -{
1.52 - edict_t *pEdict = engine->PEntityOfEntIndex(num);
1.53 - if (!pEdict || pEdict->IsFree())
1.54 - {
1.55 - return NULL;
1.56 - }
1.57 - if (num > 0 && num <= g_Players.GetMaxClients())
1.58 - {
1.59 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(num);
1.60 - if (!pPlayer || !pPlayer->IsConnected())
1.61 - {
1.62 - return NULL;
1.63 - }
1.64 - }
1.65 - return pEdict;
1.66 -}
1.67 -
1.68 -inline edict_t *GetEntity(cell_t num, CBaseEntity **pData)
1.69 -{
1.70 - edict_t *pEdict = engine->PEntityOfEntIndex(num);
1.71 - if (!pEdict || pEdict->IsFree())
1.72 - {
1.73 - return NULL;
1.74 - }
1.75 - if (num > 0 && num <= g_Players.GetMaxClients())
1.76 - {
1.77 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(num);
1.78 - if (!pPlayer || !pPlayer->IsConnected())
1.79 - {
1.80 - return NULL;
1.81 - }
1.82 - }
1.83 - IServerUnknown *pUnk;
1.84 - if ((pUnk=pEdict->GetUnknown()) == NULL)
1.85 - {
1.86 - return NULL;
1.87 - }
1.88 - *pData = pUnk->GetBaseEntity();
1.89 - return pEdict;
1.90 -}
1.91 -
1.92 -class VEmptyClass {};
1.93 -datamap_t *VGetDataDescMap(CBaseEntity *pThisPtr, int offset)
1.94 -{
1.95 - void **this_ptr = *reinterpret_cast<void ***>(&pThisPtr);
1.96 - void **vtable = *reinterpret_cast<void ***>(pThisPtr);
1.97 - void *vfunc = vtable[offset];
1.98 -
1.99 - union
1.100 - {
1.101 - datamap_t *(VEmptyClass::*mfpnew)();
1.102 -#ifndef PLATFORM_POSIX
1.103 - void *addr;
1.104 - } u;
1.105 - u.addr = vfunc;
1.106 -#else
1.107 - struct
1.108 - {
1.109 - void *addr;
1.110 - intptr_t adjustor;
1.111 - } s;
1.112 - } u;
1.113 - u.s.addr = vfunc;
1.114 - u.s.adjustor = 0;
1.115 -#endif
1.116 -
1.117 - return (datamap_t *)(reinterpret_cast<VEmptyClass *>(this_ptr)->*u.mfpnew)();
1.118 -}
1.119 -
1.120 -inline datamap_t *CBaseEntity_GetDataDescMap(CBaseEntity *pEntity)
1.121 -{
1.122 - int offset;
1.123 -
1.124 - if (!g_pGameConf->GetOffset("GetDataDescMap", &offset) || !offset)
1.125 - {
1.126 - return NULL;
1.127 - }
1.128 -
1.129 - return VGetDataDescMap(pEntity, offset);
1.130 -}
1.131 -
1.132 -/* :TODO: Move this! */
1.133 -datamap_t *CHalfLife2::GetDataMap(CBaseEntity *pEntity)
1.134 -{
1.135 - return CBaseEntity_GetDataDescMap(pEntity);
1.136 -}
1.137 -
1.138 -static cell_t GetMaxEntities(IPluginContext *pContext, const cell_t *params)
1.139 -{
1.140 - return gpGlobals->maxEntities;
1.141 -}
1.142 -
1.143 -static cell_t CreateEdict(IPluginContext *pContext, const cell_t *params)
1.144 -{
1.145 - edict_t *pEdict = engine->CreateEdict();
1.146 -
1.147 - if (!pEdict)
1.148 - {
1.149 - return 0;
1.150 - }
1.151 -
1.152 - return engine->IndexOfEdict(pEdict);
1.153 -}
1.154 -
1.155 -static cell_t RemoveEdict(IPluginContext *pContext, const cell_t *params)
1.156 -{
1.157 - edict_t *pEdict = engine->PEntityOfEntIndex(params[1]);
1.158 -
1.159 - if (!pEdict)
1.160 - {
1.161 - return pContext->ThrowNativeError("Edict %d is not a valid edict", params[1]);
1.162 - }
1.163 -
1.164 - engine->RemoveEdict(pEdict);
1.165 -
1.166 - return 1;
1.167 -}
1.168 -
1.169 -static cell_t IsValidEdict(IPluginContext *pContext, const cell_t *params)
1.170 -{
1.171 - edict_t *pEdict = GetEdict(params[1]);
1.172 -
1.173 - if (!pEdict)
1.174 - {
1.175 - return 0;
1.176 - }
1.177 -
1.178 - /* Shouldn't be necessary... not sure though */
1.179 - return pEdict->IsFree() ? 0 : 1;
1.180 -}
1.181 -
1.182 -static cell_t IsValidEntity(IPluginContext *pContext, const cell_t *params)
1.183 -{
1.184 - edict_t *pEdict = GetEdict(params[1]);
1.185 -
1.186 - if (!pEdict)
1.187 - {
1.188 - return 0;
1.189 - }
1.190 -
1.191 - IServerUnknown *pUnknown = pEdict->GetUnknown();
1.192 - if (!pUnknown)
1.193 - {
1.194 - return 0;
1.195 - }
1.196 -
1.197 - CBaseEntity *pEntity = pUnknown->GetBaseEntity();
1.198 - return (pEntity != NULL) ? 1 : 0;
1.199 -}
1.200 -
1.201 -static cell_t IsEntNetworkable(IPluginContext *pContext, const cell_t *params)
1.202 -{
1.203 - edict_t *pEdict = GetEdict(params[1]);
1.204 -
1.205 - if (!pEdict)
1.206 - {
1.207 - return 0;
1.208 - }
1.209 -
1.210 - return (pEdict->GetNetworkable() != NULL) ? 1 : 0;
1.211 -}
1.212 -
1.213 -static cell_t GetEntityCount(IPluginContext *pContext, const cell_t *params)
1.214 -{
1.215 - return engine->GetEntityCount();
1.216 -}
1.217 -
1.218 -static cell_t GetEdictFlags(IPluginContext *pContext, const cell_t *params)
1.219 -{
1.220 - edict_t *pEdict = GetEdict(params[1]);
1.221 -
1.222 - if (!pEdict)
1.223 - {
1.224 - return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
1.225 - }
1.226 -
1.227 - return pEdict->m_fStateFlags;
1.228 -}
1.229 -
1.230 -static cell_t SetEdictFlags(IPluginContext *pContext, const cell_t *params)
1.231 -{
1.232 - edict_t *pEdict = GetEdict(params[1]);
1.233 -
1.234 - if (!pEdict)
1.235 - {
1.236 - return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
1.237 - }
1.238 -
1.239 - pEdict->m_fStateFlags = params[2];
1.240 -
1.241 - return 1;
1.242 -}
1.243 -
1.244 -static cell_t GetEdictClassname(IPluginContext *pContext, const cell_t *params)
1.245 -{
1.246 - edict_t *pEdict = GetEdict(params[1]);
1.247 -
1.248 - if (!pEdict)
1.249 - {
1.250 - return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
1.251 - }
1.252 -
1.253 - const char *cls = pEdict->GetClassName();
1.254 -
1.255 - if (!cls || cls[0] == '\0')
1.256 - {
1.257 - return 0;
1.258 - }
1.259 -
1.260 - pContext->StringToLocal(params[2], params[3], cls);
1.261 -
1.262 - return 1;
1.263 -}
1.264 -
1.265 -static cell_t GetEntityNetClass(IPluginContext *pContext, const cell_t *params)
1.266 -{
1.267 - edict_t *pEdict = GetEdict(params[1]);
1.268 -
1.269 - if (!pEdict)
1.270 - {
1.271 - return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
1.272 - }
1.273 -
1.274 - IServerNetworkable *pNet = pEdict->GetNetworkable();
1.275 - if (!pNet)
1.276 - {
1.277 - return 0;
1.278 - }
1.279 -
1.280 - ServerClass *pClass = pNet->GetServerClass();
1.281 -
1.282 - pContext->StringToLocal(params[2], params[3], pClass->GetName());
1.283 -
1.284 - return 1;
1.285 -}
1.286 -
1.287 -static cell_t GetEntData(IPluginContext *pContext, const cell_t *params)
1.288 -{
1.289 - CBaseEntity *pEntity;
1.290 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.291 -
1.292 - if (!pEdict || !pEntity)
1.293 - {
1.294 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.295 - }
1.296 -
1.297 - int offset = params[2];
1.298 - if (offset < 0 || offset > 32768)
1.299 - {
1.300 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.301 - }
1.302 -
1.303 - switch (params[3])
1.304 - {
1.305 - case 4:
1.306 - return *(int *)((uint8_t *)pEntity + offset);
1.307 - case 2:
1.308 - return *(short *)((uint8_t *)pEntity + offset);
1.309 - case 1:
1.310 - return *((uint8_t *)pEntity + offset);
1.311 - default:
1.312 - return pContext->ThrowNativeError("Integer size %d is invalid", params[3]);
1.313 - }
1.314 -}
1.315 -
1.316 -static cell_t SetEntData(IPluginContext *pContext, const cell_t *params)
1.317 -{
1.318 - CBaseEntity *pEntity;
1.319 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.320 -
1.321 - if (!pEdict || !pEntity)
1.322 - {
1.323 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.324 - }
1.325 -
1.326 - int offset = params[2];
1.327 - if (offset < 0 || offset > 32768)
1.328 - {
1.329 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.330 - }
1.331 -
1.332 - if (params[5])
1.333 - {
1.334 - g_HL2.SetEdictStateChanged(pEdict, offset);
1.335 - }
1.336 -
1.337 - switch (params[4])
1.338 - {
1.339 - case 4:
1.340 - {
1.341 - *(int *)((uint8_t *)pEntity + offset) = params[3];
1.342 - break;
1.343 - }
1.344 - case 2:
1.345 - {
1.346 - *(short *)((uint8_t *)pEntity + offset) = params[3];
1.347 - break;
1.348 - }
1.349 - case 1:
1.350 - {
1.351 - *((uint8_t *)pEntity + offset) = params[3];
1.352 - break;
1.353 - }
1.354 - default:
1.355 - return pContext->ThrowNativeError("Integer size %d is invalid", params[4]);
1.356 - }
1.357 -
1.358 - return 1;
1.359 -}
1.360 -
1.361 -static cell_t GetEntDataFloat(IPluginContext *pContext, const cell_t *params)
1.362 -{
1.363 - CBaseEntity *pEntity;
1.364 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.365 -
1.366 - if (!pEdict || !pEntity)
1.367 - {
1.368 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.369 - }
1.370 -
1.371 - int offset = params[2];
1.372 - if (offset < 0 || offset > 32768)
1.373 - {
1.374 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.375 - }
1.376 -
1.377 - float f = *(float *)((uint8_t *)pEntity + offset);
1.378 -
1.379 - return sp_ftoc(f);
1.380 -}
1.381 -
1.382 -static cell_t SetEntDataFloat(IPluginContext *pContext, const cell_t *params)
1.383 -{
1.384 - CBaseEntity *pEntity;
1.385 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.386 -
1.387 - if (!pEdict || !pEntity)
1.388 - {
1.389 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.390 - }
1.391 -
1.392 - int offset = params[2];
1.393 - if (offset < 0 || offset > 32768)
1.394 - {
1.395 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.396 - }
1.397 -
1.398 - *(float *)((uint8_t *)pEntity + offset) = sp_ctof(params[3]);
1.399 -
1.400 - if (params[4])
1.401 - {
1.402 - g_HL2.SetEdictStateChanged(pEdict, offset);
1.403 - }
1.404 -
1.405 - return 1;
1.406 -}
1.407 -
1.408 -static cell_t GetEntDataVector(IPluginContext *pContext, const cell_t *params)
1.409 -{
1.410 - CBaseEntity *pEntity;
1.411 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.412 -
1.413 - if (!pEdict || !pEntity)
1.414 - {
1.415 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.416 - }
1.417 -
1.418 - int offset = params[2];
1.419 - if (offset < 0 || offset > 32768)
1.420 - {
1.421 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.422 - }
1.423 -
1.424 - Vector *v = (Vector *)((uint8_t *)pEntity + offset);
1.425 -
1.426 - cell_t *vec;
1.427 - pContext->LocalToPhysAddr(params[3], &vec);
1.428 -
1.429 - vec[0] = sp_ftoc(v->x);
1.430 - vec[1] = sp_ftoc(v->y);
1.431 - vec[2] = sp_ftoc(v->z);
1.432 -
1.433 - return 1;
1.434 -}
1.435 -
1.436 -static cell_t SetEntDataVector(IPluginContext *pContext, const cell_t *params)
1.437 -{
1.438 - CBaseEntity *pEntity;
1.439 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.440 -
1.441 - if (!pEdict || !pEntity)
1.442 - {
1.443 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.444 - }
1.445 -
1.446 - int offset = params[2];
1.447 - if (offset < 0 || offset > 32768)
1.448 - {
1.449 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.450 - }
1.451 -
1.452 - Vector *v = (Vector *)((uint8_t *)pEntity + offset);
1.453 -
1.454 - cell_t *vec;
1.455 - pContext->LocalToPhysAddr(params[3], &vec);
1.456 -
1.457 - v->x = sp_ctof(vec[0]);
1.458 - v->y = sp_ctof(vec[1]);
1.459 - v->z = sp_ctof(vec[2]);
1.460 -
1.461 - if (params[4])
1.462 - {
1.463 - g_HL2.SetEdictStateChanged(pEdict, offset);
1.464 - }
1.465 -
1.466 - return 1;
1.467 -}
1.468 -
1.469 -static cell_t GetEntDataEnt(IPluginContext *pContext, const cell_t *params)
1.470 -{
1.471 - CBaseEntity *pEntity;
1.472 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.473 -
1.474 - if (!pEdict || !pEntity)
1.475 - {
1.476 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.477 - }
1.478 -
1.479 - int offset = params[2];
1.480 - if (offset < 0 || offset > 32768)
1.481 - {
1.482 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.483 - }
1.484 -
1.485 - CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
1.486 -
1.487 - if (!hndl.IsValid())
1.488 - {
1.489 - return 0;
1.490 - }
1.491 -
1.492 - /* :TODO: check serial no.? */
1.493 -
1.494 - return hndl.GetEntryIndex();
1.495 -}
1.496 -
1.497 -static cell_t SetEntDataEnt(IPluginContext *pContext, const cell_t *params)
1.498 -{
1.499 - CBaseEntity *pEntity;
1.500 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.501 -
1.502 - if (!pEdict || !pEntity)
1.503 - {
1.504 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.505 - }
1.506 -
1.507 - int offset = params[2];
1.508 - if (offset < 0 || offset > 32768)
1.509 - {
1.510 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.511 - }
1.512 -
1.513 - CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
1.514 -
1.515 - if (params[3] == 0)
1.516 - {
1.517 - hndl.Set(NULL);
1.518 - } else {
1.519 - edict_t *pEdict = GetEdict(params[3]);
1.520 - if (!pEdict)
1.521 - {
1.522 - return pContext->ThrowNativeError("Entity %d is invalid", params[3]);
1.523 - }
1.524 - IServerEntity *pEntOther = pEdict->GetIServerEntity();
1.525 - hndl.Set(pEntOther);
1.526 - }
1.527 -
1.528 - if (params[4])
1.529 - {
1.530 - g_HL2.SetEdictStateChanged(pEdict, offset);
1.531 - }
1.532 -
1.533 - return 1;
1.534 -}
1.535 -
1.536 -static cell_t ChangeEdictState(IPluginContext *pContext, const cell_t *params)
1.537 -{
1.538 - edict_t *pEdict = GetEdict(params[1]);
1.539 -
1.540 - if (!pEdict)
1.541 - {
1.542 - return pContext->ThrowNativeError("Edict %d is invalid", params[1]);
1.543 - }
1.544 -
1.545 - g_HL2.SetEdictStateChanged(pEdict, params[2]);
1.546 -
1.547 - return 1;
1.548 -}
1.549 -
1.550 -static cell_t FindSendPropOffs(IPluginContext *pContext, const cell_t *params)
1.551 -{
1.552 - char *cls, *prop;
1.553 - pContext->LocalToString(params[1], &cls);
1.554 - pContext->LocalToString(params[2], &prop);
1.555 -
1.556 - SendProp *pSend = g_HL2.FindInSendTable(cls, prop);
1.557 -
1.558 - if (!pSend)
1.559 - {
1.560 - return -1;
1.561 - }
1.562 -
1.563 - return pSend->GetOffset();
1.564 -}
1.565 -
1.566 -static cell_t FindDataMapOffs(IPluginContext *pContext, const cell_t *params)
1.567 -{
1.568 - CBaseEntity *pEntity;
1.569 - datamap_t *pMap;
1.570 - typedescription_t *td;
1.571 - char *offset;
1.572 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.573 -
1.574 - if (!pEdict || !pEntity)
1.575 - {
1.576 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.577 - }
1.578 -
1.579 - if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
1.580 - {
1.581 - return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
1.582 - }
1.583 -
1.584 - pContext->LocalToString(params[2], &offset);
1.585 - if ((td=g_HL2.FindInDataMap(pMap, offset)) == NULL)
1.586 - {
1.587 - return -1;
1.588 - }
1.589 -
1.590 - return td->fieldOffset[TD_OFFSET_NORMAL];
1.591 -}
1.592 -
1.593 -static cell_t GetEntDataString(IPluginContext *pContext, const cell_t *params)
1.594 -{
1.595 - CBaseEntity *pEntity;
1.596 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.597 -
1.598 - if (!pEdict || !pEntity)
1.599 - {
1.600 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.601 - }
1.602 -
1.603 - int offset = params[2];
1.604 - if (offset < 0 || offset > 32768)
1.605 - {
1.606 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.607 - }
1.608 -
1.609 - size_t len;
1.610 - char *src = (char *)((uint8_t *)pEntity + offset);
1.611 - pContext->StringToLocalUTF8(params[3], params[4], src, &len);
1.612 -
1.613 - return len;
1.614 -}
1.615 -
1.616 -static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params)
1.617 -{
1.618 - CBaseEntity *pEntity;
1.619 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.620 -
1.621 - if (!pEdict || !pEntity)
1.622 - {
1.623 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.624 - }
1.625 -
1.626 - int offset = params[2];
1.627 - if (offset < 0 || offset > 32768)
1.628 - {
1.629 - return pContext->ThrowNativeError("Offset %d is invalid", offset);
1.630 - }
1.631 -
1.632 - char *src;
1.633 - char *dest = (char *)((uint8_t *)pEntity + offset);
1.634 -
1.635 - pContext->LocalToString(params[3], &src);
1.636 - size_t len = strncopy(dest, src, params[4]);
1.637 -
1.638 - if (params[5])
1.639 - {
1.640 - g_HL2.SetEdictStateChanged(pEdict, offset);
1.641 - }
1.642 -
1.643 - return len;
1.644 -}
1.645 -
1.646 -static cell_t GetEntPropString(IPluginContext *pContext, const cell_t *params)
1.647 -{
1.648 - CBaseEntity *pEntity;
1.649 - char *prop;
1.650 - int offset;
1.651 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.652 -
1.653 - if (!pEdict || !pEntity)
1.654 - {
1.655 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.656 - }
1.657 -
1.658 - switch (params[2])
1.659 - {
1.660 - case Prop_Data:
1.661 - {
1.662 - datamap_t *pMap;
1.663 - typedescription_t *td;
1.664 - if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
1.665 - {
1.666 - return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
1.667 - }
1.668 - pContext->LocalToString(params[3], &prop);
1.669 - if ((td=g_HL2.FindInDataMap(pMap, prop)) == NULL)
1.670 - {
1.671 - return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.672 - }
1.673 - if (td->fieldType != FIELD_CHARACTER)
1.674 - {
1.675 - return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.676 - }
1.677 - offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.678 - break;
1.679 - }
1.680 - case Prop_Send:
1.681 - {
1.682 - char *prop;
1.683 - IServerNetworkable *pNet = pEdict->GetNetworkable();
1.684 - if (!pNet)
1.685 - {
1.686 - return pContext->ThrowNativeError("The edict is not networkable");
1.687 - }
1.688 - pContext->LocalToString(params[3], &prop);
1.689 - SendProp *pSend = g_HL2.FindInSendTable(pNet->GetServerClass()->GetName(), prop);
1.690 - if (!pSend)
1.691 - {
1.692 - return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.693 - }
1.694 - if (pSend->GetType() != DPT_String)
1.695 - {
1.696 - return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.697 - }
1.698 - offset = pSend->GetOffset();
1.699 - break;
1.700 - }
1.701 - default:
1.702 - {
1.703 - return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.704 - }
1.705 - }
1.706 -
1.707 - size_t len;
1.708 - char *src = (char *)((uint8_t *)pEntity + offset);
1.709 - pContext->StringToLocalUTF8(params[4], params[5], src, &len);
1.710 -
1.711 - return len;
1.712 -}
1.713 -
1.714 -static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
1.715 -{
1.716 - CBaseEntity *pEntity;
1.717 - char *prop;
1.718 - int offset;
1.719 - int maxlen;
1.720 - bool is_sendprop = false;
1.721 - edict_t *pEdict = GetEntity(params[1], &pEntity);
1.722 -
1.723 - if (!pEdict || !pEntity)
1.724 - {
1.725 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
1.726 - }
1.727 -
1.728 - switch (params[2])
1.729 - {
1.730 - case Prop_Data:
1.731 - {
1.732 - datamap_t *pMap;
1.733 - typedescription_t *td;
1.734 - if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
1.735 - {
1.736 - return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
1.737 - }
1.738 - pContext->LocalToString(params[3], &prop);
1.739 - if ((td=g_HL2.FindInDataMap(pMap, prop)) == NULL)
1.740 - {
1.741 - return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.742 - }
1.743 - if (td->fieldType != FIELD_CHARACTER)
1.744 - {
1.745 - return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.746 - }
1.747 - offset = td->fieldOffset[TD_OFFSET_NORMAL];
1.748 - maxlen = td->fieldSize;
1.749 - break;
1.750 - }
1.751 - case Prop_Send:
1.752 - {
1.753 - char *prop;
1.754 - IServerNetworkable *pNet = pEdict->GetNetworkable();
1.755 - if (!pNet)
1.756 - {
1.757 - return pContext->ThrowNativeError("The edict is not networkable");
1.758 - }
1.759 - pContext->LocalToString(params[3], &prop);
1.760 - SendProp *pSend = g_HL2.FindInSendTable(pNet->GetServerClass()->GetName(), prop);
1.761 - if (!pSend)
1.762 - {
1.763 - return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
1.764 - }
1.765 - if (pSend->GetType() != DPT_String)
1.766 - {
1.767 - return pContext->ThrowNativeError("Property \"%s\" is not a valid string", prop);
1.768 - }
1.769 - offset = pSend->GetOffset();
1.770 - maxlen = DT_MAX_STRING_BUFFERSIZE;
1.771 - is_sendprop = true;
1.772 - break;
1.773 - }
1.774 - default:
1.775 - {
1.776 - return pContext->ThrowNativeError("Invalid Property type %d", params[2]);
1.777 - }
1.778 - }
1.779 -
1.780 - char *src;
1.781 - char *dest = (char *)((uint8_t *)pEntity + offset);
1.782 -
1.783 - pContext->LocalToString(params[4], &src);
1.784 - size_t len = strncopy(dest, src, maxlen);
1.785 -
1.786 - if (is_sendprop)
1.787 - {
1.788 - g_HL2.SetEdictStateChanged(pEdict, offset);
1.789 - }
1.790 -
1.791 - return len;
1.792 -}
1.793 -
1.794 -REGISTER_NATIVES(entityNatives)
1.795 -{
1.796 - {"ChangeEdictState", ChangeEdictState},
1.797 - {"CreateEdict", CreateEdict},
1.798 - {"FindSendPropOffs", FindSendPropOffs},
1.799 - {"GetEdictClassname", GetEdictClassname},
1.800 - {"GetEdictFlags", GetEdictFlags},
1.801 - {"GetEntData", GetEntData},
1.802 - {"GetEntDataEnt", GetEntDataEnt},
1.803 - {"GetEntDataFloat", GetEntDataFloat},
1.804 - {"GetEntDataVector", GetEntDataVector},
1.805 - {"GetEntityCount", GetEntityCount},
1.806 - {"GetEntityNetClass", GetEntityNetClass},
1.807 - {"GetMaxEntities", GetMaxEntities},
1.808 - {"IsEntNetworkable", IsEntNetworkable},
1.809 - {"IsValidEdict", IsValidEdict},
1.810 - {"IsValidEntity", IsValidEntity},
1.811 - {"RemoveEdict", RemoveEdict},
1.812 - {"SetEdictFlags", SetEdictFlags},
1.813 - {"SetEntData", SetEntData},
1.814 - {"SetEntDataEnt", SetEntDataEnt},
1.815 - {"SetEntDataFloat", SetEntDataFloat},
1.816 - {"SetEntDataVector", SetEntDataVector},
1.817 - {"FindDataMapOffs", FindDataMapOffs},
1.818 - {"GetEntDataString", GetEntDataString},
1.819 - {"SetEntDataString", SetEntDataString},
1.820 - {"GetEntPropString", GetEntPropString},
1.821 - {"SetEntPropString", SetEntPropString},
1.822 - {NULL, NULL}
1.823 -};