mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-18 22:32:32 +02:00
Merge branch beta into ability-copy
This commit is contained in:
commit
503afd66b0
@ -50,7 +50,8 @@
|
|||||||
"noUndeclaredVariables": "off",
|
"noUndeclaredVariables": "off",
|
||||||
"noUnusedVariables": "error",
|
"noUnusedVariables": "error",
|
||||||
"noSwitchDeclarations": "warn", // TODO: refactor and make this an error
|
"noSwitchDeclarations": "warn", // TODO: refactor and make this an error
|
||||||
"noVoidTypeReturn": "warn" // TODO: Refactor and make this an error
|
"noVoidTypeReturn": "warn", // TODO: Refactor and make this an error
|
||||||
|
"noUnusedImports": "error"
|
||||||
},
|
},
|
||||||
"style": {
|
"style": {
|
||||||
"noVar": "error",
|
"noVar": "error",
|
||||||
|
@ -72,8 +72,8 @@ import { GameModes, getGameMode } from "#app/game-mode";
|
|||||||
import FieldSpritePipeline from "#app/pipelines/field-sprite";
|
import FieldSpritePipeline from "#app/pipelines/field-sprite";
|
||||||
import SpritePipeline from "#app/pipelines/sprite";
|
import SpritePipeline from "#app/pipelines/sprite";
|
||||||
import PartyExpBar from "#app/ui/party-exp-bar";
|
import PartyExpBar from "#app/ui/party-exp-bar";
|
||||||
import type { TrainerSlot } from "#app/data/trainer-config";
|
import type { TrainerSlot } from "./enums/trainer-slot";
|
||||||
import { trainerConfigs } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
||||||
import type TrainerData from "#app/system/trainer-data";
|
import type TrainerData from "#app/system/trainer-data";
|
||||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||||
|
@ -5,7 +5,7 @@ import Trainer, { TrainerVariant } from "./field/trainer";
|
|||||||
import type { GameMode } from "./game-mode";
|
import type { GameMode } from "./game-mode";
|
||||||
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
|
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
|
||||||
import type { PokeballType } from "#enums/pokeball";
|
import type { PokeballType } from "#enums/pokeball";
|
||||||
import { trainerConfigs } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
import { SpeciesFormKey } from "#enums/species-form-key";
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
import type { EnemyPokemon, PlayerPokemon, TurnMove } from "#app/field/pokemon";
|
import type { EnemyPokemon, PlayerPokemon, TurnMove } from "#app/field/pokemon";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
|
@ -1734,6 +1734,62 @@ export class PostAttackAbAttr extends AbAttr {
|
|||||||
args: any[]): void {}
|
args: any[]): void {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies a Stat from an ally pokemon's ability.
|
||||||
|
* @see {@link applyAllyStatMultiplierAbAttrs}
|
||||||
|
* @see {@link applyAllyStat}
|
||||||
|
*/
|
||||||
|
export class AllyStatMultiplierAbAttr extends AbAttr {
|
||||||
|
private stat: BattleStat;
|
||||||
|
private multiplier: number;
|
||||||
|
private ignorable: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param stat - The stat being modified
|
||||||
|
* @param multipler - The multiplier to apply to the stat
|
||||||
|
* @param ignorable - Whether the multiplier can be ignored by mold breaker-like moves and abilities
|
||||||
|
*/
|
||||||
|
constructor(stat: BattleStat, multiplier: number, ignorable: boolean = true) {
|
||||||
|
super(false);
|
||||||
|
|
||||||
|
this.stat = stat;
|
||||||
|
this.multiplier = multiplier;
|
||||||
|
this.ignorable = ignorable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply a Pokemon's Stat due to an Ally's ability.
|
||||||
|
* @param _pokemon - The ally {@linkcode Pokemon} with the ability (unused)
|
||||||
|
* @param passive - unused
|
||||||
|
* @param _simulated - Whether the ability is being simulated (unused)
|
||||||
|
* @param _stat - The type of the checked {@linkcode Stat} (unused)
|
||||||
|
* @param statValue - {@linkcode Utils.NumberHolder} containing the value of the checked stat
|
||||||
|
* @param _checkedPokemon - The {@linkcode Pokemon} this ability is targeting (unused)
|
||||||
|
* @param _ignoreAbility - Whether the ability should be ignored if possible
|
||||||
|
* @param _args - unused
|
||||||
|
* @returns `true` if this changed the checked stat, `false` otherwise.
|
||||||
|
*/
|
||||||
|
applyAllyStat(_pokemon: Pokemon, _passive: boolean, _simulated: boolean, _stat: BattleStat, statValue: Utils.NumberHolder, _checkedPokemon: Pokemon, _ignoreAbility: boolean, _args: any[]) {
|
||||||
|
statValue.value *= this.multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this ability can apply to the checked stat.
|
||||||
|
* @param pokemon - The ally {@linkcode Pokemon} with the ability (unused)
|
||||||
|
* @param passive - unused
|
||||||
|
* @param simulated - Whether the ability is being simulated (unused)
|
||||||
|
* @param stat - The type of the checked {@linkcode Stat}
|
||||||
|
* @param statValue - {@linkcode Utils.NumberHolder} containing the value of the checked stat
|
||||||
|
* @param checkedPokemon - The {@linkcode Pokemon} this ability is targeting (unused)
|
||||||
|
* @param ignoreAbility - Whether the ability should be ignored if possible
|
||||||
|
* @param args - unused
|
||||||
|
* @returns `true` if this can apply to the checked stat, `false` otherwise.
|
||||||
|
*/
|
||||||
|
canApplyAllyStat(pokemon: Pokemon, _passive: boolean, simulated: boolean, stat: BattleStat, statValue: Utils.NumberHolder, checkedPokemon: Pokemon, ignoreAbility: boolean, args: any[]): boolean {
|
||||||
|
return stat === this.stat && !(ignoreAbility && this.ignorable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ability attribute for Gorilla Tactics
|
* Ability attribute for Gorilla Tactics
|
||||||
* @extends PostAttackAbAttr
|
* @extends PostAttackAbAttr
|
||||||
@ -5598,6 +5654,30 @@ export function applyStatMultiplierAbAttrs(
|
|||||||
args,
|
args,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies an ally's Stat multiplier attribute
|
||||||
|
* @param attrType - {@linkcode AllyStatMultiplierAbAttr} should always be AllyStatMultiplierAbAttr for the time being
|
||||||
|
* @param pokemon - The {@linkcode Pokemon} with the ability
|
||||||
|
* @param stat - The type of the checked {@linkcode Stat}
|
||||||
|
* @param statValue - {@linkcode Utils.NumberHolder} containing the value of the checked stat
|
||||||
|
* @param checkedPokemon - The {@linkcode Pokemon} with the checked stat
|
||||||
|
* @param ignoreAbility - Whether or not the ability should be ignored by the pokemon or its move.
|
||||||
|
* @param args - unused
|
||||||
|
*/
|
||||||
|
export function applyAllyStatMultiplierAbAttrs(attrType: Constructor<AllyStatMultiplierAbAttr>,
|
||||||
|
pokemon: Pokemon, stat: BattleStat, statValue: Utils.NumberHolder, simulated: boolean = false, checkedPokemon: Pokemon, ignoreAbility: boolean, ...args: any[]
|
||||||
|
): void {
|
||||||
|
return applyAbAttrsInternal<AllyStatMultiplierAbAttr>(
|
||||||
|
attrType,
|
||||||
|
pokemon,
|
||||||
|
(attr, passive) => attr.applyAllyStat(pokemon, passive, simulated, stat, statValue, checkedPokemon, ignoreAbility, args),
|
||||||
|
(attr, passive) => attr.canApplyAllyStat(pokemon, passive, simulated, stat, statValue, checkedPokemon, ignoreAbility, args),
|
||||||
|
args,
|
||||||
|
simulated,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function applyPostSetStatusAbAttrs(
|
export function applyPostSetStatusAbAttrs(
|
||||||
attrType: Constructor<PostSetStatusAbAttr>,
|
attrType: Constructor<PostSetStatusAbAttr>,
|
||||||
pokemon: Pokemon,
|
pokemon: Pokemon,
|
||||||
@ -5610,7 +5690,8 @@ export function applyPostSetStatusAbAttrs(
|
|||||||
attrType,
|
attrType,
|
||||||
pokemon,
|
pokemon,
|
||||||
(attr, passive) => attr.applyPostSetStatus(pokemon, sourcePokemon, passive, effect, simulated, args),
|
(attr, passive) => attr.applyPostSetStatus(pokemon, sourcePokemon, passive, effect, simulated, args),
|
||||||
(attr, passive) => attr.canApplyPostSetStatus(pokemon, sourcePokemon, passive, effect, simulated, args), args,
|
(attr, passive) => attr.canApplyPostSetStatus(pokemon, sourcePokemon, passive, effect, simulated, args),
|
||||||
|
args,
|
||||||
simulated,
|
simulated,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -6441,12 +6522,13 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.FLOWER_GIFT, 4)
|
new Ability(Abilities.FLOWER_GIFT, 4)
|
||||||
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), StatMultiplierAbAttr, Stat.ATK, 1.5)
|
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), StatMultiplierAbAttr, Stat.ATK, 1.5)
|
||||||
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), StatMultiplierAbAttr, Stat.SPDEF, 1.5)
|
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), StatMultiplierAbAttr, Stat.SPDEF, 1.5)
|
||||||
.uncopiable()
|
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), AllyStatMultiplierAbAttr, Stat.ATK, 1.5)
|
||||||
.unreplaceable()
|
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), AllyStatMultiplierAbAttr, Stat.SPDEF, 1.5)
|
||||||
.attr(NoFusionAbilityAbAttr)
|
.attr(NoFusionAbilityAbAttr)
|
||||||
.attr(PostSummonFormChangeByWeatherAbAttr, Abilities.FLOWER_GIFT)
|
.attr(PostSummonFormChangeByWeatherAbAttr, Abilities.FLOWER_GIFT)
|
||||||
.attr(PostWeatherChangeFormChangeAbAttr, Abilities.FLOWER_GIFT, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG, WeatherType.HAIL, WeatherType.HEAVY_RAIN, WeatherType.SNOW, WeatherType.RAIN ])
|
.attr(PostWeatherChangeFormChangeAbAttr, Abilities.FLOWER_GIFT, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG, WeatherType.HAIL, WeatherType.HEAVY_RAIN, WeatherType.SNOW, WeatherType.RAIN ])
|
||||||
.partial() // Should also boosts stats of ally
|
.uncopiable()
|
||||||
|
.unreplaceable()
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.BAD_DREAMS, 4)
|
new Ability(Abilities.BAD_DREAMS, 4)
|
||||||
.attr(PostTurnHurtIfSleepingAbAttr),
|
.attr(PostTurnHurtIfSleepingAbAttr),
|
||||||
@ -6581,7 +6663,7 @@ export function initAbilities() {
|
|||||||
.bypassFaint(),
|
.bypassFaint(),
|
||||||
new Ability(Abilities.VICTORY_STAR, 5)
|
new Ability(Abilities.VICTORY_STAR, 5)
|
||||||
.attr(StatMultiplierAbAttr, Stat.ACC, 1.1)
|
.attr(StatMultiplierAbAttr, Stat.ACC, 1.1)
|
||||||
.partial(), // Does not boost ally's accuracy
|
.attr(AllyStatMultiplierAbAttr, Stat.ACC, 1.1, false),
|
||||||
new Ability(Abilities.TURBOBLAZE, 5)
|
new Ability(Abilities.TURBOBLAZE, 5)
|
||||||
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTurboblaze", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
|
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTurboblaze", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
|
||||||
.attr(MoveAbilityBypassAbAttr),
|
.attr(MoveAbilityBypassAbAttr),
|
||||||
|
@ -1644,7 +1644,9 @@ export class ContactDamageProtectedTag extends ProtectedTag {
|
|||||||
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
|
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
|
||||||
const attacker = effectPhase.getPokemon();
|
const attacker = effectPhase.getPokemon();
|
||||||
if (!attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
if (!attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
||||||
attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), { result: HitResult.INDIRECT });
|
attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), {
|
||||||
|
result: HitResult.INDIRECT,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1970,7 +1972,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
|
|||||||
|
|
||||||
let highestStat: EffectiveStat;
|
let highestStat: EffectiveStat;
|
||||||
EFFECTIVE_STATS.map(s =>
|
EFFECTIVE_STATS.map(s =>
|
||||||
pokemon.getEffectiveStat(s, undefined, undefined, undefined, undefined, undefined, undefined, true),
|
pokemon.getEffectiveStat(s, undefined, undefined, undefined, undefined, undefined, undefined, undefined, true),
|
||||||
).reduce((highestValue: number, value: number, i: number) => {
|
).reduce((highestValue: number, value: number, i: number) => {
|
||||||
if (value > highestValue) {
|
if (value > highestValue) {
|
||||||
highestStat = EFFECTIVE_STATS[i];
|
highestStat = EFFECTIVE_STATS[i];
|
||||||
@ -2149,6 +2151,21 @@ export class TypeBoostTag extends BattlerTag {
|
|||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override onAdd(pokemon: Pokemon): void {
|
||||||
|
globalScene.queueMessage(
|
||||||
|
i18next.t("abilityTriggers:typeImmunityPowerBoost", {
|
||||||
|
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||||
|
typeName: i18next.t(`pokemonInfo:Type.${PokemonType[this.boostedType]}`),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
override onOverlap(pokemon: Pokemon): void {
|
||||||
|
globalScene.queueMessage(
|
||||||
|
i18next.t("abilityTriggers:moveImmunity", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CritBoostTag extends BattlerTag {
|
export class CritBoostTag extends BattlerTag {
|
||||||
@ -2240,7 +2257,9 @@ export class SaltCuredTag extends BattlerTag {
|
|||||||
|
|
||||||
if (!cancelled.value) {
|
if (!cancelled.value) {
|
||||||
const pokemonSteelOrWater = pokemon.isOfType(PokemonType.STEEL) || pokemon.isOfType(PokemonType.WATER);
|
const pokemonSteelOrWater = pokemon.isOfType(PokemonType.STEEL) || pokemon.isOfType(PokemonType.WATER);
|
||||||
pokemon.damageAndUpdate(toDmgValue(pokemonSteelOrWater ? pokemon.getMaxHp() / 4 : pokemon.getMaxHp() / 8), { result: HitResult.INDIRECT });
|
pokemon.damageAndUpdate(toDmgValue(pokemonSteelOrWater ? pokemon.getMaxHp() / 4 : pokemon.getMaxHp() / 8), {
|
||||||
|
result: HitResult.INDIRECT,
|
||||||
|
});
|
||||||
|
|
||||||
globalScene.queueMessage(
|
globalScene.queueMessage(
|
||||||
i18next.t("battlerTags:saltCuredLapse", {
|
i18next.t("battlerTags:saltCuredLapse", {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { BattleSpec } from "#enums/battle-spec";
|
import { BattleSpec } from "#enums/battle-spec";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { trainerConfigs } from "./trainer-config";
|
import { trainerConfigs } from "./trainers/trainer-config";
|
||||||
|
|
||||||
export interface TrainerTypeMessages {
|
export interface TrainerTypeMessages {
|
||||||
encounter?: string | string[];
|
encounter?: string | string[];
|
||||||
|
@ -902,7 +902,7 @@ export default class Move implements Localizable {
|
|||||||
SacrificialAttrOnHit
|
SacrificialAttrOnHit
|
||||||
];
|
];
|
||||||
|
|
||||||
// ...and cannot enhance these specific moves.
|
// ...and cannot enhance these specific moves
|
||||||
const exceptMoves: Moves[] = [
|
const exceptMoves: Moves[] = [
|
||||||
Moves.FLING,
|
Moves.FLING,
|
||||||
Moves.UPROAR,
|
Moves.UPROAR,
|
||||||
@ -911,10 +911,14 @@ export default class Move implements Localizable {
|
|||||||
Moves.ENDEAVOR
|
Moves.ENDEAVOR
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// ...and cannot enhance Pollen Puff when targeting an ally.
|
||||||
|
const exceptPollenPuffAlly: boolean = this.id === Moves.POLLEN_PUFF && targets.includes(user.getAlly().getBattlerIndex())
|
||||||
|
|
||||||
return (!restrictSpread || !isMultiTarget)
|
return (!restrictSpread || !isMultiTarget)
|
||||||
&& !this.isChargingMove()
|
&& !this.isChargingMove()
|
||||||
&& !exceptAttrs.some(attr => this.hasAttr(attr))
|
&& !exceptAttrs.some(attr => this.hasAttr(attr))
|
||||||
&& !exceptMoves.some(id => this.id === id)
|
&& !exceptMoves.some(id => this.id === id)
|
||||||
|
&& !exceptPollenPuffAlly
|
||||||
&& this.category !== MoveCategory.STATUS;
|
&& this.category !== MoveCategory.STATUS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1577,10 +1581,6 @@ export class SurviveDamageAttr extends ModifiedDamageAttr {
|
|||||||
return Math.min(damage, target.hp - 1);
|
return Math.min(damage, target.hp - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCondition(): MoveConditionFunc {
|
|
||||||
return (user, target, move) => target.hp > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
|
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
|
||||||
return target.hp > 1 ? 0 : -20;
|
return target.hp > 1 ? 0 : -20;
|
||||||
}
|
}
|
||||||
@ -4795,8 +4795,8 @@ export class ShellSideArmCategoryAttr extends VariableMoveCategoryAttr {
|
|||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const category = (args[0] as Utils.NumberHolder);
|
const category = (args[0] as Utils.NumberHolder);
|
||||||
|
|
||||||
const predictedPhysDmg = target.getBaseDamage(user, move, MoveCategory.PHYSICAL, true, true);
|
const predictedPhysDmg = target.getBaseDamage(user, move, MoveCategory.PHYSICAL, true, true, true, true);
|
||||||
const predictedSpecDmg = target.getBaseDamage(user, move, MoveCategory.SPECIAL, true, true);
|
const predictedSpecDmg = target.getBaseDamage(user, move, MoveCategory.SPECIAL, true, true, true, true);
|
||||||
|
|
||||||
if (predictedPhysDmg > predictedSpecDmg) {
|
if (predictedPhysDmg > predictedSpecDmg) {
|
||||||
category.value = MoveCategory.PHYSICAL;
|
category.value = MoveCategory.PHYSICAL;
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
setEncounterRewards,
|
setEncounterRewards,
|
||||||
transitionMysteryEncounterIntroVisuals,
|
transitionMysteryEncounterIntroVisuals,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { trainerConfigs } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
|
@ -31,7 +31,7 @@ import {
|
|||||||
catchPokemon,
|
catchPokemon,
|
||||||
getHighestLevelPlayerPokemon,
|
getHighestLevelPlayerPokemon,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
import type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||||
import type { BerryType } from "#enums/berry-type";
|
import type { BerryType } from "#enums/berry-type";
|
||||||
|
@ -9,13 +9,10 @@ import {
|
|||||||
setEncounterRewards,
|
setEncounterRewards,
|
||||||
transitionMysteryEncounterIntroVisuals,
|
transitionMysteryEncounterIntroVisuals,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import {
|
import { getRandomPartyMemberFunc, trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
getRandomPartyMemberFunc,
|
import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
trainerConfigs,
|
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
TrainerPartyCompoundTemplate,
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
TrainerPartyTemplate,
|
|
||||||
TrainerSlot,
|
|
||||||
} from "#app/data/trainer-config";
|
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
|
@ -8,7 +8,9 @@ import {
|
|||||||
setEncounterRewards,
|
setEncounterRewards,
|
||||||
transitionMysteryEncounterIntroVisuals,
|
transitionMysteryEncounterIntroVisuals,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { trainerConfigs, TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
|
import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
|
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||||
import { ModifierPoolType, modifierTypes } from "#app/modifier/modifier-type";
|
import { ModifierPoolType, modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
@ -20,7 +20,7 @@ import {
|
|||||||
STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER,
|
STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import type { PlayerPokemon } from "#app/field/pokemon";
|
import type { PlayerPokemon } from "#app/field/pokemon";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
|
import { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
|
@ -10,7 +10,7 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import type { PlayerPokemon } from "#app/field/pokemon";
|
import type { PlayerPokemon } from "#app/field/pokemon";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { FieldPosition } from "#app/field/pokemon";
|
import { FieldPosition } from "#app/field/pokemon";
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
selectPokemonForOption,
|
selectPokemonForOption,
|
||||||
setEncounterRewards,
|
setEncounterRewards,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { MusicPreference } from "#app/system/settings/settings";
|
import { MusicPreference } from "#app/system/settings/settings";
|
||||||
import type { ModifierTypeOption } from "#app/modifier/modifier-type";
|
import type { ModifierTypeOption } from "#app/modifier/modifier-type";
|
||||||
|
@ -3,12 +3,10 @@ import {
|
|||||||
initBattleWithEnemyConfig,
|
initBattleWithEnemyConfig,
|
||||||
setEncounterRewards,
|
setEncounterRewards,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import {
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
trainerConfigs,
|
import { trainerPartyTemplates } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
TrainerPartyCompoundTemplate,
|
import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
TrainerPartyTemplate,
|
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
trainerPartyTemplates,
|
|
||||||
} from "#app/data/trainer-config";
|
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
@ -10,7 +10,7 @@ import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounte
|
|||||||
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
import type MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
|
import type MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { HiddenAbilityRateBoosterModifier, IvScannerModifier } from "#app/modifier/modifier";
|
import { HiddenAbilityRateBoosterModifier, IvScannerModifier } from "#app/modifier/modifier";
|
||||||
import type { EnemyPokemon } from "#app/field/pokemon";
|
import type { EnemyPokemon } from "#app/field/pokemon";
|
||||||
import { PokeballType } from "#enums/pokeball";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
|
@ -24,7 +24,7 @@ import { Biome } from "#enums/biome";
|
|||||||
import { getBiomeKey } from "#app/field/arena";
|
import { getBiomeKey } from "#app/field/arena";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { getPartyLuckValue, modifierTypes } from "#app/modifier/modifier-type";
|
import { getPartyLuckValue, modifierTypes } from "#app/modifier/modifier-type";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
initBattleWithEnemyConfig,
|
initBattleWithEnemyConfig,
|
||||||
setEncounterRewards,
|
setEncounterRewards,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { trainerConfigs } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { randSeedShuffle } from "#app/utils";
|
import { randSeedShuffle } from "#app/utils";
|
||||||
@ -30,7 +30,6 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode
|
|||||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { getPokeballTintColor } from "#app/data/pokeball";
|
import { getPokeballTintColor } from "#app/data/pokeball";
|
||||||
import type { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/theExpertPokemonBreeder";
|
const namespace = "mysteryEncounters/theExpertPokemonBreeder";
|
||||||
|
@ -41,7 +41,8 @@ import { TrainerType } from "#enums/trainer-type";
|
|||||||
import PokemonData from "#app/system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { Nature } from "#enums/nature";
|
import { Nature } from "#enums/nature";
|
||||||
import type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
import type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||||
import { trainerConfigs, TrainerPartyTemplate } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
|
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
|
@ -332,7 +332,6 @@ export function initMysteryEncounters() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Add ANY biome encounters to biome map
|
// Add ANY biome encounters to biome map
|
||||||
// eslint-disable-next-line
|
|
||||||
let _encounterBiomeTableLog = "";
|
let _encounterBiomeTableLog = "";
|
||||||
mysteryEncountersByBiome.forEach((biomeEncounters, biome) => {
|
mysteryEncountersByBiome.forEach((biomeEncounters, biome) => {
|
||||||
anyBiomeEncounters.forEach(encounter => {
|
anyBiomeEncounters.forEach(encounter => {
|
||||||
|
@ -43,8 +43,9 @@ import type { Moves } from "#enums/moves";
|
|||||||
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
|
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
|
||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
import { Status } from "#app/data/status-effect";
|
import { Status } from "#app/data/status-effect";
|
||||||
import type { TrainerConfig } from "#app/data/trainer-config";
|
import type { TrainerConfig } from "#app/data/trainers/trainer-config";
|
||||||
import { trainerConfigs, TrainerSlot } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
import type PokemonSpecies from "#app/data/pokemon-species";
|
||||||
import type { IEggOptions } from "#app/data/egg";
|
import type { IEggOptions } from "#app/data/egg";
|
||||||
import { Egg } from "#app/data/egg";
|
import { Egg } from "#app/data/egg";
|
||||||
|
@ -7,7 +7,7 @@ import i18next from "i18next";
|
|||||||
import type { AnySound } from "#app/battle-scene";
|
import type { AnySound } from "#app/battle-scene";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type { GameMode } from "#app/game-mode";
|
import type { GameMode } from "#app/game-mode";
|
||||||
import { DexAttr, DexEntry, type StarterMoveset } from "#app/system/game-data";
|
import { DexAttr, type StarterMoveset } from "#app/system/game-data";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import { uncatchableSpecies } from "#app/data/balance/biomes";
|
import { uncatchableSpecies } from "#app/data/balance/biomes";
|
||||||
import { speciesEggMoves } from "#app/data/balance/egg-moves";
|
import { speciesEggMoves } from "#app/data/balance/egg-moves";
|
||||||
|
@ -214,7 +214,7 @@ const commonSplashMessages = [
|
|||||||
"bornToBeAWinner",
|
"bornToBeAWinner",
|
||||||
"onARollout",
|
"onARollout",
|
||||||
"itsAlwaysNightDeepInTheAbyss",
|
"itsAlwaysNightDeepInTheAbyss",
|
||||||
"folksThisIsInsane"
|
"folksThisIsInsane",
|
||||||
];
|
];
|
||||||
|
|
||||||
//#region Seasonal Messages
|
//#region Seasonal Messages
|
||||||
@ -224,10 +224,7 @@ const seasonalSplashMessages: Season[] = [
|
|||||||
name: "New Year's",
|
name: "New Year's",
|
||||||
start: "01-01",
|
start: "01-01",
|
||||||
end: "01-15",
|
end: "01-15",
|
||||||
messages: [
|
messages: ["newYears.happyNewYear", "newYears.andAHappyNewYear"],
|
||||||
"newYears.happyNewYear",
|
|
||||||
"newYears.andAHappyNewYear"
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Valentines",
|
name: "Valentines",
|
||||||
@ -239,7 +236,7 @@ const seasonalSplashMessages: Season[] = [
|
|||||||
"valentines.applinForYou",
|
"valentines.applinForYou",
|
||||||
"valentines.thePowerOfLoveIsThreeThirtyBST",
|
"valentines.thePowerOfLoveIsThreeThirtyBST",
|
||||||
"valentines.haveAHeartScale",
|
"valentines.haveAHeartScale",
|
||||||
"valentines.i<3You"
|
"valentines.i<3You",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -279,7 +276,7 @@ const seasonalSplashMessages: Season[] = [
|
|||||||
"aprilFools.nowWithQuickTimeEncounters",
|
"aprilFools.nowWithQuickTimeEncounters",
|
||||||
"aprilFools.timeYourInputsForHigherCatchrate",
|
"aprilFools.timeYourInputsForHigherCatchrate",
|
||||||
"aprilFools.certifiedButtonSimulator",
|
"aprilFools.certifiedButtonSimulator",
|
||||||
"aprilFools.iHopeYouGetSuckerPunched"
|
"aprilFools.iHopeYouGetSuckerPunched",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -293,7 +290,7 @@ const seasonalSplashMessages: Season[] = [
|
|||||||
"halloween.mayContainSpiders",
|
"halloween.mayContainSpiders",
|
||||||
"halloween.spookyScarySkeledirge",
|
"halloween.spookyScarySkeledirge",
|
||||||
"halloween.gourgeistUsedTrickOrTreat",
|
"halloween.gourgeistUsedTrickOrTreat",
|
||||||
"halloween.letsSnuggleForever"
|
"halloween.letsSnuggleForever",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -316,7 +313,7 @@ const seasonalSplashMessages: Season[] = [
|
|||||||
"winterHoliday.tisTheSeasonToBeSpeSpa",
|
"winterHoliday.tisTheSeasonToBeSpeSpa",
|
||||||
"winterHoliday.deckTheHalls",
|
"winterHoliday.deckTheHalls",
|
||||||
"winterHoliday.saveScummingGetsYouOnTheNaughtyList",
|
"winterHoliday.saveScummingGetsYouOnTheNaughtyList",
|
||||||
"winterHoliday.badTrainersGetRolycoly"
|
"winterHoliday.badTrainersGetRolycoly",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
255
src/data/trainers/TrainerPartyTemplate.ts
Normal file
255
src/data/trainers/TrainerPartyTemplate.ts
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
import { startingWave } from "#app/battle-scene";
|
||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
|
|
||||||
|
export class TrainerPartyTemplate {
|
||||||
|
public size: number;
|
||||||
|
public strength: PartyMemberStrength;
|
||||||
|
public sameSpecies: boolean;
|
||||||
|
public balanced: boolean;
|
||||||
|
|
||||||
|
constructor(size: number, strength: PartyMemberStrength, sameSpecies?: boolean, balanced?: boolean) {
|
||||||
|
this.size = size;
|
||||||
|
this.strength = strength;
|
||||||
|
this.sameSpecies = !!sameSpecies;
|
||||||
|
this.balanced = !!balanced;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStrength(_index: number): PartyMemberStrength {
|
||||||
|
return this.strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
isSameSpecies(_index: number): boolean {
|
||||||
|
return this.sameSpecies;
|
||||||
|
}
|
||||||
|
|
||||||
|
isBalanced(_index: number): boolean {
|
||||||
|
return this.balanced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TrainerPartyCompoundTemplate extends TrainerPartyTemplate {
|
||||||
|
public templates: TrainerPartyTemplate[];
|
||||||
|
|
||||||
|
constructor(...templates: TrainerPartyTemplate[]) {
|
||||||
|
super(
|
||||||
|
templates.reduce((total: number, template: TrainerPartyTemplate) => {
|
||||||
|
total += template.size;
|
||||||
|
return total;
|
||||||
|
}, 0),
|
||||||
|
PartyMemberStrength.AVERAGE,
|
||||||
|
);
|
||||||
|
this.templates = templates;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStrength(index: number): PartyMemberStrength {
|
||||||
|
let t = 0;
|
||||||
|
for (const template of this.templates) {
|
||||||
|
if (t + template.size > index) {
|
||||||
|
return template.getStrength(index - t);
|
||||||
|
}
|
||||||
|
t += template.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getStrength(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
isSameSpecies(index: number): boolean {
|
||||||
|
let t = 0;
|
||||||
|
for (const template of this.templates) {
|
||||||
|
if (t + template.size > index) {
|
||||||
|
return template.isSameSpecies(index - t);
|
||||||
|
}
|
||||||
|
t += template.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.isSameSpecies(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
isBalanced(index: number): boolean {
|
||||||
|
let t = 0;
|
||||||
|
for (const template of this.templates) {
|
||||||
|
if (t + template.size > index) {
|
||||||
|
return template.isBalanced(index - t);
|
||||||
|
}
|
||||||
|
t += template.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.isBalanced(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const trainerPartyTemplates = {
|
||||||
|
ONE_WEAK_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.WEAK),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
),
|
||||||
|
ONE_AVG: new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
ONE_AVG_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
),
|
||||||
|
ONE_STRONG: new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
ONE_STRONGER: new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
||||||
|
TWO_WEAKER: new TrainerPartyTemplate(2, PartyMemberStrength.WEAKER),
|
||||||
|
TWO_WEAK: new TrainerPartyTemplate(2, PartyMemberStrength.WEAK),
|
||||||
|
TWO_WEAK_ONE_AVG: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
),
|
||||||
|
TWO_WEAK_SAME_ONE_AVG: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
),
|
||||||
|
TWO_WEAK_SAME_TWO_WEAK_SAME: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true),
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true),
|
||||||
|
),
|
||||||
|
TWO_WEAK_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
),
|
||||||
|
TWO_AVG: new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
||||||
|
TWO_AVG_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
),
|
||||||
|
TWO_AVG_SAME_ONE_AVG: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
),
|
||||||
|
TWO_AVG_SAME_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
),
|
||||||
|
TWO_AVG_SAME_TWO_AVG_SAME: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true),
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true),
|
||||||
|
),
|
||||||
|
TWO_STRONG: new TrainerPartyTemplate(2, PartyMemberStrength.STRONG),
|
||||||
|
THREE_WEAK: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK),
|
||||||
|
THREE_WEAK_SAME: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK, true),
|
||||||
|
THREE_AVG: new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE),
|
||||||
|
THREE_AVG_SAME: new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, true),
|
||||||
|
THREE_WEAK_BALANCED: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK, false, true),
|
||||||
|
FOUR_WEAKER: new TrainerPartyTemplate(4, PartyMemberStrength.WEAKER),
|
||||||
|
FOUR_WEAKER_SAME: new TrainerPartyTemplate(4, PartyMemberStrength.WEAKER, true),
|
||||||
|
FOUR_WEAK: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK),
|
||||||
|
FOUR_WEAK_SAME: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK, true),
|
||||||
|
FOUR_WEAK_BALANCED: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK, false, true),
|
||||||
|
FIVE_WEAKER: new TrainerPartyTemplate(5, PartyMemberStrength.WEAKER),
|
||||||
|
FIVE_WEAK: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK),
|
||||||
|
FIVE_WEAK_BALANCED: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK, false, true),
|
||||||
|
SIX_WEAKER: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER),
|
||||||
|
SIX_WEAKER_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER, true),
|
||||||
|
SIX_WEAK_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, true),
|
||||||
|
SIX_WEAK_BALANCED: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, false, true),
|
||||||
|
|
||||||
|
GYM_LEADER_1: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
),
|
||||||
|
GYM_LEADER_2: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
||||||
|
),
|
||||||
|
GYM_LEADER_3: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
||||||
|
),
|
||||||
|
GYM_LEADER_4: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
||||||
|
),
|
||||||
|
GYM_LEADER_5: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
||||||
|
),
|
||||||
|
|
||||||
|
ELITE_FOUR: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(3, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
||||||
|
),
|
||||||
|
|
||||||
|
CHAMPION: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(4, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.STRONGER, false, true),
|
||||||
|
),
|
||||||
|
|
||||||
|
RIVAL: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
),
|
||||||
|
RIVAL_2: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true),
|
||||||
|
),
|
||||||
|
RIVAL_3: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE, false, true),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true),
|
||||||
|
),
|
||||||
|
RIVAL_4: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, false, true),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true),
|
||||||
|
),
|
||||||
|
RIVAL_5: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
),
|
||||||
|
RIVAL_6: new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
||||||
|
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function to get variable strength grunts
|
||||||
|
* @returns the correct TrainerPartyTemplate
|
||||||
|
*/
|
||||||
|
export function getEvilGruntPartyTemplate(): TrainerPartyTemplate {
|
||||||
|
const waveIndex = globalScene.currentBattle?.waveIndex;
|
||||||
|
if (waveIndex < 40) {
|
||||||
|
return trainerPartyTemplates.TWO_AVG;
|
||||||
|
}
|
||||||
|
if (waveIndex < 63) {
|
||||||
|
return trainerPartyTemplates.THREE_AVG;
|
||||||
|
}
|
||||||
|
if (waveIndex < 65) {
|
||||||
|
return trainerPartyTemplates.TWO_AVG_ONE_STRONG;
|
||||||
|
}
|
||||||
|
if (waveIndex < 112) {
|
||||||
|
return trainerPartyTemplates.GYM_LEADER_4; // 3avg 1 strong 1 stronger
|
||||||
|
}
|
||||||
|
return trainerPartyTemplates.GYM_LEADER_5; // 3 avg 2 strong 1 stronger
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWavePartyTemplate(...templates: TrainerPartyTemplate[]) {
|
||||||
|
const { currentBattle, gameMode } = globalScene;
|
||||||
|
const wave = gameMode.getWaveForDifficulty(currentBattle?.waveIndex || startingWave, true);
|
||||||
|
const templateIndex = Math.ceil((wave - 20) / 30);
|
||||||
|
return templates[Phaser.Math.Clamp(templateIndex, 0, templates.length - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGymLeaderPartyTemplate() {
|
||||||
|
return getWavePartyTemplate(
|
||||||
|
trainerPartyTemplates.GYM_LEADER_1,
|
||||||
|
trainerPartyTemplates.GYM_LEADER_2,
|
||||||
|
trainerPartyTemplates.GYM_LEADER_3,
|
||||||
|
trainerPartyTemplates.GYM_LEADER_4,
|
||||||
|
trainerPartyTemplates.GYM_LEADER_5,
|
||||||
|
);
|
||||||
|
}
|
436
src/data/trainers/evil-admin-trainer-pools.ts
Normal file
436
src/data/trainers/evil-admin-trainer-pools.ts
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
import type { TrainerTierPools } from "#app/data/trainers/typedefs";
|
||||||
|
import { TrainerPoolTier } from "#enums/trainer-pool-tier";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
|
||||||
|
/** Team Rocket's admin trainer pool. */
|
||||||
|
const ROCKET: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.RATICATE,
|
||||||
|
Species.ARBOK,
|
||||||
|
Species.VILEPLUME,
|
||||||
|
Species.ARCANINE,
|
||||||
|
Species.GENGAR,
|
||||||
|
Species.HYPNO,
|
||||||
|
Species.ELECTRODE,
|
||||||
|
Species.EXEGGUTOR,
|
||||||
|
Species.CUBONE,
|
||||||
|
Species.KOFFING,
|
||||||
|
Species.GYARADOS,
|
||||||
|
Species.CROBAT,
|
||||||
|
Species.STEELIX,
|
||||||
|
Species.HOUNDOOM,
|
||||||
|
Species.HONCHKROW,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.OMASTAR,
|
||||||
|
Species.KABUTOPS,
|
||||||
|
Species.MAGNEZONE,
|
||||||
|
Species.ELECTIVIRE,
|
||||||
|
Species.MAGMORTAR,
|
||||||
|
Species.PORYGON_Z,
|
||||||
|
Species.ANNIHILAPE,
|
||||||
|
Species.ALOLA_SANDSLASH,
|
||||||
|
Species.ALOLA_PERSIAN,
|
||||||
|
Species.ALOLA_GOLEM,
|
||||||
|
Species.ALOLA_MUK,
|
||||||
|
Species.PALDEA_TAUROS,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.DRAGONITE, Species.TYRANITAR],
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Team Magma's admin trainer pool */
|
||||||
|
const MAGMA: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.ARCANINE,
|
||||||
|
Species.MAGCARGO,
|
||||||
|
Species.HOUNDOOM,
|
||||||
|
Species.TORKOAL,
|
||||||
|
Species.SOLROCK,
|
||||||
|
Species.CLAYDOL,
|
||||||
|
Species.HIPPOWDON,
|
||||||
|
Species.MAGMORTAR,
|
||||||
|
Species.GLISCOR,
|
||||||
|
Species.COALOSSAL,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.AGGRON,
|
||||||
|
Species.FLYGON,
|
||||||
|
Species.CRADILY,
|
||||||
|
Species.ARMALDO,
|
||||||
|
Species.RHYPERIOR,
|
||||||
|
Species.TURTONATOR,
|
||||||
|
Species.SANDACONDA,
|
||||||
|
Species.TOEDSCRUEL,
|
||||||
|
Species.HISUI_ARCANINE,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.CHARCADET, Species.SCOVILLAIN],
|
||||||
|
};
|
||||||
|
|
||||||
|
const AQUA: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.TENTACRUEL,
|
||||||
|
Species.LANTURN,
|
||||||
|
Species.AZUMARILL,
|
||||||
|
Species.QUAGSIRE,
|
||||||
|
Species.OCTILLERY,
|
||||||
|
Species.LUDICOLO,
|
||||||
|
Species.PELIPPER,
|
||||||
|
Species.WAILORD,
|
||||||
|
Species.WHISCASH,
|
||||||
|
Species.CRAWDAUNT,
|
||||||
|
Species.WALREIN,
|
||||||
|
Species.CLAMPERL,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.QUAGSIRE,
|
||||||
|
Species.MANTINE,
|
||||||
|
Species.KINGDRA,
|
||||||
|
Species.MILOTIC,
|
||||||
|
Species.DRAGALGE,
|
||||||
|
Species.DHELMISE,
|
||||||
|
Species.BARRASKEWDA,
|
||||||
|
Species.GRAPPLOCT,
|
||||||
|
Species.OVERQWIL,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.BASCULEGION, Species.DONDOZO],
|
||||||
|
};
|
||||||
|
|
||||||
|
const GALACTIC: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.ELECTRODE,
|
||||||
|
Species.GYARADOS,
|
||||||
|
Species.CROBAT,
|
||||||
|
Species.HONCHKROW,
|
||||||
|
Species.BRONZONG,
|
||||||
|
Species.DRAPION,
|
||||||
|
Species.LICKILICKY,
|
||||||
|
Species.TANGROWTH,
|
||||||
|
Species.ELECTIVIRE,
|
||||||
|
Species.MAGMORTAR,
|
||||||
|
Species.YANMEGA,
|
||||||
|
Species.MAMOSWINE,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.ALAKAZAM,
|
||||||
|
Species.WEAVILE,
|
||||||
|
Species.GLISCOR,
|
||||||
|
Species.DUSKNOIR,
|
||||||
|
Species.ROTOM,
|
||||||
|
Species.OVERQWIL,
|
||||||
|
Species.HISUI_ARCANINE,
|
||||||
|
Species.HISUI_ELECTRODE,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.SPIRITOMB, Species.URSALUNA, Species.SNEASLER, Species.HISUI_LILLIGANT],
|
||||||
|
};
|
||||||
|
|
||||||
|
const PLASMA_ZINZOLIN: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.GIGALITH,
|
||||||
|
Species.CONKELDURR,
|
||||||
|
Species.SEISMITOAD,
|
||||||
|
Species.KROOKODILE,
|
||||||
|
Species.DARMANITAN,
|
||||||
|
Species.COFAGRIGUS,
|
||||||
|
Species.VANILLUXE,
|
||||||
|
Species.AMOONGUSS,
|
||||||
|
Species.JELLICENT,
|
||||||
|
Species.GALVANTULA,
|
||||||
|
Species.FERROTHORN,
|
||||||
|
Species.BEARTIC,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.EXCADRILL,
|
||||||
|
Species.SIGILYPH,
|
||||||
|
Species.ZOROARK,
|
||||||
|
Species.KLINKLANG,
|
||||||
|
Species.EELEKTROSS,
|
||||||
|
Species.MIENSHAO,
|
||||||
|
Species.GOLURK,
|
||||||
|
Species.BISHARP,
|
||||||
|
Species.MANDIBUZZ,
|
||||||
|
Species.DURANT,
|
||||||
|
Species.GALAR_DARMANITAN,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.HAXORUS, Species.HYDREIGON, Species.HISUI_ZOROARK, Species.HISUI_BRAVIARY],
|
||||||
|
};
|
||||||
|
|
||||||
|
const PLASMA_COLRESS: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.MUK,
|
||||||
|
Species.ELECTRODE,
|
||||||
|
Species.BRONZONG,
|
||||||
|
Species.MAGNEZONE,
|
||||||
|
Species.PORYGON_Z,
|
||||||
|
Species.MUSHARNA,
|
||||||
|
Species.REUNICLUS,
|
||||||
|
Species.GALVANTULA,
|
||||||
|
Species.FERROTHORN,
|
||||||
|
Species.EELEKTROSS,
|
||||||
|
Species.BEHEEYEM,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.METAGROSS,
|
||||||
|
Species.ROTOM,
|
||||||
|
Species.CARRACOSTA,
|
||||||
|
Species.ARCHEOPS,
|
||||||
|
Species.GOLURK,
|
||||||
|
Species.DURANT,
|
||||||
|
Species.VIKAVOLT,
|
||||||
|
Species.ORBEETLE,
|
||||||
|
Species.REVAVROOM,
|
||||||
|
Species.ALOLA_MUK,
|
||||||
|
Species.HISUI_ELECTRODE,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.ELECTIVIRE, Species.MAGMORTAR, Species.BISHARP, Species.ARCHALUDON],
|
||||||
|
};
|
||||||
|
|
||||||
|
const FLARE: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.MANECTRIC,
|
||||||
|
Species.DRAPION,
|
||||||
|
Species.LIEPARD,
|
||||||
|
Species.AMOONGUSS,
|
||||||
|
Species.DIGGERSBY,
|
||||||
|
Species.TALONFLAME,
|
||||||
|
Species.PYROAR,
|
||||||
|
Species.PANGORO,
|
||||||
|
Species.MEOWSTIC,
|
||||||
|
Species.MALAMAR,
|
||||||
|
Species.CLAWITZER,
|
||||||
|
Species.HELIOLISK,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.HOUNDOOM,
|
||||||
|
Species.WEAVILE,
|
||||||
|
Species.CHANDELURE,
|
||||||
|
Species.AEGISLASH,
|
||||||
|
Species.BARBARACLE,
|
||||||
|
Species.DRAGALGE,
|
||||||
|
Species.GOODRA,
|
||||||
|
Species.TREVENANT,
|
||||||
|
Species.GOURGEIST,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.NOIVERN, Species.HISUI_GOODRA, Species.HISUI_AVALUGG],
|
||||||
|
};
|
||||||
|
|
||||||
|
const AETHER: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.ALAKAZAM,
|
||||||
|
Species.SLOWBRO,
|
||||||
|
Species.EXEGGUTOR,
|
||||||
|
Species.XATU,
|
||||||
|
Species.CLAYDOL,
|
||||||
|
Species.BEHEEYEM,
|
||||||
|
Species.ORANGURU,
|
||||||
|
Species.BRUXISH,
|
||||||
|
Species.ORBEETLE,
|
||||||
|
Species.FARIGIRAF,
|
||||||
|
Species.ALOLA_RAICHU,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.KIRLIA,
|
||||||
|
Species.MEDICHAM,
|
||||||
|
Species.METAGROSS,
|
||||||
|
Species.MALAMAR,
|
||||||
|
Species.HATTERENE,
|
||||||
|
Species.MR_RIME,
|
||||||
|
Species.GALAR_SLOWKING,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.PORYGON_Z, Species.ARMAROUGE, Species.HISUI_BRAVIARY],
|
||||||
|
};
|
||||||
|
|
||||||
|
const SKULL: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.NIDOQUEEN,
|
||||||
|
Species.GENGAR,
|
||||||
|
Species.KOFFING,
|
||||||
|
Species.CROBAT,
|
||||||
|
Species.ROSERADE,
|
||||||
|
Species.SKUNTANK,
|
||||||
|
Species.TOXICROAK,
|
||||||
|
Species.SCOLIPEDE,
|
||||||
|
Species.TOXAPEX,
|
||||||
|
Species.LURANTIS,
|
||||||
|
Species.ALOLA_MUK,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.DRAPION,
|
||||||
|
Species.MANDIBUZZ,
|
||||||
|
Species.OVERQWIL,
|
||||||
|
Species.GLIMMORA,
|
||||||
|
Species.CLODSIRE,
|
||||||
|
Species.GALAR_SLOWBRO,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.DRAGALGE, Species.SNEASLER],
|
||||||
|
};
|
||||||
|
|
||||||
|
const MACRO_COSMOS: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.NINETALES,
|
||||||
|
Species.BELLOSSOM,
|
||||||
|
Species.MILOTIC,
|
||||||
|
Species.FROSLASS,
|
||||||
|
Species.GOTHITELLE,
|
||||||
|
Species.JELLICENT,
|
||||||
|
Species.SALAZZLE,
|
||||||
|
Species.TSAREENA,
|
||||||
|
Species.POLTEAGEIST,
|
||||||
|
Species.HATTERENE,
|
||||||
|
Species.GALAR_RAPIDASH,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.TOGEKISS,
|
||||||
|
Species.MANDIBUZZ,
|
||||||
|
Species.TOXAPEX,
|
||||||
|
Species.APPLETUN,
|
||||||
|
Species.CURSOLA,
|
||||||
|
Species.ALOLA_NINETALES,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.TINKATON, Species.HISUI_LILLIGANT],
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAR_DARK: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.SHIFTRY,
|
||||||
|
Species.CACTURNE,
|
||||||
|
Species.HONCHKROW,
|
||||||
|
Species.SKUNTANK,
|
||||||
|
Species.KROOKODILE,
|
||||||
|
Species.OBSTAGOON,
|
||||||
|
Species.LOKIX,
|
||||||
|
Species.MABOSSTIFF,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.UMBREON,
|
||||||
|
Species.CRAWDAUNT,
|
||||||
|
Species.WEAVILE,
|
||||||
|
Species.ZOROARK,
|
||||||
|
Species.MALAMAR,
|
||||||
|
Species.BOMBIRDIER,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.HYDREIGON, Species.MEOWSCARADA],
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAR_FIRE: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.ARCANINE,
|
||||||
|
Species.HOUNDOOM,
|
||||||
|
Species.CAMERUPT,
|
||||||
|
Species.CHANDELURE,
|
||||||
|
Species.TALONFLAME,
|
||||||
|
Species.PYROAR,
|
||||||
|
Species.COALOSSAL,
|
||||||
|
Species.SCOVILLAIN,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.RAPIDASH,
|
||||||
|
Species.FLAREON,
|
||||||
|
Species.TORKOAL,
|
||||||
|
Species.MAGMORTAR,
|
||||||
|
Species.SALAZZLE,
|
||||||
|
Species.TURTONATOR,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.VOLCARONA, Species.SKELEDIRGE],
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAR_POISON: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.MUK,
|
||||||
|
Species.CROBAT,
|
||||||
|
Species.SKUNTANK,
|
||||||
|
Species.AMOONGUSS,
|
||||||
|
Species.TOXAPEX,
|
||||||
|
Species.TOXTRICITY,
|
||||||
|
Species.GRAFAIAI,
|
||||||
|
Species.CLODSIRE,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.GENGAR,
|
||||||
|
Species.SEVIPER,
|
||||||
|
Species.DRAGALGE,
|
||||||
|
Species.OVERQWIL,
|
||||||
|
Species.ALOLA_MUK,
|
||||||
|
Species.GALAR_SLOWBRO,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.GLIMMORA, Species.VENUSAUR],
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAR_FAIRY: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.CLEFABLE,
|
||||||
|
Species.WIGGLYTUFF,
|
||||||
|
Species.AZUMARILL,
|
||||||
|
Species.WHIMSICOTT,
|
||||||
|
Species.FLORGES,
|
||||||
|
Species.HATTERENE,
|
||||||
|
Species.GRIMMSNARL,
|
||||||
|
Species.TINKATON,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.TOGEKISS,
|
||||||
|
Species.GARDEVOIR,
|
||||||
|
Species.SYLVEON,
|
||||||
|
Species.KLEFKI,
|
||||||
|
Species.MIMIKYU,
|
||||||
|
Species.ALOLA_NINETALES,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.GALAR_RAPIDASH, Species.PRIMARINA],
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAR_FIGHTING: TrainerTierPools = {
|
||||||
|
[TrainerPoolTier.COMMON]: [
|
||||||
|
Species.BRELOOM,
|
||||||
|
Species.HARIYAMA,
|
||||||
|
Species.MEDICHAM,
|
||||||
|
Species.TOXICROAK,
|
||||||
|
Species.SCRAFTY,
|
||||||
|
Species.MIENSHAO,
|
||||||
|
Species.PAWMOT,
|
||||||
|
Species.PALDEA_TAUROS,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.UNCOMMON]: [
|
||||||
|
Species.LUCARIO,
|
||||||
|
Species.CONKELDURR,
|
||||||
|
Species.HAWLUCHA,
|
||||||
|
Species.PASSIMIAN,
|
||||||
|
Species.FALINKS,
|
||||||
|
Species.FLAMIGO,
|
||||||
|
],
|
||||||
|
[TrainerPoolTier.RARE]: [Species.KOMMO_O, Species.QUAQUAVAL],
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EvilTeam =
|
||||||
|
| "rocket"
|
||||||
|
| "magma"
|
||||||
|
| "aqua"
|
||||||
|
| "galactic"
|
||||||
|
| "plasma_zinzolin"
|
||||||
|
| "plasma_colress"
|
||||||
|
| "flare"
|
||||||
|
| "aether"
|
||||||
|
| "skull"
|
||||||
|
| "macro_cosmos"
|
||||||
|
| "star_dark"
|
||||||
|
| "star_fire"
|
||||||
|
| "star_poison"
|
||||||
|
| "star_fairy"
|
||||||
|
| "star_fighting";
|
||||||
|
|
||||||
|
/** Trainer pools for each evil admin team */
|
||||||
|
export const evilAdminTrainerPools: Record<EvilTeam, TrainerTierPools> = {
|
||||||
|
rocket: ROCKET,
|
||||||
|
magma: MAGMA,
|
||||||
|
aqua: AQUA,
|
||||||
|
galactic: GALACTIC,
|
||||||
|
plasma_zinzolin: PLASMA_ZINZOLIN,
|
||||||
|
plasma_colress: PLASMA_COLRESS,
|
||||||
|
flare: FLARE,
|
||||||
|
aether: AETHER,
|
||||||
|
macro_cosmos: MACRO_COSMOS,
|
||||||
|
skull: SKULL,
|
||||||
|
star_dark: STAR_DARK,
|
||||||
|
star_fire: STAR_FIRE,
|
||||||
|
star_poison: STAR_POISON,
|
||||||
|
star_fairy: STAR_FAIRY,
|
||||||
|
star_fighting: STAR_FIGHTING,
|
||||||
|
};
|
@ -1,29 +1,53 @@
|
|||||||
import { startingWave } from "#app/battle-scene";
|
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type { ModifierTypeFunc } from "#app/modifier/modifier-type";
|
|
||||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
import type { EnemyPokemon } from "#app/field/pokemon";
|
|
||||||
import { PokemonMove } from "#app/field/pokemon";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import { PokeballType } from "#enums/pokeball";
|
|
||||||
import { pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
import { pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import type { PokemonSpeciesFilter } from "#app/data/pokemon-species";
|
|
||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
|
||||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import { tmSpecies } from "#app/data/balance/tms";
|
import { tmSpecies } from "#app/data/balance/tms";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
|
||||||
import { doubleBattleDialogue } from "#app/data/dialogue";
|
import { doubleBattleDialogue } from "#app/data/dialogue";
|
||||||
import type { PersistentModifier } from "#app/modifier/modifier";
|
|
||||||
import { TrainerVariant } from "#app/field/trainer";
|
import { TrainerVariant } from "#app/field/trainer";
|
||||||
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
|
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { Moves } from "#enums/moves";
|
import { Gender } from "#app/data/gender";
|
||||||
|
import { signatureSpecies } from "../balance/signature-species";
|
||||||
|
import {
|
||||||
|
getEvilGruntPartyTemplate,
|
||||||
|
getGymLeaderPartyTemplate,
|
||||||
|
getWavePartyTemplate,
|
||||||
|
TrainerPartyCompoundTemplate,
|
||||||
|
TrainerPartyTemplate,
|
||||||
|
trainerPartyTemplates,
|
||||||
|
} from "./TrainerPartyTemplate";
|
||||||
|
import { evilAdminTrainerPools } from "./evil-admin-trainer-pools";
|
||||||
|
|
||||||
|
// Enum imports
|
||||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { PokeballType } from "#enums/pokeball";
|
||||||
import { Gender } from "#app/data/gender";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { signatureSpecies } from "./balance/signature-species";
|
import { Moves } from "#enums/moves";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { TeraAIMode } from "#enums/tera-ai-mode";
|
||||||
|
import { TrainerPoolTier } from "#enums/trainer-pool-tier";
|
||||||
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
|
|
||||||
|
// Type imports
|
||||||
|
import type { PokemonSpeciesFilter } from "#app/data/pokemon-species";
|
||||||
|
import type PokemonSpecies from "#app/data/pokemon-species";
|
||||||
|
import type { ModifierTypeFunc } from "#app/modifier/modifier-type";
|
||||||
|
import type { EnemyPokemon } from "#app/field/pokemon";
|
||||||
|
import type { EvilTeam } from "./evil-admin-trainer-pools";
|
||||||
|
import type {
|
||||||
|
PartyMemberFunc,
|
||||||
|
GenModifiersFunc,
|
||||||
|
GenAIFunc,
|
||||||
|
PartyTemplateFunc,
|
||||||
|
TrainerTierPools,
|
||||||
|
TrainerConfigs,
|
||||||
|
PartyMemberFuncs,
|
||||||
|
} from "./typedefs";
|
||||||
|
|
||||||
/** Minimum BST for Pokemon generated onto the Elite Four's teams */
|
/** Minimum BST for Pokemon generated onto the Elite Four's teams */
|
||||||
const ELITE_FOUR_MINIMUM_BST = 460;
|
const ELITE_FOUR_MINIMUM_BST = 460;
|
||||||
@ -31,253 +55,6 @@ const ELITE_FOUR_MINIMUM_BST = 460;
|
|||||||
/** The wave at which (non-Paldean) Gym Leaders start having Tera mons*/
|
/** The wave at which (non-Paldean) Gym Leaders start having Tera mons*/
|
||||||
const GYM_LEADER_TERA_WAVE = 100;
|
const GYM_LEADER_TERA_WAVE = 100;
|
||||||
|
|
||||||
export enum TrainerPoolTier {
|
|
||||||
COMMON,
|
|
||||||
UNCOMMON,
|
|
||||||
RARE,
|
|
||||||
SUPER_RARE,
|
|
||||||
ULTRA_RARE,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TrainerTierPools {
|
|
||||||
[key: number]: Species[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum TrainerSlot {
|
|
||||||
NONE,
|
|
||||||
TRAINER,
|
|
||||||
TRAINER_PARTNER,
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TrainerPartyTemplate {
|
|
||||||
public size: number;
|
|
||||||
public strength: PartyMemberStrength;
|
|
||||||
public sameSpecies: boolean;
|
|
||||||
public balanced: boolean;
|
|
||||||
|
|
||||||
constructor(size: number, strength: PartyMemberStrength, sameSpecies?: boolean, balanced?: boolean) {
|
|
||||||
this.size = size;
|
|
||||||
this.strength = strength;
|
|
||||||
this.sameSpecies = !!sameSpecies;
|
|
||||||
this.balanced = !!balanced;
|
|
||||||
}
|
|
||||||
|
|
||||||
getStrength(_index: number): PartyMemberStrength {
|
|
||||||
return this.strength;
|
|
||||||
}
|
|
||||||
|
|
||||||
isSameSpecies(_index: number): boolean {
|
|
||||||
return this.sameSpecies;
|
|
||||||
}
|
|
||||||
|
|
||||||
isBalanced(_index: number): boolean {
|
|
||||||
return this.balanced;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class TrainerPartyCompoundTemplate extends TrainerPartyTemplate {
|
|
||||||
public templates: TrainerPartyTemplate[];
|
|
||||||
|
|
||||||
constructor(...templates: TrainerPartyTemplate[]) {
|
|
||||||
super(
|
|
||||||
templates.reduce((total: number, template: TrainerPartyTemplate) => {
|
|
||||||
total += template.size;
|
|
||||||
return total;
|
|
||||||
}, 0),
|
|
||||||
PartyMemberStrength.AVERAGE,
|
|
||||||
);
|
|
||||||
this.templates = templates;
|
|
||||||
}
|
|
||||||
|
|
||||||
getStrength(index: number): PartyMemberStrength {
|
|
||||||
let t = 0;
|
|
||||||
for (const template of this.templates) {
|
|
||||||
if (t + template.size > index) {
|
|
||||||
return template.getStrength(index - t);
|
|
||||||
}
|
|
||||||
t += template.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getStrength(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
isSameSpecies(index: number): boolean {
|
|
||||||
let t = 0;
|
|
||||||
for (const template of this.templates) {
|
|
||||||
if (t + template.size > index) {
|
|
||||||
return template.isSameSpecies(index - t);
|
|
||||||
}
|
|
||||||
t += template.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.isSameSpecies(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
isBalanced(index: number): boolean {
|
|
||||||
let t = 0;
|
|
||||||
for (const template of this.templates) {
|
|
||||||
if (t + template.size > index) {
|
|
||||||
return template.isBalanced(index - t);
|
|
||||||
}
|
|
||||||
t += template.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.isBalanced(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const trainerPartyTemplates = {
|
|
||||||
ONE_WEAK_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.WEAK),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
),
|
|
||||||
ONE_AVG: new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
ONE_AVG_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
),
|
|
||||||
ONE_STRONG: new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
ONE_STRONGER: new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
|
||||||
TWO_WEAKER: new TrainerPartyTemplate(2, PartyMemberStrength.WEAKER),
|
|
||||||
TWO_WEAK: new TrainerPartyTemplate(2, PartyMemberStrength.WEAK),
|
|
||||||
TWO_WEAK_ONE_AVG: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
),
|
|
||||||
TWO_WEAK_SAME_ONE_AVG: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
),
|
|
||||||
TWO_WEAK_SAME_TWO_WEAK_SAME: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true),
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK, true),
|
|
||||||
),
|
|
||||||
TWO_WEAK_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.WEAK),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
),
|
|
||||||
TWO_AVG: new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
|
||||||
TWO_AVG_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
),
|
|
||||||
TWO_AVG_SAME_ONE_AVG: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
),
|
|
||||||
TWO_AVG_SAME_ONE_STRONG: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
),
|
|
||||||
TWO_AVG_SAME_TWO_AVG_SAME: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true),
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, true),
|
|
||||||
),
|
|
||||||
TWO_STRONG: new TrainerPartyTemplate(2, PartyMemberStrength.STRONG),
|
|
||||||
THREE_WEAK: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK),
|
|
||||||
THREE_WEAK_SAME: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK, true),
|
|
||||||
THREE_AVG: new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE),
|
|
||||||
THREE_AVG_SAME: new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, true),
|
|
||||||
THREE_WEAK_BALANCED: new TrainerPartyTemplate(3, PartyMemberStrength.WEAK, false, true),
|
|
||||||
FOUR_WEAKER: new TrainerPartyTemplate(4, PartyMemberStrength.WEAKER),
|
|
||||||
FOUR_WEAKER_SAME: new TrainerPartyTemplate(4, PartyMemberStrength.WEAKER, true),
|
|
||||||
FOUR_WEAK: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK),
|
|
||||||
FOUR_WEAK_SAME: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK, true),
|
|
||||||
FOUR_WEAK_BALANCED: new TrainerPartyTemplate(4, PartyMemberStrength.WEAK, false, true),
|
|
||||||
FIVE_WEAKER: new TrainerPartyTemplate(5, PartyMemberStrength.WEAKER),
|
|
||||||
FIVE_WEAK: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK),
|
|
||||||
FIVE_WEAK_BALANCED: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK, false, true),
|
|
||||||
SIX_WEAKER: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER),
|
|
||||||
SIX_WEAKER_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER, true),
|
|
||||||
SIX_WEAK_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, true),
|
|
||||||
SIX_WEAK_BALANCED: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, false, true),
|
|
||||||
|
|
||||||
GYM_LEADER_1: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
),
|
|
||||||
GYM_LEADER_2: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
|
||||||
),
|
|
||||||
GYM_LEADER_3: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
|
||||||
),
|
|
||||||
GYM_LEADER_4: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
|
||||||
),
|
|
||||||
GYM_LEADER_5: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
|
||||||
),
|
|
||||||
|
|
||||||
ELITE_FOUR: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(3, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
|
||||||
),
|
|
||||||
|
|
||||||
CHAMPION: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(4, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.STRONGER, false, true),
|
|
||||||
),
|
|
||||||
|
|
||||||
RIVAL: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
),
|
|
||||||
RIVAL_2: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true),
|
|
||||||
),
|
|
||||||
RIVAL_3: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE, false, true),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true),
|
|
||||||
),
|
|
||||||
RIVAL_4: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE, false, true),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.WEAK, false, true),
|
|
||||||
),
|
|
||||||
RIVAL_5: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
),
|
|
||||||
RIVAL_6: new TrainerPartyCompoundTemplate(
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE),
|
|
||||||
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true),
|
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
type PartyTemplateFunc = () => TrainerPartyTemplate;
|
|
||||||
type PartyMemberFunc = (level: number, strength: PartyMemberStrength) => EnemyPokemon;
|
|
||||||
type GenModifiersFunc = (party: EnemyPokemon[]) => PersistentModifier[];
|
|
||||||
type GenAIFunc = (party: EnemyPokemon[]) => void;
|
|
||||||
|
|
||||||
export interface PartyMemberFuncs {
|
|
||||||
[key: number]: PartyMemberFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum TeraAIMode {
|
|
||||||
NO_TERA,
|
|
||||||
INSTANT_TERA,
|
|
||||||
SMART_TERA,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores data and helper functions about a trainers AI options.
|
* Stores data and helper functions about a trainers AI options.
|
||||||
*/
|
*/
|
||||||
@ -759,430 +536,6 @@ export class TrainerConfig {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the pool of species for an evil team admin
|
|
||||||
* @param team - The evil team the admin belongs to.
|
|
||||||
* @returns {TrainerTierPools}
|
|
||||||
*/
|
|
||||||
speciesPoolPerEvilTeamAdmin(team): TrainerTierPools {
|
|
||||||
team = team.toLowerCase();
|
|
||||||
switch (team) {
|
|
||||||
case "rocket": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.RATICATE,
|
|
||||||
Species.ARBOK,
|
|
||||||
Species.VILEPLUME,
|
|
||||||
Species.ARCANINE,
|
|
||||||
Species.GENGAR,
|
|
||||||
Species.HYPNO,
|
|
||||||
Species.ELECTRODE,
|
|
||||||
Species.EXEGGUTOR,
|
|
||||||
Species.CUBONE,
|
|
||||||
Species.KOFFING,
|
|
||||||
Species.GYARADOS,
|
|
||||||
Species.CROBAT,
|
|
||||||
Species.STEELIX,
|
|
||||||
Species.HOUNDOOM,
|
|
||||||
Species.HONCHKROW,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.OMASTAR,
|
|
||||||
Species.KABUTOPS,
|
|
||||||
Species.MAGNEZONE,
|
|
||||||
Species.ELECTIVIRE,
|
|
||||||
Species.MAGMORTAR,
|
|
||||||
Species.PORYGON_Z,
|
|
||||||
Species.ANNIHILAPE,
|
|
||||||
Species.ALOLA_SANDSLASH,
|
|
||||||
Species.ALOLA_PERSIAN,
|
|
||||||
Species.ALOLA_GOLEM,
|
|
||||||
Species.ALOLA_MUK,
|
|
||||||
Species.PALDEA_TAUROS,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.DRAGONITE, Species.TYRANITAR],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "magma": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.ARCANINE,
|
|
||||||
Species.MAGCARGO,
|
|
||||||
Species.HOUNDOOM,
|
|
||||||
Species.TORKOAL,
|
|
||||||
Species.SOLROCK,
|
|
||||||
Species.CLAYDOL,
|
|
||||||
Species.HIPPOWDON,
|
|
||||||
Species.MAGMORTAR,
|
|
||||||
Species.GLISCOR,
|
|
||||||
Species.COALOSSAL,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.AGGRON,
|
|
||||||
Species.FLYGON,
|
|
||||||
Species.CRADILY,
|
|
||||||
Species.ARMALDO,
|
|
||||||
Species.RHYPERIOR,
|
|
||||||
Species.TURTONATOR,
|
|
||||||
Species.SANDACONDA,
|
|
||||||
Species.TOEDSCRUEL,
|
|
||||||
Species.HISUI_ARCANINE,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.CHARCADET, Species.SCOVILLAIN],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "aqua": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.TENTACRUEL,
|
|
||||||
Species.LANTURN,
|
|
||||||
Species.AZUMARILL,
|
|
||||||
Species.QUAGSIRE,
|
|
||||||
Species.OCTILLERY,
|
|
||||||
Species.LUDICOLO,
|
|
||||||
Species.PELIPPER,
|
|
||||||
Species.WAILORD,
|
|
||||||
Species.WHISCASH,
|
|
||||||
Species.CRAWDAUNT,
|
|
||||||
Species.WALREIN,
|
|
||||||
Species.CLAMPERL,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.QUAGSIRE,
|
|
||||||
Species.MANTINE,
|
|
||||||
Species.KINGDRA,
|
|
||||||
Species.MILOTIC,
|
|
||||||
Species.DRAGALGE,
|
|
||||||
Species.DHELMISE,
|
|
||||||
Species.BARRASKEWDA,
|
|
||||||
Species.GRAPPLOCT,
|
|
||||||
Species.OVERQWIL,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.BASCULEGION, Species.DONDOZO],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "galactic": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.ELECTRODE,
|
|
||||||
Species.GYARADOS,
|
|
||||||
Species.CROBAT,
|
|
||||||
Species.HONCHKROW,
|
|
||||||
Species.BRONZONG,
|
|
||||||
Species.DRAPION,
|
|
||||||
Species.LICKILICKY,
|
|
||||||
Species.TANGROWTH,
|
|
||||||
Species.ELECTIVIRE,
|
|
||||||
Species.MAGMORTAR,
|
|
||||||
Species.YANMEGA,
|
|
||||||
Species.MAMOSWINE,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.ALAKAZAM,
|
|
||||||
Species.WEAVILE,
|
|
||||||
Species.GLISCOR,
|
|
||||||
Species.DUSKNOIR,
|
|
||||||
Species.ROTOM,
|
|
||||||
Species.OVERQWIL,
|
|
||||||
Species.HISUI_ARCANINE,
|
|
||||||
Species.HISUI_ELECTRODE,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.SPIRITOMB, Species.URSALUNA, Species.SNEASLER, Species.HISUI_LILLIGANT],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "plasma": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.GIGALITH,
|
|
||||||
Species.CONKELDURR,
|
|
||||||
Species.SEISMITOAD,
|
|
||||||
Species.KROOKODILE,
|
|
||||||
Species.DARMANITAN,
|
|
||||||
Species.COFAGRIGUS,
|
|
||||||
Species.VANILLUXE,
|
|
||||||
Species.AMOONGUSS,
|
|
||||||
Species.JELLICENT,
|
|
||||||
Species.GALVANTULA,
|
|
||||||
Species.FERROTHORN,
|
|
||||||
Species.BEARTIC,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.EXCADRILL,
|
|
||||||
Species.SIGILYPH,
|
|
||||||
Species.ZOROARK,
|
|
||||||
Species.KLINKLANG,
|
|
||||||
Species.EELEKTROSS,
|
|
||||||
Species.MIENSHAO,
|
|
||||||
Species.GOLURK,
|
|
||||||
Species.BISHARP,
|
|
||||||
Species.MANDIBUZZ,
|
|
||||||
Species.DURANT,
|
|
||||||
Species.GALAR_DARMANITAN,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.HAXORUS, Species.HYDREIGON, Species.HISUI_ZOROARK, Species.HISUI_BRAVIARY],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "plasma_2": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.MUK,
|
|
||||||
Species.ELECTRODE,
|
|
||||||
Species.BRONZONG,
|
|
||||||
Species.MAGNEZONE,
|
|
||||||
Species.PORYGON_Z,
|
|
||||||
Species.MUSHARNA,
|
|
||||||
Species.REUNICLUS,
|
|
||||||
Species.GALVANTULA,
|
|
||||||
Species.FERROTHORN,
|
|
||||||
Species.EELEKTROSS,
|
|
||||||
Species.BEHEEYEM,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.METAGROSS,
|
|
||||||
Species.ROTOM,
|
|
||||||
Species.CARRACOSTA,
|
|
||||||
Species.ARCHEOPS,
|
|
||||||
Species.GOLURK,
|
|
||||||
Species.DURANT,
|
|
||||||
Species.VIKAVOLT,
|
|
||||||
Species.ORBEETLE,
|
|
||||||
Species.REVAVROOM,
|
|
||||||
Species.ALOLA_MUK,
|
|
||||||
Species.HISUI_ELECTRODE,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.ELECTIVIRE, Species.MAGMORTAR, Species.BISHARP, Species.ARCHALUDON],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "flare": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.MANECTRIC,
|
|
||||||
Species.DRAPION,
|
|
||||||
Species.LIEPARD,
|
|
||||||
Species.AMOONGUSS,
|
|
||||||
Species.DIGGERSBY,
|
|
||||||
Species.TALONFLAME,
|
|
||||||
Species.PYROAR,
|
|
||||||
Species.PANGORO,
|
|
||||||
Species.MEOWSTIC,
|
|
||||||
Species.MALAMAR,
|
|
||||||
Species.CLAWITZER,
|
|
||||||
Species.HELIOLISK,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.HOUNDOOM,
|
|
||||||
Species.WEAVILE,
|
|
||||||
Species.CHANDELURE,
|
|
||||||
Species.AEGISLASH,
|
|
||||||
Species.BARBARACLE,
|
|
||||||
Species.DRAGALGE,
|
|
||||||
Species.GOODRA,
|
|
||||||
Species.TREVENANT,
|
|
||||||
Species.GOURGEIST,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.NOIVERN, Species.HISUI_GOODRA, Species.HISUI_AVALUGG],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "aether": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.ALAKAZAM,
|
|
||||||
Species.SLOWBRO,
|
|
||||||
Species.EXEGGUTOR,
|
|
||||||
Species.XATU,
|
|
||||||
Species.CLAYDOL,
|
|
||||||
Species.BEHEEYEM,
|
|
||||||
Species.ORANGURU,
|
|
||||||
Species.BRUXISH,
|
|
||||||
Species.ORBEETLE,
|
|
||||||
Species.FARIGIRAF,
|
|
||||||
Species.ALOLA_RAICHU,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.KIRLIA,
|
|
||||||
Species.MEDICHAM,
|
|
||||||
Species.METAGROSS,
|
|
||||||
Species.MALAMAR,
|
|
||||||
Species.HATTERENE,
|
|
||||||
Species.MR_RIME,
|
|
||||||
Species.GALAR_SLOWKING,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.PORYGON_Z, Species.ARMAROUGE, Species.HISUI_BRAVIARY],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "skull": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.NIDOQUEEN,
|
|
||||||
Species.GENGAR,
|
|
||||||
Species.KOFFING,
|
|
||||||
Species.CROBAT,
|
|
||||||
Species.ROSERADE,
|
|
||||||
Species.SKUNTANK,
|
|
||||||
Species.TOXICROAK,
|
|
||||||
Species.SCOLIPEDE,
|
|
||||||
Species.TOXAPEX,
|
|
||||||
Species.LURANTIS,
|
|
||||||
Species.ALOLA_MUK,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.DRAPION,
|
|
||||||
Species.MANDIBUZZ,
|
|
||||||
Species.OVERQWIL,
|
|
||||||
Species.GLIMMORA,
|
|
||||||
Species.CLODSIRE,
|
|
||||||
Species.GALAR_SLOWBRO,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.DRAGALGE, Species.SNEASLER],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "macro": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.NINETALES,
|
|
||||||
Species.BELLOSSOM,
|
|
||||||
Species.MILOTIC,
|
|
||||||
Species.FROSLASS,
|
|
||||||
Species.GOTHITELLE,
|
|
||||||
Species.JELLICENT,
|
|
||||||
Species.SALAZZLE,
|
|
||||||
Species.TSAREENA,
|
|
||||||
Species.POLTEAGEIST,
|
|
||||||
Species.HATTERENE,
|
|
||||||
Species.GALAR_RAPIDASH,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.TOGEKISS,
|
|
||||||
Species.MANDIBUZZ,
|
|
||||||
Species.TOXAPEX,
|
|
||||||
Species.APPLETUN,
|
|
||||||
Species.CURSOLA,
|
|
||||||
Species.ALOLA_NINETALES,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.TINKATON, Species.HISUI_LILLIGANT],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "star_1": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.SHIFTRY,
|
|
||||||
Species.CACTURNE,
|
|
||||||
Species.HONCHKROW,
|
|
||||||
Species.SKUNTANK,
|
|
||||||
Species.KROOKODILE,
|
|
||||||
Species.OBSTAGOON,
|
|
||||||
Species.LOKIX,
|
|
||||||
Species.MABOSSTIFF,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.UMBREON,
|
|
||||||
Species.CRAWDAUNT,
|
|
||||||
Species.WEAVILE,
|
|
||||||
Species.ZOROARK,
|
|
||||||
Species.MALAMAR,
|
|
||||||
Species.BOMBIRDIER,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.HYDREIGON, Species.MEOWSCARADA],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "star_2": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.ARCANINE,
|
|
||||||
Species.HOUNDOOM,
|
|
||||||
Species.CAMERUPT,
|
|
||||||
Species.CHANDELURE,
|
|
||||||
Species.TALONFLAME,
|
|
||||||
Species.PYROAR,
|
|
||||||
Species.COALOSSAL,
|
|
||||||
Species.SCOVILLAIN,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.RAPIDASH,
|
|
||||||
Species.FLAREON,
|
|
||||||
Species.TORKOAL,
|
|
||||||
Species.MAGMORTAR,
|
|
||||||
Species.SALAZZLE,
|
|
||||||
Species.TURTONATOR,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.VOLCARONA, Species.SKELEDIRGE],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "star_3": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.MUK,
|
|
||||||
Species.CROBAT,
|
|
||||||
Species.SKUNTANK,
|
|
||||||
Species.AMOONGUSS,
|
|
||||||
Species.TOXAPEX,
|
|
||||||
Species.TOXTRICITY,
|
|
||||||
Species.GRAFAIAI,
|
|
||||||
Species.CLODSIRE,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.GENGAR,
|
|
||||||
Species.SEVIPER,
|
|
||||||
Species.DRAGALGE,
|
|
||||||
Species.OVERQWIL,
|
|
||||||
Species.ALOLA_MUK,
|
|
||||||
Species.GALAR_SLOWBRO,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.GLIMMORA, Species.VENUSAUR],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "star_4": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.CLEFABLE,
|
|
||||||
Species.WIGGLYTUFF,
|
|
||||||
Species.AZUMARILL,
|
|
||||||
Species.WHIMSICOTT,
|
|
||||||
Species.FLORGES,
|
|
||||||
Species.HATTERENE,
|
|
||||||
Species.GRIMMSNARL,
|
|
||||||
Species.TINKATON,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.TOGEKISS,
|
|
||||||
Species.GARDEVOIR,
|
|
||||||
Species.SYLVEON,
|
|
||||||
Species.KLEFKI,
|
|
||||||
Species.MIMIKYU,
|
|
||||||
Species.ALOLA_NINETALES,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.GALAR_RAPIDASH, Species.PRIMARINA],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "star_5": {
|
|
||||||
return {
|
|
||||||
[TrainerPoolTier.COMMON]: [
|
|
||||||
Species.BRELOOM,
|
|
||||||
Species.HARIYAMA,
|
|
||||||
Species.MEDICHAM,
|
|
||||||
Species.TOXICROAK,
|
|
||||||
Species.SCRAFTY,
|
|
||||||
Species.MIENSHAO,
|
|
||||||
Species.PAWMOT,
|
|
||||||
Species.PALDEA_TAUROS,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.UNCOMMON]: [
|
|
||||||
Species.LUCARIO,
|
|
||||||
Species.CONKELDURR,
|
|
||||||
Species.HAWLUCHA,
|
|
||||||
Species.PASSIMIAN,
|
|
||||||
Species.FALINKS,
|
|
||||||
Species.FLAMIGO,
|
|
||||||
],
|
|
||||||
[TrainerPoolTier.RARE]: [Species.KOMMO_O, Species.QUAQUAVAL],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.warn(`Evil team admin for ${team} not found. Returning empty species pools.`);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the trainer configuration for an evil team admin.
|
* Initializes the trainer configuration for an evil team admin.
|
||||||
* @param title The title of the evil team admin.
|
* @param title The title of the evil team admin.
|
||||||
@ -1193,7 +546,7 @@ export class TrainerConfig {
|
|||||||
* **/
|
* **/
|
||||||
initForEvilTeamAdmin(
|
initForEvilTeamAdmin(
|
||||||
title: string,
|
title: string,
|
||||||
poolName: string,
|
poolName: EvilTeam,
|
||||||
signatureSpecies: (Species | Species[])[],
|
signatureSpecies: (Species | Species[])[],
|
||||||
specialtyType?: PokemonType,
|
specialtyType?: PokemonType,
|
||||||
): TrainerConfig {
|
): TrainerConfig {
|
||||||
@ -1208,7 +561,7 @@ export class TrainerConfig {
|
|||||||
this.setPartyTemplates(trainerPartyTemplates.RIVAL_5);
|
this.setPartyTemplates(trainerPartyTemplates.RIVAL_5);
|
||||||
|
|
||||||
// Set the species pools for the evil team admin.
|
// Set the species pools for the evil team admin.
|
||||||
this.speciesPools = this.speciesPoolPerEvilTeamAdmin(poolName);
|
this.speciesPools = evilAdminTrainerPools[poolName];
|
||||||
|
|
||||||
signatureSpecies.forEach((speciesPool, s) => {
|
signatureSpecies.forEach((speciesPool, s) => {
|
||||||
if (!Array.isArray(speciesPool)) {
|
if (!Array.isArray(speciesPool)) {
|
||||||
@ -1637,56 +990,6 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
let t = 0;
|
let t = 0;
|
||||||
|
|
||||||
interface TrainerConfigs {
|
|
||||||
[key: number]: TrainerConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The function to get variable strength grunts
|
|
||||||
* @returns the correct TrainerPartyTemplate
|
|
||||||
*/
|
|
||||||
function getEvilGruntPartyTemplate(): TrainerPartyTemplate {
|
|
||||||
const waveIndex = globalScene.currentBattle?.waveIndex;
|
|
||||||
if (waveIndex < 40) {
|
|
||||||
return trainerPartyTemplates.TWO_AVG;
|
|
||||||
}
|
|
||||||
if (waveIndex < 63) {
|
|
||||||
return trainerPartyTemplates.THREE_AVG;
|
|
||||||
}
|
|
||||||
if (waveIndex < 65) {
|
|
||||||
return trainerPartyTemplates.TWO_AVG_ONE_STRONG;
|
|
||||||
}
|
|
||||||
if (waveIndex < 112) {
|
|
||||||
return trainerPartyTemplates.GYM_LEADER_4; // 3avg 1 strong 1 stronger
|
|
||||||
}
|
|
||||||
return trainerPartyTemplates.GYM_LEADER_5; // 3 avg 2 strong 1 stronger
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWavePartyTemplate(...templates: TrainerPartyTemplate[]) {
|
|
||||||
return templates[
|
|
||||||
Math.min(
|
|
||||||
Math.max(
|
|
||||||
Math.ceil(
|
|
||||||
(globalScene.gameMode.getWaveForDifficulty(globalScene.currentBattle?.waveIndex || startingWave, true) - 20) /
|
|
||||||
30,
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
templates.length - 1,
|
|
||||||
)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getGymLeaderPartyTemplate() {
|
|
||||||
return getWavePartyTemplate(
|
|
||||||
trainerPartyTemplates.GYM_LEADER_1,
|
|
||||||
trainerPartyTemplates.GYM_LEADER_2,
|
|
||||||
trainerPartyTemplates.GYM_LEADER_3,
|
|
||||||
trainerPartyTemplates.GYM_LEADER_4,
|
|
||||||
trainerPartyTemplates.GYM_LEADER_5,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Randomly selects one of the `Species` from `speciesPool`, determines its evolution, level, and strength.
|
* Randomly selects one of the `Species` from `speciesPool`, determines its evolution, level, and strength.
|
||||||
* Then adds Pokemon to globalScene.
|
* Then adds Pokemon to globalScene.
|
||||||
@ -2878,7 +2181,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
}),
|
}),
|
||||||
[TrainerType.ZINZOLIN]: new TrainerConfig(++t)
|
[TrainerType.ZINZOLIN]: new TrainerConfig(++t)
|
||||||
.setMoneyMultiplier(1.5)
|
.setMoneyMultiplier(1.5)
|
||||||
.initForEvilTeamAdmin("plasma_sage", "plasma", [Species.CRYOGONAL])
|
.initForEvilTeamAdmin("plasma_sage", "plasma_zinzolin", [Species.CRYOGONAL])
|
||||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||||
.setBattleBgm("battle_plasma_grunt")
|
.setBattleBgm("battle_plasma_grunt")
|
||||||
.setMixedBattleBgm("battle_plasma_grunt")
|
.setMixedBattleBgm("battle_plasma_grunt")
|
||||||
@ -2886,7 +2189,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
.setPartyTemplateFunc(() => getEvilGruntPartyTemplate()),
|
.setPartyTemplateFunc(() => getEvilGruntPartyTemplate()),
|
||||||
[TrainerType.COLRESS]: new TrainerConfig(++t)
|
[TrainerType.COLRESS]: new TrainerConfig(++t)
|
||||||
.setMoneyMultiplier(1.5)
|
.setMoneyMultiplier(1.5)
|
||||||
.initForEvilTeamAdmin("plasma_boss", "plasma_2", [Species.KLINKLANG])
|
.initForEvilTeamAdmin("plasma_boss", "plasma_colress", [Species.KLINKLANG])
|
||||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||||
.setBattleBgm("battle_colress")
|
.setBattleBgm("battle_colress")
|
||||||
.setMixedBattleBgm("battle_colress")
|
.setMixedBattleBgm("battle_colress")
|
||||||
@ -3105,7 +2408,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
}),
|
}),
|
||||||
[TrainerType.OLEANA]: new TrainerConfig(++t)
|
[TrainerType.OLEANA]: new TrainerConfig(++t)
|
||||||
.setMoneyMultiplier(1.5)
|
.setMoneyMultiplier(1.5)
|
||||||
.initForEvilTeamAdmin("macro_admin", "macro", [Species.GARBODOR])
|
.initForEvilTeamAdmin("macro_admin", "macro_cosmos", [Species.GARBODOR])
|
||||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||||
.setBattleBgm("battle_plasma_grunt")
|
.setBattleBgm("battle_plasma_grunt")
|
||||||
.setMixedBattleBgm("battle_oleana")
|
.setMixedBattleBgm("battle_oleana")
|
||||||
@ -3172,7 +2475,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
}),
|
}),
|
||||||
[TrainerType.GIACOMO]: new TrainerConfig(++t)
|
[TrainerType.GIACOMO]: new TrainerConfig(++t)
|
||||||
.setMoneyMultiplier(1.5)
|
.setMoneyMultiplier(1.5)
|
||||||
.initForEvilTeamAdmin("star_admin", "star_1", [Species.KINGAMBIT], PokemonType.DARK)
|
.initForEvilTeamAdmin("star_admin", "star_dark", [Species.KINGAMBIT], PokemonType.DARK)
|
||||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||||
.setBattleBgm("battle_plasma_grunt")
|
.setBattleBgm("battle_plasma_grunt")
|
||||||
.setMixedBattleBgm("battle_star_admin")
|
.setMixedBattleBgm("battle_star_admin")
|
||||||
@ -3192,7 +2495,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
),
|
),
|
||||||
[TrainerType.MELA]: new TrainerConfig(++t)
|
[TrainerType.MELA]: new TrainerConfig(++t)
|
||||||
.setMoneyMultiplier(1.5)
|
.setMoneyMultiplier(1.5)
|
||||||
.initForEvilTeamAdmin("star_admin", "star_2", [Species.ARMAROUGE], PokemonType.FIRE)
|
.initForEvilTeamAdmin("star_admin", "star_fire", [Species.ARMAROUGE], PokemonType.FIRE)
|
||||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||||
.setBattleBgm("battle_plasma_grunt")
|
.setBattleBgm("battle_plasma_grunt")
|
||||||
.setMixedBattleBgm("battle_star_admin")
|
.setMixedBattleBgm("battle_star_admin")
|
||||||
@ -3212,7 +2515,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
),
|
),
|
||||||
[TrainerType.ATTICUS]: new TrainerConfig(++t)
|
[TrainerType.ATTICUS]: new TrainerConfig(++t)
|
||||||
.setMoneyMultiplier(1.5)
|
.setMoneyMultiplier(1.5)
|
||||||
.initForEvilTeamAdmin("star_admin", "star_3", [Species.REVAVROOM], PokemonType.POISON)
|
.initForEvilTeamAdmin("star_admin", "star_poison", [Species.REVAVROOM], PokemonType.POISON)
|
||||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||||
.setBattleBgm("battle_plasma_grunt")
|
.setBattleBgm("battle_plasma_grunt")
|
||||||
.setMixedBattleBgm("battle_star_admin")
|
.setMixedBattleBgm("battle_star_admin")
|
||||||
@ -3232,7 +2535,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
),
|
),
|
||||||
[TrainerType.ORTEGA]: new TrainerConfig(++t)
|
[TrainerType.ORTEGA]: new TrainerConfig(++t)
|
||||||
.setMoneyMultiplier(1.5)
|
.setMoneyMultiplier(1.5)
|
||||||
.initForEvilTeamAdmin("star_admin", "star_4", [Species.DACHSBUN], PokemonType.FAIRY)
|
.initForEvilTeamAdmin("star_admin", "star_fairy", [Species.DACHSBUN], PokemonType.FAIRY)
|
||||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||||
.setBattleBgm("battle_plasma_grunt")
|
.setBattleBgm("battle_plasma_grunt")
|
||||||
.setMixedBattleBgm("battle_star_admin")
|
.setMixedBattleBgm("battle_star_admin")
|
||||||
@ -3252,7 +2555,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
),
|
),
|
||||||
[TrainerType.ERI]: new TrainerConfig(++t)
|
[TrainerType.ERI]: new TrainerConfig(++t)
|
||||||
.setMoneyMultiplier(1.5)
|
.setMoneyMultiplier(1.5)
|
||||||
.initForEvilTeamAdmin("star_admin", "star_5", [Species.ANNIHILAPE], PokemonType.FIGHTING)
|
.initForEvilTeamAdmin("star_admin", "star_fighting", [Species.ANNIHILAPE], PokemonType.FIGHTING)
|
||||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||||
.setBattleBgm("battle_plasma_grunt")
|
.setBattleBgm("battle_plasma_grunt")
|
||||||
.setMixedBattleBgm("battle_star_admin")
|
.setMixedBattleBgm("battle_star_admin")
|
22
src/data/trainers/typedefs.ts
Normal file
22
src/data/trainers/typedefs.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import type { EnemyPokemon } from "#app/field/pokemon";
|
||||||
|
import type { PersistentModifier } from "#app/modifier/modifier";
|
||||||
|
import type { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
|
import type { Species } from "#enums/species";
|
||||||
|
import type { TrainerConfig } from "./trainer-config";
|
||||||
|
import type { TrainerPartyTemplate } from "./TrainerPartyTemplate";
|
||||||
|
|
||||||
|
export type PartyTemplateFunc = () => TrainerPartyTemplate;
|
||||||
|
export type PartyMemberFunc = (level: number, strength: PartyMemberStrength) => EnemyPokemon;
|
||||||
|
export type GenModifiersFunc = (party: EnemyPokemon[]) => PersistentModifier[];
|
||||||
|
export type GenAIFunc = (party: EnemyPokemon[]) => void;
|
||||||
|
|
||||||
|
export interface TrainerTierPools {
|
||||||
|
[key: number]: Species[];
|
||||||
|
}
|
||||||
|
export interface TrainerConfigs {
|
||||||
|
[key: number]: TrainerConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PartyMemberFuncs {
|
||||||
|
[key: number]: PartyMemberFunc;
|
||||||
|
}
|
5
src/enums/tera-ai-mode.ts
Normal file
5
src/enums/tera-ai-mode.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export enum TeraAIMode {
|
||||||
|
NO_TERA,
|
||||||
|
INSTANT_TERA,
|
||||||
|
SMART_TERA
|
||||||
|
}
|
7
src/enums/trainer-pool-tier.ts
Normal file
7
src/enums/trainer-pool-tier.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export enum TrainerPoolTier {
|
||||||
|
COMMON,
|
||||||
|
UNCOMMON,
|
||||||
|
RARE,
|
||||||
|
SUPER_RARE,
|
||||||
|
ULTRA_RARE
|
||||||
|
}
|
5
src/enums/trainer-slot.ts
Normal file
5
src/enums/trainer-slot.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export enum TrainerSlot {
|
||||||
|
NONE,
|
||||||
|
TRAINER,
|
||||||
|
TRAINER_PARTNER
|
||||||
|
}
|
@ -191,6 +191,9 @@ import {
|
|||||||
applyPreLeaveFieldAbAttrs,
|
applyPreLeaveFieldAbAttrs,
|
||||||
applyOnLoseAbAttrs,
|
applyOnLoseAbAttrs,
|
||||||
PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr,
|
PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr,
|
||||||
|
applyAllyStatMultiplierAbAttrs,
|
||||||
|
AllyStatMultiplierAbAttr,
|
||||||
|
MoveAbilityBypassAbAttr,
|
||||||
} from "#app/data/ability";
|
} from "#app/data/ability";
|
||||||
import type PokemonData from "#app/system/pokemon-data";
|
import type PokemonData from "#app/system/pokemon-data";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
@ -221,7 +224,7 @@ import {
|
|||||||
SpeciesFormChangeStatusEffectTrigger,
|
SpeciesFormChangeStatusEffectTrigger,
|
||||||
} from "#app/data/pokemon-forms";
|
} from "#app/data/pokemon-forms";
|
||||||
import { TerrainType } from "#app/data/terrain";
|
import { TerrainType } from "#app/data/terrain";
|
||||||
import type { TrainerSlot } from "#app/data/trainer-config";
|
import type { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { speciesEggMoves } from "#app/data/balance/egg-moves";
|
import { speciesEggMoves } from "#app/data/balance/egg-moves";
|
||||||
@ -259,6 +262,7 @@ import {
|
|||||||
import { Nature } from "#enums/nature";
|
import { Nature } from "#enums/nature";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import { doShinySparkleAnim } from "#app/field/anims";
|
import { doShinySparkleAnim } from "#app/field/anims";
|
||||||
|
import { MoveFlags } from "#enums/MoveFlags";
|
||||||
|
|
||||||
export enum LearnMoveSituation {
|
export enum LearnMoveSituation {
|
||||||
MISC,
|
MISC,
|
||||||
@ -1388,6 +1392,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @param move the {@linkcode Move} being used
|
* @param move the {@linkcode Move} being used
|
||||||
* @param ignoreAbility determines whether this Pokemon's abilities should be ignored during the stat calculation
|
* @param ignoreAbility determines whether this Pokemon's abilities should be ignored during the stat calculation
|
||||||
* @param ignoreOppAbility during an attack, determines whether the opposing Pokemon's abilities should be ignored during the stat calculation.
|
* @param ignoreOppAbility during an attack, determines whether the opposing Pokemon's abilities should be ignored during the stat calculation.
|
||||||
|
* @param ignoreAllyAbility during an attack, determines whether the ally Pokemon's abilities should be ignored during the stat calculation.
|
||||||
* @param isCritical determines whether a critical hit has occurred or not (`false` by default)
|
* @param isCritical determines whether a critical hit has occurred or not (`false` by default)
|
||||||
* @param simulated if `true`, nullifies any effects that produce any changes to game state from triggering
|
* @param simulated if `true`, nullifies any effects that produce any changes to game state from triggering
|
||||||
* @param ignoreHeldItems determines whether this Pokemon's held items should be ignored during the stat calculation, default `false`
|
* @param ignoreHeldItems determines whether this Pokemon's held items should be ignored during the stat calculation, default `false`
|
||||||
@ -1399,6 +1404,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
move?: Move,
|
move?: Move,
|
||||||
ignoreAbility = false,
|
ignoreAbility = false,
|
||||||
ignoreOppAbility = false,
|
ignoreOppAbility = false,
|
||||||
|
ignoreAllyAbility = false,
|
||||||
isCritical = false,
|
isCritical = false,
|
||||||
simulated = true,
|
simulated = true,
|
||||||
ignoreHeldItems = false,
|
ignoreHeldItems = false,
|
||||||
@ -1440,6 +1446,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ally = this.getAlly();
|
||||||
|
if (ally) {
|
||||||
|
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, stat, statValue, simulated, this, move?.hasFlag(MoveFlags.IGNORE_ABILITIES) || ignoreAllyAbility);
|
||||||
|
}
|
||||||
|
|
||||||
let ret =
|
let ret =
|
||||||
statValue.value *
|
statValue.value *
|
||||||
this.getStatStageMultiplier(
|
this.getStatStageMultiplier(
|
||||||
@ -3888,6 +3899,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
evasionMultiplier,
|
evasionMultiplier,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const ally = this.getAlly();
|
||||||
|
if (ally) {
|
||||||
|
const ignore = this.hasAbilityWithAttr(MoveAbilityBypassAbAttr) || sourceMove.hasFlag(MoveFlags.IGNORE_ABILITIES);
|
||||||
|
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, Stat.ACC, accuracyMultiplier, false, this, ignore);
|
||||||
|
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, Stat.EVA, evasionMultiplier, false, this, ignore);
|
||||||
|
}
|
||||||
|
|
||||||
return accuracyMultiplier.value / evasionMultiplier.value;
|
return accuracyMultiplier.value / evasionMultiplier.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3899,6 +3917,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @param moveCategory the move's {@linkcode MoveCategory} after variable-category effects are applied.
|
* @param moveCategory the move's {@linkcode MoveCategory} after variable-category effects are applied.
|
||||||
* @param ignoreAbility if `true`, ignores this Pokemon's defensive ability effects (defaults to `false`).
|
* @param ignoreAbility if `true`, ignores this Pokemon's defensive ability effects (defaults to `false`).
|
||||||
* @param ignoreSourceAbility if `true`, ignore's the attacking Pokemon's ability effects (defaults to `false`).
|
* @param ignoreSourceAbility if `true`, ignore's the attacking Pokemon's ability effects (defaults to `false`).
|
||||||
|
* @param ignoreAllyAbility if `true`, ignores the ally Pokemon's ability effects (defaults to `false`).
|
||||||
|
* @param ignoreSourceAllyAbility if `true`, ignores the attacking Pokemon's ally's ability effects (defaults to `false`).
|
||||||
* @param isCritical if `true`, calculates effective stats as if the hit were critical (defaults to `false`).
|
* @param isCritical if `true`, calculates effective stats as if the hit were critical (defaults to `false`).
|
||||||
* @param simulated if `true`, suppresses changes to game state during calculation (defaults to `true`).
|
* @param simulated if `true`, suppresses changes to game state during calculation (defaults to `true`).
|
||||||
* @returns The move's base damage against this Pokemon when used by the source Pokemon.
|
* @returns The move's base damage against this Pokemon when used by the source Pokemon.
|
||||||
@ -3909,6 +3929,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
moveCategory: MoveCategory,
|
moveCategory: MoveCategory,
|
||||||
ignoreAbility = false,
|
ignoreAbility = false,
|
||||||
ignoreSourceAbility = false,
|
ignoreSourceAbility = false,
|
||||||
|
ignoreAllyAbility = false,
|
||||||
|
ignoreSourceAllyAbility = false,
|
||||||
isCritical = false,
|
isCritical = false,
|
||||||
simulated = true,
|
simulated = true,
|
||||||
): number {
|
): number {
|
||||||
@ -3931,6 +3953,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
undefined,
|
undefined,
|
||||||
ignoreSourceAbility,
|
ignoreSourceAbility,
|
||||||
ignoreAbility,
|
ignoreAbility,
|
||||||
|
ignoreAllyAbility,
|
||||||
isCritical,
|
isCritical,
|
||||||
simulated,
|
simulated,
|
||||||
),
|
),
|
||||||
@ -3948,6 +3971,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
move,
|
move,
|
||||||
ignoreAbility,
|
ignoreAbility,
|
||||||
ignoreSourceAbility,
|
ignoreSourceAbility,
|
||||||
|
ignoreSourceAllyAbility,
|
||||||
isCritical,
|
isCritical,
|
||||||
simulated,
|
simulated,
|
||||||
),
|
),
|
||||||
@ -3982,6 +4006,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @param move {@linkcode Pokemon} the move used in the attack
|
* @param move {@linkcode Pokemon} the move used in the attack
|
||||||
* @param ignoreAbility If `true`, ignores this Pokemon's defensive ability effects
|
* @param ignoreAbility If `true`, ignores this Pokemon's defensive ability effects
|
||||||
* @param ignoreSourceAbility If `true`, ignores the attacking Pokemon's ability effects
|
* @param ignoreSourceAbility If `true`, ignores the attacking Pokemon's ability effects
|
||||||
|
* @param ignoreAllyAbility If `true`, ignores the ally Pokemon's ability effects
|
||||||
|
* @param ignoreSourceAllyAbility If `true`, ignores the ability effects of the attacking pokemon's ally
|
||||||
* @param isCritical If `true`, calculates damage for a critical hit.
|
* @param isCritical If `true`, calculates damage for a critical hit.
|
||||||
* @param simulated If `true`, suppresses changes to game state during the calculation.
|
* @param simulated If `true`, suppresses changes to game state during the calculation.
|
||||||
* @returns a {@linkcode DamageCalculationResult} object with three fields:
|
* @returns a {@linkcode DamageCalculationResult} object with three fields:
|
||||||
@ -3994,6 +4020,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
move: Move,
|
move: Move,
|
||||||
ignoreAbility = false,
|
ignoreAbility = false,
|
||||||
ignoreSourceAbility = false,
|
ignoreSourceAbility = false,
|
||||||
|
ignoreAllyAbility = false,
|
||||||
|
ignoreSourceAllyAbility = false,
|
||||||
isCritical = false,
|
isCritical = false,
|
||||||
simulated = true,
|
simulated = true,
|
||||||
): DamageCalculationResult {
|
): DamageCalculationResult {
|
||||||
@ -4103,6 +4131,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
moveCategory,
|
moveCategory,
|
||||||
ignoreAbility,
|
ignoreAbility,
|
||||||
ignoreSourceAbility,
|
ignoreSourceAbility,
|
||||||
|
ignoreAllyAbility,
|
||||||
|
ignoreSourceAllyAbility,
|
||||||
isCritical,
|
isCritical,
|
||||||
simulated,
|
simulated,
|
||||||
);
|
);
|
||||||
@ -4428,7 +4458,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
cancelled,
|
cancelled,
|
||||||
result,
|
result,
|
||||||
damage: dmg,
|
damage: dmg,
|
||||||
} = this.getAttackDamage(source, move, false, false, isCritical, false);
|
} = this.getAttackDamage(source, move, false, false, false, false, isCritical, false);
|
||||||
|
|
||||||
const typeBoost = source.findTag(
|
const typeBoost = source.findTag(
|
||||||
t =>
|
t =>
|
||||||
@ -7113,6 +7143,8 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
move,
|
move,
|
||||||
!p.battleData.abilityRevealed,
|
!p.battleData.abilityRevealed,
|
||||||
false,
|
false,
|
||||||
|
!p.getAlly()?.battleData.abilityRevealed,
|
||||||
|
false,
|
||||||
isCritical,
|
isCritical,
|
||||||
).damage >= p.hp
|
).damage >= p.hp
|
||||||
);
|
);
|
||||||
|
@ -2,15 +2,14 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
import type PokemonSpecies from "#app/data/pokemon-species";
|
||||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import type { TrainerConfig, TrainerPartyTemplate } from "#app/data/trainer-config";
|
import type { TrainerConfig } from "#app/data/trainers/trainer-config";
|
||||||
import {
|
import type { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
TrainerPartyCompoundTemplate,
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
TrainerPoolTier,
|
import { trainerPartyTemplates } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
TrainerSlot,
|
import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
trainerConfigs,
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
trainerPartyTemplates,
|
import { TrainerPoolTier } from "#enums/trainer-pool-tier";
|
||||||
TeraAIMode,
|
import { TeraAIMode } from "#enums/tera-ai-mode";
|
||||||
} from "#app/data/trainer-config";
|
|
||||||
import type { EnemyPokemon } from "#app/field/pokemon";
|
import type { EnemyPokemon } from "#app/field/pokemon";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import type { PersistentModifier } from "#app/modifier/modifier";
|
import type { PersistentModifier } from "#app/modifier/modifier";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { Phase } from "#app/phase";
|
import { Phase } from "#app/phase";
|
||||||
|
|
||||||
export class BattlePhase extends Phase {
|
export class BattlePhase extends Phase {
|
||||||
|
@ -7,7 +7,7 @@ import { getCharVariantFromDialogue } from "#app/data/dialogue";
|
|||||||
import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { doTrainerExclamation } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import { doTrainerExclamation } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { getGoldenBugNetSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { getGoldenBugNetSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { getRandomWeatherType } from "#app/data/weather";
|
import { getRandomWeatherType } from "#app/data/weather";
|
||||||
import { EncounterPhaseEvent } from "#app/events/battle-scene";
|
import { EncounterPhaseEvent } from "#app/events/battle-scene";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type { ModifierTypeFunc } from "#app/modifier/modifier-type";
|
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { ModifierRewardPhase } from "./modifier-reward-phase";
|
import { ModifierRewardPhase } from "./modifier-reward-phase";
|
||||||
|
@ -5,7 +5,7 @@ import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
|
|||||||
import { getCharVariantFromDialogue } from "#app/data/dialogue";
|
import { getCharVariantFromDialogue } from "#app/data/dialogue";
|
||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
import type PokemonSpecies from "#app/data/pokemon-species";
|
||||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import { trainerConfigs } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
import { BattlePhase } from "#app/phases/battle-phase";
|
import { BattlePhase } from "#app/phases/battle-phase";
|
||||||
|
@ -29,7 +29,7 @@ export class MessagePhase extends Phase {
|
|||||||
|
|
||||||
if (this.text.indexOf("$") > -1) {
|
if (this.text.indexOf("$") > -1) {
|
||||||
const pokename: string[] = [];
|
const pokename: string[] = [];
|
||||||
const repname = [ "#POKEMON1", "#POKEMON2" ];
|
const repname = ["#POKEMON1", "#POKEMON2"];
|
||||||
for (let p = 0; p < globalScene.getPlayerField().length; p++) {
|
for (let p = 0; p < globalScene.getPlayerField().length; p++) {
|
||||||
pokename.push(globalScene.getPlayerField()[p].getNameToRender());
|
pokename.push(globalScene.getPlayerField()[p].getNameToRender());
|
||||||
this.text = this.text.split(pokename[p]).join(repname[p]);
|
this.text = this.text.split(pokename[p]).join(repname[p]);
|
||||||
|
@ -653,7 +653,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
this.applyOnHitEffects(user, target, firstHit, lastHit, firstTarget);
|
this.applyOnHitEffects(user, target, firstHit, lastHit, firstTarget);
|
||||||
this.applyOnGetHitAbEffects(user, target, hitResult);
|
this.applyOnGetHitAbEffects(user, target, hitResult);
|
||||||
applyPostAttackAbAttrs(PostAttackAbAttr, user, target, this.move.getMove(), hitResult);
|
applyPostAttackAbAttrs(PostAttackAbAttr, user, target, this.move.getMove(), hitResult);
|
||||||
if (this.move.getMove() instanceof AttackMove) {
|
if (this.move.getMove() instanceof AttackMove && hitResult !== HitResult.STATUS) {
|
||||||
globalScene.applyModifiers(ContactHeldItemTransferChanceModifier, this.player, user, target);
|
globalScene.applyModifiers(ContactHeldItemTransferChanceModifier, this.player, user, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type { BattlerIndex } from "#app/battle";
|
|
||||||
import { BattlerTagLapseType } from "#app/data/battler-tags";
|
import { BattlerTagLapseType } from "#app/data/battler-tags";
|
||||||
import { PokemonPhase } from "./pokemon-phase";
|
import { PokemonPhase } from "./pokemon-phase";
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import { globalScene } from "#app/global-scene";
|
|||||||
import { getCharVariantFromDialogue } from "../data/dialogue";
|
import { getCharVariantFromDialogue } from "../data/dialogue";
|
||||||
import type { OptionSelectSettings } from "../data/mystery-encounters/utils/encounter-phase-utils";
|
import type { OptionSelectSettings } from "../data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { transitionMysteryEncounterIntroVisuals } from "../data/mystery-encounters/utils/encounter-phase-utils";
|
import { transitionMysteryEncounterIntroVisuals } from "../data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { TrainerSlot } from "../data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { IvScannerModifier } from "../modifier/modifier";
|
import { IvScannerModifier } from "../modifier/modifier";
|
||||||
import { Phase } from "../phase";
|
import { Phase } from "../phase";
|
||||||
import { Mode } from "../ui/ui";
|
import { Mode } from "../ui/ui";
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type { BattlerIndex } from "#app/battle";
|
|
||||||
import { applyAbAttrs, applyPostSummonAbAttrs, CommanderAbAttr, PostSummonAbAttr } from "#app/data/ability";
|
import { applyAbAttrs, applyPostSummonAbAttrs, CommanderAbAttr, PostSummonAbAttr } from "#app/data/ability";
|
||||||
import { ArenaTrapTag } from "#app/data/arena-tag";
|
import { ArenaTrapTag } from "#app/data/arena-tag";
|
||||||
import { StatusEffect } from "#app/enums/status-effect";
|
import { StatusEffect } from "#app/enums/status-effect";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { BattleType } from "#app/battle";
|
import { BattleType } from "#app/battle";
|
||||||
import { getPokeballAtlasKey, getPokeballTintColor } from "#app/data/pokeball";
|
import { getPokeballAtlasKey, getPokeballTintColor } from "#app/data/pokeball";
|
||||||
import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms";
|
import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { PlayerGender } from "#app/enums/player-gender";
|
import { PlayerGender } from "#app/enums/player-gender";
|
||||||
import { addPokeballOpenParticles } from "#app/field/anims";
|
import { addPokeballOpenParticles } from "#app/field/anims";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
|
@ -3,7 +3,7 @@ import { applyPreSwitchOutAbAttrs, PostDamageForceSwitchAbAttr, PreSwitchOutAbAt
|
|||||||
import { allMoves, ForceSwitchOutAttr } from "#app/data/moves/move";
|
import { allMoves, ForceSwitchOutAttr } from "#app/data/moves/move";
|
||||||
import { getPokeballTintColor } from "#app/data/pokeball";
|
import { getPokeballTintColor } from "#app/data/pokeball";
|
||||||
import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms";
|
import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { SwitchEffectTransferModifier } from "#app/modifier/modifier";
|
import { SwitchEffectTransferModifier } from "#app/modifier/modifier";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { trainerConfigs } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
import type { TrainerType } from "#app/enums/trainer-type";
|
import type { TrainerType } from "#app/enums/trainer-type";
|
||||||
import { BattlePhase } from "./battle-phase";
|
import { BattlePhase } from "./battle-phase";
|
||||||
import { TestMessagePhase } from "./test-message-phase";
|
import { TestMessagePhase } from "./test-message-phase";
|
||||||
|
@ -7,7 +7,7 @@ import * as Utils from "#app/utils";
|
|||||||
import { BattlePhase } from "./battle-phase";
|
import { BattlePhase } from "./battle-phase";
|
||||||
import { ModifierRewardPhase } from "./modifier-reward-phase";
|
import { ModifierRewardPhase } from "./modifier-reward-phase";
|
||||||
import { MoneyRewardPhase } from "./money-reward-phase";
|
import { MoneyRewardPhase } from "./money-reward-phase";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { Biome } from "#app/enums/biome";
|
import { Biome } from "#app/enums/biome";
|
||||||
import { achvs } from "#app/system/achv";
|
import { achvs } from "#app/system/achv";
|
||||||
|
@ -17,7 +17,7 @@ import { Unlockables } from "#app/system/unlockables";
|
|||||||
import { GameModes, getGameMode } from "#app/game-mode";
|
import { GameModes, getGameMode } from "#app/game-mode";
|
||||||
import { BattleType } from "#app/battle";
|
import { BattleType } from "#app/battle";
|
||||||
import TrainerData from "#app/system/trainer-data";
|
import TrainerData from "#app/system/trainer-data";
|
||||||
import { trainerConfigs } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
import { resetSettings, setSetting, SettingKeys } from "#app/system/settings/settings";
|
import { resetSettings, setSetting, SettingKeys } from "#app/system/settings/settings";
|
||||||
import { achvs } from "#app/system/achv";
|
import { achvs } from "#app/system/achv";
|
||||||
import EggData from "#app/system/egg-data";
|
import EggData from "#app/system/egg-data";
|
||||||
|
@ -5,8 +5,8 @@ import type BattleScene from "#app/battle-scene";
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
|
|
||||||
type FadeIn = typeof FadeIn;
|
type FadeInType = typeof FadeIn;
|
||||||
type FadeOut = typeof FadeOut;
|
type FadeOutType = typeof FadeOut;
|
||||||
|
|
||||||
export function initGameSpeed() {
|
export function initGameSpeed() {
|
||||||
const thisArg = this as BattleScene;
|
const thisArg = this as BattleScene;
|
||||||
@ -101,7 +101,7 @@ export function initGameSpeed() {
|
|||||||
|
|
||||||
const originalFadeOut = SoundFade.fadeOut;
|
const originalFadeOut = SoundFade.fadeOut;
|
||||||
SoundFade.fadeOut = ((_scene: Phaser.Scene, sound: Phaser.Sound.BaseSound, duration: number, destroy?: boolean) =>
|
SoundFade.fadeOut = ((_scene: Phaser.Scene, sound: Phaser.Sound.BaseSound, duration: number, destroy?: boolean) =>
|
||||||
originalFadeOut(globalScene, sound, transformValue(duration), destroy)) as FadeOut;
|
originalFadeOut(globalScene, sound, transformValue(duration), destroy)) as FadeOutType;
|
||||||
|
|
||||||
const originalFadeIn = SoundFade.fadeIn;
|
const originalFadeIn = SoundFade.fadeIn;
|
||||||
SoundFade.fadeIn = ((
|
SoundFade.fadeIn = ((
|
||||||
@ -110,5 +110,5 @@ export function initGameSpeed() {
|
|||||||
duration: number,
|
duration: number,
|
||||||
endVolume?: number,
|
endVolume?: number,
|
||||||
startVolume?: number,
|
startVolume?: number,
|
||||||
) => originalFadeIn(globalScene, sound, transformValue(duration), endVolume, startVolume)) as FadeIn;
|
) => originalFadeIn(globalScene, sound, transformValue(duration), endVolume, startVolume)) as FadeInType;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import type { PokeballType } from "#enums/pokeball";
|
|||||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "../data/pokemon-species";
|
import { getPokemonSpecies, getPokemonSpeciesForm } from "../data/pokemon-species";
|
||||||
import { Status } from "../data/status-effect";
|
import { Status } from "../data/status-effect";
|
||||||
import Pokemon, { EnemyPokemon, PokemonMove, PokemonSummonData } from "../field/pokemon";
|
import Pokemon, { EnemyPokemon, PokemonMove, PokemonSummonData } from "../field/pokemon";
|
||||||
import { TrainerSlot } from "../data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import type { Variant } from "#app/data/variant";
|
import type { Variant } from "#app/data/variant";
|
||||||
import { loadBattlerTag } from "../data/battler-tags";
|
import { loadBattlerTag } from "../data/battler-tags";
|
||||||
import type { Biome } from "#enums/biome";
|
import type { Biome } from "#enums/biome";
|
||||||
@ -14,7 +14,6 @@ import { Moves } from "#enums/moves";
|
|||||||
import type { Species } from "#enums/species";
|
import type { Species } from "#enums/species";
|
||||||
import { CustomPokemonData } from "#app/data/custom-pokemon-data";
|
import { CustomPokemonData } from "#app/data/custom-pokemon-data";
|
||||||
import type { PokemonType } from "#enums/pokemon-type";
|
import type { PokemonType } from "#enums/pokemon-type";
|
||||||
import { getSpeciesFormChangeMessage } from "#app/data/pokemon-forms";
|
|
||||||
|
|
||||||
export default class PokemonData {
|
export default class PokemonData {
|
||||||
public id: number;
|
public id: number;
|
||||||
|
@ -950,7 +950,7 @@ export function setSetting(setting: string, value: number): boolean {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Català",
|
label: "Català",
|
||||||
handler: () => changeLocaleHandler("ca-ES")
|
handler: () => changeLocaleHandler("ca-ES"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: i18next.t("settings:back"),
|
label: i18next.t("settings:back"),
|
||||||
|
@ -3,7 +3,7 @@ import { AchvTier, achvs, getAchievementDescription } from "./achv";
|
|||||||
import type { PlayerGender } from "#enums/player-gender";
|
import type { PlayerGender } from "#enums/player-gender";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import type { ConditionFn } from "#app/@types/common";
|
import type { ConditionFn } from "#app/@types/common";
|
||||||
import { trainerConfigs } from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||||
|
|
||||||
export enum VoucherType {
|
export enum VoucherType {
|
||||||
REGULAR,
|
REGULAR,
|
||||||
|
@ -77,7 +77,7 @@ export default abstract class MessageUiHandler extends AwaitableUiHandler {
|
|||||||
const actionPattern = /@(c|d|s|f)\{(.*?)\}/;
|
const actionPattern = /@(c|d|s|f)\{(.*?)\}/;
|
||||||
let actionMatch: RegExpExecArray | null;
|
let actionMatch: RegExpExecArray | null;
|
||||||
const pokename: string[] = [];
|
const pokename: string[] = [];
|
||||||
const repname = [ "#POKEMON1", "#POKEMON2" ];
|
const repname = ["#POKEMON1", "#POKEMON2"];
|
||||||
for (let p = 0; p < globalScene.getPlayerField().length; p++) {
|
for (let p = 0; p < globalScene.getPlayerField().length; p++) {
|
||||||
pokename.push(globalScene.getPlayerField()[p].getNameToRender());
|
pokename.push(globalScene.getPlayerField()[p].getNameToRender());
|
||||||
text = text.split(pokename[p]).join(repname[p]);
|
text = text.split(pokename[p]).join(repname[p]);
|
||||||
|
@ -1150,8 +1150,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
|||||||
});
|
});
|
||||||
this.blockInput = false;
|
this.blockInput = false;
|
||||||
} else {
|
} else {
|
||||||
ui.revertMode()
|
ui.revertMode().then(() => {
|
||||||
.then(() => {
|
|
||||||
console.log("exitCallback", this.exitCallback);
|
console.log("exitCallback", this.exitCallback);
|
||||||
if (this.exitCallback instanceof Function) {
|
if (this.exitCallback instanceof Function) {
|
||||||
const exitCallback = this.exitCallback;
|
const exitCallback = this.exitCallback;
|
||||||
|
@ -12,7 +12,7 @@ import { getStarterValueFriendshipCap, speciesStarterCosts, POKERUS_STARTER_COUN
|
|||||||
import { catchableSpecies } from "#app/data/balance/biomes";
|
import { catchableSpecies } from "#app/data/balance/biomes";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import type { DexAttrProps, DexEntry, StarterAttributes, StarterPreferences } from "#app/system/game-data";
|
import type { DexAttrProps, DexEntry, StarterAttributes, StarterPreferences } from "#app/system/game-data";
|
||||||
import { AbilityAttr, DexAttr, loadStarterPreferences, saveStarterPreferences } from "#app/system/game-data";
|
import { AbilityAttr, DexAttr, loadStarterPreferences } from "#app/system/game-data";
|
||||||
import MessageUiHandler from "#app/ui/message-ui-handler";
|
import MessageUiHandler from "#app/ui/message-ui-handler";
|
||||||
import PokemonIconAnimHandler, { PokemonIconAnimMode } from "#app/ui/pokemon-icon-anim-handler";
|
import PokemonIconAnimHandler, { PokemonIconAnimMode } from "#app/ui/pokemon-icon-anim-handler";
|
||||||
import { TextStyle, addTextObject } from "#app/ui/text";
|
import { TextStyle, addTextObject } from "#app/ui/text";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { CandyUpgradeNotificationChangedEvent } from "#app/events/battle-scene";
|
import type { CandyUpgradeNotificationChangedEvent } from "#app/events/battle-scene";
|
||||||
import { BattleSceneEventType } from "#app/events/battle-scene";
|
import { BattleSceneEventType } from "#app/events/battle-scene";
|
||||||
import { pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import type { Variant } from "#app/data/variant";
|
import type { Variant } from "#app/data/variant";
|
||||||
import { getVariantTint, getVariantIcon } from "#app/data/variant";
|
import { getVariantTint, getVariantIcon } from "#app/data/variant";
|
||||||
import { argbFromRgba } from "@material/material-color-utilities";
|
import { argbFromRgba } from "@material/material-color-utilities";
|
||||||
@ -19,7 +19,7 @@ import { pokemonFormChanges } from "#app/data/pokemon-forms";
|
|||||||
import type { LevelMoves } from "#app/data/balance/pokemon-level-moves";
|
import type { LevelMoves } from "#app/data/balance/pokemon-level-moves";
|
||||||
import { pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "#app/data/balance/pokemon-level-moves";
|
import { pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "#app/data/balance/pokemon-level-moves";
|
||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
import type PokemonSpecies from "#app/data/pokemon-species";
|
||||||
import { allSpecies, getPokemonSpecies, getPokemonSpeciesForm, getPokerusStarters } from "#app/data/pokemon-species";
|
import { allSpecies, getPokemonSpeciesForm, getPokerusStarters } from "#app/data/pokemon-species";
|
||||||
import { getStarterValueFriendshipCap, speciesStarterCosts, POKERUS_STARTER_COUNT } from "#app/data/balance/starters";
|
import { getStarterValueFriendshipCap, speciesStarterCosts, POKERUS_STARTER_COUNT } from "#app/data/balance/starters";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { GameModes } from "#app/game-mode";
|
import { GameModes } from "#app/game-mode";
|
||||||
|
@ -329,7 +329,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
|||||||
promptDelay?: number | null,
|
promptDelay?: number | null,
|
||||||
): void {
|
): void {
|
||||||
const pokename: string[] = [];
|
const pokename: string[] = [];
|
||||||
const repname = [ "#POKEMON1", "#POKEMON2" ];
|
const repname = ["#POKEMON1", "#POKEMON2"];
|
||||||
for (let p = 0; p < globalScene.getPlayerField().length; p++) {
|
for (let p = 0; p < globalScene.getPlayerField().length; p++) {
|
||||||
pokename.push(globalScene.getPlayerField()[p].getNameToRender());
|
pokename.push(globalScene.getPlayerField()[p].getNameToRender());
|
||||||
text = text.split(pokename[p]).join(repname[p]);
|
text = text.split(pokename[p]).join(repname[p]);
|
||||||
|
@ -135,10 +135,8 @@ describe("Abilities - Desolate Land", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should lift after fleeing from a wild pokemon", async () => {
|
it("should lift after fleeing from a wild pokemon", async () => {
|
||||||
game.override
|
game.override.enemyAbility(Abilities.DESOLATE_LAND).ability(Abilities.BALL_FETCH);
|
||||||
.enemyAbility(Abilities.DESOLATE_LAND)
|
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||||
.ability(Abilities.BALL_FETCH);
|
|
||||||
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
|
||||||
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN);
|
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN);
|
||||||
|
|
||||||
vi.spyOn(game.scene.getPlayerPokemon()!, "randSeedInt").mockReturnValue(0);
|
vi.spyOn(game.scene.getPlayerPokemon()!, "randSeedInt").mockReturnValue(0);
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { allAbilities } from "#app/data/ability";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { Abilities } from "#app/enums/abilities";
|
||||||
import { Stat } from "#app/enums/stat";
|
import { Stat } from "#app/enums/stat";
|
||||||
import { WeatherType } from "#app/enums/weather-type";
|
import { WeatherType } from "#app/enums/weather-type";
|
||||||
|
import { TurnEndPhase } from "#app/phases/turn-end-phase";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
describe("Abilities - Flower Gift", () => {
|
describe("Abilities - Flower Gift", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
@ -28,6 +30,64 @@ describe("Abilities - Flower Gift", () => {
|
|||||||
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(OVERCAST_FORM);
|
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(OVERCAST_FORM);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests damage dealt by a move used against a target before and after Flower Gift is activated.
|
||||||
|
* @param game The game manager instance
|
||||||
|
* @param move The move that should be used
|
||||||
|
* @param allyAttacker True if the ally is attacking the enemy, false if the enemy is attacking the ally
|
||||||
|
* @param ability The ability that the ally pokemon should have
|
||||||
|
* @param enemyAbility The ability that the enemy pokemon should have
|
||||||
|
*
|
||||||
|
* @returns Two numbers, the first being the damage done to the target without flower gift active, the second being the damage done with flower gift active
|
||||||
|
*/
|
||||||
|
const testDamageDealt = async (
|
||||||
|
game: GameManager,
|
||||||
|
move: Moves,
|
||||||
|
allyAttacker: boolean,
|
||||||
|
allyAbility = Abilities.BALL_FETCH,
|
||||||
|
enemyAbility = Abilities.BALL_FETCH,
|
||||||
|
): Promise<[number, number]> => {
|
||||||
|
game.override.battleType("double");
|
||||||
|
game.override.moveset([Moves.SPLASH, Moves.SUNNY_DAY, move, Moves.HEAL_PULSE]);
|
||||||
|
game.override.enemyMoveset([Moves.SPLASH, Moves.HEAL_PULSE]);
|
||||||
|
const target_index = allyAttacker ? BattlerIndex.ENEMY : BattlerIndex.PLAYER_2;
|
||||||
|
const attacker_index = allyAttacker ? BattlerIndex.PLAYER_2 : BattlerIndex.ENEMY;
|
||||||
|
const ally_move = allyAttacker ? move : Moves.SPLASH;
|
||||||
|
const enemy_move = allyAttacker ? Moves.SPLASH : move;
|
||||||
|
const ally_target = allyAttacker ? BattlerIndex.ENEMY : null;
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]);
|
||||||
|
const target = allyAttacker ? game.scene.getEnemyField()[0] : game.scene.getPlayerField()[1];
|
||||||
|
const initialHp = target.getMaxHp();
|
||||||
|
|
||||||
|
// Override the ability for the target and attacker only
|
||||||
|
vi.spyOn(game.scene.getPlayerField()[1], "getAbility").mockReturnValue(allAbilities[allyAbility]);
|
||||||
|
vi.spyOn(game.scene.getEnemyField()[0], "getAbility").mockReturnValue(allAbilities[enemyAbility]);
|
||||||
|
|
||||||
|
// turn 1
|
||||||
|
game.move.select(Moves.SUNNY_DAY, 0);
|
||||||
|
game.move.select(ally_move, 1, ally_target);
|
||||||
|
await game.forceEnemyMove(enemy_move, BattlerIndex.PLAYER_2);
|
||||||
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
|
// Ensure sunny day is used last.
|
||||||
|
await game.setTurnOrder([attacker_index, target_index, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
const damageWithoutGift = initialHp - target.hp;
|
||||||
|
|
||||||
|
target.hp = initialHp;
|
||||||
|
|
||||||
|
// turn 2. Make target use recover to reset hp calculation.
|
||||||
|
game.move.select(Moves.SPLASH, 0, target_index);
|
||||||
|
game.move.select(ally_move, 1, ally_target);
|
||||||
|
await game.forceEnemyMove(enemy_move, BattlerIndex.PLAYER_2);
|
||||||
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
|
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, target_index, attacker_index]);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
const damageWithGift = initialHp - target.hp;
|
||||||
|
|
||||||
|
return [damageWithoutGift, damageWithGift];
|
||||||
|
};
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
type: Phaser.HEADLESS,
|
type: Phaser.HEADLESS,
|
||||||
@ -41,23 +101,24 @@ describe("Abilities - Flower Gift", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.moveset([Moves.SPLASH, Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.SKILL_SWAP])
|
.moveset([Moves.SPLASH, Moves.SUNSTEEL_STRIKE, Moves.SUNNY_DAY, Moves.MUD_SLAP])
|
||||||
.enemySpecies(Species.MAGIKARP)
|
.enemySpecies(Species.MAGIKARP)
|
||||||
.enemyMoveset(Moves.SPLASH)
|
.enemyMoveset(Moves.SPLASH)
|
||||||
.enemyAbility(Abilities.BALL_FETCH);
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.enemyLevel(100)
|
||||||
|
.startingLevel(100);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Uncomment expect statements when the ability is implemented - currently does not increase stats of allies
|
|
||||||
it("increases the ATK and SPDEF stat stages of the Pokémon with this Ability and its allies by 1.5× during Harsh Sunlight", async () => {
|
it("increases the ATK and SPDEF stat stages of the Pokémon with this Ability and its allies by 1.5× during Harsh Sunlight", async () => {
|
||||||
game.override.battleType("double");
|
game.override.battleType("double");
|
||||||
await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]);
|
await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]);
|
||||||
|
|
||||||
const [cherrim] = game.scene.getPlayerField();
|
const [cherrim, magikarp] = game.scene.getPlayerField();
|
||||||
const cherrimAtkStat = cherrim.getEffectiveStat(Stat.ATK);
|
const cherrimAtkStat = cherrim.getEffectiveStat(Stat.ATK);
|
||||||
const cherrimSpDefStat = cherrim.getEffectiveStat(Stat.SPDEF);
|
const cherrimSpDefStat = cherrim.getEffectiveStat(Stat.SPDEF);
|
||||||
|
|
||||||
// const magikarpAtkStat = magikarp.getEffectiveStat(Stat.ATK);;
|
const magikarpAtkStat = magikarp.getEffectiveStat(Stat.ATK);
|
||||||
// const magikarpSpDefStat = magikarp.getEffectiveStat(Stat.SPDEF);
|
const magikarpSpDefStat = magikarp.getEffectiveStat(Stat.SPDEF);
|
||||||
|
|
||||||
game.move.select(Moves.SUNNY_DAY, 0);
|
game.move.select(Moves.SUNNY_DAY, 0);
|
||||||
game.move.select(Moves.SPLASH, 1);
|
game.move.select(Moves.SPLASH, 1);
|
||||||
@ -68,8 +129,34 @@ describe("Abilities - Flower Gift", () => {
|
|||||||
expect(cherrim.formIndex).toBe(SUNSHINE_FORM);
|
expect(cherrim.formIndex).toBe(SUNSHINE_FORM);
|
||||||
expect(cherrim.getEffectiveStat(Stat.ATK)).toBe(Math.floor(cherrimAtkStat * 1.5));
|
expect(cherrim.getEffectiveStat(Stat.ATK)).toBe(Math.floor(cherrimAtkStat * 1.5));
|
||||||
expect(cherrim.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(cherrimSpDefStat * 1.5));
|
expect(cherrim.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(cherrimSpDefStat * 1.5));
|
||||||
// expect(magikarp.getEffectiveStat(Stat.ATK)).toBe(Math.floor(magikarpAtkStat * 1.5));
|
expect(magikarp.getEffectiveStat(Stat.ATK)).toBe(Math.floor(magikarpAtkStat * 1.5));
|
||||||
// expect(magikarp.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(magikarpSpDefStat * 1.5));
|
expect(magikarp.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(magikarpSpDefStat * 1.5));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not increase the damage of an ally using an ability ignoring move", async () => {
|
||||||
|
const [damageWithGift, damageWithoutGift] = await testDamageDealt(game, Moves.SUNSTEEL_STRIKE, true);
|
||||||
|
expect(damageWithGift).toBe(damageWithoutGift);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not increase the damage of a mold breaker ally", async () => {
|
||||||
|
const [damageWithGift, damageWithoutGift] = await testDamageDealt(game, Moves.TACKLE, true, Abilities.MOLD_BREAKER);
|
||||||
|
expect(damageWithGift).toBe(damageWithoutGift);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should decrease the damage an ally takes from a special attack", async () => {
|
||||||
|
const [damageWithoutGift, damageWithGift] = await testDamageDealt(game, Moves.MUD_SLAP, false);
|
||||||
|
expect(damageWithGift).toBeLessThan(damageWithoutGift);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not decrease the damage an ally takes from a mold breaker enemy using a special attack", async () => {
|
||||||
|
const [damageWithoutGift, damageWithGift] = await testDamageDealt(
|
||||||
|
game,
|
||||||
|
Moves.MUD_SLAP,
|
||||||
|
false,
|
||||||
|
Abilities.BALL_FETCH,
|
||||||
|
Abilities.MOLD_BREAKER,
|
||||||
|
);
|
||||||
|
expect(damageWithGift).toBe(damageWithoutGift);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("changes the Pokemon's form during Harsh Sunlight", async () => {
|
it("changes the Pokemon's form during Harsh Sunlight", async () => {
|
||||||
|
@ -160,10 +160,8 @@ describe("Abilities - Neutralizing Gas", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should deactivate after fleeing from a wild pokemon", async () => {
|
it("should deactivate after fleeing from a wild pokemon", async () => {
|
||||||
game.override
|
game.override.enemyAbility(Abilities.NEUTRALIZING_GAS).ability(Abilities.BALL_FETCH);
|
||||||
.enemyAbility(Abilities.NEUTRALIZING_GAS)
|
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||||
.ability(Abilities.BALL_FETCH);
|
|
||||||
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
|
||||||
expect(game.scene.arena.getTag(ArenaTagType.NEUTRALIZING_GAS)).toBeDefined();
|
expect(game.scene.arena.getTag(ArenaTagType.NEUTRALIZING_GAS)).toBeDefined();
|
||||||
|
|
||||||
vi.spyOn(game.scene.getPlayerPokemon()!, "randSeedInt").mockReturnValue(0);
|
vi.spyOn(game.scene.getPlayerPokemon()!, "randSeedInt").mockReturnValue(0);
|
||||||
|
@ -9,6 +9,7 @@ import { StatusEffect } from "#enums/status-effect";
|
|||||||
import GameManager from "#test/testUtils/gameManager";
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
|
||||||
describe("Abilities - Parental Bond", () => {
|
describe("Abilities - Parental Bond", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
@ -426,4 +427,21 @@ describe("Abilities - Parental Bond", () => {
|
|||||||
// TODO: Update hit count to 1 once Future Sight is fixed to not activate abilities if user is off the field
|
// TODO: Update hit count to 1 once Future Sight is fixed to not activate abilities if user is off the field
|
||||||
expect(enemyPokemon.damageAndUpdate).toHaveBeenCalledTimes(2);
|
expect(enemyPokemon.damageAndUpdate).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should not allow Pollen Puff to heal ally more than once", async () => {
|
||||||
|
game.override.battleType("double").moveset([Moves.POLLEN_PUFF, Moves.ENDURE]);
|
||||||
|
await game.classicMode.startBattle([Species.BULBASAUR, Species.OMANYTE]);
|
||||||
|
|
||||||
|
const [, rightPokemon] = game.scene.getPlayerField();
|
||||||
|
|
||||||
|
rightPokemon.damageAndUpdate(rightPokemon.hp - 1);
|
||||||
|
|
||||||
|
game.move.select(Moves.POLLEN_PUFF, 0, BattlerIndex.PLAYER_2);
|
||||||
|
game.move.select(Moves.ENDURE, 1);
|
||||||
|
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
// Pollen Puff heals with a ratio of 0.5, as long as Pollen Puff triggers only once the pokemon will always be <= (0.5 * Max HP) + 1
|
||||||
|
expect(rightPokemon.hp).toBeLessThanOrEqual(0.5 * rightPokemon.getMaxHp() + 1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -46,16 +46,56 @@ describe("Abilities - Protosynthesis", () => {
|
|||||||
// Nature of starting mon is randomized. We need to fix it to a neutral nature for the automated test.
|
// Nature of starting mon is randomized. We need to fix it to a neutral nature for the automated test.
|
||||||
mew.setNature(Nature.HARDY);
|
mew.setNature(Nature.HARDY);
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
const def_before_boost = mew.getEffectiveStat(Stat.DEF, undefined, undefined, false, undefined, false, false, true);
|
const def_before_boost = mew.getEffectiveStat(
|
||||||
const atk_before_boost = mew.getEffectiveStat(Stat.ATK, undefined, undefined, false, undefined, false, false, true);
|
Stat.DEF,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
const atk_before_boost = mew.getEffectiveStat(
|
||||||
|
Stat.ATK,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
);
|
||||||
const initialHp = enemy.hp;
|
const initialHp = enemy.hp;
|
||||||
game.move.select(Moves.TACKLE);
|
game.move.select(Moves.TACKLE);
|
||||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
const unboosted_dmg = initialHp - enemy.hp;
|
const unboosted_dmg = initialHp - enemy.hp;
|
||||||
enemy.hp = initialHp;
|
enemy.hp = initialHp;
|
||||||
const def_after_boost = mew.getEffectiveStat(Stat.DEF, undefined, undefined, false, undefined, false, false, true);
|
const def_after_boost = mew.getEffectiveStat(
|
||||||
const atk_after_boost = mew.getEffectiveStat(Stat.ATK, undefined, undefined, false, undefined, false, false, true);
|
Stat.DEF,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
const atk_after_boost = mew.getEffectiveStat(
|
||||||
|
Stat.ATK,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
);
|
||||||
game.move.select(Moves.TACKLE);
|
game.move.select(Moves.TACKLE);
|
||||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
60
test/abilities/victory_star.test.ts
Normal file
60
test/abilities/victory_star.test.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { TurnEndPhase } from "#app/phases/turn-end-phase";
|
||||||
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
describe("Abilities - Victory Star", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
game.override
|
||||||
|
.moveset([Moves.TACKLE, Moves.SPLASH])
|
||||||
|
.battleType("double")
|
||||||
|
.disableCrits()
|
||||||
|
.enemySpecies(Species.MAGIKARP)
|
||||||
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.enemyMoveset(Moves.SPLASH);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should increase the accuracy of its user", async () => {
|
||||||
|
await game.classicMode.startBattle([Species.VICTINI, Species.MAGIKARP]);
|
||||||
|
|
||||||
|
const user = game.scene.getPlayerField()[0];
|
||||||
|
|
||||||
|
vi.spyOn(user, "getAccuracyMultiplier");
|
||||||
|
game.move.select(Moves.TACKLE, 0, BattlerIndex.ENEMY);
|
||||||
|
game.move.select(Moves.SPLASH, 1);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
expect(user.getAccuracyMultiplier).toHaveReturnedWith(1.1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should increase the accuracy of its user's ally", async () => {
|
||||||
|
await game.classicMode.startBattle([Species.MAGIKARP, Species.VICTINI]);
|
||||||
|
|
||||||
|
const ally = game.scene.getPlayerField()[0];
|
||||||
|
vi.spyOn(ally, "getAccuracyMultiplier");
|
||||||
|
|
||||||
|
game.move.select(Moves.TACKLE, 0, BattlerIndex.ENEMY);
|
||||||
|
game.move.select(Moves.SPLASH, 1);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
|
||||||
|
expect(ally.getAccuracyMultiplier).toHaveReturnedWith(1.1);
|
||||||
|
});
|
||||||
|
});
|
@ -1,4 +1,3 @@
|
|||||||
import { allAbilities } from "#app/data/ability";
|
|
||||||
import { allMoves } from "#app/data/moves/move";
|
import { allMoves } from "#app/data/moves/move";
|
||||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
|
@ -9,7 +9,7 @@ describe("Data - Splash Messages", () => {
|
|||||||
|
|
||||||
// Make sure to adjust this test if the weight is changed!
|
// Make sure to adjust this test if the weight is changed!
|
||||||
it("should add contain 15 `battlesWon` splash messages", () => {
|
it("should add contain 15 `battlesWon` splash messages", () => {
|
||||||
const battlesWonMessages = getSplashMessages().filter((message) => message === "splashMessages:battlesWon");
|
const battlesWonMessages = getSplashMessages().filter(message => message === "splashMessages:battlesWon");
|
||||||
expect(battlesWonMessages).toHaveLength(15);
|
expect(battlesWonMessages).toHaveLength(15);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -98,6 +98,31 @@ describe("Items - Grip Claw", () => {
|
|||||||
expect(enemy1HeldItemCountsAfter).toBe(enemy1HeldItemCount);
|
expect(enemy1HeldItemCountsAfter).toBe(enemy1HeldItemCount);
|
||||||
expect(enemy2HeldItemCountsAfter).toBe(enemy2HeldItemCount);
|
expect(enemy2HeldItemCountsAfter).toBe(enemy2HeldItemCount);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should not allow Pollen Puff to steal items when healing ally", async () => {
|
||||||
|
game.override
|
||||||
|
.battleType("double")
|
||||||
|
.moveset([Moves.POLLEN_PUFF, Moves.ENDURE])
|
||||||
|
.startingHeldItems([
|
||||||
|
{ name: "GRIP_CLAW", count: 1 },
|
||||||
|
{ name: "BERRY", type: BerryType.LUM, count: 1 },
|
||||||
|
]);
|
||||||
|
await game.classicMode.startBattle([Species.BULBASAUR, Species.OMANYTE]);
|
||||||
|
|
||||||
|
const [leftPokemon, rightPokemon] = game.scene.getPlayerField();
|
||||||
|
|
||||||
|
const gripClaw = leftPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier;
|
||||||
|
vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100);
|
||||||
|
|
||||||
|
const heldItemCountBefore = getHeldItemCount(rightPokemon);
|
||||||
|
|
||||||
|
game.move.select(Moves.POLLEN_PUFF, 0, BattlerIndex.PLAYER_2);
|
||||||
|
game.move.select(Moves.ENDURE, 1);
|
||||||
|
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(getHeldItemCount(rightPokemon)).toBe(heldItemCountBefore);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -211,4 +211,21 @@ describe("Items - Multi Lens", () => {
|
|||||||
// TODO: Update hit count to 1 once Future Sight is fixed to not activate held items if user is off the field
|
// TODO: Update hit count to 1 once Future Sight is fixed to not activate held items if user is off the field
|
||||||
expect(enemyPokemon.damageAndUpdate).toHaveBeenCalledTimes(2);
|
expect(enemyPokemon.damageAndUpdate).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should not allow Pollen Puff to heal ally more than once", async () => {
|
||||||
|
game.override.battleType("double").moveset([Moves.POLLEN_PUFF, Moves.ENDURE]);
|
||||||
|
await game.classicMode.startBattle([Species.BULBASAUR, Species.OMANYTE]);
|
||||||
|
|
||||||
|
const [, rightPokemon] = game.scene.getPlayerField();
|
||||||
|
|
||||||
|
rightPokemon.damageAndUpdate(rightPokemon.hp - 1);
|
||||||
|
|
||||||
|
game.move.select(Moves.POLLEN_PUFF, 0, BattlerIndex.PLAYER_2);
|
||||||
|
game.move.select(Moves.ENDURE, 1);
|
||||||
|
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
// Pollen Puff heals with a ratio of 0.5, as long as Pollen Puff triggers only once the pokemon will always be <= (0.5 * Max HP) + 1
|
||||||
|
expect(rightPokemon.hp).toBeLessThanOrEqual(0.5 * rightPokemon.getMaxHp() + 1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -26,7 +26,7 @@ describe("Items - Reviver Seed", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.moveset([ Moves.SPLASH, Moves.TACKLE, Moves.ENDURE ])
|
.moveset([Moves.SPLASH, Moves.TACKLE, Moves.ENDURE])
|
||||||
.ability(Abilities.BALL_FETCH)
|
.ability(Abilities.BALL_FETCH)
|
||||||
.battleType("single")
|
.battleType("single")
|
||||||
.disableCrits()
|
.disableCrits()
|
||||||
@ -47,13 +47,10 @@ describe("Items - Reviver Seed", () => {
|
|||||||
{ moveType: "Fixed Damage Move", move: Moves.SEISMIC_TOSS },
|
{ moveType: "Fixed Damage Move", move: Moves.SEISMIC_TOSS },
|
||||||
{ moveType: "Final Gambit", move: Moves.FINAL_GAMBIT },
|
{ moveType: "Final Gambit", move: Moves.FINAL_GAMBIT },
|
||||||
{ moveType: "Counter", move: Moves.COUNTER },
|
{ moveType: "Counter", move: Moves.COUNTER },
|
||||||
{ moveType: "OHKO", move: Moves.SHEER_COLD }
|
{ moveType: "OHKO", move: Moves.SHEER_COLD },
|
||||||
])("should activate the holder's reviver seed from a $moveType", async ({ move }) => {
|
])("should activate the holder's reviver seed from a $moveType", async ({ move }) => {
|
||||||
game.override
|
game.override.enemyLevel(100).startingLevel(1).enemyMoveset(move);
|
||||||
.enemyLevel(100)
|
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]);
|
||||||
.startingLevel(1)
|
|
||||||
.enemyMoveset(move);
|
|
||||||
await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]);
|
|
||||||
const player = game.scene.getPlayerPokemon()!;
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
player.damageAndUpdate(player.hp - 1);
|
player.damageAndUpdate(player.hp - 1);
|
||||||
|
|
||||||
@ -67,11 +64,8 @@ describe("Items - Reviver Seed", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should activate the holder's reviver seed from confusion self-hit", async () => {
|
it("should activate the holder's reviver seed from confusion self-hit", async () => {
|
||||||
game.override
|
game.override.enemyLevel(1).startingLevel(100).enemyMoveset(Moves.SPLASH);
|
||||||
.enemyLevel(1)
|
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]);
|
||||||
.startingLevel(100)
|
|
||||||
.enemyMoveset(Moves.SPLASH);
|
|
||||||
await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]);
|
|
||||||
const player = game.scene.getPlayerPokemon()!;
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
player.damageAndUpdate(player.hp - 1);
|
player.damageAndUpdate(player.hp - 1);
|
||||||
player.addTag(BattlerTagType.CONFUSED, 3);
|
player.addTag(BattlerTagType.CONFUSED, 3);
|
||||||
@ -100,7 +94,7 @@ describe("Items - Reviver Seed", () => {
|
|||||||
.enemySpecies(Species.MAGIKARP)
|
.enemySpecies(Species.MAGIKARP)
|
||||||
.moveset(move)
|
.moveset(move)
|
||||||
.enemyMoveset(Moves.ENDURE);
|
.enemyMoveset(Moves.ENDURE);
|
||||||
await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]);
|
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]);
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
enemy.damageAndUpdate(enemy.hp - 1);
|
enemy.damageAndUpdate(enemy.hp - 1);
|
||||||
|
|
||||||
@ -124,7 +118,7 @@ describe("Items - Reviver Seed", () => {
|
|||||||
.moveset(move)
|
.moveset(move)
|
||||||
.enemyAbility(Abilities.LIQUID_OOZE)
|
.enemyAbility(Abilities.LIQUID_OOZE)
|
||||||
.enemyMoveset(Moves.SPLASH);
|
.enemyMoveset(Moves.SPLASH);
|
||||||
await game.classicMode.startBattle([ Species.GASTLY, Species.FEEBAS ]);
|
await game.classicMode.startBattle([Species.GASTLY, Species.FEEBAS]);
|
||||||
const player = game.scene.getPlayerPokemon()!;
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
player.damageAndUpdate(player.hp - 1);
|
player.damageAndUpdate(player.hp - 1);
|
||||||
|
|
||||||
@ -145,13 +139,13 @@ describe("Items - Reviver Seed", () => {
|
|||||||
.moveset(Moves.DESTINY_BOND)
|
.moveset(Moves.DESTINY_BOND)
|
||||||
.startingHeldItems([]) // reset held items to nothing so user doesn't revive and not trigger Destiny Bond
|
.startingHeldItems([]) // reset held items to nothing so user doesn't revive and not trigger Destiny Bond
|
||||||
.enemyMoveset(Moves.TACKLE);
|
.enemyMoveset(Moves.TACKLE);
|
||||||
await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]);
|
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]);
|
||||||
const player = game.scene.getPlayerPokemon()!;
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
player.damageAndUpdate(player.hp - 1);
|
player.damageAndUpdate(player.hp - 1);
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
game.move.select(Moves.DESTINY_BOND);
|
game.move.select(Moves.DESTINY_BOND);
|
||||||
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase");
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
|
|
||||||
expect(enemy.isFainted()).toBeTruthy();
|
expect(enemy.isFainted()).toBeTruthy();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { allMoves } from "#app/data/moves/move";
|
import { allMoves } from "#app/data/moves/move";
|
||||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#enums/trainer-slot";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { Abilities } from "#app/enums/abilities";
|
||||||
import { Moves } from "#app/enums/moves";
|
import { Moves } from "#app/enums/moves";
|
||||||
|
@ -22,7 +22,7 @@ describe("Moves - Endure", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.moveset([ Moves.THUNDER, Moves.BULLET_SEED, Moves.TOXIC, Moves.SHEER_COLD ])
|
.moveset([Moves.THUNDER, Moves.BULLET_SEED, Moves.TOXIC, Moves.SHEER_COLD])
|
||||||
.ability(Abilities.SKILL_LINK)
|
.ability(Abilities.SKILL_LINK)
|
||||||
.startingLevel(100)
|
.startingLevel(100)
|
||||||
.battleType("single")
|
.battleType("single")
|
||||||
@ -51,7 +51,7 @@ describe("Moves - Endure", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should let the pokemon survive against OHKO moves", async () => {
|
it("should let the pokemon survive against OHKO moves", async () => {
|
||||||
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
game.move.select(Moves.SHEER_COLD);
|
game.move.select(Moves.SHEER_COLD);
|
||||||
@ -74,7 +74,7 @@ describe("Moves - Endure", () => {
|
|||||||
.enemySpecies(Species.MAGIKARP)
|
.enemySpecies(Species.MAGIKARP)
|
||||||
.moveset(move)
|
.moveset(move)
|
||||||
.enemyMoveset(Moves.ENDURE);
|
.enemyMoveset(Moves.ENDURE);
|
||||||
await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]);
|
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]);
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
enemy.damageAndUpdate(enemy.hp - 1);
|
enemy.damageAndUpdate(enemy.hp - 1);
|
||||||
|
|
||||||
|
53
test/moves/false_swipe.test.ts
Normal file
53
test/moves/false_swipe.test.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { MoveResult } from "#app/field/pokemon";
|
||||||
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
describe("Moves - False Swipe", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
game.override
|
||||||
|
.moveset([Moves.FALSE_SWIPE])
|
||||||
|
.ability(Abilities.BALL_FETCH)
|
||||||
|
.startingLevel(1000)
|
||||||
|
.battleType("single")
|
||||||
|
.disableCrits()
|
||||||
|
.enemySpecies(Species.MAGIKARP)
|
||||||
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.enemyMoveset(Moves.SPLASH);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should reduce the target to 1 HP", async () => {
|
||||||
|
await game.classicMode.startBattle([Species.MILOTIC]);
|
||||||
|
|
||||||
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
game.move.select(Moves.FALSE_SWIPE);
|
||||||
|
await game.toNextTurn();
|
||||||
|
game.move.select(Moves.FALSE_SWIPE);
|
||||||
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
|
expect(enemy.hp).toBe(1);
|
||||||
|
const falseSwipeHistory = player
|
||||||
|
.getMoveHistory()
|
||||||
|
.every(turnMove => turnMove.move === Moves.FALSE_SWIPE && turnMove.result === MoveResult.SUCCESS);
|
||||||
|
expect(falseSwipeHistory).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
@ -116,12 +116,8 @@ describe("Moves - Revival Blessing", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should not summon multiple pokemon to the same slot when reviving the enemy ally in doubles", async () => {
|
it("should not summon multiple pokemon to the same slot when reviving the enemy ally in doubles", async () => {
|
||||||
game.override
|
game.override.battleType("double").enemyMoveset([Moves.REVIVAL_BLESSING]).moveset([Moves.SPLASH]).startingWave(25); // 2nd rival battle - must have 3+ pokemon
|
||||||
.battleType("double")
|
await game.classicMode.startBattle([Species.ARCEUS, Species.GIRATINA]);
|
||||||
.enemyMoveset([ Moves.REVIVAL_BLESSING ])
|
|
||||||
.moveset([ Moves.SPLASH ])
|
|
||||||
.startingWave(25); // 2nd rival battle - must have 3+ pokemon
|
|
||||||
await game.classicMode.startBattle([ Species.ARCEUS, Species.GIRATINA ]);
|
|
||||||
|
|
||||||
const enemyFainting = game.scene.getEnemyField()[0];
|
const enemyFainting = game.scene.getEnemyField()[0];
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils";
|
import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { MysteriousChallengersEncounter } from "#app/data/mystery-encounters/encounters/mysterious-challengers-encounter";
|
import { MysteriousChallengersEncounter } from "#app/data/mystery-encounters/encounters/mysterious-challengers-encounter";
|
||||||
import { TrainerConfig, TrainerPartyCompoundTemplate, TrainerPartyTemplate } from "#app/data/trainer-config";
|
import { TrainerConfig } from "#app/data/trainers/trainer-config";
|
||||||
|
import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
|
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||||
|
@ -1,31 +1,25 @@
|
|||||||
/* eslint-disable */
|
// @ts-nocheck - TODO: remove this
|
||||||
// @ts-nocheck
|
|
||||||
import BattleScene, * as battleScene from "#app/battle-scene";
|
import BattleScene, * as battleScene from "#app/battle-scene";
|
||||||
import { MoveAnim } from "#app/data/battle-anims";
|
import { MoveAnim } from "#app/data/battle-anims";
|
||||||
import Pokemon from "#app/field/pokemon";
|
import Pokemon from "#app/field/pokemon";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import { blobToString } from "#test/testUtils/gameManagerUtils";
|
import { blobToString } from "#test/testUtils/gameManagerUtils";
|
||||||
import { MockClock } from "#test/testUtils/mocks/mockClock";
|
import { MockClock } from "#test/testUtils/mocks/mockClock";
|
||||||
import { MockConsoleLog } from "#test/testUtils/mocks/mockConsoleLog";
|
|
||||||
import { MockFetch } from "#test/testUtils/mocks/mockFetch";
|
import { MockFetch } from "#test/testUtils/mocks/mockFetch";
|
||||||
import MockLoader from "#test/testUtils/mocks/mockLoader";
|
import MockLoader from "#test/testUtils/mocks/mockLoader";
|
||||||
import { mockLocalStorage } from "#test/testUtils/mocks/mockLocalStorage";
|
|
||||||
import { MockImage } from "#test/testUtils/mocks/mocksContainer/mockImage";
|
|
||||||
import MockTextureManager from "#test/testUtils/mocks/mockTextureManager";
|
import MockTextureManager from "#test/testUtils/mocks/mockTextureManager";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import InputText from "phaser3-rex-plugins/plugins/inputtext";
|
|
||||||
import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
|
|
||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
|
import { version } from "../../package.json";
|
||||||
import { MockGameObjectCreator } from "./mocks/mockGameObjectCreator";
|
import { MockGameObjectCreator } from "./mocks/mockGameObjectCreator";
|
||||||
|
import { MockTimedEventManager } from "./mocks/mockTimedEventManager";
|
||||||
import InputManager = Phaser.Input.InputManager;
|
import InputManager = Phaser.Input.InputManager;
|
||||||
import KeyboardManager = Phaser.Input.Keyboard.KeyboardManager;
|
import KeyboardManager = Phaser.Input.Keyboard.KeyboardManager;
|
||||||
import KeyboardPlugin = Phaser.Input.Keyboard.KeyboardPlugin;
|
import KeyboardPlugin = Phaser.Input.Keyboard.KeyboardPlugin;
|
||||||
import GamepadPlugin = Phaser.Input.Gamepad.GamepadPlugin;
|
import GamepadPlugin = Phaser.Input.Gamepad.GamepadPlugin;
|
||||||
import EventEmitter = Phaser.Events.EventEmitter;
|
import EventEmitter = Phaser.Events.EventEmitter;
|
||||||
import UpdateList = Phaser.GameObjects.UpdateList;
|
import UpdateList = Phaser.GameObjects.UpdateList;
|
||||||
import { version } from "../../package.json";
|
|
||||||
import { MockTimedEventManager } from "./mocks/mockTimedEventManager";
|
|
||||||
|
|
||||||
window.URL.createObjectURL = (blob: Blob) => {
|
window.URL.createObjectURL = (blob: Blob) => {
|
||||||
blobToString(blob).then((data: string) => {
|
blobToString(blob).then((data: string) => {
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
import type { Variant } from "#app/data/variant";
|
import type { Variant } from "#app/data/variant";
|
||||||
import { Weather } from "#app/data/weather";
|
import { Weather } from "#app/data/weather";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { Abilities } from "#app/enums/abilities";
|
||||||
import * as GameMode from "#app/game-mode";
|
|
||||||
import type { GameModes } from "#app/game-mode";
|
|
||||||
import { getGameMode } from "#app/game-mode";
|
|
||||||
import type { ModifierOverride } from "#app/modifier/modifier-type";
|
import type { ModifierOverride } from "#app/modifier/modifier-type";
|
||||||
import type { BattleStyle } from "#app/overrides";
|
import type { BattleStyle } from "#app/overrides";
|
||||||
import Overrides, { defaultOverrides } from "#app/overrides";
|
import Overrides, { defaultOverrides } from "#app/overrides";
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { off } from "process";
|
|
||||||
import type { MockGameObject } from "../mockGameObject";
|
import type { MockGameObject } from "../mockGameObject";
|
||||||
|
|
||||||
export default class MockRectangle implements MockGameObject {
|
export default class MockRectangle implements MockGameObject {
|
||||||
|
@ -1,17 +1,4 @@
|
|||||||
import "vitest-canvas-mock";
|
import "vitest-canvas-mock";
|
||||||
|
|
||||||
import { initLoggedInUser } from "#app/account";
|
|
||||||
import { initAbilities } from "#app/data/ability";
|
|
||||||
import { initBiomes } from "#app/data/balance/biomes";
|
|
||||||
import { initEggMoves } from "#app/data/balance/egg-moves";
|
|
||||||
import { initPokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
|
||||||
import { initMoves } from "#app/data/moves/move";
|
|
||||||
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
|
|
||||||
import { initPokemonForms } from "#app/data/pokemon-forms";
|
|
||||||
import { initSpecies } from "#app/data/pokemon-species";
|
|
||||||
import { initAchievements } from "#app/system/achv";
|
|
||||||
import { initVouchers } from "#app/system/voucher";
|
|
||||||
import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
|
|
||||||
import { afterAll, beforeAll, vi } from "vitest";
|
import { afterAll, beforeAll, vi } from "vitest";
|
||||||
|
|
||||||
import { initTestFile } from "./testUtils/testFileInitialization";
|
import { initTestFile } from "./testUtils/testFileInitialization";
|
||||||
@ -20,13 +7,11 @@ import { initTestFile } from "./testUtils/testFileInitialization";
|
|||||||
|
|
||||||
/** Mock the override import to always return default values, ignoring any custom overrides. */
|
/** Mock the override import to always return default values, ignoring any custom overrides. */
|
||||||
vi.mock("#app/overrides", async importOriginal => {
|
vi.mock("#app/overrides", async importOriginal => {
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
||||||
const { defaultOverrides } = await importOriginal<typeof import("#app/overrides")>();
|
const { defaultOverrides } = await importOriginal<typeof import("#app/overrides")>();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
default: defaultOverrides,
|
default: defaultOverrides,
|
||||||
defaultOverrides,
|
defaultOverrides,
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
||||||
} satisfies typeof import("#app/overrides");
|
} satisfies typeof import("#app/overrides");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user