new rpg mode

This commit is contained in:
Warren H
2026-07-17 12:47:42 -04:00
parent de7b59ce77
commit 10ff124466
180 changed files with 20863 additions and 1014 deletions
+45 -2
View File
@@ -3,6 +3,8 @@ import { subscribeControllerToken } from "../input/controller";
import { ABILITY_ORDER } from "./data";
import { isRunBuffInputLocked, useGameStore } from "./store";
import { ABILITY_BY_CONTROLLER_BUTTON } from "./controllerBindings";
import { cycleBottomTab } from "./bottomTabs";
import { resolveRpgFocusCommand } from "./rpgRoguelike/uiModel";
function cycleRunBuff(direction: 1 | -1) {
const store = useGameStore.getState();
@@ -12,6 +14,21 @@ function cycleRunBuff(direction: 1 | -1) {
store.setSelectedRunBuff(store.draftBuffIds[nextIndex]);
}
function rpgInputIsGated() {
const run = useGameStore.getState().rpgRun;
return Boolean(run && run.phase !== "challenge-active" && run.phase !== "boss-combat");
}
function activateRpgFocus(onExit?: () => void) {
const store = useGameStore.getState();
if (!store.rpgRun) return;
const command = resolveRpgFocusCommand(store.rpgRun, store.rpgFocusId);
if (!command) return;
if (command.type === "run-action") store.dispatchRpgAction(command.action);
else if (command.type === "restart-run") store.restart();
else onExit?.();
}
export function useActionBindings(enabled = true, onExit?: () => void) {
const exitRef = useRef(onExit);
exitRef.current = onExit;
@@ -32,6 +49,16 @@ export function useActionBindings(enabled = true, onExit?: () => void) {
}
return;
}
if (store.runMode === "rpg-roguelike" && store.rpgRun && rpgInputIsGated()) {
if (["arrowleft", "arrowup", "arrowright", "arrowdown", "enter", "escape"].includes(key)) event.preventDefault();
if (key === "arrowleft") store.moveRpgFocus("left");
if (key === "arrowright") store.moveRpgFocus("right");
if (key === "arrowup") store.moveRpgFocus("up");
if (key === "arrowdown") store.moveRpgFocus("down");
if (key === "enter") activateRpgFocus(exitRef.current);
if (key === "escape") exitRef.current?.();
return;
}
if (store.phase === "intermission") {
if (["arrowleft", "arrowup", "arrowright", "arrowdown", "enter"].includes(key)) event.preventDefault();
if (isRunBuffInputLocked(store)) return;
@@ -71,7 +98,14 @@ export function useActionBindings(enabled = true, onExit?: () => void) {
store.setActiveTab(store.activeTab === "map" ? "combat" : "map");
break;
case "i":
store.setActiveTab(store.activeTab === "pack" ? "combat" : "pack");
if (store.runMode !== "hockey-healing-pvp") {
store.setActiveTab(store.activeTab === "pack" ? "combat" : "pack");
}
break;
case "p":
if (store.runMode === "hockey-healing-pvp") {
store.setActiveTab(store.activeTab === "pvp" ? "combat" : "pvp");
}
break;
case "enter":
if (store.phase === "briefing") store.startEncounter();
@@ -101,6 +135,15 @@ export function useActionBindings(enabled = true, onExit?: () => void) {
}
return;
}
if (store.runMode === "rpg-roguelike" && store.rpgRun && rpgInputIsGated()) {
if (token === "Button12" || token === "Axis1-") store.moveRpgFocus("up");
if (token === "Button13" || token === "Axis1+") store.moveRpgFocus("down");
if (token === "Button14" || token === "Axis0-") store.moveRpgFocus("left");
if (token === "Button15" || token === "Axis0+") store.moveRpgFocus("right");
if (!repeat && token === "Button0") activateRpgFocus(exitRef.current);
if (!repeat && token === "Button1") exitRef.current?.();
return;
}
if (store.phase === "intermission") {
if (isRunBuffInputLocked(store)) return;
if (["Button12", "Button14", "Axis0-", "Axis1-"].includes(token)) cycleRunBuff(-1);
@@ -129,7 +172,7 @@ export function useActionBindings(enabled = true, onExit?: () => void) {
}
if (token === "Button12") store.cycleMember(-1);
if (token === "Button13") store.cycleMember(1);
if (token === "Button8") store.setActiveTab(store.activeTab === "map" ? "combat" : "map");
if (token === "Button8") store.setActiveTab(cycleBottomTab(store.activeTab, store.runMode));
if (token === "Button9" || (token === "Button0" && store.phase !== "combat")) {
if (store.phase === "briefing") store.startEncounter();
else if (store.phase === "victory" || store.phase === "defeat") store.restart();