Port the remaining battle items, the stats screen and hBattleTurn at the menu
- Run every non-ball item effect usable in battle from the ROM's ItemEffects: Full Restore, revives, bitter medicine, Bitter Berry, Ethers and Elixers, X items, X Accuracy, Guard Spec, Dire Hit and Poké Doll. - Read happiness changes from HappinessChanges, including the larger level-up gain where a Pokémon was caught. - Model hBattleTurn at the battle menu, including the trainer AI's writes, and drop the status-heal refusal. - Port the stats screen for battles and Bill's PC. - Compare the send-out and withdraw texts, RestoreHealth, RestorePP, ChangeHappiness and CalcPlayerStats with the original routines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cfd083c16d
commit
b13e09ec20
22 files changed
+1547
-171
No files matched your search
@@ -94,6 +94,7 @@ describe("trainer AI native scoring", () => {
|
||||
move: 2,
|
||||
index: 1,
|
||||
scores: [20, 20, 80, 80],
|
||||
enemyTurn: false,
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -124,8 +125,34 @@ describe("trainer AI native scoring", () => {
|
||||
move: 2,
|
||||
index: 1,
|
||||
scores: [20, 20, 80, 80],
|
||||
enemyTurn: false,
|
||||
});
|
||||
});
|
||||
it("reports when AI_Types, AI_Status or AIDamageCalc set hBattleTurn", () => {
|
||||
const run = (
|
||||
weights: number,
|
||||
moves = [move(1), move(2)],
|
||||
playerTypes = [0, 0],
|
||||
) => {
|
||||
const input = fixture(moves, [0, 1, 2, 3, 0, 1, 2, 3]);
|
||||
input.weights = weights;
|
||||
input.player.mon.types = playerTypes;
|
||||
input.damage = () => 0;
|
||||
return chooseTrainerMove(input).enemyTurn;
|
||||
};
|
||||
expect(run(0)).toBe(false);
|
||||
expect(run(4)).toBe(true); // Types
|
||||
expect(run(64)).toBe(true); // Aggressive's damage estimates
|
||||
expect(run(256)).toBe(true); // Status, for damaging moves
|
||||
// A poison move against a Poison type skips the matchup and the write;
|
||||
// a status move with no power checks nothing.
|
||||
const poison = [
|
||||
move(1, C.EFFECT_POISON, 0),
|
||||
move(2, C.EFFECT_ATTACK_UP, 0),
|
||||
];
|
||||
expect(run(256, poison, [C.POISON, C.POISON])).toBe(false);
|
||||
expect(run(256, poison)).toBe(true);
|
||||
});
|
||||
it("refuses a random source that never produces a candidate", () => {
|
||||
const input = fixture();
|
||||
input.random = () => 3;
|
||||
@@ -140,6 +167,7 @@ describe("trainer AI native scoring", () => {
|
||||
move: 3,
|
||||
index: 2,
|
||||
scores: [80, 80, 20, 80],
|
||||
enemyTurn: false,
|
||||
});
|
||||
});
|
||||
it("still scores exhausted moves and consumes randomness before Struggle", () => {
|
||||
@@ -153,6 +181,7 @@ describe("trainer AI native scoring", () => {
|
||||
move: 1,
|
||||
index: 0,
|
||||
scores: [78, 80, 80, 80],
|
||||
enemyTurn: false,
|
||||
});
|
||||
});
|
||||
it("still selects when the only move is disabled", () => {
|
||||
@@ -163,6 +192,7 @@ describe("trainer AI native scoring", () => {
|
||||
move: 1,
|
||||
index: 0,
|
||||
scores: [80, 20, 80, 80],
|
||||
enemyTurn: false,
|
||||
});
|
||||
});
|
||||
it("refuses empty move lists instead of the cartridge's infinite loop", () => {
|
||||
|
||||
Reference in new issue
Block a user