Skip to content

Commit

Permalink
Update staggersolver (SirPlease#718)
Browse files Browse the repository at this point in the history
  • Loading branch information
fbef0102 authored Nov 28, 2023
1 parent fce3a40 commit 5f3d0c8
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 32 deletions.
Binary file modified addons/sourcemod/plugins/optional/staggersolver.smx
Binary file not shown.
112 changes: 80 additions & 32 deletions addons/sourcemod/scripting/staggersolver.sp
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,44 @@ public Plugin myinfo =
name = "Super Stagger Solver",
author = "CanadaRox, A1m (fix), Sir (rework), Forgetest",
description = "Blocks all button presses and restarts animations during stumbles",
version = "2.2",
version = "2.3",
url = "https://github.com/SirPlease/L4D2-Competitive-Rework"
};

public void L4D_OnShovedBySurvivor_Post(int client, int victim, const float vecDir[3])
{
if (L4D_IsPlayerStaggering(victim))
{
if (!FixSpitter(victim))
{
SetEntPropFloat(victim, Prop_Send, "m_fServerAnimStartTime", GetGameTime());
SetEntPropFloat(victim, Prop_Send, "m_flCycle", 0.0);
}
}
L4D2_OnStagger_Post(victim, client);
}

public void L4D2_OnEntityShoved_Post(int client, int entity, int weapon, const float vecDir[3], bool bIsHighPounce)
public void L4D2_OnStagger_Post(int client, int source)
{
if( entity > 0 && entity <= MaxClients && IsClientInGame(entity) && GetClientTeam(entity) == 3)
if (!L4D_IsPlayerStaggering(client))
return;

if (IsTankThrowingRock(client)) // handled by plugin "rock_stumble_block"
return;

PlayerAnimState anim = PlayerAnimState.FromPlayer(client);

switch (anim.GetMainActivity())
{
if (L4D_IsPlayerStaggering(entity))
case L4D2_ACT_TERROR_HULK_VICTORY,
L4D2_ACT_TERROR_HULK_VICTORY_B,
L4D2_ACT_TERROR_RAGE_AT_ENEMY,
L4D2_ACT_TERROR_RAGE_AT_KNOCKDOWN:
{
SetEntPropFloat(client, Prop_Send, "m_flCycle", 1.0);
}
default:
{
if (!FixSpitter(entity))
{
SetEntPropFloat(entity, Prop_Send, "m_fServerAnimStartTime", GetGameTime());
SetEntPropFloat(entity, Prop_Send, "m_flCycle", 0.0);
}
anim.m_bIsTonguing = false;
anim.m_bIsSpitting = false;

anim.ResetMainActivity();
}
}
}

bool FixSpitter(int client)
{
if (GetClientTeam(client) != 3)
return false;

if (GetEntProp(client, Prop_Send, "m_zombieClass") != 4)
return false;

if (GetEntProp(client, Prop_Send, "m_nSequence") != 21)
return false;

SetEntPropFloat(client, Prop_Send, "m_flCycle", 1.0);
return true;
}

public Action OnPlayerRunCmd(int client, int &buttons)
{
if (IsClientInGame(client)
Expand All @@ -71,4 +63,60 @@ public Action OnPlayerRunCmd(int client, int &buttons)
}
}
return Plugin_Continue;
}

bool IsTankThrowingRock(int client)
{
if (!IsTank(client))
return false;

int ability = GetEntPropEnt(client, Prop_Send, "m_customAbility");
if (ability == -1)
return false;

return CThrow__IsActive(ability) || CThrow__SelectingTankAttack(ability);
}

bool IsTank(int client)
{
static int s_iTankClass = -1;
if (s_iTankClass == -1)
{
s_iTankClass = L4D_IsEngineLeft4Dead() ? 5 : 8;
}

return GetClientTeam(client) == 3
&& GetEntProp(client, Prop_Send, "m_zombieClass") == s_iTankClass;
}

bool CThrow__IsActive(int ability)
{
CountdownTimer ct = CThrow__GetThrowTimer(ability);
if (!CTimer_HasStarted(ct))
return false;

return CTimer_IsElapsed(ct) ? false : true;
}

CountdownTimer CThrow__GetThrowTimer(int ability)
{
static int s_iOffs_m_throwTimer = -1;
if (s_iOffs_m_throwTimer == -1)
s_iOffs_m_throwTimer = FindSendPropInfo("CThrow", "m_hasBeenUsed") + 4;

return view_as<CountdownTimer>(
GetEntityAddress(ability) + view_as<Address>(s_iOffs_m_throwTimer)
);
}

bool CThrow__SelectingTankAttack(int ability)
{
if (L4D_IsEngineLeft4Dead())
return false;

static int s_iOffs_m_bSelectingAttack = -1;
if (s_iOffs_m_bSelectingAttack == -1)
s_iOffs_m_bSelectingAttack = FindSendPropInfo("CThrow", "m_hasBeenUsed") + 28;

return GetEntData(ability, s_iOffs_m_bSelectingAttack, 1) > 0;
}

0 comments on commit 5f3d0c8

Please sign in to comment.