mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 17:02:42 +00:00
adventure: Tier 6 postgame "Mythic" dungeons (P1–P7 calibration)
Five post-game dungeons above the T5 ceiling, gated on both T5 bosses beaten + level 18. Opt-in endgame: deadly solo, clearable by a party with Pete + pets. - P1 gating: postgameUnlocked (T5 clears + level floor), zonesForLevel excludes T6 unconditionally; wired into startZoneRun, !zone/!expedition, party accept, boredom picker, and the list dividers. - P2 bestiary: 15 elites + 5 signature bosses (Layer-1 stat blocks). - P3 zone defs + 4-region registries; ZoneLootEntry.BossOnly. - P4 five zone graphs on a shared builder (44–52 rooms, no soft-lock; Ossuary secret Verse nodes). - P5 loot: BossOnly enforced; signature items are real registry magic items; five Thom pity recipes off the per-zone crafting anchors. - P6 narration/flavor (5 files), T6 achievements, Pete stays zone-parametric. - P7 (in progress): sim can now reach gated T6 (SimRunner.SeedPostgameUnlock + IsPostgameZone). First calibration pass on millenia — hardened ossuary + drowned_star, softened first_hoard + unplace; last_meridian in band. Fix: party members were refused from every T6 zone because expeditionCmdAccept ran the level gate (which excludes T6) before the postgame check — the intended party endgame was unreachable. Route T6 through postgameUnlocked. Regression tests added.
This commit is contained in:
@@ -507,6 +507,33 @@ func TestZoneTrapRoom_AntimagicFieldNoHPLoss(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestZoneLootToInventory_RegistryItemBecomesMagicItem — a signature drop whose
|
||||
// ItemID is in the magic-item registry materializes as an equippable magic_item
|
||||
// carrying the "magic_item:<id>" SkillSource, not generic treasure.
|
||||
func TestZoneLootToInventory_RegistryItemBecomesMagicItem(t *testing.T) {
|
||||
zone, ok := getZone(ZoneFirstHoard)
|
||||
if !ok {
|
||||
t.Fatal("first_hoard zone not registered")
|
||||
}
|
||||
rng := newDeterministicRNG(t, "sig-loot")
|
||||
entry := ZoneLootEntry{ItemID: "aegis_of_the_first_scale", DropChance: 1.0, BossOnly: true}
|
||||
item, ok := zoneLootToInventory(entry, zone, rng)
|
||||
if !ok {
|
||||
t.Fatal("zoneLootToInventory returned ok=false for a registry item")
|
||||
}
|
||||
if item.Type != "magic_item" {
|
||||
t.Errorf("Type = %q, want magic_item", item.Type)
|
||||
}
|
||||
if item.SkillSource != "magic_item:aegis_of_the_first_scale" {
|
||||
t.Errorf("SkillSource = %q, want magic_item:aegis_of_the_first_scale", item.SkillSource)
|
||||
}
|
||||
// A plain non-registry entry still falls through to treasure.
|
||||
plain, _ := zoneLootToInventory(ZoneLootEntry{ItemID: "cooling_ember_of_aurvandryx", UniqueAlways: true}, zone, rng)
|
||||
if plain.Type != "treasure" {
|
||||
t.Errorf("crafting anchor Type = %q, want treasure", plain.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRollZoneLoot_BossLootDrops(t *testing.T) {
|
||||
setupAuditTestDB(t)
|
||||
uid := id.UserID("@zone-loot:example")
|
||||
@@ -517,7 +544,7 @@ func TestRollZoneLoot_BossLootDrops(t *testing.T) {
|
||||
zone, _ := getZone(ZoneCryptValdris)
|
||||
|
||||
p := &AdventurePlugin{}
|
||||
granted := p.rollZoneLoot(uid, run, zone)
|
||||
granted := p.rollZoneLoot(uid, run, zone, true)
|
||||
// Crypt of Valdris has UniqueAlways "valdris_phylactery_shard" + always-drop coins.
|
||||
foundShard := false
|
||||
foundCoins := false
|
||||
|
||||
Reference in New Issue
Block a user