This commit is contained in:
1 parent
6a74f59e46
commit
3e92936cb9
20 files changed
+1417
-32
No files matched your search
@@ -154,7 +154,12 @@ export type ScriptEffect =
|
||||
selected: number;
|
||||
}
|
||||
/** startbattle: answered with wBattleResult. */
|
||||
| { kind: "battle"; wild: { species: number; level: number } }
|
||||
| {
|
||||
kind: "battle";
|
||||
wild?: { species: number; level: number };
|
||||
trainer?: { classId: number; id: number; winText?: number; lossText?: number };
|
||||
canLose?: boolean;
|
||||
}
|
||||
/** newloadmap: the world enters this map after the script ends. */
|
||||
| { kind: "warp"; map: string; x: number; y: number };
|
||||
|
||||
@@ -266,6 +271,10 @@ export class ScriptRun {
|
||||
value = 0,
|
||||
battleResult = 0,
|
||||
spawn = 0;
|
||||
let wild = this.options.wild;
|
||||
let trainer: { classId: number; id: number } | undefined;
|
||||
let winText: number | undefined, lossText: number | undefined;
|
||||
let canLose = false;
|
||||
// One array for the whole run: specials append to and clear it in place.
|
||||
const pages: string[] = [];
|
||||
const byte = () => r.byte(p++);
|
||||
@@ -463,18 +472,49 @@ export class ScriptRun {
|
||||
p = SYMBOLS.fruitTreeScript;
|
||||
break;
|
||||
}
|
||||
case 0x1e: {
|
||||
// Only VAR_BATTLETYPE's normal and CANLOSE modes are translated.
|
||||
const variable = byte(), setting = byte();
|
||||
if (variable !== 3 || (setting !== 0 && setting !== 1))
|
||||
throw new UnsupportedScript(offset, opcode, " (battle type or variable)");
|
||||
canLose = setting === 1;
|
||||
break;
|
||||
}
|
||||
case 0x5b:
|
||||
trainer = undefined;
|
||||
wild = this.options.wild;
|
||||
break; // randomwildmon clears wBattleScriptFlags.
|
||||
case 0x5d:
|
||||
wild = { species: byte(), level: byte() };
|
||||
trainer = undefined;
|
||||
break;
|
||||
case 0x5e:
|
||||
trainer = { classId: byte(), id: byte() };
|
||||
wild = undefined;
|
||||
break;
|
||||
case 0x64: {
|
||||
// Null pointers request the battle engine's default end text.
|
||||
const bank = r.bank(p), won = word(), lost = word();
|
||||
winText = won ? r.address(bank, won) : undefined;
|
||||
lossText = lost ? r.address(bank, lost) : undefined;
|
||||
break;
|
||||
}
|
||||
case 0x5f: {
|
||||
if (!this.options.wild) throw new UnsupportedScript(offset, opcode, " (trainer battle)");
|
||||
const result = yield synchronous({ kind: "battle", wild: this.options.wild });
|
||||
if (!wild && !trainer) throw new UnsupportedScript(offset, opcode, " (no opponent)");
|
||||
yield* flush();
|
||||
const result = yield synchronous({
|
||||
kind: "battle", wild,
|
||||
trainer: trainer && { ...trainer, winText, lossText }, canLose,
|
||||
});
|
||||
if (typeof result !== "number") throw new Error("Invalid battle result.");
|
||||
battleResult = result;
|
||||
value = result & 0x3f; // Script_startbattle also updates wScriptVar.
|
||||
break;
|
||||
}
|
||||
case 0x60:
|
||||
// Script_reloadmapafterbattle: a loss continues with the whiteout.
|
||||
if ((battleResult & 0x3f) === 1) p = SYMBOLS.battleWhiteoutScript;
|
||||
canLose = false;
|
||||
break;
|
||||
case 0x8a: {
|
||||
byte(); // newloadmap MAPSETUP_WARP
|
||||
|
||||
@@ -71,6 +71,7 @@ const CHARACTERS: Record<number, string> = {
|
||||
export interface TextContext {
|
||||
player: string;
|
||||
rival: string;
|
||||
trainer?: string;
|
||||
mom: string;
|
||||
/** Native strings stored at the RAM addresses named by text_ram. */
|
||||
strings: Readonly<Record<number, string>>;
|
||||
@@ -126,6 +127,7 @@ function character(code: number, context: TextContext): string | undefined {
|
||||
if (code === 0x5a) return battler(context, context.battle?.turn === 1);
|
||||
if (code === 0x52 || code === 0x14) return context.player;
|
||||
if (code === 0x53) return context.rival;
|
||||
if (code === 0x3f) return context.trainer;
|
||||
if (code === 0x49) return context.mom;
|
||||
if (code >= 0x80 && code <= 0x99)
|
||||
return String.fromCharCode(65 + code - 0x80);
|
||||
|
||||
Reference in new issue
Block a user