Long expeditions D1-a: graph-driven TotalRooms; goblin_warrens 7→16

Length is now sourced from the zone graph's longest entry→boss path,
not the dice roll, so "Room X/Y" matches what the player walks. The
dice fallback stays for graphless zones.

Goblin Warrens grows to the T1 12–14 band (13-node traversal): adds the
missing Trap anchor and deepens both fork branches + the post-merge
approach. Pattern reference for the remaining zones in D1-b…d.
This commit is contained in:
prosolis
2026-05-27 17:24:36 -07:00
parent 92b99a0399
commit 4999368031
6 changed files with 134 additions and 38 deletions

View File

@@ -108,11 +108,21 @@ func (r *DungeonRun) CurrentRoomType() RoomType {
// generateRoomSequence builds the deterministic-but-seeded room layout
// for a run of the given zone. The boss room is always last; one Entry
// is always first; one Trap and one Elite room sit between explorations.
// Total length is sampled in [zone.MinRooms, zone.MaxRooms].
//
// Total length tracks the zone's *graph* longest entry→boss path so the
// "Room X/Y" display lines up with what the player actually walks. If
// the graph hasn't been authored / can't be loaded, we fall back to a
// dice roll within [zone.MinRooms, zone.MaxRooms] (the pre-graph shape).
func generateRoomSequence(zone ZoneDefinition, rng *rand.Rand) []RoomType {
total := zone.MinRooms
if zone.MaxRooms > zone.MinRooms {
total += rng.IntN(zone.MaxRooms - zone.MinRooms + 1)
total := 0
if g, ok := loadZoneGraph(zone.ID); ok {
total = graphLongestPath(g)
}
if total == 0 {
total = zone.MinRooms
if zone.MaxRooms > zone.MinRooms {
total += rng.IntN(zone.MaxRooms - zone.MinRooms + 1)
}
}
// Fixed slots: Entry + Trap + Elite + Boss = 4. Remaining = explorations.
const fixed = 4