diff options
| author | historia <[not public]> | 2026-10-06 12:57:23 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-10-06 12:57:23 -0400 |
| commit | 9666676766bf21364f4fc4d0d1d336e72f2a91b4 (patch) | |
| tree | 0cade34091d7602790dc38cd44053f0b74bbadf2 /internal/game/sys_triggers.go | |
| parent | 4bc1daaf259e0c19c5fe4a12ec8bc7f6e5a735c1 (diff) | |
| download | thehouseoficarus-9666676766bf21364f4fc4d0d1d336e72f2a91b4.tar.gz | |
refactor: split casino.go, dedup helpers, remove audit docs
Diffstat (limited to 'internal/game/sys_triggers.go')
| -rw-r--r-- | internal/game/sys_triggers.go | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/internal/game/sys_triggers.go b/internal/game/sys_triggers.go index 790eb12..6ae5e21 100644 --- a/internal/game/sys_triggers.go +++ b/internal/game/sys_triggers.go @@ -33,6 +33,7 @@ type sequence struct { key string // dedup key locked bool // atomic + resumable on disconnect roomLocked bool // skip steps whose player has left roomID + dirty bool // a step advanced since the last persisted snapshot } // verbSeqKey builds a dedup key for a verb-triggered sequence so two of the @@ -144,6 +145,7 @@ func (g *Game) advanceSequence(seq *sequence) { seq.wait-- if seq.wait <= 0 && len(seq.steps) > 0 { seq.steps = seq.steps[1:] + seq.dirty = true if len(seq.steps) > 0 { seq.wait = seq.steps[0].Wait } @@ -160,6 +162,7 @@ func (g *Game) advanceSequence(seq *sequence) { for seq.wait <= 0 && len(seq.steps) > 0 { step := seq.steps[0] seq.steps = seq.steps[1:] + seq.dirty = true jobs = append(jobs, step) if len(seq.steps) > 0 { seq.wait = seq.steps[0].Wait @@ -233,6 +236,10 @@ func (g *Game) syncPendingSequence(seq *sequence, p *player.Player) { if len(seq.steps) == 0 { return } + if !seq.dirty { + return + } + seq.dirty = false p.PendingSequence.Steps = append([]behavior.Step(nil), seq.steps...) p.PendingSequence.Wait = seq.wait g.saveCharacter(p) @@ -301,6 +308,15 @@ func (g *Game) cancelSequences(name string) { delete(g.sequences, k) } g.seqMu.Unlock() + // Clearing the live sequences is not enough: the persisted marker would + // otherwise re-arm the cancelled steps on the next login. + g.charsMu.Lock() + sess := g.loggedInChars[name] + g.charsMu.Unlock() + if sess != nil && sess.Player != nil && sess.Player.PendingSequence != nil { + sess.Player.PendingSequence = nil + g.saveCharacter(sess.Player) + } } // abortAllSequences drops every in-flight sequence (player and global) and @@ -360,7 +376,8 @@ func (g *Game) resumePendingSequence(sess *net.Session, p *player.Player) { return } ps := p.PendingSequence - p.PendingSequence = nil + // Keep the marker: completePlayerSequence clears it when the matching key + // finishes, so a crash mid-resume still has a durable snapshot to replay. seq := &sequence{ sess: sess, player: p, @@ -400,11 +417,12 @@ func (g *Game) TransientMobTick() { g.charsMu.Lock() ownerSess := g.loggedInChars[inst.Owner] g.charsMu.Unlock() - if ownerSess == nil || ownerSess.Player == nil { - continue + // An offline owner counts as out of the allowed rooms so the despawn + // grace still runs; otherwise the mob persists forever after logout. + ownerRoom := -1 + if ownerSess != nil && ownerSess.Player != nil { + ownerRoom = ownerSess.Player.RoomID } - - ownerRoom := ownerSess.Player.RoomID allowed := inst.DespawnRooms if len(allowed) == 0 { allowed = []int{inst.HomeRoomID} |
