I found the issue with the first implementation while working with the virtual method hook for bump_weapon. My original test script used the following:
Syntax: Select all
@EntityPreHook(['cs_bot', 'player'], 'bump_weapon')
My original testing worked fine, but I didn't load my test script until I was on the server without any bots. Eventually, I started testing with bots on the server. When I did this, I loaded the test script while bots were on and I wasn't. My testing in this instance worked for bots, but not for human players (me). I came to find out that what was occurring was that CCSBot::BumpWeapon was being hooked instead of CCSPlayer::BumpWeapon. Through more testing (and help from Ayuto), I realized that if I used both cs_bot and player in separate pre-hooks, and I loaded the test script prior to adding any bots, it worked fine. However, if a bot was on the server prior to loading the script, their entity classname was already set to player instead of cs_bot, which caused both the cs_bot hook and player hook to hook the same function (CCSBot::BumpWeapon).
To combat this, we decided to use the DataMap class name of the entity instead of the entity's classname. This fixed the issue for BumpWeapon, as we can use CCSBot in a bot hook and CCSPlayer in a human hook, as those are the starting DataMaps for each, respectively.
Syntax: Select all
@EntityPreHook('CCSBot', 'bump_weapon')
...
@EntityPreHook('CCSPlayer', 'bump_weapon')
However, when working on my Anti Team-Flash plugin, I came to realize that (in CS:S) flashbang_projectile entities do not have CFlashbangProjectile as either a DataMap or a ServerClass. In fact, both flashbang_projectile and hegrenade_projectile both start at CBaseCSGrenadeProjectile for both DataMap and ServerClass. If I used the second implementation, I would have to use:
Syntax: Select all
@EntityPreHook('CBaseCSGrenadeProjectile', 'detonate')
But, if I did that, and an hegrenade is thrown before a flashbang, then CHEGrenadeProjectile::Detonate would be hooked instead of CFlashbangProjectile::Detonate. Both of those virtual functions exist, but neither classname is a part of the respective entity's DataMap/ServerClass. In order to fix this issue, and make sure the original issue stayed fixed, Ayuto came up with a brilliant solution that is the purpose of this topic. If you happen to run into a situation where any of the built-in EntityCondition methods does not suffice, you can easily provide your own function instead. I think the built-ins should work in almost all cases, though.
I hope that explains it well enough. If not, let us know how we can clarify.