diff --git a/extensions/sdkhooks/extension.cpp b/extensions/sdkhooks/extension.cpp index c1d37da7..646776c7 100644 --- a/extensions/sdkhooks/extension.cpp +++ b/extensions/sdkhooks/extension.cpp @@ -438,6 +438,21 @@ FeatureStatus SDKHooks::GetFeatureStatus(FeatureType type, const char *name) /** * Functions */ + +static void PopulateCallbackList(const ke::Vector &source, ke::Vector &destination, int entity) +{ + destination.ensure(8); /* Skip trivial allocations as AMTL uses length<<1. */ + for (size_t iter = 0; iter < source.length(); ++iter) + { + if (source[iter].entity != entity) + { + continue; + } + + destination.append(source[iter].callback); + } +} + cell_t SDKHooks::Call(int entity, SDKHookType type, int other) { return Call(gamehelpers->ReferenceToEntity(entity), type, gamehelpers->ReferenceToEntity(other)); @@ -461,17 +476,14 @@ cell_t SDKHooks::Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther) continue; } - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; int entity = gamehelpers->EntityToBCompatRef(pEnt); int other = gamehelpers->EntityToBCompatRef(pOther); - for (entry = 0; entry < pawnlist.length(); ++entry) - { - if (entity != pawnlist[entry].entity) - { - continue; - } - IPluginFunction *callback = pawnlist[entry].callback; + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) + { + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCell(other); @@ -914,15 +926,11 @@ void SDKHooks::Hook_FireBulletsPost(const FireBulletsInfo_t &info) const char *weapon = pInfo->GetWeaponName(); - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCell(info.m_iShots); callback->PushString(weapon?weapon:""); @@ -956,15 +964,11 @@ int SDKHooks::Hook_GetMaxHealth() cell_t res = Pl_Continue; - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCellByRef(&new_max); callback->Execute(&res); @@ -1013,15 +1017,11 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info) cell_t res, ret = Pl_Continue; - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCellByRef(&attacker); callback->PushCellByRef(&inflictor); @@ -1095,15 +1095,11 @@ int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info) int entity = gamehelpers->EntityToBCompatRef(pEntity); - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCell(info.GetAttacker()); callback->PushCell(info.GetInflictor()); @@ -1168,15 +1164,11 @@ bool SDKHooks::Hook_Reload() int entity = gamehelpers->EntityToBCompatRef(pEntity); cell_t res = Pl_Continue; - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->Execute(&res); } @@ -1206,15 +1198,11 @@ bool SDKHooks::Hook_ReloadPost() int entity = gamehelpers->EntityToBCompatRef(pEntity); cell_t origreturn = META_RESULT_ORIG_RET(bool) ? 1 : 0; - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCell(origreturn); callback->Execute(NULL); @@ -1253,15 +1241,11 @@ bool SDKHooks::Hook_ShouldCollide(int collisionGroup, int contentsMask) cell_t origRet = ((META_RESULT_STATUS >= MRES_OVERRIDE)?(META_RESULT_OVERRIDE_RET(bool)):(META_RESULT_ORIG_RET(bool))) ? 1 : 0; cell_t res = 0; - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCell(collisionGroup); callback->PushCell(contentsMask); @@ -1301,15 +1285,11 @@ void SDKHooks::Hook_Spawn() int entity = gamehelpers->EntityToBCompatRef(pEntity); cell_t res = Pl_Continue; - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->Execute(&res); } @@ -1399,15 +1379,11 @@ void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, int ammotype = info.GetAmmoType(); cell_t res, ret = Pl_Continue; - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCellByRef(&attacker); callback->PushCellByRef(&inflictor); @@ -1477,15 +1453,11 @@ void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vec int entity = gamehelpers->EntityToBCompatRef(pEntity); - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCell(info.GetAttacker()); callback->PushCell(info.GetInflictor()); @@ -1521,15 +1493,11 @@ void SDKHooks::Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE int caller = gamehelpers->EntityToBCompatRef(pCaller); cell_t ret = Pl_Continue; - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCell(activator); callback->PushCell(caller); @@ -1564,15 +1532,11 @@ void SDKHooks::Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T int activator = gamehelpers->EntityToBCompatRef(pActivator); int caller = gamehelpers->EntityToBCompatRef(pCaller); - ke::Vector &pawnlist = vtablehooklist[entry]->hooks; - for (entry = 0; entry < pawnlist.length(); ++entry) + ke::Vector callbackList; + PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity); + for (entry = 0; entry < callbackList.length(); ++entry) { - if (entity != pawnlist[entry].entity) - { - continue; - } - - IPluginFunction *callback = pawnlist[entry].callback; + IPluginFunction *callback = callbackList[entry]; callback->PushCell(entity); callback->PushCell(activator); callback->PushCell(caller);