const char *CHalfLife2::GetEntityClassname(edict_t * pEdict) { if (pEdict == NULL || pEdict->IsFree()) { return NULL; } IServerUnknown *pUnk = pEdict->GetUnknown(); if (pUnk == NULL) { return NULL; } CBaseEntity * pEntity = pUnk->GetBaseEntity(); if (pEntity == NULL) { return NULL; } return GetEntityClassname(pEntity); }
void EntityOutputManager::FireEventDetour(void *pOutput, CBaseEntity *pActivator, CBaseEntity *pCaller, float fDelay) { if (!pCaller) { return; } char sOutput[20]; Q_snprintf(sOutput, sizeof(sOutput), "%p", pOutput); // attempt to directly lookup a hook using the pOutput pointer OutputNameStruct *pOutputName = NULL; bool fastLookup = false; // Fast lookup failed - check the slow way for hooks that haven't fired yet if ((fastLookup = EntityOutputs->Retrieve(sOutput, (void **)&pOutputName)) == false) { const char *classname = GetEntityClassname(pCaller); const char *outputname = FindOutputName(pOutput, pCaller); if (!outputname) { return; } pOutputName = FindOutputPointer(classname, outputname, false); if (!pOutputName) { return; } } if (!pOutputName->hooks.empty()) { if (!fastLookup) { // hook exists on this classname and output - map it into our quick find trie EntityOutputs->Insert(sOutput, pOutputName); } SourceHook::List<omg_hooks *>::iterator _iter; omg_hooks *hook; _iter = pOutputName->hooks.begin(); while (_iter != pOutputName->hooks.end()) { hook = (omg_hooks *)*_iter; hook->in_use = true; cell_t ref = gamehelpers->EntityToReference(pCaller); if (hook->entity_ref != -1 && gamehelpers->ReferenceToIndex(hook->entity_ref) == gamehelpers->ReferenceToIndex(ref) && ref != hook->entity_ref) { // same entity index but different reference. Entity has changed, kill the hook. _iter = pOutputName->hooks.erase(_iter); CleanUpHook(hook); continue; } 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(gamehelpers->ReferenceToBCompatRef(ref)); hook->pf->PushCell(gamehelpers->EntityToBCompatRef(pActivator)); //hook->pf->PushCell(handle); hook->pf->PushFloat(fDelay); hook->pf->Execute(NULL); if ((hook->entity_ref != -1) && hook->only_once) { _iter = pOutputName->hooks.erase(_iter); CleanUpHook(hook); continue; } if (hook->delete_me) { _iter = pOutputName->hooks.erase(_iter); CleanUpHook(hook); continue; } } hook->in_use = false; _iter++; } } }