Allow plugins to suppress entity outputs (fix 5515).

This commit is contained in:
Kristian Klausen 2015-12-30 16:37:28 +01:00
parent 23fafbd47d
commit 4cba1925fd
3 changed files with 48 additions and 12 deletions

View File

@ -77,13 +77,25 @@ bool EntityOutputManager::IsEnabled()
#ifdef PLATFORM_WINDOWS
DETOUR_DECL_MEMBER8(FireOutput, void, int, what, int, the, int, hell, int, msvc, void *, variant_t, CBaseEntity *, pActivator, CBaseEntity *, pCaller, float, fDelay)
{
g_OutputManager.FireEventDetour((void *)this, pActivator, pCaller, fDelay);
bool fireOutput = g_OutputManager.FireEventDetour((void *)this, pActivator, pCaller, fDelay);
if (!fireOutput)
{
return;
}
DETOUR_MEMBER_CALL(FireOutput)(what, the, hell, msvc, variant_t, pActivator, pCaller, fDelay);
}
#else
DETOUR_DECL_MEMBER4(FireOutput, void, void *, variant_t, CBaseEntity *, pActivator, CBaseEntity *, pCaller, float, fDelay)
{
g_OutputManager.FireEventDetour((void *)this, pActivator, pCaller, fDelay);
bool fireOutput = g_OutputManager.FireEventDetour((void *)this, pActivator, pCaller, fDelay);
if (!fireOutput)
{
return;
}
DETOUR_MEMBER_CALL(FireOutput)(variant_t, pActivator, pCaller, fDelay);
}
#endif
@ -92,16 +104,19 @@ bool EntityOutputManager::CreateFireEventDetour()
{
fireOutputDetour = DETOUR_CREATE_MEMBER(FireOutput, "FireOutput");
if (fireOutputDetour) return true;
if (fireOutputDetour)
{
return true;
}
return false;
}
void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay)
bool EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay)
{
if (!pCaller)
{
return;
return true;
}
char sOutput[20];
@ -118,20 +133,20 @@ void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator
const char *classname = gamehelpers->GetEntityClassname(pCaller);
if (!classname)
{
return;
return true;
}
const char *outputname = FindOutputName(pOutput, pCaller);
if (!outputname)
{
return;
return true;
}
pOutputName = FindOutputPointer(classname, outputname, false);
if (!pOutputName)
{
return;
return true;
}
}
@ -149,6 +164,9 @@ void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator
_iter = pOutputName->hooks.begin();
// by default we'll call the game's output func, unless a plugin overrides it
bool fireOriginal = true;
while (_iter != pOutputName->hooks.end())
{
hook = (omg_hooks *)*_iter;
@ -170,6 +188,8 @@ void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator
if (hook->entity_ref == -1 || hook->entity_ref == ref) // Global classname hook
{
cell_t result;
//fire the forward to hook->pf
hook->pf->PushString(pOutputName->Name);
hook->pf->PushCell(gamehelpers->ReferenceToBCompatRef(ref));
@ -177,7 +197,13 @@ void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator
//hook->pf->PushCell(handle);
hook->pf->PushFloat(fDelay);
hook->pf->Execute(NULL);
hook->pf->Execute(&result);
if (result > Pl_Continue)
{
// a hook doesn't want the output to be called
fireOriginal = false;
}
if ((hook->entity_ref != -1) && hook->only_once)
{
@ -198,7 +224,11 @@ void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator
hook->in_use = false;
_iter++;
}
return fireOriginal;
}
return true;
}
omg_hooks *EntityOutputManager::NewHook()

View File

@ -95,7 +95,7 @@ public:
void Shutdown();
bool IsEnabled();
void FireEventDetour(void *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay);
bool FireEventDetour(void *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay);
void OnPluginDestroyed(IPlugin *plugin);

View File

@ -42,9 +42,15 @@
* @param caller Entity index of the caller.
* @param activator Entity index of the activator.
* @param delay Delay in seconds? before the event gets fired.
* @noreturn
* @return Anything other than Plugin_Continue will supress this event,
* returning Plugin_Continue will allow it to propagate the results
* of this output to any entity inputs.
*/
typedef EntityOutput = function void (const char[] output, int caller, int activator, float delay);
typeset EntityOutput
{
function void (const char[] output, int caller, int activator, float delay);
function Action (const char[] output, int caller, int activator, float delay);
};
/**
* Add an entity output hook on a entity classname