Skip to content

Commit abdc5d5

Browse files
committed
[l4d2_smoker_drag_damage_interval] Fix the incorrect code for the first damage.
1 parent ca0a12d commit abdc5d5

2 files changed

Lines changed: 27 additions & 25 deletions

File tree

Binary file not shown.

addons/sourcemod/scripting/l4d2_smoker_drag_damage_interval.sp

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Version 2.2 by A1m`
2+
* Version 2.3 by A1m`
33
*
44
* Changes:
55
* 1. Removed duplicate plugins:
@@ -10,7 +10,11 @@
1010
* - Replaced with safer, hook-based implementation using OnTakeDamage and netprops.
1111
* - Ensures more stable and reliable drag damage behavior without unnecessary timers.
1212
*
13-
* 3. Supports late loading.
13+
* Notes:
14+
* The timing of damage is not perfect, as 'CTerrorPlayer::PostThink' is not called every frame,
15+
* but after a certain period of time depending on the number of players and the tick rate (see function 'CTerrorPlayer::ShouldPostThink').
16+
* For this reason, it is difficult to calculate using game netprops whether this was the first damage dealt or not,
17+
* the code becomes too complicated, so we introduce our own variables to determine this.
1418
**/
1519

1620
#pragma semicolon 1
@@ -39,7 +43,16 @@ float
3943
g_fDebugDamageInterval = 0.0;
4044
#endif
4145

46+
enum
47+
{
48+
eUserId = 0,
49+
eHitCount,
50+
51+
eDamageInfo_Size
52+
};
53+
4254
int
55+
g_iTongueHitCount[MAXPLAYERS + 1][eDamageInfo_Size],
4356
g_iTongueDragDamageTimerDurationOffset = -1,
4457
g_iTongueDragDamageTimerTimeStampOffset = -1;
4558

@@ -53,7 +66,7 @@ public Plugin myinfo =
5366
name = "L4D2 smoker drag damage interval",
5467
author = "Visor, Sir, A1m`",
5568
description = "Implements a native-like cvar that should've been there out of the box",
56-
version = "2.2",
69+
version = "2.3",
5770
url = "https://github.com/SirPlease/L4D2-Competitive-Rework"
5871
};
5972

@@ -83,9 +96,9 @@ void InitGameData()
8396
SetFailState("Gamedata '%s.txt' missing or corrupt.", GAMEDATA);
8497
}
8598

86-
int iTongueDragDamageTimer = GameConfGetOffset(hGamedata, "CTerrorPlayer::m_tongueDragDamageTimer");
99+
int iTongueDragDamageTimer = GameConfGetOffset(hGamedata, "CTerrorPlayer->m_tongueDragDamageTimer");
87100
if (iTongueDragDamageTimer == -1) {
88-
SetFailState("Failed to get offset 'CTerrorPlayer::m_tongueDragDamageTimer'.");
101+
SetFailState("Failed to get offset 'CTerrorPlayer->m_tongueDragDamageTimer'.");
89102
}
90103

91104
g_iTongueDragDamageTimerDurationOffset = iTongueDragDamageTimer + CT_DURATION_OFFSET;
@@ -123,6 +136,9 @@ void Event_OnTongueGrab(Event hEvent, const char[] eName, bool bDontBroadcast)
123136
SetDragDamageTimer(iVictim, GetFirstDamageInterval());
124137
}
125138

139+
g_iTongueHitCount[iVictim][eUserId] = hEvent.GetInt("victim");
140+
g_iTongueHitCount[iVictim][eHitCount] = 0;
141+
126142
#if DEBUG
127143
g_fDebugDamageInterval = GetGameTime();
128144
#endif
@@ -131,6 +147,7 @@ void Event_OnTongueGrab(Event hEvent, const char[] eName, bool bDontBroadcast)
131147
Action Hook_OnTakeDamage(int iVictim, int &iAttacker, int &iInflictor, float &fDamage, int &iDamageType)
132148
{
133149
// Replacing the function patch 'CTerrorPlayer::UpdateHangingFromTongue'.
150+
// This dmg function is called after variable 'CTerrorPlayer::m_tongueDragDamageTimer' is set, we can't get it here.
134151
if (!(iDamageType & DMG_CHOKE)) {
135152
return Plugin_Continue;
136153
}
@@ -141,23 +158,20 @@ Action Hook_OnTakeDamage(int iVictim, int &iAttacker, int &iInflictor, float &fD
141158
}
142159

143160
// Stop dragging.
144-
bool bIsHangingFromTongue = (GetEntProp(iVictim, Prop_Send, "m_isHangingFromTongue", 1) > 0);
145-
if (bIsHangingFromTongue) {
161+
if (GetEntProp(iVictim, Prop_Send, "m_isHangingFromTongue", 1) > 0) {
146162
return Plugin_Continue;
147163
}
148164

149165
// Fix damage interval.
150166
SetDragDamageTimer(iVictim, g_hTongueDragDamageInterval.FloatValue);
151167

152168
// First damage if cvar enabled.
169+
g_iTongueHitCount[iVictim][eHitCount]++;
153170
bool bFirstDamage = false;
154-
float fTongueDragFirstDamage = g_hTongueDragFirstDamage.FloatValue;
155171

156-
if (fTongueDragFirstDamage > 0.0) {
157-
float fTongueVictimTimer = GetEntPropFloat(iVictim, Prop_Send, "m_tongueVictimTimer", IT_TIMESTAMP_INDEX);
158-
159-
if (FloatCompareEps(fTongueVictimTimer, GetFirstDamageInterval()) == 0) {
160-
fDamage = fTongueDragFirstDamage;
172+
if (g_hTongueDragFirstDamage.FloatValue > 0.0) {
173+
if (g_iTongueHitCount[iVictim][eHitCount] == 1 && g_iTongueHitCount[iVictim][eUserId] == GetClientUserId(iVictim)) {
174+
fDamage = g_hTongueDragFirstDamage.FloatValue;
161175
bFirstDamage = true;
162176
}
163177
}
@@ -188,18 +202,6 @@ void SetDragDamageTimer(int iClient, float fDuration)
188202
SetEntDataFloat(iClient, g_iTongueDragDamageTimerTimeStampOffset, fTimeStamp, false); // 'CountdownTimer::timestamp'
189203
}
190204

191-
// For small differences in tick interval.
192-
int FloatCompareEps(float fOne, float fTwo, float fEps = EPSILON)
193-
{
194-
if (FloatAbs(fOne - fTwo) < fEps) {
195-
return 0;
196-
} else if (fOne > fTwo) {
197-
return 1;
198-
}
199-
200-
return -1;
201-
}
202-
203205
#if DEBUG
204206
void DebugPrint(int iVictim, float fDamage, bool bFirstDamage)
205207
{

0 commit comments

Comments
 (0)