Added support for logical (non-networked) entities using entity references - See http://wiki.alliedmods.net/Entity_References_%28SourceMod%29 (bug 2459, r=dvander)
1.1 --- a/core/HalfLife2.cpp Thu Jul 09 17:51:12 2009 -0400
1.2 +++ b/core/HalfLife2.cpp Fri Jul 24 12:34:31 2009 +1200
1.3 @@ -37,10 +37,14 @@
1.4 #include "sm_stringutil.h"
1.5 #include "GameConfigs.h"
1.6 #include <compat_wrappers.h>
1.7 +#include <Logger.h>
1.8
1.9 CHalfLife2 g_HL2;
1.10 ConVar *sv_lan = NULL;
1.11
1.12 +static void *g_EntList = NULL;
1.13 +static int entInfoOffset = -1;
1.14 +
1.15 namespace SourceHook
1.16 {
1.17 template<>
1.18 @@ -123,6 +127,51 @@
1.19 g_ShareSys.AddInterface(NULL, this);
1.20 }
1.21
1.22 +void CHalfLife2::OnSourceModAllInitialized_Post()
1.23 +{
1.24 + char *addr = NULL;
1.25 +#ifdef PLATFORM_WINDOWS
1.26 + int offset;
1.27 +
1.28 + /* gEntList and/or g_pEntityList */
1.29 + if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr))
1.30 + {
1.31 + g_Logger.LogError("Logical Entities not supported by this mod (LevelShutdown) - Reverting to networkable entities only");
1.32 + return;
1.33 + }
1.34 + if (!addr)
1.35 + {
1.36 + g_Logger.LogError("Failed lookup of LevelShutdown - Reverting to networkable entities only");
1.37 + return;
1.38 + }
1.39 + if (!g_pGameConf->GetOffset("gEntList", &offset))
1.40 + {
1.41 + g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
1.42 + return;
1.43 + }
1.44 + g_EntList = *reinterpret_cast<void **>(addr + offset);
1.45 +#elif defined PLATFORM_LINUX
1.46 + /* gEntList and/or g_pEntityList */
1.47 + if (!g_pGameConf->GetMemSig("gEntList", (void **)&addr))
1.48 + {
1.49 + g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
1.50 + return;
1.51 + }
1.52 + if (!addr)
1.53 + {
1.54 + g_Logger.LogError("Failed lookup of gEntList - Reverting to networkable entities only");
1.55 + return;
1.56 + }
1.57 + g_EntList = reinterpret_cast<void *>(addr);
1.58 +#endif
1.59 +
1.60 + if (!g_pGameConf->GetOffset("EntInfo", &entInfoOffset))
1.61 + {
1.62 + g_Logger.LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only");
1.63 + return;
1.64 + }
1.65 +}
1.66 +
1.67 #if !defined METAMOD_PLAPI_VERSION
1.68 bool CHalfLife2::IsOriginalEngine()
1.69 {
1.70 @@ -642,3 +691,173 @@
1.71 {
1.72 engine->ServerCommand(buffer);
1.73 }
1.74 +
1.75 +cell_t CHalfLife2::EntityToReference(CBaseEntity *pEntity)
1.76 +{
1.77 + IServerUnknown *pUnknown = (IServerUnknown *)pEntity;
1.78 + CBaseHandle hndl = pUnknown->GetRefEHandle();
1.79 + return (hndl.ToInt() | (1<<31));
1.80 +}
1.81 +
1.82 +CBaseEntity *CHalfLife2::ReferenceToEntity(cell_t entRef)
1.83 +{
1.84 + CEntInfo *pInfo = NULL;
1.85 +
1.86 + if (entRef & (1<<31))
1.87 + {
1.88 + /* Proper ent reference */
1.89 + int hndlValue = entRef & ~(1<<31);
1.90 + CBaseHandle hndl(hndlValue);
1.91 +
1.92 + pInfo = LookupEntity(hndl.GetEntryIndex());
1.93 + if (pInfo->m_SerialNumber != hndl.GetSerialNumber())
1.94 + {
1.95 + return NULL;
1.96 + }
1.97 + }
1.98 + else
1.99 + {
1.100 + /* Old style index only */
1.101 + pInfo = LookupEntity(entRef);
1.102 + }
1.103 +
1.104 + if (!pInfo)
1.105 + {
1.106 + return NULL;
1.107 + }
1.108 +
1.109 + IServerUnknown *pUnk = static_cast<IServerUnknown *>(pInfo->m_pEntity);
1.110 + if (pUnk)
1.111 + {
1.112 + return pUnk->GetBaseEntity();
1.113 + }
1.114 +
1.115 + return NULL;
1.116 +}
1.117 +
1.118 +/**
1.119 + * Retrieves the CEntInfo pointer from g_EntList for a given entity index
1.120 + */
1.121 +CEntInfo *CHalfLife2::LookupEntity(int entIndex)
1.122 +{
1.123 + if (!g_EntList || entInfoOffset == -1)
1.124 + {
1.125 + /* Attempt to use engine interface instead */
1.126 + static CEntInfo tempInfo;
1.127 + tempInfo.m_pNext = NULL;
1.128 + tempInfo.m_pPrev = NULL;
1.129 +
1.130 + edict_t *pEdict = engine->PEntityOfEntIndex(entIndex);
1.131 +
1.132 + if (!pEdict)
1.133 + {
1.134 + return NULL;
1.135 + }
1.136 +
1.137 + IServerUnknown *pUnk = pEdict->GetUnknown();
1.138 +
1.139 + if (!pUnk)
1.140 + {
1.141 + return NULL;
1.142 + }
1.143 +
1.144 + tempInfo.m_pEntity = pUnk;
1.145 + tempInfo.m_SerialNumber = pUnk->GetRefEHandle().GetSerialNumber();
1.146 +
1.147 + return &tempInfo;
1.148 + }
1.149 +
1.150 + CEntInfo *pArray = (CEntInfo *)(((unsigned char *)g_EntList) + entInfoOffset);
1.151 + return &pArray[entIndex];
1.152 +}
1.153 +
1.154 +/**
1.155 + SERIAL_MASK = 0x7fff (15 bits)
1.156 +
1.157 + #define MAX_EDICT_BITS 11
1.158 + #define NUM_ENT_ENTRY_BITS (MAX_EDICT_BITS + 1)
1.159 + m_Index = iEntry | (iSerialNumber << NUM_ENT_ENTRY_BITS);
1.160 +
1.161 + Top 5 bits of a handle are unused.
1.162 + Bit 31 - Our 'reference' flag indicator
1.163 +*/
1.164 +
1.165 +cell_t CHalfLife2::IndexToReference(int entIndex)
1.166 +{
1.167 + CBaseEntity *pEnt = ReferenceToEntity(entIndex);
1.168 + if (!pEnt)
1.169 + {
1.170 + return INVALID_EHANDLE_INDEX;
1.171 + }
1.172 +
1.173 + return EntityToReference(pEnt);
1.174 +}
1.175 +
1.176 +int CHalfLife2::ReferenceToIndex(cell_t entRef)
1.177 +{
1.178 + if (entRef == INVALID_EHANDLE_INDEX)
1.179 + {
1.180 + return INVALID_EHANDLE_INDEX;
1.181 + }
1.182 +
1.183 + if (entRef & (1<<31))
1.184 + {
1.185 + /* Proper ent reference */
1.186 + int hndlValue = entRef & ~(1<<31);
1.187 + CBaseHandle hndl(hndlValue);
1.188 +
1.189 + CEntInfo *pInfo = LookupEntity(hndl.GetEntryIndex());
1.190 +
1.191 + if (pInfo->m_SerialNumber != hndl.GetSerialNumber())
1.192 + {
1.193 + return INVALID_EHANDLE_INDEX;
1.194 + }
1.195 +
1.196 + return hndl.GetEntryIndex();
1.197 + }
1.198 +
1.199 + return entRef;
1.200 +}
1.201 +
1.202 +cell_t CHalfLife2::EntityToBCompatRef(CBaseEntity *pEntity)
1.203 +{
1.204 + if (pEntity == NULL)
1.205 + {
1.206 + return INVALID_EHANDLE_INDEX;
1.207 + }
1.208 +
1.209 + IServerUnknown *pUnknown = (IServerUnknown *)pEntity;
1.210 + CBaseHandle hndl = pUnknown->GetRefEHandle();
1.211 +
1.212 + if (hndl.GetEntryIndex() >= MAX_EDICTS)
1.213 + {
1.214 + return (hndl.ToInt() | (1<<31));
1.215 + }
1.216 + else
1.217 + {
1.218 + return hndl.GetEntryIndex();
1.219 + }
1.220 +}
1.221 +
1.222 +cell_t CHalfLife2::ReferenceToBCompatRef(cell_t entRef)
1.223 +{
1.224 + if (entRef == INVALID_EHANDLE_INDEX)
1.225 + {
1.226 + return INVALID_EHANDLE_INDEX;
1.227 + }
1.228 +
1.229 + int hndlValue = entRef & ~(1<<31);
1.230 + CBaseHandle hndl(hndlValue);
1.231 +
1.232 + if (hndl.GetEntryIndex() < MAX_EDICTS)
1.233 + {
1.234 + return hndl.GetEntryIndex();
1.235 + }
1.236 +
1.237 + return entRef;
1.238 +}
1.239 +
1.240 +void *CHalfLife2::GetGlobalEntityList()
1.241 +{
1.242 + return g_EntList;
1.243 +}
1.244 \ No newline at end of file
2.1 --- a/core/HalfLife2.h Thu Jul 09 17:51:12 2009 -0400
2.2 +++ b/core/HalfLife2.h Fri Jul 24 12:34:31 2009 +1200
2.3 @@ -43,6 +43,7 @@
2.4 #include <KeyValues.h>
2.5 #include <server_class.h>
2.6 #include <datamap.h>
2.7 +#include <ihandleentity.h>
2.8
2.9 class CCommand;
2.10
2.11 @@ -86,6 +87,15 @@
2.12 char buffer[384];
2.13 };
2.14
2.15 +class CEntInfo
2.16 +{
2.17 +public:
2.18 + IHandleEntity *m_pEntity;
2.19 + int m_SerialNumber;
2.20 + CEntInfo *m_pPrev;
2.21 + CEntInfo *m_pNext;
2.22 +};
2.23 +
2.24 class CHalfLife2 :
2.25 public SMGlobalClass,
2.26 public IGameHelpers
2.27 @@ -96,6 +106,7 @@
2.28 public:
2.29 void OnSourceModStartup(bool late);
2.30 void OnSourceModAllInitialized();
2.31 + void OnSourceModAllInitialized_Post();
2.32 /*void OnSourceModAllShutdown();*/
2.33 public: //IGameHelpers
2.34 SendProp *FindInSendTable(const char *classname, const char *offset);
2.35 @@ -115,6 +126,14 @@
2.36 void SetHandleEntity(CBaseHandle &hndl, edict_t *pEnt);
2.37 const char *GetCurrentMap();
2.38 void ServerCommand(const char *buffer);
2.39 + CBaseEntity *ReferenceToEntity(cell_t entRef);
2.40 + cell_t EntityToReference(CBaseEntity *pEntity);
2.41 + cell_t IndexToReference(int entIndex);
2.42 + int ReferenceToIndex(cell_t entRef);
2.43 + cell_t ReferenceToBCompatRef(cell_t entRef);
2.44 + CEntInfo *LookupEntity(int entIndex);
2.45 + cell_t EntityToBCompatRef(CBaseEntity *pEntity);
2.46 + void *GetGlobalEntityList();
2.47 public:
2.48 void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
2.49 void ProcessFakeCliCmdQueue();
3.1 --- a/core/smn_banning.cpp Thu Jul 09 17:51:12 2009 -0400
3.2 +++ b/core/smn_banning.cpp Fri Jul 24 12:34:31 2009 +1200
3.3 @@ -248,7 +248,7 @@
3.4 char *ban_reason, *ban_cmd;
3.5 int client, ban_flags, ban_source, ban_time;
3.6
3.7 - client = params[1];
3.8 + client = g_HL2.ReferenceToIndex(params[1]);
3.9
3.10 CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
3.11 if (!pPlayer || !pPlayer->IsConnected())
4.1 --- a/core/smn_bitbuffer.cpp Thu Jul 09 17:51:12 2009 -0400
4.2 +++ b/core/smn_bitbuffer.cpp Fri Jul 24 12:34:31 2009 +1200
4.3 @@ -33,6 +33,7 @@
4.4 #include "HandleSys.h"
4.5 #include <bitbuf.h>
4.6 #include <vector.h>
4.7 +#include <HalfLife2.h>
4.8
4.9 static cell_t smn_BfWriteBool(IPluginContext *pCtx, const cell_t *params)
4.10 {
4.11 @@ -226,7 +227,14 @@
4.12 return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
4.13 }
4.14
4.15 - pBitBuf->WriteShort(params[2]);
4.16 + int index = g_HL2.ReferenceToIndex(params[2]);
4.17 +
4.18 + if (index == -1)
4.19 + {
4.20 + return 0;
4.21 + }
4.22 +
4.23 + pBitBuf->WriteShort(index);
4.24
4.25 return 1;
4.26 }
4.27 @@ -523,7 +531,9 @@
4.28 return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
4.29 }
4.30
4.31 - return pBitBuf->ReadShort();
4.32 + int ref = g_HL2.IndexToReference(pBitBuf->ReadShort());
4.33 +
4.34 + return g_HL2.ReferenceToBCompatRef(ref);
4.35 }
4.36
4.37 static cell_t smn_BfReadAngle(IPluginContext *pCtx, const cell_t *params)
5.1 --- a/core/smn_entities.cpp Thu Jul 09 17:51:12 2009 -0400
5.2 +++ b/core/smn_entities.cpp Fri Jul 24 12:34:31 2009 +1200
5.3 @@ -54,45 +54,74 @@
5.4 PropField_String_T, /**< Valid for Data fields. Read only! */
5.5 };
5.6
5.7 +inline edict_t *BaseEntityToEdict(CBaseEntity *pEntity)
5.8 +{
5.9 + IServerUnknown *pUnk = (IServerUnknown *)pEntity;
5.10 + IServerNetworkable *pNet = pUnk->GetNetworkable();
5.11 +
5.12 + if (!pNet)
5.13 + {
5.14 + return NULL;
5.15 + }
5.16 +
5.17 + return pNet->GetEdict();
5.18 +}
5.19 +
5.20 inline edict_t *GetEdict(cell_t num)
5.21 {
5.22 - edict_t *pEdict = PEntityOfEntIndex(num);
5.23 + CBaseEntity *pEntity = g_HL2.ReferenceToEntity(num);
5.24 +
5.25 + if (!pEntity)
5.26 + {
5.27 + return 0;
5.28 + }
5.29 +
5.30 + edict_t *pEdict = ::BaseEntityToEdict(pEntity);
5.31 if (!pEdict || pEdict->IsFree())
5.32 {
5.33 return NULL;
5.34 }
5.35 - if (num > 0 && num <= g_Players.GetMaxClients())
5.36 +
5.37 + int index = g_HL2.ReferenceToIndex(num);
5.38 + if (index > 0 && index <= g_Players.GetMaxClients())
5.39 {
5.40 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(num);
5.41 + CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
5.42 if (!pPlayer || !pPlayer->IsConnected())
5.43 {
5.44 return NULL;
5.45 }
5.46 }
5.47 +
5.48 return pEdict;
5.49 }
5.50
5.51 edict_t *GetEntity(cell_t num, CBaseEntity **pData)
5.52 {
5.53 - edict_t *pEdict = PEntityOfEntIndex(num);
5.54 - if (!pEdict || pEdict->IsFree())
5.55 + CBaseEntity *pEntity = g_HL2.ReferenceToEntity(num);
5.56 +
5.57 + if (!pEntity)
5.58 {
5.59 - return NULL;
5.60 + return 0;
5.61 }
5.62 - if (num > 0 && num <= g_Players.GetMaxClients())
5.63 +
5.64 + int index = g_HL2.ReferenceToIndex(num);
5.65 + if (index > 0 && index <= g_Players.GetMaxClients())
5.66 {
5.67 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(num);
5.68 + CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
5.69 if (!pPlayer || !pPlayer->IsConnected())
5.70 {
5.71 return NULL;
5.72 }
5.73 }
5.74 - IServerUnknown *pUnk;
5.75 - if ((pUnk=pEdict->GetUnknown()) == NULL)
5.76 +
5.77 + *pData = pEntity;
5.78 +
5.79 + edict_t *pEdict = ::BaseEntityToEdict(pEntity);
5.80 + if (!pEdict || pEdict->IsFree())
5.81 {
5.82 return NULL;
5.83 }
5.84 - *pData = pUnk->GetBaseEntity();
5.85 +
5.86 return pEdict;
5.87 }
5.88
5.89 @@ -161,11 +190,11 @@
5.90
5.91 static cell_t RemoveEdict(IPluginContext *pContext, const cell_t *params)
5.92 {
5.93 - edict_t *pEdict = PEntityOfEntIndex(params[1]);
5.94 + edict_t *pEdict = GetEdict(params[1]);
5.95
5.96 if (!pEdict)
5.97 {
5.98 - return pContext->ThrowNativeError("Edict %d is not a valid edict", params[1]);
5.99 + return pContext->ThrowNativeError("Edict %d (%d) is not a valid edict", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.100 }
5.101
5.102 engine->RemoveEdict(pEdict);
5.103 @@ -188,20 +217,8 @@
5.104
5.105 static cell_t IsValidEntity(IPluginContext *pContext, const cell_t *params)
5.106 {
5.107 - edict_t *pEdict = GetEdict(params[1]);
5.108 -
5.109 - if (!pEdict)
5.110 - {
5.111 - return 0;
5.112 - }
5.113 + CBaseEntity *pEntity = g_HL2.ReferenceToEntity(params[1]);
5.114
5.115 - IServerUnknown *pUnknown = pEdict->GetUnknown();
5.116 - if (!pUnknown)
5.117 - {
5.118 - return 0;
5.119 - }
5.120 -
5.121 - CBaseEntity *pEntity = pUnknown->GetBaseEntity();
5.122 return (pEntity != NULL) ? 1 : 0;
5.123 }
5.124
5.125 @@ -228,7 +245,7 @@
5.126
5.127 if (!pEdict)
5.128 {
5.129 - return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
5.130 + return pContext->ThrowNativeError("Invalid edict (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.131 }
5.132
5.133 return pEdict->m_fStateFlags;
5.134 @@ -240,7 +257,7 @@
5.135
5.136 if (!pEdict)
5.137 {
5.138 - return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
5.139 + return pContext->ThrowNativeError("Invalid edict (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.140 }
5.141
5.142 pEdict->m_fStateFlags = params[2];
5.143 @@ -254,7 +271,7 @@
5.144
5.145 if (!pEdict)
5.146 {
5.147 - return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
5.148 + return pContext->ThrowNativeError("Invalid edict (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.149 }
5.150
5.151 const char *cls = pEdict->GetClassName();
5.152 @@ -271,14 +288,16 @@
5.153
5.154 static cell_t GetEntityNetClass(IPluginContext *pContext, const cell_t *params)
5.155 {
5.156 - edict_t *pEdict = GetEdict(params[1]);
5.157 + CBaseEntity *pEntity = g_HL2.ReferenceToEntity(params[1]);
5.158 +
5.159 + IServerUnknown *pUnk = (IServerUnknown *)pEntity;
5.160
5.161 - if (!pEdict)
5.162 + if (!pEntity)
5.163 {
5.164 - return pContext->ThrowNativeError("Invalid edict (%d)", params[1]);
5.165 + return pContext->ThrowNativeError("Invalid entity (%d - %d)", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.166 }
5.167
5.168 - IServerNetworkable *pNet = pEdict->GetNetworkable();
5.169 + IServerNetworkable *pNet = pUnk->GetNetworkable();
5.170 if (!pNet)
5.171 {
5.172 return 0;
5.173 @@ -294,11 +313,11 @@
5.174 static cell_t GetEntData(IPluginContext *pContext, const cell_t *params)
5.175 {
5.176 CBaseEntity *pEntity;
5.177 - edict_t *pEdict = GetEntity(params[1], &pEntity);
5.178 + GetEntity(params[1], &pEntity);
5.179
5.180 - if (!pEdict || !pEntity)
5.181 + if (!pEntity)
5.182 {
5.183 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.184 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.185 }
5.186
5.187 int offset = params[2];
5.188 @@ -325,9 +344,9 @@
5.189 CBaseEntity *pEntity;
5.190 edict_t *pEdict = GetEntity(params[1], &pEntity);
5.191
5.192 - if (!pEdict || !pEntity)
5.193 + if (!pEntity)
5.194 {
5.195 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.196 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.197 }
5.198
5.199 int offset = params[2];
5.200 @@ -336,7 +355,7 @@
5.201 return pContext->ThrowNativeError("Offset %d is invalid", offset);
5.202 }
5.203
5.204 - if (params[5])
5.205 + if (params[5] && (pEdict != NULL))
5.206 {
5.207 g_HL2.SetEdictStateChanged(pEdict, offset);
5.208 }
5.209 @@ -368,11 +387,11 @@
5.210 static cell_t GetEntDataFloat(IPluginContext *pContext, const cell_t *params)
5.211 {
5.212 CBaseEntity *pEntity;
5.213 - edict_t *pEdict = GetEntity(params[1], &pEntity);
5.214 + GetEntity(params[1], &pEntity);
5.215
5.216 - if (!pEdict || !pEntity)
5.217 + if (!pEntity)
5.218 {
5.219 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.220 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.221 }
5.222
5.223 int offset = params[2];
5.224 @@ -391,9 +410,9 @@
5.225 CBaseEntity *pEntity;
5.226 edict_t *pEdict = GetEntity(params[1], &pEntity);
5.227
5.228 - if (!pEdict || !pEntity)
5.229 + if (!pEntity)
5.230 {
5.231 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.232 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.233 }
5.234
5.235 int offset = params[2];
5.236 @@ -404,7 +423,7 @@
5.237
5.238 *(float *)((uint8_t *)pEntity + offset) = sp_ctof(params[3]);
5.239
5.240 - if (params[4])
5.241 + if (params[4] && (pEdict != NULL))
5.242 {
5.243 g_HL2.SetEdictStateChanged(pEdict, offset);
5.244 }
5.245 @@ -415,11 +434,11 @@
5.246 static cell_t GetEntDataVector(IPluginContext *pContext, const cell_t *params)
5.247 {
5.248 CBaseEntity *pEntity;
5.249 - edict_t *pEdict = GetEntity(params[1], &pEntity);
5.250 + GetEntity(params[1], &pEntity);
5.251
5.252 - if (!pEdict || !pEntity)
5.253 + if (!pEntity)
5.254 {
5.255 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.256 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.257 }
5.258
5.259 int offset = params[2];
5.260 @@ -445,9 +464,9 @@
5.261 CBaseEntity *pEntity;
5.262 edict_t *pEdict = GetEntity(params[1], &pEntity);
5.263
5.264 - if (!pEdict || !pEntity)
5.265 + if (!pEntity)
5.266 {
5.267 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.268 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.269 }
5.270
5.271 int offset = params[2];
5.272 @@ -465,7 +484,7 @@
5.273 v->y = sp_ctof(vec[1]);
5.274 v->z = sp_ctof(vec[2]);
5.275
5.276 - if (params[4])
5.277 + if (params[4] && (pEdict != NULL))
5.278 {
5.279 g_HL2.SetEdictStateChanged(pEdict, offset);
5.280 }
5.281 @@ -477,11 +496,11 @@
5.282 static cell_t GetEntDataEnt(IPluginContext *pContext, const cell_t *params)
5.283 {
5.284 CBaseEntity *pEntity;
5.285 - edict_t *pEdict = GetEntity(params[1], &pEntity);
5.286 + GetEntity(params[1], &pEntity);
5.287
5.288 - if (!pEdict || !pEntity)
5.289 + if (!pEntity)
5.290 {
5.291 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.292 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.293 }
5.294
5.295 int offset = params[2];
5.296 @@ -497,7 +516,8 @@
5.297 return 0;
5.298 }
5.299
5.300 - return hndl.GetEntryIndex();
5.301 + int ref = g_HL2.IndexToReference(hndl.GetEntryIndex());
5.302 + return g_HL2.ReferenceToBCompatRef(ref);
5.303 }
5.304
5.305 int CheckBaseHandle(CBaseHandle &hndl)
5.306 @@ -537,11 +557,11 @@
5.307 static cell_t GetEntDataEnt2(IPluginContext *pContext, const cell_t *params)
5.308 {
5.309 CBaseEntity *pEntity;
5.310 - edict_t *pEdict = GetEntity(params[1], &pEntity);
5.311 + GetEntity(params[1], &pEntity);
5.312
5.313 - if (pEdict == NULL || pEntity == NULL)
5.314 + if (pEntity == NULL)
5.315 {
5.316 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.317 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.318 }
5.319
5.320 int offset = params[2];
5.321 @@ -552,7 +572,8 @@
5.322
5.323 CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
5.324
5.325 - return CheckBaseHandle(hndl);
5.326 + int ref = g_HL2.IndexToReference(hndl.GetEntryIndex());
5.327 + return g_HL2.ReferenceToBCompatRef(ref);
5.328 }
5.329
5.330 /* THIS GUY IS DEPRECATED. */
5.331 @@ -561,9 +582,9 @@
5.332 CBaseEntity *pEntity;
5.333 edict_t *pEdict = GetEntity(params[1], &pEntity);
5.334
5.335 - if (!pEdict || !pEntity)
5.336 + if (!pEntity)
5.337 {
5.338 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.339 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.340 }
5.341
5.342 int offset = params[2];
5.343 @@ -574,20 +595,23 @@
5.344
5.345 CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
5.346
5.347 - if (params[3] == 0)
5.348 + if (params[3] == 0 || params[3] == INVALID_EHANDLE_INDEX)
5.349 {
5.350 hndl.Set(NULL);
5.351 } else {
5.352 - edict_t *pEdict = GetEdict(params[3]);
5.353 - if (!pEdict)
5.354 + CBaseEntity *pOther;
5.355 + GetEntity(params[3], &pOther);
5.356 +
5.357 + if (!pOther)
5.358 {
5.359 - return pContext->ThrowNativeError("Entity %d is invalid", params[3]);
5.360 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[3]), params[3]);
5.361 }
5.362 - IServerEntity *pEntOther = pEdict->GetIServerEntity();
5.363 - hndl.Set(pEntOther);
5.364 +
5.365 + IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
5.366 + hndl.Set(pHandleEnt);
5.367 }
5.368
5.369 - if (params[4])
5.370 + if (params[4] && (pEdict != NULL))
5.371 {
5.372 g_HL2.SetEdictStateChanged(pEdict, offset);
5.373 }
5.374 @@ -600,9 +624,9 @@
5.375 CBaseEntity *pEntity;
5.376 edict_t *pEdict = GetEntity(params[1], &pEntity);
5.377
5.378 - if (!pEdict || !pEntity)
5.379 + if (!pEntity)
5.380 {
5.381 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.382 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.383 }
5.384
5.385 int offset = params[2];
5.386 @@ -613,22 +637,25 @@
5.387
5.388 CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
5.389
5.390 - if (params[3] == -1)
5.391 + if (params[3] == INVALID_EHANDLE_INDEX)
5.392 {
5.393 hndl.Set(NULL);
5.394 }
5.395 else
5.396 {
5.397 - edict_t *pEdict = GetEdict(params[3]);
5.398 - if (!pEdict)
5.399 + CBaseEntity *pOther;
5.400 + GetEntity(params[3], &pOther);
5.401 +
5.402 + if (!pOther)
5.403 {
5.404 - return pContext->ThrowNativeError("Entity %d is invalid", params[3]);
5.405 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[3]), params[3]);
5.406 }
5.407 - IServerEntity *pEntOther = pEdict->GetIServerEntity();
5.408 - hndl.Set(pEntOther);
5.409 +
5.410 + IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
5.411 + hndl.Set(pHandleEnt);
5.412 }
5.413
5.414 - if (params[4])
5.415 + if (params[4] && (pEdict != NULL))
5.416 {
5.417 g_HL2.SetEdictStateChanged(pEdict, offset);
5.418 }
5.419 @@ -642,7 +669,7 @@
5.420
5.421 if (!pEdict)
5.422 {
5.423 - return pContext->ThrowNativeError("Edict %d is invalid", params[1]);
5.424 + return pContext->ThrowNativeError("Edict %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.425 }
5.426
5.427 g_HL2.SetEdictStateChanged(pEdict, params[2]);
5.428 @@ -725,11 +752,11 @@
5.429 datamap_t *pMap;
5.430 typedescription_t *td;
5.431 char *offset;
5.432 - edict_t *pEdict = GetEntity(params[1], &pEntity);
5.433 + GetEntity(params[1], &pEntity);
5.434
5.435 - if (!pEdict || !pEntity)
5.436 + if (!pEntity)
5.437 {
5.438 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.439 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.440 }
5.441
5.442 if ((pMap=CBaseEntity_GetDataDescMap(pEntity)) == NULL)
5.443 @@ -830,11 +857,11 @@
5.444 static cell_t GetEntDataString(IPluginContext *pContext, const cell_t *params)
5.445 {
5.446 CBaseEntity *pEntity;
5.447 - edict_t *pEdict = GetEntity(params[1], &pEntity);
5.448 + GetEntity(params[1], &pEntity);
5.449
5.450 - if (!pEdict || !pEntity)
5.451 + if (!pEntity)
5.452 {
5.453 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.454 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.455 }
5.456
5.457 int offset = params[2];
5.458 @@ -855,9 +882,9 @@
5.459 CBaseEntity *pEntity;
5.460 edict_t *pEdict = GetEntity(params[1], &pEntity);
5.461
5.462 - if (!pEdict || !pEntity)
5.463 + if (!pEntity)
5.464 {
5.465 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.466 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.467 }
5.468
5.469 int offset = params[2];
5.470 @@ -872,7 +899,7 @@
5.471 pContext->LocalToString(params[3], &src);
5.472 size_t len = strncopy(dest, src, params[4]);
5.473
5.474 - if (params[5])
5.475 + if (params[5] && (pEdict != NULL))
5.476 {
5.477 g_HL2.SetEdictStateChanged(pEdict, offset);
5.478 }
5.479 @@ -895,10 +922,11 @@
5.480 }
5.481
5.482 #define FIND_PROP_SEND(pProp) \
5.483 - IServerNetworkable *pNet = pEdict->GetNetworkable(); \
5.484 + IServerUnknown *pUnk = (IServerUnknown *)pEntity; \
5.485 + IServerNetworkable *pNet = pUnk->GetNetworkable(); \
5.486 if (!pNet) \
5.487 { \
5.488 - return pContext->ThrowNativeError("Edict %d is not networkable", params[1]); \
5.489 + return pContext->ThrowNativeError("Edict %d (%d) is not networkable", g_HL2.ReferenceToIndex(params[1]), params[1]); \
5.490 } \
5.491 if (!g_HL2.FindSendPropInfo(pNet->GetServerClass()->GetName(), prop, pProp)) \
5.492 { \
5.493 @@ -942,12 +970,13 @@
5.494
5.495 pEdict = GetEntity(params[1], &pEntity);
5.496
5.497 - if (!pEdict || !pEntity)
5.498 + if (!pEntity)
5.499 {
5.500 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.501 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.502 }
5.503
5.504 - if ((class_name = pEdict->GetClassName()) == NULL)
5.505 + /* TODO: Find a way to lookup classname without having an edict - Is this a guaranteed prop? */
5.506 + if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
5.507 {
5.508 class_name = "";
5.509 }
5.510 @@ -1033,12 +1062,12 @@
5.511
5.512 pEdict = GetEntity(params[1], &pEntity);
5.513
5.514 - if (!pEdict || !pEntity)
5.515 + if (!pEntity)
5.516 {
5.517 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.518 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.519 }
5.520
5.521 - if ((class_name = pEdict->GetClassName()) == NULL)
5.522 + if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
5.523 {
5.524 class_name = "";
5.525 }
5.526 @@ -1123,12 +1152,12 @@
5.527
5.528 pEdict = GetEntity(params[1], &pEntity);
5.529
5.530 - if (!pEdict || !pEntity)
5.531 + if (!pEntity)
5.532 {
5.533 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.534 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.535 }
5.536
5.537 - if ((class_name = pEdict->GetClassName()) == NULL)
5.538 + if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
5.539 {
5.540 class_name = "";
5.541 }
5.542 @@ -1194,12 +1223,12 @@
5.543
5.544 pEdict = GetEntity(params[1], &pEntity);
5.545
5.546 - if (!pEdict || !pEntity)
5.547 + if (!pEntity)
5.548 {
5.549 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.550 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.551 }
5.552
5.553 - if ((class_name = pEdict->GetClassName()) == NULL)
5.554 + if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
5.555 {
5.556 class_name = "";
5.557 }
5.558 @@ -1252,7 +1281,7 @@
5.559
5.560 *(float *)((uint8_t *)pEntity + offset) = sp_ctof(params[4]);
5.561
5.562 - if (params[2] == Prop_Send)
5.563 + if (params[2] == Prop_Send && (pEdict != NULL))
5.564 {
5.565 g_HL2.SetEdictStateChanged(pEdict, offset);
5.566 }
5.567 @@ -1270,12 +1299,12 @@
5.568
5.569 pEdict = GetEntity(params[1], &pEntity);
5.570
5.571 - if (!pEdict || !pEntity)
5.572 + if (!pEntity)
5.573 {
5.574 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.575 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.576 }
5.577
5.578 - if ((class_name = pEdict->GetClassName()) == NULL)
5.579 + if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
5.580 {
5.581 class_name = "";
5.582 }
5.583 @@ -1326,7 +1355,8 @@
5.584
5.585 CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
5.586
5.587 - return CheckBaseHandle(hndl);
5.588 + int ref = g_HL2.IndexToReference(hndl.GetEntryIndex());
5.589 + return g_HL2.ReferenceToBCompatRef(ref);
5.590 }
5.591
5.592 static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
5.593 @@ -1339,12 +1369,12 @@
5.594
5.595 pEdict = GetEntity(params[1], &pEntity);
5.596
5.597 - if (!pEdict || !pEntity)
5.598 + if (!pEntity)
5.599 {
5.600 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.601 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.602 }
5.603
5.604 - if ((class_name = pEdict->GetClassName()) == NULL)
5.605 + if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
5.606 {
5.607 class_name = "";
5.608 }
5.609 @@ -1401,18 +1431,19 @@
5.610 }
5.611 else
5.612 {
5.613 - edict_t *pOther;
5.614 - CBaseEntity *pOtherEnt;
5.615 + CBaseEntity *pOther;
5.616 + GetEntity(params[4], &pOther);
5.617
5.618 - if ((pOther = GetEntity(params[4], &pOtherEnt)) == NULL)
5.619 + if (!pOther)
5.620 {
5.621 - return pContext->ThrowNativeError("Invalid entity %d", params[4]);
5.622 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[4]), params[4]);
5.623 }
5.624
5.625 - hndl.Set(pOther->GetIServerEntity());
5.626 + IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
5.627 + hndl.Set(pHandleEnt);
5.628 }
5.629
5.630 - if (params[2] == Prop_Send)
5.631 + if (params[2] == Prop_Send && (pEdict != NULL))
5.632 {
5.633 g_HL2.SetEdictStateChanged(pEdict, offset);
5.634 }
5.635 @@ -1430,12 +1461,12 @@
5.636
5.637 pEdict = GetEntity(params[1], &pEntity);
5.638
5.639 - if (!pEdict || !pEntity)
5.640 + if (!pEntity)
5.641 {
5.642 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.643 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.644 }
5.645
5.646 - if ((class_name = pEdict->GetClassName()) == NULL)
5.647 + if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
5.648 {
5.649 class_name = "";
5.650 }
5.651 @@ -1508,12 +1539,12 @@
5.652
5.653 pEdict = GetEntity(params[1], &pEntity);
5.654
5.655 - if (!pEdict || !pEntity)
5.656 + if (!pEntity)
5.657 {
5.658 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.659 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.660 }
5.661
5.662 - if ((class_name = pEdict->GetClassName()) == NULL)
5.663 + if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
5.664 {
5.665 class_name = "";
5.666 }
5.667 @@ -1573,7 +1604,7 @@
5.668 v->y = sp_ctof(vec[1]);
5.669 v->z = sp_ctof(vec[2]);
5.670
5.671 - if (params[2] == Prop_Send)
5.672 + if (params[2] == Prop_Send && (pEdict != NULL))
5.673 {
5.674 g_HL2.SetEdictStateChanged(pEdict, offset);
5.675 }
5.676 @@ -1592,12 +1623,12 @@
5.677
5.678 pEdict = GetEntity(params[1], &pEntity);
5.679
5.680 - if (!pEdict || !pEntity)
5.681 + if (!pEntity)
5.682 {
5.683 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.684 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.685 }
5.686
5.687 - if ((class_name = pEdict->GetClassName()) == NULL)
5.688 + if (!pEdict || (class_name = pEdict->GetClassName()) == NULL)
5.689 {
5.690 class_name = "";
5.691 }
5.692 @@ -1682,9 +1713,9 @@
5.693 int maxlen;
5.694 edict_t *pEdict = GetEntity(params[1], &pEntity);
5.695
5.696 - if (!pEdict || !pEntity)
5.697 + if (!pEntity)
5.698 {
5.699 - return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
5.700 + return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
5.701 }
5.702
5.703 switch (params[2])
5.704 @@ -1713,7 +1744,8 @@
5.705 case Prop_Send:
5.706 {
5.707 char *prop;
5.708 - IServerNetworkable *pNet = pEdict->GetNetworkable();
5.709 + IServerUnknown *pUnk = (IServerUnknown *)pEntity;
5.710 + IServerNetworkable *pNet = pUnk->GetNetworkable();
5.711 if (!pNet)
5.712 {
5.713 return pContext->ThrowNativeError("The edict is not networkable");
5.714 @@ -1744,7 +1776,7 @@
5.715 pContext->LocalToString(params[4], &src);
5.716 size_t len = strncopy(dest, src, maxlen);
5.717
5.718 - if (params[2] == Prop_Send)
5.719 + if (params[2] == Prop_Send && (pEdict != NULL))
5.720 {
5.721 g_HL2.SetEdictStateChanged(pEdict, offset);
5.722 }
6.1 --- a/core/smn_halflife.cpp Thu Jul 09 17:51:12 2009 -0400
6.2 +++ b/core/smn_halflife.cpp Fri Jul 24 12:34:31 2009 +1200
6.3 @@ -475,6 +475,26 @@
6.4 return 0;
6.5 }
6.6
6.7 +static cell_t IndexToReference(IPluginContext *pContext, const cell_t *params)
6.8 +{
6.9 + if (params[1] >= NUM_ENT_ENTRIES || params[1] < 0)
6.10 + {
6.11 + return pContext->ThrowNativeError("Invalid entity index %i", params[1]);
6.12 + }
6.13 +
6.14 + return g_HL2.IndexToReference(params[1]);
6.15 +}
6.16 +
6.17 +static cell_t ReferenceToIndex(IPluginContext *pContext, const cell_t *params)
6.18 +{
6.19 + return g_HL2.ReferenceToIndex(params[1]);
6.20 +}
6.21 +
6.22 +static cell_t ReferenceToBCompatRef(IPluginContext *pContext, const cell_t *params)
6.23 +{
6.24 + return g_HL2.ReferenceToBCompatRef(params[1]);
6.25 +}
6.26 +
6.27 REGISTER_NATIVES(halflifeNatives)
6.28 {
6.29 {"CreateFakeClient", CreateFakeClient},
6.30 @@ -505,5 +525,8 @@
6.31 {"ShowVGUIPanel", ShowVGUIPanel},
6.32 {"IsPlayerAlive", smn_IsPlayerAlive},
6.33 {"GuessSDKVersion", GuessSDKVersion},
6.34 + {"EntIndexToEntRef", IndexToReference},
6.35 + {"EntRefToEntIndex", ReferenceToIndex},
6.36 + {"MakeCompatEntRef", ReferenceToBCompatRef},
6.37 {NULL, NULL},
6.38 };
7.1 --- a/extensions/sdktools/inputnatives.cpp Thu Jul 09 17:51:12 2009 -0400
7.2 +++ b/extensions/sdktools/inputnatives.cpp Fri Jul 24 12:34:31 2009 +1200
7.3 @@ -37,21 +37,11 @@
7.4 ICallWrapper *g_pAcceptInput = NULL;
7.5 unsigned char g_Variant_t[SIZEOF_VARIANT_T] = {0};
7.6
7.7 -#define ENTINDEX_TO_CBASEENTITY(index, buffer) \
7.8 - pEdict = PEntityOfEntIndex(index); \
7.9 - if (!pEdict || pEdict->IsFree()) \
7.10 - { \
7.11 - return pContext->ThrowNativeError("Entity %d is not valid or is freed", index); \
7.12 - } \
7.13 - pUnk = pEdict->GetUnknown(); \
7.14 - if (!pUnk) \
7.15 - { \
7.16 - return pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", index); \
7.17 - } \
7.18 - buffer = pUnk->GetBaseEntity(); \
7.19 +#define ENTINDEX_TO_CBASEENTITY(ref, buffer) \
7.20 + buffer = gamehelpers->ReferenceToEntity(ref); \
7.21 if (!buffer) \
7.22 { \
7.23 - return pContext->ThrowNativeError("Entity %d is not a CBaseEntity", index); \
7.24 + return pContext->ThrowNativeError("Entity %d (%d) is not a CBaseEntity", gamehelpers->ReferenceToIndex(ref), ref); \
7.25 }
7.26
7.27 /* Hack to init the variant_t object for the first time */
7.28 @@ -109,8 +99,6 @@
7.29 }
7.30
7.31 CBaseEntity *pActivator, *pCaller, *pDest;
7.32 - edict_t *pEdict;
7.33 - IServerUnknown *pUnk;
7.34
7.35 char *inputname;
7.36 unsigned char vstk[sizeof(void *) + sizeof(const char *) + sizeof(CBaseEntity *)*2 + SIZEOF_VARIANT_T + sizeof(int)];
7.37 @@ -257,8 +245,6 @@
7.38 static cell_t SetVariantEntity(IPluginContext *pContext, const cell_t *params)
7.39 {
7.40 CBaseEntity *pEntity;
7.41 - edict_t *pEdict;
7.42 - IServerUnknown *pUnk;
7.43 unsigned char *vptr = g_Variant_t;
7.44 CBaseHandle bHandle;
7.45
8.1 --- a/extensions/sdktools/output.cpp Thu Jul 09 17:51:12 2009 -0400
8.2 +++ b/extensions/sdktools/output.cpp Fri Jul 24 12:34:31 2009 +1200
8.3 @@ -205,20 +205,12 @@
8.4 // attempt to directly lookup a hook using the pOutput pointer
8.5 OutputNameStruct *pOutputName = NULL;
8.6
8.7 - edict_t *pEdict = gameents->BaseEntityToEdict(pCaller);
8.8 -
8.9 - /* TODO: Add support for entities without an edict */
8.10 - if (pEdict == NULL)
8.11 - {
8.12 - return;
8.13 - }
8.14 -
8.15 bool fastLookup = false;
8.16
8.17 // Fast lookup failed - check the slow way for hooks that havn't fired yet
8.18 if ((fastLookup = EntityOutputs->Retrieve(sOutput, (void **)&pOutputName)) == false)
8.19 {
8.20 - const char *classname = pEdict->GetClassName();
8.21 + const char *classname = GetEntityClassname(pCaller);
8.22 const char *outputname = FindOutputName(pOutput, pCaller);
8.23
8.24 pOutputName = FindOutputPointer(classname, outputname, false);
8.25 @@ -249,37 +241,31 @@
8.26
8.27 hook->in_use = true;
8.28
8.29 - int serial = pEdict->m_NetworkSerialNumber;
8.30 + cell_t ref = gamehelpers->EntityToReference(pCaller);
8.31
8.32 - if (serial != hook->entity_filter && hook->entity_index == IndexOfEdict(pEdict))
8.33 + if (hook->entity_ref != -1
8.34 + && gamehelpers->ReferenceToIndex(hook->entity_ref) == gamehelpers->ReferenceToIndex(ref)
8.35 + && ref != hook->entity_ref)
8.36 {
8.37 - // same entity index but different serial number. Entity has changed, kill the hook.
8.38 + // same entity index but different reference. Entity has changed, kill the hook.
8.39 _iter = pOutputName->hooks.erase(_iter);
8.40 CleanUpHook(hook);
8.41
8.42 continue;
8.43 }
8.44
8.45 - if (hook->entity_filter == -1 || hook->entity_filter == serial) // Global classname hook
8.46 + if (hook->entity_ref == -1 || hook->entity_ref == ref) // Global classname hook
8.47 {
8.48 //fire the forward to hook->pf
8.49 hook->pf->PushString(pOutputName->Name);
8.50 - hook->pf->PushCell(IndexOfEdict(pEdict));
8.51 -
8.52 - edict_t *pEdictActivator = gameents->BaseEntityToEdict(pActivator);
8.53 - if (!pEdictActivator)
8.54 - {
8.55 - hook->pf->PushCell(-1);
8.56 - }
8.57 - else
8.58 - {
8.59 - hook->pf->PushCell(IndexOfEdict(pEdictActivator));
8.60 - }
8.61 + hook->pf->PushCell(gamehelpers->ReferenceToBCompatRef(ref));
8.62 + hook->pf->PushCell(gamehelpers->EntityToBCompatRef(pActivator));
8.63 +
8.64 //hook->pf->PushCell(handle);
8.65 hook->pf->PushFloat(fDelay);
8.66 hook->pf->Execute(NULL);
8.67
8.68 - if ((hook->entity_filter != -1) && hook->only_once)
8.69 + if ((hook->entity_ref != -1) && hook->only_once)
8.70 {
8.71 _iter = pOutputName->hooks.erase(_iter);
8.72 CleanUpHook(hook);
8.73 @@ -454,36 +440,15 @@
8.74 return NULL;
8.75 }
8.76
8.77 -// Thanks SM core
8.78 -edict_t *EntityOutputManager::BaseHandleToEdict(CBaseHandle &hndl)
8.79 +const char *EntityOutputManager::GetEntityClassname(CBaseEntity *pEntity)
8.80 {
8.81 - if (!hndl.IsValid())
8.82 + static int offset = -1;
8.83 + if (offset == -1)
8.84 {
8.85 - return NULL;
8.86 + datamap_t *pMap = gamehelpers->GetDataMap(pEntity);
8.87 + typedescription_t *pDesc = gamehelpers->FindInDataMap(pMap, "m_iClassname");
8.88 + offset = pDesc->fieldOffset[TD_OFFSET_NORMAL];
8.89 }
8.90
8.91 - int index = hndl.GetEntryIndex();
8.92 -
8.93 - edict_t *pStoredEdict;
8.94 -
8.95 - pStoredEdict = PEntityOfEntIndex(index);
8.96 -
8.97 - if (pStoredEdict == NULL)
8.98 - {
8.99 - return NULL;
8.100 - }
8.101 -
8.102 - IServerEntity *pSE = pStoredEdict->GetIServerEntity();
8.103 -
8.104 - if (pSE == NULL)
8.105 - {
8.106 - return NULL;
8.107 - }
8.108 -
8.109 - if (pSE->GetRefEHandle() != hndl)
8.110 - {
8.111 - return NULL;
8.112 - }
8.113 -
8.114 - return pStoredEdict;
8.115 -}
8.116 + return (const char *)(((unsigned char *)pEntity) + offset);
8.117 +}
8.118 \ No newline at end of file
9.1 --- a/extensions/sdktools/output.h Thu Jul 09 17:51:12 2009 -0400
9.2 +++ b/extensions/sdktools/output.h Fri Jul 24 12:34:31 2009 +1200
9.3 @@ -49,8 +49,7 @@
9.4 */
9.5 struct omg_hooks
9.6 {
9.7 - int entity_filter; // if not -1 is an entity signature
9.8 - int entity_index;
9.9 + cell_t entity_ref;
9.10 bool only_once;
9.11 IPluginFunction *pf;
9.12 OutputNameStruct *m_parent;
9.13 @@ -110,6 +109,8 @@
9.14 void OnHookAdded();
9.15 void OnHookRemoved();
9.16
9.17 + const char *GetEntityClassname(CBaseEntity *pEntity);
9.18 +
9.19 private:
9.20 bool enabled;
9.21
9.22 @@ -123,7 +124,6 @@
9.23 void DeleteFireEventDetour();
9.24
9.25 const char *FindOutputName(void *pOutput, CBaseEntity *pCaller);
9.26 - edict_t *BaseHandleToEdict(CBaseHandle &hndl);
9.27
9.28 //Maps CEntityOutput * to a OutputNameStruct
9.29 IBasicTrie *EntityOutputs;
10.1 --- a/extensions/sdktools/outputnatives.cpp Thu Jul 09 17:51:12 2009 -0400
10.2 +++ b/extensions/sdktools/outputnatives.cpp Fri Jul 24 12:34:31 2009 +1200
10.3 @@ -40,12 +40,13 @@
10.4 return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details");
10.5 }
10.6
10.7 - edict_t *pEdict = PEntityOfEntIndex(params[1]);
10.8 - if (!pEdict)
10.9 + CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(params[1]);
10.10 + if (!pEntity)
10.11 {
10.12 - return pContext->ThrowNativeError("Invalid Entity index %i", params[1]);
10.13 + return pContext->ThrowNativeError("Invalid Entity index %i (%i)", gamehelpers->ReferenceToIndex(params[1]), params[1]);
10.14 }
10.15 - const char *classname = pEdict->GetClassName();
10.16 +
10.17 + const char *classname = g_OutputManager.GetEntityClassname(pEntity);
10.18
10.19 char *outputname;
10.20 pContext->LocalToString(params[2], &outputname);
10.21 @@ -63,7 +64,7 @@
10.22 for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
10.23 {
10.24 hook = (omg_hooks *)*_iter;
10.25 - if (hook->pf == pFunction && hook->entity_filter == pEdict->m_NetworkSerialNumber)
10.26 + if (hook->pf == pFunction && hook->entity_ref == gamehelpers->EntityToReference(pEntity))
10.27 {
10.28 return 0;
10.29 }
10.30 @@ -71,8 +72,7 @@
10.31
10.32 hook = g_OutputManager.NewHook();
10.33
10.34 - hook->entity_filter = pEdict->m_NetworkSerialNumber;
10.35 - hook->entity_index = IndexOfEdict(pEdict);
10.36 + hook->entity_ref = gamehelpers->EntityToReference(pEntity);
10.37 hook->only_once= !!params[4];
10.38 hook->pf = pFunction;
10.39 hook->m_parent = pOutputName;
10.40 @@ -125,7 +125,7 @@
10.41 for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
10.42 {
10.43 hook = (omg_hooks *)*_iter;
10.44 - if (hook->pf == pFunction && hook->entity_filter == -1)
10.45 + if (hook->pf == pFunction && hook->entity_ref == -1)
10.46 {
10.47 //already hooked to this function...
10.48 //throw an error or just let them get away with stupidity?
10.49 @@ -136,7 +136,7 @@
10.50
10.51 hook = g_OutputManager.NewHook();
10.52
10.53 - hook->entity_filter = -1;
10.54 + hook->entity_ref = -1;
10.55 hook->pf = pFunction;
10.56 hook->m_parent = pOutputName;
10.57 hook->in_use = false;
10.58 @@ -192,7 +192,7 @@
10.59 for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
10.60 {
10.61 hook = (omg_hooks *)*_iter;
10.62 - if (hook->pf == pFunction && hook->entity_filter == -1)
10.63 + if (hook->pf == pFunction && hook->entity_ref == -1)
10.64 {
10.65 // remove this hook.
10.66 if (hook->in_use)
10.67 @@ -220,13 +220,13 @@
10.68 }
10.69
10.70 // Find the classname of the entity and lookup the classname and output structures
10.71 - edict_t *pEdict = PEntityOfEntIndex(params[1]);
10.72 - if (!pEdict)
10.73 + CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(params[1]);
10.74 + if (!pEntity)
10.75 {
10.76 - return pContext->ThrowNativeError("Invalid Entity index %i", params[1]);
10.77 + return pContext->ThrowNativeError("Invalid Entity index %i (%i)", gamehelpers->ReferenceToIndex(params[1]), params[1]);
10.78 }
10.79
10.80 - const char *classname = pEdict->GetClassName();
10.81 + const char *classname = g_OutputManager.GetEntityClassname(pEntity);
10.82
10.83 char *outputname;
10.84 pContext->LocalToString(params[2], &outputname);
10.85 @@ -249,7 +249,8 @@
10.86 for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
10.87 {
10.88 hook = (omg_hooks *)*_iter;
10.89 - if (hook->pf == pFunction && hook->entity_index == IndexOfEdict(pEdict))
10.90 + /* We're not serial checking and just removing by index here - This was always allowed so is left for bcompat */
10.91 + if (hook->pf == pFunction && gamehelpers->ReferenceToIndex(hook->entity_ref) == gamehelpers->ReferenceToIndex(params[1]))
10.92 {
10.93 // remove this hook.
10.94 if (hook->in_use)
11.1 --- a/extensions/sdktools/trnatives.cpp Thu Jul 09 17:51:12 2009 -0400
11.2 +++ b/extensions/sdktools/trnatives.cpp Fri Jul 24 12:34:31 2009 +1200
11.3 @@ -38,8 +38,7 @@
11.4 bool ShouldHitEntity(IHandleEntity *pEntity, int contentsMask)
11.5 {
11.6 cell_t res = 1;
11.7 - edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(pEntity));
11.8 - m_pFunc->PushCell(IndexOfEdict(pEdict));
11.9 + m_pFunc->PushCell(gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(pEntity)));
11.10 m_pFunc->PushCell(contentsMask);
11.11 m_pFunc->PushCell(m_Data);
11.12 m_pFunc->Execute(&res);
11.13 @@ -505,8 +504,7 @@
11.14 return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
11.15 }
11.16
11.17 - edict_t *pEdict = gameents->BaseEntityToEdict(tr->m_pEnt);
11.18 - return IndexOfEdict(pEdict);
11.19 + return gamehelpers->EntityToBCompatRef(tr->m_pEnt);
11.20 }
11.21
11.22 static cell_t smn_TRGetPointContents(IPluginContext *pContext, const cell_t *params)
11.23 @@ -532,8 +530,7 @@
11.24 #else
11.25 mask = enginetrace->GetPointContents(pos, &hentity);
11.26 #endif
11.27 - edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(hentity));
11.28 - *ent = IndexOfEdict(pEdict);
11.29 + *ent = gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(hentity));
11.30 }
11.31
11.32 return mask;
11.33 @@ -541,7 +538,8 @@
11.34
11.35 static cell_t smn_TRGetPointContentsEnt(IPluginContext *pContext, const cell_t *params)
11.36 {
11.37 - edict_t *pEdict = PEntityOfEntIndex(params[1]);
11.38 + /* TODO: See if we can get the collidable with a prop and remove the reliance on edicts */
11.39 + edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1]));
11.40 if (!pEdict || pEdict->IsFree())
11.41 {
11.42 return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
12.1 --- a/extensions/sdktools/vdecoder.cpp Thu Jul 09 17:51:12 2009 -0400
12.2 +++ b/extensions/sdktools/vdecoder.cpp Fri Jul 24 12:34:31 2009 +1200
12.3 @@ -222,8 +222,7 @@
12.4 CBaseEntity *pEntity = *(CBaseEntity **)buffer;
12.5 if (pEntity)
12.6 {
12.7 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
12.8 - *addr = IndexOfEdict(pEdict);
12.9 + *addr = gamehelpers->EntityToBCompatRef(pEntity);
12.10 } else {
12.11 *addr = -1;
12.12 }
12.13 @@ -384,16 +383,21 @@
12.14 }
12.15 case Valve_CBasePlayer:
12.16 {
12.17 - edict_t *pEdict;
12.18 + CBaseEntity *pEntity = NULL;
12.19 if (data->decflags & VDECODE_FLAG_BYREF)
12.20 {
12.21 cell_t *addr;
12.22 pContext->LocalToPhysAddr(param, &addr);
12.23 param = *addr;
12.24 }
12.25 - if (param >= 1 && param <= playerhelpers->GetMaxClients())
12.26 + int index = gamehelpers->ReferenceToIndex(param);
12.27 + if (index == INVALID_EHANDLE_INDEX && param != -1)
12.28 {
12.29 - IGamePlayer *player = playerhelpers->GetGamePlayer(param);
12.30 + return Data_Fail;
12.31 + }
12.32 + if (index >= 1 && index <= playerhelpers->GetMaxClients())
12.33 + {
12.34 + IGamePlayer *player = playerhelpers->GetGamePlayer(index);
12.35 if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
12.36 && !player->IsConnected())
12.37 {
12.38 @@ -403,44 +407,20 @@
12.39 pContext->ThrowNativeError("Client %d is not in game", param);
12.40 return Data_Fail;
12.41 }
12.42 - pEdict = player->GetEdict();
12.43 + pEntity = gamehelpers->ReferenceToEntity(param);
12.44 } else if (param == -1) {
12.45 if (data->decflags & VDECODE_FLAG_ALLOWNULL)
12.46 {
12.47 - pEdict = NULL;
12.48 + pEntity = NULL;
12.49 } else {
12.50 pContext->ThrowNativeError("NULL not allowed");
12.51 return Data_Fail;
12.52 }
12.53 - } else if (param == 0) {
12.54 - if (data->decflags & VDECODE_FLAG_ALLOWWORLD)
12.55 - {
12.56 - pEdict = PEntityOfEntIndex(0);
12.57 - } else {
12.58 - pContext->ThrowNativeError("World not allowed");
12.59 - return Data_Fail;
12.60 - }
12.61 } else {
12.62 pContext->ThrowNativeError("Entity index %d is not a valid client", param);
12.63 return Data_Fail;
12.64 }
12.65 - CBaseEntity *pEntity = NULL;
12.66 - if (pEdict)
12.67 - {
12.68 - IServerUnknown *pUnknown = pEdict->GetUnknown();
12.69 - if (!pUnknown)
12.70 - {
12.71 - pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", param);
12.72 - return Data_Fail;
12.73 - }
12.74 - pEntity = pUnknown->GetBaseEntity();
12.75 - if (!pEntity)
12.76 - {
12.77 - pContext->ThrowNativeError("Entity %d is not a CBaseEntity", param);
12.78 - return Data_Fail;
12.79 - }
12.80 - }
12.81 -
12.82 +
12.83 CBaseEntity **ebuf = (CBaseEntity **)buffer;
12.84 *ebuf = pEntity;
12.85
12.86 @@ -448,16 +428,21 @@
12.87 }
12.88 case Valve_CBaseEntity:
12.89 {
12.90 - edict_t *pEdict;
12.91 + CBaseEntity *pEntity = NULL;
12.92 if (data->decflags & VDECODE_FLAG_BYREF)
12.93 {
12.94 cell_t *addr;
12.95 pContext->LocalToPhysAddr(param, &addr);
12.96 param = *addr;
12.97 }
12.98 - if (param >= 1 && param <= playerhelpers->GetMaxClients())
12.99 + int index = gamehelpers->ReferenceToIndex(param);
12.100 + if (index == INVALID_EHANDLE_INDEX && param != -1)
12.101 {
12.102 - IGamePlayer *player = playerhelpers->GetGamePlayer(param);
12.103 + return Data_Fail;
12.104 + }
12.105 + if (index >= 1 && index <= playerhelpers->GetMaxClients())
12.106 + {
12.107 + IGamePlayer *player = playerhelpers->GetGamePlayer(index);
12.108 if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
12.109 && !player->IsConnected())
12.110 {
12.111 @@ -467,44 +452,28 @@
12.112 pContext->ThrowNativeError("Client %d is not in game", param);
12.113 return Data_Fail;
12.114 }
12.115 - pEdict = player->GetEdict();
12.116 + pEntity = gamehelpers->ReferenceToEntity(param);
12.117 } else if (param == -1) {
12.118 if (data->decflags & VDECODE_FLAG_ALLOWNULL)
12.119 {
12.120 - pEdict = NULL;
12.121 + pEntity = NULL;
12.122 } else {
12.123 pContext->ThrowNativeError("NULL not allowed");
12.124 return Data_Fail;
12.125 }
12.126 - } else if (param == 0) {
12.127 + } else if (index == 0) {
12.128 if (data->decflags & VDECODE_FLAG_ALLOWWORLD)
12.129 {
12.130 - pEdict = PEntityOfEntIndex(0);
12.131 + pEntity = gamehelpers->ReferenceToEntity(0);
12.132 } else {
12.133 pContext->ThrowNativeError("World not allowed");
12.134 return Data_Fail;
12.135 }
12.136 } else {
12.137 - pEdict = PEntityOfEntIndex(param);
12.138 - if (!pEdict || pEdict->IsFree())
12.139 - {
12.140 - pContext->ThrowNativeError("Entity %d is not valid or is freed", param);
12.141 - return Data_Fail;
12.142 - }
12.143 - }
12.144 - CBaseEntity *pEntity = NULL;
12.145 - if (pEdict)
12.146 - {
12.147 - IServerUnknown *pUnknown = pEdict->GetUnknown();
12.148 - if (!pUnknown)
12.149 - {
12.150 - pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", param);
12.151 - return Data_Fail;
12.152 - }
12.153 - pEntity = pUnknown->GetBaseEntity();
12.154 + pEntity = gamehelpers->ReferenceToEntity(param);
12.155 if (!pEntity)
12.156 {
12.157 - pContext->ThrowNativeError("Entity %d is not a CBaseEntity", param);
12.158 + pContext->ThrowNativeError("Entity %d is not valid", param);
12.159 return Data_Fail;
12.160 }
12.161 }
13.1 --- a/extensions/sdktools/vglobals.cpp Thu Jul 09 17:51:12 2009 -0400
13.2 +++ b/extensions/sdktools/vglobals.cpp Fri Jul 24 12:34:31 2009 +1200
13.3 @@ -34,54 +34,35 @@
13.4 void **g_pGameRules = NULL;
13.5 void *g_EntList = NULL;
13.6
13.7 -#ifdef PLATFORM_WINDOWS
13.8 +
13.9 void InitializeValveGlobals()
13.10 {
13.11 - char *addr = NULL;
13.12 - int offset;
13.13 + g_EntList = gamehelpers->GetGlobalEntityList();
13.14
13.15 - /* gEntList and/or g_pEntityList */
13.16 - if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr) || !addr)
13.17 - {
13.18 - return;
13.19 - }
13.20 - if (!g_pGameConf->GetOffset("gEntList", &offset) || !offset)
13.21 - {
13.22 - return;
13.23 - }
13.24 - g_EntList = *reinterpret_cast<void **>(addr + offset);
13.25 + char *addr;
13.26
13.27 +#ifdef PLATFORM_WINDOWS
13.28 /* g_pGameRules */
13.29 if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr)
13.30 {
13.31 return;
13.32 }
13.33 +
13.34 + int offset;
13.35 if (!g_pGameConf->GetOffset("g_pGameRules", &offset) || !offset)
13.36 {
13.37 return;
13.38 }
13.39 g_pGameRules = *reinterpret_cast<void ***>(addr + offset);
13.40 -}
13.41 #elif defined PLATFORM_LINUX
13.42 -void InitializeValveGlobals()
13.43 -{
13.44 - char *addr = NULL;
13.45 -
13.46 - /* gEntList and/or g_pEntityList */
13.47 - if (!g_pGameConf->GetMemSig("gEntList", (void **)&addr) || !addr)
13.48 - {
13.49 - return;
13.50 - }
13.51 - g_EntList = reinterpret_cast<void *>(addr);
13.52 -
13.53 /* g_pGameRules */
13.54 if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr)
13.55 {
13.56 return;
13.57 }
13.58 g_pGameRules = reinterpret_cast<void **>(addr);
13.59 +#endif
13.60 }
13.61 -#endif
13.62
13.63 size_t UTIL_StringToSignature(const char *str, char buffer[], size_t maxlength)
13.64 {
14.1 --- a/extensions/sdktools/vhelpers.cpp Thu Jul 09 17:51:12 2009 -0400
14.2 +++ b/extensions/sdktools/vhelpers.cpp Fri Jul 24 12:34:31 2009 +1200
14.3 @@ -241,13 +241,8 @@
14.4 return -1;
14.5 }
14.6
14.7 - edict_t *pTarget = gameents->BaseEntityToEdict(tr.m_pEnt);
14.8 - if (pTarget == NULL)
14.9 - {
14.10 - return -1;
14.11 - }
14.12 -
14.13 - int ent_index = IndexOfEdict(pTarget);
14.14 + int ent_ref = gamehelpers->EntityToBCompatRef(tr.m_pEnt);
14.15 + int ent_index = gamehelpers->ReferenceToIndex(ent_ref);
14.16
14.17 IGamePlayer *pTargetPlayer = playerhelpers->GetGamePlayer(ent_index);
14.18 if (pTargetPlayer != NULL && !pTargetPlayer->IsInGame())
14.19 @@ -259,7 +254,7 @@
14.20 return -1;
14.21 }
14.22
14.23 - return ent_index;
14.24 + return ent_ref;
14.25 }
14.26
14.27 bool IsEyeAnglesSupported()
15.1 --- a/extensions/sdktools/vnatives.cpp Thu Jul 09 17:51:12 2009 -0400
15.2 +++ b/extensions/sdktools/vnatives.cpp Fri Jul 24 12:34:31 2009 +1200
15.3 @@ -164,18 +164,7 @@
15.4 DECODE_VALVE_PARAM(3, vparams, 1);
15.5 FINISH_CALL_SIMPLE(&pEntity);
15.6
15.7 - if (pEntity == NULL)
15.8 - {
15.9 - return -1;
15.10 - }
15.11 -
15.12 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
15.13 - if (!pEdict)
15.14 - {
15.15 - return -1;
15.16 - }
15.17 -
15.18 - return IndexOfEdict(pEdict);
15.19 + return gamehelpers->EntityToBCompatRef(pEntity);
15.20 }
15.21
15.22 static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params)
15.23 @@ -200,18 +189,7 @@
15.24 DECODE_VALVE_PARAM(2, vparams, 0);
15.25 FINISH_CALL_SIMPLE(&pEntity);
15.26
15.27 - if (pEntity == NULL)
15.28 - {
15.29 - return -1;
15.30 - }
15.31 -
15.32 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
15.33 - if (!pEdict)
15.34 - {
15.35 - return -1;
15.36 - }
15.37 -
15.38 - return IndexOfEdict(pEdict);
15.39 + return gamehelpers->EntityToBCompatRef(pEntity);
15.40 }
15.41
15.42 #if SOURCE_ENGINE != SE_DARKMESSIAH
15.43 @@ -389,7 +367,7 @@
15.44 return pContext->ThrowNativeError("Client %d is not in game", params[1]);
15.45 }
15.46
15.47 - edict_t *pEdict = PEntityOfEntIndex(params[2]);
15.48 + edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1]));
15.49 if (!pEdict || pEdict->IsFree())
15.50 {
15.51 return pContext->ThrowNativeError("Entity %d is not valid", params[2]);
15.52 @@ -477,13 +455,12 @@
15.53 }
15.54
15.55 /* First check if the client is valid */
15.56 - int client = params[1];
15.57 - IGamePlayer *player = playerhelpers->GetGamePlayer(client);
15.58 + IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
15.59 if (!player)
15.60 {
15.61 - return pContext->ThrowNativeError("Client %d is not valid", client);
15.62 + return pContext->ThrowNativeError("Client %d is not valid", params[1]);
15.63 } else if (!player->IsInGame()) {
15.64 - return pContext->ThrowNativeError("Client %d is not in game", client);
15.65 + return pContext->ThrowNativeError("Client %d is not in game", params[1]);
15.66 }
15.67
15.68 edict_t *pEdict = player->GetEdict();
15.69 @@ -551,7 +528,7 @@
15.70 CellRecipientFilter rf;
15.71 rf.SetToReliable(true);
15.72 rf.Initialize(player_list, total_players);
15.73 - engsound->EmitSound(rf, client, CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos);
15.74 + engsound->EmitSound(rf, params[1], CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos);
15.75 }
15.76 }
15.77
15.78 @@ -619,16 +596,15 @@
15.79
15.80 static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params)
15.81 {
15.82 - int client = params[1];
15.83 - IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
15.84 + IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(params[1]);
15.85
15.86 if (!pPlayer)
15.87 {
15.88 - return pContext->ThrowNativeError("Invalid client index %d", client);
15.89 + return pContext->ThrowNativeError("Invalid client index %d", params[1]);
15.90 }
15.91 else if (!pPlayer->IsInGame())
15.92 {
15.93 - return pContext->ThrowNativeError("Client %d is not in game", client);
15.94 + return pContext->ThrowNativeError("Client %d is not in game", params[1]);
15.95 }
15.96
15.97 edict_t *pEdict = pPlayer->GetEdict();
15.98 @@ -678,18 +654,7 @@
15.99 DECODE_VALVE_PARAM(2, vparams, 1);
15.100 FINISH_CALL_SIMPLE(&pEntity);
15.101
15.102 - if (pEntity == NULL)
15.103 - {
15.104 - return -1;
15.105 - }
15.106 -
15.107 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
15.108 - if (!pEdict)
15.109 - {
15.110 - return -1;
15.111 - }
15.112 -
15.113 - return IndexOfEdict(pEdict);
15.114 + return gamehelpers->EntityToBCompatRef(pEntity);
15.115 }
15.116
15.117 #if SOURCE_ENGINE == SE_LEFT4DEAD
15.118 @@ -718,18 +683,7 @@
15.119 *(bool *)(vptr + 8) = true;
15.120 FINISH_CALL_SIMPLE(&pEntity);
15.121
15.122 - if (pEntity == NULL)
15.123 - {
15.124 - return -1;
15.125 - }
15.126 -
15.127 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
15.128 - if (!pEdict)
15.129 - {
15.130 - return -1;
15.131 - }
15.132 -
15.133 - return IndexOfEdict(pEdict);
15.134 + return gamehelpers->EntityToBCompatRef(pEntity);
15.135 }
15.136 #else
15.137 static cell_t CreateEntityByName(IPluginContext *pContext, const cell_t *params)
15.138 @@ -755,18 +709,7 @@
15.139 DECODE_VALVE_PARAM(2, vparams, 1);
15.140 FINISH_CALL_SIMPLE(&pEntity);
15.141
15.142 - if (pEntity == NULL)
15.143 - {
15.144 - return -1;
15.145 - }
15.146 -
15.147 - edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
15.148 - if (!pEdict)
15.149 - {
15.150 - return -1;
15.151 - }
15.152 -
15.153 - return IndexOfEdict(pEdict);
15.154 + return gamehelpers->EntityToBCompatRef(pEntity);
15.155 }
15.156 #endif
15.157
15.158 @@ -881,16 +824,15 @@
15.159
15.160 static cell_t sm_GetClientAimTarget(IPluginContext *pContext, const cell_t *params)
15.161 {
15.162 - int client = params[1];
15.163 - IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
15.164 + IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(params[1]);
15.165
15.166 if (!pPlayer)
15.167 {
15.168 - return pContext->ThrowNativeError("Invalid client index %d", client);
15.169 + return pContext->ThrowNativeError("Invalid client index %d", params[1]);
15.170 }
15.171 else if (!pPlayer->IsInGame())
15.172 {
15.173 - return pContext->ThrowNativeError("Client %d is not in game", client);
15.174 + return pContext->ThrowNativeError("Client %d is not in game", params[1]);
15.175 }
15.176
15.177 return GetClientAimTarget(pPlayer->GetEdict(), params[2] ? true : false);
16.1 --- a/extensions/sdktools/vsound.cpp Thu Jul 09 17:51:12 2009 -0400
16.2 +++ b/extensions/sdktools/vsound.cpp Fri Jul 24 12:34:31 2009 +1200
16.3 @@ -383,7 +383,7 @@
16.4 float vol, delay;
16.5 int pitch, flags, level;
16.6
16.7 - entity = params[3];
16.8 + entity = gamehelpers->ReferenceToIndex(params[3]);
16.9
16.10 cell_t *addr;
16.11 pContext->LocalToPhysAddr(params[2], &addr);
16.12 @@ -436,7 +436,7 @@
16.13
16.14 static cell_t StopSound(IPluginContext *pContext, const cell_t *params)
16.15 {
16.16 - int entity = params[1];
16.17 + int entity = gamehelpers->ReferenceToIndex(params[1]);
16.18 int channel = params[2];
16.19
16.20 char *name;
16.21 @@ -477,7 +477,7 @@
16.22 char *sample;
16.23 pContext->LocalToString(params[3], &sample);
16.24
16.25 - int entity = params[4];
16.26 + int entity = gamehelpers->ReferenceToIndex(params[4]);
16.27 int channel = params[5];
16.28 int level = params[6];
16.29 int flags = params[7];
16.30 @@ -648,7 +648,7 @@
16.31 crf.Initialize(addr, numClients);
16.32
16.33 int sentence = params[3];
16.34 - int entity = params[4];
16.35 + int entity = gamehelpers->ReferenceToIndex(params[4]);
16.36 int channel = params[5];
16.37 int level = params[6];
16.38 int flags = params[7];
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/gamedata/core.games/engine.darkm.txt Fri Jul 24 12:34:31 2009 +1200
17.3 @@ -0,0 +1,46 @@
17.4 +/**
17.5 + * Do not edit this file. Any changes will be overwritten by the gamedata
17.6 + * updater or by upgrading your SourceMod install.
17.7 + *
17.8 + * To override data in this file, create a subdirectory named "custom" and
17.9 + * place your own gamedata file(s) inside of it. Such files will be parsed
17.10 + * after SM's own.
17.11 + *
17.12 + * For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
17.13 + */
17.14 +
17.15 +"Games"
17.16 +{
17.17 + /* CGlobalEntityList */
17.18 + "#default"
17.19 + {
17.20 + "#supported"
17.21 + {
17.22 + "game" "!Might and Magic Multiplayer"
17.23 + }
17.24 +
17.25 + "Offsets"
17.26 + {
17.27 + /* Offset into LevelShutdown */
17.28 + "gEntList"
17.29 + {
17.30 + "windows" "11"
17.31 + }
17.32 +
17.33 + "EntInfo"
17.34 + {
17.35 + "windows" "4"
17.36 + "linux" "4"
17.37 + }
17.38 + }
17.39 +
17.40 + "Signatures"
17.41 + {
17.42 + "LevelShutdown"
17.43 + {
17.44 + "library" "server"
17.45 + "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
17.46 + }
17.47 + }
17.48 + }
17.49 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/gamedata/core.games/engine.ep1.txt Fri Jul 24 12:34:31 2009 +1200
18.3 @@ -0,0 +1,62 @@
18.4 +/**
18.5 + * Do not edit this file. Any changes will be overwritten by the gamedata
18.6 + * updater or by upgrading your SourceMod install.
18.7 + *
18.8 + * To override data in this file, create a subdirectory named "custom" and
18.9 + * place your own gamedata file(s) inside of it. Such files will be parsed
18.10 + * after SM's own.
18.11 + *
18.12 + * For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
18.13 + */
18.14 +
18.15 +"Games"
18.16 +{
18.17 + /* CGlobalEntityList */
18.18 + "#default"
18.19 + {
18.20 + "#supported"
18.21 + {
18.22 + "game" "cstrike"
18.23 + "game" "garrysmod"
18.24 + "game" "hl2mp"
18.25 + "game" "ship"
18.26 + "game" "insurgency"
18.27 + "game" "pvkii"
18.28 + "game" "sourceforts"
18.29 + "game" "FortressForever"
18.30 + "game" "empires"
18.31 + "game" "synergy"
18.32 + "game" "hidden"
18.33 + "game" "zombie_master"
18.34 + }
18.35 +
18.36 + "Offsets"
18.37 + {
18.38 + /* Offset into LevelShutdown */
18.39 + "gEntList"
18.40 + {
18.41 + "windows" "11"
18.42 + }
18.43 +
18.44 + "EntInfo"
18.45 + {
18.46 + "windows" "4"
18.47 + "linux" "4"
18.48 + }
18.49 + }
18.50 +
18.51 + "Signatures"
18.52 + {
18.53 + "LevelShutdown"
18.54 + {
18.55 + "library" "server"
18.56 + "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
18.57 + }
18.58 + "gEntList"
18.59 + {
18.60 + "library" "server"
18.61 + "linux" "@gEntList"
18.62 + }
18.63 + }
18.64 + }
18.65 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/gamedata/core.games/engine.ep2.txt Fri Jul 24 12:34:31 2009 +1200
19.3 @@ -0,0 +1,54 @@
19.4 +/**
19.5 + * Do not edit this file. Any changes will be overwritten by the gamedata
19.6 + * updater or by upgrading your SourceMod install.
19.7 + *
19.8 + * To override data in this file, create a subdirectory named "custom" and
19.9 + * place your own gamedata file(s) inside of it. Such files will be parsed
19.10 + * after SM's own.
19.11 + *
19.12 + * For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
19.13 + */
19.14 +
19.15 +"Games"
19.16 +{
19.17 + /* CGlobalEntityList */
19.18 + "#default"
19.19 + {
19.20 + "#supported"
19.21 + {
19.22 + "game" "dod"
19.23 + "game" "tf"
19.24 + "game" "ageofchivalry"
19.25 + "game" "ZPS"
19.26 + }
19.27 +
19.28 + "Offsets"
19.29 + {
19.30 + /* Offset into LevelShutdown */
19.31 + "gEntList"
19.32 + {
19.33 + "windows" "11"
19.34 + }
19.35 +
19.36 + "EntInfo"
19.37 + {
19.38 + "windows" "4"
19.39 + "linux" "4"
19.40 + }
19.41 + }
19.42 +
19.43 + "Signatures"
19.44 + {
19.45 + "LevelShutdown"
19.46 + {
19.47 + "library" "server"
19.48 + "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
19.49 + }
19.50 + "gEntList"
19.51 + {
19.52 + "library" "server"
19.53 + "linux" "@gEntList"
19.54 + }
19.55 + }
19.56 + }
19.57 +}
19.58 \ No newline at end of file
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/gamedata/core.games/engine.l4d.txt Fri Jul 24 12:34:31 2009 +1200
20.3 @@ -0,0 +1,51 @@
20.4 +/**
20.5 + * Do not edit this file. Any changes will be overwritten by the gamedata
20.6 + * updater or by upgrading your SourceMod install.
20.7 + *
20.8 + * To override data in this file, create a subdirectory named "custom" and
20.9 + * place your own gamedata file(s) inside of it. Such files will be parsed
20.10 + * after SM's own.
20.11 + *
20.12 + * For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(SourceMod)
20.13 + */
20.14 +
20.15 +"Games"
20.16 +{
20.17 + /* CGlobalEntityList */
20.18 + "#default"
20.19 + {
20.20 + "#supported"
20.21 + {
20.22 + "game" "left4dead"
20.23 + }
20.24 +
20.25 + "Offsets"
20.26 + {
20.27 + /* Offset into LevelShutdown */
20.28 + "gEntList"
20.29 + {
20.30 + "windows" "11"
20.31 + }
20.32 +
20.33 + "EntInfo"
20.34 + {
20.35 + "windows" "4"
20.36 + "linux" "4"
20.37 + }
20.38 + }
20.39 +
20.40 + "Signatures"
20.41 + {
20.42 + "LevelShutdown"
20.43 + {
20.44 + "library" "server"
20.45 + "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
20.46 + }
20.47 + "gEntList"
20.48 + {
20.49 + "library" "server"
20.50 + "linux" "@gEntList"
20.51 + }
20.52 + }
20.53 + }
20.54 +}
21.1 --- a/gamedata/core.games/master.games.txt Thu Jul 09 17:51:12 2009 -0400
21.2 +++ b/gamedata/core.games/master.games.txt Fri Jul 24 12:34:31 2009 +1200
21.3 @@ -14,4 +14,25 @@
21.4 "common.games.txt"
21.5 {
21.6 }
21.7 -}
21.8 +
21.9 + "engine.l4d.txt"
21.10 + {
21.11 + "engine" "left4dead"
21.12 + }
21.13 +
21.14 + "engine.ep2.txt"
21.15 + {
21.16 + "engine" "orangebox"
21.17 + }
21.18 +
21.19 + "engine.ep1.txt"
21.20 + {
21.21 + "engine" "original"
21.22 + }
21.23 +
21.24 + "engine.darkm.txt"
21.25 + {
21.26 + "engine" "darkmessiah"
21.27 + }
21.28 +
21.29 +}
21.30 \ No newline at end of file
22.1 --- a/gamedata/sdktools.games/engine.darkm.txt Thu Jul 09 17:51:12 2009 -0400
22.2 +++ b/gamedata/sdktools.games/engine.darkm.txt Fri Jul 24 12:34:31 2009 +1200
22.3 @@ -105,24 +105,9 @@
22.4 {
22.5 "game" "!Might and Magic Multiplayer"
22.6 }
22.7 -
22.8 - "Offsets"
22.9 - {
22.10 - /* Offset into LevelShutdown */
22.11 - "gEntList"
22.12 - {
22.13 - "windows" "11"
22.14 - }
22.15 - }
22.16 -
22.17 +
22.18 "Signatures"
22.19 {
22.20 - "LevelShutdown"
22.21 - {
22.22 - "library" "server"
22.23 - "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
22.24 - }
22.25 -
22.26 /* Functions in CGlobalEntityList */
22.27 "FindEntityByClassname"
22.28 {
22.29 @@ -239,7 +224,7 @@
22.30 /**
22.31 * CBaseClient::SetUserCVar(char const*,char const*);
22.32 * Linux offset straight from VTable dump.
22.33 - * Windows offset is crazy. Found the windows 'SetName' function using string "(%d)%-0.*s"
22.34 + * Windows offset is crazy. Found the windows SetName function using string "(%d)%-0.*s"
22.35 * Cross referenced back to the vtable and counted manually (SetUserCvar is 1 higher, offsets start from 1)
22.36 */
22.37 "SetUserCvar"
23.1 --- a/gamedata/sdktools.games/engine.ep1.txt Thu Jul 09 17:51:12 2009 -0400
23.2 +++ b/gamedata/sdktools.games/engine.ep1.txt Fri Jul 24 12:34:31 2009 +1200
23.3 @@ -139,28 +139,8 @@
23.4 "game" "zombie_master"
23.5 }
23.6
23.7 - "Offsets"
23.8 - {
23.9 - /* Offset into LevelShutdown */
23.10 - "gEntList"
23.11 - {
23.12 - "windows" "11"
23.13 - }
23.14 - }
23.15 -
23.16 "Signatures"
23.17 - {
23.18 - "LevelShutdown"
23.19 - {
23.20 - "library" "server"
23.21 - "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
23.22 - }
23.23 - "gEntList"
23.24 - {
23.25 - "library" "server"
23.26 - "linux" "@gEntList"
23.27 - }
23.28 -
23.29 + {
23.30 /* Functions in CGlobalEntityList */
23.31 "FindEntityByClassname"
23.32 {
23.33 @@ -288,7 +268,7 @@
23.34 /**
23.35 * CBaseClient::SetUserCVar(char const*,char const*);
23.36 * Linux offset straight from VTable dump.
23.37 - * Windows offset is crazy. Found the windows 'SetName' function using string "(%d)%-0.*s"
23.38 + * Windows offset is crazy. Found the windows SetName function using string "(%d)%-0.*s"
23.39 * Cross referenced back to the vtable and counted manually (SetUserCvar is 1 higher, offsets start from 1)
23.40 */
23.41 "SetUserCvar"
24.1 --- a/gamedata/sdktools.games/engine.ep2.txt Thu Jul 09 17:51:12 2009 -0400
24.2 +++ b/gamedata/sdktools.games/engine.ep2.txt Fri Jul 24 12:34:31 2009 +1200
24.3 @@ -100,28 +100,8 @@
24.4 "game" "ZPS"
24.5 }
24.6
24.7 - "Offsets"
24.8 - {
24.9 - /* Offset into LevelShutdown */
24.10 - "gEntList"
24.11 - {
24.12 - "windows" "11"
24.13 - }
24.14 - }
24.15 -
24.16 "Signatures"
24.17 {
24.18 - "LevelShutdown"
24.19 - {
24.20 - "library" "server"
24.21 - "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
24.22 - }
24.23 - "gEntList"
24.24 - {
24.25 - "library" "server"
24.26 - "linux" "@gEntList"
24.27 - }
24.28 -
24.29 /* Functions in CGlobalEntityList */
24.30 "FindEntityByClassname"
24.31 {
24.32 @@ -261,7 +241,7 @@
24.33 /**
24.34 * CBaseClient::SetUserCVar(char const*,char const*);
24.35 * Linux offset straight from VTable dump.
24.36 - * Windows offset is crazy. Found the windows 'SetName' function using string "(%d)%-0.*s"
24.37 + * Windows offset is crazy. Found the windows SetName function using string "(%d)%-0.*s"
24.38 * Cross referenced back to the vtable and counted manually (SetUserCvar is 1 higher, offsets start from 1)
24.39 */
24.40 "SetUserCvar"
25.1 --- a/gamedata/sdktools.games/engine.l4d.txt Thu Jul 09 17:51:12 2009 -0400
25.2 +++ b/gamedata/sdktools.games/engine.l4d.txt Fri Jul 24 12:34:31 2009 +1200
25.3 @@ -101,29 +101,9 @@
25.4 {
25.5 "game" "left4dead"
25.6 }
25.7 -
25.8 - "Offsets"
25.9 - {
25.10 - /* Offset into LevelShutdown */
25.11 - "gEntList"
25.12 - {
25.13 - "windows" "11"
25.14 - }
25.15 - }
25.16 -
25.17 +
25.18 "Signatures"
25.19 {
25.20 - "LevelShutdown"
25.21 - {
25.22 - "library" "server"
25.23 - "windows" "\xE8\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\xE8"
25.24 - }
25.25 - "gEntList"
25.26 - {
25.27 - "library" "server"
25.28 - "linux" "@gEntList"
25.29 - }
25.30 -
25.31 /* Functions in CGlobalEntityList */
25.32 "FindEntityByClassname"
25.33 {
25.34 @@ -258,7 +238,7 @@
25.35 /**
25.36 * CBaseClient::SetUserCVar(char const*,char const*);
25.37 * Linux offset straight from VTable dump.
25.38 - * Windows offset is crazy. Found the windows 'SetName' function using string "(%d)%-0.*s"
25.39 + * Windows offset is crazy. Found the windows SetName function using string "(%d)%-0.*s"
25.40 * Cross referenced back to the vtable and counted manually (SetUserCvar is 1 higher, offsets start from 1)
25.41 */
25.42 "SetUserCvar"
26.1 --- a/plugins/include/halflife.inc Thu Jul 09 17:51:12 2009 -0400
26.2 +++ b/plugins/include/halflife.inc Fri Jul 24 12:34:31 2009 +1200
26.3 @@ -56,6 +56,8 @@
26.4 DialogType_AskConnect /**< ask the client to connect to a specified IP */
26.5 };
26.6
26.7 +#define INVALID_ENT_REFERENCE 0xFFFFFFFF
26.8 +
26.9 /**
26.10 * Logs a generic message to the HL2 logs.
26.11 *
26.12 @@ -544,3 +546,28 @@
26.13 CreateDialog(client, Kv, DialogType_AskConnect);
26.14 CloseHandle(Kv);
26.15 }
26.16 +
26.17 +/**
26.18 + * Converts an entity index into a serial encoded entity reference.
26.19 + *
26.20 + * @param entity Entity index.
26.21 + * @return Entity reference.
26.22 + */
26.23 +native EntIndexToEntRef(entity);
26.24 +
26.25 +/**
26.26 + * Retrieves the entity index from a reference.
26.27 + *
26.28 + * @param ref Entity reference.
26.29 + * @return Entity index.
26.30 + */
26.31 +native EntRefToEntIndex(ref);
26.32 +
26.33 +/**
26.34 + * Converts a reference into a backwards compatible version.
26.35 + *
26.36 + * @param ref Entity reference.
26.37 + * @return Bcompat reference.
26.38 + */
26.39 +native MakeCompatEntRef(ref);
26.40 +
27.1 --- a/public/IGameHelpers.h Thu Jul 09 17:51:12 2009 -0400
27.2 +++ b/public/IGameHelpers.h Fri Jul 24 12:34:31 2009 +1200
27.3 @@ -193,6 +193,63 @@
27.4 * @param buffer Command buffer (does not auto \n terminate).
27.5 */
27.6 virtual void ServerCommand(const char *buffer) =0;
27.7 +
27.8 + /**
27.9 + * @brief Looks up a reference and returns the CBasseEntity* it points to.
27.10 + *
27.11 + * @note Supports 'old style' simple indexes and does a serial confirmation check on references.
27.12 + *
27.13 + * @param entRef Entity reference.
27.14 + * @return Entity pointer.
27.15 + */
27.16 + virtual CBaseEntity *ReferenceToEntity(cell_t entRef) =0;
27.17 +
27.18 + /**
27.19 + * @brief Returns the entity reference for an entity.
27.20 + *
27.21 + * @param pEntity Entity pointer.
27.22 + * @return Entity reference.
27.23 + */
27.24 + virtual cell_t EntityToReference(CBaseEntity *pEntity) =0;
27.25 +
27.26 + /**
27.27 + * @brief Returns the entity reference for logical entities, or the index for networked entities.
27.28 + *
27.29 + * @param pEntity Entity pointer.
27.30 + * @return Entity reference/index.
27.31 + */
27.32 + virtual cell_t EntityToBCompatRef(CBaseEntity *pEntity) =0;
27.33 +
27.34 + /**
27.35 + * @brief Converts an entity index into an entity reference.
27.36 + *
27.37 + * @param entIndex Entity index.
27.38 + * @return Entity reference.
27.39 + */
27.40 + virtual cell_t IndexToReference(int entIndex) =0;
27.41 +
27.42 + /**
27.43 + * @brief Retrieves the entity index from a reference.
27.44 + *
27.45 + * @param entRef Entity reference.
27.46 + * @return Entity index.
27.47 + */
27.48 + virtual int ReferenceToIndex(cell_t entRef) =0;
27.49 +
27.50 + /**
27.51 + * @brief Converts a reference into a bcompat version (index for networked entities).
27.52 + *
27.53 + * @param entRef Entity reference.
27.54 + * @return Entity reference/index.
27.55 + */
27.56 + virtual cell_t ReferenceToBCompatRef(cell_t entRef) =0;
27.57 +
27.58 + /**
27.59 + * @brief Returns the g_EntList pointer.
27.60 + *
27.61 + * @return g_EntList pointer.
27.62 + */
27.63 + virtual void *GetGlobalEntityList() =0;
27.64 };
27.65 }
27.66