mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 00:52:40 +00:00
Adv 2.0 D&D Phase 12 E3b: Haunted Manor nightly reset
§7.2 cycle: every 3rd day's morning briefing in Blackspire fires the "manor reset" temporal log — non-boss rooms respawn one enemy each. Boss-defeated suppresses. Wrong-zone is a no-op. Exposes ManorReset(e, day) bool for the combat-link phase to read at !advance time when applying the actual respawn (per the deferral pattern from E2b's wandering-encounter combat). Reuses flavor.HauntedManorResetMorning per feedback_reuse_existing_flavor. Deferred: Night-2 quiet warning narration on the recap path — needs a new hook in deliverRecap; not load-bearing for the reset itself. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,10 @@ func applyZoneTemporalPreBurn(e *Expedition, nextDay int) (extraHarsh bool) {
|
||||
return extraHarsh
|
||||
}
|
||||
|
||||
// ManorResetCycleDays is the §7.2 reset cadence — non-boss rooms
|
||||
// respawn one enemy each on the morning of every Nth day.
|
||||
const ManorResetCycleDays = 3
|
||||
|
||||
// applyZoneTemporalPostRollover runs AFTER advance + threat drift.
|
||||
// It appends per-zone narration log entries for the day that just
|
||||
// became current. Returns lines to append to the briefing body.
|
||||
@@ -56,6 +60,8 @@ func applyZoneTemporalPostRollover(e *Expedition) []string {
|
||||
switch e.ZoneID {
|
||||
case ZoneSunkenTemple:
|
||||
return sunkenTempleTemporalPostRollover(e)
|
||||
case ZoneManorBlackspire:
|
||||
return manorTemporalPostRollover(e)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -95,3 +101,39 @@ func sunkenTempleTemporalPostRollover(e *Expedition) []string {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────
|
||||
// §7.2 — Haunted Manor of Blackspire, Nightly Reset
|
||||
// ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
// ManorReset reports whether the briefing rolling onto `day` is the
|
||||
// reset morning (every 3rd day: 3, 6, 9, ...). Boss-defeated suppresses.
|
||||
func ManorReset(e *Expedition, day int) bool {
|
||||
if e.BossDefeated || e.ZoneID != ZoneManorBlackspire {
|
||||
return false
|
||||
}
|
||||
return day >= ManorResetCycleDays && day%ManorResetCycleDays == 0
|
||||
}
|
||||
|
||||
// manorTemporalPostRollover writes a "house reset" entry on Day 3, 6,
|
||||
// 9, ... and a quiet pre-reset warning on the day after that (Day 4,
|
||||
// 7, ...) — which corresponds to the briefing fired on the morning
|
||||
// after the warning night, so we anchor narration at the briefing.
|
||||
//
|
||||
// Spec §7.2: "TwinBee notes on Night 2: 'The house has been quiet.
|
||||
// That will not last.' On Night 3 morning: 'Overnight, something moved
|
||||
// back in.'" — we fire the reset narration on the reset morning. The
|
||||
// quiet-warning Night 2 line lives on the recap path (E2b's deliverRecap
|
||||
// will add it as a separate hook in a future commit if desired); for
|
||||
// E3b we keep the rule simple: only the reset morning fires here.
|
||||
func manorTemporalPostRollover(e *Expedition) []string {
|
||||
day := e.CurrentDay
|
||||
if !ManorReset(e, day) {
|
||||
return nil
|
||||
}
|
||||
line := flavor.Pick(flavor.HauntedManorResetMorning)
|
||||
_ = appendExpeditionLog(e.ID, day, "temporal",
|
||||
fmt.Sprintf("manor reset — non-boss rooms respawned one enemy each (cycle day %d)", day),
|
||||
line)
|
||||
return []string{line}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user