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

+11 -3
View File
@@ -8,6 +8,8 @@ this file inside the companion mod: mod/src/main/resources/assets/cobblesurvival
pokemon every species of a line that lives on the island: its drops (as the Drop Synthesizer rolls them)
and the zones it spawns in, or the zones where its line lives
(legendaries: where a Sigil summons them, world/summons.json; that line's evolutions too)
summons each Sigil: species, name, zone, level, so JEI can list it as an item of its own
spawn_drops zone spawns that drop something else than their species (e.g. Beheeyem in the End)
guardians each zone guardian: species, level, drops, return time
end_boss the End boss and what beating it gives
@@ -104,15 +106,21 @@ def main():
for zid, levels in zs.items():
line_zones[root_of(sid, species)].setdefault(zid, sid)
table = json.loads((ROOT / "world/summons.json").read_text())
summoned = {f"cobblemon:{k}": {"zone": v["zone"], "level": table["tiers"][str(v["tier"])]["level"]} for k, v in table["summons"].items()}
summons = [{"species": sid, "name": species[sid]["name"], **s} for sid, s in summoned.items()]
pokemon = []
for sid, s in sorted(species.items()):
drops = drop_entries(s["drops"])
root = root_of(sid, species)
if not drops or not s["implemented"] or not (where.get(sid) or line_zones.get(root)):
if not drops or not s["implemented"] or not (where.get(sid) or line_zones.get(root) or root in summoned):
continue
entry = {"species": sid, "drops": drops,
"zones": [{"zone": z, "levels": f"{lo}-{hi}"} for z, (lo, hi) in sorted(where.get(sid, {}).items())]}
if not entry["zones"]:
if root in summoned:
entry["summon"] = summoned[root]
elif not entry["zones"]:
entry["line"] = [{"zone": z, "species": member} for z, member in sorted(line_zones[root].items())]
pokemon.append(entry)
@@ -159,7 +167,7 @@ def main():
"mod's JEI plugin (jei/DropSourcesJei.kt); checked against the live server by the self-test "
"drop_sources_match_the_server.",
"zones": {zid: {"name": z["name"], "levels": z["levels"]} for zid, z in zones.items()},
"pokemon": pokemon, "spawn_drops": spawn_drops, "guardians": guardians, "end_boss": end_boss,
"pokemon": pokemon, "summons": summons, "spawn_drops": spawn_drops, "guardians": guardians, "end_boss": end_boss,
"altar": {"tiers": altar["tiers"], "specials": altar.get("specials", [])}, "rebirth": rebirth.get("extra", []),
"ore_veins": [{"zone": z, "items": items} for z, items in sorted(ore_veins.items())],
"pasture_finds": pasture_finds,