Fix battlefield objectives never completing capture, and PQ timers following players - #177
Open
Chris443C wants to merge 1 commit into
Open
Fix battlefield objectives never completing capture, and PQ timers following players#177Chris443C wants to merge 1 commit into
Chris443C wants to merge 1 commit into
Conversation
…llowing players BattlefieldObjective.CheckTimers(): CaptureTimer and GuardedTimer were never reset once they elapsed. Neither SetObjectiveCaptured nor SetObjectiveGuarded clears them, so CheckTimers - which runs once a second and fires on timer <= now - re-fired the same command every second indefinitely. Those repeat fires land in a state that has no transition for them, for example OnCaptureTimerEnd while the objective is already Captured, and since the state machine registers no exception listener that raises out of CheckTimers once per second. The objective stayed showing its capture state at 0:00 and never progressed to Guarded. Both timers are now cleared before firing, making them one-shot as the code already intended - each is set fresh in SetObjectiveCapturing and SetObjectiveCaptured. Player.CheckArea(): public quest membership was only dropped when moving into the "no PQ area" sentinel (31). Moving from one PQ area directly into another, or into any area with no matching PQ, left the player on the old quest's ActivePlayers list and still receiving its stage timer long after leaving. Membership is now dropped on any area change, and re-added below when the new area maps to a PQ. RemovePlayer already emits F_OBJECTIVE_UPDATE with 0, which clears the tracker on the client. CampaignCommands: add ".campaign objdiag", reporting the state, owner, capture and secure progress, and raw timers of the battlefield objective the player is standing at. BattlefieldObjective.SendDiagnostic() already existed but nothing called it - ".campaign diag" covers campaign victory points and keep status only, so there was previously no way to inspect an objective's actual state in game. This is what identified both issues above. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three related fixes found while testing RvR on a local server. Independent of #176.
1.
BattlefieldObjective.CheckTimers()— objectives never finish capturingCaptureTimerandGuardedTimerare never reset once they elapse. NeitherSetObjectiveCapturednorSetObjectiveGuardedclears them, andCheckTimersruns once a second firing ontimer <= now— so an elapsed timer re-fires its command every second, indefinitely.Those repeat fires land in a state with no transition for them (e.g.
OnCaptureTimerEndwhile alreadyCaptured). The state machine registers no exception listener, so that raises out ofCheckTimersonce per second and the objective never progresses toGuarded— it sits displaying its capture state at0:00.Both timers are now cleared before firing, making them one-shot as the code already intends: each is set fresh in
SetObjectiveCapturing/SetObjectiveCaptured.2.
Player.CheckArea()— public quest timer follows the playerPQ membership was only dropped when moving into the "no PQ area" sentinel (
pqarea == 31). Moving from one PQ area straight into another — or into any area with no matching PQ — left the player on the old quest'sActivePlayerslist, still receiving its stage timer long after leaving the area.Membership is now dropped on any area change, and re-added below when the new area maps to a PQ.
RemovePlayeralready emitsF_OBJECTIVE_UPDATEwith0, which clears the tracker client-side.3.
.campaign objdiag— newBattlefieldObjective.SendDiagnostic()already existed but nothing ever called it;.campaign diagreports campaign victory points and keep status only. There was no way to inspect an objective's real state in game..campaign objdiagreports the state, owner, control/secure progress and raw timers for the objective the player is standing at. This is what identified both issues above, and it distinguishes a server-side fault from a client display one.Testing
On a local server against the published database:
0:00, never announcing capture or spawning guards.Contested → Secure → Guardedcompletes, the capture is announced and guards spawn. Verified on Martyr's Square in Praag.Two notes on scope, in the interest of being straight about what was and wasn't verified:
AddInRangeis gated onValidInTier. That is existing intended behaviour and is not changed here, but it makes objective issues easy to misdiagnose when testing at the wrong rank.No configuration or data files are included.
🤖 Generated with Claude Code