Adv 2.0 Phase L3: delete co-op dungeons; refund in-flight runs on startup

Drop the coop_dungeon system per migration plan §5. 11 coop_*.go files
removed; cleanup_l3.go added with an idempotent per-run status-guarded
UPDATE that cancels any open/active runs and refunds member contributions
plus unsettled bets via EuroPlugin.Credit. Tables retained for now;
schema purge deferred to a future GOGOBEE_COOP_PURGE pass.

adventure.go drops !coop dispatch, coopTicker, the startup combat-lock
hook, and the !coop help line. adventure_scheduler.go loses the
activeCoopMemberSet skip branch and the post-reset combat-lock call.
adventure_render.go drops the teaser plus the in-coop status block;
replaced with a one-week morning-DM closure announcement
(TODO: remove after 2026-05-16). TestPickCoopTeaserCandidate_SkipsLeader
removed.

go vet ./... and go test ./... clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-09 09:17:10 -07:00
parent 3b4dfa44d3
commit d300008812
17 changed files with 133 additions and 4916 deletions

View File

@@ -42,7 +42,7 @@ type AdventurePlugin struct {
// stopCh is closed by Stop() to signal all background tickers
// (morning/summary/midnight/event/rival/robbie/hospital/mortgage/
// coop/expedition briefing+recap) to exit. Each ticker selects
// expedition briefing+recap) to exit. Each ticker selects
// on its time.Ticker channel and stopCh; the second branch returns.
stopCh chan struct{}
}
@@ -194,9 +194,9 @@ func (p *AdventurePlugin) Init() error {
if err := backfillPlayerMetaArena(); err != nil {
slog.Error("player_meta: arena backfill failed", "err", err)
}
if err := lockCoopCombatActions(); err != nil {
slog.Error("adventure: startup coop combat lock failed", "err", err)
}
// Phase L3 — cancel any open/active legacy coop dungeon runs and
// refund member contributions + unsettled bets. Idempotent.
closeAndRefundLegacyCoopRuns(p.euro)
// Phase R1 orphan-archive used to run here on every Init, but it
// over-archived: it treats any active dnd_zone_run row not linked to
// an active expedition as a legacy `!adventure dungeon` orphan, which
@@ -221,7 +221,6 @@ func (p *AdventurePlugin) Init() error {
go p.robbieTicker()
go p.hospitalNudgeTicker()
go p.mortgageTicker()
go p.coopTicker()
go p.expeditionBriefingTicker()
go p.expeditionRecapTicker()
@@ -366,11 +365,6 @@ func (p *AdventurePlugin) OnMessage(ctx MessageContext) error {
return p.handleHospitalCmd(ctx)
}
// 1c. Co-op dungeon commands (work in rooms and DMs)
if p.IsCommand(ctx.Body, "coop") {
return p.handleCoopCmd(ctx)
}
// 2. Check if this is a DM reply from a registered player
p.mu.Lock()
playerID, isDM := p.dmToPlayer[ctx.RoomID]
@@ -478,7 +472,6 @@ const advHelpText = `**Adventure Commands**
` + "`!adventure recipes`" + ` — List crafting recipes known at your current Foraging level
` + "`!adventure mastery`" + ` — Per-slot equipment mastery progress and active bonus
` + "`!adventure treasures`" + ` — List your treasures · ` + "`treasures lock`" + ` to refuse swaps
` + "`!coop`" + ` — Co-op dungeons (multi-day party runs). See ` + "`!coop help`" + `.
` + "`!hospital`" + ` — Visit St. Guildmore's Memorial Hospital (same-day revival when dead)
` + "`!thom`" + ` — Visit Thom Krooke (housing and loans)
` + "`!adventure help`" + ` — This message