From dfc024b3d84130b3c2bed421da65ec06634488dd Mon Sep 17 00:00:00 2001 From: BotoX Date: Fri, 27 Sep 2019 16:40:58 +0200 Subject: [PATCH] change KnockbackOnClientHurt to KnockbackOnTakeDamageAlivePost --- src/zombiereloaded.sp | 4 +++ src/zr/damage.inc | 6 ++-- src/zr/event.inc | 2 -- src/zr/immunityhandler.inc | 8 ++--- src/zr/infect.inc | 17 +++------ src/zr/knockback.inc | 70 ++++++++++++++++++++++++++++++-------- src/zr/tools.inc | 14 ++++++++ src/zr/tools_functions.inc | 39 +++++++++++++++++++++ 8 files changed, 123 insertions(+), 37 deletions(-) diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp index 1be0302..00e7d3f 100644 --- a/src/zombiereloaded.sp +++ b/src/zombiereloaded.sp @@ -26,6 +26,8 @@ */ #pragma semicolon 1 +#pragma newdecls optional + #include #include #include @@ -316,6 +318,7 @@ public OnClientPutInServer(client) WeaponsClientInit(client); InfectClientInit(client); DamageClientInit(client); + KnockbackClientInit(client); SEffectsClientInit(client); AntiStickClientInit(client); SpawnProtectClientInit(client); @@ -372,6 +375,7 @@ public OnClientDisconnect(client) WeaponsOnClientDisconnect(client); InfectOnClientDisconnect(client); DamageOnClientDisconnect(client); + KnockbackOnClientDisconnect(client); AntiStickOnClientDisconnect(client); ZSpawnOnClientDisconnect(client); VolOnPlayerDisconnect(client); diff --git a/src/zr/damage.inc b/src/zr/damage.inc index 3e91300..fdb7242 100644 --- a/src/zr/damage.inc +++ b/src/zr/damage.inc @@ -116,15 +116,15 @@ DamageOnClientInfected(client, bool:motherinfect) * Called right before the bullet enters a client. * * @param client The client index. - * @param inflictor The entity index of the inflictor. * @param attacker The client index of the attacker. + * @param inflictor The entity index of the inflictor. * @param damage The amount of damage inflicted. * @param hitbox The hitbox index. * @param hitgroup The hitgroup index. * @return Return Plugin_Handled to stop bullet from hitting client. * Plugin_Continue to allow bullet to hit client. */ -public Action:DamageTraceAttack(client, &attacker, &inflictor, &Float:damage, &damagetype, &ammotype, hitbox, hitgroup) +public Action DamageTraceAttack(int client, int &attacker, int &inflictor, float &damage, int &damagetype, int &ammotype, int hitbox, int hitgroup) { // If attacker isn't valid, then stop. if (!ZRIsClientValid(attacker)) @@ -159,7 +159,7 @@ public Action:DamageTraceAttack(client, &attacker, &inflictor, &Float:damage, &d // Here we know that attacker and client are different teams. // Check if immunity module requires damage to be blocked. - if (ImmunityOnClientTraceAttack(client, attacker, damage, hitgroup, damagetype)) + if (ImmunityOnClientTraceAttack(client, attacker, inflictor, damage, damagetype, ammotype)) { // Block damage. return Plugin_Handled; diff --git a/src/zr/event.inc b/src/zr/event.inc index 0089c87..84b4b38 100644 --- a/src/zr/event.inc +++ b/src/zr/event.inc @@ -227,7 +227,6 @@ public Action:EventPlayerHurt(Handle:event, const String:name[], bool:dontBroadc // Get all required event info. new index = GetClientOfUserId(GetEventInt(event, "userid")); new attacker = GetClientOfUserId(GetEventInt(event, "attacker")); - new hitgroup = GetEventInt(event, "hitgroup"); new dmg_health = GetEventInt(event, "dmg_health"); decl String:weapon[WEAPONS_MAX_LENGTH]; @@ -238,7 +237,6 @@ public Action:EventPlayerHurt(Handle:event, const String:name[], bool:dontBroadc InfectOnClientHurt(index, attacker, weapon); AccountOnClientHurt(index, attacker, dmg_health); SEffectsOnClientHurt(index); - KnockbackOnClientHurt(index, attacker, weapon, hitgroup, dmg_health); NapalmOnClientHurt(index, attacker, weapon, dmg_health); ZHPOnClientHurt(index); } diff --git a/src/zr/immunityhandler.inc b/src/zr/immunityhandler.inc index 814d433..7157631 100644 --- a/src/zr/immunityhandler.inc +++ b/src/zr/immunityhandler.inc @@ -156,12 +156,12 @@ bool:ImmunityOnClientInfect(client, attacker) * * @param client Client index. * @param attacker Attacker client, if any. + * @param inflictor The entity index of the inflictor. * @param damage Damage received by client. - * @param hitgroup Hitgroup receiving damage. * * @return True if damage should be blocked, false otherwise. */ -bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damageType) +bool ImmunityOnClientTraceAttack(int client, int &attacker, int &inflictor, float &damage, int &damagetype, int &ammotype) { // Check if there is no attacker (world damage). if (!ZRIsClientValid(attacker)) @@ -212,7 +212,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag // Get attacker weapon. decl String:weapon[32]; weapon[0] = 0; - if (damageType == DMG_BLAST) + if (damagetype == DMG_BLAST) { // Most likely a HE grenade. GetClientWeapon can't be used if // the attacker throw grenades. The attacker may switch weapon @@ -225,7 +225,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag } // Since damage is blocked, trigger knock back hurt event manually. - KnockbackOnClientHurt(client, attacker, weapon, hitgroup, RoundToNearest(damage)); + DamageOnTakeDamageAlivePost(client, attacker, inflictor, damage, damagetype, -1, NULL_VECTOR, NULL_VECTOR, 0); // Block damage from attacker. return true; diff --git a/src/zr/infect.inc b/src/zr/infect.inc index 8759b49..e3cb233 100644 --- a/src/zr/infect.inc +++ b/src/zr/infect.inc @@ -285,7 +285,8 @@ InfectOnClientSpawn(client) CS_RespawnPlayer(client); } - InfectUnglitchKevlar(client); + // Unglitch kevlar, set last hitgroup to HITGROUP_GENERIC + ToolsSetClientLastHitGroup(client, HITGROUP_GENERIC); // Forward event to modules. ZSpawnOnClientSpawn(client); @@ -899,7 +900,8 @@ InfectZombieToHuman(client, bool:respawn = false, bool:protect = false) SpawnProtectStart(client); } - InfectUnglitchKevlar(client); + // Unglitch kevlar, set last hitgroup to HITGROUP_GENERIC + ToolsSetClientLastHitGroup(client, HITGROUP_GENERIC); // Forward event to modules. SEffectsOnClientHuman(client); @@ -1536,14 +1538,3 @@ InfectMode:InfectGetModeOrFail() return mode; } - -InfectUnglitchKevlar(client) -{ - // Unglitch kevlar. (Reset hitbox to HITBOX_GENERIC) - // Example: You get hit in the head by a bullet as a zombie - // the round ends, you spawn as a human. - // You get damaged by a trigger, the game still thinks you - // are getting damaged in the head hitgroup, >mfw source engine. - // Thanks to leaked 2007 Source Engine Code. - SetEntData(client, 4444, 0, 4); -} diff --git a/src/zr/knockback.inc b/src/zr/knockback.inc index 69f948c..0566d72 100644 --- a/src/zr/knockback.inc +++ b/src/zr/knockback.inc @@ -31,15 +31,37 @@ #define CSGO_KNOCKBACK_BOOST 251.0 #define CSGO_KNOCKBACK_BOOST_MAX 350.0 -/** Client has been hurt. +/** + * Client is joining the server. * - * @param client The client index. (zombie) - * @param attacker The attacker index. (human) - * @param weapon The weapon used. - * @param hitgroup Hitgroup attacker has damaged. - * @param dmg_health Damage done. + * @param client The client index. */ -KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_health) +KnockbackClientInit(client) +{ + SDKHook(client, SDKHook_OnTakeDamageAlivePost, KnockbackOnTakeDamageAlivePost); +} + +/** + * Client is leaving the server. + * + * @param client The client index. + */ +KnockbackOnClientDisconnect(client) +{ + SDKUnhook(client, SDKHook_OnTakeDamageAlivePost, KnockbackOnTakeDamageAlivePost); +} + +/** + * Hook: KnockbackOnTakeDamageAlivePost + * Called after client has been hurt. + * + * @param client The client index. + * @param inflictor The entity index of the inflictor. + * @param attacker The client index of the attacker. + * @param damage The amount of damage inflicted. + */ +public void KnockbackOnTakeDamageAlivePost(int victim, int attacker, int inflictor, float damage, int damagetype, int weapon, + const float damageForce[3], const float damagePosition[3], int damagecustom) { // If attacker is invalid, then stop. if (!ZRIsClientValid(attacker)) @@ -48,7 +70,7 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea } // Client is a human, then stop. - if (InfectIsClientHuman(client)) + if (InfectIsClientHuman(victim)) { return; } @@ -60,21 +82,35 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea } // Block knock back if an immunity mode is handling this. - if (ImmunityOnClientKnockBack(client)) + if (ImmunityOnClientKnockBack(victim)) { return; } // Get zombie knockback value. - new Float:knockback = ClassGetKnockback(client); + new Float:knockback = ClassGetKnockback(victim); new Float:clientloc[3]; new Float:attackerloc[3]; - GetClientAbsOrigin(client, clientloc); + GetClientAbsOrigin(victim, clientloc); + + char weaponname[64]; + int active_weapon = -42; + if (inflictor == attacker) + { + active_weapon = ToolsGetClientActiveWeapon(attacker); + if (active_weapon > 0) + GetEdictClassname(active_weapon, weaponname, sizeof(weaponname)); + } + else + GetEdictClassname(inflictor, weaponname, sizeof(weaponname)); + + ReplaceString(weaponname, sizeof(weaponname), "weapon_", ""); + ReplaceString(weaponname, sizeof(weaponname), "_projectile", ""); // Check if a grenade was thrown. - if (StrEqual(weapon, "hegrenade")) + if (StrEqual(weaponname, "hegrenade")) { // Get the location of the grenade. if (KnockbackFindExplodingGrenade(attackerloc) == -1) @@ -100,7 +136,7 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]); if (weapons) { - new weaponindex = WeaponsNameToIndex(weapon); + new weaponindex = WeaponsNameToIndex(weaponname); if (weaponindex != -1) { // Apply weapon knockback multiplier. @@ -108,6 +144,10 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea } } + int hitgroup = HITGROUP_GENERIC; + if (!(damagetype & DMG_BLAST)) + hitgroup = ToolsGetClientLastHitGroup(victim); + new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]); if (hitgroups) { @@ -120,10 +160,10 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea } // Apply damage knockback multiplier. - knockback *= float(dmg_health); + knockback *= damage; // Apply knockback. - KnockbackSetVelocity(client, attackerloc, clientloc, knockback); + KnockbackSetVelocity(victim, attackerloc, clientloc, knockback); } /** diff --git a/src/zr/tools.inc b/src/zr/tools.inc index 15d9d6c..5a1c025 100644 --- a/src/zr/tools.inc +++ b/src/zr/tools.inc @@ -33,6 +33,8 @@ new g_iToolsLMV; new g_iToolsHasNightVision; new g_iToolsNightVisionOn; new g_iToolsFOV; +new g_iActiveWeapon; +new g_iToolsLastHitGroup; /** * @endsection @@ -90,6 +92,18 @@ ToolsFindOffsets() LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "Offsets", "Offset \"CBasePlayer::m_iFOV\" was not found."); } + g_iActiveWeapon = FindSendPropInfo("CBaseCombatCharacter", "m_hActiveWeapon"); + if (g_iActiveWeapon == -1) + { + LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "Offsets", "Offset \"CBaseCombatCharacter::m_hActiveWeapon\" was not found."); + } + + // CCSPlayer::m_LastHitGroup + // CCSPlayer::OnTakeDamage_Alive(CTakeDamageInfo const&)+122 mov ecx, [ebp+this] + // CCSPlayer::OnTakeDamage_Alive(CTakeDamageInfo const&)+125 mov edx, [ecx+4444] + // CCSPlayer::OnTakeDamage_Alive(CTakeDamageInfo const&)+12B mov dword ptr [esp+4], offset aHitgroup ; "hitgroup" + g_iToolsLastHitGroup = 4444; + Handle hGameConf = LoadGameConfigFile("zombiereloaded"); if (hGameConf != INVALID_HANDLE) { diff --git a/src/zr/tools_functions.inc b/src/zr/tools_functions.inc index 97d40d9..73cfae2 100644 --- a/src/zr/tools_functions.inc +++ b/src/zr/tools_functions.inc @@ -250,3 +250,42 @@ stock ToolsGetEntityColor(entity, color[4]) for (new i = 0; i < 4; i++) color[i] = GetEntData(entity, offset + i, 1); } + +/** + * Get client's m_hActiveWeapon. + * + * @param client The client index. + */ +stock int ToolsGetClientActiveWeapon(int client) +{ + return GetEntDataEnt2(client, g_iActiveWeapon); +} + +/** + * Get client's m_LastHitGroup. + * + * @param client The client index. + */ +stock int ToolsGetClientLastHitGroup(int client) +{ +/* WRONG OFFSET + if (g_iToolsLastHitGroup == -1) + g_iToolsLastHitGroup = FindDataMapInfo(client, "m_LastHitGroup"); +*/ + return GetEntData(client, g_iToolsLastHitGroup, 4); +} + +/** + * Set client's m_LastHitGroup. + * + * @param client The client index. + * @param hitgroup The hitgroup. + */ +stock void ToolsSetClientLastHitGroup(int client, int hitgroup) +{ +/* WRONG OFFSET + if (g_iToolsLastHitGroup == -1) + g_iToolsLastHitGroup = FindDataMapInfo(client, "m_LastHitGroup"); +*/ + SetEntData(client, g_iToolsLastHitGroup, hitgroup, 4); +}