aboutsummaryrefslogtreecommitdiff
path: root/internal/combat
diff options
context:
space:
mode:
Diffstat (limited to 'internal/combat')
-rw-r--r--internal/combat/state.go7
-rw-r--r--internal/combat/state_test.go20
2 files changed, 27 insertions, 0 deletions
diff --git a/internal/combat/state.go b/internal/combat/state.go
index e1ee8e7..17a9c09 100644
--- a/internal/combat/state.go
+++ b/internal/combat/state.go
@@ -36,6 +36,13 @@ func (t *Tracker) Enter(playerName, mobID string) {
if prev, ok := t.combatants[playerName]; ok {
delete(t.mobTargets, prev.MobID)
}
+ // If another player already holds this mob, replacing the mobTargets
+ // entry would leave their combatants entry pointing at a mob this new
+ // player now owns. Clear it so their later Leave cannot delete this
+ // player's claim and unlock a mob that is still being fought.
+ if prevOwner, ok := t.mobTargets[mobID]; ok && prevOwner != playerName {
+ delete(t.combatants, prevOwner)
+ }
t.combatants[playerName] = &State{
PlayerName: playerName,
MobID: mobID,
diff --git a/internal/combat/state_test.go b/internal/combat/state_test.go
index 8005ba3..d21bc0d 100644
--- a/internal/combat/state_test.go
+++ b/internal/combat/state_test.go
@@ -19,3 +19,23 @@ func TestTrackerEnterReleasesPreviousMob(t *testing.T) {
t.Fatal("mobB still marked in combat after leave")
}
}
+
+// Regression: two players claiming the same mob must not leave a dangling
+// combatants entry for the displaced player; otherwise that player's later
+// Leave deletes the new owner's mobTargets claim and unlocks a live fight.
+func TestTrackerEnterDisplacesOtherPlayer(t *testing.T) {
+ tr := NewTracker()
+ tr.Enter("alice", "mobA")
+ tr.Enter("bob", "mobA")
+ if !tr.IsMobInCombat("mobA") {
+ t.Fatal("mobA should still be in combat after the second claim")
+ }
+ if tr.MobTarget("mobA") != "bob" {
+ t.Fatalf("mobTarget = %q, want bob", tr.MobTarget("mobA"))
+ }
+ // Alice was displaced; her leave must not unlock Bob's fight.
+ tr.Leave("alice")
+ if !tr.IsMobInCombat("mobA") || tr.MobTarget("mobA") != "bob" {
+ t.Fatal("alice's leave unlocked the mob bob is still fighting")
+ }
+}