change KnockbackOnClientHurt to KnockbackOnTakeDamageAlivePost

This commit is contained in:
BotoX 2019-09-27 16:40:58 +02:00
parent d75e123e35
commit dfc024b3d8
8 changed files with 123 additions and 37 deletions

View File

@ -26,6 +26,8 @@
*/ */
#pragma semicolon 1 #pragma semicolon 1
#pragma newdecls optional
#include <sourcemod> #include <sourcemod>
#include <sdktools> #include <sdktools>
#include <clientprefs> #include <clientprefs>
@ -316,6 +318,7 @@ public OnClientPutInServer(client)
WeaponsClientInit(client); WeaponsClientInit(client);
InfectClientInit(client); InfectClientInit(client);
DamageClientInit(client); DamageClientInit(client);
KnockbackClientInit(client);
SEffectsClientInit(client); SEffectsClientInit(client);
AntiStickClientInit(client); AntiStickClientInit(client);
SpawnProtectClientInit(client); SpawnProtectClientInit(client);
@ -372,6 +375,7 @@ public OnClientDisconnect(client)
WeaponsOnClientDisconnect(client); WeaponsOnClientDisconnect(client);
InfectOnClientDisconnect(client); InfectOnClientDisconnect(client);
DamageOnClientDisconnect(client); DamageOnClientDisconnect(client);
KnockbackOnClientDisconnect(client);
AntiStickOnClientDisconnect(client); AntiStickOnClientDisconnect(client);
ZSpawnOnClientDisconnect(client); ZSpawnOnClientDisconnect(client);
VolOnPlayerDisconnect(client); VolOnPlayerDisconnect(client);

View File

@ -116,15 +116,15 @@ DamageOnClientInfected(client, bool:motherinfect)
* Called right before the bullet enters a client. * Called right before the bullet enters a client.
* *
* @param client The client index. * @param client The client index.
* @param inflictor The entity index of the inflictor.
* @param attacker The client index of the attacker. * @param attacker The client index of the attacker.
* @param inflictor The entity index of the inflictor.
* @param damage The amount of damage inflicted. * @param damage The amount of damage inflicted.
* @param hitbox The hitbox index. * @param hitbox The hitbox index.
* @param hitgroup The hitgroup index. * @param hitgroup The hitgroup index.
* @return Return Plugin_Handled to stop bullet from hitting client. * @return Return Plugin_Handled to stop bullet from hitting client.
* Plugin_Continue to allow bullet to hit 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 attacker isn't valid, then stop.
if (!ZRIsClientValid(attacker)) 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. // Here we know that attacker and client are different teams.
// Check if immunity module requires damage to be blocked. // 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. // Block damage.
return Plugin_Handled; return Plugin_Handled;

View File

@ -227,7 +227,6 @@ public Action:EventPlayerHurt(Handle:event, const String:name[], bool:dontBroadc
// Get all required event info. // Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid")); new index = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker")); new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
new hitgroup = GetEventInt(event, "hitgroup");
new dmg_health = GetEventInt(event, "dmg_health"); new dmg_health = GetEventInt(event, "dmg_health");
decl String:weapon[WEAPONS_MAX_LENGTH]; decl String:weapon[WEAPONS_MAX_LENGTH];
@ -238,7 +237,6 @@ public Action:EventPlayerHurt(Handle:event, const String:name[], bool:dontBroadc
InfectOnClientHurt(index, attacker, weapon); InfectOnClientHurt(index, attacker, weapon);
AccountOnClientHurt(index, attacker, dmg_health); AccountOnClientHurt(index, attacker, dmg_health);
SEffectsOnClientHurt(index); SEffectsOnClientHurt(index);
KnockbackOnClientHurt(index, attacker, weapon, hitgroup, dmg_health);
NapalmOnClientHurt(index, attacker, weapon, dmg_health); NapalmOnClientHurt(index, attacker, weapon, dmg_health);
ZHPOnClientHurt(index); ZHPOnClientHurt(index);
} }

View File

