diff --git a/extensions/sdktools/output.cpp b/extensions/sdktools/output.cpp index aef1c6eb..0cd4643e 100644 --- a/extensions/sdktools/output.cpp +++ b/extensions/sdktools/output.cpp @@ -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() diff --git a/extensions/sdktools/output.h b/extensions/sdktools/output.h index 299d08ba..e71a6b7d 100644 --- a/extensions/sdktools/output.h +++ b/extensions/sdktools/output.h @@ -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); diff --git a/plugins/include/sdktools_entoutput.inc b/plugins/include/sdktools_entoutput.inc index 7c00f39f..a7332a57 100644 --- a/plugins/include/sdktools_entoutput.inc +++ b/plugins/include/sdktools_entoutput.inc @@ -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