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 newdecls optional
#include <sourcemod>
#include <sdktools>
#include <clientprefs>
@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}
/**

View File

@ -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)
{

View File

@ -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);
}