@ -156,12 +156,12 @@ bool:ImmunityOnClientInfect(client, attacker)
* *
* @param client Client index. * @param client Client index.
* @param attacker Attacker client, if any. * @param attacker Attacker client, if any.
* @param inflictor The entity index of the inflictor.
* @param damage Damage received by client. * @param damage Damage received by client.
* @param hitgroup Hitgroup receiving damage.
* *
* @return True if damage should be blocked, false otherwise. * @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). // Check if there is no attacker (world damage).
if (!ZRIsClientValid(attacker)) if (!ZRIsClientValid(attacker))
@ -212,7 +212,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
// Get attacker weapon. // Get attacker weapon.
decl String:weapon[32]; decl String:weapon[32];
weapon[0] = 0; weapon[0] = 0;
if (damageType == DMG_BLAST) if (damagetype == DMG_BLAST)
{ {
// Most likely a HE grenade. GetClientWeapon can't be used if // Most likely a HE grenade. GetClientWeapon can't be used if
// the attacker throw grenades. The attacker may switch weapon // 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. // 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. // Block damage from attacker.
return true; return true;

View File

@ -285,7 +285,8 @@ InfectOnClientSpawn(client)
CS_RespawnPlayer(client); CS_RespawnPlayer(client);
} }
InfectUnglitchKevlar(client); // Unglitch kevlar, set last hitgroup to HITGROUP_GENERIC
ToolsSetClientLastHitGroup(client, HITGROUP_GENERIC);
// Forward event to modules. // Forward event to modules.
ZSpawnOnClientSpawn(client); ZSpawnOnClientSpawn(client);
@ -899,7 +900,8 @@ InfectZombieToHuman(client, bool:respawn = false, bool:protect = false)
SpawnProtectStart(client); SpawnProtectStart(client);
} }
InfectUnglitchKevlar(client); // Unglitch kevlar, set last hitgroup to HITGROUP_GENERIC
ToolsSetClientLastHitGroup(client, HITGROUP_GENERIC);
// Forward event to modules. // Forward event to modules.
SEffectsOnClientHuman(client); SEffectsOnClientHuman(client);
@ -1536,14 +1538,3 @@ InfectMode:InfectGetModeOrFail()
return mode; 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);
}

View File

@ -31,15 +31,37 @@
#define CSGO_KNOCKBACK_BOOST 251.0 #define CSGO_KNOCKBACK_BOOST 251.0
#define CSGO_KNOCKBACK_BOOST_MAX 350.0 #define CSGO_KNOCKBACK_BOOST_MAX 350.0
/** Client has been hurt. /**
* Client is joining the server.
* *
* @param client The client index. (zombie) * @param client The client index.
* @param attacker The attacker index. (human)
* @param weapon The weapon used.
* @param hitgroup Hitgroup attacker has damaged.
* @param dmg_health Damage done.
*/ */
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 attacker is invalid, then stop.
if (!ZRIsClientValid(attacker)) if (!ZRIsClientValid(attacker))
@ -48,7 +70,7 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea
} }
// Client is a human, then stop. // Client is a human, then stop.
if (InfectIsClientHuman(client)) if (InfectIsClientHuman(victim))
{ {
return; return;
} }
@ -60,21 +82,35 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea
} }
// Block knock back if an immunity mode is handling this. // Block knock back if an immunity mode is handling this.
if (ImmunityOnClientKnockBack(client)) if (ImmunityOnClientKnockBack(victim))
{ {
return; return;
} }
// Get zombie knockback value. // Get zombie knockback value.
new Float:knockback = ClassGetKnockback(client); new Float:knockback = ClassGetKnockback(victim);
new Float:clientloc[3]; new Float:clientloc[3];
new Float:attackerloc[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. // Check if a grenade was thrown.
if (StrEqual(weapon, "hegrenade")) if (StrEqual(weaponname, "hegrenade"))
{ {
// Get the location of the grenade. // Get the location of the grenade.
if (KnockbackFindExplodingGrenade(attackerloc) == -1) 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]); new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (weapons) if (weapons)
{ {
new weaponindex = WeaponsNameToIndex(weapon); new weaponindex = WeaponsNameToIndex(weaponname);
if (weaponindex != -1) if (weaponindex != -1)
{ {
// Apply weapon knockback multiplier. // 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]); new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
if (hitgroups) if (hitgroups)
{ {
@ -120,10 +160,10 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea
} }
// Apply damage knockback multiplier. // Apply damage knockback multiplier.
knockback *= float(dmg_health); knockback *= damage;
// Apply knockback. // Apply knockback.
KnockbackSetVelocity(client, attackerloc, clientloc, knockback); KnockbackSetVelocity(victim, attackerloc, clientloc, knockback);
} }
/** /**

View File

@ -33,6 +33,8 @@ new g_iToolsLMV;
new g_iToolsHasNightVision; new g_iToolsHasNightVision;
new g_iToolsNightVisionOn; new g_iToolsNightVisionOn;
new g_iToolsFOV; new g_iToolsFOV;
new g_iActiveWeapon;
new g_iToolsLastHitGroup;
/** /**
* @endsection * @endsection
@ -90,6 +92,18 @@ ToolsFindOffsets()
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "Offsets", "Offset \"CBasePlayer::m_iFOV\" was not found."); 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"); Handle hGameConf = LoadGameConfigFile("zombiereloaded");
if (hGameConf != INVALID_HANDLE) if (hGameConf != INVALID_HANDLE)
{ {

View File

@ -250,3 +250,42 @@ stock ToolsGetEntityColor(entity, color[4])
for (new i = 0; i < 4; i++) for (new i = 0; i < 4; i++)
color[i] = GetEntData(entity, offset + i, 1); 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);
}