diff --git a/extensions/sdkhooks/extension.cpp b/extensions/sdkhooks/extension.cpp index 6865ea5c..7ae00ef2 100644 --- a/extensions/sdkhooks/extension.cpp +++ b/extensions/sdkhooks/extension.cpp @@ -185,6 +185,7 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late) sharesys->AddDependency(myself, "bintools.ext", true, true); sharesys->AddNatives(myself, g_Natives); sharesys->RegisterLibrary(myself, "sdkhooks"); + sharesys->AddInterface(myself, &g_Interface); sharesys->AddCapabilityProvider(myself, this, "SDKHook_DmgCustomInOTD"); sharesys->AddCapabilityProvider(myself, this, "SDKHook_LogicalEntSupport"); @@ -391,18 +392,36 @@ void SDKHooks::OnPluginUnloaded(IPlugin *plugin) void SDKHooks::OnClientPutInServer(int client) { - g_pOnEntityCreated->PushCell(client); - CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(client); + const char *pName = gamehelpers->GetEntityClassname(pPlayer); - const char * pName = gamehelpers->GetEntityClassname(pPlayer); + // Send OnEntityCreated to SM listeners + SourceHook::List::iterator iter; + ISMEntityListener *pListener = NULL; + for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++) + { + pListener = (*iter); + pListener->OnEntityCreated(pPlayer, pName ? pName : ""); + } + // Call OnEntityCreated forward + g_pOnEntityCreated->PushCell(client); g_pOnEntityCreated->PushString(pName ? pName : ""); g_pOnEntityCreated->Execute(NULL); m_EntityExists.Set(client); } +void SDKHooks::AddEntityListener(ISMEntityListener *listener) +{ + m_EntListeners.push_back(listener); +} + +void SDKHooks::RemoveEntityListener(ISMEntityListener *listener) +{ + m_EntListeners.remove(listener); +} + bool SDKHooks::RegisterConCommandBase(ConCommandBase *pVar) { /* Always call META_REGCVAR instead of going through the engine. */ @@ -824,11 +843,19 @@ void SDKHooks::OnEntityCreated(CBaseEntity *pEntity) return; } + const char *pName = gamehelpers->GetEntityClassname(pEntity); + + // Send OnEntityCreated to SM listeners + SourceHook::List::iterator iter; + ISMEntityListener *pListener = NULL; + for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++) + { + pListener = (*iter); + pListener->OnEntityCreated(pEntity, pName ? pName : ""); + } + g_pOnEntityCreated->PushCell(gamehelpers->EntityToBCompatRef(pEntity)); - - const char * pName = gamehelpers->GetEntityClassname(pEntity); g_pOnEntityCreated->PushString(pName ? pName : ""); - g_pOnEntityCreated->Execute(NULL); m_EntityExists.Set(entity); @@ -1394,6 +1421,15 @@ void SDKHooks::Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T void SDKHooks::OnEntityDeleted(CBaseEntity *pEntity) { + // Send OnEntityDestroyed to SM listeners + SourceHook::List::iterator iter; + ISMEntityListener *pListener = NULL; + for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++) + { + pListener = (*iter); + pListener->OnEntityDestroyed(pEntity); + } + int entity = gamehelpers->EntityToBCompatRef(pEntity); // Call OnEntityDestroyed forward diff --git a/extensions/sdkhooks/extension.h b/extensions/sdkhooks/extension.h index 7af983ab..9965f6fa 100644 --- a/extensions/sdkhooks/extension.h +++ b/extensions/sdkhooks/extension.h @@ -2,8 +2,10 @@ #define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ #include "smsdk_ext.h" +#include #include #include +#include #include #include @@ -120,7 +122,8 @@ class SDKHooks : public IPluginsListener, public IFeatureProvider, public IEntityListener, - public IClientListener + public IClientListener, + public ISDKHooks { public: /** @@ -215,6 +218,13 @@ public: // IEntityListener public: // IClientListener virtual void OnClientPutInServer(int client); +public: // ISDKHooks + virtual void AddEntityListener(ISMEntityListener *listener); + virtual void RemoveEntityListener(ISMEntityListener *listener); + +private: + SourceHook::List m_EntListeners; + public: /** * Functions diff --git a/extensions/sdkhooks/msvc10/sdkhooks.vcxproj b/extensions/sdkhooks/msvc10/sdkhooks.vcxproj index 6a834982..61250e43 100644 --- a/extensions/sdkhooks/msvc10/sdkhooks.vcxproj +++ b/extensions/sdkhooks/msvc10/sdkhooks.vcxproj @@ -1300,6 +1300,7 @@ + diff --git a/extensions/sdkhooks/msvc10/sdkhooks.vcxproj.filters b/extensions/sdkhooks/msvc10/sdkhooks.vcxproj.filters index 58538990..45f3aa9f 100644 --- a/extensions/sdkhooks/msvc10/sdkhooks.vcxproj.filters +++ b/extensions/sdkhooks/msvc10/sdkhooks.vcxproj.filters @@ -56,6 +56,9 @@ SourceMod SDK + + Header Files + diff --git a/public/extensions/ISDKHooks.h b/public/extensions/ISDKHooks.h new file mode 100644 index 00000000..66d6f2c7 --- /dev/null +++ b/public/extensions/ISDKHooks.h @@ -0,0 +1,107 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * Source SDK Hooks Extension + * Copyright (C) 2010-2012 Nicholas Hastings + * Copyright (C) 2009-2010 Erik Minekus + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_SMEXT_I_SDKHOOKS_H_ +#define _INCLUDE_SMEXT_I_SDKHOOKS_H_ + +#include + +#define SMINTERFACE_SDKHOOKS_NAME "ISDKHooks" +#define SMINTERFACE_SDKHOOKS_VERSION 1 + +class CBaseEntity; + +/** + * @brief SDKHooks shared API + * @file ISDKHooks.h + */ + +namespace SourceMod +{ + /** + * @brief Provides callbacks for entity events. + */ + class ISMEntityListener + { + public: + /** + * @brief When an entity is created + * + * @param pEntity CBaseEntity entity. + * @param classname Entity classname. + */ + virtual void OnEntityCreated(CBaseEntity *pEntity, const char *classname) + { + } + + /** + * @brief When an entity is destroyed + * + * @param pEntity CBaseEntity entity. + */ + virtual void OnEntityDestroyed(CBaseEntity *pEntity) + { + } + }; + + /** + * @brief SDKHooks API. + */ + class ISDKHooks : public SMInterface + { + public: + virtual const char *GetInterfaceName() + { + return SMINTERFACE_SDKHOOKS_NAME; + } + virtual unsigned int GetInterfaceVersion() + { + return SMINTERFACE_SDKHOOKS_VERSION; + } + public: + /** + * @brief Adds an entity listener. + * + * @param listener Pointer to an ISMEntityListener. + */ + virtual void AddEntityListener(ISMEntityListener *listener) =0; + + /** + * @brief Removes an entity listener. + * + * @param listener Pointer to an ISMEntityListener. + */ + virtual void RemoveEntityListener(ISMEntityListener *listener) =0; + }; +} + +#endif /* _INCLUDE_SMEXT_I_SDKHOOKS_H_ */