Added support for logical (non-networked) entities using entity references - See http://wiki.alliedmods.net/Entity_References_%28SourceMod%29 (bug 2459, r=dvander)

This commit is contained in:
Matt Woodrow
2009-07-24 12:34:31 +12:00
parent 7ec656db09
commit 3e36382b58
27 changed files with 863 additions and 480 deletions
+3 -17
View File
@@ -37,21 +37,11 @@
ICallWrapper *g_pAcceptInput = NULL;
unsigned char g_Variant_t[SIZEOF_VARIANT_T] = {0};
#define ENTINDEX_TO_CBASEENTITY(index, buffer) \
pEdict = PEntityOfEntIndex(index); \
if (!pEdict || pEdict->IsFree()) \
{ \
return pContext->ThrowNativeError("Entity %d is not valid or is freed", index); \
} \
pUnk = pEdict->GetUnknown(); \
if (!pUnk) \
{ \
return pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", index); \
} \
buffer = pUnk->GetBaseEntity(); \
#define ENTINDEX_TO_CBASEENTITY(ref, buffer) \
buffer = gamehelpers->ReferenceToEntity(ref); \
if (!buffer) \
{ \
return pContext->ThrowNativeError("Entity %d is not a CBaseEntity", index); \
return pContext->ThrowNativeError("Entity %d (%d) is not a CBaseEntity", gamehelpers->ReferenceToIndex(ref), ref); \
}
/* Hack to init the variant_t object for the first time */
@@ -109,8 +99,6 @@ static cell_t AcceptEntityInput(IPluginContext *pContext, const cell_t *params)
}
CBaseEntity *pActivator, *pCaller, *pDest;
edict_t *pEdict;
IServerUnknown *pUnk;
char *inputname;
unsigned char vstk[sizeof(void *) + sizeof(const char *) + sizeof(CBaseEntity *)*2 + SIZEOF_VARIANT_T + sizeof(int)];
@@ -257,8 +245,6 @@ static cell_t SetVariantColor(IPluginContext *pContext, const cell_t *params)
static cell_t SetVariantEntity(IPluginContext *pContext, const cell_t *params)
{
CBaseEntity *pEntity;
edict_t *pEdict;
IServerUnknown *pUnk;
unsigned char *vptr = g_Variant_t;
CBaseHandle bHandle;
+19 -54
View File
@@ -205,20 +205,12 @@ void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator
// attempt to directly lookup a hook using the pOutput pointer
OutputNameStruct *pOutputName = NULL;
edict_t *pEdict = gameents->BaseEntityToEdict(pCaller);
/* TODO: Add support for entities without an edict */
if (pEdict == NULL)
{
return;
}
bool fastLookup = false;
// Fast lookup failed - check the slow way for hooks that havn't fired yet
if ((fastLookup = EntityOutputs->Retrieve(sOutput, (void **)&pOutputName)) == false)
{
const char *classname = pEdict->GetClassName();
const char *classname = GetEntityClassname(pCaller);
const char *outputname = FindOutputName(pOutput, pCaller);
pOutputName = FindOutputPointer(classname, outputname, false);
@@ -249,37 +241,31 @@ void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator
hook->in_use = true;
int serial = pEdict->m_NetworkSerialNumber;
cell_t ref = gamehelpers->EntityToReference(pCaller);
if (serial != hook->entity_filter && hook->entity_index == IndexOfEdict(pEdict))
if (hook->entity_ref != -1
&& gamehelpers->ReferenceToIndex(hook->entity_ref) == gamehelpers->ReferenceToIndex(ref)
&& ref != hook->entity_ref)
{
// same entity index but different serial number. Entity has changed, kill the hook.
// same entity index but different reference. Entity has changed, kill the hook.
_iter = pOutputName->hooks.erase(_iter);
CleanUpHook(hook);
continue;
}
if (hook->entity_filter == -1 || hook->entity_filter == serial) // Global classname hook
if (hook->entity_ref == -1 || hook->entity_ref == ref) // Global classname hook
{
//fire the forward to hook->pf
hook->pf->PushString(pOutputName->Name);
hook->pf->PushCell(IndexOfEdict(pEdict));
edict_t *pEdictActivator = gameents->BaseEntityToEdict(pActivator);
if (!pEdictActivator)
{
hook->pf->PushCell(-1);
}
else
{
hook->pf->PushCell(IndexOfEdict(pEdictActivator));
}
hook->pf->PushCell(gamehelpers->ReferenceToBCompatRef(ref));
hook->pf->PushCell(gamehelpers->EntityToBCompatRef(pActivator));
//hook->pf->PushCell(handle);
hook->pf->PushFloat(fDelay);
hook->pf->Execute(NULL);
if ((hook->entity_filter != -1) && hook->only_once)
if ((hook->entity_ref != -1) && hook->only_once)
{
_iter = pOutputName->hooks.erase(_iter);
CleanUpHook(hook);
@@ -454,36 +440,15 @@ const char *EntityOutputManager::FindOutputName(void *pOutput, CBaseEntity *pCal
return NULL;
}
// Thanks SM core
edict_t *EntityOutputManager::BaseHandleToEdict(CBaseHandle &hndl)
const char *EntityOutputManager::GetEntityClassname(CBaseEntity *pEntity)
{
if (!hndl.IsValid())
static int offset = -1;
if (offset == -1)
{
return NULL;
datamap_t *pMap = gamehelpers->GetDataMap(pEntity);
typedescription_t *pDesc = gamehelpers->FindInDataMap(pMap, "m_iClassname");
offset = pDesc->fieldOffset[TD_OFFSET_NORMAL];
}
int index = hndl.GetEntryIndex();
edict_t *pStoredEdict;
pStoredEdict = PEntityOfEntIndex(index);
if (pStoredEdict == NULL)
{
return NULL;
}
IServerEntity *pSE = pStoredEdict->GetIServerEntity();
if (pSE == NULL)
{
return NULL;
}
if (pSE->GetRefEHandle() != hndl)
{
return NULL;
}
return pStoredEdict;
}
return (const char *)(((unsigned char *)pEntity) + offset);
}
+3 -3
View File
@@ -49,8 +49,7 @@ struct OutputNameStruct;
*/
struct omg_hooks
{
int entity_filter; // if not -1 is an entity signature
int entity_index;
cell_t entity_ref;
bool only_once;
IPluginFunction *pf;
OutputNameStruct *m_parent;
@@ -110,6 +109,8 @@ public:
void OnHookAdded();
void OnHookRemoved();
const char *GetEntityClassname(CBaseEntity *pEntity);
private:
bool enabled;
@@ -123,7 +124,6 @@ private:
void DeleteFireEventDetour();
const char *FindOutputName(void *pOutput, CBaseEntity *pCaller);
edict_t *BaseHandleToEdict(CBaseHandle &hndl);
//Maps CEntityOutput * to a OutputNameStruct
IBasicTrie *EntityOutputs;
+16 -15
View File
@@ -40,12 +40,13 @@ cell_t HookSingleEntityOutput(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details");
}
edict_t *pEdict = PEntityOfEntIndex(params[1]);
if (!pEdict)
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(params[1]);
if (!pEntity)
{
return pContext->ThrowNativeError("Invalid Entity index %i", params[1]);
return pContext->ThrowNativeError("Invalid Entity index %i (%i)", gamehelpers->ReferenceToIndex(params[1]), params[1]);
}
const char *classname = pEdict->GetClassName();
const char *classname = g_OutputManager.GetEntityClassname(pEntity);
char *outputname;
pContext->LocalToString(params[2], &outputname);
@@ -63,7 +64,7 @@ cell_t HookSingleEntityOutput(IPluginContext *pContext, const cell_t *params)
for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
{
hook = (omg_hooks *)*_iter;
if (hook->pf == pFunction && hook->entity_filter == pEdict->m_NetworkSerialNumber)
if (hook->pf == pFunction && hook->entity_ref == gamehelpers->EntityToReference(pEntity))
{
return 0;
}
@@ -71,8 +72,7 @@ cell_t HookSingleEntityOutput(IPluginContext *pContext, const cell_t *params)
hook = g_OutputManager.NewHook();
hook->entity_filter = pEdict->m_NetworkSerialNumber;
hook->entity_index = IndexOfEdict(pEdict);
hook->entity_ref = gamehelpers->EntityToReference(pEntity);
hook->only_once= !!params[4];
hook->pf = pFunction;
hook->m_parent = pOutputName;
@@ -125,7 +125,7 @@ cell_t HookEntityOutput(IPluginContext *pContext, const cell_t *params)
for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
{
hook = (omg_hooks *)*_iter;
if (hook->pf == pFunction && hook->entity_filter == -1)
if (hook->pf == pFunction && hook->entity_ref == -1)
{
//already hooked to this function...
//throw an error or just let them get away with stupidity?
@@ -136,7 +136,7 @@ cell_t HookEntityOutput(IPluginContext *pContext, const cell_t *params)
hook = g_OutputManager.NewHook();
hook->entity_filter = -1;
hook->entity_ref = -1;
hook->pf = pFunction;
hook->m_parent = pOutputName;
hook->in_use = false;
@@ -192,7 +192,7 @@ cell_t UnHookEntityOutput(IPluginContext *pContext, const cell_t *params)
for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
{
hook = (omg_hooks *)*_iter;
if (hook->pf == pFunction && hook->entity_filter == -1)
if (hook->pf == pFunction && hook->entity_ref == -1)
{
// remove this hook.
if (hook->in_use)
@@ -220,13 +220,13 @@ cell_t UnHookSingleEntityOutput(IPluginContext *pContext, const cell_t *params)
}
// Find the classname of the entity and lookup the classname and output structures
edict_t *pEdict = PEntityOfEntIndex(params[1]);
if (!pEdict)
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(params[1]);
if (!pEntity)
{
return pContext->ThrowNativeError("Invalid Entity index %i", params[1]);
return pContext->ThrowNativeError("Invalid Entity index %i (%i)", gamehelpers->ReferenceToIndex(params[1]), params[1]);
}
const char *classname = pEdict->GetClassName();
const char *classname = g_OutputManager.GetEntityClassname(pEntity);
char *outputname;
pContext->LocalToString(params[2], &outputname);
@@ -249,7 +249,8 @@ cell_t UnHookSingleEntityOutput(IPluginContext *pContext, const cell_t *params)
for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
{
hook = (omg_hooks *)*_iter;
if (hook->pf == pFunction && hook->entity_index == IndexOfEdict(pEdict))
/* We're not serial checking and just removing by index here - This was always allowed so is left for bcompat */
if (hook->pf == pFunction && gamehelpers->ReferenceToIndex(hook->entity_ref) == gamehelpers->ReferenceToIndex(params[1]))
{
// remove this hook.
if (hook->in_use)
+5 -7
View File
@@ -38,8 +38,7 @@ public:
bool ShouldHitEntity(IHandleEntity *pEntity, int contentsMask)
{
cell_t res = 1;
edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(pEntity));
m_pFunc->PushCell(IndexOfEdict(pEdict));
m_pFunc->PushCell(gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(pEntity)));
m_pFunc->PushCell(contentsMask);
m_pFunc->PushCell(m_Data);
m_pFunc->Execute(&res);
@@ -505,8 +504,7 @@ static cell_t smn_TRGetEntityIndex(IPluginContext *pContext, const cell_t *param
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
}
edict_t *pEdict = gameents->BaseEntityToEdict(tr->m_pEnt);
return IndexOfEdict(pEdict);
return gamehelpers->EntityToBCompatRef(tr->m_pEnt);
}
static cell_t smn_TRGetPointContents(IPluginContext *pContext, const cell_t *params)
@@ -532,8 +530,7 @@ static cell_t smn_TRGetPointContents(IPluginContext *pContext, const cell_t *par
#else
mask = enginetrace->GetPointContents(pos, &hentity);
#endif
edict_t *pEdict = gameents->BaseEntityToEdict(reinterpret_cast<CBaseEntity *>(hentity));
*ent = IndexOfEdict(pEdict);
*ent = gamehelpers->EntityToBCompatRef(reinterpret_cast<CBaseEntity *>(hentity));
}
return mask;
@@ -541,7 +538,8 @@ static cell_t smn_TRGetPointContents(IPluginContext *pContext, const cell_t *par
static cell_t smn_TRGetPointContentsEnt(IPluginContext *pContext, const cell_t *params)
{
edict_t *pEdict = PEntityOfEntIndex(params[1]);
/* TODO: See if we can get the collidable with a prop and remove the reliance on edicts */
edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1]));
if (!pEdict || pEdict->IsFree())
{
return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
+26 -57
View File
@@ -222,8 +222,7 @@ DataStatus EncodeValveParam(IPluginContext *pContext,
CBaseEntity *pEntity = *(CBaseEntity **)buffer;
if (pEntity)
{
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
*addr = IndexOfEdict(pEdict);
*addr = gamehelpers->EntityToBCompatRef(pEntity);
} else {
*addr = -1;
}
@@ -384,16 +383,21 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
}
case Valve_CBasePlayer:
{
edict_t *pEdict;
CBaseEntity *pEntity = NULL;
if (data->decflags & VDECODE_FLAG_BYREF)
{
cell_t *addr;
pContext->LocalToPhysAddr(param, &addr);
param = *addr;
}
if (param >= 1 && param <= playerhelpers->GetMaxClients())
int index = gamehelpers->ReferenceToIndex(param);
if (index == INVALID_EHANDLE_INDEX && param != -1)
{
IGamePlayer *player = playerhelpers->GetGamePlayer(param);
return Data_Fail;
}
if (index >= 1 && index <= playerhelpers->GetMaxClients())
{
IGamePlayer *player = playerhelpers->GetGamePlayer(index);
if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
&& !player->IsConnected())
{
@@ -403,44 +407,20 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
pContext->ThrowNativeError("Client %d is not in game", param);
return Data_Fail;
}
pEdict = player->GetEdict();
pEntity = gamehelpers->ReferenceToEntity(param);
} else if (param == -1) {
if (data->decflags & VDECODE_FLAG_ALLOWNULL)
{
pEdict = NULL;
pEntity = NULL;
} else {
pContext->ThrowNativeError("NULL not allowed");
return Data_Fail;
}
} else if (param == 0) {
if (data->decflags & VDECODE_FLAG_ALLOWWORLD)
{
pEdict = PEntityOfEntIndex(0);
} else {
pContext->ThrowNativeError("World not allowed");
return Data_Fail;
}
} else {
pContext->ThrowNativeError("Entity index %d is not a valid client", param);
return Data_Fail;
}
CBaseEntity *pEntity = NULL;
if (pEdict)
{
IServerUnknown *pUnknown = pEdict->GetUnknown();
if (!pUnknown)
{
pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", param);
return Data_Fail;
}
pEntity = pUnknown->GetBaseEntity();
if (!pEntity)
{
pContext->ThrowNativeError("Entity %d is not a CBaseEntity", param);
return Data_Fail;
}
}
CBaseEntity **ebuf = (CBaseEntity **)buffer;
*ebuf = pEntity;
@@ -448,16 +428,21 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
}
case Valve_CBaseEntity:
{
edict_t *pEdict;
CBaseEntity *pEntity = NULL;
if (data->decflags & VDECODE_FLAG_BYREF)
{
cell_t *addr;
pContext->LocalToPhysAddr(param, &addr);
param = *addr;
}
if (param >= 1 && param <= playerhelpers->GetMaxClients())
int index = gamehelpers->ReferenceToIndex(param);
if (index == INVALID_EHANDLE_INDEX && param != -1)
{
IGamePlayer *player = playerhelpers->GetGamePlayer(param);
return Data_Fail;
}
if (index >= 1 && index <= playerhelpers->GetMaxClients())
{
IGamePlayer *player = playerhelpers->GetGamePlayer(index);
if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
&& !player->IsConnected())
{
@@ -467,44 +452,28 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
pContext->ThrowNativeError("Client %d is not in game", param);
return Data_Fail;
}
pEdict = player->GetEdict();
pEntity = gamehelpers->ReferenceToEntity(param);
} else if (param == -1) {
if (data->decflags & VDECODE_FLAG_ALLOWNULL)
{
pEdict = NULL;
pEntity = NULL;
} else {
pContext->ThrowNativeError("NULL not allowed");
return Data_Fail;
}
} else if (param == 0) {
} else if (index == 0) {
if (data->decflags & VDECODE_FLAG_ALLOWWORLD)
{
pEdict = PEntityOfEntIndex(0);
pEntity = gamehelpers->ReferenceToEntity(0);
} else {
pContext->ThrowNativeError("World not allowed");
return Data_Fail;
}
} else {
pEdict = PEntityOfEntIndex(param);
if (!pEdict || pEdict->IsFree())
{
pContext->ThrowNativeError("Entity %d is not valid or is freed", param);
return Data_Fail;
}
}
CBaseEntity *pEntity = NULL;
if (pEdict)
{
IServerUnknown *pUnknown = pEdict->GetUnknown();
if (!pUnknown)
{
pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", param);
return Data_Fail;
}
pEntity = pUnknown->GetBaseEntity();
pEntity = gamehelpers->ReferenceToEntity(param);
if (!pEntity)
{
pContext->ThrowNativeError("Entity %d is not a CBaseEntity", param);
pContext->ThrowNativeError("Entity %d is not valid", param);
return Data_Fail;
}
}
+7 -26
View File
@@ -34,54 +34,35 @@
void **g_pGameRules = NULL;
void *g_EntList = NULL;
#ifdef PLATFORM_WINDOWS
void InitializeValveGlobals()
{
char *addr = NULL;
int offset;
g_EntList = gamehelpers->GetGlobalEntityList();
/* gEntList and/or g_pEntityList */
if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr) || !addr)
{
return;
}
if (!g_pGameConf->GetOffset("gEntList", &offset) || !offset)
{
return;
}
g_EntList = *reinterpret_cast<void **>(addr + offset);
char *addr;
#ifdef PLATFORM_WINDOWS
/* g_pGameRules */
if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr)
{
return;
}
int offset;
if (!g_pGameConf->GetOffset("g_pGameRules", &offset) || !offset)
{
return;
}
g_pGameRules = *reinterpret_cast<void ***>(addr + offset);
}
#elif defined PLATFORM_LINUX
void InitializeValveGlobals()
{
char *addr = NULL;
/* gEntList and/or g_pEntityList */
if (!g_pGameConf->GetMemSig("gEntList", (void **)&addr) || !addr)
{
return;
}
g_EntList = reinterpret_cast<void *>(addr);
/* g_pGameRules */
if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr)
{
return;
}
g_pGameRules = reinterpret_cast<void **>(addr);
}
#endif
}
size_t UTIL_StringToSignature(const char *str, char buffer[], size_t maxlength)
{
+3 -8
View File
@@ -241,13 +241,8 @@ int GetClientAimTarget(edict_t *pEdict, bool only_players)
return -1;
}
edict_t *pTarget = gameents->BaseEntityToEdict(tr.m_pEnt);
if (pTarget == NULL)
{
return -1;
}
int ent_index = IndexOfEdict(pTarget);
int ent_ref = gamehelpers->EntityToBCompatRef(tr.m_pEnt);
int ent_index = gamehelpers->ReferenceToIndex(ent_ref);
IGamePlayer *pTargetPlayer = playerhelpers->GetGamePlayer(ent_index);
if (pTargetPlayer != NULL && !pTargetPlayer->IsInGame())
@@ -259,7 +254,7 @@ int GetClientAimTarget(edict_t *pEdict, bool only_players)
return -1;
}
return ent_index;
return ent_ref;
}
bool IsEyeAnglesSupported()
+16 -74
View File
@@ -164,18 +164,7 @@ static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
DECODE_VALVE_PARAM(3, vparams, 1);
FINISH_CALL_SIMPLE(&pEntity);
if (pEntity == NULL)
{
return -1;
}
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
if (!pEdict)
{
return -1;
}
return IndexOfEdict(pEdict);
return gamehelpers->EntityToBCompatRef(pEntity);
}
static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params)
@@ -200,18 +189,7 @@ static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params
DECODE_VALVE_PARAM(2, vparams, 0);
FINISH_CALL_SIMPLE(&pEntity);
if (pEntity == NULL)
{
return -1;
}
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
if (!pEdict)
{
return -1;
}
return IndexOfEdict(pEdict);
return gamehelpers->EntityToBCompatRef(pEntity);
}
#if SOURCE_ENGINE != SE_DARKMESSIAH
@@ -389,7 +367,7 @@ static cell_t SetClientViewEntity(IPluginContext *pContext, const cell_t *params
return pContext->ThrowNativeError("Client %d is not in game", params[1]);
}
edict_t *pEdict = PEntityOfEntIndex(params[2]);
edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1]));
if (!pEdict || pEdict->IsFree())
{
return pContext->ThrowNativeError("Entity %d is not valid", params[2]);
@@ -477,13 +455,12 @@ static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params)
}
/* First check if the client is valid */
int client = params[1];
IGamePlayer *player = playerhelpers->GetGamePlayer(client);
IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
if (!player)
{
return pContext->ThrowNativeError("Client %d is not valid", client);
return pContext->ThrowNativeError("Client %d is not valid", params[1]);
} else if (!player->IsInGame()) {
return pContext->ThrowNativeError("Client %d is not in game", client);
return pContext->ThrowNativeError("Client %d is not in game", params[1]);
}
edict_t *pEdict = player->GetEdict();
@@ -551,7 +528,7 @@ static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params)
CellRecipientFilter rf;
rf.SetToReliable(true);
rf.Initialize(player_list, total_players);
engsound->EmitSound(rf, client, CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos);
engsound->EmitSound(rf, params[1], CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos);
}
}
@@ -619,16 +596,15 @@ static cell_t GetClientEyePosition(IPluginContext *pContext, const cell_t *param
static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(params[1]);
if (!pPlayer)
{
return pContext->ThrowNativeError("Invalid client index %d", client);
return pContext->ThrowNativeError("Invalid client index %d", params[1]);
}
else if (!pPlayer->IsInGame())
{
return pContext->ThrowNativeError("Client %d is not in game", client);
return pContext->ThrowNativeError("Client %d is not in game", params[1]);
}
edict_t *pEdict = pPlayer->GetEdict();
@@ -678,18 +654,7 @@ static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *para
DECODE_VALVE_PARAM(2, vparams, 1);
FINISH_CALL_SIMPLE(&pEntity);
if (pEntity == NULL)
{
return -1;
}
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
if (!pEdict)
{
return -1;
}
return IndexOfEdict(pEdict);
return gamehelpers->EntityToBCompatRef(pEntity);
}
#if SOURCE_ENGINE == SE_LEFT4DEAD
@@ -718,18 +683,7 @@ static cell_t CreateEntityByName(IPluginContext *pContext, const cell_t *params)
*(bool *)(vptr + 8) = true;
FINISH_CALL_SIMPLE(&pEntity);
if (pEntity == NULL)
{
return -1;
}
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
if (!pEdict)
{
return -1;
}
return IndexOfEdict(pEdict);
return gamehelpers->EntityToBCompatRef(pEntity);
}
#else
static cell_t CreateEntityByName(IPluginContext *pContext, const cell_t *params)
@@ -755,18 +709,7 @@ static cell_t CreateEntityByName(IPluginContext *pContext, const cell_t *params)
DECODE_VALVE_PARAM(2, vparams, 1);
FINISH_CALL_SIMPLE(&pEntity);
if (pEntity == NULL)
{
return -1;
}
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
if (!pEdict)
{
return -1;
}
return IndexOfEdict(pEdict);
return gamehelpers->EntityToBCompatRef(pEntity);
}
#endif
@@ -881,16 +824,15 @@ static cell_t DispatchKeyValueVector(IPluginContext *pContext, const cell_t *par
static cell_t sm_GetClientAimTarget(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(params[1]);
if (!pPlayer)
{
return pContext->ThrowNativeError("Invalid client index %d", client);
return pContext->ThrowNativeError("Invalid client index %d", params[1]);
}
else if (!pPlayer->IsInGame())
{
return pContext->ThrowNativeError("Client %d is not in game", client);
return pContext->ThrowNativeError("Client %d is not in game", params[1]);
}
return GetClientAimTarget(pPlayer->GetEdict(), params[2] ? true : false);
+4 -4
View File
@@ -383,7 +383,7 @@ static cell_t EmitAmbientSound(IPluginContext *pContext, const cell_t *params)
float vol, delay;
int pitch, flags, level;
entity = params[3];
entity = gamehelpers->ReferenceToIndex(params[3]);
cell_t *addr;
pContext->LocalToPhysAddr(params[2], &addr);
@@ -436,7 +436,7 @@ static cell_t FadeClientVolume(IPluginContext *pContext, const cell_t *params)
static cell_t StopSound(IPluginContext *pContext, const cell_t *params)
{
int entity = params[1];
int entity = gamehelpers->ReferenceToIndex(params[1]);
int channel = params[2];
char *name;
@@ -477,7 +477,7 @@ static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
char *sample;
pContext->LocalToString(params[3], &sample);
int entity = params[4];
int entity = gamehelpers->ReferenceToIndex(params[4]);
int channel = params[5];
int level = params[6];
int flags = params[7];
@@ -648,7 +648,7 @@ static cell_t EmitSentence(IPluginContext *pContext, const cell_t *params)
crf.Initialize(addr, numClients);
int sentence = params[3];
int entity = params[4];
int entity = gamehelpers->ReferenceToIndex(params[4]);
int channel = params[5];
int level = params[6];
int flags = params[7];