Port the PC and boxes
Checks / web (push) Canceled after 0s

Read TileCollisionStdScripts from the ROM so the Pokémon Center PC runs
PokemonCenterPC: Bill's PC (deposit, withdraw, release, change and name
boxes), the player's item storage (withdraw, deposit, toss, mail box) and
Oak's Pokédex rating. The house PC now opens the full player's PC menu.

A catch with a full party goes to the current box through SendMonIntoBox;
a full box keeps the ball, and filling it queues Bill's call as a memory
script after the battle. Saves gain boxes, box names and PC items,
migrated by absence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sébastien QUEROLandClaude Opus 5.5 committed 2026-09-25 17:12:26 +02:00
1 parent 451464f7c6
commit 3bdca0099e
21 files changed
+1999 -131

No files matched your search

+23 -8
View File
@@ -148,8 +148,14 @@ function showChoice(choice: Choice | undefined) {
const option = button(item, choice.selected === index, () =>
runtime.choose(index),
);
const detail = choice.details?.[index];
if (detail) {
const small = document.createElement("small");
small.textContent = detail;
option.append(small);
}
option.setAttribute("role", "option");
option.setAttribute("aria-label", item);
option.setAttribute("aria-label", detail ? `${item} ${detail}` : item);
option.setAttribute("aria-selected", String(choice.selected === index));
return option;
}),
@@ -218,6 +224,11 @@ function showMart(world: GameWorld, mart: MartChoice | undefined) {
martMenuKey = "";
return;
}
// The PC's item storage reuses these lists without prices.
const shop =
mart.kind === "martmenu" || mart.mode === "buy" || mart.mode === "sell";
get("mart").setAttribute("aria-label", shop ? "Poké Mart" : "Item storage");
get("mart-money").hidden = !shop;
get("mart-money").textContent = `MONEY ¥${world.liveState.money}`;
get("mart-prompt").textContent = mart.kind === "martlist" ? "" : mart.prompt;
const key = JSON.stringify(mart);
@@ -260,7 +271,11 @@ function showMart(world: GameWorld, mart: MartChoice | undefined) {
const buttons = mart.entries.map((entry, index) =>
button(entry.name, () => runtime.choose(index), {
detail:
mart.mode === "sell" ? `have ${entry.owned}` : `¥${entry.price}`,
mart.mode === "sell"
? `have ${entry.owned}`
: mart.mode === "buy"
? `¥${entry.price}`
: `×${entry.owned}`,
selected: mart.selected === index,
}),
);
@@ -290,7 +305,9 @@ function showMart(world: GameWorld, mart: MartChoice | undefined) {
return element;
};
const output = document.createElement("output");
output.textContent = `${mart.name} ×${mart.selected} ¥${total}`;
output.textContent = shop
? `${mart.name} ×${mart.selected} ¥${total}`
: `${mart.name} ×${mart.selected}`;
stepper.append(
step("◀◀", "Minus 10", "left"),
step("▼", "Minus 1", "down"),
@@ -300,11 +317,9 @@ function showMart(world: GameWorld, mart: MartChoice | undefined) {
);
menu.replaceChildren(
stepper,
button(
mart.mode === "sell" ? "SELL" : "BUY",
() => runtime.choose(mart.selected),
{ wide: true },
),
button(mart.mode.toUpperCase(), () => runtime.choose(mart.selected), {
wide: true,
}),
button("CANCEL", () => runtime.choose(-1), { wide: true }),
);
}