From 459fb95fbd08903fda1cfc8d603f97438dd9f8d9 Mon Sep 17 00:00:00 2001 From: Laeticia PIERRE Date: Wed, 8 May 2024 22:39:49 +0200 Subject: [PATCH 1/9] Clean imports --- src/battle-scene.ts | 13 ++++--------- src/battle.ts | 1 - src/phases.ts | 6 +++--- src/system/voucher.ts | 1 - src/ui/egg-gacha-ui-handler.ts | 2 +- 5 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index f117615e5..0f4700653 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1,8 +1,8 @@ import Phaser from 'phaser'; -import UI, { Mode } from './ui/ui'; +import UI from './ui/ui'; import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, MovePhase, TitlePhase, SwitchPhase } from './phases'; import Pokemon, { PlayerPokemon, EnemyPokemon } from './field/pokemon'; -import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies, speciesStarters } from './data/pokemon-species'; +import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies } from './data/pokemon-species'; import * as Utils from './utils'; import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier } from './modifier/modifier'; import { PokeballType } from './data/pokeball'; @@ -12,7 +12,6 @@ import { initGameSpeed } from './system/game-speed'; import { Biome } from "./data/enums/biome"; import { Arena, ArenaBase } from './field/arena'; import { GameData, PlayerGender } from './system/game-data'; -import StarterSelectUiHandler from './ui/starter-select-ui-handler'; import { TextStyle, addTextObject } from './ui/text'; import { Moves } from "./data/enums/moves"; import { allMoves } from "./data/move"; @@ -20,7 +19,6 @@ import { initMoves } from './data/move'; import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getPartyLuckValue } from './modifier/modifier-type'; import AbilityBar from './ui/ability-bar'; import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, IncrementMovePriorityAbAttr, applyAbAttrs, initAbilities } from './data/ability'; -import { Abilities } from "./data/enums/abilities"; import { allAbilities } from "./data/ability"; import Battle, { BattleType, FixedBattleConfig, fixedBattles } from './battle'; import { GameMode, GameModes, gameModes } from './game-mode'; @@ -33,9 +31,6 @@ import TrainerData from './system/trainer-data'; import SoundFade from 'phaser3-rex-plugins/plugins/soundfade'; import { pokemonPrevolutions } from './data/pokemon-evolutions'; import PokeballTray from './ui/pokeball-tray'; -import { Setting, settingOptions } from './system/settings'; -import SettingsUiHandler from './ui/settings-ui-handler'; -import MessageUiHandler from './ui/message-ui-handler'; import { Species } from './data/enums/species'; import InvertPostFX from './pipelines/invert'; import { Achv, ModifierAchv, MoneyAchv, achvs } from './system/achv'; @@ -60,8 +55,8 @@ import CandyBar from './ui/candy-bar'; import { Variant, variantData } from './data/variant'; import { Localizable } from './plugins/i18n'; import { STARTING_WAVE_OVERRIDE, OPP_SPECIES_OVERRIDE, SEED_OVERRIDE, STARTING_BIOME_OVERRIDE, DOUBLE_BATTLE_OVERRIDE } from './overrides'; -import {InputsController} from "./inputs-controller"; -import {UiInputs} from "./ui-inputs"; +import { InputsController } from "./inputs-controller"; +import { UiInputs } from "./ui-inputs"; export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1"; diff --git a/src/battle.ts b/src/battle.ts index 580bad9a5..01611ba6d 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -10,7 +10,6 @@ import { GameMode } from "./game-mode"; import { BattleSpec } from "./enums/battle-spec"; import { PlayerGender } from "./system/game-data"; import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier"; -import { MoneyAchv } from "./system/achv"; export enum BattleType { WILD, diff --git a/src/phases.ts b/src/phases.ts index e5d67de28..7d0c15841 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -1,8 +1,8 @@ -import BattleScene, { AnySound, bypassLogin, startingWave } from "./battle-scene"; +import BattleScene, { bypassLogin, startingWave } from "./battle-scene"; import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon"; import * as Utils from './utils'; import { Moves } from "./data/enums/moves"; -import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, FixedDamageAttr, PostVictoryStatChangeAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr } from "./data/move"; +import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, FixedDamageAttr, PostVictoryStatChangeAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr } from "./data/move"; import { Mode } from './ui/ui'; import { Command } from "./ui/command-ui-handler"; import { Stat } from "./data/pokemon-stat"; @@ -55,7 +55,7 @@ import { OptionSelectConfig, OptionSelectItem } from "./ui/abstact-option-select import { SaveSlotUiMode } from "./ui/save-slot-select-ui-handler"; import { fetchDailyRunSeed, getDailyRunStarters } from "./data/daily-run"; import { GameModes, gameModes } from "./game-mode"; -import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./data/pokemon-species"; +import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "./data/pokemon-species"; import i18next from './plugins/i18n'; import { Abilities } from "./data/enums/abilities"; import { STARTER_FORM_OVERRIDE, STARTER_SPECIES_OVERRIDE } from './overrides'; diff --git a/src/system/voucher.ts b/src/system/voucher.ts index 276e74eeb..e29e4b6d9 100644 --- a/src/system/voucher.ts +++ b/src/system/voucher.ts @@ -1,6 +1,5 @@ import BattleScene from "../battle-scene"; import { TrainerType } from "../data/enums/trainer-type"; -import { ModifierTier } from "../modifier/modifier-tier"; import { Achv, AchvTier, achvs } from "./achv"; export enum VoucherType { diff --git a/src/ui/egg-gacha-ui-handler.ts b/src/ui/egg-gacha-ui-handler.ts index 315dfdbd3..4695bc03c 100644 --- a/src/ui/egg-gacha-ui-handler.ts +++ b/src/ui/egg-gacha-ui-handler.ts @@ -9,7 +9,7 @@ import { getPokemonSpecies } from "../data/pokemon-species"; import { addWindow } from "./ui-theme"; import { Tutorial, handleTutorial } from "../tutorial"; import { EggTier } from "../data/enums/egg-type"; -import {Button} from "../enums/buttons"; +import { Button } from "../enums/buttons"; const defaultText = 'Select a machine.'; From 3d9b0253ef0117b2cde0a33fd090b3dccfb0ed2f Mon Sep 17 00:00:00 2001 From: Laeticia PIERRE Date: Wed, 8 May 2024 22:40:35 +0200 Subject: [PATCH 2/9] Rework and test getTitle --- src/data/trainer-config.test.ts | 69 +++++++++++++++++++++++++++++++++ src/data/trainer-config.ts | 18 ++++----- 2 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 src/data/trainer-config.test.ts diff --git a/src/data/trainer-config.test.ts b/src/data/trainer-config.test.ts new file mode 100644 index 000000000..dcacbbc72 --- /dev/null +++ b/src/data/trainer-config.test.ts @@ -0,0 +1,69 @@ +import { expect, describe, it, beforeAll, vi, afterAll, beforeEach } from "vitest"; +import { TrainerConfig, TrainerSlot } from "./trainer-config"; +import { TrainerType } from "./enums/trainer-type"; +import { TrainerVariant } from "#app/field/trainer.js"; + +describe("trainer-config", () => { + describe("getTitle", () => { + let trainerConfig: TrainerConfig; + + beforeAll(() => { + // Error when importing biomes / voucher (imported by different files) + vi.mock('./biomes', () => ({ + biomeLinks: {}, + BiomePoolTier: {}, + PokemonPools: {}, + getBiomeName: () => "", + BiomeTierTrainerPools: {}, + biomePokemonPools: {}, + biomeTrainerPools: {}, + })); + vi.mock('../system/voucher', () => ({ + vouchers: {}, + VoucherType: {}, + getVoucherTypeIcon: () => "", + Voucher: {}, + getVoucherTypeName: () => "", + })); + }); + + afterAll(() => { + vi.clearAllMocks(); + }); + + beforeEach(() => { + trainerConfig = new TrainerConfig(TrainerType.ARTIST, false); + }); + + it("returns the name double when trainer variant double", () => { + trainerConfig.nameDouble = "Lae & Ticia"; + expect(trainerConfig.getTitle(TrainerSlot.NONE, TrainerVariant.DOUBLE)).toBe("Lae & Ticia"); + }); + + it("returns the trainer type name when no gender selected", () => { + expect(trainerConfig.getTitle(TrainerSlot.NONE, TrainerVariant.DEFAULT)).toBe("Artist"); + }); + + it("returns the female name when gender is female", () => { + trainerConfig.nameFemale = "Laeticia"; + trainerConfig.hasGenders = true; + expect(trainerConfig.getTitle(TrainerSlot.NONE, TrainerVariant.FEMALE)).toBe("Laeticia"); + }); + + it("returns the female name when trainer variant double and trainer partner", () => { + trainerConfig.nameFemale = "Laeticia"; + trainerConfig.hasGenders = true; + expect(trainerConfig.getTitle(TrainerSlot.TRAINER_PARTNER, TrainerVariant.DOUBLE)).toBe("Laeticia"); + }); + + it("returns the trainer type name with the female gender", () => { + trainerConfig.hasGenders = true; + expect(trainerConfig.getTitle(TrainerSlot.NONE, TrainerVariant.FEMALE)).toBe("Artist♀"); + }); + + it("returns the trainer type name with the male gender", () => { + trainerConfig.hasGenders = true; + expect(trainerConfig.getTitle(TrainerSlot.NONE, TrainerVariant.DEFAULT)).toBe("Artist♂"); + }); + }); +}); diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 36d76edcf..cd3e78a0d 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -429,20 +429,16 @@ export class TrainerConfig { } getTitle(trainerSlot: TrainerSlot = TrainerSlot.NONE, variant: TrainerVariant): string { - let ret = this.name; - - if (!trainerSlot && variant === TrainerVariant.DOUBLE && this.nameDouble) + if (trainerSlot === TrainerSlot.NONE && variant === TrainerVariant.DOUBLE && this.nameDouble) return this.nameDouble; - if (this.hasGenders) { - if (this.nameFemale) { - if (variant === TrainerVariant.FEMALE || (variant === TrainerVariant.DOUBLE && trainerSlot === TrainerSlot.TRAINER_PARTNER)) - return this.nameFemale; - } else - ret += !variant ? '♂' : '♀'; - } + if (!this.hasGenders) + return this.name; - return ret; + if (this.nameFemale && (variant === TrainerVariant.FEMALE || (variant === TrainerVariant.DOUBLE && trainerSlot === TrainerSlot.TRAINER_PARTNER))) + return this.nameFemale; + + return `${this.name}${variant === TrainerVariant.DEFAULT ? '♂' : '♀'}`; } loadAssets(scene: BattleScene, variant: TrainerVariant): Promise { From 29914de5f6d4b074cf384583edaccead2b6f21b7 Mon Sep 17 00:00:00 2001 From: Laeticia PIERRE Date: Wed, 8 May 2024 22:41:00 +0200 Subject: [PATCH 3/9] Rework and test getDataTypeKey --- src/system/game-data.test.ts | 50 ++++++++++++++++++++++++++++++++++++ src/system/game-data.ts | 5 +--- 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/system/game-data.test.ts diff --git a/src/system/game-data.test.ts b/src/system/game-data.test.ts new file mode 100644 index 000000000..867da7fd4 --- /dev/null +++ b/src/system/game-data.test.ts @@ -0,0 +1,50 @@ +import { expect, describe, it, beforeAll, vi, afterAll } from "vitest"; +import { GameDataType, getDataTypeKey } from "./game-data"; + +describe("game-data", () => { + describe("getDataTypeKey", () => { + beforeAll(() => { + // Error when importing biomes (imported by different files) + vi.mock('../data/biomes', () => ({ + biomeLinks: {}, + BiomePoolTier: {}, + PokemonPools: {}, + getBiomeName: () => "", + BiomeTierTrainerPools: {}, + biomePokemonPools: {}, + biomeTrainerPools: {}, + })); + }); + + afterAll(() => { + vi.clearAllMocks(); + }); + + it("returns sessionData for session data type", () => { + expect(getDataTypeKey(GameDataType.SESSION)).toBe("sessionData"); + expect(getDataTypeKey(GameDataType.SESSION, 0)).toBe("sessionData"); + }); + + it("returns sessionData with the slot id given for session data type", () => { + expect(getDataTypeKey(GameDataType.SESSION, 1)).toBe("sessionData1"); + }); + + it("returns data for system data type", () => { + expect(getDataTypeKey(GameDataType.SYSTEM)).toBe("data"); + expect(getDataTypeKey(GameDataType.SYSTEM, 0)).toBe("data"); + expect(getDataTypeKey(GameDataType.SYSTEM, 1)).toBe("data"); + }); + + it("returns settings for settings data type", () => { + expect(getDataTypeKey(GameDataType.SETTINGS)).toBe("settings"); + expect(getDataTypeKey(GameDataType.SETTINGS, 0)).toBe("settings"); + expect(getDataTypeKey(GameDataType.SETTINGS, 1)).toBe("settings"); + }); + + it("returns tutorials for tutorials data type", () => { + expect(getDataTypeKey(GameDataType.TUTORIALS)).toBe("tutorials"); + expect(getDataTypeKey(GameDataType.TUTORIALS, 0)).toBe("tutorials"); + expect(getDataTypeKey(GameDataType.TUTORIALS, 1)).toBe("tutorials"); + }); + }); +}); diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 60fe7ac8e..8db9baf5f 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -55,10 +55,7 @@ export function getDataTypeKey(dataType: GameDataType, slotId: integer = 0): str case GameDataType.SYSTEM: return 'data'; case GameDataType.SESSION: - let ret = 'sessionData'; - if (slotId) - ret += slotId; - return ret; + return `sessionData${slotId ? slotId : ''}`; case GameDataType.SETTINGS: return 'settings'; case GameDataType.TUTORIALS: From 1bf975569187071f91c9f11e04d1d3f151877219 Mon Sep 17 00:00:00 2001 From: Laeticia PIERRE Date: Wed, 8 May 2024 22:41:49 +0200 Subject: [PATCH 4/9] Rework and test getPokemonPrefix --- src/messages.test.ts | 81 ++++++++++++++++++++++++++++++++++++++++++++ src/messages.ts | 12 +++---- 2 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 src/messages.test.ts diff --git a/src/messages.test.ts b/src/messages.test.ts new file mode 100644 index 000000000..b5a3b71b2 --- /dev/null +++ b/src/messages.test.ts @@ -0,0 +1,81 @@ +import { expect, describe, it } from "vitest"; +import Pokemon from "./field/pokemon"; +import { getPokemonMessage, getPokemonPrefix } from "./messages"; +import { BattleSpec } from "./enums/battle-spec"; + +describe("messages", () => { + describe("getPokemonPrefix", () => { + it("returns an empty prefix if the pokemon is a pokemon of the player", () => { + const pokemon = { + isPlayer: () => true, + hasTrainer: () => false, + scene: { + currentBattle: { + battleSpec: BattleSpec.DEFAULT + } + } + } as Pokemon; + + expect(getPokemonPrefix(pokemon)).toBe(''); + }); + + it("returns the wild prefix if the pokemon does not have a trainer", () => { + const pokemon = { + isPlayer: () => false, + hasTrainer: () => false, + scene: { + currentBattle: { + battleSpec: BattleSpec.DEFAULT + } + } + } as Pokemon; + + expect(getPokemonPrefix(pokemon)).toBe('Wild '); + }); + + it("returns the foe prefix if the pokemon has a trainer which is not the player", () => { + const pokemon = { + isPlayer: () => false, + hasTrainer: () => true, + scene: { + currentBattle: { + battleSpec: BattleSpec.DEFAULT + } + } + } as Pokemon; + + expect(getPokemonPrefix(pokemon)).toBe('Foe '); + }); + + it("returns the foe prefix if the pokemon is the final boss", () => { + const pokemon = { + isPlayer: () => false, + hasTrainer: () => false, + scene: { + currentBattle: { + battleSpec: BattleSpec.FINAL_BOSS + } + } + } as Pokemon; + + expect(getPokemonPrefix(pokemon)).toBe('Foe '); + }); + }); + + describe("getPokemonMessage", () => { + it("returns a message with pokemon prefix, pokemon name and content given", () => { + const pokemon = { + name: "Gengar", + isPlayer: () => false, + hasTrainer: () => true, + scene: { + currentBattle: { + battleSpec: BattleSpec.DEFAULT + } + } + } as Pokemon; + + expect(getPokemonMessage(pokemon, " is hurt\nby poison!")).toBe('Foe Gengar is hurt\nby poison!'); + }); + }); +}); diff --git a/src/messages.ts b/src/messages.ts index ffd9aa6ef..c5be0b175 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -6,14 +6,12 @@ export function getPokemonMessage(pokemon: Pokemon, content: string): string { } export function getPokemonPrefix(pokemon: Pokemon): string { - let prefix: string; + if (pokemon.isPlayer()) return ''; + switch (pokemon.scene.currentBattle.battleSpec) { case BattleSpec.DEFAULT: - prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? 'Foe ' : 'Wild ' : ''; - break; + return pokemon.hasTrainer() ? 'Foe ' : 'Wild '; case BattleSpec.FINAL_BOSS: - prefix = !pokemon.isPlayer() ? 'Foe ' : ''; - break; + return 'Foe '; } - return prefix; -} \ No newline at end of file +} From aebca1c424400f686c28892942f9635cdf1eb677 Mon Sep 17 00:00:00 2001 From: Laeticia PIERRE Date: Wed, 8 May 2024 22:43:51 +0200 Subject: [PATCH 5/9] Add underscore prefix on unused args --- src/battle.ts | 2 +- src/inputs-controller.ts | 4 ++-- src/system/game-data.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index 01611ba6d..0ee525012 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -130,7 +130,7 @@ export default class Battle { return this.double ? 2 : 1; } - incrementTurn(scene: BattleScene): void { + incrementTurn(_scene: BattleScene): void { this.turn++; this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ])); this.battleSeedState = null; diff --git a/src/inputs-controller.ts b/src/inputs-controller.ts index 5f5615358..323b0db89 100644 --- a/src/inputs-controller.ts +++ b/src/inputs-controller.ts @@ -142,7 +142,7 @@ export class InputsController { return gamepadMapping; } - gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void { + gamepadButtonDown(_pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, _value: number): void { if (!this.scene.gamepadSupport) return; const actionMapping = this.getActionGamepadMapping(); const buttonDown = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index]; @@ -155,7 +155,7 @@ export class InputsController { } } - gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void { + gamepadButtonUp(_pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, _value: number): void { if (!this.scene.gamepadSupport) return; const actionMapping = this.getActionGamepadMapping(); const buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index]; diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 8db9baf5f..374e5b49e 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1189,7 +1189,7 @@ export class GameData { return ret; } - getSpeciesDexAttrProps(species: PokemonSpecies, dexAttr: bigint): DexAttrProps { + getSpeciesDexAttrProps(_species: PokemonSpecies, dexAttr: bigint): DexAttrProps { const shiny = !(dexAttr & DexAttr.NON_SHINY); const female = !(dexAttr & DexAttr.MALE); const variant = dexAttr & DexAttr.DEFAULT_VARIANT ? 0 : dexAttr & DexAttr.VARIANT_2 ? 1 : dexAttr & DexAttr.VARIANT_3 ? 2 : 0; From df5c5a376c95bb1ca7167db5e2724203e7f9c63b Mon Sep 17 00:00:00 2001 From: Laeticia PIERRE Date: Wed, 8 May 2024 22:47:15 +0200 Subject: [PATCH 6/9] Small changes --- src/battle.ts | 4 +--- src/form-change-phase.ts | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/battle.ts b/src/battle.ts index 0ee525012..3959d8bf4 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -217,7 +217,6 @@ export default class Battle { randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer { if (range <= 1) return min; - let ret: integer; const tempRngCounter = scene.rngCounter; const tempSeedOverride = scene.rngSeedOverride; const state = Phaser.Math.RND.state(); @@ -229,12 +228,11 @@ export default class Battle { } scene.rngCounter = this.rngCounter++; scene.rngSeedOverride = this.battleSeed; - ret = Utils.randSeedInt(range, min); this.battleSeedState = Phaser.Math.RND.state(); Phaser.Math.RND.state(state); scene.rngCounter = tempRngCounter; scene.rngSeedOverride = tempSeedOverride; - return ret; + return Utils.randSeedInt(range, min); } } diff --git a/src/form-change-phase.ts b/src/form-change-phase.ts index db325bd3d..bbdedf998 100644 --- a/src/form-change-phase.ts +++ b/src/form-change-phase.ts @@ -27,9 +27,7 @@ export class FormChangePhase extends EvolutionPhase { } setMode(): Promise { - if (!this.modal) - return super.setMode(); - return this.scene.ui.setOverlayMode(Mode.EVOLUTION_SCENE); + return this.modal ? this.scene.ui.setOverlayMode(Mode.EVOLUTION_SCENE) : super.setMode(); } doEvolution(): void { From 609893d44e48c599169dff21fbac4f9900a56c4d Mon Sep 17 00:00:00 2001 From: Laeticia PIERRE Date: Thu, 9 May 2024 10:52:28 +0200 Subject: [PATCH 7/9] Rework and test initBattleSpec + getLevelForWave --- src/battle.test.ts | 157 +++++++++++++++++++++++++++++++++++++++++++++ src/battle.ts | 29 ++++----- 2 files changed, 169 insertions(+), 17 deletions(-) create mode 100644 src/battle.test.ts diff --git a/src/battle.test.ts b/src/battle.test.ts new file mode 100644 index 000000000..a5affeb4e --- /dev/null +++ b/src/battle.test.ts @@ -0,0 +1,157 @@ +import { expect, describe, it, beforeAll, vi, afterAll } from "vitest"; +import Battle, { BattleType } from "./battle"; +import { GameMode } from "./game-mode"; +import Trainer from "./field/trainer"; +import { BattleSpec } from "./enums/battle-spec"; +import BattleScene from "./battle-scene"; +import { TrainerType } from "./data/enums/trainer-type"; + +const NUM_TEST_RUNS = 10; + +describe("battle", () => { + beforeAll(() => { + // Prevent errors + vi.mock('./data/biomes', () => ({})); + vi.mock('./form-change-phase', () => ({})); + vi.mock('./data/move', () => ({ + initMoves: () => {}, + })); + vi.mock("./field/trainer", () => ({ + default: vi.fn().mockImplementation(() => ({ + getPartyLevels: (_waveIndex: integer) => [1] + })), + })); + vi.mock("./data/pokemon-forms", () => ({})); + vi.mock("./data/pokemon-evolutions", () => ({})); + }); + + afterAll(() => { + vi.clearAllMocks(); + }); + + // private method but calls in constructor and updates battleSpec + describe("initBattleSpec", () => { + const trainer = new Trainer(new BattleScene(), TrainerType.ARTIST, 0); // 0 = TrainerVariant.DEFAULT + + it("has final boss as battleSpec when wave 200 and classic mode", () => { + const battle = new Battle(new GameMode(1, { isClassic: true }), 200, BattleType.TRAINER, trainer, false); + + expect(battle.battleSpec).toBe(BattleSpec.FINAL_BOSS); + }); + + it("has default as battleSpec when not wave 200 and classic mode", () => { + const battle = new Battle(new GameMode(1, { isClassic: true }), 190, BattleType.TRAINER, trainer, false); + + expect(battle.battleSpec).toBe(BattleSpec.DEFAULT); + }); + + it("has default as battleSpec when not classic mode", () => { + const battle = new Battle(new GameMode(1, { isClassic: false }), 190, BattleType.TRAINER, trainer, false); + const battle2 = new Battle(new GameMode(1, { isClassic: false }), 200, BattleType.TRAINER, trainer, false); + + expect(battle.battleSpec).toBe(BattleSpec.DEFAULT); + expect(battle2.battleSpec).toBe(BattleSpec.DEFAULT); + }); + }); + + // private method but calls in constructor and updates enemyLevels for battleType !== BattleType.TRAINER + describe("getLevelForWave", () => { + const trainer = new Trainer(new BattleScene(), TrainerType.ARTIST, 0); // 0 = TrainerVariant.DEFAULT + + it("has 2 or 3 as enemyLevels when first wave and single battle", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 1, BattleType.WILD, trainer, false); + + expect(battle.enemyLevels.length).toBe(1); + expect([2, 3]).toContain(battle.enemyLevels[0]); + } + }); + + it("has 2 or 3 x2 as enemyLevels when first wave and double battle", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 1, BattleType.WILD, trainer, true); + + expect(battle.enemyLevels.length).toBe(2); + expect(battle.enemyLevels.every(level => [2, 3].includes(level))).toBeTruthy(); + } + }); + + it("has 164<=x<=184 as enemyLevels when 199th wave and single battle", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 199, BattleType.WILD, trainer, false); + + expect(battle.enemyLevels.length).toBe(1); + expect(battle.enemyLevels[0] >= 164 && battle.enemyLevels[0] <= 184).toBeTruthy(); + } + }); + + it("has 164<=x<=184 x2 as enemyLevels when 199th wave and double battle", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 199, BattleType.WILD, trainer, true); + + expect(battle.enemyLevels.length).toBe(2); + expect(battle.enemyLevels.every(level => level >= 164 && level <= 184)).toBeTruthy(); + } + }); + + it("has 6<=x<=8 as enemyLevels when 10th wave and single battle", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 10, BattleType.WILD, trainer, false); + + expect(battle.enemyLevels.length).toBe(1); + expect(battle.enemyLevels[0] >= 6 && battle.enemyLevels[0] <= 8).toBeTruthy(); + } + }); + + it("has 6<=x<=8 x2 as enemyLevels when 10th wave and double battle", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 10, BattleType.WILD, trainer, true); + + expect(battle.enemyLevels.length).toBe(2); + expect(battle.enemyLevels.every(level => level >= 6 && level <= 8)).toBeTruthy(); + } + }); + + it("has 165<=x<=203 as enemyLevels when 190th wave and single battle", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 190, BattleType.WILD, trainer, false); + + expect(battle.enemyLevels.length).toBe(1); + expect(battle.enemyLevels[0] >= 165 && battle.enemyLevels[0] <= 203).toBeTruthy(); + } + }); + + it("has 165<=x<=203 x2 as enemyLevels when 190th wave and double battle", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 190, BattleType.WILD, trainer, true); + + expect(battle.enemyLevels.length).toBe(2); + expect(battle.enemyLevels.every(level => level >= 165 && level <= 203)).toBeTruthy(); + } + }); + + it("has 200 as enemyLevels when 200th wave, final boss", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 200, BattleType.WILD, trainer, false); + + expect(battle.enemyLevels).toStrictEqual([200]); + } + }); + + it("has 275 as enemyLevels when 250th wave", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 250, BattleType.WILD, trainer, false); + + expect(battle.enemyLevels).toStrictEqual([275]); + } + }); + + it("has 800 as enemyLevels when 500th wave", () => { + for (let i = 0; i < NUM_TEST_RUNS; i++) { + const battle = new Battle(new GameMode(1, { isClassic: true }), 500, BattleType.WILD, trainer, false); + + expect(battle.enemyLevels).toStrictEqual([800]); + } + }); + }); +}); diff --git a/src/battle.ts b/src/battle.ts index 3959d8bf4..d47e17bc4 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -88,33 +88,28 @@ export default class Battle { } private initBattleSpec(): void { - let spec = BattleSpec.DEFAULT; - if (this.gameMode.isClassic) { - if (this.waveIndex === 200) - spec = BattleSpec.FINAL_BOSS; - } - this.battleSpec = spec; + this.battleSpec = this.gameMode.isClassic && this.waveIndex === 200 + ? BattleSpec.FINAL_BOSS + : BattleSpec.DEFAULT; } private getLevelForWave(): integer { - let levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex); - let baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2); + const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex); + const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2); const bossMultiplier = 1.2; if (!(this.waveIndex % 10)) { - const ret = Math.floor(baseLevel * bossMultiplier); + const levelForWave = Math.floor(baseLevel * bossMultiplier); if (this.battleSpec === BattleSpec.FINAL_BOSS || !(this.waveIndex % 250)) - return Math.ceil(ret / 25) * 25; - let levelOffset = 0; - if (!this.gameMode.isWaveFinal(this.waveIndex)) - levelOffset = Math.round(Phaser.Math.RND.realInRange(-1, 1) * Math.floor(levelWaveIndex / 10)); - return ret + levelOffset; + return Math.ceil(levelForWave / 25) * 25; + const levelOffset = !this.gameMode.isWaveFinal(this.waveIndex) + ? Math.round(Phaser.Math.RND.realInRange(-1, 1) * Math.floor(levelWaveIndex / 10)) + : 0; + return levelForWave + levelOffset; } - let levelOffset = 0; - const deviation = 10 / levelWaveIndex; - levelOffset = Math.abs(this.randSeedGaussForLevel(deviation)); + const levelOffset = Math.abs(this.randSeedGaussForLevel(deviation)); return Math.max(Math.round(baseLevel + levelOffset), 1); } From b9d1500375a631ebf4c1cc336b57a8c366d25824 Mon Sep 17 00:00:00 2001 From: Laeticia PIERRE Date: Thu, 9 May 2024 11:08:16 +0200 Subject: [PATCH 8/9] Add default and remove new line --- src/messages.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/messages.ts b/src/messages.ts index c5be0b175..acb042385 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -13,5 +13,7 @@ export function getPokemonPrefix(pokemon: Pokemon): string { return pokemon.hasTrainer() ? 'Foe ' : 'Wild '; case BattleSpec.FINAL_BOSS: return 'Foe '; + default: + return ''; } -} +} \ No newline at end of file From 8706b816aead16c76552378bbb3f642a24965a1c Mon Sep 17 00:00:00 2001 From: Laeticia PIERRE Date: Thu, 9 May 2024 11:16:25 +0200 Subject: [PATCH 9/9] Clean mocks --- src/data/trainer-config.test.ts | 16 +++------------- src/system/game-data.test.ts | 12 ++---------- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/src/data/trainer-config.test.ts b/src/data/trainer-config.test.ts index dcacbbc72..7e18374d1 100644 --- a/src/data/trainer-config.test.ts +++ b/src/data/trainer-config.test.ts @@ -8,22 +8,12 @@ describe("trainer-config", () => { let trainerConfig: TrainerConfig; beforeAll(() => { - // Error when importing biomes / voucher (imported by different files) - vi.mock('./biomes', () => ({ - biomeLinks: {}, - BiomePoolTier: {}, - PokemonPools: {}, - getBiomeName: () => "", - BiomeTierTrainerPools: {}, - biomePokemonPools: {}, - biomeTrainerPools: {}, - })); + // Prevent errors + vi.mock('./biomes', () => ({})); vi.mock('../system/voucher', () => ({ - vouchers: {}, VoucherType: {}, - getVoucherTypeIcon: () => "", - Voucher: {}, getVoucherTypeName: () => "", + getVoucherTypeIcon: () => "", })); }); diff --git a/src/system/game-data.test.ts b/src/system/game-data.test.ts index 867da7fd4..c6a3c8745 100644 --- a/src/system/game-data.test.ts +++ b/src/system/game-data.test.ts @@ -4,16 +4,8 @@ import { GameDataType, getDataTypeKey } from "./game-data"; describe("game-data", () => { describe("getDataTypeKey", () => { beforeAll(() => { - // Error when importing biomes (imported by different files) - vi.mock('../data/biomes', () => ({ - biomeLinks: {}, - BiomePoolTier: {}, - PokemonPools: {}, - getBiomeName: () => "", - BiomeTierTrainerPools: {}, - biomePokemonPools: {}, - biomeTrainerPools: {}, - })); + // Prevent errors + vi.mock('../data/biomes', () => ({})); }); afterAll(() => {