mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 00:52:40 +00:00
Adv 2.0 D&D Phase 11 D2b: Tier 1 zone flavor files
New additive flavor files (zone_goblin_warrens_flavor.go, zone_crypt_valdris_flavor.go) with elite-room intros, boss ability callouts (Grol: Surprise Attack / Heart of Hruggek / Terrifying Roar; Valdris: Corrupting Touch / Legendary Resistance / Call of the Grave / Phase Two), and zone-specific lore deep-dives. Existing twinbee_gm_flavor.go is untouched per the protected-files contract. Wires three narration helpers in dnd_zone_narration.go: composeBossEntry — boss-entry render plus a one-line ability callout eliteRoomEntryLine — elite-room atmospheric prefix zoneLorePool — zone-specific !lore pool with generic fallback Boss-entry callsite in dnd_zone_cmd.go now uses composeBossEntry; the elite branch of resolveCombatRoom prefixes with the zone's elite line. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -133,11 +133,81 @@ func pickPool(zoneID ZoneID, kind GMNarrationType) []string {
|
||||
case GMTrapTripped:
|
||||
return flavor.TrapTriggered
|
||||
case GMLore:
|
||||
return flavor.LoreLines
|
||||
return zoneLorePool(zoneID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// zoneLorePool returns the zone-specific lore pool prepended to the
|
||||
// generic LoreLines pool. Tier 1 zones ship dedicated lore (D2b); other
|
||||
// tiers fall back to the generic pool until their flavor files land.
|
||||
func zoneLorePool(zoneID ZoneID) []string {
|
||||
switch zoneID {
|
||||
case ZoneGoblinWarrens:
|
||||
return append(append([]string{}, flavor.LoreLinesWarrens...), flavor.LoreLines...)
|
||||
case ZoneCryptValdris:
|
||||
return append(append([]string{}, flavor.LoreLinesCrypt...), flavor.LoreLines...)
|
||||
}
|
||||
return flavor.LoreLines
|
||||
}
|
||||
|
||||
// bossSignaturePool returns the zone-boss ability-callout pool (one-line
|
||||
// cinematic suffix sampled at boss-entry render). Returns nil when the
|
||||
// zone has no signature pool yet — caller skips the suffix.
|
||||
func bossSignaturePool(zoneID ZoneID) []string {
|
||||
switch zoneID {
|
||||
case ZoneGoblinWarrens:
|
||||
return flavor.GrolSignatureCallouts
|
||||
case ZoneCryptValdris:
|
||||
return flavor.ValdrisSignatureCallouts
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// eliteRoomEntryPool returns the zone-specific elite-room atmospheric
|
||||
// pool. Returns nil when the zone has no dedicated elite prose.
|
||||
func eliteRoomEntryPool(zoneID ZoneID) []string {
|
||||
switch zoneID {
|
||||
case ZoneGoblinWarrens:
|
||||
return flavor.EliteRoomEntryWarrens
|
||||
case ZoneCryptValdris:
|
||||
return flavor.EliteRoomEntryCrypt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// composeBossEntry renders the boss-entry narration plus, when the zone
|
||||
// has a signature pool, a single ability callout on the line below.
|
||||
// Falls back to the bare boss-entry line when no signature pool exists.
|
||||
func composeBossEntry(zoneID ZoneID, runID string, roomIdx int) string {
|
||||
entry := twinBeeLine(zoneID, GMBossEntry, runID, roomIdx)
|
||||
pool := bossSignaturePool(zoneID)
|
||||
if entry == "" || len(pool) == 0 {
|
||||
return entry
|
||||
}
|
||||
// Salt the suffix selector with a constant so the entry line and the
|
||||
// callout line vary independently across rooms.
|
||||
callout := pickLineDeterministic(pool, runID, roomIdx^0x5BD17EF1)
|
||||
if callout == "" {
|
||||
return entry
|
||||
}
|
||||
return entry + "\n🎭 **TwinBee:** " + callout
|
||||
}
|
||||
|
||||
// eliteRoomEntryLine renders the zone-specific elite atmospheric line
|
||||
// for an elite room. Empty string when the zone has no elite pool yet.
|
||||
func eliteRoomEntryLine(zoneID ZoneID, runID string, roomIdx int) string {
|
||||
pool := eliteRoomEntryPool(zoneID)
|
||||
if len(pool) == 0 {
|
||||
return ""
|
||||
}
|
||||
line := pickLineDeterministic(pool, runID, roomIdx^0x2C9E1A37)
|
||||
if line == "" {
|
||||
return ""
|
||||
}
|
||||
return "🎭 **TwinBee:** " + line
|
||||
}
|
||||
|
||||
// pickLineDeterministic — stable selection across (runID, salt). Same
|
||||
// inputs always yield the same line, so a player who re-reads status
|
||||
// sees the same prose; different rooms / different runs vary.
|
||||
|
||||
Reference in New Issue
Block a user