mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 16:42:41 +00:00
Both T3 zones follow the D1-a/b pattern: extend the graph so the longest entry→boss walk lands in band, keep the zone's authored topology intact. manor_blackspire (T3): 11 → 35 nodes, longest 23 (band 22-26) underforge (T3): 10 → 31 nodes, longest 23 (band 22-26) Topology preserved per zone: - Manor: two-stacked-3-way forks identity + full lock-kind coverage (LockNone, LockPerception, LockStatCheck, LockLevelMin). Adds the missing Trap anchor (Cursed Threshold). All six spokes are 3 mid-nodes so route choice is loot/encounter character, not shortcut economics. - Underforge: one-way-descent gauntlet identity preserved — 17-node linear preamble through the existing Cooling River (TRAP) and Magma Chamber (ELITE), single 3-way antechamber fork before boss. All three antechamber spokes are 4 mid-nodes. MinRooms/MaxRooms re-pitched 7-9 → 22-26 so the dice fallback also lands in band for any future graphless variant.
67 lines
2.0 KiB
Go
67 lines
2.0 KiB
Go
package plugin
|
|
|
|
import "testing"
|
|
|
|
func TestUnderforgeGraph_Registered(t *testing.T) {
|
|
g, ok := zoneGraphRegistry[ZoneUnderforge]
|
|
if !ok {
|
|
t.Fatal("zoneUnderforgeGraph not registered")
|
|
}
|
|
// Long-expedition D1-c widened this zone from 10 → 31 nodes so the
|
|
// longest entry→boss walk lands in the T3 [22,26] traversal band.
|
|
if len(g.Nodes) != 31 {
|
|
t.Errorf("nodes = %d, want 31", len(g.Nodes))
|
|
}
|
|
}
|
|
|
|
// TestUnderforgeGraph_LinearPreamble locks in the gauntlet identity:
|
|
// every node from entry through resonance_passage has exactly one
|
|
// outgoing edge — the only decision in the zone is the antechamber
|
|
// 3-way at the very end. D1-c extends the chain but preserves the
|
|
// "one-way descent" intent ("Kharak Dûn is a one-way descent — there
|
|
// is no scenic route").
|
|
func TestUnderforgeGraph_LinearPreamble(t *testing.T) {
|
|
g := zoneUnderforgeGraph()
|
|
for _, id := range []string{
|
|
"underforge.entry",
|
|
"underforge.sealed_threshold",
|
|
"underforge.wardstone_arch",
|
|
"underforge.forge_descent",
|
|
"underforge.vapor_steps",
|
|
"underforge.slag_warrens",
|
|
"underforge.cooling_river",
|
|
"underforge.bellows_chamber",
|
|
"underforge.cinder_walk",
|
|
"underforge.magma_chamber",
|
|
"underforge.emberforge_hall",
|
|
"underforge.ashfall_corridor",
|
|
"underforge.smelting_vault",
|
|
"underforge.foreman_landing",
|
|
"underforge.broken_crucible",
|
|
"underforge.great_anvil",
|
|
"underforge.resonance_passage",
|
|
} {
|
|
outs := g.outgoingEdges(id)
|
|
if len(outs) != 1 {
|
|
t.Errorf("preamble node %s outgoing = %d, want 1 (gauntlet)", id, len(outs))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUnderforgeGraph_AntechamberThreeWay(t *testing.T) {
|
|
g := zoneUnderforgeGraph()
|
|
outs := g.outgoingEdges("underforge.antechamber")
|
|
if len(outs) != 3 {
|
|
t.Fatalf("antechamber outgoing = %d, want 3", len(outs))
|
|
}
|
|
for _, leaf := range []string{
|
|
"underforge.direct_assault",
|
|
"underforge.catwalks",
|
|
"underforge.forge_vault",
|
|
} {
|
|
if !reachable(g, leaf, "underforge.boss") {
|
|
t.Errorf("%s unreachable to boss", leaf)
|
|
}
|
|
}
|
|
}
|