mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 08:52:42 +00:00
N6/C3 W2: world boss — the daily bout, command, operator spawn
Wires the player-facing half of the Siege on top of W1's model + lifecycle. - !adventure worldboss [status|fight|spawn] (alias !adventure siege). Status shows the shared-pool board + your daily bout state + the muster; fight takes today's bout; spawn is an admin override (the "both" spawn decision). - The bout is an arena-style solo fight through runZoneCombat vs a disposable per-tier stat block; the damage dealt (EnemyEntryHP-EnemyEndHP) is subtracted from the shared pool atomically (MAX(0, …) WHERE status='active') win or lose. Real HP cost like the arena, but no death/no hospital: worldBossFloorHP raises a 0-HP loser to 1 so a loss reads as "battered", not a corpse. - One bout per player per UTC day (worldBossBoutUsedToday off the contrib's last_fight_date). The per-user advUserLock serialises a player's own repeat submits so the gate can't be raced; cross-player pool-crossing is safe because only the setWorldBossStatus winner resolves a defeat. - A killing bout trips resolveWorldBossDefeated (minted bounty by fights + cache + treasure roll), after the fighter's own bout DM has streamed. Bout core (resolveWorldBossBout) + the once/day predicate + the HP floor are factored out of the DM path so they're unit-tested end to end with a real fightable character; the DM/games-room emission stays thin (no client stub). Combat golden byte-identical; full plugin suite green. Claude-Session: https://claude.ai/code/session_017mEwUmmS7aQTP2NQXj6rUa
This commit is contained in:
@@ -537,6 +537,10 @@ func (p *AdventurePlugin) dispatchCommand(ctx MessageContext) error {
|
||||
return p.handleJournalCmd(ctx)
|
||||
case lower == "shadow":
|
||||
return p.handleShadowCmd(ctx)
|
||||
case lower == "worldboss" || strings.HasPrefix(lower, "worldboss "):
|
||||
return p.handleWorldBossCmd(ctx, strings.TrimSpace(args[len("worldboss"):]))
|
||||
case lower == "siege" || strings.HasPrefix(lower, "siege "):
|
||||
return p.handleWorldBossCmd(ctx, strings.TrimSpace(args[len("siege"):]))
|
||||
}
|
||||
|
||||
return p.SendDM(ctx.Sender, "Unknown command. Type `!adventure help` to see available commands.")
|
||||
@@ -570,6 +574,7 @@ const advHelpText = `**Adventure Commands**
|
||||
` + "`!adventure treasures`" + ` — List your treasures · ` + "`treasures lock`" + ` to refuse swaps
|
||||
` + "`!adventure journal`" + ` — Read the campaign pages you've recovered
|
||||
` + "`!adventure shadow`" + ` — See how your rival's run compares to yours
|
||||
` + "`!adventure worldboss`" + ` — The monthly Siege: one communal bout a day (` + "`fight`" + ` to join)
|
||||
` + "`!hospital`" + ` — Visit St. Guildmore's Memorial Hospital (same-day revival when dead)
|
||||
` + "`!thom`" + ` — Visit Thom Krooke (housing and loans)
|
||||
` + "`!adventure help`" + ` — This message
|
||||
|
||||
Reference in New Issue
Block a user