Integrate battles with the overworld UI and validate browser flows
Checks / web (push) Canceled after 0s
Checks / web (push) Canceled after 0s
- Drive wild battles through the real UI in Chromium and WebKit using a test-only encounter fixture: victory with level-up, escape, whiteout, mid-battle backup restore and unsupported-effect rollback. - Add keyboard and on-screen D-pad navigation for battle menus. - Accept pending stat experience in saves (awarded without CalcMonStats). - Commit whiteout healing, money loss and destination callbacks together; aborted scripts restore state and map. - Give long notices their own status-bar row on narrow screens. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c08d250cf6
commit
11d1153802
11 files changed
+462
-13
No files matched your search
+22
-6
@@ -143,7 +143,13 @@ interface ActiveScript {
|
||||
effect?: ScriptEffect;
|
||||
/** Committed save data for the whole interaction, used for mid-script saves. */
|
||||
committed: NativeSave;
|
||||
rollback: { player: Actor; actors: Map<number, Actor>; spawned: Set<number> };
|
||||
rollback: {
|
||||
player: Actor;
|
||||
actors: Map<number, Actor>;
|
||||
spawned: Set<number>;
|
||||
state: ScriptState;
|
||||
mapId: string;
|
||||
};
|
||||
waitTicks: number;
|
||||
moving: Map<number, { steps: MovementStep[]; index: number; wait: number }>;
|
||||
follow?: { leader: number; follower: number };
|
||||
@@ -644,9 +650,13 @@ export class GameWorld {
|
||||
|
||||
/** Evaluate map callbacks on a copy, so an unsupported callback leaves the
|
||||
* current map untouched. Methods follow the original map setup scripts. */
|
||||
private prepareMap(id: string, method: "warp" | "connection" | "continue") {
|
||||
private prepareMap(
|
||||
id: string,
|
||||
method: "warp" | "connection" | "continue",
|
||||
sourceState = this.state,
|
||||
) {
|
||||
const map = this.assets.map(id);
|
||||
const state = copyScriptState(this.state);
|
||||
const state = copyScriptState(sourceState);
|
||||
const actors = new Map<number, Actor>();
|
||||
if (method !== "continue")
|
||||
for (let event = 0; event < 8; event++) state.events.delete(event);
|
||||
@@ -779,6 +789,8 @@ export class GameWorld {
|
||||
),
|
||||
committed,
|
||||
rollback: {
|
||||
state: this.state,
|
||||
mapId: this.mapId,
|
||||
player: copyActor(this.player),
|
||||
actors: new Map(
|
||||
[...this.actors].map(([id, actor]) => [id, copyActor(actor)]),
|
||||
@@ -1045,10 +1057,12 @@ export class GameWorld {
|
||||
|
||||
private finishScript() {
|
||||
const script = this.script!;
|
||||
this.state = script.run.state;
|
||||
if (script.warp) {
|
||||
const { map, x, y } = script.warp;
|
||||
const entry = this.prepareMap(map, "warp");
|
||||
if (!this.assets.isPorted(map) || !this.walkable(this.assets.map(map), x, y))
|
||||
throw new Error("Script warp destination is not supported.");
|
||||
// Whiteout healing/money and destination callbacks commit together.
|
||||
const entry = this.prepareMap(map, "warp", script.run.state);
|
||||
this.player = {
|
||||
...this.player,
|
||||
x,
|
||||
@@ -1057,7 +1071,7 @@ export class GameWorld {
|
||||
motion: undefined,
|
||||
};
|
||||
this.applyMap(entry);
|
||||
}
|
||||
} else this.state = script.run.state;
|
||||
this.script = undefined;
|
||||
this.dialogue = undefined;
|
||||
this.emote = undefined;
|
||||
@@ -1071,6 +1085,8 @@ export class GameWorld {
|
||||
const script = this.script!;
|
||||
this.battle = undefined;
|
||||
this.battleRun = undefined;
|
||||
this.state = script.rollback.state;
|
||||
this.mapId = script.rollback.mapId;
|
||||
this.player = script.rollback.player;
|
||||
this.actors = script.rollback.actors;
|
||||
this.spawned = script.rollback.spawned;
|
||||
|
||||
Reference in new issue
Block a user