Skip to content

Commit f8d5c83

Browse files
DayKevfabske0emdeann
authored
Hotfix 1.11.20 to Main
* chore!: update version to `1.11.20` * fix(battle): defeating the last 2 enemies simultaneously won't crash #7325 * github: find correct PR in changelog script (#7327) find correct PR * fix(ui): Update level display on cap phase (#7328) * Update level display on cap phase * Update level display in updateinfo * Remove ratio recalculation for exp duration * Update full exp display for playerpokemon --------- Co-authored-by: Fabi <192151969+fabske0@users.noreply.github.com> Co-authored-by: Dean <69436131+emdeann@users.noreply.github.com>
1 parent b6f4b95 commit f8d5c83

8 files changed

Lines changed: 49 additions & 26 deletions

File tree

.github/scripts/changelog-reader/main.mts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ async function getPullRequests(commits: Set<string>): Promise<PullRequest[]> {
115115
repo: CONFIG.REPO_NAME,
116116
commit_sha: sha,
117117
});
118-
const pr = prs.data.at(-1);
119-
if (!pr || !pr.merged_at) {
118+
const pr = prs.data.find(p => p.merged_at != null && p.base.ref === CONFIG.REPO_BRANCH);
119+
if (!pr) {
120120
continue;
121121
}
122122
const section = getChangelogSection(pr.body || "");

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "pokemon-rogue-battle",
33
"private": true,
4-
"version": "1.11.19",
4+
"version": "1.11.20",
55
"type": "module",
66
"scripts": {
77
"start:prod": "vite --mode production",

src/field/pokemon.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ import { BiomeId } from "#enums/biome-id";
8888
import { ChallengeType } from "#enums/challenge-type";
8989
import { Challenges } from "#enums/challenges";
9090
import { DexAttr } from "#enums/dex-attr";
91+
import { ExpGainsSpeed } from "#enums/exp-gains-speed";
9192
import { FieldPosition } from "#enums/field-position";
9293
import { HitResult } from "#enums/hit-result";
9394
import { LearnMoveSituation } from "#enums/learn-move-situation";
@@ -6438,7 +6439,7 @@ export class PlayerPokemon extends Pokemon {
64386439
* @param lastLevel - The level of this Pokemon before the EXP increase
64396440
*/
64406441
public async showExpGain(lastLevel: number): Promise<void> {
6441-
await this.battleInfo.updatePokemonExpDisplay(this, lastLevel);
6442+
await this.battleInfo.updatePokemonExpDisplay(this, lastLevel, globalScene.expGainsSpeed === ExpGainsSpeed.SKIP);
64426443
await this.updateInfo();
64436444
}
64446445

src/phases/level-up-phase.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
3333
const prevStats = this.pokemon.stats.slice(0);
3434

3535
this.pokemon.calculateStats();
36-
this.pokemon.getBattleInfo().setLevelDisplay(this.pokemon.level);
3736
this.pokemon.updateInfo();
3837

3938
switch (globalScene.expParty) {

src/phases/victory-phase.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@ import { PokemonPhase } from "#phases/pokemon-phase";
99

1010
export class VictoryPhase extends PokemonPhase {
1111
public readonly phaseName = "VictoryPhase";
12+
1213
/** If true, indicates that the phase is intended for EXP purposes only, and not to continue a battle to next phase */
13-
isExpOnly: boolean;
14+
private readonly isExpOnly: boolean;
1415

1516
constructor(battlerIndex: BattlerIndex | number, isExpOnly = false) {
1617
super(battlerIndex);
1718

1819
this.isExpOnly = isExpOnly;
1920
}
2021

21-
start() {
22+
public override start(): void {
2223
super.start();
2324

2425
const isMysteryEncounter = globalScene.currentBattle.isBattleMysteryEncounter();
@@ -33,13 +34,16 @@ export class VictoryPhase extends PokemonPhase {
3334

3435
if (isMysteryEncounter) {
3536
handleMysteryEncounterVictory(false, this.isExpOnly);
36-
return this.end();
37+
this.end();
38+
return;
3739
}
3840

41+
// TODO: clean this up a bit - this shouldn't use `.find`; invert conditional and use early return
3942
if (
4043
!globalScene
4144
.getEnemyParty()
4245
.find(p => (globalScene.currentBattle.battleType === BattleType.WILD ? p.isOnField() : !p?.isFainted()))
46+
&& !globalScene.phaseManager.hasPhaseOfType("TrainerVictoryPhase") // temporary hotfix
4347
) {
4448
globalScene.phaseManager.pushNew("BattleEndPhase", true);
4549
if (globalScene.currentBattle.battleType === BattleType.TRAINER) {

src/ui/battle-info/battle-info.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ export abstract class BattleInfo extends Phaser.GameObjects.Container {
5757
protected lastHp: number;
5858
protected lastMaxHp: number;
5959
protected lastHpFrame: string | null;
60-
protected lastLevelCapped: boolean;
6160
protected lastStats: string;
6261

6362
protected box: Phaser.GameObjects.Sprite;

src/ui/battle-info/player-battle-info.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ export class PlayerBattleInfo extends BattleInfo {
141141
* @param lastLevel - The level the Pokemon was at before the update
142142
* @param lastLevelExp - The relative EXP the Pokemon had within its level before the update
143143
*/
144-
public async updatePokemonExpDisplay(pokemon: PlayerPokemon, lastLevel: number): Promise<void> {
145-
if (globalScene.expGainsSpeed === ExpGainsSpeed.SKIP) {
144+
public async updatePokemonExpDisplay(pokemon: PlayerPokemon, lastLevel: number, skip: boolean): Promise<void> {
145+
if (skip) {
146146
this.setLevelDisplay(pokemon.level);
147147
const relLevelExp = getLevelRelExp(pokemon.level + 1, pokemon.species.growthRate);
148148
this.expMaskRect.x = EXP_BAR_WIDTH * (relLevelExp === 0 ? 0 : pokemon.levelExp / relLevelExp);
@@ -156,6 +156,11 @@ export class PlayerBattleInfo extends BattleInfo {
156156
await this.doUpdateExpAnimation(pokemon, pokemon.level, false);
157157
}
158158

159+
public override async updateInfo(pokemon: PlayerPokemon, instant?: boolean): Promise<void> {
160+
await super.updateInfo(pokemon, instant);
161+
this.updatePokemonExpDisplay(pokemon, pokemon.level, true);
162+
}
163+
159164
/**
160165
* Calculate the duration multiplier for the EXP bar animation based on the current and final levels.
161166
* The smaller the difference, the greater the multiplier (i.e. the longer the animation).
@@ -195,10 +200,7 @@ export class PlayerBattleInfo extends BattleInfo {
195200

196201
const levelDurationMultiplier = this.getLevelDurationMultiplier(lastLevel, pokemon.level);
197202
let duration = this.visible
198-
? ((nextWidth - this.expMaskRect.x) / EXP_BAR_WIDTH)
199-
* BattleInfo.EXP_GAINS_DURATION_BASE
200-
* durationMultiplier
201-
* levelDurationMultiplier
203+
? ratio * BattleInfo.EXP_GAINS_DURATION_BASE * durationMultiplier * levelDurationMultiplier
202204
: 0;
203205
if (speed && speed >= ExpGainsSpeed.DEFAULT) {
204206
duration = speed >= ExpGainsSpeed.SKIP ? ExpGainsSpeed.DEFAULT : duration / Math.pow(2, speed);
@@ -224,7 +226,7 @@ export class PlayerBattleInfo extends BattleInfo {
224226
this.setLevelDisplay(level);
225227
globalScene.time.delayedCall(500 * levelDurationMultiplier, () => {
226228
this.expMaskRect.x = 0;
227-
this.updateInfo(pokemon).then(() => resolve());
229+
resolve();
228230
});
229231
return;
230232
}

test/tests/battle/double-battle.test.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { getGameMode } from "#app/game-mode";
22
import { Status } from "#data/status-effect";
33
import { AbilityId } from "#enums/ability-id";
4+
import { BattleType } from "#enums/battle-type";
45
import { GameModes } from "#enums/game-modes";
56
import { MoveId } from "#enums/move-id";
67
import { SpeciesId } from "#enums/species-id";
78
import { StatusEffect } from "#enums/status-effect";
9+
import { TrainerType } from "#enums/trainer-type";
10+
import { TrainerVariant } from "#enums/trainer-variant";
811
import { GameManager } from "#test/framework/game-manager";
912
import Phaser from "phaser";
1013
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
@@ -23,16 +26,20 @@ describe("Double Battles", () => {
2326

2427
beforeEach(() => {
2528
game = new GameManager(phaserGame);
29+
game.override //
30+
.enemyAbility(AbilityId.BALL_FETCH)
31+
.enemyMoveset(MoveId.SPLASH)
32+
.ability(AbilityId.BALL_FETCH);
2633
});
2734

2835
// double-battle player's pokemon both fainted in same round, then revive one, and next double battle summons two player's pokemon successfully.
2936
// (There were bugs that either only summon one when can summon two, player stuck in switchPhase etc)
3037
it("3v2 edge case: player summons 2 pokemon on the next battle after being fainted and revived", async () => {
31-
game.override.battleStyle("double").enemyMoveset(MoveId.SPLASH).moveset(MoveId.SPLASH);
38+
game.override.battleStyle("double");
3239
await game.classicMode.startBattle(SpeciesId.BULBASAUR, SpeciesId.CHARIZARD, SpeciesId.SQUIRTLE);
3340

34-
game.move.select(MoveId.SPLASH);
35-
game.move.select(MoveId.SPLASH, 1);
41+
game.move.use(MoveId.SPLASH);
42+
game.move.use(MoveId.SPLASH, 1);
3643

3744
for (const pokemon of game.scene.getPlayerField()) {
3845
pokemon.hp = 0;
@@ -61,20 +68,14 @@ describe("Double Battles", () => {
6168
return rngSweepProgress * (max - min) + min;
6269
});
6370

64-
game.override
65-
.enemyMoveset(MoveId.SPLASH)
66-
.moveset(MoveId.SPLASH)
67-
.enemyAbility(AbilityId.BALL_FETCH)
68-
.ability(AbilityId.BALL_FETCH);
69-
7071
// Play through endless, waves 1 to 9, counting number of double battles from waves 2 to 9
7172
await game.classicMode.startBattle(SpeciesId.BULBASAUR);
7273
game.scene.gameMode = getGameMode(GameModes.ENDLESS);
7374

7475
for (let i = 0; i < DOUBLE_CHANCE; i++) {
7576
rngSweepProgress = (i + 0.5) / DOUBLE_CHANCE;
7677

77-
game.move.select(MoveId.SPLASH);
78+
game.move.use(MoveId.SPLASH);
7879
await game.doKillOpponents();
7980
await game.toNextWave();
8081

@@ -88,4 +89,21 @@ describe("Double Battles", () => {
8889
expect(doubleCount).toBe(1);
8990
expect(singleCount).toBe(DOUBLE_CHANCE - 1);
9091
});
92+
93+
it("won't queue multiple `BattleEndPhase`s/etc if the last 2 enemy Pokemon are defeated simultaneously in a trainer battle", async () => {
94+
game.override //
95+
.battleType(BattleType.TRAINER)
96+
.randomTrainer({ trainerType: TrainerType.YOUNGSTER, trainerVariant: TrainerVariant.DOUBLE })
97+
.startingLevel(200);
98+
99+
await game.classicMode.startBattle(SpeciesId.FEEBAS);
100+
101+
expect(game.field.getEnemyParty()).toHaveLength(2);
102+
expect(game.scene.getEnemyField()).toHaveLength(2);
103+
104+
game.move.use(MoveId.SURF);
105+
await game.toEndOfTurn(false);
106+
107+
expect(game.scene.phaseManager["phaseQueue"].findAll("BattleEndPhase")).toHaveLength(1);
108+
});
91109
});

0 commit comments

Comments
 (0)