Add the Johto and Kanto atlas to the Map tab
The Map tab draws the region's Town Map from the ROM with the player's landmark, the visited flypoints as Fly destinations and the landmarks whose maps are ported. Kanto opens with the Fly map's Indigo Plateau rule. Landmark positions and flypoints are compared with the pinned PRET source. Closes #36 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cdee576818
commit
29248172bd
13 files changed
+536
-30
No files matched your search
+62
-1
@@ -1,4 +1,5 @@
|
||||
import { drawTownMap } from "./game/rendering/town-map";
|
||||
import { drawAtlas, drawTownMap } from "./game/rendering/town-map";
|
||||
import type { AtlasRegion } from "./game/world/atlas";
|
||||
import {
|
||||
drawCardPic,
|
||||
drawTrainerCardBadges,
|
||||
@@ -1127,6 +1128,64 @@ function showPokedexTab() {
|
||||
});
|
||||
}
|
||||
|
||||
let atlasKey = "";
|
||||
let atlasRegion: AtlasRegion | undefined;
|
||||
/** The Map tab's region atlas, from the loaded game's live state. */
|
||||
function showAtlas() {
|
||||
if (tabs.active() !== "map") return;
|
||||
const world = ready() ? runtime.world : undefined;
|
||||
const panel = get("atlas");
|
||||
panel.hidden = !world;
|
||||
if (!world) {
|
||||
atlasKey = "";
|
||||
return;
|
||||
}
|
||||
const view = world.atlas(atlasRegion);
|
||||
const key = JSON.stringify([view, world.avatar]);
|
||||
if (key === atlasKey) return;
|
||||
atlasKey = key;
|
||||
const names = { johto: "Johto", kanto: "Kanto" } as const;
|
||||
get("atlas-title").textContent = names[view.region];
|
||||
get("atlas-regions").replaceChildren(
|
||||
...(view.regions.length > 1 ? view.regions : []).map((region) => {
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.textContent = names[region];
|
||||
button.setAttribute("aria-pressed", String(region === view.region));
|
||||
button.addEventListener("click", () => {
|
||||
atlasRegion = region;
|
||||
showAtlas();
|
||||
});
|
||||
return button;
|
||||
}),
|
||||
);
|
||||
const canvas = get<HTMLCanvasElement>("atlas-map");
|
||||
drawAtlas(canvas, world, view);
|
||||
const here = view.landmarks.find((landmark) => landmark.landmark === view.player);
|
||||
canvas.setAttribute("aria-label", `${names[view.region]} map${here ? `, you are in ${here.name}` : ""}`);
|
||||
get("atlas-here").textContent = here
|
||||
? `You are in ${here.name}.`
|
||||
: `You are outside ${names[view.region]}.`;
|
||||
const items = (list: string[], empty: string) =>
|
||||
(list.length ? list : [empty]).map((text) => {
|
||||
const item = document.createElement("li");
|
||||
item.textContent = text;
|
||||
return item;
|
||||
});
|
||||
get("atlas-fly").replaceChildren(
|
||||
...items(
|
||||
view.landmarks.filter((landmark) => landmark.flypoint?.visited).map((landmark) => landmark.name),
|
||||
"None yet",
|
||||
),
|
||||
);
|
||||
get("atlas-open").replaceChildren(
|
||||
...items(
|
||||
view.landmarks.filter((landmark) => landmark.open).map((landmark) => landmark.name),
|
||||
"None",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
let optionsKey = "";
|
||||
/** _Option's screen: each option with its setting, and the ▶ cursor. */
|
||||
function showOptions(world: GameWorld) {
|
||||
@@ -1512,6 +1571,7 @@ const tabs = bindTabs(
|
||||
},
|
||||
(id) => {
|
||||
if (id === "pokedex") showPokedexTab();
|
||||
if (id === "map") showAtlas();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1554,6 +1614,7 @@ function update() {
|
||||
get<HTMLButtonElement>("dialogue-next").disabled =
|
||||
busy || session.state !== "playing";
|
||||
showPokedexTab();
|
||||
showAtlas();
|
||||
}
|
||||
|
||||
async function save() {
|
||||
|
||||
Reference in new issue
Block a user