mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 00:52:40 +00:00
Adv 2.0 D&D polish: GM→DM rename, streamed zone combat, end-to-end scenario test
GM→DM rename across docs and code (GMNarrationType→DMNarrationType, GMState→DMState, narration constants, comments) so the system reads as "Dungeon Master" everywhere. Player-visible "GM mood" wording stays where it appears in flavor. Streamed zone/expedition combat: zone advance now stages patrol → patrol play-by-play → patrol resolution → room intro → room play-by-play → final outcome through sendZoneCombatMessages with 2–3s pacing (arena keeps its 5–8s window). Combat narrative lines pick up a compact d20-vs-AC roll annotation for hit/crit/miss/block events. Combat outcome polish: dndHPSnapshot lets narration show sheet HP rather than legacy combat-engine HP, and markAdventureDead clears the zombie state where hp_current was 0 but the legacy alive flag stayed true after a D&D-layer KO. Adv 2.0 announcement (ADVENTURE_2.0_ANNOUNCEMENT.md), README rewrite covering the new layer, and adv2_scenario_test.go — a full zone-run + expedition + harvest playthrough against a copy of the prod DB asserting persisted state end-to-end. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -328,12 +328,27 @@ func (p *AdventurePlugin) prependCraftNarrative(userID id.UserID, messages []str
|
||||
// Runs in a goroutine so it doesn't block the message handler.
|
||||
// Returns a channel that is closed when all messages have been sent.
|
||||
func (p *AdventurePlugin) sendCombatMessages(userID id.UserID, phaseMessages []string, finalMessage string) <-chan struct{} {
|
||||
return p.sendCombatMessagesWithDelay(userID, phaseMessages, finalMessage, 5, 4) // 5–8s
|
||||
}
|
||||
|
||||
// sendZoneCombatMessages is the zone/expedition variant — same staging as
|
||||
// arena, but tighter pacing (2–3s) so dungeon advances feel snappier.
|
||||
func (p *AdventurePlugin) sendZoneCombatMessages(userID id.UserID, phaseMessages []string, finalMessage string) <-chan struct{} {
|
||||
return p.sendCombatMessagesWithDelay(userID, phaseMessages, finalMessage, 2, 2) // 2–3s
|
||||
}
|
||||
|
||||
// sendCombatMessagesWithDelay is the shared streamer. base/jitter define
|
||||
// the per-message delay window in seconds: delay = base + rand.IntN(jitter).
|
||||
func (p *AdventurePlugin) sendCombatMessagesWithDelay(userID id.UserID, phaseMessages []string, finalMessage string, base, jitter int) <-chan struct{} {
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer close(done)
|
||||
for _, msg := range phaseMessages {
|
||||
_ = p.SendDM(userID, msg)
|
||||
delay := 5 + rand.IntN(4) // 5-8 seconds
|
||||
delay := base
|
||||
if jitter > 0 {
|
||||
delay += rand.IntN(jitter)
|
||||
}
|
||||
time.Sleep(time.Duration(delay) * time.Second)
|
||||
}
|
||||
_ = p.SendDM(userID, finalMessage)
|
||||
|
||||
Reference in New Issue
Block a user