Match the original's choice layouts: vertical YES/NO and lists, full PC menu [no-card]
YES/NO and battle lists are single columns moved with Up/Down, the battle menu cursor follows the 2x2 grid, and the dialogue menu shows every entry. Not pushed yet: awaiting manual testing (#64, #65). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ce8129703f
commit
5546e575f4
3 files changed
+79
-7
No files matched your search
+56
-3
@@ -143,6 +143,7 @@ function showChoice(choice: Choice | undefined) {
|
||||
const key = choice ? JSON.stringify(choice) : "";
|
||||
if (container.dataset.choice === key) return;
|
||||
container.dataset.choice = key;
|
||||
container.dataset.kind = choice?.kind ?? "";
|
||||
const button = (
|
||||
label: string,
|
||||
pressed: boolean | undefined,
|
||||
@@ -294,6 +295,10 @@ function showChoice(choice: Choice | undefined) {
|
||||
list,
|
||||
button("CANCEL", undefined, () => runtime.choose(-1)),
|
||||
);
|
||||
// On a small screen the box scrolls; keep the highlighted entry in view.
|
||||
list
|
||||
.querySelector('[aria-selected="true"]')
|
||||
?.scrollIntoView({ block: "nearest" });
|
||||
}
|
||||
}
|
||||
/** The naming screen as a text field and OK: an empty name keeps the
|
||||
@@ -627,6 +632,42 @@ function battleButtons() {
|
||||
),
|
||||
];
|
||||
}
|
||||
/** The enabled button next to `from` in the arrow's direction as drawn, so
|
||||
* the cursor always follows the layout: a column moves with up and down, a
|
||||
* row with left and right, and a grid with all four. */
|
||||
function adjacentButton(
|
||||
buttons: HTMLButtonElement[],
|
||||
from: number,
|
||||
arrow: "up" | "down" | "left" | "right",
|
||||
): number | undefined {
|
||||
const origin = buttons[from]?.getBoundingClientRect();
|
||||
if (!origin) return undefined;
|
||||
const vertical = arrow === "up" || arrow === "down";
|
||||
let best: number | undefined;
|
||||
let bestScore = Infinity;
|
||||
buttons.forEach((candidate, index) => {
|
||||
if (index === from) return;
|
||||
const box = candidate.getBoundingClientRect();
|
||||
const gap =
|
||||
arrow === "up"
|
||||
? origin.top - box.bottom
|
||||
: arrow === "down"
|
||||
? box.top - origin.bottom
|
||||
: arrow === "left"
|
||||
? origin.left - box.right
|
||||
: box.left - origin.right;
|
||||
if (gap < -1) return;
|
||||
const offset = vertical
|
||||
? Math.abs(box.left + box.width / 2 - (origin.left + origin.width / 2))
|
||||
: Math.abs(box.top + box.height / 2 - (origin.top + origin.height / 2));
|
||||
const score = Math.max(gap, 0) + offset * 2;
|
||||
if (score < bestScore) {
|
||||
bestScore = score;
|
||||
best = index;
|
||||
}
|
||||
});
|
||||
return best;
|
||||
}
|
||||
function highlightBattleChoice() {
|
||||
battleButtons().forEach((button, index) => {
|
||||
button.classList.toggle("battle-selected", index === battleCursor);
|
||||
@@ -664,9 +705,14 @@ function handleBattleInput(button: Button): boolean {
|
||||
buttons[battleCursor]?.click();
|
||||
return true;
|
||||
}
|
||||
if (["up", "down", "left", "right"].includes(button)) {
|
||||
const delta = button === "up" || button === "left" ? -1 : 1;
|
||||
battleCursor = (battleCursor + delta + buttons.length) % buttons.length;
|
||||
if (
|
||||
button === "up" ||
|
||||
button === "down" ||
|
||||
button === "left" ||
|
||||
button === "right"
|
||||
) {
|
||||
battleCursor =
|
||||
adjacentButton(buttons, battleCursor, button) ?? battleCursor;
|
||||
if (yesNoPrompt(world.battle.prompt))
|
||||
world.battle.selected = battleCursor === 0 ? 1 : 0;
|
||||
highlightBattleChoice();
|
||||
@@ -1012,6 +1058,13 @@ function showBattle(world: GameWorld) {
|
||||
button("Continue ▶", () => runtime.advanceDialogue(), { wide: true }),
|
||||
);
|
||||
}
|
||||
// FIGHT/PKMN/PACK/RUN is the original's 2x2 grid; every other choice is a
|
||||
// vertical list, moved with Up and Down as it is drawn.
|
||||
const grid =
|
||||
(prompt?.kind === "action" && !showMoves && !showPack) ||
|
||||
prompt?.kind === "stats";
|
||||
menu.dataset.layout = grid ? "grid" : "list";
|
||||
menu.dataset.kind = prompt?.kind ?? "";
|
||||
menu.replaceChildren(...buttons);
|
||||
battleCursor = Math.min(
|
||||
battleCursor,
|
||||
|
||||
Reference in new issue
Block a user