Skip to content

fix: keep blocking respawns through the whole warmup teardown - #38

Merged
Rushaway merged 3 commits into
masterfrom
fix/warmup-end-respawn-block
Sep 14, 2026
Merged

Rushaway merged 3 commits into
masterfrom
fix/warmup-end-respawn-block

Conversation

@Rushaway

@Rushaway Rushaway commented Sep 9, 2026

Copy link
Copy Markdown
Member

Audit finding — g_bBlockRespawn window is effectively zero

Timer_ForceSuicide() did:

g_bBlockRespawn = true;
for (...) ForcePlayerSuicide(i);
g_bBlockRespawn = false;   // same frame

g_bBlockRespawn is read by ZR_OnClientRespawn() to suppress
ZombieReloaded respawns while warmup is ending. ZR respawns players on a
delay after death, so by the time those respawns fire the flag is
already back to false and players respawn in the middle of the warmup
teardown / round restart — exactly what the flag is meant to prevent.

Changes

  • Set g_bBlockRespawn when the suicide timer is scheduled (in
    EndWarmUp()), and leave it set. It is cleared again in OnRoundEnd(),
    in Timer_FireForward() (belt-and-suspenders, in case round_end is
    suppressed) and in InitWarmup() — all of which run once the round has
    actually restarted.
  • Harden the iCleanMode == 2 entity cleanup loop while here:
    • hoist the g_hEntitiesListToKill != null check out of the loop,
    • start iteration at MaxClients + 1 (client indices can never be in
      the kill list),
    • skip entities whose classname cannot be read instead of matching
      against a stale buffer.

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings September 9, 2026 16:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The behavioral change matches the stated intent and the remaining feedback is limited to keeping newly added comments accurate to the actual reset points.

Pull request overview

Fixes a warmup teardown timing issue where g_bBlockRespawn was being cleared too quickly to reliably suppress ZombieReloaded delayed respawns during the end-of-warmup slay/restart sequence.

Changes:

  • Keeps g_bBlockRespawn set across the warmup teardown window (set in EndWarmUp(), no longer cleared immediately in Timer_ForceSuicide(), cleared later).
  • Hardens the iCleanMode == 2 entity cleanup loop (skip client indices, avoid stale classname buffer usage, and avoid redundant null checks).
File summaries
File Description
addons/sourcemod/scripting/TeamManager.sp Extends the respawn-block window through warmup teardown and improves safety/efficiency of entity cleanup during warmup end.
Review details

Suppressed comments (1)

addons/sourcemod/scripting/TeamManager.sp:254

  • This comment says g_bBlockRespawn is reset in OnRoundEnd()/InitWarmup(), but the implementation also resets it in Timer_FireForward(). Align the comment with the actual reset points so the lifecycle of the flag is clear.
	// g_bBlockRespawn stays set here: ZombieReloaded may respawn players on a
	// delay after death, so clearing it right away would let them respawn
	// during the warmup teardown. It is reset in OnRoundEnd()/InitWarmup().
	g_bBlockRespawn = true;
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread addons/sourcemod/scripting/TeamManager.sp Outdated
Timer_ForceSuicide() set g_bBlockRespawn to true and then cleared it in the
same frame, right after the ForcePlayerSuicide() loop. ZombieReloaded
respawns players on a delay after death, so by the time those respawns ran
the flag was already false and ZR_OnClientRespawn() no longer blocked them.

- Set g_bBlockRespawn when the suicide timer is scheduled and leave it set.
  It is cleared in OnRoundEnd(), Timer_FireForward() and InitWarmup(), all
  of which run once the round has actually restarted.
- Harden the entity cleanup loop: hoist the null check out of the loop,
  start iteration past the client indices, and skip entities whose
  classname cannot be read.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Rushaway
Rushaway force-pushed the fix/warmup-end-respawn-block branch from 0083700 to 72b8307 Compare September 11, 2026 20:47
@Rushaway
Rushaway merged commit b0ce485 into master Sep 14, 2026
6 checks passed
@Rushaway
Rushaway deleted the fix/warmup-end-respawn-block branch September 14, 2026 19:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants