From 2c86e8099aea962a72f2b8453acc2af14c8f5804 Mon Sep 17 00:00:00 2001 From: BotoX Date: Wed, 25 Sep 2019 20:26:55 +0200 Subject: [PATCH] Add OnEntitySpawned to SDKHooks. --- extensions/sdkhooks/extension.cpp | 51 +++++++++++++++++++++++++++++++ extensions/sdkhooks/extension.h | 2 ++ plugins/include/sdkhooks.inc | 8 +++++ public/extensions/ISDKHooks.h | 12 +++++++- 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/extensions/sdkhooks/extension.cpp b/extensions/sdkhooks/extension.cpp index 3a457fb5..0f9b8ec8 100644 --- a/extensions/sdkhooks/extension.cpp +++ b/extensions/sdkhooks/extension.cpp @@ -112,6 +112,7 @@ IServerTools *servertools = NULL; // global hooks and forwards IForward *g_pOnEntityCreated = NULL; +IForward *g_pOnEntitySpawned = NULL; IForward *g_pOnEntityDestroyed = NULL; #ifdef GAMEDESC_CAN_CHANGE @@ -255,6 +256,7 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late) plsys->AddPluginsListener(&g_Interface); g_pOnEntityCreated = forwards->CreateForward("OnEntityCreated", ET_Ignore, 2, NULL, Param_Cell, Param_String); + g_pOnEntitySpawned = forwards->CreateForward("OnEntitySpawned", ET_Ignore, 2, NULL, Param_Cell, Param_String); g_pOnEntityDestroyed = forwards->CreateForward("OnEntityDestroyed", ET_Ignore, 1, NULL, Param_Cell); #ifdef GAMEDESC_CAN_CHANGE g_pOnGetGameNameDescription = forwards->CreateForward("OnGetGameDescription", ET_Hook, 2, NULL, Param_String); @@ -361,6 +363,7 @@ void SDKHooks::SDK_OnUnload() #endif forwards->ReleaseForward(g_pOnEntityCreated); + forwards->ReleaseForward(g_pOnEntitySpawned); forwards->ReleaseForward(g_pOnEntityDestroyed); #ifdef GAMEDESC_CAN_CHANGE forwards->ReleaseForward(g_pOnGetGameNameDescription); @@ -441,6 +444,7 @@ void SDKHooks::OnClientPutInServer(int client) CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(client); HandleEntityCreated(pPlayer, client, gamehelpers->EntityToReference(pPlayer)); + HandleEntitySpawned(pPlayer, client, gamehelpers->EntityToReference(pPlayer)); } void SDKHooks::OnClientDisconnecting(int client) @@ -935,6 +939,27 @@ void SDKHooks::OnEntityCreated(CBaseEntity *pEntity) } } +void SDKHooks::OnEntitySpawned(CBaseEntity *pEntity) +{ + // Call OnEntitySpawned forward + int ref = gamehelpers->EntityToReference(pEntity); + int index = gamehelpers->ReferenceToIndex(ref); + + // This can be -1 for player ents before any players have connected + if ((unsigned)index == INVALID_EHANDLE_INDEX || (index > 0 && index <= playerhelpers->GetMaxClients())) + { + return; + } + + if (!IsEntityIndexInRange(index)) + { + g_pSM->LogError(myself, "SDKHooks::OnEntitySpawned - Got entity index out of range (%d)", index); + return; + } + + HandleEntitySpawned(pEntity, index, ref); +} + #ifdef GAMEDESC_CAN_CHANGE const char *SDKHooks::Hook_GetGameDescription() { @@ -1861,6 +1886,32 @@ void SDKHooks::HandleEntityCreated(CBaseEntity *pEntity, int index, cell_t ref) m_EntityCache[index] = ref; } +void SDKHooks::HandleEntitySpawned(CBaseEntity *pEntity, int index, cell_t ref) +{ + if (g_pOnEntitySpawned->GetFunctionCount() || m_EntListeners.size()) + { + cell_t bcompatRef = gamehelpers->EntityToBCompatRef(pEntity); + const char *pName = gamehelpers->GetEntityClassname(pEntity); + if (!pName) + pName = ""; + + // Send OnEntitySpawned to SM listeners + for (SourceHook::List::iterator iter = m_EntListeners.begin(); iter != m_EntListeners.end(); iter++) + { + ISMEntityListener *pListener = (*iter); + pListener->OnEntitySpawned(pEntity, pName); + } + + // Call OnEntitySpawned forward + if (g_pOnEntitySpawned->GetFunctionCount()) + { + g_pOnEntitySpawned->PushCell(bcompatRef); + g_pOnEntitySpawned->PushString(pName); + g_pOnEntitySpawned->Execute(NULL); + } + } +} + void SDKHooks::HandleEntityDeleted(CBaseEntity *pEntity) { cell_t bcompatRef = gamehelpers->EntityToBCompatRef(pEntity); diff --git a/extensions/sdkhooks/extension.h b/extensions/sdkhooks/extension.h index 1168fe91..67cda87c 100644 --- a/extensions/sdkhooks/extension.h +++ b/extensions/sdkhooks/extension.h @@ -249,6 +249,7 @@ public: // IFeatureProvider public: // IEntityListener virtual void OnEntityCreated(CBaseEntity *pEntity); + virtual void OnEntitySpawned(CBaseEntity *pEntity); virtual void OnEntityDeleted(CBaseEntity *pEntity); public: // IClientListener @@ -342,6 +343,7 @@ public: private: void HandleEntityCreated(CBaseEntity *pEntity, int index, cell_t ref); + void HandleEntitySpawned(CBaseEntity *pEntity, int index, cell_t ref); void HandleEntityDeleted(CBaseEntity *pEntity); void Unhook(CBaseEntity *pEntity); void Unhook(IPluginContext *pContext); diff --git a/plugins/include/sdkhooks.inc b/plugins/include/sdkhooks.inc index b6f73c19..17ae6216 100644 --- a/plugins/include/sdkhooks.inc +++ b/plugins/include/sdkhooks.inc @@ -348,6 +348,14 @@ typeset SDKHookCB */ forward void OnEntityCreated(int entity, const char[] classname); +/** + * When an entity is spawned + * + * @param entity Entity index + * @param classname Class name + */ +forward void OnEntitySpawned(int entity, const char[] classname); + /** * When an entity is destroyed * diff --git a/public/extensions/ISDKHooks.h b/public/extensions/ISDKHooks.h index 66d6f2c7..b4f2dd75 100644 --- a/public/extensions/ISDKHooks.h +++ b/public/extensions/ISDKHooks.h @@ -36,7 +36,7 @@ #include #define SMINTERFACE_SDKHOOKS_NAME "ISDKHooks" -#define SMINTERFACE_SDKHOOKS_VERSION 1 +#define SMINTERFACE_SDKHOOKS_VERSION 2 class CBaseEntity; @@ -71,6 +71,16 @@ namespace SourceMod virtual void OnEntityDestroyed(CBaseEntity *pEntity) { } + + /** + * @brief When an entity is spawned + * + * @param pEntity CBaseEntity entity. + * @param classname Entity classname. + */ + virtual void OnEntitySpawned(CBaseEntity *pEntity, const char *classname) + { + } }; /**