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:
1 parent
e206664b3d
commit
f7ea371862
92 files changed
+4081
-21
No files matched your search
+18
-4
@@ -230,6 +230,15 @@ def chapter_quests(chapter, book, zones):
|
||||
for t in q.get("tasks", []):
|
||||
tasks += [{**t, "item": o, "each": None} for o in fields["ores"]] if t.get("each") == "ores" else [t]
|
||||
q["tasks"] = [{k: v for k, v in t.items() if k != "each"} for t in tasks]
|
||||
# One quest per Sigil: craft it, use it, catch what comes (world/summons.json; names from the JEI data).
|
||||
if chapter.get("summons"):
|
||||
sigils = json.loads((ROOT / "mod/src/main/resources/assets/cobblesurvival/jei/drop_sources.json").read_text())["summons"]
|
||||
for s in sigils:
|
||||
quests.append({
|
||||
"id": s["species"].split(":")[1], "title": s["name"], "icon": "cobblesurvival:summon_sigil", "after": ["about"],
|
||||
"text": f"Craft the {s['name']} Sigil and use it in {zones[s['zone']]['name']}. Catch the Lv {s['level']} {s['name']} that answers.",
|
||||
"tasks": [{"cobblemon": "catch", "pokemon": [s["species"]]}],
|
||||
})
|
||||
# "Catch Pokémon of a zone": its spawn pool's species (Cobblemon Quests' own biome filter knows no zones).
|
||||
for q in quests:
|
||||
for t in q.get("tasks", []):
|
||||
@@ -264,8 +273,9 @@ def task_nbt(task, name, events):
|
||||
raise ValueError(f"{name}: unknown task {task}")
|
||||
|
||||
|
||||
def auto_layout(quests, chapter_id):
|
||||
"""Left to right by dependency depth inside the chapter, stacked within a column."""
|
||||
def auto_layout(quests, chapter_id, grid=None):
|
||||
"""Left to right by dependency depth inside the chapter, stacked within a column; with `grid` columns, what depends
|
||||
on something goes into a grid to the right instead of one tall column."""
|
||||
local = {q["id"] for q in quests}
|
||||
depth = {}
|
||||
|
||||
@@ -279,6 +289,10 @@ def auto_layout(quests, chapter_id):
|
||||
for q in quests:
|
||||
columns.setdefault(d(q), []).append(q["id"])
|
||||
pos = {}
|
||||
if grid:
|
||||
for i, qid in enumerate(q["id"] for q in quests if depth[q["id"]] > 0):
|
||||
pos[f"{chapter_id}/{qid}"] = [2.0 + (i % grid) * 1.5, (i // grid) * 1.5]
|
||||
columns = {c: ids for c, ids in columns.items() if c == 0}
|
||||
for col, ids in columns.items():
|
||||
for row, qid in enumerate(ids):
|
||||
pos[f"{chapter_id}/{qid}"] = [col * 2.0, (row - (len(ids) - 1) / 2) * 1.5]
|
||||
@@ -296,7 +310,7 @@ def build(book):
|
||||
for index, chapter in enumerate(book["chapters"]):
|
||||
cid = chapter["id"]
|
||||
quests = expanded[cid]
|
||||
auto = auto_layout(quests, cid)
|
||||
auto = auto_layout(quests, cid, chapter.get("columns"))
|
||||
chapter_id = object_id(f"chapter:{cid}")
|
||||
lang[f"chapter.{chapter_id}.title"] = chapter["title"]
|
||||
if chapter.get("subtitle"):
|
||||
@@ -369,7 +383,7 @@ def pull(book, folder):
|
||||
auto, by_id = {}, {}
|
||||
for c in book["chapters"]:
|
||||
quests = chapter_quests(c, book, zones)
|
||||
auto |= auto_layout(quests, c["id"])
|
||||
auto |= auto_layout(quests, c["id"], c.get("columns"))
|
||||
by_id |= {object_id(f"quest:{c['id']}/{q['id']}"): f"{c['id']}/{q['id']}" for q in quests}
|
||||
layout = dict(book.get("layout") or {})
|
||||
for path in sorted((folder / "chapters").glob("*.snbt")):
|
||||
|
||||
Reference in new issue
Block a user