Phase 9: crafted summons for the legendaries

Adrian, 2026-11-09: legendaries, mythicals, Ultra Beasts and Paradox Pokemon
come from crafted summons. 22 Sigils (Naganadel evolves from Poipole), one
item told apart by custom data, from world/summons.json through
tools/summons.py: late-game recipes in three tiers (Lv 70, 80, 90), each used
in a fitting zone. A summoned legend fights as a boss (area attacks by level
and type, arena 32, the Guardian's Ward) but can be caught; on capture it
loses every boss mark. One at a time within 96 blocks.

Quest book: a Legends chapter, one quest per Sigil (97 quests). JEI lists each
Sigil as its own item, and Island Drops says where a legend is summoned; drops
Cobblemon names but doesn't have (Ho-Oh's Sacred Ash) get no slot.

Self-tests every_implemented_pokemon_is_obtainable (spawn, fossil or Sigil for
every implemented species) and sigil_summons_a_catchable_legend. Self-tests
and the island check pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-11-09 13:03:50 +01:00
1 parent e206664b3d
commit f7ea371862
92 files changed
+4081 -21

No files matched your search

+8
View File
@@ -26,6 +26,8 @@ END = {"species": "eternatus", "level": 80, "respawn_hours": 5, "xp_first_win":
# Adrian, 2026-11-02: Eternatus was too small (0.2x, about a block). Scaled to stand this many blocks tall.
END_HEIGHT = 15
END_ARENA = 40
# A summoned legendary's fight (world/summons.json; Adrian, 2026-11-09): catchable, same rules as a boss.
SUMMON_ARENA = 32
# Up to this level: these patterns.
TIERS = [
@@ -71,6 +73,7 @@ def species_data(jar):
if name.startswith("data/cobblemon/species/") and name.endswith(".json"):
d = json.loads(z.read(name))
types[d["name"].lower()] = {t for t in (d.get("primaryType"), d.get("secondaryType")) if t}
types[Path(name).stem] = types[d["name"].lower()]
heights[d["name"].lower()] = (d.get("hitbox") or {}).get("height", 1) * d.get("baseScale", 1)
return types, heights
@@ -94,6 +97,11 @@ def main():
end = boss(END["level"], types.get(END["species"], set()), END_ARENA, end=end_def)
(OUT / "end.json").write_text(json.dumps({"_comment": comment, **end}, indent=1) + "\n")
print(f"end: {END['species']} Lv {END['level']}, {len(end['patterns'])} patterns")
table = json.loads((ROOT / "world/summons.json").read_text())
for species, s in table["summons"].items():
fight = boss(table["tiers"][str(s["tier"])]["level"], types.get(species, set()), SUMMON_ARENA, summon=species)
(OUT / f"summon_{species}.json").write_text(json.dumps({"_comment": comment, **fight}, indent=1) + "\n")
print(f"{len(table['summons'])} summoned legendaries")
if __name__ == "__main__":