Merge 8706b816ae into 1d7d8b1ac7
commit
92d3435b34
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -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,
|
||||
|
|
@ -89,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);
|
||||
}
|
||||
|
|
@ -131,7 +125,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;
|
||||
|
|
@ -218,7 +212,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();
|
||||
|
|
@ -230,12 +223,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
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(() => {
|
||||
// Prevent errors
|
||||
vi.mock('./biomes', () => ({}));
|
||||
vi.mock('../system/voucher', () => ({
|
||||
VoucherType: {},
|
||||
getVoucherTypeName: () => "",
|
||||
getVoucherTypeIcon: () => "",
|
||||
}));
|
||||
});
|
||||
|
||||
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♂");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -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<void> {
|
||||
|
|
|
|||
|
|
@ -27,9 +27,7 @@ export class FormChangePhase extends EvolutionPhase {
|
|||
}
|
||||
|
||||
setMode(): Promise<void> {
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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!');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -6,14 +6,14 @@ 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 ';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
import { expect, describe, it, beforeAll, vi, afterAll } from "vitest";
|
||||
import { GameDataType, getDataTypeKey } from "./game-data";
|
||||
|
||||
describe("game-data", () => {
|
||||
describe("getDataTypeKey", () => {
|
||||
beforeAll(() => {
|
||||
// Prevent errors
|
||||
vi.mock('../data/biomes', () => ({}));
|
||||
});
|
||||
|
||||
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");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -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:
|
||||
|
|
@ -1192,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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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.';
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue