mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-23 06:53:27 +02:00
Revert use of typed arrays
This commit is contained in:
parent
9921b57ef3
commit
ba7be773dc
@ -1 +1,4 @@
|
||||
export type ConditionFn = (args?: any[]) => boolean;
|
||||
|
||||
/** Alias for the constructor of a class */
|
||||
export type Constructor<T> = new (...args: unknown[]) => T;
|
||||
|
@ -123,7 +123,7 @@ export interface Starter {
|
||||
pokerus: boolean;
|
||||
nickname?: string;
|
||||
teraType?: PokemonType;
|
||||
ivs: Uint8Array;
|
||||
ivs: number[];
|
||||
}
|
||||
|
||||
export type RunHistoryData = Record<number, RunEntry>;
|
||||
|
@ -118,9 +118,9 @@ import type { TrainerData } from "#system/trainer-data";
|
||||
import type { Voucher } from "#system/voucher";
|
||||
import { vouchers } from "#system/voucher";
|
||||
import { trainerConfigs } from "#trainers/trainer-config";
|
||||
import type { Constructor } from "#types/common";
|
||||
import type { HeldModifierConfig } from "#types/held-modifier-config";
|
||||
import type { Localizable } from "#types/locales";
|
||||
import type { ReadonlyUint8Array } from "#types/typed-arrays";
|
||||
import { AbilityBar } from "#ui/ability-bar";
|
||||
import { ArenaFlyout } from "#ui/arena-flyout";
|
||||
import { CandyBar } from "#ui/candy-bar";
|
||||
@ -133,7 +133,6 @@ import { UI } from "#ui/ui";
|
||||
import { addUiThemeOverrides } from "#ui/ui-theme";
|
||||
import {
|
||||
BooleanHolder,
|
||||
type Constructor,
|
||||
fixedInt,
|
||||
formatMoney,
|
||||
getIvsFromId,
|
||||
@ -867,7 +866,7 @@ export class BattleScene extends SceneBase {
|
||||
gender?: Gender,
|
||||
shiny?: boolean,
|
||||
variant?: Variant,
|
||||
ivs?: ReadonlyUint8Array | number[],
|
||||
ivs?: number[],
|
||||
nature?: Nature,
|
||||
dataSource?: Pokemon | PokemonData,
|
||||
postProcess?: (playerPokemon: PlayerPokemon) => void,
|
||||
@ -898,12 +897,12 @@ export class BattleScene extends SceneBase {
|
||||
if (Overrides.IVS_OVERRIDE.some(value => !isBetween(value, 0, 31))) {
|
||||
throw new Error("All IVs in the player IV override must be between 0 and 31!");
|
||||
}
|
||||
pokemon.ivs = new Uint8Array(Overrides.IVS_OVERRIDE);
|
||||
pokemon.ivs = Overrides.IVS_OVERRIDE;
|
||||
} else {
|
||||
if (!isBetween(Overrides.IVS_OVERRIDE, 0, 31)) {
|
||||
throw new Error("The Player IV override must be a value between 0 and 31!");
|
||||
}
|
||||
pokemon.ivs = new Uint8Array(6).fill(Overrides.IVS_OVERRIDE);
|
||||
pokemon.ivs = new Array(6).fill(Overrides.IVS_OVERRIDE);
|
||||
}
|
||||
|
||||
if (Overrides.NATURE_OVERRIDE !== null) {
|
||||
@ -963,12 +962,12 @@ export class BattleScene extends SceneBase {
|
||||
if (Overrides.ENEMY_IVS_OVERRIDE.some(value => !isBetween(value, 0, 31))) {
|
||||
throw new Error("All IVs in the enemy IV override must be between 0 and 31!");
|
||||
}
|
||||
pokemon.ivs = new Uint8Array(Overrides.ENEMY_IVS_OVERRIDE);
|
||||
pokemon.ivs = Overrides.ENEMY_IVS_OVERRIDE;
|
||||
} else {
|
||||
if (!isBetween(Overrides.ENEMY_IVS_OVERRIDE, 0, 31)) {
|
||||
throw new Error("The Enemy IV override must be a value between 0 and 31!");
|
||||
}
|
||||
pokemon.ivs = new Uint8Array(6).fill(Overrides.ENEMY_IVS_OVERRIDE);
|
||||
pokemon.ivs = new Array(6).fill(Overrides.ENEMY_IVS_OVERRIDE);
|
||||
}
|
||||
|
||||
if (Overrides.ENEMY_NATURE_OVERRIDE !== null) {
|
||||
|
@ -62,11 +62,10 @@ import type {
|
||||
PokemonDefendCondition,
|
||||
PokemonStatStageChangeCondition,
|
||||
} from "#types/ability-types";
|
||||
import type { Constructor } from "#types/common";
|
||||
import type { Localizable } from "#types/locales";
|
||||
import type { Closed, Exact } from "#types/type-helpers";
|
||||
import type { GenericUint8Array, ReadonlyGenericInt8Array, ReadonlyGenericUint8Array } from "#types/typed-arrays";
|
||||
import { coerceArray } from "#utils/array";
|
||||
import type { Constructor } from "#utils/common";
|
||||
import { BooleanHolder, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
|
||||
import { toCamelCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
@ -1211,13 +1210,13 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr {
|
||||
|
||||
export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr {
|
||||
private chance: number;
|
||||
private readonly effects: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
private readonly effects: readonly StatusEffect[];
|
||||
|
||||
constructor(chance: number, ...effects: StatusEffect[]) {
|
||||
super(true);
|
||||
|
||||
this.chance = chance;
|
||||
this.effects = new Uint8Array(effects);
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
override canApply({ pokemon, move, opponent: attacker }: PostMoveInteractionAbAttrParams): boolean {
|
||||
@ -2181,14 +2180,14 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
||||
export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
|
||||
private contactRequired: boolean;
|
||||
private chance: number;
|
||||
private readonly effects: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
private readonly effects: readonly StatusEffect[];
|
||||
|
||||
constructor(contactRequired: boolean, chance: number, ...effects: StatusEffect[]) {
|
||||
super();
|
||||
|
||||
this.contactRequired = contactRequired;
|
||||
this.chance = chance;
|
||||
this.effects = new Uint8Array(effects);
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
override canApply(params: PostMoveInteractionAbAttrParams): boolean {
|
||||
@ -2941,7 +2940,7 @@ export class PostSummonTerrainChangeAbAttr extends PostSummonAbAttr {
|
||||
* Heals a status effect if the Pokemon is afflicted with it upon switch in (or gain)
|
||||
*/
|
||||
export class PostSummonHealStatusAbAttr extends PostSummonRemoveEffectAbAttr {
|
||||
private readonly immuneEffects: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
private readonly immuneEffects: readonly StatusEffect[];
|
||||
private statusHealed: StatusEffect;
|
||||
|
||||
/**
|
||||
@ -2949,7 +2948,7 @@ export class PostSummonHealStatusAbAttr extends PostSummonRemoveEffectAbAttr {
|
||||
*/
|
||||
constructor(...immuneEffects: StatusEffect[]) {
|
||||
super();
|
||||
this.immuneEffects = new Uint8Array(immuneEffects);
|
||||
this.immuneEffects = immuneEffects;
|
||||
}
|
||||
|
||||
public override canApply({ pokemon }: AbAttrBaseParams): boolean {
|
||||
@ -3050,7 +3049,7 @@ export class PostSummonCopyAbilityAbAttr extends PostSummonAbAttr {
|
||||
* Removes supplied status effects from the user's field.
|
||||
*/
|
||||
export class PostSummonUserFieldRemoveStatusEffectAbAttr extends PostSummonAbAttr {
|
||||
private readonly statusEffect: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
private readonly statusEffect: readonly StatusEffect[];
|
||||
|
||||
/**
|
||||
* @param statusEffect - The status effects to be removed from the user's field.
|
||||
@ -3058,7 +3057,7 @@ export class PostSummonUserFieldRemoveStatusEffectAbAttr extends PostSummonAbAtt
|
||||
constructor(...statusEffect: StatusEffect[]) {
|
||||
super(false);
|
||||
|
||||
this.statusEffect = new Uint8Array(statusEffect);
|
||||
this.statusEffect = statusEffect;
|
||||
}
|
||||
|
||||
override canApply({ pokemon }: AbAttrBaseParams): boolean {
|
||||
@ -3638,7 +3637,7 @@ export class PreSetStatusAbAttr extends AbAttr {
|
||||
* Provides immunity to status effects to specified targets.
|
||||
*/
|
||||
export class PreSetStatusEffectImmunityAbAttr extends PreSetStatusAbAttr {
|
||||
protected readonly immuneEffects: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
protected readonly immuneEffects: readonly StatusEffect[];
|
||||
|
||||
/**
|
||||
* @param immuneEffects - An array of {@linkcode StatusEffect}s to prevent application.
|
||||
@ -3647,7 +3646,7 @@ export class PreSetStatusEffectImmunityAbAttr extends PreSetStatusAbAttr {
|
||||
constructor(...immuneEffects: StatusEffect[]) {
|
||||
super();
|
||||
|
||||
this.immuneEffects = new Uint8Array(immuneEffects);
|
||||
this.immuneEffects = immuneEffects;
|
||||
}
|
||||
|
||||
override canApply({ effect, cancelled }: PreSetStatusAbAttrParams): boolean {
|
||||
@ -3706,7 +3705,7 @@ export interface UserFieldStatusEffectImmunityAbAttrParams extends AbAttrBasePar
|
||||
*/
|
||||
export class UserFieldStatusEffectImmunityAbAttr extends CancelInteractionAbAttr {
|
||||
private declare readonly _: never;
|
||||
protected readonly immuneEffects: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
protected readonly immuneEffects: readonly StatusEffect[];
|
||||
|
||||
/**
|
||||
* @param immuneEffects - An array of {@linkcode StatusEffect}s to prevent application.
|
||||
@ -3715,7 +3714,7 @@ export class UserFieldStatusEffectImmunityAbAttr extends CancelInteractionAbAttr
|
||||
constructor(...immuneEffects: StatusEffect[]) {
|
||||
super();
|
||||
|
||||
this.immuneEffects = new Uint8Array(immuneEffects);
|
||||
this.immuneEffects = immuneEffects;
|
||||
}
|
||||
|
||||
override canApply({ effect, cancelled }: UserFieldStatusEffectImmunityAbAttrParams): boolean {
|
||||
@ -3999,7 +3998,7 @@ export class BlockNonDirectDamageAbAttr extends CancelInteractionAbAttr {
|
||||
* This attribute will block any status damage that you put in the parameter.
|
||||
*/
|
||||
export class BlockStatusDamageAbAttr extends CancelInteractionAbAttr {
|
||||
private readonly effects: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
private readonly effects: readonly StatusEffect[];
|
||||
|
||||
/**
|
||||
* @param effects - The status effect(s) that will be blocked from damaging the ability pokemon
|
||||
@ -4007,7 +4006,7 @@ export class BlockStatusDamageAbAttr extends CancelInteractionAbAttr {
|
||||
constructor(...effects: StatusEffect[]) {
|
||||
super(false);
|
||||
|
||||
this.effects = new Uint8Array(effects);
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
override canApply({ pokemon, cancelled }: AbAttrParamsWithCancel): boolean {
|
||||
@ -4540,7 +4539,7 @@ export class PostTurnAbAttr extends AbAttr {
|
||||
* @sealed
|
||||
*/
|
||||
export class PostTurnStatusHealAbAttr extends PostTurnAbAttr {
|
||||
private readonly effects: GenericUint8Array<StatusEffect>;
|
||||
private readonly effects: readonly StatusEffect[];
|
||||
|
||||
/**
|
||||
* @param effects - The status effect(s) that will qualify healing the ability pokemon
|
||||
@ -4548,7 +4547,7 @@ export class PostTurnStatusHealAbAttr extends PostTurnAbAttr {
|
||||
constructor(...effects: StatusEffect[]) {
|
||||
super(false);
|
||||
|
||||
this.effects = new Uint8Array(effects);
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
override canApply({ pokemon }: AbAttrBaseParams): boolean {
|
||||
@ -5809,14 +5808,14 @@ export interface IgnoreTypeStatusEffectImmunityAbAttrParams extends AbAttrParams
|
||||
* @sealed
|
||||
*/
|
||||
export class IgnoreTypeStatusEffectImmunityAbAttr extends AbAttr {
|
||||
private readonly statusEffect: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
private readonly defenderType: ReadonlyGenericInt8Array<PokemonType>;
|
||||
private readonly statusEffect: readonly StatusEffect[];
|
||||
private readonly defenderType: readonly PokemonType[];
|
||||
|
||||
constructor(statusEffect: StatusEffect[], defenderType: PokemonType[]) {
|
||||
constructor(statusEffect: readonly StatusEffect[], defenderType: readonly PokemonType[]) {
|
||||
super(false);
|
||||
|
||||
this.statusEffect = new Uint8Array(statusEffect);
|
||||
this.defenderType = new Int8Array(defenderType);
|
||||
this.statusEffect = statusEffect;
|
||||
this.defenderType = defenderType;
|
||||
}
|
||||
|
||||
override canApply({ statusEffect, defenderType, cancelled }: IgnoreTypeStatusEffectImmunityAbAttrParams): boolean {
|
||||
|
@ -87,7 +87,8 @@ import type { AttackMoveResult } from "#types/attack-move-result";
|
||||
import type { Localizable } from "#types/locales";
|
||||
import type { ChargingMove, MoveAttrMap, MoveAttrString, MoveClassMap, MoveKindString, MoveMessageFunc } from "#types/move-types";
|
||||
import type { TurnMove } from "#types/turn-move";
|
||||
import { BooleanHolder, type Constructor, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
|
||||
import { BooleanHolder, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
|
||||
import type { Constructor } from "#types/common";
|
||||
import { coerceArray } from "#utils/array";
|
||||
import { getEnumValues } from "#utils/enums";
|
||||
import { toCamelCase, toTitleCase } from "#utils/strings";
|
||||
@ -2596,11 +2597,11 @@ export class StatusEffectAttr extends MoveEffectAttr {
|
||||
* Used for {@linkcode Moves.TRI_ATTACK} and {@linkcode Moves.DIRE_CLAW}.
|
||||
*/
|
||||
export class MultiStatusEffectAttr extends StatusEffectAttr {
|
||||
public readonly effects: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
public readonly effects: readonly StatusEffect[];
|
||||
|
||||
constructor(effects: StatusEffect[], selfTarget?: boolean) {
|
||||
super(effects[0], selfTarget);
|
||||
this.effects = new Uint8Array(effects);
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
@ -2926,7 +2927,7 @@ export class StealEatBerryAttr extends EatBerryAttr {
|
||||
*/
|
||||
export class HealStatusEffectAttr extends MoveEffectAttr {
|
||||
/** List of Status Effects to cure */
|
||||
private readonly effects: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
private readonly effects: readonly StatusEffect[];
|
||||
|
||||
/**
|
||||
* @param selfTarget - Whether this move targets the user
|
||||
@ -2934,7 +2935,7 @@ export class HealStatusEffectAttr extends MoveEffectAttr {
|
||||
*/
|
||||
constructor(selfTarget: boolean, effects: StatusEffect | StatusEffect[]) {
|
||||
super(selfTarget, { lastHitOnly: true });
|
||||
this.effects = new Uint8Array(coerceArray(effects));
|
||||
this.effects = coerceArray(effects);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,6 @@ import { WeatherType } from "#enums/weather-type";
|
||||
import type { PlayerPokemon } from "#field/pokemon";
|
||||
import { AttackTypeBoosterModifier } from "#modifiers/modifier";
|
||||
import type { AttackTypeBoosterModifierType } from "#modifiers/modifier-type";
|
||||
import type { ReadonlyGenericUint8Array } from "#types/typed-arrays";
|
||||
import { coerceArray } from "#utils/array";
|
||||
|
||||
export interface EncounterRequirement {
|
||||
@ -697,15 +696,15 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
|
||||
}
|
||||
|
||||
export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
||||
requiredStatusEffect: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
requiredStatusEffect: readonly StatusEffect[];
|
||||
minNumberOfPokemon: number;
|
||||
invertQuery: boolean;
|
||||
|
||||
constructor(statusEffect: StatusEffect | StatusEffect[], minNumberOfPokemon = 1, invertQuery = false) {
|
||||
constructor(statusEffect: StatusEffect | readonly StatusEffect[], minNumberOfPokemon = 1, invertQuery = false) {
|
||||
super();
|
||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||
this.invertQuery = invertQuery;
|
||||
this.requiredStatusEffect = new Uint8Array(coerceArray(statusEffect));
|
||||
this.requiredStatusEffect = coerceArray(statusEffect);
|
||||
}
|
||||
|
||||
override meetsRequirement(): boolean {
|
||||
@ -718,7 +717,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
||||
return x;
|
||||
}
|
||||
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: readonly PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter(pokemon => {
|
||||
return this.requiredStatusEffect.some(statusEffect => {
|
||||
@ -762,11 +761,11 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
||||
* If you want to trigger the event based on the form change enabler, use PersistentModifierRequirement.
|
||||
*/
|
||||
export class CanFormChangeWithItemRequirement extends EncounterPokemonRequirement {
|
||||
requiredFormChangeItem: FormChangeItem[];
|
||||
requiredFormChangeItem: readonly FormChangeItem[];
|
||||
minNumberOfPokemon: number;
|
||||
invertQuery: boolean;
|
||||
|
||||
constructor(formChangeItem: FormChangeItem | FormChangeItem[], minNumberOfPokemon = 1, invertQuery = false) {
|
||||
constructor(formChangeItem: FormChangeItem | readonly FormChangeItem[], minNumberOfPokemon = 1, invertQuery = false) {
|
||||
super();
|
||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||
this.invertQuery = invertQuery;
|
||||
@ -793,7 +792,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
||||
);
|
||||
}
|
||||
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: readonly PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter(
|
||||
pokemon =>
|
||||
@ -878,13 +877,13 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
||||
}
|
||||
|
||||
export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRequirement {
|
||||
requiredHeldItemTypes: PokemonType[];
|
||||
requiredHeldItemTypes: readonly PokemonType[];
|
||||
minNumberOfPokemon: number;
|
||||
invertQuery: boolean;
|
||||
requireTransferable: boolean;
|
||||
|
||||
constructor(
|
||||
heldItemTypes: PokemonType | PokemonType[],
|
||||
heldItemTypes: PokemonType | readonly PokemonType[],
|
||||
minNumberOfPokemon = 1,
|
||||
invertQuery = false,
|
||||
requireTransferable = true,
|
||||
|
@ -319,7 +319,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
|
||||
|
||||
// Set IVs
|
||||
if (config.ivs) {
|
||||
enemyPokemon.ivs = new Uint8Array(config.ivs);
|
||||
enemyPokemon.ivs = config.ivs;
|
||||
}
|
||||
|
||||
// Set Status
|
||||
|
@ -24,7 +24,8 @@ import { SpeciesFormKey } from "#enums/species-form-key";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { WeatherType } from "#enums/weather-type";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import type { Constructor, nil } from "#utils/common";
|
||||
import type { Constructor } from "#types/common";
|
||||
import type { nil } from "#utils/common";
|
||||
|
||||
export type SpeciesFormChangeConditionPredicate = (p: Pokemon) => boolean;
|
||||
export type SpeciesFormChangeConditionEnforceFunc = (p: Pokemon) => void;
|
||||
|
@ -11,9 +11,8 @@ import type { TimeOfDay } from "#enums/time-of-day";
|
||||
import { WeatherType } from "#enums/weather-type";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import type { PokemonFormChangeItemModifier } from "#modifiers/modifier";
|
||||
import type { ReadonlyGenericUint8Array } from "#types/typed-arrays";
|
||||
import type { Constructor } from "#types/common";
|
||||
import { coerceArray } from "#utils/array";
|
||||
import type { Constructor } from "#utils/common";
|
||||
import { toCamelCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
|
||||
@ -123,12 +122,12 @@ export class SpeciesFormChangeActiveTrigger extends SpeciesFormChangeTrigger {
|
||||
}
|
||||
|
||||
export class SpeciesFormChangeStatusEffectTrigger extends SpeciesFormChangeTrigger {
|
||||
public readonly statusEffects: ReadonlyGenericUint8Array<StatusEffect>;
|
||||
public readonly statusEffects: readonly StatusEffect[];
|
||||
public invert: boolean;
|
||||
|
||||
constructor(statusEffects: StatusEffect | StatusEffect[], invert = false) {
|
||||
super();
|
||||
this.statusEffects = new Uint8Array(coerceArray(statusEffects));
|
||||
this.statusEffects = coerceArray(statusEffects);
|
||||
this.invert = invert;
|
||||
// this.description = i18next.t("pokemonEvolutions:forms.statusEffect");
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import type { AttackMoveResult } from "#types/attack-move-result";
|
||||
import type { IllusionData } from "#types/illusion-data";
|
||||
import type { TurnMove } from "#types/turn-move";
|
||||
import type { CoerceNullPropertiesToUndefined } from "#types/type-helpers";
|
||||
import { setTypedArray } from "#utils/array";
|
||||
import { getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
||||
|
||||
/**
|
||||
@ -130,7 +129,7 @@ export class PokemonSummonData {
|
||||
public passiveAbility: AbilityId | undefined;
|
||||
public gender: Gender | undefined;
|
||||
public fusionGender: Gender | undefined;
|
||||
public stats: Uint32Array = new Uint32Array(6);
|
||||
public stats: number[] = [0, 0, 0, 0, 0, 0];
|
||||
public moveset: PokemonMove[] | null;
|
||||
|
||||
// If not initialized this value will not be populated from save data.
|
||||
@ -166,11 +165,6 @@ export class PokemonSummonData {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key === "stats") {
|
||||
setTypedArray(this.stats, source.stats);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key === "illusion" && typeof value === "object") {
|
||||
// Make a copy so as not to mutate provided value
|
||||
const illusionData = {
|
||||
@ -227,10 +221,8 @@ export class PokemonSummonData {
|
||||
// We coerce null to undefined in the type, as the for loop below replaces `null` with `undefined`
|
||||
...(this as Omit<
|
||||
CoerceNullPropertiesToUndefined<PokemonSummonData>,
|
||||
"speciesForm" | "fusionSpeciesForm" | "illusion" | "stats"
|
||||
"speciesForm" | "fusionSpeciesForm" | "illusion"
|
||||
>),
|
||||
// TypedArrays do not serialize to JSON as an array.
|
||||
stats: Array.from(this.stats),
|
||||
speciesForm: speciesForm == null ? undefined : { id: speciesForm.speciesId, formIdx: speciesForm.formIndex },
|
||||
fusionSpeciesForm:
|
||||
fusionSpeciesForm == null
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { DelayedAttackTag, type PositionalTag, WishTag } from "#data/positional-tags/positional-tag";
|
||||
import { PositionalTagType } from "#enums/positional-tag-type";
|
||||
import type { Constructor } from "#types/common";
|
||||
import type { ObjectValues } from "#types/type-helpers";
|
||||
import type { Constructor } from "#utils/common";
|
||||
|
||||
/**
|
||||
* Load the attributes of a {@linkcode PositionalTag}.
|
||||
|
@ -35,8 +35,9 @@ import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEven
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import { FieldEffectModifier } from "#modifiers/modifier";
|
||||
import type { Move } from "#moves/move";
|
||||
import type { Constructor } from "#types/common";
|
||||
import type { AbstractConstructor } from "#types/type-helpers";
|
||||
import { type Constructor, NumberHolder, randSeedInt } from "#utils/common";
|
||||
import { NumberHolder, randSeedInt } from "#utils/common";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
|
||||
export class Arena {
|
||||
|
@ -141,22 +141,21 @@ import type { PokemonData } from "#system/pokemon-data";
|
||||
import { RibbonData } from "#system/ribbons/ribbon-data";
|
||||
import { awardRibbonsToSpeciesLine } from "#system/ribbons/ribbon-methods";
|
||||
import type { AbAttrMap, AbAttrString, TypeMultiplierAbAttrParams } from "#types/ability-types";
|
||||
import type { Constructor } from "#types/common";
|
||||
import type { getAttackDamageParams, getBaseDamageParams } from "#types/damage-params";
|
||||
import type { DamageCalculationResult, DamageResult } from "#types/damage-result";
|
||||
import type { IllusionData } from "#types/illusion-data";
|
||||
import type { StarterDataEntry, StarterMoveset } from "#types/save-data";
|
||||
import type { TurnMove } from "#types/turn-move";
|
||||
import type { ReadonlyUint8Array } from "#types/typed-arrays";
|
||||
import { BattleInfo } from "#ui/battle-info";
|
||||
import { EnemyBattleInfo } from "#ui/enemy-battle-info";
|
||||
import type { PartyOption } from "#ui/party-ui-handler";
|
||||
import { PartyUiHandler, PartyUiMode } from "#ui/party-ui-handler";
|
||||
import { PlayerBattleInfo } from "#ui/player-battle-info";
|
||||
import { coerceArray, setTypedArray } from "#utils/array";
|
||||
import { coerceArray } from "#utils/array";
|
||||
import { applyChallenges } from "#utils/challenge-utils";
|
||||
import {
|
||||
BooleanHolder,
|
||||
type Constructor,
|
||||
deltaRgb,
|
||||
fixedInt,
|
||||
getIvsFromId,
|
||||
@ -204,8 +203,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
public levelExp: number;
|
||||
public gender: Gender;
|
||||
public hp: number;
|
||||
public stats = Uint32Array.of(1, 1, 1, 1, 1, 1);
|
||||
public ivs = Uint8Array.of(0, 0, 0, 0, 0, 0);
|
||||
public stats: number[];
|
||||
public ivs: number[];
|
||||
public nature: Nature;
|
||||
public moveset: PokemonMove[];
|
||||
/**
|
||||
@ -312,7 +311,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
gender?: Gender,
|
||||
shiny?: boolean,
|
||||
variant?: Variant,
|
||||
ivs?: ReadonlyUint8Array | number[],
|
||||
ivs?: number[],
|
||||
nature?: Nature,
|
||||
dataSource?: Pokemon | PokemonData,
|
||||
) {
|
||||
@ -346,8 +345,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (dataSource) {
|
||||
this.id = dataSource.id;
|
||||
this.hp = dataSource.hp;
|
||||
setTypedArray(this.stats, dataSource.stats);
|
||||
setTypedArray(this.ivs, dataSource.ivs ?? getIvsFromId(dataSource.id));
|
||||
this.stats = dataSource.stats;
|
||||
this.ivs = dataSource.ivs;
|
||||
this.passive = !!dataSource.passive;
|
||||
if (this.variant === undefined) {
|
||||
this.variant = 0;
|
||||
@ -386,7 +385,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
this.stellarTypesBoosted = dataSource.stellarTypesBoosted ?? [];
|
||||
} else {
|
||||
this.id = randSeedInt(4294967296);
|
||||
setTypedArray(this.ivs, ivs ?? getIvsFromId(this.id));
|
||||
this.ivs = ivs || getIvsFromId(this.id);
|
||||
|
||||
if (this.gender === undefined) {
|
||||
this.gender = this.species.generateGender();
|
||||
@ -1320,7 +1319,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* @param bypassSummonData - Whether to prefer actual stats (`true`) or in-battle overridden stats (`false`); default `true`
|
||||
* @returns The numeric values of this {@linkcode Pokemon}'s stats as an array.
|
||||
*/
|
||||
getStats(bypassSummonData = true): Uint32Array {
|
||||
getStats(bypassSummonData = true): number[] {
|
||||
if (!bypassSummonData) {
|
||||
// Only grab summon data stats if nonzero
|
||||
return this.summonData.stats.map((s, i) => s || this.stats[i]);
|
||||
@ -1552,6 +1551,10 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
calculateStats(): void {
|
||||
if (!this.stats) {
|
||||
this.stats = [0, 0, 0, 0, 0, 0];
|
||||
}
|
||||
|
||||
// Get and manipulate base stats
|
||||
const baseStats = this.calculateBaseStats();
|
||||
// Using base stats, calculate and store stats one by one
|
||||
@ -1584,7 +1587,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
globalScene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder);
|
||||
}
|
||||
|
||||
statHolder.value = Phaser.Math.Clamp(statHolder.value, 1, 0xffffffff);
|
||||
statHolder.value = Phaser.Math.Clamp(statHolder.value, 1, Number.MAX_SAFE_INTEGER);
|
||||
|
||||
this.setStat(s, statHolder.value);
|
||||
}
|
||||
@ -5701,7 +5704,7 @@ export class PlayerPokemon extends Pokemon {
|
||||
gender?: Gender,
|
||||
shiny?: boolean,
|
||||
variant?: Variant,
|
||||
ivs?: ReadonlyUint8Array | number[],
|
||||
ivs?: number[],
|
||||
nature?: Nature,
|
||||
dataSource?: Pokemon | PokemonData,
|
||||
) {
|
||||
@ -6321,9 +6324,9 @@ export class EnemyPokemon extends Pokemon {
|
||||
|
||||
if (this.hasTrainer() && globalScene.currentBattle) {
|
||||
const { waveIndex } = globalScene.currentBattle;
|
||||
const ivs = new Uint8Array(6);
|
||||
for (let i = 0; i < 6; i++) {
|
||||
ivs[i] = this.randBattleSeedIntRange(Math.floor(waveIndex / 10), 31);
|
||||
const ivs: number[] = [];
|
||||
while (ivs.length < 6) {
|
||||
ivs.push(randSeedIntRange(Math.floor(waveIndex / 10), 31));
|
||||
}
|
||||
this.ivs = ivs;
|
||||
}
|
||||
|
@ -1914,7 +1914,7 @@ export class GameData {
|
||||
_unlockSpeciesNature(species.speciesId);
|
||||
}
|
||||
|
||||
updateSpeciesDexIvs(speciesId: SpeciesId, ivs: Uint8Array): void {
|
||||
updateSpeciesDexIvs(speciesId: SpeciesId, ivs: number[]): void {
|
||||
let dexEntry: DexEntry;
|
||||
do {
|
||||
dexEntry = globalScene.gameData.dexData[speciesId];
|
||||
|
@ -99,8 +99,8 @@ export class PokemonData {
|
||||
this.levelExp = source.levelExp;
|
||||
this.gender = source.gender;
|
||||
this.hp = source.hp;
|
||||
this.stats = Array.from(source.stats);
|
||||
this.ivs = Array.from(source.ivs);
|
||||
this.stats = source.stats;
|
||||
this.ivs = source.ivs;
|
||||
|
||||
// TODO: Can't we move some of this verification stuff to an upgrade script?
|
||||
this.nature = source.nature ?? Nature.HARDY;
|
||||
@ -162,7 +162,7 @@ export class PokemonData {
|
||||
this.gender,
|
||||
this.shiny,
|
||||
this.variant,
|
||||
new Uint8Array(this.ivs.slice(0, 6)),
|
||||
this.ivs,
|
||||
this.nature,
|
||||
this,
|
||||
playerPokemon => {
|
||||
|
@ -104,7 +104,7 @@ export class StatsContainer extends Phaser.GameObjects.Container {
|
||||
}
|
||||
}
|
||||
|
||||
updateIvs(ivs: Uint8Array | number[], originalIvs?: number[]): void {
|
||||
updateIvs(ivs: number[], originalIvs?: number[]): void {
|
||||
if (ivs) {
|
||||
const ivChartData = new Array(6)
|
||||
.fill(null)
|
||||
|
@ -195,7 +195,7 @@ export class BattleMessageUiHandler extends MessageUiHandler {
|
||||
super.showDialogue(text, name, delay, callback, callbackDelay, prompt, promptDelay);
|
||||
}
|
||||
|
||||
promptLevelUpStats(partyMemberIndex: number, prevStats: ArrayLike<number>, showTotals: boolean): Promise<void> {
|
||||
promptLevelUpStats(partyMemberIndex: number, prevStats: number[], showTotals: boolean): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
if (!globalScene.showLevelUpStats) {
|
||||
return resolve();
|
||||
@ -219,7 +219,7 @@ export class BattleMessageUiHandler extends MessageUiHandler {
|
||||
});
|
||||
}
|
||||
|
||||
promptIvs(pokemonId: number, ivs: ArrayLike<number>): Promise<void> {
|
||||
promptIvs(pokemonId: number, ivs: number[]): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
globalScene.executeWithSeedOffset(() => {
|
||||
let levelUpStatsValuesText = "";
|
||||
|
@ -2759,7 +2759,7 @@ export class StarterSelectUiHandler extends MessageUiHandler {
|
||||
pokerus: this.pokerusSpecies.includes(species),
|
||||
nickname: this.starterPreferences[species.speciesId]?.nickname,
|
||||
teraType,
|
||||
ivs: new Uint8Array(dexEntry.ivs),
|
||||
ivs: dexEntry.ivs,
|
||||
};
|
||||
|
||||
this.starters.push(starter);
|
||||
|
@ -12,7 +12,7 @@ import type {
|
||||
* If the input isn't already an array, turns it into one.
|
||||
* @returns An array with the same type as the type of the input
|
||||
*/
|
||||
export function coerceArray<T>(input: T): T extends any[] ? T : [T];
|
||||
export function coerceArray<T>(input: T): T extends readonly any[] ? T : [T];
|
||||
export function coerceArray<T>(input: T): T | [T] {
|
||||
return Array.isArray(input) ? input : [input];
|
||||
}
|
||||
|
@ -176,15 +176,15 @@ export function getPlayTimeString(totalSeconds: number): string {
|
||||
* @param id 32-bit number
|
||||
* @returns An array of six numbers corresponding to 5-bit chunks from {@linkcode id}
|
||||
*/
|
||||
export function getIvsFromId(id: number): Uint8Array {
|
||||
return Uint8Array.of(
|
||||
export function getIvsFromId(id: number): [number, number, number, number, number, number] {
|
||||
return [
|
||||
(id & 0x3e000000) >>> 25,
|
||||
(id & 0x01f00000) >>> 20,
|
||||
(id & 0x000f8000) >>> 15,
|
||||
(id & 0x00007c00) >>> 10,
|
||||
(id & 0x000003e0) >>> 5,
|
||||
id & 0x0000001f,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
export function formatLargeNumber(count: number, threshold: number): string {
|
||||
@ -292,9 +292,6 @@ export async function localPing(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
/** Alias for the constructor of a class */
|
||||
export type Constructor<T> = new (...args: unknown[]) => T;
|
||||
|
||||
export class BooleanHolder {
|
||||
public value: boolean;
|
||||
|
||||
|
@ -38,7 +38,7 @@ describe("Abilities - Beast Boost", () => {
|
||||
|
||||
const playerPokemon = game.field.getPlayerPokemon();
|
||||
// Set the pokemon's highest stat to DEF, so it should be picked by Beast Boost
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue(Uint32Array.of(10000, 100, 1000, 200, 100, 100));
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue([10000, 100, 1000, 200, 100, 100]);
|
||||
console.log(playerPokemon.stats);
|
||||
|
||||
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0);
|
||||
@ -56,7 +56,7 @@ describe("Abilities - Beast Boost", () => {
|
||||
|
||||
const playerPokemon = game.field.getPlayerPokemon();
|
||||
// If the opponent uses Guard Split, the pokemon's second highest stat (SPATK) should be chosen
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue(Uint32Array.of(10000, 100, 201, 200, 100, 100));
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue([10000, 100, 201, 200, 100, 100]);
|
||||
|
||||
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0);
|
||||
|
||||
@ -75,7 +75,7 @@ describe("Abilities - Beast Boost", () => {
|
||||
const playerPokemon = game.field.getPlayerPokemon();
|
||||
|
||||
// Set up tie between SPATK, SPDEF, and SPD, where SPATK should win
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue(Uint32Array.of(10000, 1, 1, 100, 100, 100));
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue([10000, 1, 1, 100, 100, 100]);
|
||||
|
||||
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0);
|
||||
|
||||
|
@ -39,8 +39,8 @@ describe("Battle order", () => {
|
||||
const enemyPokemon = game.field.getEnemyPokemon();
|
||||
const enemyStartHp = enemyPokemon.hp;
|
||||
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 50)); // set playerPokemon's speed to 50
|
||||
vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 150)); // set enemyPokemon's speed to 150
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 50]); // set playerPokemon's speed to 50
|
||||
vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set enemyPokemon's speed to 150
|
||||
game.move.select(MoveId.TACKLE);
|
||||
|
||||
await game.phaseInterceptor.to("MoveEndPhase", false);
|
||||
@ -55,8 +55,8 @@ describe("Battle order", () => {
|
||||
const playerStartHp = playerPokemon.hp;
|
||||
const enemyPokemon = game.field.getEnemyPokemon();
|
||||
const enemyStartHp = enemyPokemon.hp;
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 150)); // set playerPokemon's speed to 150
|
||||
vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 50)); // set enemyPokemon's speed to 50
|
||||
vi.spyOn(playerPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set playerPokemon's speed to 150
|
||||
vi.spyOn(enemyPokemon, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 50]); // set enemyPokemon's speed to 50
|
||||
|
||||
game.move.select(MoveId.TACKLE);
|
||||
|
||||
@ -74,8 +74,8 @@ describe("Battle order", () => {
|
||||
const enemyPokemon = game.scene.getEnemyField();
|
||||
const enemyHps = enemyPokemon.map(p => p.hp);
|
||||
|
||||
playerPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 50))); // set both playerPokemons' speed to 50
|
||||
enemyPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 150))); // set both enemyPokemons' speed to 150
|
||||
playerPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 50])); // set both playerPokemons' speed to 50
|
||||
enemyPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150])); // set both enemyPokemons' speed to 150
|
||||
|
||||
game.move.select(MoveId.TACKLE);
|
||||
game.move.select(MoveId.TACKLE, 1);
|
||||
@ -96,9 +96,9 @@ describe("Battle order", () => {
|
||||
|
||||
const playerPokemon = game.scene.getPlayerField();
|
||||
const enemyPokemon = game.scene.getEnemyField();
|
||||
playerPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 100))); //set both playerPokemons' speed to 100
|
||||
vi.spyOn(enemyPokemon[0], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 100)); // set enemyPokemon's speed to 100
|
||||
vi.spyOn(enemyPokemon[1], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 150)); // set enemyPokemon's speed to 150
|
||||
playerPokemon.forEach(p => vi.spyOn(p, "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 100])); //set both playerPokemons' speed to 100
|
||||
vi.spyOn(enemyPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 100]); // set enemyPokemon's speed to 100
|
||||
vi.spyOn(enemyPokemon[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set enemyPokemon's speed to 150
|
||||
|
||||
game.move.select(MoveId.TACKLE);
|
||||
game.move.select(MoveId.TACKLE, 1);
|
||||
@ -114,10 +114,10 @@ describe("Battle order", () => {
|
||||
|
||||
const playerPokemon = game.scene.getPlayerField();
|
||||
const enemyPokemon = game.scene.getEnemyField();
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 100)); // set one playerPokemon's speed to 100
|
||||
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 150)); // set other playerPokemon's speed to 150
|
||||
vi.spyOn(enemyPokemon[0], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 100)); // set one enemyPokemon's speed to 100
|
||||
vi.spyOn(enemyPokemon[1], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, 150)); // set other enemyPokemon's speed to 150
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 100]); // set one playerPokemon's speed to 100
|
||||
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set other playerPokemon's speed to 150
|
||||
vi.spyOn(enemyPokemon[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 100]); // set one enemyPokemon's speed to 100
|
||||
vi.spyOn(enemyPokemon[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, 150]); // set other enemyPokemon's speed to 150
|
||||
|
||||
game.move.select(MoveId.TACKLE);
|
||||
game.move.select(MoveId.TACKLE, 1);
|
||||
|
@ -38,7 +38,7 @@ describe("Escape chance calculations", () => {
|
||||
const enemyField = game.scene.getEnemyField();
|
||||
const enemySpeed = 100;
|
||||
// set enemyPokemon's speed to 100
|
||||
vi.spyOn(enemyField[0], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, enemySpeed));
|
||||
vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemySpeed]);
|
||||
|
||||
const commandPhase = game.scene.phaseManager.getCurrentPhase() as CommandPhase;
|
||||
commandPhase.handleCommand(Command.RUN, 0);
|
||||
@ -81,9 +81,14 @@ describe("Escape chance calculations", () => {
|
||||
// set the number of escape attempts to the required amount
|
||||
game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
|
||||
// set playerPokemon's speed to a multiple of the enemySpeed
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue(
|
||||
Uint32Array.of(20, 20, 20, 20, 20, check.pokemonSpeedRatio * enemySpeed),
|
||||
);
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
check.pokemonSpeedRatio * enemySpeed,
|
||||
]);
|
||||
const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts);
|
||||
expect(chance).toBe(check.expectedEscapeChance);
|
||||
}
|
||||
@ -102,9 +107,9 @@ describe("Escape chance calculations", () => {
|
||||
// this is used to find the ratio of the player's first pokemon
|
||||
const playerASpeedPercentage = 0.4;
|
||||
// set enemyAPokemon's speed to 70
|
||||
vi.spyOn(enemyField[0], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, enemyASpeed));
|
||||
vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemyASpeed]);
|
||||
// set enemyBPokemon's speed to 30
|
||||
vi.spyOn(enemyField[1], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, enemyBSpeed));
|
||||
vi.spyOn(enemyField[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemyBSpeed]);
|
||||
|
||||
const commandPhase = game.scene.phaseManager.getCurrentPhase() as CommandPhase;
|
||||
commandPhase.handleCommand(Command.RUN, 0);
|
||||
@ -146,20 +151,23 @@ describe("Escape chance calculations", () => {
|
||||
// sets the number of escape attempts to the required amount
|
||||
game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
|
||||
// set the first playerPokemon's speed to a multiple of the enemySpeed
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue(
|
||||
Uint32Array.of(
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
Math.floor(check.pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage),
|
||||
),
|
||||
);
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
Math.floor(check.pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage),
|
||||
]);
|
||||
// set the second playerPokemon's speed to the remaining value of speed
|
||||
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue(
|
||||
Uint32Array.of(20, 20, 20, 20, 20, check.pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5]),
|
||||
);
|
||||
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
check.pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5],
|
||||
]);
|
||||
const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts);
|
||||
// checks to make sure the escape values are the same
|
||||
expect(chance).toBe(check.expectedEscapeChance);
|
||||
@ -176,7 +184,7 @@ describe("Escape chance calculations", () => {
|
||||
const enemyField = game.scene.getEnemyField()!;
|
||||
const enemySpeed = 100;
|
||||
// set enemyPokemon's speed to 100
|
||||
vi.spyOn(enemyField[0], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, enemySpeed));
|
||||
vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemySpeed]);
|
||||
|
||||
const commandPhase = game.scene.phaseManager.getCurrentPhase() as CommandPhase;
|
||||
commandPhase.handleCommand(Command.RUN, 0);
|
||||
@ -233,9 +241,14 @@ describe("Escape chance calculations", () => {
|
||||
// sets the number of escape attempts to the required amount
|
||||
game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
|
||||
// set playerPokemon's speed to a multiple of the enemySpeed
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue(
|
||||
Uint32Array.of(20, 20, 20, 20, 20, check.pokemonSpeedRatio * enemySpeed),
|
||||
);
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
check.pokemonSpeedRatio * enemySpeed,
|
||||
]);
|
||||
const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts);
|
||||
expect(chance).toBe(check.expectedEscapeChance);
|
||||
}
|
||||
@ -254,9 +267,9 @@ describe("Escape chance calculations", () => {
|
||||
// this is used to find the ratio of the player's first pokemon
|
||||
const playerASpeedPercentage = 0.8;
|
||||
// set enemyAPokemon's speed to 70
|
||||
vi.spyOn(enemyField[0], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, enemyASpeed));
|
||||
vi.spyOn(enemyField[0], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemyASpeed]);
|
||||
// set enemyBPokemon's speed to 30
|
||||
vi.spyOn(enemyField[1], "stats", "get").mockReturnValue(Uint32Array.of(20, 20, 20, 20, 20, enemyBSpeed));
|
||||
vi.spyOn(enemyField[1], "stats", "get").mockReturnValue([20, 20, 20, 20, 20, enemyBSpeed]);
|
||||
|
||||
const commandPhase = game.scene.phaseManager.getCurrentPhase() as CommandPhase;
|
||||
commandPhase.handleCommand(Command.RUN, 0);
|
||||
@ -311,20 +324,23 @@ describe("Escape chance calculations", () => {
|
||||
// sets the number of escape attempts to the required amount
|
||||
game.scene.currentBattle.escapeAttempts = check.escapeAttempts;
|
||||
// set the first playerPokemon's speed to a multiple of the enemySpeed
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue(
|
||||
Uint32Array.of(
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
Math.floor(check.pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage),
|
||||
),
|
||||
);
|
||||
vi.spyOn(playerPokemon[0], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
Math.floor(check.pokemonSpeedRatio * totalEnemySpeed * playerASpeedPercentage),
|
||||
]);
|
||||
// set the second playerPokemon's speed to the remaining value of speed
|
||||
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue(
|
||||
Uint32Array.of(20, 20, 20, 20, 20, check.pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5]),
|
||||
);
|
||||
vi.spyOn(playerPokemon[1], "stats", "get").mockReturnValue([
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
check.pokemonSpeedRatio * totalEnemySpeed - playerPokemon[0].stats[5],
|
||||
]);
|
||||
const chance = phase.calculateEscapeChance(game.scene.currentBattle.escapeAttempts);
|
||||
// checks to make sure the escape values are the same
|
||||
expect(chance).toBe(check.expectedEscapeChance);
|
||||
|
@ -45,10 +45,10 @@ describe("Moves - Rollout", () => {
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
const playerPkm = game.field.getPlayerPokemon();
|
||||
vi.spyOn(playerPkm, "stats", "get").mockReturnValue(Uint32Array.of(500000, 1, 1, 1, 1, 1)); // HP, ATK, DEF, SPATK, SPDEF, SPD
|
||||
vi.spyOn(playerPkm, "stats", "get").mockReturnValue([500000, 1, 1, 1, 1, 1]); // HP, ATK, DEF, SPATK, SPDEF, SPD
|
||||
|
||||
const enemyPkm = game.field.getEnemyPokemon();
|
||||
vi.spyOn(enemyPkm, "stats", "get").mockReturnValue(Uint32Array.of(500000, 1, 1, 1, 1, 1)); // HP, ATK, DEF, SPATK, SPDEF, SPD
|
||||
vi.spyOn(enemyPkm, "stats", "get").mockReturnValue([500000, 1, 1, 1, 1, 1]); // HP, ATK, DEF, SPATK, SPDEF, SPD
|
||||
vi.spyOn(enemyPkm, "getHeldItems").mockReturnValue([]); //no berries
|
||||
|
||||
enemyPkm.hp = enemyPkm.getMaxHp();
|
||||
|
@ -144,7 +144,7 @@ describe("Fun And Games! - Mystery Encounter", () => {
|
||||
|
||||
expect(game).toBeAtPhase("CommandPhase");
|
||||
expect(game.field.getEnemyPokemon().species.speciesId).toBe(SpeciesId.WOBBUFFET);
|
||||
expect(game.field.getEnemyPokemon().ivs).toEqual(Uint8Array.of(0, 0, 0, 0, 0, 0));
|
||||
expect(game.field.getEnemyPokemon().ivs).toEqual([0, 0, 0, 0, 0, 0]);
|
||||
expect(game.field.getEnemyPokemon().nature).toBe(Nature.MILD);
|
||||
|
||||
game.onNextPrompt("MessagePhase", UiMode.MESSAGE, () => {
|
||||
|
@ -122,7 +122,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
||||
// Override party levels to 50 so stats can be fully reflective
|
||||
scene.getPlayerParty().forEach(p => {
|
||||
p.level = 50;
|
||||
p.ivs = Uint8Array.of(20, 20, 20, 20, 20, 20);
|
||||
p.ivs = [20, 20, 20, 20, 20, 20];
|
||||
p.calculateStats();
|
||||
});
|
||||
await runMysteryEncounterToEnd(game, 1, { pokemonNo: 2 });
|
||||
@ -168,7 +168,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
||||
// Override party levels to 50 so stats can be fully reflective
|
||||
scene.getPlayerParty().forEach(p => {
|
||||
p.level = 50;
|
||||
p.ivs = Uint8Array.of(0, 0, 0, 0, 0, 0);
|
||||
p.ivs = [0, 0, 0, 0, 0, 0];
|
||||
p.calculateStats();
|
||||
});
|
||||
await runMysteryEncounterToEnd(game, 2, { pokemonNo: 3 });
|
||||
@ -188,7 +188,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
||||
// Override party levels to 50 so stats can be fully reflective
|
||||
scene.getPlayerParty().forEach(p => {
|
||||
p.level = 50;
|
||||
p.ivs = Uint8Array.of(20, 20, 20, 20, 20, 20);
|
||||
p.ivs = [20, 20, 20, 20, 20, 20];
|
||||
p.calculateStats();
|
||||
});
|
||||
await runMysteryEncounterToEnd(game, 2, { pokemonNo: 4 });
|
||||
|
Loading…
Reference in New Issue
Block a user