示例#1
0
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);
}
示例#2
0
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++;
		}
	}
}