Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ham_Killed/DeathMsg getting called before Ham_TakeDamage? #713

Closed
OciXCrom opened this issue May 7, 2019 · 5 comments
Closed

Ham_Killed/DeathMsg getting called before Ham_TakeDamage? #713

OciXCrom opened this issue May 7, 2019 · 5 comments

Comments

@OciXCrom
Copy link
Contributor

OciXCrom commented May 7, 2019

I don't think this is how it should work. Why is the damage dealt after the player has died?

#include <amxmodx>
#include <hamsandwich>

public plugin_init()
{
	register_plugin("Ham_Test", "1.0", "OciXCrom")
	RegisterHam(Ham_TakeDamage, "player", "OnTakeDamage", 1)
	RegisterHam(Ham_Killed, "player", "OnPlayerKilledHam", 1)
	register_event("DeathMsg", "OnPlayerKilled", "a")
}

public OnTakeDamage(iVictim, iInflictor, iAttacker, Float:fDamage, iDamageBits)
{
	client_print(iAttacker, print_chat, "You dealt %.0f damage to %n", fDamage, iVictim)
}

public OnPlayerKilled()
{
	new iAttacker = read_data(1), iVictim = read_data(2)
	client_print(iAttacker, print_chat, "You killed %n", iVictim)
}

public OnPlayerKilledHam(iVictim, iAttacker)
{
	client_print(iAttacker, print_chat, "[HAM] You killed %n", iVictim)
}

Result:

You killed a poor soul
[HAM] You killed a poor soul
You dealt 195 damage to a poor soul
@fl0werD
Copy link

fl0werD commented May 7, 2019

Because player dies in takedamage

@OciXCrom
Copy link
Contributor Author

OciXCrom commented May 9, 2019

@fl0werD that doesn't explain why death is called before damage.

@Mistrick
Copy link

Mistrick commented May 9, 2019

pre takedamage
pre killed
post killed
post takedamage

@Th3-822
Copy link
Contributor

Th3-822 commented May 9, 2019

First thing to notice, you are hooking Ham_TakeDamage as Post
Your callback function will be called after TakeDamage is executed

If there is another function getting called is because it was called inside TakeDamage, so let's follow the function from the SDK:

It's TakeDamage from player, so let's find CBasePlayer::TakeDamage:
https://github.com/ValveSoftware/halflife/blob/master/dlls/player.cpp#L443
Lines 443-673

There is a call in line 507 to CBaseMonster::TakeDamage, so let's go there and check:
https://github.com/ValveSoftware/halflife/blob/master/dlls/combat.cpp#L838
Lines 838-968

Oh, what is in line 909?
https://github.com/ValveSoftware/halflife/blob/master/dlls/combat.cpp#L909

	if ( pev->health <= 0 )
	{
		g_pevLastInflictor = pevInflictor;

		if ( bitsDamageType & DMG_ALWAYSGIB )
		{
			Killed( pevAttacker, GIB_ALWAYS );
		}
		else if ( bitsDamageType & DMG_NEVERGIB )
		{
			Killed( pevAttacker, GIB_NEVER );
		}
		else
		{
			Killed( pevAttacker, GIB_NORMAL );
		}

		g_pevLastInflictor = NULL;

		return 0;
	}

So CBasePlayer::Killed is called on TakeDamage...

So functions are called like this

CBasePlayer::TakeDamage() - Start || Pre hook gets called before running this
  CBaseMonster::TakeDamage()
    CBasePlayer::Killed() - Start || Pre hook of Ham_Killed on player before running this
      CHalfLifeMultiplay::PlayerKilled()
        CHalfLifeMultiplay::DeathNotice() || At here DeathMsg is sent, and your OnPlayerKilled() its called
    CBasePlayer::Killed() - End || Post hook gets called here, so your OnPlayerKilledHam() gets called at here
CBasePlayer::TakeDamage() - End || Post hook gets called here, OnTakeDamage() gets called

Thats why are you getting that result

@OciXCrom
Copy link
Contributor Author

OciXCrom commented May 9, 2019

Thanks for the detailed explanation. If that's how the game works, I'm not going to judge it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants