mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-19 14:52:19 +02:00
Merge branch 'beta' into fix-caught-pokedex
This commit is contained in:
commit
5dec940672
@ -72,8 +72,8 @@ import { GameModes, getGameMode } from "#app/game-mode";
|
||||
import FieldSpritePipeline from "#app/pipelines/field-sprite";
|
||||
import SpritePipeline from "#app/pipelines/sprite";
|
||||
import PartyExpBar from "#app/ui/party-exp-bar";
|
||||
import type { TrainerSlot } from "#app/data/trainer-config";
|
||||
import { trainerConfigs } from "#app/data/trainer-config";
|
||||
import type { TrainerSlot } from "./enums/trainer-slot";
|
||||
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
||||
import type TrainerData from "#app/system/trainer-data";
|
||||
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 { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
|
||||
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 type { EnemyPokemon, PlayerPokemon, TurnMove } from "#app/field/pokemon";
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
|
@ -1712,6 +1712,62 @@ export class PostAttackAbAttr extends AbAttr {
|
||||
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
|
||||
* @extends PostAttackAbAttr
|
||||
@ -5594,6 +5650,30 @@ export function applyStatMultiplierAbAttrs(
|
||||
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(
|
||||
attrType: Constructor<PostSetStatusAbAttr>,
|
||||
pokemon: Pokemon,
|
||||
@ -5606,7 +5686,8 @@ export function applyPostSetStatusAbAttrs(
|
||||
attrType,
|
||||
pokemon,
|
||||
(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,
|
||||
);
|
||||
}
|
||||
@ -6437,11 +6518,12 @@ export function initAbilities() {
|
||||
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.SPDEF, 1.5)
|
||||
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), AllyStatMultiplierAbAttr, Stat.ATK, 1.5)
|
||||
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), AllyStatMultiplierAbAttr, Stat.SPDEF, 1.5)
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
.attr(NoFusionAbilityAbAttr)
|
||||
.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 ])
|
||||
.partial() // Should also boosts stats of ally
|
||||
.ignorable(),
|
||||
new Ability(Abilities.BAD_DREAMS, 4)
|
||||
.attr(PostTurnHurtIfSleepingAbAttr),
|
||||
@ -6577,7 +6659,7 @@ export function initAbilities() {
|
||||
.bypassFaint(),
|
||||
new Ability(Abilities.VICTORY_STAR, 5)
|
||||
.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)
|
||||
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTurboblaze", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
|
||||
.attr(MoveAbilityBypassAbAttr),
|
||||
|
@ -1644,7 +1644,9 @@ export class ContactDamageProtectedTag extends ProtectedTag {
|
||||
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
|
||||
const attacker = effectPhase.getPokemon();
|
||||
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;
|
||||
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) => {
|
||||
if (value > highestValue) {
|
||||
highestStat = EFFECTIVE_STATS[i];
|
||||
@ -2240,7 +2242,9 @@ export class SaltCuredTag extends BattlerTag {
|
||||
|
||||
if (!cancelled.value) {
|
||||
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(
|
||||
i18next.t("battlerTags:saltCuredLapse", {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { BattleSpec } from "#enums/battle-spec";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { trainerConfigs } from "./trainer-config";
|
||||
import { trainerConfigs } from "./trainers/trainer-config";
|
||||
|
||||
export interface TrainerTypeMessages {
|
||||
encounter?: string | string[];
|
||||
|
@ -4798,8 +4798,8 @@ export class ShellSideArmCategoryAttr extends VariableMoveCategoryAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const category = (args[0] as Utils.NumberHolder);
|
||||
|
||||
const predictedPhysDmg = target.getBaseDamage(user, move, MoveCategory.PHYSICAL, true, true);
|
||||
const predictedSpecDmg = target.getBaseDamage(user, move, MoveCategory.SPECIAL, true, true);
|
||||
const predictedPhysDmg = target.getBaseDamage(user, move, MoveCategory.PHYSICAL, true, true, true, true);
|
||||
const predictedSpecDmg = target.getBaseDamage(user, move, MoveCategory.SPECIAL, true, true, true, true);
|
||||
|
||||
if (predictedPhysDmg > predictedSpecDmg) {
|
||||
category.value = MoveCategory.PHYSICAL;
|
||||
|
@ -6,7 +6,7 @@ import {
|
||||
setEncounterRewards,
|
||||
transitionMysteryEncounterIntroVisuals,
|
||||
} 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 type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
|
@ -31,7 +31,7 @@ import {
|
||||
catchPokemon,
|
||||
getHighestLevelPlayerPokemon,
|
||||
} 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 type HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||
import type { BerryType } from "#enums/berry-type";
|
||||
|
@ -9,13 +9,10 @@ import {
|
||||
setEncounterRewards,
|
||||
transitionMysteryEncounterIntroVisuals,
|
||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import {
|
||||
getRandomPartyMemberFunc,
|
||||
trainerConfigs,
|
||||
TrainerPartyCompoundTemplate,
|
||||
TrainerPartyTemplate,
|
||||
TrainerSlot,
|
||||
} from "#app/data/trainer-config";
|
||||
import { getRandomPartyMemberFunc, trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||
import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
|
@ -8,7 +8,9 @@ import {
|
||||
setEncounterRewards,
|
||||
transitionMysteryEncounterIntroVisuals,
|
||||
} 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 type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||
import { ModifierPoolType, modifierTypes } from "#app/modifier/modifier-type";
|
||||
|
@ -20,7 +20,7 @@ import {
|
||||
STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER,
|
||||
} from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
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 Pokemon 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 { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
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 Pokemon from "#app/field/pokemon";
|
||||
import { FieldPosition } from "#app/field/pokemon";
|
||||
|
@ -3,7 +3,7 @@ import {
|
||||
selectPokemonForOption,
|
||||
setEncounterRewards,
|
||||
} 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 { MusicPreference } from "#app/system/settings/settings";
|
||||
import type { ModifierTypeOption } from "#app/modifier/modifier-type";
|
||||
|
@ -3,12 +3,10 @@ import {
|
||||
initBattleWithEnemyConfig,
|
||||
setEncounterRewards,
|
||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import {
|
||||
trainerConfigs,
|
||||
TrainerPartyCompoundTemplate,
|
||||
TrainerPartyTemplate,
|
||||
trainerPartyTemplates,
|
||||
} from "#app/data/trainer-config";
|
||||
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||
import { trainerPartyTemplates } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||
import { modifierTypes } from "#app/modifier/modifier-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 type MysteryEncounterOption 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 type { EnemyPokemon } from "#app/field/pokemon";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
|
@ -24,7 +24,7 @@ import { Biome } from "#enums/biome";
|
||||
import { getBiomeKey } from "#app/field/arena";
|
||||
import { PokemonType } from "#enums/pokemon-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 { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||
|
@ -4,7 +4,7 @@ import {
|
||||
initBattleWithEnemyConfig,
|
||||
setEncounterRewards,
|
||||
} 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 { globalScene } from "#app/global-scene";
|
||||
import { randSeedShuffle } from "#app/utils";
|
||||
|
@ -41,7 +41,8 @@ import { TrainerType } from "#enums/trainer-type";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { Nature } from "#enums/nature";
|
||||
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";
|
||||
|
||||
/** i18n namespace for encounter */
|
||||
|
@ -43,8 +43,9 @@ import type { Moves } from "#enums/moves";
|
||||
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
|
||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
import { Status } from "#app/data/status-effect";
|
||||
import type { TrainerConfig } from "#app/data/trainer-config";
|
||||
import { trainerConfigs, TrainerSlot } from "#app/data/trainer-config";
|
||||
import type { TrainerConfig } from "#app/data/trainers/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 { IEggOptions } from "#app/data/egg";
|
||||
import { Egg } from "#app/data/egg";
|
||||
|
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 type { ModifierTypeFunc } 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 * as Utils from "#app/utils";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
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 { tmSpecies } from "#app/data/balance/tms";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import { doubleBattleDialogue } from "#app/data/dialogue";
|
||||
import type { PersistentModifier } from "#app/modifier/modifier";
|
||||
import { TrainerVariant } from "#app/field/trainer";
|
||||
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
|
||||
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 { Species } from "#enums/species";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { Gender } from "#app/data/gender";
|
||||
import { signatureSpecies } from "./balance/signature-species";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import { Moves } from "#enums/moves";
|
||||
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 */
|
||||
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*/
|
||||
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.
|
||||
*/
|
||||
@ -759,430 +536,6 @@ export class TrainerConfig {
|
||||
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.
|
||||
* @param title The title of the evil team admin.
|
||||
@ -1193,7 +546,7 @@ export class TrainerConfig {
|
||||
* **/
|
||||
initForEvilTeamAdmin(
|
||||
title: string,
|
||||
poolName: string,
|
||||
poolName: EvilTeam,
|
||||
signatureSpecies: (Species | Species[])[],
|
||||
specialtyType?: PokemonType,
|
||||
): TrainerConfig {
|
||||
@ -1208,7 +561,7 @@ export class TrainerConfig {
|
||||
this.setPartyTemplates(trainerPartyTemplates.RIVAL_5);
|
||||
|
||||
// Set the species pools for the evil team admin.
|
||||
this.speciesPools = this.speciesPoolPerEvilTeamAdmin(poolName);
|
||||
this.speciesPools = evilAdminTrainerPools[poolName];
|
||||
|
||||
signatureSpecies.forEach((speciesPool, s) => {
|
||||
if (!Array.isArray(speciesPool)) {
|
||||
@ -1637,56 +990,6 @@ export class TrainerConfig {
|
||||
|
||||
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.
|
||||
* Then adds Pokemon to globalScene.
|
||||
@ -2878,7 +2181,7 @@ export const trainerConfigs: TrainerConfigs = {
|
||||
}),
|
||||
[TrainerType.ZINZOLIN]: new TrainerConfig(++t)
|
||||
.setMoneyMultiplier(1.5)
|
||||
.initForEvilTeamAdmin("plasma_sage", "plasma", [Species.CRYOGONAL])
|
||||
.initForEvilTeamAdmin("plasma_sage", "plasma_zinzolin", [Species.CRYOGONAL])
|
||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||
.setBattleBgm("battle_plasma_grunt")
|
||||
.setMixedBattleBgm("battle_plasma_grunt")
|
||||
@ -2886,7 +2189,7 @@ export const trainerConfigs: TrainerConfigs = {
|
||||
.setPartyTemplateFunc(() => getEvilGruntPartyTemplate()),
|
||||
[TrainerType.COLRESS]: new TrainerConfig(++t)
|
||||
.setMoneyMultiplier(1.5)
|
||||
.initForEvilTeamAdmin("plasma_boss", "plasma_2", [Species.KLINKLANG])
|
||||
.initForEvilTeamAdmin("plasma_boss", "plasma_colress", [Species.KLINKLANG])
|
||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||
.setBattleBgm("battle_colress")
|
||||
.setMixedBattleBgm("battle_colress")
|
||||
@ -3105,7 +2408,7 @@ export const trainerConfigs: TrainerConfigs = {
|
||||
}),
|
||||
[TrainerType.OLEANA]: new TrainerConfig(++t)
|
||||
.setMoneyMultiplier(1.5)
|
||||
.initForEvilTeamAdmin("macro_admin", "macro", [Species.GARBODOR])
|
||||
.initForEvilTeamAdmin("macro_admin", "macro_cosmos", [Species.GARBODOR])
|
||||
.setEncounterBgm(TrainerType.PLASMA_GRUNT)
|
||||
.setBattleBgm("battle_plasma_grunt")
|
||||
.setMixedBattleBgm("battle_oleana")
|
||||
@ -3172,7 +2475,7 @@ export const trainerConfigs: TrainerConfigs = {
|
||||
}),
|
||||
[TrainerType.GIACOMO]: new TrainerConfig(++t)
|
||||
.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)
|
||||
.setBattleBgm("battle_plasma_grunt")
|
||||
.setMixedBattleBgm("battle_star_admin")
|
||||
@ -3192,7 +2495,7 @@ export const trainerConfigs: TrainerConfigs = {
|
||||
),
|
||||
[TrainerType.MELA]: new TrainerConfig(++t)
|
||||
.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)
|
||||
.setBattleBgm("battle_plasma_grunt")
|
||||
.setMixedBattleBgm("battle_star_admin")
|
||||
@ -3212,7 +2515,7 @@ export const trainerConfigs: TrainerConfigs = {
|
||||
),
|
||||
[TrainerType.ATTICUS]: new TrainerConfig(++t)
|
||||
.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)
|
||||
.setBattleBgm("battle_plasma_grunt")
|
||||
.setMixedBattleBgm("battle_star_admin")
|
||||
@ -3232,7 +2535,7 @@ export const trainerConfigs: TrainerConfigs = {
|
||||
),
|
||||
[TrainerType.ORTEGA]: new TrainerConfig(++t)
|
||||
.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)
|
||||
.setBattleBgm("battle_plasma_grunt")
|
||||
.setMixedBattleBgm("battle_star_admin")
|
||||
@ -3252,7 +2555,7 @@ export const trainerConfigs: TrainerConfigs = {
|
||||
),
|
||||
[TrainerType.ERI]: new TrainerConfig(++t)
|
||||
.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)
|
||||
.setBattleBgm("battle_plasma_grunt")
|
||||
.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
|
||||
}
|
@ -192,6 +192,9 @@ import {
|
||||
applyPreLeaveFieldAbAttrs,
|
||||
applyOnLoseAbAttrs,
|
||||
PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr,
|
||||
applyAllyStatMultiplierAbAttrs,
|
||||
AllyStatMultiplierAbAttr,
|
||||
MoveAbilityBypassAbAttr,
|
||||
} from "#app/data/ability";
|
||||
import type PokemonData from "#app/system/pokemon-data";
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
@ -222,7 +225,7 @@ import {
|
||||
SpeciesFormChangeStatusEffectTrigger,
|
||||
} from "#app/data/pokemon-forms";
|
||||
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 i18next from "i18next";
|
||||
import { speciesEggMoves } from "#app/data/balance/egg-moves";
|
||||
@ -260,6 +263,7 @@ import {
|
||||
import { Nature } from "#enums/nature";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import { doShinySparkleAnim } from "#app/field/anims";
|
||||
import { MoveFlags } from "#enums/MoveFlags";
|
||||
|
||||
export enum LearnMoveSituation {
|
||||
MISC,
|
||||
@ -1389,6 +1393,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* @param move the {@linkcode Move} being used
|
||||
* @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 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 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`
|
||||
@ -1400,6 +1405,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
move?: Move,
|
||||
ignoreAbility = false,
|
||||
ignoreOppAbility = false,
|
||||
ignoreAllyAbility = false,
|
||||
isCritical = false,
|
||||
simulated = true,
|
||||
ignoreHeldItems = false,
|
||||
@ -1441,6 +1447,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 =
|
||||
statValue.value *
|
||||
this.getStatStageMultiplier(
|
||||
@ -3889,6 +3900,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -3900,6 +3918,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* @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 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 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.
|
||||
@ -3910,6 +3930,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
moveCategory: MoveCategory,
|
||||
ignoreAbility = false,
|
||||
ignoreSourceAbility = false,
|
||||
ignoreAllyAbility = false,
|
||||
ignoreSourceAllyAbility = false,
|
||||
isCritical = false,
|
||||
simulated = true,
|
||||
): number {
|
||||
@ -3932,6 +3954,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
undefined,
|
||||
ignoreSourceAbility,
|
||||
ignoreAbility,
|
||||
ignoreAllyAbility,
|
||||
isCritical,
|
||||
simulated,
|
||||
),
|
||||
@ -3949,6 +3972,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
move,
|
||||
ignoreAbility,
|
||||
ignoreSourceAbility,
|
||||
ignoreSourceAllyAbility,
|
||||
isCritical,
|
||||
simulated,
|
||||
),
|
||||
@ -3983,6 +4007,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* @param move {@linkcode Pokemon} the move used in the attack
|
||||
* @param ignoreAbility If `true`, ignores this Pokemon's defensive 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 simulated If `true`, suppresses changes to game state during the calculation.
|
||||
* @returns a {@linkcode DamageCalculationResult} object with three fields:
|
||||
@ -3995,6 +4021,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
move: Move,
|
||||
ignoreAbility = false,
|
||||
ignoreSourceAbility = false,
|
||||
ignoreAllyAbility = false,
|
||||
ignoreSourceAllyAbility = false,
|
||||
isCritical = false,
|
||||
simulated = true,
|
||||
): DamageCalculationResult {
|
||||
@ -4104,6 +4132,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
moveCategory,
|
||||
ignoreAbility,
|
||||
ignoreSourceAbility,
|
||||
ignoreAllyAbility,
|
||||
ignoreSourceAllyAbility,
|
||||
isCritical,
|
||||
simulated,
|
||||
);
|
||||
@ -4429,7 +4459,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
cancelled,
|
||||
result,
|
||||
damage: dmg,
|
||||
} = this.getAttackDamage(source, move, false, false, isCritical, false);
|
||||
} = this.getAttackDamage(source, move, false, false, false, false, isCritical, false);
|
||||
|
||||
const typeBoost = source.findTag(
|
||||
t =>
|
||||
@ -7114,6 +7144,8 @@ export class EnemyPokemon extends Pokemon {
|
||||
move,
|
||||
!p.battleData.abilityRevealed,
|
||||
false,
|
||||
!p.getAlly()?.battleData.abilityRevealed,
|
||||
false,
|
||||
isCritical,
|
||||
).damage >= p.hp
|
||||
);
|
||||
|
@ -2,15 +2,14 @@ import { globalScene } from "#app/global-scene";
|
||||
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import type { TrainerConfig, TrainerPartyTemplate } from "#app/data/trainer-config";
|
||||
import {
|
||||
TrainerPartyCompoundTemplate,
|
||||
TrainerPoolTier,
|
||||
TrainerSlot,
|
||||
trainerConfigs,
|
||||
trainerPartyTemplates,
|
||||
TeraAIMode,
|
||||
} from "#app/data/trainer-config";
|
||||
import type { TrainerConfig } from "#app/data/trainers/trainer-config";
|
||||
import type { TrainerPartyTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { trainerConfigs } from "#app/data/trainers/trainer-config";
|
||||
import { trainerPartyTemplates } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { TrainerPartyCompoundTemplate } from "#app/data/trainers/TrainerPartyTemplate";
|
||||
import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import { TrainerPoolTier } from "#enums/trainer-pool-tier";
|
||||
import { TeraAIMode } from "#enums/tera-ai-mode";
|
||||
import type { EnemyPokemon } from "#app/field/pokemon";
|
||||
import * as Utils from "#app/utils";
|
||||
import type { PersistentModifier } from "#app/modifier/modifier";
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { TrainerSlot } from "#app/data/trainer-config";
|
||||
import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import { Phase } from "#app/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 { doTrainerExclamation } from "#app/data/mystery-encounters/utils/encounter-phase-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 { EncounterPhaseEvent } from "#app/events/battle-scene";
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
|
@ -5,7 +5,7 @@ import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
|
||||
import { getCharVariantFromDialogue } from "#app/data/dialogue";
|
||||
import type PokemonSpecies 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 { modifierTypes } from "#app/modifier/modifier-type";
|
||||
import { BattlePhase } from "#app/phases/battle-phase";
|
||||
|
@ -22,7 +22,7 @@ import { globalScene } from "#app/global-scene";
|
||||
import { getCharVariantFromDialogue } from "../data/dialogue";
|
||||
import type { OptionSelectSettings } 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 { Phase } from "../phase";
|
||||
import { Mode } from "../ui/ui";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { BattleType } from "#app/battle";
|
||||
import { getPokeballAtlasKey, getPokeballTintColor } from "#app/data/pokeball";
|
||||
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 { addPokeballOpenParticles } from "#app/field/anims";
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
|
@ -3,7 +3,7 @@ import { applyPreSwitchOutAbAttrs, PostDamageForceSwitchAbAttr, PreSwitchOutAbAt
|
||||
import { allMoves, ForceSwitchOutAttr } from "#app/data/moves/move";
|
||||
import { getPokeballTintColor } from "#app/data/pokeball";
|
||||
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 { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { SwitchEffectTransferModifier } from "#app/modifier/modifier";
|
||||
|
@ -1,5 +1,5 @@
|
||||
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 { BattlePhase } from "./battle-phase";
|
||||
import { TestMessagePhase } from "./test-message-phase";
|
||||
|
@ -7,7 +7,7 @@ import * as Utils from "#app/utils";
|
||||
import { BattlePhase } from "./battle-phase";
|
||||
import { ModifierRewardPhase } from "./modifier-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 { Biome } from "#app/enums/biome";
|
||||
import { achvs } from "#app/system/achv";
|
||||
|
@ -17,7 +17,7 @@ import { Unlockables } from "#app/system/unlockables";
|
||||
import { GameModes, getGameMode } from "#app/game-mode";
|
||||
import { BattleType } from "#app/battle";
|
||||
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 { achvs } from "#app/system/achv";
|
||||
import EggData from "#app/system/egg-data";
|
||||
|
@ -6,7 +6,7 @@ import type { PokeballType } from "#enums/pokeball";
|
||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "../data/pokemon-species";
|
||||
import { Status } from "../data/status-effect";
|
||||
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 { loadBattlerTag } from "../data/battler-tags";
|
||||
import type { Biome } from "#enums/biome";
|
||||
|
@ -3,7 +3,7 @@ import { AchvTier, achvs, getAchievementDescription } from "./achv";
|
||||
import type { PlayerGender } from "#enums/player-gender";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
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 {
|
||||
REGULAR,
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { allAbilities } from "#app/data/ability";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
import { Stat } from "#app/enums/stat";
|
||||
import { WeatherType } from "#app/enums/weather-type";
|
||||
import { TurnEndPhase } from "#app/phases/turn-end-phase";
|
||||
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";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
describe("Abilities - Flower Gift", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
@ -28,6 +30,59 @@ describe("Abilities - Flower Gift", () => {
|
||||
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(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
@ -41,23 +96,24 @@ describe("Abilities - Flower Gift", () => {
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
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)
|
||||
.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 () => {
|
||||
game.override.battleType("double");
|
||||
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 cherrimSpDefStat = cherrim.getEffectiveStat(Stat.SPDEF);
|
||||
|
||||
// const magikarpAtkStat = magikarp.getEffectiveStat(Stat.ATK);;
|
||||
// const magikarpSpDefStat = magikarp.getEffectiveStat(Stat.SPDEF);
|
||||
const magikarpAtkStat = magikarp.getEffectiveStat(Stat.ATK);
|
||||
const magikarpSpDefStat = magikarp.getEffectiveStat(Stat.SPDEF);
|
||||
|
||||
game.move.select(Moves.SUNNY_DAY, 0);
|
||||
game.move.select(Moves.SPLASH, 1);
|
||||
@ -68,8 +124,28 @@ describe("Abilities - Flower Gift", () => {
|
||||
expect(cherrim.formIndex).toBe(SUNSHINE_FORM);
|
||||
expect(cherrim.getEffectiveStat(Stat.ATK)).toBe(Math.floor(cherrimAtkStat * 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.SPDEF)).toBe(Math.floor(magikarpSpDefStat * 1.5));
|
||||
expect(magikarp.getEffectiveStat(Stat.ATK)).toBe(Math.floor(magikarpAtkStat * 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 () => {
|
||||
@ -92,6 +168,7 @@ describe("Abilities - Flower Gift", () => {
|
||||
|
||||
it("reverts to Overcast Form when the Pokémon loses Flower Gift, changes form under Harsh Sunlight/Sunny when it regains it", async () => {
|
||||
game.override.enemyMoveset([Moves.SKILL_SWAP]).weather(WeatherType.HARSH_SUN);
|
||||
game.override.moveset([ Moves.SKILL_SWAP ]);
|
||||
|
||||
await game.classicMode.startBattle([Species.CHERRIM]);
|
||||
|
||||
|
@ -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.
|
||||
mew.setNature(Nature.HARDY);
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
const def_before_boost = mew.getEffectiveStat(Stat.DEF, undefined, undefined, false, undefined, false, false, true);
|
||||
const atk_before_boost = mew.getEffectiveStat(Stat.ATK, undefined, undefined, false, undefined, false, false, true);
|
||||
const def_before_boost = mew.getEffectiveStat(
|
||||
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;
|
||||
game.move.select(Moves.TACKLE);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.toNextTurn();
|
||||
const unboosted_dmg = initialHp - enemy.hp;
|
||||
enemy.hp = initialHp;
|
||||
const def_after_boost = mew.getEffectiveStat(Stat.DEF, undefined, undefined, false, undefined, false, false, true);
|
||||
const atk_after_boost = mew.getEffectiveStat(Stat.ATK, undefined, undefined, false, undefined, false, false, true);
|
||||
const def_after_boost = mew.getEffectiveStat(
|
||||
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);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
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,6 +1,6 @@
|
||||
import { allMoves } from "#app/data/moves/move";
|
||||
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 { Abilities } from "#app/enums/abilities";
|
||||
import { Moves } from "#app/enums/moves";
|
||||
|
@ -16,7 +16,9 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { initSceneWithoutEncounterPhase } from "#test/testUtils/gameManagerUtils";
|
||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||
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 { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||
|
Loading…
Reference in New Issue
Block a user