mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-01-19 07:20:57 +00:00
Merge branch 'beta' into refactor/api-requests
This commit is contained in:
commit
e620c68b56
@ -17,7 +17,12 @@ If you have the motivation and experience with Typescript/Javascript (or are wil
|
|||||||
2. Run `npm run start:dev` to locally run the project in `localhost:8000`
|
2. Run `npm run start:dev` to locally run the project in `localhost:8000`
|
||||||
|
|
||||||
#### Linting
|
#### Linting
|
||||||
We're using ESLint as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run eslint` script.
|
We're using ESLint as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run eslint` script. To view the complete rules, check out the [eslint.config.js](./eslint.config.js) file.
|
||||||
|
|
||||||
|
### 📚 Documentation
|
||||||
|
You can find the auto-generated documentation [here](https://pagefaultgames.github.io/pokerogue/main/index.html).
|
||||||
|
For information on enemy AI, check out the [enemy-ai.md](./docs/enemy-ai.md) file.
|
||||||
|
For detailed guidelines on documenting your code, refer to the [comments.md](./docs/comments.md) file.
|
||||||
|
|
||||||
### ❔ FAQ
|
### ❔ FAQ
|
||||||
|
|
||||||
|
@ -41,6 +41,11 @@ export default [
|
|||||||
"keyword-spacing": ["error", { "before": true, "after": true }], // Enforces spacing before and after keywords
|
"keyword-spacing": ["error", { "before": true, "after": true }], // Enforces spacing before and after keywords
|
||||||
"comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after comma
|
"comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after comma
|
||||||
"import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json
|
"import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json
|
||||||
|
"array-bracket-spacing": ["error", "always", { "objectsInArrays": false, "arraysInArrays": false }], // Enforces consistent spacing inside array brackets
|
||||||
|
"object-curly-spacing": ["error", "always", { "arraysInObjects": false, "objectsInObjects": false }], // Enforces consistent spacing inside braces of object literals, destructuring assignments, and import/export specifiers
|
||||||
|
"computed-property-spacing": ["error", "never" ], // Enforces consistent spacing inside computed property brackets
|
||||||
|
"space-infix-ops": ["error", { "int32Hint": false }], // Enforces spacing around infix operators
|
||||||
|
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], // Disallows multiple empty lines
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
1
package-lock.json
generated
1
package-lock.json
generated
@ -7,6 +7,7 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "pokemon-rogue-battle",
|
"name": "pokemon-rogue-battle",
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material/material-color-utilities": "^0.2.7",
|
"@material/material-color-utilities": "^0.2.7",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
|
@ -853,14 +853,14 @@
|
|||||||
"spriteSourceSize": { "x": 7, "y": 2, "w": 27, "h": 26 },
|
"spriteSourceSize": { "x": 7, "y": 2, "w": 27, "h": 26 },
|
||||||
"sourceSize": { "w": 40, "h": 30 }
|
"sourceSize": { "w": 40, "h": 30 }
|
||||||
},
|
},
|
||||||
"981_2.png": {
|
"981_2": {
|
||||||
"frame": { "x": 108, "y": 87, "w": 23, "h": 30 },
|
"frame": { "x": 108, "y": 87, "w": 23, "h": 30 },
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": { "x": 9, "y": 0, "w": 23, "h": 30 },
|
"spriteSourceSize": { "x": 9, "y": 0, "w": 23, "h": 30 },
|
||||||
"sourceSize": { "w": 40, "h": 30 }
|
"sourceSize": { "w": 40, "h": 30 }
|
||||||
},
|
},
|
||||||
"981_3.png": {
|
"981_3": {
|
||||||
"frame": { "x": 246, "y": 86, "w": 23, "h": 30 },
|
"frame": { "x": 246, "y": 86, "w": 23, "h": 30 },
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
|
@ -14,7 +14,7 @@ export function initLoggedInUser(): void {
|
|||||||
export function updateUserInfo(): Promise<[boolean, integer]> {
|
export function updateUserInfo(): Promise<[boolean, integer]> {
|
||||||
return new Promise<[boolean, integer]>(resolve => {
|
return new Promise<[boolean, integer]>(resolve => {
|
||||||
if (bypassLogin) {
|
if (bypassLogin) {
|
||||||
loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: "", hasAdminRole: false};
|
loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: "", hasAdminRole: false };
|
||||||
let lastSessionSlot = -1;
|
let lastSessionSlot = -1;
|
||||||
for (let s = 0; s < 5; s++) {
|
for (let s = 0; s < 5; s++) {
|
||||||
if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) {
|
if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) {
|
||||||
@ -37,7 +37,7 @@ export function updateUserInfo(): Promise<[boolean, integer]> {
|
|||||||
});
|
});
|
||||||
return resolve([ true, 200 ]);
|
return resolve([ true, 200 ]);
|
||||||
}
|
}
|
||||||
pokerogueApi.account.getInfo().then(([accountInfo, status]) => {
|
pokerogueApi.account.getInfo().then(([ accountInfo, status ]) => {
|
||||||
if (!accountInfo) {
|
if (!accountInfo) {
|
||||||
resolve([ false, status ]);
|
resolve([ false, status ]);
|
||||||
return;
|
return;
|
||||||
|
@ -1,57 +1,57 @@
|
|||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import UI from "./ui/ui";
|
import UI from "#app/ui/ui";
|
||||||
import Pokemon, { EnemyPokemon, PlayerPokemon } from "./field/pokemon";
|
import Pokemon, { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
|
||||||
import PokemonSpecies, { allSpecies, getPokemonSpecies, PokemonSpeciesFilter } from "./data/pokemon-species";
|
import PokemonSpecies, { allSpecies, getPokemonSpecies, PokemonSpeciesFilter } from "#app/data/pokemon-species";
|
||||||
import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils";
|
import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||||
import * as Utils from "./utils";
|
import * as Utils from "#app/utils";
|
||||||
import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, Modifier, ModifierBar, ModifierPredicate, MultipleParticipantExpBonusModifier, overrideHeldItems, overrideModifiers, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, TerastallizeModifier, TurnHeldItemTransferModifier } from "./modifier/modifier";
|
import { ConsumableModifier, ConsumablePokemonModifier, DoubleBattleChanceBoosterModifier, ExpBalanceModifier, ExpShareModifier, FusePokemonModifier, HealingBoosterModifier, Modifier, ModifierBar, ModifierPredicate, MultipleParticipantExpBonusModifier, overrideHeldItems, overrideModifiers, PersistentModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, TerastallizeModifier, TurnHeldItemTransferModifier } from "./modifier/modifier";
|
||||||
import { PokeballType } from "./data/pokeball";
|
import { PokeballType } from "#app/data/pokeball";
|
||||||
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims";
|
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "#app/data/battle-anims";
|
||||||
import { Phase } from "./phase";
|
import { Phase } from "#app/phase";
|
||||||
import { initGameSpeed } from "./system/game-speed";
|
import { initGameSpeed } from "#app/system/game-speed";
|
||||||
import { Arena, ArenaBase } from "./field/arena";
|
import { Arena, ArenaBase } from "#app/field/arena";
|
||||||
import { GameData } from "./system/game-data";
|
import { GameData } from "#app/system/game-data";
|
||||||
import { addTextObject, getTextColor, TextStyle } from "./ui/text";
|
import { addTextObject, getTextColor, TextStyle } from "#app/ui/text";
|
||||||
import { allMoves } from "./data/move";
|
import { allMoves } from "#app/data/move";
|
||||||
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getModifierType, getPartyLuckValue, ModifierPoolType, modifierTypes, PokemonHeldItemModifierType } from "./modifier/modifier-type";
|
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getModifierType, getPartyLuckValue, ModifierPoolType, modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||||
import AbilityBar from "./ui/ability-bar";
|
import AbilityBar from "#app/ui/ability-bar";
|
||||||
import { allAbilities, applyAbAttrs, applyPostBattleInitAbAttrs, BlockItemTheftAbAttr, ChangeMovePriorityAbAttr, DoubleBattleChanceAbAttr, PostBattleInitAbAttr } from "./data/ability";
|
import { allAbilities, applyAbAttrs, applyPostBattleInitAbAttrs, BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, PostBattleInitAbAttr } from "#app/data/ability";
|
||||||
import Battle, { BattleType, FixedBattleConfig } from "./battle";
|
import Battle, { BattleType, FixedBattleConfig } from "#app/battle";
|
||||||
import { GameMode, GameModes, getGameMode } from "./game-mode";
|
import { GameMode, GameModes, getGameMode } from "#app/game-mode";
|
||||||
import FieldSpritePipeline from "./pipelines/field-sprite";
|
import FieldSpritePipeline from "#app/pipelines/field-sprite";
|
||||||
import SpritePipeline from "./pipelines/sprite";
|
import SpritePipeline from "#app/pipelines/sprite";
|
||||||
import PartyExpBar from "./ui/party-exp-bar";
|
import PartyExpBar from "#app/ui/party-exp-bar";
|
||||||
import { trainerConfigs, TrainerSlot } from "./data/trainer-config";
|
import { trainerConfigs, TrainerSlot } from "#app/data/trainer-config";
|
||||||
import Trainer, { TrainerVariant } from "./field/trainer";
|
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
||||||
import TrainerData from "./system/trainer-data";
|
import TrainerData from "#app/system/trainer-data";
|
||||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||||
import { pokemonPrevolutions } from "./data/balance/pokemon-evolutions";
|
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import PokeballTray from "./ui/pokeball-tray";
|
import PokeballTray from "#app/ui/pokeball-tray";
|
||||||
import InvertPostFX from "./pipelines/invert";
|
import InvertPostFX from "#app/pipelines/invert";
|
||||||
import { Achv, achvs, ModifierAchv, MoneyAchv } from "./system/achv";
|
import { Achv, achvs, ModifierAchv, MoneyAchv } from "#app/system/achv";
|
||||||
import { Voucher, vouchers } from "./system/voucher";
|
import { Voucher, vouchers } from "#app/system/voucher";
|
||||||
import { Gender } from "./data/gender";
|
import { Gender } from "#app/data/gender";
|
||||||
import UIPlugin from "phaser3-rex-plugins/templates/ui/ui-plugin";
|
import UIPlugin from "phaser3-rex-plugins/templates/ui/ui-plugin";
|
||||||
import { addUiThemeOverrides } from "./ui/ui-theme";
|
import { addUiThemeOverrides } from "#app/ui/ui-theme";
|
||||||
import PokemonData from "./system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { Nature } from "./data/nature";
|
import { Nature } from "#app/data/nature";
|
||||||
import { FormChangeItem, pokemonFormChanges, SpeciesFormChange, SpeciesFormChangeManualTrigger, SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger } from "./data/pokemon-forms";
|
import { FormChangeItem, pokemonFormChanges, SpeciesFormChange, SpeciesFormChangeManualTrigger, SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger } from "#app/data/pokemon-forms";
|
||||||
import { FormChangePhase } from "./phases/form-change-phase";
|
import { FormChangePhase } from "#app/phases/form-change-phase";
|
||||||
import { getTypeRgb } from "./data/type";
|
import { getTypeRgb } from "#app/data/type";
|
||||||
import PokemonSpriteSparkleHandler from "./field/pokemon-sprite-sparkle-handler";
|
import PokemonSpriteSparkleHandler from "#app/field/pokemon-sprite-sparkle-handler";
|
||||||
import CharSprite from "./ui/char-sprite";
|
import CharSprite from "#app/ui/char-sprite";
|
||||||
import DamageNumberHandler from "./field/damage-number-handler";
|
import DamageNumberHandler from "#app/field/damage-number-handler";
|
||||||
import PokemonInfoContainer from "./ui/pokemon-info-container";
|
import PokemonInfoContainer from "#app/ui/pokemon-info-container";
|
||||||
import { biomeDepths, getBiomeName } from "./data/balance/biomes";
|
import { biomeDepths, getBiomeName } from "#app/data/balance/biomes";
|
||||||
import { SceneBase } from "./scene-base";
|
import { SceneBase } from "#app/scene-base";
|
||||||
import CandyBar from "./ui/candy-bar";
|
import CandyBar from "#app/ui/candy-bar";
|
||||||
import { Variant, variantData } from "./data/variant";
|
import { Variant, variantData } from "#app/data/variant";
|
||||||
import { Localizable } from "#app/interfaces/locales";
|
import { Localizable } from "#app/interfaces/locales";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import { InputsController } from "./inputs-controller";
|
import { InputsController } from "#app/inputs-controller";
|
||||||
import { UiInputs } from "./ui-inputs";
|
import { UiInputs } from "#app/ui-inputs";
|
||||||
import { NewArenaEvent } from "./events/battle-scene";
|
import { NewArenaEvent } from "#app/events/battle-scene";
|
||||||
import { ArenaFlyout } from "./ui/arena-flyout";
|
import { ArenaFlyout } from "#app/ui/arena-flyout";
|
||||||
import { EaseType } from "#enums/ease-type";
|
import { EaseType } from "#enums/ease-type";
|
||||||
import { BattleSpec } from "#enums/battle-spec";
|
import { BattleSpec } from "#enums/battle-spec";
|
||||||
import { BattleStyle } from "#enums/battle-style";
|
import { BattleStyle } from "#enums/battle-style";
|
||||||
@ -66,27 +66,27 @@ import { TimedEventManager } from "#app/timed-event-manager";
|
|||||||
import { PokemonAnimType } from "#enums/pokemon-anim-type";
|
import { PokemonAnimType } from "#enums/pokemon-anim-type";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { battleSpecDialogue } from "./data/dialogue";
|
import { battleSpecDialogue } from "#app/data/dialogue";
|
||||||
import { LoadingScene } from "./loading-scene";
|
import { LoadingScene } from "#app/loading-scene";
|
||||||
import { LevelCapPhase } from "./phases/level-cap-phase";
|
import { LevelCapPhase } from "#app/phases/level-cap-phase";
|
||||||
import { LoginPhase } from "./phases/login-phase";
|
import { LoginPhase } from "#app/phases/login-phase";
|
||||||
import { MessagePhase } from "./phases/message-phase";
|
import { MessagePhase } from "#app/phases/message-phase";
|
||||||
import { MovePhase } from "./phases/move-phase";
|
import { MovePhase } from "#app/phases/move-phase";
|
||||||
import { NewBiomeEncounterPhase } from "./phases/new-biome-encounter-phase";
|
import { NewBiomeEncounterPhase } from "#app/phases/new-biome-encounter-phase";
|
||||||
import { NextEncounterPhase } from "./phases/next-encounter-phase";
|
import { NextEncounterPhase } from "#app/phases/next-encounter-phase";
|
||||||
import { PokemonAnimPhase } from "./phases/pokemon-anim-phase";
|
import { PokemonAnimPhase } from "#app/phases/pokemon-anim-phase";
|
||||||
import { QuietFormChangePhase } from "./phases/quiet-form-change-phase";
|
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
|
||||||
import { ReturnPhase } from "./phases/return-phase";
|
import { ReturnPhase } from "#app/phases/return-phase";
|
||||||
import { SelectBiomePhase } from "./phases/select-biome-phase";
|
import { SelectBiomePhase } from "#app/phases/select-biome-phase";
|
||||||
import { ShowTrainerPhase } from "./phases/show-trainer-phase";
|
import { ShowTrainerPhase } from "#app/phases/show-trainer-phase";
|
||||||
import { SummonPhase } from "./phases/summon-phase";
|
import { SummonPhase } from "#app/phases/summon-phase";
|
||||||
import { SwitchPhase } from "./phases/switch-phase";
|
import { SwitchPhase } from "#app/phases/switch-phase";
|
||||||
import { TitlePhase } from "./phases/title-phase";
|
import { TitlePhase } from "#app/phases/title-phase";
|
||||||
import { ToggleDoublePositionPhase } from "./phases/toggle-double-position-phase";
|
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
|
||||||
import { TurnInitPhase } from "./phases/turn-init-phase";
|
import { TurnInitPhase } from "#app/phases/turn-init-phase";
|
||||||
import { ShopCursorTarget } from "./enums/shop-cursor-target";
|
import { ShopCursorTarget } from "#app/enums/shop-cursor-target";
|
||||||
import MysteryEncounter from "./data/mystery-encounters/mystery-encounter";
|
import MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
import { allMysteryEncounters, ANTI_VARIANCE_WEIGHT_MODIFIER, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT, mysteryEncountersByBiome, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "./data/mystery-encounters/mystery-encounters";
|
import { allMysteryEncounters, ANTI_VARIANCE_WEIGHT_MODIFIER, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT, mysteryEncountersByBiome, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
|
||||||
import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data";
|
import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
@ -94,7 +94,7 @@ import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
|||||||
import { ExpPhase } from "#app/phases/exp-phase";
|
import { ExpPhase } from "#app/phases/exp-phase";
|
||||||
import { ShowPartyExpBarPhase } from "#app/phases/show-party-exp-bar-phase";
|
import { ShowPartyExpBarPhase } from "#app/phases/show-party-exp-bar-phase";
|
||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
import { ExpGainsSpeed } from "./enums/exp-gains-speed";
|
import { ExpGainsSpeed } from "#enums/exp-gains-speed";
|
||||||
|
|
||||||
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
||||||
|
|
||||||
@ -889,6 +889,9 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource);
|
const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource);
|
||||||
|
if (Overrides.OPP_FUSION_OVERRIDE) {
|
||||||
|
pokemon.generateFusionSpecies();
|
||||||
|
}
|
||||||
|
|
||||||
overrideModifiers(this, false);
|
overrideModifiers(this, false);
|
||||||
overrideHeldItems(this, pokemon, false);
|
overrideHeldItems(this, pokemon, false);
|
||||||
@ -1261,7 +1264,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
const isEndlessFifthWave = this.gameMode.hasShortBiomes && (lastBattle.waveIndex % 5) === 0;
|
const isEndlessFifthWave = this.gameMode.hasShortBiomes && (lastBattle.waveIndex % 5) === 0;
|
||||||
const isWaveIndexMultipleOfFiftyMinusOne = (lastBattle.waveIndex % 50) === 49;
|
const isWaveIndexMultipleOfFiftyMinusOne = (lastBattle.waveIndex % 50) === 49;
|
||||||
const isNewBiome = isWaveIndexMultipleOfTen || isEndlessFifthWave || (isEndlessOrDaily && isWaveIndexMultipleOfFiftyMinusOne);
|
const isNewBiome = isWaveIndexMultipleOfTen || isEndlessFifthWave || (isEndlessOrDaily && isWaveIndexMultipleOfFiftyMinusOne);
|
||||||
const resetArenaState = isNewBiome || [BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.currentBattle.battleType) || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS;
|
const resetArenaState = isNewBiome || [ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(this.currentBattle.battleType) || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS;
|
||||||
this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy());
|
this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy());
|
||||||
this.trySpreadPokerus();
|
this.trySpreadPokerus();
|
||||||
if (!isNewBiome && (newWaveIndex % 10) === 5) {
|
if (!isNewBiome && (newWaveIndex % 10) === 5) {
|
||||||
@ -1758,14 +1761,14 @@ export default class BattleScene extends SceneBase {
|
|||||||
if (fromArenaPool) {
|
if (fromArenaPool) {
|
||||||
return this.arena.randomSpecies(waveIndex, level, undefined, getPartyLuckValue(this.party));
|
return this.arena.randomSpecies(waveIndex, level, undefined, getPartyLuckValue(this.party));
|
||||||
}
|
}
|
||||||
const filteredSpecies = speciesFilter ? [...new Set(allSpecies.filter(s => s.isCatchable()).filter(speciesFilter).map(s => {
|
const filteredSpecies = speciesFilter ? [ ...new Set(allSpecies.filter(s => s.isCatchable()).filter(speciesFilter).map(s => {
|
||||||
if (!filterAllEvolutions) {
|
if (!filterAllEvolutions) {
|
||||||
while (pokemonPrevolutions.hasOwnProperty(s.speciesId)) {
|
while (pokemonPrevolutions.hasOwnProperty(s.speciesId)) {
|
||||||
s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]);
|
s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}))] : allSpecies.filter(s => s.isCatchable());
|
})) ] : allSpecies.filter(s => s.isCatchable());
|
||||||
return filteredSpecies[Utils.randSeedInt(filteredSpecies.length)];
|
return filteredSpecies[Utils.randSeedInt(filteredSpecies.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1885,14 +1888,14 @@ export default class BattleScene extends SceneBase {
|
|||||||
case "battle_anims":
|
case "battle_anims":
|
||||||
case "cry":
|
case "cry":
|
||||||
if (soundDetails[1].startsWith("PRSFX- ")) {
|
if (soundDetails[1].startsWith("PRSFX- ")) {
|
||||||
sound.setVolume(this.masterVolume*this.fieldVolume*0.5);
|
sound.setVolume(this.masterVolume * this.fieldVolume * 0.5);
|
||||||
} else {
|
} else {
|
||||||
sound.setVolume(this.masterVolume*this.fieldVolume);
|
sound.setVolume(this.masterVolume * this.fieldVolume);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "se":
|
case "se":
|
||||||
case "ui":
|
case "ui":
|
||||||
sound.setVolume(this.masterVolume*this.seVolume);
|
sound.setVolume(this.masterVolume * this.seVolume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2221,7 +2224,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
pushConditionalPhase(phase: Phase, condition: () => boolean): void {
|
pushConditionalPhase(phase: Phase, condition: () => boolean): void {
|
||||||
this.conditionalQueue.push([condition, phase]);
|
this.conditionalQueue.push([ condition, phase ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2356,17 +2359,6 @@ export default class BattleScene extends SceneBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pushMovePhase(movePhase: MovePhase, priorityOverride?: integer): void {
|
|
||||||
const movePriority = new Utils.IntegerHolder(priorityOverride !== undefined ? priorityOverride : movePhase.move.getMove().priority);
|
|
||||||
applyAbAttrs(ChangeMovePriorityAbAttr, movePhase.pokemon, null, false, movePhase.move.getMove(), movePriority);
|
|
||||||
const lowerPriorityPhase = this.phaseQueue.find(p => p instanceof MovePhase && p.move.getMove().priority < movePriority.value);
|
|
||||||
if (lowerPriorityPhase) {
|
|
||||||
this.phaseQueue.splice(this.phaseQueue.indexOf(lowerPriorityPhase), 0, movePhase);
|
|
||||||
} else {
|
|
||||||
this.pushPhase(movePhase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to add the input phase to index before target phase in the phaseQueue, else simply calls unshiftPhase()
|
* Tries to add the input phase to index before target phase in the phaseQueue, else simply calls unshiftPhase()
|
||||||
* @param phase {@linkcode Phase} the phase to be added
|
* @param phase {@linkcode Phase} the phase to be added
|
||||||
@ -2498,7 +2490,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.allSettled([this.party.map(p => p.updateInfo(instant)), ...modifierPromises]).then(() => resolve(success));
|
return Promise.allSettled([ this.party.map(p => p.updateInfo(instant)), ...modifierPromises ]).then(() => resolve(success));
|
||||||
} else {
|
} else {
|
||||||
const args = [ this ];
|
const args = [ this ];
|
||||||
if (modifier.shouldApply(...args)) {
|
if (modifier.shouldApply(...args)) {
|
||||||
@ -2818,7 +2810,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
const rand = Utils.randSeedInt(mods.length);
|
const rand = Utils.randSeedInt(mods.length);
|
||||||
return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))];
|
return [ mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand)) ];
|
||||||
};
|
};
|
||||||
modifiers = shuffleModifiers(modifiers);
|
modifiers = shuffleModifiers(modifiers);
|
||||||
}, scene.currentBattle.turn << 4, scene.waveSeed);
|
}, scene.currentBattle.turn << 4, scene.waveSeed);
|
||||||
@ -2978,7 +2970,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
keys.push(p.getBattleSpriteKey(true, true));
|
keys.push(p.getBattleSpriteKey(true, true));
|
||||||
keys.push("cry/" + p.species.getCryKey(p.formIndex));
|
keys.push("cry/" + p.species.getCryKey(p.formIndex));
|
||||||
if (p.fusionSpecies) {
|
if (p.fusionSpecies) {
|
||||||
keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex));
|
keys.push("cry/" + p.fusionSpecies.getCryKey(p.fusionFormIndex));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// enemyParty has to be operated on separately from playerParty because playerPokemon =/= enemyPokemon
|
// enemyParty has to be operated on separately from playerParty because playerPokemon =/= enemyPokemon
|
||||||
@ -2987,7 +2979,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
keys.push(p.getSpriteKey(true));
|
keys.push(p.getSpriteKey(true));
|
||||||
keys.push("cry/" + p.species.getCryKey(p.formIndex));
|
keys.push("cry/" + p.species.getCryKey(p.formIndex));
|
||||||
if (p.fusionSpecies) {
|
if (p.fusionSpecies) {
|
||||||
keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex));
|
keys.push("cry/" + p.fusionSpecies.getCryKey(p.fusionFormIndex));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return keys;
|
return keys;
|
||||||
@ -3135,7 +3127,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
* @param sessionDataEncounterType
|
* @param sessionDataEncounterType
|
||||||
*/
|
*/
|
||||||
private isWaveMysteryEncounter(newBattleType: BattleType, waveIndex: number, sessionDataEncounterType?: MysteryEncounterType): boolean {
|
private isWaveMysteryEncounter(newBattleType: BattleType, waveIndex: number, sessionDataEncounterType?: MysteryEncounterType): boolean {
|
||||||
const [lowestMysteryEncounterWave, highestMysteryEncounterWave] = this.gameMode.getMysteryEncounterLegalWaves();
|
const [ lowestMysteryEncounterWave, highestMysteryEncounterWave ] = this.gameMode.getMysteryEncounterLegalWaves();
|
||||||
if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(waveIndex) && waveIndex < highestMysteryEncounterWave && waveIndex > lowestMysteryEncounterWave) {
|
if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(waveIndex) && waveIndex < highestMysteryEncounterWave && waveIndex > lowestMysteryEncounterWave) {
|
||||||
// Base spawn weight is BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT/256, and increases by WEIGHT_INCREMENT_ON_SPAWN_MISS/256 for each missed attempt at spawning an encounter on a valid floor
|
// Base spawn weight is BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT/256, and increases by WEIGHT_INCREMENT_ON_SPAWN_MISS/256 for each missed attempt at spawning an encounter on a valid floor
|
||||||
const sessionEncounterRate = this.mysteryEncounterSaveData.encounterSpawnChance;
|
const sessionEncounterRate = this.mysteryEncounterSaveData.encounterSpawnChance;
|
||||||
@ -3201,7 +3193,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See Enum values for base tier weights
|
// See Enum values for base tier weights
|
||||||
const tierWeights = [MysteryEncounterTier.COMMON, MysteryEncounterTier.GREAT, MysteryEncounterTier.ULTRA, MysteryEncounterTier.ROGUE];
|
const tierWeights = [ MysteryEncounterTier.COMMON, MysteryEncounterTier.GREAT, MysteryEncounterTier.ULTRA, MysteryEncounterTier.ROGUE ];
|
||||||
|
|
||||||
// Adjust tier weights by previously encountered events to lower odds of only Common/Great in run
|
// Adjust tier weights by previously encountered events to lower odds of only Common/Great in run
|
||||||
this.mysteryEncounterSaveData.encounteredEvents.forEach(seenEncounterData => {
|
this.mysteryEncounterSaveData.encounteredEvents.forEach(seenEncounterData => {
|
||||||
|
@ -497,7 +497,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 1/3 chance for evil team grunts to be double battles */
|
/* 1/3 chance for evil team grunts to be double battles */
|
||||||
const evilTeamGrunts = [TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT];
|
const evilTeamGrunts = [ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ];
|
||||||
const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]);
|
const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]);
|
||||||
|
|
||||||
if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) {
|
if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) {
|
||||||
@ -527,34 +527,34 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
||||||
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
|
||||||
[35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
||||||
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
|
||||||
[62]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[62]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
||||||
[64]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[64]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
||||||
[66]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[66]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ] ], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true)),
|
||||||
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
||||||
[112]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[112]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
||||||
[114]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[114]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ] ], true, 1)),
|
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true, 1)),
|
||||||
[ClassicFixedBossWaves.EVIL_BOSS_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[ClassicFixedBossWaves.EVIL_BOSS_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE, TrainerType.PENNY ]))
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE, TrainerType.PENNY ]))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
||||||
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
||||||
[ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2, TrainerType.PENNY_2 ]))
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2, TrainerType.PENNY_2 ]))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
||||||
[182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])),
|
||||||
[184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
|
[184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
|
||||||
@ -567,5 +567,5 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
|||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN ])),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN ])),
|
||||||
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false })
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false })
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {Button} from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
import {SettingKeyboard} from "#app/system/settings/settings-keyboard";
|
import { SettingKeyboard } from "#app/system/settings/settings-keyboard";
|
||||||
|
|
||||||
const cfg_keyboard_qwerty = {
|
const cfg_keyboard_qwerty = {
|
||||||
padID: "default",
|
padID: "default",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Device} from "#enums/devices";
|
import { Device } from "#enums/devices";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the key associated with the specified keycode from the mapping.
|
* Retrieves the key associated with the specified keycode from the mapping.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {SettingGamepad} from "../../system/settings/settings-gamepad";
|
import { SettingGamepad } from "../../system/settings/settings-gamepad";
|
||||||
import {Button} from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dualshock mapping
|
* Dualshock mapping
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {SettingGamepad} from "../../system/settings/settings-gamepad";
|
import { SettingGamepad } from "../../system/settings/settings-gamepad";
|
||||||
import {Button} from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic pad mapping
|
* Generic pad mapping
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {SettingGamepad} from "#app/system/settings/settings-gamepad";
|
import { SettingGamepad } from "#app/system/settings/settings-gamepad";
|
||||||
import {Button} from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nintendo Pro Controller mapping
|
* Nintendo Pro Controller mapping
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {SettingGamepad} from "../../system/settings/settings-gamepad";
|
import { SettingGamepad } from "../../system/settings/settings-gamepad";
|
||||||
import {Button} from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 081f-e401 - UnlicensedSNES
|
* 081f-e401 - UnlicensedSNES
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {SettingGamepad} from "../../system/settings/settings-gamepad";
|
import { SettingGamepad } from "../../system/settings/settings-gamepad";
|
||||||
import {Button} from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic pad mapping
|
* Generic pad mapping
|
||||||
|
@ -162,7 +162,7 @@ export class BlockRecoilDamageAttr extends AbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) {
|
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) {
|
||||||
return i18next.t("abilityTriggers:blockRecoilDamage", {pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName});
|
return i18next.t("abilityTriggers:blockRecoilDamage", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -964,7 +964,7 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
||||||
return i18next.t("abilityTriggers:perishBody", {pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName});
|
return i18next.t("abilityTriggers:perishBody", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1268,7 +1268,7 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr {
|
|||||||
if (pokemon.getTypes().some((t) => t !== moveType)) {
|
if (pokemon.getTypes().some((t) => t !== moveType)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
this.moveType = moveType;
|
this.moveType = moveType;
|
||||||
pokemon.summonData.types = [moveType];
|
pokemon.summonData.types = [ moveType ];
|
||||||
pokemon.updateInfo();
|
pokemon.updateInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2814,7 +2814,7 @@ export class PreApplyBattlerTagImmunityAbAttr extends PreApplyBattlerTagAbAttr {
|
|||||||
constructor(immuneTagTypes: BattlerTagType | BattlerTagType[]) {
|
constructor(immuneTagTypes: BattlerTagType | BattlerTagType[]) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.immuneTagTypes = Array.isArray(immuneTagTypes) ? immuneTagTypes : [immuneTagTypes];
|
this.immuneTagTypes = Array.isArray(immuneTagTypes) ? immuneTagTypes : [ immuneTagTypes ];
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPreApplyBattlerTag(pokemon: Pokemon, passive: boolean, simulated: boolean, tag: BattlerTag, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
applyPreApplyBattlerTag(pokemon: Pokemon, passive: boolean, simulated: boolean, tag: BattlerTag, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
@ -3099,17 +3099,17 @@ function getAnticipationCondition(): AbAttrCondition {
|
|||||||
// edge case for hidden power, type is computed
|
// edge case for hidden power, type is computed
|
||||||
if (move.getMove().id === Moves.HIDDEN_POWER) {
|
if (move.getMove().id === Moves.HIDDEN_POWER) {
|
||||||
const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1)
|
const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1)
|
||||||
+(opponent.ivs[Stat.ATK] & 1) * 2
|
+ (opponent.ivs[Stat.ATK] & 1) * 2
|
||||||
+(opponent.ivs[Stat.DEF] & 1) * 4
|
+ (opponent.ivs[Stat.DEF] & 1) * 4
|
||||||
+(opponent.ivs[Stat.SPD] & 1) * 8
|
+ (opponent.ivs[Stat.SPD] & 1) * 8
|
||||||
+(opponent.ivs[Stat.SPATK] & 1) * 16
|
+ (opponent.ivs[Stat.SPATK] & 1) * 16
|
||||||
+(opponent.ivs[Stat.SPDEF] & 1) * 32) * 15/63);
|
+ (opponent.ivs[Stat.SPDEF] & 1) * 32) * 15 / 63);
|
||||||
|
|
||||||
const type = [
|
const type = [
|
||||||
Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND,
|
Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND,
|
||||||
Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL,
|
Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL,
|
||||||
Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC,
|
Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC,
|
||||||
Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK][iv_val];
|
Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK ][iv_val];
|
||||||
|
|
||||||
if (pokemon.getAttackTypeEffectiveness(type, opponent) >= 2) {
|
if (pokemon.getAttackTypeEffectiveness(type, opponent) >= 2) {
|
||||||
return true;
|
return true;
|
||||||
@ -3644,7 +3644,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
|
|||||||
if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER);
|
opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER);
|
||||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: getPokemonNameWithAffix(opp)}));
|
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) }));
|
||||||
}
|
}
|
||||||
hadEffect = true;
|
hadEffect = true;
|
||||||
}
|
}
|
||||||
@ -3755,8 +3755,8 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
|
|||||||
*/
|
*/
|
||||||
applyPostMoveUsed(dancer: Pokemon, move: PokemonMove, source: Pokemon, targets: BattlerIndex[], simulated: boolean, args: any[]): boolean | Promise<boolean> {
|
applyPostMoveUsed(dancer: Pokemon, move: PokemonMove, source: Pokemon, targets: BattlerIndex[], simulated: boolean, args: any[]): boolean | Promise<boolean> {
|
||||||
// List of tags that prevent the Dancer from replicating the move
|
// List of tags that prevent the Dancer from replicating the move
|
||||||
const forbiddenTags = [BattlerTagType.FLYING, BattlerTagType.UNDERWATER,
|
const forbiddenTags = [ BattlerTagType.FLYING, BattlerTagType.UNDERWATER,
|
||||||
BattlerTagType.UNDERGROUND, BattlerTagType.HIDDEN];
|
BattlerTagType.UNDERGROUND, BattlerTagType.HIDDEN ];
|
||||||
// The move to replicate cannot come from the Dancer
|
// The move to replicate cannot come from the Dancer
|
||||||
if (source.getBattlerIndex() !== dancer.getBattlerIndex()
|
if (source.getBattlerIndex() !== dancer.getBattlerIndex()
|
||||||
&& !dancer.summonData.tags.some(tag => forbiddenTags.includes(tag.tagType))) {
|
&& !dancer.summonData.tags.some(tag => forbiddenTags.includes(tag.tagType))) {
|
||||||
@ -3767,7 +3767,7 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
|
|||||||
dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, target, move, true, true));
|
dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, target, move, true, true));
|
||||||
} else if (move.getMove() instanceof SelfStatusMove) {
|
} else if (move.getMove() instanceof SelfStatusMove) {
|
||||||
// If the move is a SelfStatusMove (ie. Swords Dance) the Dancer should replicate it on itself
|
// If the move is a SelfStatusMove (ie. Swords Dance) the Dancer should replicate it on itself
|
||||||
dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, [dancer.getBattlerIndex()], move, true, true));
|
dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, [ dancer.getBattlerIndex() ], move, true, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -3784,9 +3784,9 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
|
|||||||
*/
|
*/
|
||||||
getTarget(dancer: Pokemon, source: Pokemon, targets: BattlerIndex[]) : BattlerIndex[] {
|
getTarget(dancer: Pokemon, source: Pokemon, targets: BattlerIndex[]) : BattlerIndex[] {
|
||||||
if (dancer.isPlayer()) {
|
if (dancer.isPlayer()) {
|
||||||
return source.isPlayer() ? targets : [source.getBattlerIndex()];
|
return source.isPlayer() ? targets : [ source.getBattlerIndex() ];
|
||||||
}
|
}
|
||||||
return source.isPlayer() ? [source.getBattlerIndex()] : targets;
|
return source.isPlayer() ? [ source.getBattlerIndex() ] : targets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4561,7 +4561,7 @@ export class BypassSpeedChanceAbAttr extends AbAttr {
|
|||||||
const turnCommand =
|
const turnCommand =
|
||||||
pokemon.scene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
|
pokemon.scene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
|
||||||
const isCommandFight = turnCommand?.command === Command.FIGHT;
|
const isCommandFight = turnCommand?.command === Command.FIGHT;
|
||||||
const move = turnCommand?.move?.move ?allMoves[turnCommand.move.move] : null;
|
const move = turnCommand?.move?.move ? allMoves[turnCommand.move.move] : null;
|
||||||
const isDamageMove = move?.category === MoveCategory.PHYSICAL || move?.category === MoveCategory.SPECIAL;
|
const isDamageMove = move?.category === MoveCategory.PHYSICAL || move?.category === MoveCategory.SPECIAL;
|
||||||
|
|
||||||
if (isCommandFight && isDamageMove) {
|
if (isCommandFight && isDamageMove) {
|
||||||
@ -4574,7 +4574,7 @@ export class BypassSpeedChanceAbAttr extends AbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
||||||
return i18next.t("abilityTriggers:quickDraw", {pokemonName: getPokemonNameWithAffix(pokemon)});
|
return i18next.t("abilityTriggers:quickDraw", { pokemonName: getPokemonNameWithAffix(pokemon) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4622,7 +4622,7 @@ async function applyAbAttrsInternal<TAttr extends AbAttr>(
|
|||||||
simulated: boolean = false,
|
simulated: boolean = false,
|
||||||
messages: string[] = [],
|
messages: string[] = [],
|
||||||
) {
|
) {
|
||||||
for (const passive of [false, true]) {
|
for (const passive of [ false, true ]) {
|
||||||
if (!pokemon?.canApplyAbility(passive)) {
|
if (!pokemon?.canApplyAbility(passive)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -4872,7 +4872,7 @@ export function initAbilities() {
|
|||||||
.attr(TypeImmunityHealAbAttr, Type.WATER)
|
.attr(TypeImmunityHealAbAttr, Type.WATER)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.OBLIVIOUS, 3)
|
new Ability(Abilities.OBLIVIOUS, 3)
|
||||||
.attr(BattlerTagImmunityAbAttr, [BattlerTagType.INFATUATED, BattlerTagType.TAUNT])
|
.attr(BattlerTagImmunityAbAttr, [ BattlerTagType.INFATUATED, BattlerTagType.TAUNT ])
|
||||||
.attr(IntimidateImmunityAbAttr)
|
.attr(IntimidateImmunityAbAttr)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.CLOUD_NINE, 3)
|
new Ability(Abilities.CLOUD_NINE, 3)
|
||||||
@ -5017,10 +5017,10 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.CUTE_CHARM, 3)
|
new Ability(Abilities.CUTE_CHARM, 3)
|
||||||
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
|
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
|
||||||
new Ability(Abilities.PLUS, 3)
|
new Ability(Abilities.PLUS, 3)
|
||||||
.conditionalAttr(p => p.scene.currentBattle.double && [Abilities.PLUS, Abilities.MINUS].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
|
.conditionalAttr(p => p.scene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.MINUS, 3)
|
new Ability(Abilities.MINUS, 3)
|
||||||
.conditionalAttr(p => p.scene.currentBattle.double && [Abilities.PLUS, Abilities.MINUS].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
|
.conditionalAttr(p => p.scene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.FORECAST, 3)
|
new Ability(Abilities.FORECAST, 3)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
@ -5138,7 +5138,7 @@ export function initAbilities() {
|
|||||||
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), StatMultiplierAbAttr, Stat.SPD, 1.5),
|
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), StatMultiplierAbAttr, Stat.SPD, 1.5),
|
||||||
new Ability(Abilities.NORMALIZE, 4)
|
new Ability(Abilities.NORMALIZE, 4)
|
||||||
.attr(MoveTypeChangeAbAttr, Type.NORMAL, 1.2, (user, target, move) => {
|
.attr(MoveTypeChangeAbAttr, Type.NORMAL, 1.2, (user, target, move) => {
|
||||||
return ![Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST].includes(move.id);
|
return ![ Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST ].includes(move.id);
|
||||||
}),
|
}),
|
||||||
new Ability(Abilities.SNIPER, 4)
|
new Ability(Abilities.SNIPER, 4)
|
||||||
.attr(MultCritAbAttr, 1.5),
|
.attr(MultCritAbAttr, 1.5),
|
||||||
@ -5184,7 +5184,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.SLOW_START, 4)
|
new Ability(Abilities.SLOW_START, 4)
|
||||||
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5),
|
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5),
|
||||||
new Ability(Abilities.SCRAPPY, 4)
|
new Ability(Abilities.SCRAPPY, 4)
|
||||||
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING])
|
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [ Type.NORMAL, Type.FIGHTING ])
|
||||||
.attr(IntimidateImmunityAbAttr),
|
.attr(IntimidateImmunityAbAttr),
|
||||||
new Ability(Abilities.STORM_DRAIN, 4)
|
new Ability(Abilities.STORM_DRAIN, 4)
|
||||||
.attr(RedirectTypeMoveAbAttr, Type.WATER)
|
.attr(RedirectTypeMoveAbAttr, Type.WATER)
|
||||||
@ -5225,7 +5225,7 @@ export function initAbilities() {
|
|||||||
.attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT))
|
.attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT))
|
||||||
.condition(getSheerForceHitDisableAbCondition()),
|
.condition(getSheerForceHitDisableAbCondition()),
|
||||||
new Ability(Abilities.SHEER_FORCE, 5)
|
new Ability(Abilities.SHEER_FORCE, 5)
|
||||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 5461/4096)
|
.attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 5461 / 4096)
|
||||||
.attr(MoveEffectChanceMultiplierAbAttr, 0)
|
.attr(MoveEffectChanceMultiplierAbAttr, 0)
|
||||||
.partial(),
|
.partial(),
|
||||||
new Ability(Abilities.CONTRARY, 5)
|
new Ability(Abilities.CONTRARY, 5)
|
||||||
@ -5234,7 +5234,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.UNNERVE, 5)
|
new Ability(Abilities.UNNERVE, 5)
|
||||||
.attr(PreventBerryUseAbAttr),
|
.attr(PreventBerryUseAbAttr),
|
||||||
new Ability(Abilities.DEFIANT, 5)
|
new Ability(Abilities.DEFIANT, 5)
|
||||||
.attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [Stat.ATK], 2),
|
.attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [ Stat.ATK ], 2),
|
||||||
new Ability(Abilities.DEFEATIST, 5)
|
new Ability(Abilities.DEFEATIST, 5)
|
||||||
.attr(StatMultiplierAbAttr, Stat.ATK, 0.5)
|
.attr(StatMultiplierAbAttr, Stat.ATK, 0.5)
|
||||||
.attr(StatMultiplierAbAttr, Stat.SPATK, 0.5)
|
.attr(StatMultiplierAbAttr, Stat.SPATK, 0.5)
|
||||||
@ -5320,7 +5320,7 @@ export function initAbilities() {
|
|||||||
return move.category !== MoveCategory.STATUS
|
return move.category !== MoveCategory.STATUS
|
||||||
&& (moveType === Type.DARK || moveType === Type.BUG || moveType === Type.GHOST);
|
&& (moveType === Type.DARK || moveType === Type.BUG || moveType === Type.GHOST);
|
||||||
}, Stat.SPD, 1)
|
}, Stat.SPD, 1)
|
||||||
.attr(PostIntimidateStatStageChangeAbAttr, [Stat.SPD], 1),
|
.attr(PostIntimidateStatStageChangeAbAttr, [ Stat.SPD ], 1),
|
||||||
new Ability(Abilities.MAGIC_BOUNCE, 5)
|
new Ability(Abilities.MAGIC_BOUNCE, 5)
|
||||||
.ignorable()
|
.ignorable()
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
@ -5357,12 +5357,12 @@ export function initAbilities() {
|
|||||||
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTeravolt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
|
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTeravolt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
|
||||||
.attr(MoveAbilityBypassAbAttr),
|
.attr(MoveAbilityBypassAbAttr),
|
||||||
new Ability(Abilities.AROMA_VEIL, 6)
|
new Ability(Abilities.AROMA_VEIL, 6)
|
||||||
.attr(UserFieldBattlerTagImmunityAbAttr, [BattlerTagType.INFATUATED, BattlerTagType.TAUNT, BattlerTagType.DISABLED, BattlerTagType.TORMENT, BattlerTagType.HEAL_BLOCK]),
|
.attr(UserFieldBattlerTagImmunityAbAttr, [ BattlerTagType.INFATUATED, BattlerTagType.TAUNT, BattlerTagType.DISABLED, BattlerTagType.TORMENT, BattlerTagType.HEAL_BLOCK ]),
|
||||||
new Ability(Abilities.FLOWER_VEIL, 6)
|
new Ability(Abilities.FLOWER_VEIL, 6)
|
||||||
.ignorable()
|
.ignorable()
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new Ability(Abilities.CHEEK_POUCH, 6)
|
new Ability(Abilities.CHEEK_POUCH, 6)
|
||||||
.attr(HealFromBerryUseAbAttr, 1/3),
|
.attr(HealFromBerryUseAbAttr, 1 / 3),
|
||||||
new Ability(Abilities.PROTEAN, 6)
|
new Ability(Abilities.PROTEAN, 6)
|
||||||
.attr(PokemonTypeChangeAbAttr),
|
.attr(PokemonTypeChangeAbAttr),
|
||||||
//.condition((p) => !p.summonData?.abilitiesApplied.includes(Abilities.PROTEAN)), //Gen 9 Implementation
|
//.condition((p) => !p.summonData?.abilitiesApplied.includes(Abilities.PROTEAN)), //Gen 9 Implementation
|
||||||
@ -5375,7 +5375,7 @@ export function initAbilities() {
|
|||||||
.attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.hasFlag(MoveFlags.BALLBOMB_MOVE))
|
.attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.hasFlag(MoveFlags.BALLBOMB_MOVE))
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.COMPETITIVE, 6)
|
new Ability(Abilities.COMPETITIVE, 6)
|
||||||
.attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [Stat.SPATK], 2),
|
.attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [ Stat.SPATK ], 2),
|
||||||
new Ability(Abilities.STRONG_JAW, 6)
|
new Ability(Abilities.STRONG_JAW, 6)
|
||||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.BITING_MOVE), 1.5),
|
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.BITING_MOVE), 1.5),
|
||||||
new Ability(Abilities.REFRIGERATE, 6)
|
new Ability(Abilities.REFRIGERATE, 6)
|
||||||
@ -5471,7 +5471,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.STEELWORKER, 7)
|
new Ability(Abilities.STEELWORKER, 7)
|
||||||
.attr(MoveTypePowerBoostAbAttr, Type.STEEL),
|
.attr(MoveTypePowerBoostAbAttr, Type.STEEL),
|
||||||
new Ability(Abilities.BERSERK, 7)
|
new Ability(Abilities.BERSERK, 7)
|
||||||
.attr(PostDefendHpGatedStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, 0.5, [Stat.SPATK], 1)
|
.attr(PostDefendHpGatedStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, 0.5, [ Stat.SPATK ], 1)
|
||||||
.condition(getSheerForceHitDisableAbCondition()),
|
.condition(getSheerForceHitDisableAbCondition()),
|
||||||
new Ability(Abilities.SLUSH_RUSH, 7)
|
new Ability(Abilities.SLUSH_RUSH, 7)
|
||||||
.attr(StatMultiplierAbAttr, Stat.SPD, 2)
|
.attr(StatMultiplierAbAttr, Stat.SPD, 2)
|
||||||
@ -5528,7 +5528,7 @@ export function initAbilities() {
|
|||||||
.bypassFaint()
|
.bypassFaint()
|
||||||
.partial(),
|
.partial(),
|
||||||
new Ability(Abilities.CORROSION, 7) // TODO: Test Corrosion against Magic Bounce once it is implemented
|
new Ability(Abilities.CORROSION, 7) // TODO: Test Corrosion against Magic Bounce once it is implemented
|
||||||
.attr(IgnoreTypeStatusEffectImmunityAbAttr, [StatusEffect.POISON, StatusEffect.TOXIC], [Type.STEEL, Type.POISON])
|
.attr(IgnoreTypeStatusEffectImmunityAbAttr, [ StatusEffect.POISON, StatusEffect.TOXIC ], [ Type.STEEL, Type.POISON ])
|
||||||
.partial(),
|
.partial(),
|
||||||
new Ability(Abilities.COMATOSE, 7)
|
new Ability(Abilities.COMATOSE, 7)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
@ -5545,7 +5545,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.DANCER, 7)
|
new Ability(Abilities.DANCER, 7)
|
||||||
.attr(PostDancingMoveAbAttr),
|
.attr(PostDancingMoveAbAttr),
|
||||||
new Ability(Abilities.BATTERY, 7)
|
new Ability(Abilities.BATTERY, 7)
|
||||||
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL], 1.3),
|
.attr(AllyMoveCategoryPowerBoostAbAttr, [ MoveCategory.SPECIAL ], 1.3),
|
||||||
new Ability(Abilities.FLUFFY, 7)
|
new Ability(Abilities.FLUFFY, 7)
|
||||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 0.5)
|
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 0.5)
|
||||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => user.getMoveType(move) === Type.FIRE, 2)
|
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => user.getMoveType(move) === Type.FIRE, 2)
|
||||||
@ -5671,11 +5671,11 @@ export function initAbilities() {
|
|||||||
.bypassFaint()
|
.bypassFaint()
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.POWER_SPOT, 8)
|
new Ability(Abilities.POWER_SPOT, 8)
|
||||||
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL], 1.3),
|
.attr(AllyMoveCategoryPowerBoostAbAttr, [ MoveCategory.SPECIAL, MoveCategory.PHYSICAL ], 1.3),
|
||||||
new Ability(Abilities.MIMICRY, 8)
|
new Ability(Abilities.MIMICRY, 8)
|
||||||
.unimplemented(),
|
.unimplemented(),
|
||||||
new Ability(Abilities.SCREEN_CLEANER, 8)
|
new Ability(Abilities.SCREEN_CLEANER, 8)
|
||||||
.attr(PostSummonRemoveArenaTagAbAttr, [ArenaTagType.AURORA_VEIL, ArenaTagType.LIGHT_SCREEN, ArenaTagType.REFLECT]),
|
.attr(PostSummonRemoveArenaTagAbAttr, [ ArenaTagType.AURORA_VEIL, ArenaTagType.LIGHT_SCREEN, ArenaTagType.REFLECT ]),
|
||||||
new Ability(Abilities.STEELY_SPIRIT, 8)
|
new Ability(Abilities.STEELY_SPIRIT, 8)
|
||||||
.attr(UserFieldMoveTypePowerBoostAbAttr, Type.STEEL),
|
.attr(UserFieldMoveTypePowerBoostAbAttr, Type.STEEL),
|
||||||
new Ability(Abilities.PERISH_BODY, 8)
|
new Ability(Abilities.PERISH_BODY, 8)
|
||||||
@ -5758,7 +5758,7 @@ export function initAbilities() {
|
|||||||
.attr(PostSummonStatStageChangeOnArenaAbAttr, ArenaTagType.TAILWIND)
|
.attr(PostSummonStatStageChangeOnArenaAbAttr, ArenaTagType.TAILWIND)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.GUARD_DOG, 9)
|
new Ability(Abilities.GUARD_DOG, 9)
|
||||||
.attr(PostIntimidateStatStageChangeAbAttr, [Stat.ATK], 1, true)
|
.attr(PostIntimidateStatStageChangeAbAttr, [ Stat.ATK ], 1, true)
|
||||||
.attr(ForceSwitchOutImmunityAbAttr)
|
.attr(ForceSwitchOutImmunityAbAttr)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.ROCKY_PAYLOAD, 9)
|
new Ability(Abilities.ROCKY_PAYLOAD, 9)
|
||||||
@ -5847,7 +5847,7 @@ export function initAbilities() {
|
|||||||
.attr(PreventBypassSpeedChanceAbAttr, (pokemon, move) => move.category === MoveCategory.STATUS)
|
.attr(PreventBypassSpeedChanceAbAttr, (pokemon, move) => move.category === MoveCategory.STATUS)
|
||||||
.attr(MoveAbilityBypassAbAttr, (pokemon, move: Move) => move.category === MoveCategory.STATUS),
|
.attr(MoveAbilityBypassAbAttr, (pokemon, move: Move) => move.category === MoveCategory.STATUS),
|
||||||
new Ability(Abilities.MINDS_EYE, 9)
|
new Ability(Abilities.MINDS_EYE, 9)
|
||||||
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING])
|
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [ Type.NORMAL, Type.FIGHTING ])
|
||||||
.attr(ProtectStatAbAttr, Stat.ACC)
|
.attr(ProtectStatAbAttr, Stat.ACC)
|
||||||
.attr(IgnoreOpponentStatStagesAbAttr, [ Stat.EVA ])
|
.attr(IgnoreOpponentStatStagesAbAttr, [ Stat.EVA ])
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
|
@ -19,6 +19,7 @@ import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
|||||||
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
||||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
|
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
|
||||||
|
|
||||||
export enum ArenaTagSide {
|
export enum ArenaTagSide {
|
||||||
BOTH,
|
BOTH,
|
||||||
@ -135,7 +136,7 @@ export class WeakenMoveScreenTag extends ArenaTag {
|
|||||||
*/
|
*/
|
||||||
apply(arena: Arena, args: any[]): boolean {
|
apply(arena: Arena, args: any[]): boolean {
|
||||||
if (this.weakenedCategories.includes((args[0] as MoveCategory))) {
|
if (this.weakenedCategories.includes((args[0] as MoveCategory))) {
|
||||||
(args[2] as Utils.NumberHolder).value = (args[1] as boolean) ? 2732/4096 : 0.5;
|
(args[2] as Utils.NumberHolder).value = (args[1] as boolean) ? 2732 / 4096 : 0.5;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -148,7 +149,7 @@ export class WeakenMoveScreenTag extends ArenaTag {
|
|||||||
*/
|
*/
|
||||||
class ReflectTag extends WeakenMoveScreenTag {
|
class ReflectTag extends WeakenMoveScreenTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [MoveCategory.PHYSICAL]);
|
super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [ MoveCategory.PHYSICAL ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(arena: Arena, quiet: boolean = false): void {
|
onAdd(arena: Arena, quiet: boolean = false): void {
|
||||||
@ -164,7 +165,7 @@ class ReflectTag extends WeakenMoveScreenTag {
|
|||||||
*/
|
*/
|
||||||
class LightScreenTag extends WeakenMoveScreenTag {
|
class LightScreenTag extends WeakenMoveScreenTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [MoveCategory.SPECIAL]);
|
super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [ MoveCategory.SPECIAL ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(arena: Arena, quiet: boolean = false): void {
|
onAdd(arena: Arena, quiet: boolean = false): void {
|
||||||
@ -180,7 +181,7 @@ class LightScreenTag extends WeakenMoveScreenTag {
|
|||||||
*/
|
*/
|
||||||
class AuroraVeilTag extends WeakenMoveScreenTag {
|
class AuroraVeilTag extends WeakenMoveScreenTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL]);
|
super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [ MoveCategory.SPECIAL, MoveCategory.PHYSICAL ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(arena: Arena, quiet: boolean = false): void {
|
onAdd(arena: Arena, quiet: boolean = false): void {
|
||||||
@ -512,15 +513,16 @@ class WaterSportTag extends WeakenMoveTypeTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arena Tag class for the secondary effect of {@link https://bulbapedia.bulbagarden.net/wiki/Plasma_Fists_(move) | Plasma Fists}.
|
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Ion_Deluge_(move) | Ion Deluge}
|
||||||
|
* and the secondary effect of {@link https://bulbapedia.bulbagarden.net/wiki/Plasma_Fists_(move) | Plasma Fists}.
|
||||||
* Converts Normal-type moves to Electric type for the rest of the turn.
|
* Converts Normal-type moves to Electric type for the rest of the turn.
|
||||||
*/
|
*/
|
||||||
export class PlasmaFistsTag extends ArenaTag {
|
export class IonDelugeTag extends ArenaTag {
|
||||||
constructor() {
|
constructor(sourceMove?: Moves) {
|
||||||
super(ArenaTagType.PLASMA_FISTS, 1, Moves.PLASMA_FISTS);
|
super(ArenaTagType.ION_DELUGE, 1, sourceMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Queues Plasma Fists' on-add message */
|
/** Queues an on-add message */
|
||||||
onAdd(arena: Arena): void {
|
onAdd(arena: Arena): void {
|
||||||
arena.scene.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd"));
|
arena.scene.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd"));
|
||||||
}
|
}
|
||||||
@ -988,7 +990,7 @@ class ImprisonTag extends ArenaTrapTag {
|
|||||||
party?.forEach((p: PlayerPokemon | EnemyPokemon ) => {
|
party?.forEach((p: PlayerPokemon | EnemyPokemon ) => {
|
||||||
p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId);
|
p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId);
|
||||||
});
|
});
|
||||||
scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", {pokemonNameWithAffix: getPokemonNameWithAffix(this.source)}));
|
scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(this.source) }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1025,6 +1027,81 @@ class ImprisonTag extends ArenaTrapTag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arena Tag implementing the "sea of fire" effect from the combination
|
||||||
|
* of {@link https://bulbapedia.bulbagarden.net/wiki/Fire_Pledge_(move) | Fire Pledge}
|
||||||
|
* and {@link https://bulbapedia.bulbagarden.net/wiki/Grass_Pledge_(move) | Grass Pledge}.
|
||||||
|
* Damages all non-Fire-type Pokemon on the given side of the field at the end
|
||||||
|
* of each turn for 4 turns.
|
||||||
|
*/
|
||||||
|
class FireGrassPledgeTag extends ArenaTag {
|
||||||
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
|
super(ArenaTagType.FIRE_GRASS_PLEDGE, 4, Moves.FIRE_PLEDGE, sourceId, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
override onAdd(arena: Arena): void {
|
||||||
|
// "A sea of fire enveloped your/the opposing team!"
|
||||||
|
arena.scene.queueMessage(i18next.t(`arenaTag:fireGrassPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
override lapse(arena: Arena): boolean {
|
||||||
|
const field: Pokemon[] = (this.side === ArenaTagSide.PLAYER)
|
||||||
|
? arena.scene.getPlayerField()
|
||||||
|
: arena.scene.getEnemyField();
|
||||||
|
|
||||||
|
field.filter(pokemon => !pokemon.isOfType(Type.FIRE)).forEach(pokemon => {
|
||||||
|
// "{pokemonNameWithAffix} was hurt by the sea of fire!"
|
||||||
|
pokemon.scene.queueMessage(i18next.t("arenaTag:fireGrassPledgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||||
|
// TODO: Replace this with a proper animation
|
||||||
|
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.MAGMA_STORM));
|
||||||
|
pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / 8));
|
||||||
|
});
|
||||||
|
|
||||||
|
return super.lapse(arena);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arena Tag implementing the "rainbow" effect from the combination
|
||||||
|
* of {@link https://bulbapedia.bulbagarden.net/wiki/Water_Pledge_(move) | Water Pledge}
|
||||||
|
* and {@link https://bulbapedia.bulbagarden.net/wiki/Fire_Pledge_(move) | Fire Pledge}.
|
||||||
|
* Doubles the secondary effect chance of moves from Pokemon on the
|
||||||
|
* given side of the field for 4 turns.
|
||||||
|
*/
|
||||||
|
class WaterFirePledgeTag extends ArenaTag {
|
||||||
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
|
super(ArenaTagType.WATER_FIRE_PLEDGE, 4, Moves.WATER_PLEDGE, sourceId, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
override onAdd(arena: Arena): void {
|
||||||
|
// "A rainbow appeared in the sky on your/the opposing team's side!"
|
||||||
|
arena.scene.queueMessage(i18next.t(`arenaTag:waterFirePledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
override apply(arena: Arena, args: any[]): boolean {
|
||||||
|
const moveChance = args[0] as Utils.NumberHolder;
|
||||||
|
moveChance.value *= 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arena Tag implementing the "swamp" effect from the combination
|
||||||
|
* of {@link https://bulbapedia.bulbagarden.net/wiki/Grass_Pledge_(move) | Grass Pledge}
|
||||||
|
* and {@link https://bulbapedia.bulbagarden.net/wiki/Water_Pledge_(move) | Water Pledge}.
|
||||||
|
* Quarters the Speed of Pokemon on the given side of the field for 4 turns.
|
||||||
|
*/
|
||||||
|
class GrassWaterPledgeTag extends ArenaTag {
|
||||||
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
|
super(ArenaTagType.GRASS_WATER_PLEDGE, 4, Moves.GRASS_PLEDGE, sourceId, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
override onAdd(arena: Arena): void {
|
||||||
|
// "A swamp enveloped your/the opposing team!"
|
||||||
|
arena.scene.queueMessage(i18next.t(`arenaTag:grassWaterPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null {
|
export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null {
|
||||||
switch (tagType) {
|
switch (tagType) {
|
||||||
case ArenaTagType.MIST:
|
case ArenaTagType.MIST:
|
||||||
@ -1043,8 +1120,8 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
|
|||||||
return new MudSportTag(turnCount, sourceId);
|
return new MudSportTag(turnCount, sourceId);
|
||||||
case ArenaTagType.WATER_SPORT:
|
case ArenaTagType.WATER_SPORT:
|
||||||
return new WaterSportTag(turnCount, sourceId);
|
return new WaterSportTag(turnCount, sourceId);
|
||||||
case ArenaTagType.PLASMA_FISTS:
|
case ArenaTagType.ION_DELUGE:
|
||||||
return new PlasmaFistsTag();
|
return new IonDelugeTag(sourceMove);
|
||||||
case ArenaTagType.SPIKES:
|
case ArenaTagType.SPIKES:
|
||||||
return new SpikesTag(sourceId, side);
|
return new SpikesTag(sourceId, side);
|
||||||
case ArenaTagType.TOXIC_SPIKES:
|
case ArenaTagType.TOXIC_SPIKES:
|
||||||
@ -1076,6 +1153,12 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
|
|||||||
return new SafeguardTag(turnCount, sourceId, side);
|
return new SafeguardTag(turnCount, sourceId, side);
|
||||||
case ArenaTagType.IMPRISON:
|
case ArenaTagType.IMPRISON:
|
||||||
return new ImprisonTag(sourceId, side);
|
return new ImprisonTag(sourceId, side);
|
||||||
|
case ArenaTagType.FIRE_GRASS_PLEDGE:
|
||||||
|
return new FireGrassPledgeTag(sourceId, side);
|
||||||
|
case ArenaTagType.WATER_FIRE_PLEDGE:
|
||||||
|
return new WaterFirePledgeTag(sourceId, side);
|
||||||
|
case ArenaTagType.GRASS_WATER_PLEDGE:
|
||||||
|
return new GrassWaterPledgeTag(sourceId, side);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -630,16 +630,16 @@ export const speciesStarterCosts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const starterCandyCosts: { passive: number; costReduction: [number, number]; egg: number; }[] = [
|
const starterCandyCosts: { passive: number; costReduction: [number, number]; egg: number; }[] = [
|
||||||
{ passive: 40, costReduction: [25, 60], egg: 30 }, // 1 Cost
|
{ passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 1 Cost
|
||||||
{ passive: 40, costReduction: [25, 60], egg: 30 }, // 2 Cost
|
{ passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 2 Cost
|
||||||
{ passive: 35, costReduction: [20, 50], egg: 25 }, // 3 Cost
|
{ passive: 35, costReduction: [ 20, 50 ], egg: 25 }, // 3 Cost
|
||||||
{ passive: 30, costReduction: [15, 40], egg: 20 }, // 4 Cost
|
{ passive: 30, costReduction: [ 15, 40 ], egg: 20 }, // 4 Cost
|
||||||
{ passive: 25, costReduction: [12, 35], egg: 18 }, // 5 Cost
|
{ passive: 25, costReduction: [ 12, 35 ], egg: 18 }, // 5 Cost
|
||||||
{ passive: 20, costReduction: [10, 30], egg: 15 }, // 6 Cost
|
{ passive: 20, costReduction: [ 10, 30 ], egg: 15 }, // 6 Cost
|
||||||
{ passive: 15, costReduction: [8, 20], egg: 12 }, // 7 Cost
|
{ passive: 15, costReduction: [ 8, 20 ], egg: 12 }, // 7 Cost
|
||||||
{ passive: 10, costReduction: [5, 15], egg: 10 }, // 8 Cost
|
{ passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 8 Cost
|
||||||
{ passive: 10, costReduction: [5, 15], egg: 10 }, // 9 Cost
|
{ passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 9 Cost
|
||||||
{ passive: 10, costReduction: [5, 15], egg: 10 }, // 10 Cost
|
{ passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 10 Cost
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -556,7 +556,7 @@ function logMissingMoveAnim(move: Moves, ...optionalParams: any[]) {
|
|||||||
* @param encounterAnim one or more animations to fetch
|
* @param encounterAnim one or more animations to fetch
|
||||||
*/
|
*/
|
||||||
export async function initEncounterAnims(scene: BattleScene, encounterAnim: EncounterAnim | EncounterAnim[]): Promise<void> {
|
export async function initEncounterAnims(scene: BattleScene, encounterAnim: EncounterAnim | EncounterAnim[]): Promise<void> {
|
||||||
const anims = Array.isArray(encounterAnim) ? encounterAnim : [encounterAnim];
|
const anims = Array.isArray(encounterAnim) ? encounterAnim : [ encounterAnim ];
|
||||||
const encounterAnimNames = Utils.getEnumKeys(EncounterAnim);
|
const encounterAnimNames = Utils.getEnumKeys(EncounterAnim);
|
||||||
const encounterAnimFetches: Promise<Map<EncounterAnim, AnimConfig>>[] = [];
|
const encounterAnimFetches: Promise<Map<EncounterAnim, AnimConfig>>[] = [];
|
||||||
for (const anim of anims) {
|
for (const anim of anims) {
|
||||||
@ -774,9 +774,9 @@ export abstract class BattleAnim {
|
|||||||
|
|
||||||
private getGraphicFrameData(scene: BattleScene, frames: AnimFrame[], onSubstitute?: boolean): Map<integer, Map<AnimFrameTarget, GraphicFrameData>> {
|
private getGraphicFrameData(scene: BattleScene, frames: AnimFrame[], onSubstitute?: boolean): Map<integer, Map<AnimFrameTarget, GraphicFrameData>> {
|
||||||
const ret: Map<integer, Map<AnimFrameTarget, GraphicFrameData>> = new Map([
|
const ret: Map<integer, Map<AnimFrameTarget, GraphicFrameData>> = new Map([
|
||||||
[AnimFrameTarget.GRAPHIC, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
[ AnimFrameTarget.GRAPHIC, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
||||||
[AnimFrameTarget.USER, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
[ AnimFrameTarget.USER, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
||||||
[AnimFrameTarget.TARGET, new Map<AnimFrameTarget, GraphicFrameData>() ]
|
[ AnimFrameTarget.TARGET, new Map<AnimFrameTarget, GraphicFrameData>() ]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const isOppAnim = this.isOppAnim();
|
const isOppAnim = this.isOppAnim();
|
||||||
@ -1093,9 +1093,9 @@ export abstract class BattleAnim {
|
|||||||
|
|
||||||
private getGraphicFrameDataWithoutTarget(frames: AnimFrame[], targetInitialX: number, targetInitialY: number): Map<integer, Map<AnimFrameTarget, GraphicFrameData>> {
|
private getGraphicFrameDataWithoutTarget(frames: AnimFrame[], targetInitialX: number, targetInitialY: number): Map<integer, Map<AnimFrameTarget, GraphicFrameData>> {
|
||||||
const ret: Map<integer, Map<AnimFrameTarget, GraphicFrameData>> = new Map([
|
const ret: Map<integer, Map<AnimFrameTarget, GraphicFrameData>> = new Map([
|
||||||
[AnimFrameTarget.GRAPHIC, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
[ AnimFrameTarget.GRAPHIC, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
||||||
[AnimFrameTarget.USER, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
[ AnimFrameTarget.USER, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
||||||
[AnimFrameTarget.TARGET, new Map<AnimFrameTarget, GraphicFrameData>() ]
|
[ AnimFrameTarget.TARGET, new Map<AnimFrameTarget, GraphicFrameData>() ]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let g = 0;
|
let g = 0;
|
||||||
|
@ -363,7 +363,7 @@ export class RechargingTag extends BattlerTag {
|
|||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
|
|
||||||
// Queue a placeholder move for the Pokemon to "use" next turn
|
// Queue a placeholder move for the Pokemon to "use" next turn
|
||||||
pokemon.getMoveQueue().push({ move: Moves.NONE, targets: [] });
|
pokemon.getMoveQueue().push({ move: Moves.NONE, targets: []});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cancels the source's move this turn and queues a "__ must recharge!" message */
|
/** Cancels the source's move this turn and queues a "__ must recharge!" message */
|
||||||
@ -569,7 +569,7 @@ export class InterruptedTag extends BattlerTag {
|
|||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
|
|
||||||
pokemon.getMoveQueue().shift();
|
pokemon.getMoveQueue().shift();
|
||||||
pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER});
|
pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.OTHER });
|
||||||
}
|
}
|
||||||
|
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
@ -1935,10 +1935,10 @@ export class RoostedTag extends BattlerTag {
|
|||||||
modifiedTypes = currentTypes.filter(type => type !== Type.NORMAL);
|
modifiedTypes = currentTypes.filter(type => type !== Type.NORMAL);
|
||||||
modifiedTypes.push(Type.FLYING);
|
modifiedTypes.push(Type.FLYING);
|
||||||
} else {
|
} else {
|
||||||
modifiedTypes = [Type.FLYING];
|
modifiedTypes = [ Type.FLYING ];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
modifiedTypes = [...currentTypes];
|
modifiedTypes = [ ...currentTypes ];
|
||||||
modifiedTypes.push(Type.FLYING);
|
modifiedTypes.push(Type.FLYING);
|
||||||
}
|
}
|
||||||
pokemon.summonData.types = modifiedTypes;
|
pokemon.summonData.types = modifiedTypes;
|
||||||
@ -1958,10 +1958,10 @@ export class RoostedTag extends BattlerTag {
|
|||||||
if (this.isBaseFlying) {
|
if (this.isBaseFlying) {
|
||||||
let modifiedTypes: Type[];
|
let modifiedTypes: Type[];
|
||||||
if (this.isBasePureFlying && !isCurrentlyDualType) {
|
if (this.isBasePureFlying && !isCurrentlyDualType) {
|
||||||
modifiedTypes = [Type.NORMAL];
|
modifiedTypes = [ Type.NORMAL ];
|
||||||
} else {
|
} else {
|
||||||
if (!!pokemon.getTag(RemovedTypeTag) && isOriginallyDualType && !isCurrentlyDualType) {
|
if (!!pokemon.getTag(RemovedTypeTag) && isOriginallyDualType && !isCurrentlyDualType) {
|
||||||
modifiedTypes = [Type.UNKNOWN];
|
modifiedTypes = [ Type.UNKNOWN ];
|
||||||
} else {
|
} else {
|
||||||
modifiedTypes = currentTypes.filter(type => type !== Type.FLYING);
|
modifiedTypes = currentTypes.filter(type => type !== Type.FLYING);
|
||||||
}
|
}
|
||||||
@ -2067,8 +2067,8 @@ export class StockpilingTag extends BattlerTag {
|
|||||||
super.loadTag(source);
|
super.loadTag(source);
|
||||||
this.stockpiledCount = source.stockpiledCount || 0;
|
this.stockpiledCount = source.stockpiledCount || 0;
|
||||||
this.statChangeCounts = {
|
this.statChangeCounts = {
|
||||||
[ Stat.DEF ]: source.statChangeCounts?.[ Stat.DEF ] ?? 0,
|
[Stat.DEF]: source.statChangeCounts?.[Stat.DEF] ?? 0,
|
||||||
[ Stat.SPDEF ]: source.statChangeCounts?.[ Stat.SPDEF ] ?? 0,
|
[Stat.SPDEF]: source.statChangeCounts?.[Stat.SPDEF] ?? 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2090,7 +2090,7 @@ export class StockpilingTag extends BattlerTag {
|
|||||||
// Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes.
|
// Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes.
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(
|
||||||
pokemon.scene, pokemon.getBattlerIndex(), true,
|
pokemon.scene, pokemon.getBattlerIndex(), true,
|
||||||
[Stat.SPDEF, Stat.DEF], 1, true, false, true, this.onStatStagesChanged
|
[ Stat.SPDEF, Stat.DEF ], 1, true, false, true, this.onStatStagesChanged
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2267,7 +2267,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag {
|
|||||||
* Uses DisabledTag's selectionDeniedText() message
|
* Uses DisabledTag's selectionDeniedText() message
|
||||||
*/
|
*/
|
||||||
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
|
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:moveDisabled", { moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledHealBlock", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name, healBlockName: allMoves[Moves.HEAL_BLOCK].name });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2277,7 +2277,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag {
|
|||||||
* @returns {string} text to display when the move is interrupted
|
* @returns {string} text to display when the move is interrupted
|
||||||
*/
|
*/
|
||||||
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledHealBlock", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name, healBlockName: allMoves[Moves.HEAL_BLOCK].name });
|
||||||
}
|
}
|
||||||
|
|
||||||
override onRemove(pokemon: Pokemon): void {
|
override onRemove(pokemon: Pokemon): void {
|
||||||
@ -2310,6 +2310,21 @@ export class TarShotTag extends BattlerTag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Battler Tag implementing the type-changing effect of {@link https://bulbapedia.bulbagarden.net/wiki/Electrify_(move) | Electrify}.
|
||||||
|
* While this tag is in effect, the afflicted Pokemon's moves are changed to Electric type.
|
||||||
|
*/
|
||||||
|
export class ElectrifiedTag extends BattlerTag {
|
||||||
|
constructor() {
|
||||||
|
super(BattlerTagType.ELECTRIFIED, BattlerTagLapseType.TURN_END, 1, Moves.ELECTRIFY);
|
||||||
|
}
|
||||||
|
|
||||||
|
override onAdd(pokemon: Pokemon): void {
|
||||||
|
// "{pokemonNameWithAffix}'s moves have been electrified!"
|
||||||
|
pokemon.scene.queueMessage(i18next.t("battlerTags:electrifiedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Battler Tag that keeps track of how many times the user has Autotomized
|
* Battler Tag that keeps track of how many times the user has Autotomized
|
||||||
* Each count of Autotomization reduces the weight by 100kg
|
* Each count of Autotomization reduces the weight by 100kg
|
||||||
@ -2354,7 +2369,7 @@ export class SubstituteTag extends BattlerTag {
|
|||||||
public sourceInFocus: boolean;
|
public sourceInFocus: boolean;
|
||||||
|
|
||||||
constructor(sourceMove: Moves, sourceId: integer) {
|
constructor(sourceMove: Moves, sourceId: integer) {
|
||||||
super(BattlerTagType.SUBSTITUTE, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE, BattlerTagLapseType.HIT], 0, sourceMove, sourceId, true);
|
super(BattlerTagType.SUBSTITUTE, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE, BattlerTagLapseType.HIT ], 0, sourceMove, sourceId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the Substitute's HP and queues an on-add battle animation that initializes the Substitute's sprite. */
|
/** Sets the Substitute's HP and queues an on-add battle animation that initializes the Substitute's sprite. */
|
||||||
@ -2378,7 +2393,7 @@ export class SubstituteTag extends BattlerTag {
|
|||||||
onRemove(pokemon: Pokemon): void {
|
onRemove(pokemon: Pokemon): void {
|
||||||
// Only play the animation if the cause of removal isn't from the source's own move
|
// Only play the animation if the cause of removal isn't from the source's own move
|
||||||
if (!this.sourceInFocus) {
|
if (!this.sourceInFocus) {
|
||||||
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_REMOVE, [this.sprite]);
|
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_REMOVE, [ this.sprite ]);
|
||||||
} else {
|
} else {
|
||||||
this.sprite.destroy();
|
this.sprite.destroy();
|
||||||
}
|
}
|
||||||
@ -2402,13 +2417,13 @@ export class SubstituteTag extends BattlerTag {
|
|||||||
|
|
||||||
/** Triggers an animation that brings the Pokemon into focus before it uses a move */
|
/** Triggers an animation that brings the Pokemon into focus before it uses a move */
|
||||||
onPreMove(pokemon: Pokemon): void {
|
onPreMove(pokemon: Pokemon): void {
|
||||||
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_PRE_MOVE, [this.sprite]);
|
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_PRE_MOVE, [ this.sprite ]);
|
||||||
this.sourceInFocus = true;
|
this.sourceInFocus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Triggers an animation that brings the Pokemon out of focus after it uses a move */
|
/** Triggers an animation that brings the Pokemon out of focus after it uses a move */
|
||||||
onAfterMove(pokemon: Pokemon): void {
|
onAfterMove(pokemon: Pokemon): void {
|
||||||
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_POST_MOVE, [this.sprite]);
|
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_POST_MOVE, [ this.sprite ]);
|
||||||
this.sourceInFocus = false;
|
this.sourceInFocus = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2530,8 +2545,8 @@ export class TormentTag extends MoveRestrictionBattlerTag {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {
|
override selectionDeniedText(pokemon: Pokemon, _move: Moves): string {
|
||||||
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledTorment", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2542,7 +2557,7 @@ export class TormentTag extends MoveRestrictionBattlerTag {
|
|||||||
*/
|
*/
|
||||||
export class TauntTag extends MoveRestrictionBattlerTag {
|
export class TauntTag extends MoveRestrictionBattlerTag {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(BattlerTagType.TAUNT, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE], 4, Moves.TAUNT);
|
super(BattlerTagType.TAUNT, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 4, Moves.TAUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
override onAdd(pokemon: Pokemon) {
|
override onAdd(pokemon: Pokemon) {
|
||||||
@ -2559,12 +2574,12 @@ export class TauntTag extends MoveRestrictionBattlerTag {
|
|||||||
return allMoves[move].category === MoveCategory.STATUS;
|
return allMoves[move].category === MoveCategory.STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {
|
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledTaunt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
||||||
}
|
}
|
||||||
|
|
||||||
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledTaunt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2577,7 +2592,7 @@ export class ImprisonTag extends MoveRestrictionBattlerTag {
|
|||||||
private source: Pokemon | null;
|
private source: Pokemon | null;
|
||||||
|
|
||||||
constructor(sourceId: number) {
|
constructor(sourceId: number) {
|
||||||
super(BattlerTagType.IMPRISON, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE], 1, Moves.IMPRISON, sourceId);
|
super(BattlerTagType.IMPRISON, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 1, Moves.IMPRISON, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
override onAdd(pokemon: Pokemon) {
|
override onAdd(pokemon: Pokemon) {
|
||||||
@ -2609,12 +2624,12 @@ export class ImprisonTag extends MoveRestrictionBattlerTag {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {
|
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledImprison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
||||||
}
|
}
|
||||||
|
|
||||||
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
||||||
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
return i18next.t("battle:moveDisabledImprison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2650,7 +2665,7 @@ export class SyrupBombTag extends BattlerTag {
|
|||||||
pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); // Custom message in lieu of an animation in mainline
|
pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); // Custom message in lieu of an animation in mainline
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(
|
||||||
pokemon.scene, pokemon.getBattlerIndex(), true,
|
pokemon.scene, pokemon.getBattlerIndex(), true,
|
||||||
[Stat.SPD], -1, true, false, true
|
[ Stat.SPD ], -1, true, false, true
|
||||||
));
|
));
|
||||||
return --this.turnCount > 0;
|
return --this.turnCount > 0;
|
||||||
}
|
}
|
||||||
@ -2803,14 +2818,16 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
|||||||
case BattlerTagType.DISABLED:
|
case BattlerTagType.DISABLED:
|
||||||
return new DisabledTag(sourceId);
|
return new DisabledTag(sourceId);
|
||||||
case BattlerTagType.IGNORE_GHOST:
|
case BattlerTagType.IGNORE_GHOST:
|
||||||
return new ExposedTag(tagType, sourceMove, Type.GHOST, [Type.NORMAL, Type.FIGHTING]);
|
return new ExposedTag(tagType, sourceMove, Type.GHOST, [ Type.NORMAL, Type.FIGHTING ]);
|
||||||
case BattlerTagType.IGNORE_DARK:
|
case BattlerTagType.IGNORE_DARK:
|
||||||
return new ExposedTag(tagType, sourceMove, Type.DARK, [Type.PSYCHIC]);
|
return new ExposedTag(tagType, sourceMove, Type.DARK, [ Type.PSYCHIC ]);
|
||||||
case BattlerTagType.GULP_MISSILE_ARROKUDA:
|
case BattlerTagType.GULP_MISSILE_ARROKUDA:
|
||||||
case BattlerTagType.GULP_MISSILE_PIKACHU:
|
case BattlerTagType.GULP_MISSILE_PIKACHU:
|
||||||
return new GulpMissileTag(tagType, sourceMove);
|
return new GulpMissileTag(tagType, sourceMove);
|
||||||
case BattlerTagType.TAR_SHOT:
|
case BattlerTagType.TAR_SHOT:
|
||||||
return new TarShotTag();
|
return new TarShotTag();
|
||||||
|
case BattlerTagType.ELECTRIFIED:
|
||||||
|
return new ElectrifiedTag();
|
||||||
case BattlerTagType.THROAT_CHOPPED:
|
case BattlerTagType.THROAT_CHOPPED:
|
||||||
return new ThroatChoppedTag();
|
return new ThroatChoppedTag();
|
||||||
case BattlerTagType.GORILLA_TACTICS:
|
case BattlerTagType.GORILLA_TACTICS:
|
||||||
|
@ -185,7 +185,7 @@ export abstract class Challenge {
|
|||||||
*/
|
*/
|
||||||
getDescription(overrideValue?: number): string {
|
getDescription(overrideValue?: number): string {
|
||||||
const value = overrideValue ?? this.value;
|
const value = overrideValue ?? this.value;
|
||||||
return `${i18next.t([`challenges:${this.geti18nKey()}.desc.${value}`, `challenges:${this.geti18nKey()}.desc`])}`;
|
return `${i18next.t([ `challenges:${this.geti18nKey()}.desc.${value}`, `challenges:${this.geti18nKey()}.desc` ])}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -414,9 +414,9 @@ export class SingleGenerationChallenge extends Challenge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean {
|
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean {
|
||||||
const generations = [pokemon.generation];
|
const generations = [ pokemon.generation ];
|
||||||
if (soft) {
|
if (soft) {
|
||||||
const speciesToCheck = [pokemon.speciesId];
|
const speciesToCheck = [ pokemon.speciesId ];
|
||||||
while (speciesToCheck.length) {
|
while (speciesToCheck.length) {
|
||||||
const checking = speciesToCheck.pop();
|
const checking = speciesToCheck.pop();
|
||||||
if (checking && pokemonEvolutions.hasOwnProperty(checking)) {
|
if (checking && pokemonEvolutions.hasOwnProperty(checking)) {
|
||||||
@ -455,7 +455,7 @@ export class SingleGenerationChallenge extends Challenge {
|
|||||||
trainerTypes = [ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY ];
|
trainerTypes = [ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY ];
|
||||||
break;
|
break;
|
||||||
case 186:
|
case 186:
|
||||||
trainerTypes = [ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, Utils.randSeedItem([TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE]), TrainerType.LARRY_ELITE ];
|
trainerTypes = [ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, Utils.randSeedItem([ TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE ]), TrainerType.LARRY_ELITE ];
|
||||||
break;
|
break;
|
||||||
case 188:
|
case 188:
|
||||||
trainerTypes = [ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL ];
|
trainerTypes = [ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL ];
|
||||||
@ -528,10 +528,10 @@ interface monotypeOverride {
|
|||||||
*/
|
*/
|
||||||
export class SingleTypeChallenge extends Challenge {
|
export class SingleTypeChallenge extends Challenge {
|
||||||
private static TYPE_OVERRIDES: monotypeOverride[] = [
|
private static TYPE_OVERRIDES: monotypeOverride[] = [
|
||||||
{species: Species.CASTFORM, type: Type.NORMAL, fusion: false},
|
{ species: Species.CASTFORM, type: Type.NORMAL, fusion: false },
|
||||||
];
|
];
|
||||||
// TODO: Find a solution for all Pokemon with this ssui issue, including Basculin and Burmy
|
// TODO: Find a solution for all Pokemon with this ssui issue, including Basculin and Burmy
|
||||||
private static SPECIES_OVERRIDES: Species[] = [Species.MELOETTA];
|
private static SPECIES_OVERRIDES: Species[] = [ Species.MELOETTA ];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(Challenges.SINGLE_TYPE, 18);
|
super(Challenges.SINGLE_TYPE, 18);
|
||||||
@ -539,9 +539,9 @@ export class SingleTypeChallenge extends Challenge {
|
|||||||
|
|
||||||
override applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean {
|
override applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean {
|
||||||
const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex);
|
const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex);
|
||||||
const types = [speciesForm.type1, speciesForm.type2];
|
const types = [ speciesForm.type1, speciesForm.type2 ];
|
||||||
if (soft && !SingleTypeChallenge.SPECIES_OVERRIDES.includes(pokemon.speciesId)) {
|
if (soft && !SingleTypeChallenge.SPECIES_OVERRIDES.includes(pokemon.speciesId)) {
|
||||||
const speciesToCheck = [pokemon.speciesId];
|
const speciesToCheck = [ pokemon.speciesId ];
|
||||||
while (speciesToCheck.length) {
|
while (speciesToCheck.length) {
|
||||||
const checking = speciesToCheck.pop();
|
const checking = speciesToCheck.pop();
|
||||||
if (checking && pokemonEvolutions.hasOwnProperty(checking)) {
|
if (checking && pokemonEvolutions.hasOwnProperty(checking)) {
|
||||||
@ -606,9 +606,9 @@ export class SingleTypeChallenge extends Challenge {
|
|||||||
overrideValue = this.value;
|
overrideValue = this.value;
|
||||||
}
|
}
|
||||||
const type = i18next.t(`pokemonInfo:Type.${Type[this.value - 1]}`);
|
const type = i18next.t(`pokemonInfo:Type.${Type[this.value - 1]}`);
|
||||||
const typeColor = `[color=${TypeColor[Type[this.value-1]]}][shadow=${TypeShadow[Type[this.value-1]]}]${type}[/shadow][/color]`;
|
const typeColor = `[color=${TypeColor[Type[this.value - 1]]}][shadow=${TypeShadow[Type[this.value - 1]]}]${type}[/shadow][/color]`;
|
||||||
const defaultDesc = i18next.t("challenges:singleType.desc_default");
|
const defaultDesc = i18next.t("challenges:singleType.desc_default");
|
||||||
const typeDesc = i18next.t("challenges:singleType.desc", {type: typeColor});
|
const typeDesc = i18next.t("challenges:singleType.desc", { type: typeColor });
|
||||||
return this.value === 0 ? defaultDesc : typeDesc;
|
return this.value === 0 ? defaultDesc : typeDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +653,7 @@ export class FreshStartChallenge extends Challenge {
|
|||||||
pokemon.shiny = false; // Not shiny
|
pokemon.shiny = false; // Not shiny
|
||||||
pokemon.variant = 0; // Not shiny
|
pokemon.variant = 0; // Not shiny
|
||||||
pokemon.formIndex = 0; // Froakie should be base form
|
pokemon.formIndex = 0; // Froakie should be base form
|
||||||
pokemon.ivs = [10, 10, 10, 10, 10, 10]; // Default IVs of 10 for all stats
|
pokemon.ivs = [ 10, 10, 10, 10, 10, 10 ]; // Default IVs of 10 for all stats
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3123,44 +3123,44 @@ export const trainerTypeDialogue: TrainerTypeDialogue = {
|
|||||||
|
|
||||||
export const doubleBattleDialogue = {
|
export const doubleBattleDialogue = {
|
||||||
"blue_red_double": {
|
"blue_red_double": {
|
||||||
encounter: ["doubleBattleDialogue:blue_red_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:blue_red_double.encounter.1" ],
|
||||||
victory: ["doubleBattleDialogue:blue_red_double.victory.1"]
|
victory: [ "doubleBattleDialogue:blue_red_double.victory.1" ]
|
||||||
},
|
},
|
||||||
"red_blue_double": {
|
"red_blue_double": {
|
||||||
encounter: ["doubleBattleDialogue:red_blue_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:red_blue_double.encounter.1" ],
|
||||||
victory: ["doubleBattleDialogue:red_blue_double.victory.1"]
|
victory: [ "doubleBattleDialogue:red_blue_double.victory.1" ]
|
||||||
},
|
},
|
||||||
"tate_liza_double": {
|
"tate_liza_double": {
|
||||||
encounter: ["doubleBattleDialogue:tate_liza_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:tate_liza_double.encounter.1" ],
|
||||||
victory: ["doubleBattleDialogue:tate_liza_double.victory.1"]
|
victory: [ "doubleBattleDialogue:tate_liza_double.victory.1" ]
|
||||||
},
|
},
|
||||||
"liza_tate_double": {
|
"liza_tate_double": {
|
||||||
encounter: ["doubleBattleDialogue:liza_tate_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:liza_tate_double.encounter.1" ],
|
||||||
victory: [ "doubleBattleDialogue:liza_tate_double.victory.1"]
|
victory: [ "doubleBattleDialogue:liza_tate_double.victory.1" ]
|
||||||
},
|
},
|
||||||
"wallace_steven_double": {
|
"wallace_steven_double": {
|
||||||
encounter: [ "doubleBattleDialogue:wallace_steven_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:wallace_steven_double.encounter.1" ],
|
||||||
victory: [ "doubleBattleDialogue:wallace_steven_double.victory.1"]
|
victory: [ "doubleBattleDialogue:wallace_steven_double.victory.1" ]
|
||||||
},
|
},
|
||||||
"steven_wallace_double": {
|
"steven_wallace_double": {
|
||||||
encounter: [ "doubleBattleDialogue:steven_wallace_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:steven_wallace_double.encounter.1" ],
|
||||||
victory: [ "doubleBattleDialogue:steven_wallace_double.victory.1"]
|
victory: [ "doubleBattleDialogue:steven_wallace_double.victory.1" ]
|
||||||
},
|
},
|
||||||
"alder_iris_double": {
|
"alder_iris_double": {
|
||||||
encounter: [ "doubleBattleDialogue:alder_iris_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:alder_iris_double.encounter.1" ],
|
||||||
victory: [ "doubleBattleDialogue:alder_iris_double.victory.1"]
|
victory: [ "doubleBattleDialogue:alder_iris_double.victory.1" ]
|
||||||
},
|
},
|
||||||
"iris_alder_double": {
|
"iris_alder_double": {
|
||||||
encounter: [ "doubleBattleDialogue:iris_alder_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:iris_alder_double.encounter.1" ],
|
||||||
victory: [ "doubleBattleDialogue:iris_alder_double.victory.1"]
|
victory: [ "doubleBattleDialogue:iris_alder_double.victory.1" ]
|
||||||
},
|
},
|
||||||
"marnie_piers_double": {
|
"marnie_piers_double": {
|
||||||
encounter: [ "doubleBattleDialogue:marnie_piers_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:marnie_piers_double.encounter.1" ],
|
||||||
victory: [ "doubleBattleDialogue:marnie_piers_double.victory.1"]
|
victory: [ "doubleBattleDialogue:marnie_piers_double.victory.1" ]
|
||||||
},
|
},
|
||||||
"piers_marnie_double": {
|
"piers_marnie_double": {
|
||||||
encounter: [ "doubleBattleDialogue:piers_marnie_double.encounter.1"],
|
encounter: [ "doubleBattleDialogue:piers_marnie_double.encounter.1" ],
|
||||||
victory: [ "doubleBattleDialogue:piers_marnie_double.victory.1"]
|
victory: [ "doubleBattleDialogue:piers_marnie_double.victory.1" ]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -3193,7 +3193,7 @@ export function initTrainerTypeDialogue(): void {
|
|||||||
const trainerTypes = Object.keys(trainerTypeDialogue).map(t => parseInt(t) as TrainerType);
|
const trainerTypes = Object.keys(trainerTypeDialogue).map(t => parseInt(t) as TrainerType);
|
||||||
for (const trainerType of trainerTypes) {
|
for (const trainerType of trainerTypes) {
|
||||||
const messages = trainerTypeDialogue[trainerType];
|
const messages = trainerTypeDialogue[trainerType];
|
||||||
const messageTypes = ["encounter", "victory", "defeat"];
|
const messageTypes = [ "encounter", "victory", "defeat" ];
|
||||||
for (const messageType of messageTypes) {
|
for (const messageType of messageTypes) {
|
||||||
if (Array.isArray(messages)) {
|
if (Array.isArray(messages)) {
|
||||||
if (messages[0][messageType]) {
|
if (messages[0][messageType]) {
|
||||||
|
@ -48,7 +48,7 @@ export class EggHatchData {
|
|||||||
seenCount: currDexEntry.seenCount,
|
seenCount: currDexEntry.seenCount,
|
||||||
caughtCount: currDexEntry.caughtCount,
|
caughtCount: currDexEntry.caughtCount,
|
||||||
hatchedCount: currDexEntry.hatchedCount,
|
hatchedCount: currDexEntry.hatchedCount,
|
||||||
ivs: [...currDexEntry.ivs]
|
ivs: [ ...currDexEntry.ivs ]
|
||||||
};
|
};
|
||||||
this.starterDataEntryBeforeUpdate = {
|
this.starterDataEntryBeforeUpdate = {
|
||||||
moveset: currStarterDataEntry.moveset,
|
moveset: currStarterDataEntry.moveset,
|
||||||
|
@ -288,7 +288,7 @@ export class Egg {
|
|||||||
public getEggTypeDescriptor(scene: BattleScene): string {
|
public getEggTypeDescriptor(scene: BattleScene): string {
|
||||||
switch (this.sourceType) {
|
switch (this.sourceType) {
|
||||||
case EggSourceType.SAME_SPECIES_EGG:
|
case EggSourceType.SAME_SPECIES_EGG:
|
||||||
return this._eggDescriptor ?? i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName()});
|
return this._eggDescriptor ?? i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName() });
|
||||||
case EggSourceType.GACHA_LEGENDARY:
|
case EggSourceType.GACHA_LEGENDARY:
|
||||||
return this._eggDescriptor ?? `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp)).getName()})`;
|
return this._eggDescriptor ?? `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp)).getName()})`;
|
||||||
case EggSourceType.GACHA_SHINY:
|
case EggSourceType.GACHA_SHINY:
|
||||||
@ -396,7 +396,7 @@ export class Egg {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ignoredSpecies = [Species.PHIONE, Species.MANAPHY, Species.ETERNATUS];
|
const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ];
|
||||||
|
|
||||||
let speciesPool = Object.keys(speciesStarterCosts)
|
let speciesPool = Object.keys(speciesStarterCosts)
|
||||||
.filter(s => speciesStarterCosts[s] >= minStarterValue && speciesStarterCosts[s] <= maxStarterValue)
|
.filter(s => speciesStarterCosts[s] >= minStarterValue && speciesStarterCosts[s] <= maxStarterValue)
|
||||||
|
499
src/data/move.ts
499
src/data/move.ts
File diff suppressed because it is too large
Load Diff
@ -152,7 +152,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
tier: EggTier.ULTRA
|
tier: EggTier.ULTRA
|
||||||
};
|
};
|
||||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`));
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`));
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SACRED_ASH], guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ULTRA], fillRemaining: true }, [eggOptions]);
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SACRED_ASH ], guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ULTRA ], fillRemaining: true }, [ eggOptions ]);
|
||||||
return initBattleWithEnemyConfig(scene, config);
|
return initBattleWithEnemyConfig(scene, config);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -174,7 +174,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
tier: EggTier.GREAT
|
tier: EggTier.GREAT
|
||||||
};
|
};
|
||||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.rare`));
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.rare`));
|
||||||
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [eggOptions]);
|
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [ eggOptions ]);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -195,7 +195,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
// Can't define stack count on a ModifierType, have to just create separate instances for each stack
|
// Can't define stack count on a ModifierType, have to just create separate instances for each stack
|
||||||
// Overflow berries will be "lost" on the boss, but it's un-catchable anyway
|
// Overflow berries will be "lost" on the boss, but it's un-catchable anyway
|
||||||
for (let i = 0; i < berryMod.stackCount; i++) {
|
for (let i = 0; i < berryMod.stackCount; i++) {
|
||||||
const modifierType = generateModifierType(scene, modifierTypes.BERRY, [berryMod.berryType]) as PokemonHeldItemModifierType;
|
const modifierType = generateModifierType(scene, modifierTypes.BERRY, [ berryMod.berryType ]) as PokemonHeldItemModifierType;
|
||||||
bossModifierConfigs.push({ modifier: modifierType });
|
bossModifierConfigs.push({ modifier: modifierType });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -204,8 +204,8 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// SpDef buff below wave 50, +1 to all stats otherwise
|
// SpDef buff below wave 50, +1 to all stats otherwise
|
||||||
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
|
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
|
||||||
[Stat.SPDEF] :
|
[ Stat.SPDEF ] :
|
||||||
[Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD];
|
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
|
||||||
|
|
||||||
// Calculate boss mon
|
// Calculate boss mon
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
@ -215,9 +215,9 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
species: getPokemonSpecies(Species.GREEDENT),
|
species: getPokemonSpecies(Species.GREEDENT),
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
bossSegments: 3,
|
bossSegments: 3,
|
||||||
moveSet: [Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH],
|
moveSet: [ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH ],
|
||||||
modifierConfigs: bossModifierConfigs,
|
modifierConfigs: bossModifierConfigs,
|
||||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
||||||
@ -226,7 +226,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
encounter.setDialogueToken("greedentName", getPokemonSpecies(Species.GREEDENT).getName());
|
encounter.setDialogueToken("greedentName", getPokemonSpecies(Species.GREEDENT).getName());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -280,7 +280,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
setEncounterRewards(scene, { fillRemaining: true }, undefined, givePartyPokemonReviverSeeds);
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, givePartyPokemonReviverSeeds);
|
||||||
encounter.startOfBattleEffects.push({
|
encounter.startOfBattleEffects.push({
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.ENEMY],
|
targets: [ BattlerIndex.ENEMY ],
|
||||||
move: new PokemonMove(Moves.STUFF_CHEEKS),
|
move: new PokemonMove(Moves.STUFF_CHEEKS),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
});
|
});
|
||||||
@ -320,7 +320,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
Phaser.Math.RND.shuffle(berryTypesAsArray);
|
Phaser.Math.RND.shuffle(berryTypesAsArray);
|
||||||
const randBerryType = berryTypesAsArray.pop();
|
const randBerryType = berryTypesAsArray.pop();
|
||||||
|
|
||||||
const berryModType = generateModifierType(scene, modifierTypes.BERRY, [randBerryType]) as BerryModifierType;
|
const berryModType = generateModifierType(scene, modifierTypes.BERRY, [ randBerryType ]) as BerryModifierType;
|
||||||
applyModifierTypeToPlayerPokemon(scene, pokemon, berryModType);
|
applyModifierTypeToPlayerPokemon(scene, pokemon, berryModType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,7 +355,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
// Greedent joins the team, level equal to 2 below highest party member
|
// Greedent joins the team, level equal to 2 below highest party member
|
||||||
const level = getHighestLevelPlayerPokemon(scene, false, true).level - 2;
|
const level = getHighestLevelPlayerPokemon(scene, false, true).level - 2;
|
||||||
const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false);
|
const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false);
|
||||||
greedent.moveset = [new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF)];
|
greedent.moveset = [ new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF) ];
|
||||||
greedent.passive = true;
|
greedent.passive = true;
|
||||||
|
|
||||||
transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
|
transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
|
||||||
@ -472,7 +472,7 @@ function doGreedentEatBerries(scene: BattleScene) {
|
|||||||
*/
|
*/
|
||||||
function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) {
|
function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) {
|
||||||
const berryAddDelay = 150;
|
const berryAddDelay = 150;
|
||||||
let animationOrder = ["starf", "sitrus", "lansat", "salac", "apicot", "enigma", "liechi", "ganlon", "lum", "petaya", "leppa"];
|
let animationOrder = [ "starf", "sitrus", "lansat", "salac", "apicot", "enigma", "liechi", "ganlon", "lum", "petaya", "leppa" ];
|
||||||
if (isEat) {
|
if (isEat) {
|
||||||
animationOrder = animationOrder.reverse();
|
animationOrder = animationOrder.reverse();
|
||||||
}
|
}
|
||||||
@ -496,7 +496,7 @@ function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) {
|
|||||||
// Animate Petaya berry falling off the pile
|
// Animate Petaya berry falling off the pile
|
||||||
if (berry === "petaya" && sprite && tintSprite && !isEat) {
|
if (berry === "petaya" && sprite && tintSprite && !isEat) {
|
||||||
scene.time.delayedCall(200, () => {
|
scene.time.delayedCall(200, () => {
|
||||||
doBerryBounce(scene, [sprite, tintSprite], 30, 500);
|
doBerryBounce(scene, [ sprite, tintSprite ], 30, 500);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -69,7 +69,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
isBoss: true
|
isBoss: true
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
|
|
||||||
// Calculate the number of extra berries that player receives
|
// Calculate the number of extra berries that player receives
|
||||||
// 10-40: 2, 40-120: 4, 120-160: 5, 160-180: 7
|
// 10-40: 2, 40-120: 4, 120-160: 5, 160-180: 7
|
||||||
@ -193,11 +193,11 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
|
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
|
||||||
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
|
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
|
||||||
[Stat.DEF, Stat.SPDEF, Stat.SPD] :
|
[ Stat.DEF, Stat.SPDEF, Stat.SPD ] :
|
||||||
[Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD];
|
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
|
||||||
|
|
||||||
const config = scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
|
const config = scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
|
||||||
config.pokemonConfigs![0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON];
|
config.pokemonConfigs![0].tags = [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ];
|
||||||
config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
|
config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}:option.2.boss_enraged`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.2.boss_enraged`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
||||||
@ -208,7 +208,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Gains 1 berry for every 10% faster the player's pokemon is than the enemy, up to a max of numBerries, minimum of 2
|
// Gains 1 berry for every 10% faster the player's pokemon is than the enemy, up to a max of numBerries, minimum of 2
|
||||||
const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1)/0.08), numBerries), 2);
|
const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1) / 0.08), numBerries), 2);
|
||||||
encounter.setDialogueToken("numBerries", String(numBerriesGrabbed));
|
encounter.setDialogueToken("numBerries", String(numBerriesGrabbed));
|
||||||
const doFasterBerryRewards = () => {
|
const doFasterBerryRewards = () => {
|
||||||
const berryText = i18next.t(`${namespace}:berries`);
|
const berryText = i18next.t(`${namespace}:berries`);
|
||||||
@ -250,7 +250,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
function tryGiveBerry(scene: BattleScene, prioritizedPokemon?: PlayerPokemon) {
|
function tryGiveBerry(scene: BattleScene, prioritizedPokemon?: PlayerPokemon) {
|
||||||
const berryType = randSeedInt(Object.keys(BerryType).filter(s => !isNaN(Number(s))).length) as BerryType;
|
const berryType = randSeedInt(Object.keys(BerryType).filter(s => !isNaN(Number(s))).length) as BerryType;
|
||||||
const berry = generateModifierType(scene, modifierTypes.BERRY, [berryType]) as BerryModifierType;
|
const berry = generateModifierType(scene, modifierTypes.BERRY, [ berryType ]) as BerryModifierType;
|
||||||
|
|
||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ const MISC_TUTOR_MOVES = [
|
|||||||
/**
|
/**
|
||||||
* Wave breakpoints that determine how strong to make the Bug-Type Superfan's team
|
* Wave breakpoints that determine how strong to make the Bug-Type Superfan's team
|
||||||
*/
|
*/
|
||||||
const WAVE_LEVEL_BREAKPOINTS = [30, 50, 70, 100, 120, 140, 160];
|
const WAVE_LEVEL_BREAKPOINTS = [ 30, 50, 70, 100, 120, 140, 160 ];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bug Type Superfan encounter.
|
* Bug Type Superfan encounter.
|
||||||
@ -193,7 +193,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||||
// Must have at least 1 Bug type on team, OR have a bug item somewhere on the team
|
// Must have at least 1 Bug type on team, OR have a bug item somewhere on the team
|
||||||
new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1),
|
new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1),
|
||||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
||||||
new TypeRequirement(Type.BUG, false, 1)
|
new TypeRequirement(Type.BUG, false, 1)
|
||||||
))
|
))
|
||||||
@ -268,7 +268,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
const requiredItems = [
|
const requiredItems = [
|
||||||
generateModifierType(scene, modifierTypes.QUICK_CLAW),
|
generateModifierType(scene, modifierTypes.QUICK_CLAW),
|
||||||
generateModifierType(scene, modifierTypes.GRIP_CLAW),
|
generateModifierType(scene, modifierTypes.GRIP_CLAW),
|
||||||
generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.BUG]),
|
generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.BUG ]),
|
||||||
];
|
];
|
||||||
|
|
||||||
const requiredItemString = requiredItems.map(m => m?.name ?? "unknown").join("/");
|
const requiredItemString = requiredItems.map(m => m?.name ?? "unknown").join("/");
|
||||||
@ -331,7 +331,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
encounter.setDialogueToken("numBugTypes", numBugTypesText);
|
encounter.setDialogueToken("numBugTypes", numBugTypesText);
|
||||||
|
|
||||||
if (numBugTypes < 2) {
|
if (numBugTypes < 2) {
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL ], fillRemaining: false });
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}:speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
@ -339,7 +339,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
} else if (numBugTypes < 4) {
|
} else if (numBugTypes < 4) {
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL ], fillRemaining: false });
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}:speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
@ -347,7 +347,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
} else if (numBugTypes < 6) {
|
} else if (numBugTypes < 6) {
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL ], fillRemaining: false });
|
||||||
encounter.selectedOption!.dialogue!.selected = [
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `${namespace}:speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
@ -356,7 +356,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
// If player has any evolution/form change items that are valid for their party, will spawn one of those items in addition to a Master Ball
|
// If player has any evolution/form change items that are valid for their party, will spawn one of those items in addition to a Master Ball
|
||||||
const modifierOptions: ModifierTypeOption[] = [generateModifierTypeOption(scene, modifierTypes.MASTER_BALL)!, generateModifierTypeOption(scene, modifierTypes.MAX_LURE)!];
|
const modifierOptions: ModifierTypeOption[] = [ generateModifierTypeOption(scene, modifierTypes.MASTER_BALL)!, generateModifierTypeOption(scene, modifierTypes.MAX_LURE)! ];
|
||||||
const specialOptions: ModifierTypeOption[] = [];
|
const specialOptions: ModifierTypeOption[] = [];
|
||||||
|
|
||||||
const nonRareEvolutionModifier = generateModifierTypeOption(scene, modifierTypes.EVOLUTION_ITEM);
|
const nonRareEvolutionModifier = generateModifierTypeOption(scene, modifierTypes.EVOLUTION_ITEM);
|
||||||
@ -397,7 +397,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||||
// Meets one or both of the below reqs
|
// Meets one or both of the below reqs
|
||||||
new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1),
|
new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1),
|
||||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1)
|
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1)
|
||||||
))
|
))
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
@ -474,7 +474,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
const bugNet = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!;
|
const bugNet = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!;
|
||||||
bugNet.type.tier = ModifierTier.ROGUE;
|
bugNet.type.tier = ModifierTier.ROGUE;
|
||||||
|
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [bugNet], guaranteedModifierTypeFuncs: [modifierTypes.REVIVER_SEED], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ bugNet ], guaranteedModifierTypeFuncs: [ modifierTypes.REVIVER_SEED ], fillRemaining: false });
|
||||||
leaveEncounterWithoutBattle(scene, true);
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
})
|
})
|
||||||
.build())
|
.build())
|
||||||
@ -535,7 +535,7 @@ function getTrainerConfigForWave(waveIndex: number) {
|
|||||||
}))
|
}))
|
||||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => {
|
||||||
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||||
p.formIndex = pool3Mon.formIndex;
|
p.formIndex = pool3Mon.formIndex;
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
@ -558,14 +558,14 @@ function getTrainerConfigForWave(waveIndex: number) {
|
|||||||
p.generateName();
|
p.generateName();
|
||||||
}))
|
}))
|
||||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => {
|
||||||
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||||
p.formIndex = pool3Mon.formIndex;
|
p.formIndex = pool3Mon.formIndex;
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
p.generateName();
|
p.generateName();
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => {
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc([ pool3Mon2.species ], TrainerSlot.TRAINER, true, p => {
|
||||||
if (!isNullOrUndefined(pool3Mon2.formIndex)) {
|
if (!isNullOrUndefined(pool3Mon2.formIndex)) {
|
||||||
p.formIndex = pool3Mon2.formIndex;
|
p.formIndex = pool3Mon2.formIndex;
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
@ -586,7 +586,7 @@ function getTrainerConfigForWave(waveIndex: number) {
|
|||||||
p.generateName();
|
p.generateName();
|
||||||
}))
|
}))
|
||||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => {
|
||||||
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||||
p.formIndex = pool3Mon.formIndex;
|
p.formIndex = pool3Mon.formIndex;
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
@ -611,14 +611,14 @@ function getTrainerConfigForWave(waveIndex: number) {
|
|||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
p.generateName();
|
p.generateName();
|
||||||
}))
|
}))
|
||||||
.setPartyMemberFunc(2, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => {
|
||||||
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||||
p.formIndex = pool3Mon.formIndex;
|
p.formIndex = pool3Mon.formIndex;
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
p.generateName();
|
p.generateName();
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => {
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ pool3Mon2.species ], TrainerSlot.TRAINER, true, p => {
|
||||||
if (!isNullOrUndefined(pool3Mon2.formIndex)) {
|
if (!isNullOrUndefined(pool3Mon2.formIndex)) {
|
||||||
p.formIndex = pool3Mon2.formIndex;
|
p.formIndex = pool3Mon2.formIndex;
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
|
@ -129,20 +129,20 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
{
|
{
|
||||||
species: getPokemonSpecies(Species.MR_MIME),
|
species: getPokemonSpecies(Species.MR_MIME),
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
moveSet: [Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC]
|
moveSet: [ Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC ]
|
||||||
},
|
},
|
||||||
{ // Blacephalon has the random ability from pool, and 2 entirely random types to fit with the theme of the encounter
|
{ // Blacephalon has the random ability from pool, and 2 entirely random types to fit with the theme of the encounter
|
||||||
species: getPokemonSpecies(Species.BLACEPHALON),
|
species: getPokemonSpecies(Species.BLACEPHALON),
|
||||||
mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ ability: ability, types: [randSeedInt(18), randSeedInt(18)] }),
|
mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ ability: ability, types: [ randSeedInt(18), randSeedInt(18) ]}),
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN]
|
moveSet: [ Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN ]
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
doubleBattle: true
|
doubleBattle: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load animations/sfx for start of fight moves
|
// Load animations/sfx for start of fight moves
|
||||||
loadCustomMovesForEncounter(scene, [Moves.ROLE_PLAY, Moves.TAUNT]);
|
loadCustomMovesForEncounter(scene, [ Moves.ROLE_PLAY, Moves.TAUNT ]);
|
||||||
|
|
||||||
encounter.setDialogueToken("blacephalonName", getPokemonSpecies(Species.BLACEPHALON).getName());
|
encounter.setDialogueToken("blacephalonName", getPokemonSpecies(Species.BLACEPHALON).getName());
|
||||||
|
|
||||||
@ -175,19 +175,19 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
encounter.startOfBattleEffects.push(
|
encounter.startOfBattleEffects.push(
|
||||||
{ // Mr. Mime copies the Blacephalon's random ability
|
{ // Mr. Mime copies the Blacephalon's random ability
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.ENEMY_2],
|
targets: [ BattlerIndex.ENEMY_2 ],
|
||||||
move: new PokemonMove(Moves.ROLE_PLAY),
|
move: new PokemonMove(Moves.ROLE_PLAY),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
||||||
targets: [BattlerIndex.PLAYER],
|
targets: [ BattlerIndex.PLAYER ],
|
||||||
move: new PokemonMove(Moves.TAUNT),
|
move: new PokemonMove(Moves.TAUNT),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
||||||
targets: [BattlerIndex.PLAYER_2],
|
targets: [ BattlerIndex.PLAYER_2 ],
|
||||||
move: new PokemonMove(Moves.TAUNT),
|
move: new PokemonMove(Moves.TAUNT),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
});
|
});
|
||||||
@ -336,11 +336,11 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
.filter(move => move && !originalTypes.includes(move.getMove().type) && move.getMove().category !== MoveCategory.STATUS)
|
.filter(move => move && !originalTypes.includes(move.getMove().type) && move.getMove().category !== MoveCategory.STATUS)
|
||||||
.map(move => move!.getMove().type);
|
.map(move => move!.getMove().type);
|
||||||
if (priorityTypes?.length > 0) {
|
if (priorityTypes?.length > 0) {
|
||||||
priorityTypes = [...new Set(priorityTypes)].sort();
|
priorityTypes = [ ...new Set(priorityTypes) ].sort();
|
||||||
priorityTypes = randSeedShuffle(priorityTypes);
|
priorityTypes = randSeedShuffle(priorityTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const newTypes = [originalTypes[0]];
|
const newTypes = [ originalTypes[0] ];
|
||||||
let secondType: Type | null = null;
|
let secondType: Type | null = null;
|
||||||
while (secondType === null || secondType === newTypes[0] || originalTypes.includes(secondType)) {
|
while (secondType === null || secondType === newTypes[0] || originalTypes.includes(secondType)) {
|
||||||
if (priorityTypes.length > 0) {
|
if (priorityTypes.length > 0) {
|
||||||
@ -453,37 +453,37 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem
|
|||||||
// Pools have instances of the modifier type equal to the max stacks that modifier can be applied to any one pokemon
|
// Pools have instances of the modifier type equal to the max stacks that modifier can be applied to any one pokemon
|
||||||
// This is to prevent "over-generating" a random item of a certain type during item swaps
|
// This is to prevent "over-generating" a random item of a certain type during item swaps
|
||||||
const ultraPool = [
|
const ultraPool = [
|
||||||
[modifierTypes.REVIVER_SEED, 1],
|
[ modifierTypes.REVIVER_SEED, 1 ],
|
||||||
[modifierTypes.GOLDEN_PUNCH, 5],
|
[ modifierTypes.GOLDEN_PUNCH, 5 ],
|
||||||
[modifierTypes.ATTACK_TYPE_BOOSTER, 99],
|
[ modifierTypes.ATTACK_TYPE_BOOSTER, 99 ],
|
||||||
[modifierTypes.QUICK_CLAW, 3],
|
[ modifierTypes.QUICK_CLAW, 3 ],
|
||||||
[modifierTypes.WIDE_LENS, 3]
|
[ modifierTypes.WIDE_LENS, 3 ]
|
||||||
];
|
];
|
||||||
|
|
||||||
const roguePool = [
|
const roguePool = [
|
||||||
[modifierTypes.LEFTOVERS, 4],
|
[ modifierTypes.LEFTOVERS, 4 ],
|
||||||
[modifierTypes.SHELL_BELL, 4],
|
[ modifierTypes.SHELL_BELL, 4 ],
|
||||||
[modifierTypes.SOUL_DEW, 10],
|
[ modifierTypes.SOUL_DEW, 10 ],
|
||||||
[modifierTypes.SOOTHE_BELL, 3],
|
[ modifierTypes.SOOTHE_BELL, 3 ],
|
||||||
[modifierTypes.SCOPE_LENS, 1],
|
[ modifierTypes.SCOPE_LENS, 1 ],
|
||||||
[modifierTypes.BATON, 1],
|
[ modifierTypes.BATON, 1 ],
|
||||||
[modifierTypes.FOCUS_BAND, 5],
|
[ modifierTypes.FOCUS_BAND, 5 ],
|
||||||
[modifierTypes.KINGS_ROCK, 3],
|
[ modifierTypes.KINGS_ROCK, 3 ],
|
||||||
[modifierTypes.GRIP_CLAW, 5]
|
[ modifierTypes.GRIP_CLAW, 5 ]
|
||||||
];
|
];
|
||||||
|
|
||||||
const berryPool = [
|
const berryPool = [
|
||||||
[BerryType.APICOT, 3],
|
[ BerryType.APICOT, 3 ],
|
||||||
[BerryType.ENIGMA, 2],
|
[ BerryType.ENIGMA, 2 ],
|
||||||
[BerryType.GANLON, 3],
|
[ BerryType.GANLON, 3 ],
|
||||||
[BerryType.LANSAT, 3],
|
[ BerryType.LANSAT, 3 ],
|
||||||
[BerryType.LEPPA, 2],
|
[ BerryType.LEPPA, 2 ],
|
||||||
[BerryType.LIECHI, 3],
|
[ BerryType.LIECHI, 3 ],
|
||||||
[BerryType.LUM, 2],
|
[ BerryType.LUM, 2 ],
|
||||||
[BerryType.PETAYA, 3],
|
[ BerryType.PETAYA, 3 ],
|
||||||
[BerryType.SALAC, 2],
|
[ BerryType.SALAC, 2 ],
|
||||||
[BerryType.SITRUS, 2],
|
[ BerryType.SITRUS, 2 ],
|
||||||
[BerryType.STARF, 3]
|
[ BerryType.STARF, 3 ]
|
||||||
];
|
];
|
||||||
|
|
||||||
let pool: any[];
|
let pool: any[];
|
||||||
@ -502,7 +502,7 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem
|
|||||||
const newItemType = pool[randIndex];
|
const newItemType = pool[randIndex];
|
||||||
let newMod: PokemonHeldItemModifierType;
|
let newMod: PokemonHeldItemModifierType;
|
||||||
if (tier === "Berries") {
|
if (tier === "Berries") {
|
||||||
newMod = generateModifierType(scene, modifierTypes.BERRY, [newItemType[0]]) as PokemonHeldItemModifierType;
|
newMod = generateModifierType(scene, modifierTypes.BERRY, [ newItemType[0] ]) as PokemonHeldItemModifierType;
|
||||||
} else {
|
} else {
|
||||||
newMod = generateModifierType(scene, newItemType[0]) as PokemonHeldItemModifierType;
|
newMod = generateModifierType(scene, newItemType[0]) as PokemonHeldItemModifierType;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
scene.getEnemyParty().forEach(enemyPokemon => {
|
scene.getEnemyParty().forEach(enemyPokemon => {
|
||||||
scene.field.remove(enemyPokemon, true);
|
scene.field.remove(enemyPokemon, true);
|
||||||
});
|
});
|
||||||
scene.currentBattle.enemyParty = [oricorio];
|
scene.currentBattle.enemyParty = [ oricorio ];
|
||||||
scene.field.add(oricorio);
|
scene.field.add(oricorio);
|
||||||
// Spawns on offscreen field
|
// Spawns on offscreen field
|
||||||
oricorio.x -= 300;
|
oricorio.x -= 300;
|
||||||
@ -153,14 +153,14 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
dataSource: oricorioData,
|
dataSource: oricorioData,
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
// Gets +1 to all stats except SPD on battle start
|
// Gets +1 to all stats except SPD on battle start
|
||||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF], 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF ], 1));
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
encounter.misc = {
|
encounter.misc = {
|
||||||
oricorioData
|
oricorioData
|
||||||
};
|
};
|
||||||
@ -187,13 +187,13 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
encounter.startOfBattleEffects.push({
|
encounter.startOfBattleEffects.push({
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.PLAYER],
|
targets: [ BattlerIndex.PLAYER ],
|
||||||
move: new PokemonMove(Moves.REVELATION_DANCE),
|
move: new PokemonMove(Moves.REVELATION_DANCE),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
});
|
});
|
||||||
|
|
||||||
await hideOricorioPokemon(scene);
|
await hideOricorioPokemon(scene);
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.BATON], fillRemaining: true });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.BATON ], fillRemaining: true });
|
||||||
await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]);
|
await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]);
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
|
@ -164,7 +164,7 @@ export const DarkDealEncounter: MysteryEncounter =
|
|||||||
// Starter egg tier, 35/50/10/5 %odds for tiers 6/7/8/9+
|
// Starter egg tier, 35/50/10/5 %odds for tiers 6/7/8/9+
|
||||||
const roll = randSeedInt(100);
|
const roll = randSeedInt(100);
|
||||||
const starterTier: number | [number, number] =
|
const starterTier: number | [number, number] =
|
||||||
roll >= 65 ? 6 : roll >= 15 ? 7 : roll >= 5 ? 8 : [9, 10];
|
roll >= 65 ? 6 : roll >= 15 ? 7 : roll >= 5 ? 8 : [ 9, 10 ];
|
||||||
const bossSpecies = getPokemonSpecies(getRandomSpeciesByStarterTier(starterTier, excludedBosses, bossTypes));
|
const bossSpecies = getPokemonSpecies(getRandomSpeciesByStarterTier(starterTier, excludedBosses, bossTypes));
|
||||||
const pokemonConfig: EnemyPokemonConfig = {
|
const pokemonConfig: EnemyPokemonConfig = {
|
||||||
species: bossSpecies,
|
species: bossSpecies,
|
||||||
@ -179,7 +179,7 @@ export const DarkDealEncounter: MysteryEncounter =
|
|||||||
pokemonConfig.formIndex = 0;
|
pokemonConfig.formIndex = 0;
|
||||||
}
|
}
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
pokemonConfigs: [pokemonConfig],
|
pokemonConfigs: [ pokemonConfig ],
|
||||||
};
|
};
|
||||||
return initBattleWithEnemyConfig(scene, config);
|
return initBattleWithEnemyConfig(scene, config);
|
||||||
})
|
})
|
||||||
|
@ -22,7 +22,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
const namespace = "mysteryEncounters/delibirdy";
|
const namespace = "mysteryEncounters/delibirdy";
|
||||||
|
|
||||||
/** Berries only */
|
/** Berries only */
|
||||||
const OPTION_2_ALLOWED_MODIFIERS = ["BerryModifier", "PokemonInstantReviveModifier"];
|
const OPTION_2_ALLOWED_MODIFIERS = [ "BerryModifier", "PokemonInstantReviveModifier" ];
|
||||||
|
|
||||||
/** Disallowed items are berries, Reviver Seeds, and Vitamins (form change items and fusion items are not PokemonHeldItemModifiers) */
|
/** Disallowed items are berries, Reviver Seeds, and Vitamins (form change items and fusion items are not PokemonHeldItemModifiers) */
|
||||||
const OPTION_3_DISALLOWED_MODIFIERS = [
|
const OPTION_3_DISALLOWED_MODIFIERS = [
|
||||||
|
@ -87,9 +87,9 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
if (encounter.misc.correctMove) {
|
if (encounter.misc.correctMove) {
|
||||||
const modifiers = [
|
const modifiers = [
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ATK])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.ATK ])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.DEF])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.DEF ])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPD ])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||||
];
|
];
|
||||||
@ -133,9 +133,9 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
if (encounter.misc.correctMove) {
|
if (encounter.misc.correctMove) {
|
||||||
const modifiers = [
|
const modifiers = [
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPATK])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPATK ])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPDEF])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPDEF ])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPD ])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||||
];
|
];
|
||||||
@ -179,8 +179,8 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
if (encounter.misc.correctMove) {
|
if (encounter.misc.correctMove) {
|
||||||
const modifiers = [
|
const modifiers = [
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ACC])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.ACC ])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPD ])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.GREAT_BALL)!,
|
generateModifierTypeOption(scene, modifierTypes.GREAT_BALL)!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.IV_SCANNER)!,
|
generateModifierTypeOption(scene, modifierTypes.IV_SCANNER)!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||||
@ -227,7 +227,7 @@ function pokemonAndMoveChosen(scene: BattleScene, pokemon: PlayerPokemon, move:
|
|||||||
text: `${namespace}:correct_exp`,
|
text: `${namespace}:correct_exp`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
setEncounterExp(scene, [pokemon.id], 100);
|
setEncounterExp(scene, [ pokemon.id ], 100);
|
||||||
}
|
}
|
||||||
encounter.misc = {
|
encounter.misc = {
|
||||||
correctMove: correctMove,
|
correctMove: correctMove,
|
||||||
|
@ -73,7 +73,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
doubleBattle: true,
|
doubleBattle: true,
|
||||||
disableSwitch: true
|
disableSwitch: true
|
||||||
};
|
};
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
|
|
||||||
// Load hidden Volcarona sprites
|
// Load hidden Volcarona sprites
|
||||||
encounter.spriteConfigs = [
|
encounter.spriteConfigs = [
|
||||||
@ -99,7 +99,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Load animations/sfx for Volcarona moves
|
// Load animations/sfx for Volcarona moves
|
||||||
loadCustomMovesForEncounter(scene, [Moves.FIRE_SPIN, Moves.QUIVER_DANCE]);
|
loadCustomMovesForEncounter(scene, [ Moves.FIRE_SPIN, Moves.QUIVER_DANCE ]);
|
||||||
|
|
||||||
scene.arena.trySetWeather(WeatherType.SUNNY, true);
|
scene.arena.trySetWeather(WeatherType.SUNNY, true);
|
||||||
|
|
||||||
@ -143,25 +143,25 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
encounter.startOfBattleEffects.push(
|
encounter.startOfBattleEffects.push(
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.PLAYER],
|
targets: [ BattlerIndex.PLAYER ],
|
||||||
move: new PokemonMove(Moves.FIRE_SPIN),
|
move: new PokemonMove(Moves.FIRE_SPIN),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
||||||
targets: [BattlerIndex.PLAYER_2],
|
targets: [ BattlerIndex.PLAYER_2 ],
|
||||||
move: new PokemonMove(Moves.FIRE_SPIN),
|
move: new PokemonMove(Moves.FIRE_SPIN),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.ENEMY],
|
targets: [ BattlerIndex.ENEMY ],
|
||||||
move: new PokemonMove(Moves.QUIVER_DANCE),
|
move: new PokemonMove(Moves.QUIVER_DANCE),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
||||||
targets: [BattlerIndex.ENEMY_2],
|
targets: [ BattlerIndex.ENEMY_2 ],
|
||||||
move: new PokemonMove(Moves.QUIVER_DANCE),
|
move: new PokemonMove(Moves.QUIVER_DANCE),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
});
|
});
|
||||||
@ -237,7 +237,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
const primary = encounter.options[2].primaryPokemon!;
|
const primary = encounter.options[2].primaryPokemon!;
|
||||||
const secondary = encounter.options[2].secondaryPokemon![0];
|
const secondary = encounter.options[2].secondaryPokemon![0];
|
||||||
|
|
||||||
setEncounterExp(scene, [primary.id, secondary.id], getPokemonSpecies(Species.VOLCARONA).baseExp * 2);
|
setEncounterExp(scene, [ primary.id, secondary.id ], getPokemonSpecies(Species.VOLCARONA).baseExp * 2);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
@ -248,7 +248,7 @@ function giveLeadPokemonCharcoal(scene: BattleScene) {
|
|||||||
// Give first party pokemon Charcoal for free at end of battle
|
// Give first party pokemon Charcoal for free at end of battle
|
||||||
const leadPokemon = scene.getParty()?.[0];
|
const leadPokemon = scene.getParty()?.[0];
|
||||||
if (leadPokemon) {
|
if (leadPokemon) {
|
||||||
const charcoal = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FIRE]) as AttackTypeBoosterModifierType;
|
const charcoal = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.FIRE ]) as AttackTypeBoosterModifierType;
|
||||||
applyModifierTypeToPlayerPokemon(scene, leadPokemon, charcoal);
|
applyModifierTypeToPlayerPokemon(scene, leadPokemon, charcoal);
|
||||||
scene.currentBattle.mysteryEncounter!.setDialogueToken("leadPokemon", leadPokemon.getNameToRender());
|
scene.currentBattle.mysteryEncounter!.setDialogueToken("leadPokemon", leadPokemon.getNameToRender());
|
||||||
queueEncounterMessage(scene, `${namespace}:found_charcoal`);
|
queueEncounterMessage(scene, `${namespace}:found_charcoal`);
|
||||||
|
@ -65,16 +65,16 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
species: bossSpecies,
|
species: bossSpecies,
|
||||||
dataSource: new PokemonData(bossPokemon),
|
dataSource: new PokemonData(bossPokemon),
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`);
|
||||||
// Randomly boost 1 stat 2 stages
|
// Randomly boost 1 stat 2 stages
|
||||||
// Cannot boost Spd, Acc, or Evasion
|
// Cannot boost Spd, Acc, or Evasion
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [randSeedInt(4, 1)], 2));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randSeedInt(4, 1) ], 2));
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
|
|
||||||
// Calculate item
|
// Calculate item
|
||||||
// Waves 10-40 GREAT, 60-120 ULTRA, 120-160 ROGUE, 160-180 MASTER
|
// Waves 10-40 GREAT, 60-120 ULTRA, 120-160 ROGUE, 160-180 MASTER
|
||||||
@ -90,7 +90,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
let item: ModifierTypeOption | null = null;
|
let item: ModifierTypeOption | null = null;
|
||||||
// TMs and Candy Jar excluded from possible rewards as they're too swingy in value for a singular item reward
|
// TMs and Candy Jar excluded from possible rewards as they're too swingy in value for a singular item reward
|
||||||
while (!item || item.type.id.includes("TM_") || item.type.id === "CANDY_JAR") {
|
while (!item || item.type.id.includes("TM_") || item.type.id === "CANDY_JAR") {
|
||||||
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0];
|
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0];
|
||||||
}
|
}
|
||||||
encounter.setDialogueToken("itemName", item.type.name);
|
encounter.setDialogueToken("itemName", item.type.name);
|
||||||
encounter.misc = item;
|
encounter.misc = item;
|
||||||
@ -137,7 +137,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
// Pick battle
|
// Pick battle
|
||||||
// Pokemon will randomly boost 1 stat by 2 stages
|
// Pokemon will randomly boost 1 stat by 2 stages
|
||||||
const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
|
const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false });
|
||||||
await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
|
await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -159,7 +159,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
// Pick steal
|
// Pick steal
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
|
const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false });
|
||||||
|
|
||||||
// Use primaryPokemon to execute the thievery
|
// Use primaryPokemon to execute the thievery
|
||||||
const primaryPokemon = encounter.options[1].primaryPokemon!;
|
const primaryPokemon = encounter.options[1].primaryPokemon!;
|
||||||
|
@ -197,7 +197,7 @@ async function summonPlayerPokemon(scene: BattleScene) {
|
|||||||
const enemySpecies = getPokemonSpecies(Species.WOBBUFFET);
|
const enemySpecies = getPokemonSpecies(Species.WOBBUFFET);
|
||||||
scene.currentBattle.enemyParty = [];
|
scene.currentBattle.enemyParty = [];
|
||||||
const wobbuffet = scene.addEnemyPokemon(enemySpecies, encounter.misc.playerPokemon.level, TrainerSlot.NONE, false);
|
const wobbuffet = scene.addEnemyPokemon(enemySpecies, encounter.misc.playerPokemon.level, TrainerSlot.NONE, false);
|
||||||
wobbuffet.ivs = [0, 0, 0, 0, 0, 0];
|
wobbuffet.ivs = [ 0, 0, 0, 0, 0, 0 ];
|
||||||
wobbuffet.setNature(Nature.MILD);
|
wobbuffet.setNature(Nature.MILD);
|
||||||
wobbuffet.setAlpha(0);
|
wobbuffet.setAlpha(0);
|
||||||
wobbuffet.setVisible(false);
|
wobbuffet.setVisible(false);
|
||||||
@ -256,15 +256,15 @@ function handleNextTurn(scene: BattleScene) {
|
|||||||
let isHealPhase = false;
|
let isHealPhase = false;
|
||||||
if (healthRatio < 0.03) {
|
if (healthRatio < 0.03) {
|
||||||
// Grand prize
|
// Grand prize
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MULTI_LENS], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MULTI_LENS ], fillRemaining: false });
|
||||||
resultMessageKey = `${namespace}:best_result`;
|
resultMessageKey = `${namespace}:best_result`;
|
||||||
} else if (healthRatio < 0.15) {
|
} else if (healthRatio < 0.15) {
|
||||||
// 2nd prize
|
// 2nd prize
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SCOPE_LENS], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SCOPE_LENS ], fillRemaining: false });
|
||||||
resultMessageKey = `${namespace}:great_result`;
|
resultMessageKey = `${namespace}:great_result`;
|
||||||
} else if (healthRatio < 0.33) {
|
} else if (healthRatio < 0.33) {
|
||||||
// 3rd prize
|
// 3rd prize
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.WIDE_LENS], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.WIDE_LENS ], fillRemaining: false });
|
||||||
resultMessageKey = `${namespace}:good_result`;
|
resultMessageKey = `${namespace}:good_result`;
|
||||||
} else {
|
} else {
|
||||||
// No prize
|
// No prize
|
||||||
@ -411,7 +411,7 @@ function hideShowmanIntroSprite(scene: BattleScene) {
|
|||||||
|
|
||||||
// Slide the Wobbuffet and Game over slightly
|
// Slide the Wobbuffet and Game over slightly
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: [wobbuffet, carnivalGame],
|
targets: [ wobbuffet, carnivalGame ],
|
||||||
x: "+=16",
|
x: "+=16",
|
||||||
ease: "Sine.easeInOut",
|
ease: "Sine.easeInOut",
|
||||||
duration: 750
|
duration: 750
|
||||||
|
@ -35,15 +35,15 @@ const WONDER_TRADE_SHINY_CHANCE = 512;
|
|||||||
const MAX_WONDER_TRADE_SHINY_CHANCE = 4096;
|
const MAX_WONDER_TRADE_SHINY_CHANCE = 4096;
|
||||||
|
|
||||||
const LEGENDARY_TRADE_POOLS = {
|
const LEGENDARY_TRADE_POOLS = {
|
||||||
1: [Species.RATTATA, Species.PIDGEY, Species.WEEDLE],
|
1: [ Species.RATTATA, Species.PIDGEY, Species.WEEDLE ],
|
||||||
2: [Species.SENTRET, Species.HOOTHOOT, Species.LEDYBA],
|
2: [ Species.SENTRET, Species.HOOTHOOT, Species.LEDYBA ],
|
||||||
3: [Species.POOCHYENA, Species.ZIGZAGOON, Species.TAILLOW],
|
3: [ Species.POOCHYENA, Species.ZIGZAGOON, Species.TAILLOW ],
|
||||||
4: [Species.BIDOOF, Species.STARLY, Species.KRICKETOT],
|
4: [ Species.BIDOOF, Species.STARLY, Species.KRICKETOT ],
|
||||||
5: [Species.PATRAT, Species.PURRLOIN, Species.PIDOVE],
|
5: [ Species.PATRAT, Species.PURRLOIN, Species.PIDOVE ],
|
||||||
6: [Species.BUNNELBY, Species.LITLEO, Species.SCATTERBUG],
|
6: [ Species.BUNNELBY, Species.LITLEO, Species.SCATTERBUG ],
|
||||||
7: [Species.PIKIPEK, Species.YUNGOOS, Species.ROCKRUFF],
|
7: [ Species.PIKIPEK, Species.YUNGOOS, Species.ROCKRUFF ],
|
||||||
8: [Species.SKWOVET, Species.WOOLOO, Species.ROOKIDEE],
|
8: [ Species.SKWOVET, Species.WOOLOO, Species.ROOKIDEE ],
|
||||||
9: [Species.LECHONK, Species.FIDOUGH, Species.TAROUNTULA]
|
9: [ Species.LECHONK, Species.FIDOUGH, Species.TAROUNTULA ]
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Exclude Paradox mons as they aren't considered legendary/mythical */
|
/** Exclude Paradox mons as they aren't considered legendary/mythical */
|
||||||
@ -387,11 +387,11 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
let item: ModifierTypeOption | null = null;
|
let item: ModifierTypeOption | null = null;
|
||||||
// TMs excluded from possible rewards
|
// TMs excluded from possible rewards
|
||||||
while (!item || item.type.id.includes("TM_")) {
|
while (!item || item.type.id.includes("TM_")) {
|
||||||
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0];
|
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
encounter.setDialogueToken("itemName", item.type.name);
|
encounter.setDialogueToken("itemName", item.type.name);
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false });
|
||||||
|
|
||||||
// Remove the chosen modifier if its stacks go to 0
|
// Remove the chosen modifier if its stacks go to 0
|
||||||
modifier.stackCount -= 1;
|
modifier.stackCount -= 1;
|
||||||
@ -650,7 +650,7 @@ function doPokemonTradeSequence(scene: BattleScene, tradedPokemon: PlayerPokemon
|
|||||||
// addPokeballOpenParticles(scene, tradedPokemon.x, tradedPokemon.y, tradedPokemon.pokeball);
|
// addPokeballOpenParticles(scene, tradedPokemon.x, tradedPokemon.y, tradedPokemon.pokeball);
|
||||||
|
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: [tradedPokemonTintSprite, tradedPokemonSprite],
|
targets: [ tradedPokemonTintSprite, tradedPokemonSprite ],
|
||||||
duration: 500,
|
duration: 500,
|
||||||
ease: "Sine.easeIn",
|
ease: "Sine.easeIn",
|
||||||
scale: 0.25,
|
scale: 0.25,
|
||||||
@ -726,7 +726,7 @@ function doPokemonTradeFlyBySequence(scene: BattleScene, tradedPokemonSprite: Ph
|
|||||||
duration: FADE_DELAY,
|
duration: FADE_DELAY,
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: [receivedPokemonSprite, tradedPokemonSprite],
|
targets: [ receivedPokemonSprite, tradedPokemonSprite ],
|
||||||
y: tradeBaseBg.displayWidth / 2 - 100,
|
y: tradeBaseBg.displayWidth / 2 - 100,
|
||||||
ease: "Cubic.easeInOut",
|
ease: "Cubic.easeInOut",
|
||||||
duration: BASE_ANIM_DURATION * 3,
|
duration: BASE_ANIM_DURATION * 3,
|
||||||
|
@ -10,7 +10,7 @@ import { applyDamageToPokemon } from "#app/data/mystery-encounters/utils/encount
|
|||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
import {PokemonMove} from "#app/field/pokemon";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
|
|
||||||
const OPTION_1_REQUIRED_MOVE = Moves.SURF;
|
const OPTION_1_REQUIRED_MOVE = Moves.SURF;
|
||||||
const OPTION_2_REQUIRED_MOVE = Moves.FLY;
|
const OPTION_2_REQUIRED_MOVE = Moves.FLY;
|
||||||
|
@ -143,7 +143,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
// Spawn standard trainer battle with memory mushroom reward
|
// Spawn standard trainer battle with memory mushroom reward
|
||||||
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
||||||
|
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.TM_COMMON, modifierTypes.TM_GREAT, modifierTypes.MEMORY_MUSHROOM], fillRemaining: true });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.TM_COMMON, modifierTypes.TM_GREAT, modifierTypes.MEMORY_MUSHROOM ], fillRemaining: true });
|
||||||
|
|
||||||
// Seed offsets to remove possibility of different trainers having exact same teams
|
// Seed offsets to remove possibility of different trainers having exact same teams
|
||||||
let ret;
|
let ret;
|
||||||
@ -168,7 +168,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
// Spawn hard fight
|
// Spawn hard fight
|
||||||
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
|
||||||
|
|
||||||
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], fillRemaining: true });
|
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], fillRemaining: true });
|
||||||
|
|
||||||
// Seed offsets to remove possibility of different trainers having exact same teams
|
// Seed offsets to remove possibility of different trainers having exact same teams
|
||||||
let ret;
|
let ret;
|
||||||
@ -196,7 +196,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
// To avoid player level snowballing from picking this option
|
// To avoid player level snowballing from picking this option
|
||||||
encounter.expMultiplier = 0.9;
|
encounter.expMultiplier = 0.9;
|
||||||
|
|
||||||
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true });
|
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT ], fillRemaining: true });
|
||||||
|
|
||||||
// Seed offsets to remove possibility of different trainers having exact same teams
|
// Seed offsets to remove possibility of different trainers having exact same teams
|
||||||
let ret;
|
let ret;
|
||||||
|
@ -76,12 +76,12 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
species: getPokemonSpecies(Species.GIMMIGHOUL),
|
species: getPokemonSpecies(Species.GIMMIGHOUL),
|
||||||
formIndex: 0,
|
formIndex: 0,
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
moveSet: [Moves.NASTY_PLOT, Moves.SHADOW_BALL, Moves.POWER_GEM, Moves.THIEF]
|
moveSet: [ Moves.NASTY_PLOT, Moves.SHADOW_BALL, Moves.POWER_GEM, Moves.THIEF ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
|
|
||||||
encounter.setDialogueToken("gimmighoulName", getPokemonSpecies(Species.GIMMIGHOUL).getName());
|
encounter.setDialogueToken("gimmighoulName", getPokemonSpecies(Species.GIMMIGHOUL).getName());
|
||||||
encounter.setDialogueToken("trapPercent", TRAP_PERCENT.toString());
|
encounter.setDialogueToken("trapPercent", TRAP_PERCENT.toString());
|
||||||
@ -157,13 +157,13 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT) {
|
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT) {
|
||||||
// Choose between 2 ROGUE tier items (10%)
|
// Choose between 2 ROGUE tier items (10%)
|
||||||
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE] });
|
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE ]});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to rewards
|
||||||
queueEncounterMessage(scene, `${namespace}:option.1.great`);
|
queueEncounterMessage(scene, `${namespace}:option.1.great`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT - MASTER_REWARDS_PERCENT) {
|
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT - MASTER_REWARDS_PERCENT) {
|
||||||
// Choose 1 MASTER tier item (5%)
|
// Choose 1 MASTER tier item (5%)
|
||||||
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.MASTER] });
|
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.MASTER ]});
|
||||||
// Display result message then proceed to rewards
|
// Display result message then proceed to rewards
|
||||||
queueEncounterMessage(scene, `${namespace}:option.1.amazing`);
|
queueEncounterMessage(scene, `${namespace}:option.1.amazing`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
@ -94,7 +94,7 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
// Calculation from Pokemon.calculateStats
|
// Calculation from Pokemon.calculateStats
|
||||||
const baselineValue = Math.floor(((2 * 90 + 16) * pokemon.level) * 0.01) + 5;
|
const baselineValue = Math.floor(((2 * 90 + 16) * pokemon.level) * 0.01) + 5;
|
||||||
const percentDiff = (pokemon.getStat(Stat.SPD) - baselineValue) / baselineValue;
|
const percentDiff = (pokemon.getStat(Stat.SPD) - baselineValue) / baselineValue;
|
||||||
const moneyMultiplier = Math.min(Math.max(2.5 * (1+ percentDiff), 1), 4);
|
const moneyMultiplier = Math.min(Math.max(2.5 * (1 + percentDiff), 1), 4);
|
||||||
|
|
||||||
encounter.misc = {
|
encounter.misc = {
|
||||||
moneyMultiplier
|
moneyMultiplier
|
||||||
|
@ -23,7 +23,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/safariZone";
|
const namespace = "mysteryEncounters/safariZone";
|
||||||
|
|
||||||
const TRAINER_THROW_ANIMATION_TIMES = [512, 184, 768];
|
const TRAINER_THROW_ANIMATION_TIMES = [ 512, 184, 768 ];
|
||||||
|
|
||||||
const SAFARI_MONEY_MULTIPLIER = 2;
|
const SAFARI_MONEY_MULTIPLIER = 2;
|
||||||
|
|
||||||
@ -260,7 +260,7 @@ async function summonSafariPokemon(scene: BattleScene) {
|
|||||||
let enemySpecies;
|
let enemySpecies;
|
||||||
let pokemon;
|
let pokemon;
|
||||||
scene.executeWithSeedOffset(() => {
|
scene.executeWithSeedOffset(() => {
|
||||||
enemySpecies = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5], undefined, undefined, false, false, false));
|
enemySpecies = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false));
|
||||||
const level = scene.currentBattle.getLevelForWave();
|
const level = scene.currentBattle.getLevelForWave();
|
||||||
enemySpecies = getPokemonSpecies(enemySpecies.getWildSpeciesForLevel(level, true, false, scene.gameMode));
|
enemySpecies = getPokemonSpecies(enemySpecies.getWildSpeciesForLevel(level, true, false, scene.gameMode));
|
||||||
pokemon = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, false);
|
pokemon = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, false);
|
||||||
|
@ -33,7 +33,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withSceneRequirement(new MoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER)) // Must have the money for at least the cheap deal
|
.withSceneRequirement(new MoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER)) // Must have the money for at least the cheap deal
|
||||||
.withPrimaryPokemonHealthRatioRequirement([0.51, 1]) // At least 1 Pokemon must have above half HP
|
.withPrimaryPokemonHealthRatioRequirement([ 0.51, 1 ]) // At least 1 Pokemon must have above half HP
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: Species.KROOKODILE.toString(),
|
spriteKey: Species.KROOKODILE.toString(),
|
||||||
@ -140,7 +140,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
chosenPokemon.nature = newNature;
|
chosenPokemon.nature = newNature;
|
||||||
encounter.setDialogueToken("newNature", getNatureName(newNature));
|
encounter.setDialogueToken("newNature", getNatureName(newNature));
|
||||||
queueEncounterMessage(scene, `${namespace}:cheap_side_effects`);
|
queueEncounterMessage(scene, `${namespace}:cheap_side_effects`);
|
||||||
setEncounterExp(scene, [chosenPokemon.id], 100);
|
setEncounterExp(scene, [ chosenPokemon.id ], 100);
|
||||||
chosenPokemon.updateInfo();
|
chosenPokemon.updateInfo();
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
@ -201,7 +201,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
const chosenPokemon = encounter.misc.chosenPokemon;
|
const chosenPokemon = encounter.misc.chosenPokemon;
|
||||||
|
|
||||||
queueEncounterMessage(scene, `${namespace}:no_bad_effects`);
|
queueEncounterMessage(scene, `${namespace}:no_bad_effects`);
|
||||||
setEncounterExp(scene, [chosenPokemon.id], 100);
|
setEncounterExp(scene, [ chosenPokemon.id ], 100);
|
||||||
|
|
||||||
chosenPokemon.updateInfo();
|
chosenPokemon.updateInfo();
|
||||||
})
|
})
|
||||||
|
@ -60,15 +60,15 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
const pokemonConfig: EnemyPokemonConfig = {
|
const pokemonConfig: EnemyPokemonConfig = {
|
||||||
species: bossSpecies,
|
species: bossSpecies,
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
status: [StatusEffect.SLEEP, 5], // Extra turns on timer for Snorlax's start of fight moves
|
status: [ StatusEffect.SLEEP, 5 ], // Extra turns on timer for Snorlax's start of fight moves
|
||||||
moveSet: [Moves.REST, Moves.SLEEP_TALK, Moves.CRUNCH, Moves.GIGA_IMPACT],
|
moveSet: [ Moves.REST, Moves.SLEEP_TALK, Moves.CRUNCH, Moves.GIGA_IMPACT ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2
|
stackCount: 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2
|
stackCount: 2
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -77,12 +77,12 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
};
|
};
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
levelAdditiveModifier: 0.5,
|
levelAdditiveModifier: 0.5,
|
||||||
pokemonConfigs: [pokemonConfig],
|
pokemonConfigs: [ pokemonConfig ],
|
||||||
};
|
};
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
|
|
||||||
// Load animations/sfx for Snorlax fight start moves
|
// Load animations/sfx for Snorlax fight start moves
|
||||||
loadCustomMovesForEncounter(scene, [Moves.SNORE]);
|
loadCustomMovesForEncounter(scene, [ Moves.SNORE ]);
|
||||||
|
|
||||||
encounter.setDialogueToken("snorlaxName", getPokemonSpecies(Species.SNORLAX).getName());
|
encounter.setDialogueToken("snorlaxName", getPokemonSpecies(Species.SNORLAX).getName());
|
||||||
|
|
||||||
@ -104,17 +104,17 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Pick battle
|
// Pick battle
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: true});
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.LEFTOVERS ], fillRemaining: true });
|
||||||
encounter.startOfBattleEffects.push(
|
encounter.startOfBattleEffects.push(
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.PLAYER],
|
targets: [ BattlerIndex.PLAYER ],
|
||||||
move: new PokemonMove(Moves.SNORE),
|
move: new PokemonMove(Moves.SNORE),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.PLAYER],
|
targets: [ BattlerIndex.PLAYER ],
|
||||||
move: new PokemonMove(Moves.SNORE),
|
move: new PokemonMove(Moves.SNORE),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
});
|
});
|
||||||
@ -156,7 +156,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Steal the Snorlax's Leftovers
|
// Steal the Snorlax's Leftovers
|
||||||
const instance = scene.currentBattle.mysteryEncounter!;
|
const instance = scene.currentBattle.mysteryEncounter!;
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.LEFTOVERS ], fillRemaining: false });
|
||||||
// Snorlax exp to Pokemon that did the stealing
|
// Snorlax exp to Pokemon that did the stealing
|
||||||
setEncounterExp(scene, instance.primaryPokemon!.id, getPokemonSpecies(Species.SNORLAX).baseExp);
|
setEncounterExp(scene, instance.primaryPokemon!.id, getPokemonSpecies(Species.SNORLAX).baseExp);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
@ -26,8 +26,8 @@ import { getEncounterPokemonLevelForWave, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIF
|
|||||||
const namespace = "mysteryEncounters/teleportingHijinks";
|
const namespace = "mysteryEncounters/teleportingHijinks";
|
||||||
|
|
||||||
const MONEY_COST_MULTIPLIER = 1.75;
|
const MONEY_COST_MULTIPLIER = 1.75;
|
||||||
const BIOME_CANDIDATES = [Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND, Biome.WASTELAND, Biome.DOJO];
|
const BIOME_CANDIDATES = [ Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND, Biome.WASTELAND, Biome.DOJO ];
|
||||||
const MACHINE_INTERFACING_TYPES = [Type.ELECTRIC, Type.STEEL];
|
const MACHINE_INTERFACING_TYPES = [ Type.ELECTRIC, Type.STEEL ];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Teleporting Hijinks encounter.
|
* Teleporting Hijinks encounter.
|
||||||
@ -38,7 +38,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TELEPORTING_HIJINKS)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TELEPORTING_HIJINKS)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withSceneRequirement(new WaveModulusRequirement([1, 2, 3], 10)) // Must be in first 3 waves after boss wave
|
.withSceneRequirement(new WaveModulusRequirement([ 1, 2, 3 ], 10)) // Must be in first 3 waves after boss wave
|
||||||
.withSceneRequirement(new MoneyRequirement(0, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost
|
.withSceneRequirement(new MoneyRequirement(0, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
@ -145,9 +145,9 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
|
|||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
|
|
||||||
const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.STEEL])!;
|
const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.STEEL ])!;
|
||||||
const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.ELECTRIC])!;
|
const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.ELECTRIC ])!;
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [magnet, metalCoat], fillRemaining: true });
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ magnet, metalCoat ], fillRemaining: true });
|
||||||
transitionMysteryEncounterIntroVisuals(scene, true, true);
|
transitionMysteryEncounterIntroVisuals(scene, true, true);
|
||||||
await initBattleWithEnemyConfig(scene, config);
|
await initBattleWithEnemyConfig(scene, config);
|
||||||
}
|
}
|
||||||
@ -163,7 +163,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
|
|||||||
|
|
||||||
// Show dialogue and transition biome
|
// Show dialogue and transition biome
|
||||||
await showEncounterText(scene, `${namespace}:transport`);
|
await showEncounterText(scene, `${namespace}:transport`);
|
||||||
await Promise.all([animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene)]);
|
await Promise.all([ animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene) ]);
|
||||||
scene.playBgm();
|
scene.playBgm();
|
||||||
await showEncounterText(scene, `${namespace}:attacked`);
|
await showEncounterText(scene, `${namespace}:attacked`);
|
||||||
|
|
||||||
@ -175,8 +175,8 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
|
|||||||
|
|
||||||
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
|
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
|
||||||
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
|
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
|
||||||
[Stat.DEF, Stat.SPDEF, Stat.SPD] :
|
[ Stat.DEF, Stat.SPDEF, Stat.SPD ] :
|
||||||
[Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD];
|
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
|
||||||
|
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
pokemonConfigs: [{
|
pokemonConfigs: [{
|
||||||
@ -184,7 +184,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
|
|||||||
species: bossSpecies,
|
species: bossSpecies,
|
||||||
dataSource: new PokemonData(bossPokemon),
|
dataSource: new PokemonData(bossPokemon),
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}:boss_enraged`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:boss_enraged`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
||||||
@ -198,7 +198,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
|
|||||||
async function animateBiomeChange(scene: BattleScene, nextBiome: Biome) {
|
async function animateBiomeChange(scene: BattleScene, nextBiome: Biome) {
|
||||||
return new Promise<void>(resolve => {
|
return new Promise<void>(resolve => {
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: [scene.arenaEnemy, scene.lastEnemyTrainer],
|
targets: [ scene.arenaEnemy, scene.lastEnemyTrainer ],
|
||||||
x: "+=300",
|
x: "+=300",
|
||||||
duration: 2000,
|
duration: 2000,
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
@ -214,7 +214,7 @@ async function animateBiomeChange(scene: BattleScene, nextBiome: Biome) {
|
|||||||
scene.arenaPlayerTransition.setVisible(true);
|
scene.arenaPlayerTransition.setVisible(true);
|
||||||
|
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: [scene.arenaPlayer, scene.arenaBgTransition, scene.arenaPlayerTransition],
|
targets: [ scene.arenaPlayer, scene.arenaBgTransition, scene.arenaPlayerTransition ],
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
ease: "Sine.easeInOut",
|
ease: "Sine.easeInOut",
|
||||||
alpha: (target: any) => target === scene.arenaPlayer ? 0 : 1,
|
alpha: (target: any) => target === scene.arenaPlayer ? 0 : 1,
|
||||||
|
@ -48,29 +48,29 @@ class BreederSpeciesEvolution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const POOL_1_POKEMON: (Species | BreederSpeciesEvolution)[][] = [
|
const POOL_1_POKEMON: (Species | BreederSpeciesEvolution)[][] = [
|
||||||
[Species.MUNCHLAX, new BreederSpeciesEvolution(Species.SNORLAX, SECOND_STAGE_EVOLUTION_WAVE)],
|
[ Species.MUNCHLAX, new BreederSpeciesEvolution(Species.SNORLAX, SECOND_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.HAPPINY, new BreederSpeciesEvolution(Species.CHANSEY, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.BLISSEY, FINAL_STAGE_EVOLUTION_WAVE)],
|
[ Species.HAPPINY, new BreederSpeciesEvolution(Species.CHANSEY, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.BLISSEY, FINAL_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.MAGBY, new BreederSpeciesEvolution(Species.MAGMAR, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MAGMORTAR, FINAL_STAGE_EVOLUTION_WAVE)],
|
[ Species.MAGBY, new BreederSpeciesEvolution(Species.MAGMAR, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MAGMORTAR, FINAL_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.ELEKID, new BreederSpeciesEvolution(Species.ELECTABUZZ, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ELECTIVIRE, FINAL_STAGE_EVOLUTION_WAVE)],
|
[ Species.ELEKID, new BreederSpeciesEvolution(Species.ELECTABUZZ, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ELECTIVIRE, FINAL_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.RIOLU, new BreederSpeciesEvolution(Species.LUCARIO, SECOND_STAGE_EVOLUTION_WAVE)],
|
[ Species.RIOLU, new BreederSpeciesEvolution(Species.LUCARIO, SECOND_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.BUDEW, new BreederSpeciesEvolution(Species.ROSELIA, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ROSERADE, FINAL_STAGE_EVOLUTION_WAVE)],
|
[ Species.BUDEW, new BreederSpeciesEvolution(Species.ROSELIA, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ROSERADE, FINAL_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.TOXEL, new BreederSpeciesEvolution(Species.TOXTRICITY, SECOND_STAGE_EVOLUTION_WAVE)],
|
[ Species.TOXEL, new BreederSpeciesEvolution(Species.TOXTRICITY, SECOND_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.MIME_JR, new BreederSpeciesEvolution(Species.GALAR_MR_MIME, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MR_RIME, FINAL_STAGE_EVOLUTION_WAVE)]
|
[ Species.MIME_JR, new BreederSpeciesEvolution(Species.GALAR_MR_MIME, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MR_RIME, FINAL_STAGE_EVOLUTION_WAVE) ]
|
||||||
];
|
];
|
||||||
|
|
||||||
const POOL_2_POKEMON: (Species | BreederSpeciesEvolution)[][] = [
|
const POOL_2_POKEMON: (Species | BreederSpeciesEvolution)[][] = [
|
||||||
[Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.RAICHU, FINAL_STAGE_EVOLUTION_WAVE)],
|
[ Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.RAICHU, FINAL_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ALOLA_RAICHU, FINAL_STAGE_EVOLUTION_WAVE)],
|
[ Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ALOLA_RAICHU, FINAL_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.JYNX],
|
[ Species.JYNX ],
|
||||||
[Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONLEE, SECOND_STAGE_EVOLUTION_WAVE)],
|
[ Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONLEE, SECOND_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONCHAN, SECOND_STAGE_EVOLUTION_WAVE)],
|
[ Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONCHAN, SECOND_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONTOP, SECOND_STAGE_EVOLUTION_WAVE)],
|
[ Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONTOP, SECOND_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.IGGLYBUFF, new BreederSpeciesEvolution(Species.JIGGLYPUFF, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.WIGGLYTUFF, FINAL_STAGE_EVOLUTION_WAVE)],
|
[ Species.IGGLYBUFF, new BreederSpeciesEvolution(Species.JIGGLYPUFF, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.WIGGLYTUFF, FINAL_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.AZURILL, new BreederSpeciesEvolution(Species.MARILL, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.AZUMARILL, FINAL_STAGE_EVOLUTION_WAVE)],
|
[ Species.AZURILL, new BreederSpeciesEvolution(Species.MARILL, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.AZUMARILL, FINAL_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.WYNAUT, new BreederSpeciesEvolution(Species.WOBBUFFET, SECOND_STAGE_EVOLUTION_WAVE)],
|
[ Species.WYNAUT, new BreederSpeciesEvolution(Species.WOBBUFFET, SECOND_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.CHINGLING, new BreederSpeciesEvolution(Species.CHIMECHO, SECOND_STAGE_EVOLUTION_WAVE)],
|
[ Species.CHINGLING, new BreederSpeciesEvolution(Species.CHIMECHO, SECOND_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.BONSLY, new BreederSpeciesEvolution(Species.SUDOWOODO, SECOND_STAGE_EVOLUTION_WAVE)],
|
[ Species.BONSLY, new BreederSpeciesEvolution(Species.SUDOWOODO, SECOND_STAGE_EVOLUTION_WAVE) ],
|
||||||
[Species.MANTYKE, new BreederSpeciesEvolution(Species.MANTINE, SECOND_STAGE_EVOLUTION_WAVE)]
|
[ Species.MANTYKE, new BreederSpeciesEvolution(Species.MANTINE, SECOND_STAGE_EVOLUTION_WAVE) ]
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,7 +138,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
encounter.setDialogueToken("pokemon3Name", pokemon3.getNameToRender());
|
encounter.setDialogueToken("pokemon3Name", pokemon3.getNameToRender());
|
||||||
|
|
||||||
// Dialogue and egg calcs for Pokemon 1
|
// Dialogue and egg calcs for Pokemon 1
|
||||||
const [pokemon1CommonEggs, pokemon1RareEggs] = calculateEggRewardsForPokemon(pokemon1);
|
const [ pokemon1CommonEggs, pokemon1RareEggs ] = calculateEggRewardsForPokemon(pokemon1);
|
||||||
let pokemon1Tooltip = getEncounterText(scene, `${namespace}:option.1.tooltip_base`)!;
|
let pokemon1Tooltip = getEncounterText(scene, `${namespace}:option.1.tooltip_base`)!;
|
||||||
if (pokemon1RareEggs > 0) {
|
if (pokemon1RareEggs > 0) {
|
||||||
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon1RareEggs, rarity: i18next.t("egg:greatTier") });
|
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon1RareEggs, rarity: i18next.t("egg:greatTier") });
|
||||||
@ -153,7 +153,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
encounter.options[0].dialogue!.buttonTooltip = pokemon1Tooltip;
|
encounter.options[0].dialogue!.buttonTooltip = pokemon1Tooltip;
|
||||||
|
|
||||||
// Dialogue and egg calcs for Pokemon 2
|
// Dialogue and egg calcs for Pokemon 2
|
||||||
const [pokemon2CommonEggs, pokemon2RareEggs] = calculateEggRewardsForPokemon(pokemon2);
|
const [ pokemon2CommonEggs, pokemon2RareEggs ] = calculateEggRewardsForPokemon(pokemon2);
|
||||||
let pokemon2Tooltip = getEncounterText(scene, `${namespace}:option.2.tooltip_base`)!;
|
let pokemon2Tooltip = getEncounterText(scene, `${namespace}:option.2.tooltip_base`)!;
|
||||||
if (pokemon2RareEggs > 0) {
|
if (pokemon2RareEggs > 0) {
|
||||||
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon2RareEggs, rarity: i18next.t("egg:greatTier") });
|
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon2RareEggs, rarity: i18next.t("egg:greatTier") });
|
||||||
@ -168,7 +168,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
encounter.options[1].dialogue!.buttonTooltip = pokemon2Tooltip;
|
encounter.options[1].dialogue!.buttonTooltip = pokemon2Tooltip;
|
||||||
|
|
||||||
// Dialogue and egg calcs for Pokemon 3
|
// Dialogue and egg calcs for Pokemon 3
|
||||||
const [pokemon3CommonEggs, pokemon3RareEggs] = calculateEggRewardsForPokemon(pokemon3);
|
const [ pokemon3CommonEggs, pokemon3RareEggs ] = calculateEggRewardsForPokemon(pokemon3);
|
||||||
let pokemon3Tooltip = getEncounterText(scene, `${namespace}:option.3.tooltip_base`)!;
|
let pokemon3Tooltip = getEncounterText(scene, `${namespace}:option.3.tooltip_base`)!;
|
||||||
if (pokemon3RareEggs > 0) {
|
if (pokemon3RareEggs > 0) {
|
||||||
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon3RareEggs, rarity: i18next.t("egg:greatTier") });
|
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon3RareEggs, rarity: i18next.t("egg:greatTier") });
|
||||||
@ -381,11 +381,11 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
abilityIndex: 1, // Magic Guard
|
abilityIndex: 1, // Magic Guard
|
||||||
shiny: false,
|
shiny: false,
|
||||||
nature: Nature.ADAMANT,
|
nature: Nature.ADAMANT,
|
||||||
moveSet: [Moves.METEOR_MASH, Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH],
|
moveSet: [ Moves.METEOR_MASH, Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH ],
|
||||||
ivs: [31, 31, 31, 31, 31, 31],
|
ivs: [ 31, 31, 31, 31, 31, 31 ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.TERA_SHARD, [Type.STEEL]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.TERA_SHARD, [ Type.STEEL ]) as PokemonHeldItemModifierType,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -402,8 +402,8 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
shiny: true,
|
shiny: true,
|
||||||
variant: 1,
|
variant: 1,
|
||||||
nature: Nature.MODEST,
|
nature: Nature.MODEST,
|
||||||
moveSet: [Moves.MOONBLAST, Moves.MYSTICAL_FIRE, Moves.ICE_BEAM, Moves.THUNDERBOLT],
|
moveSet: [ Moves.MOONBLAST, Moves.MYSTICAL_FIRE, Moves.ICE_BEAM, Moves.THUNDERBOLT ],
|
||||||
ivs: [31, 31, 31, 31, 31, 31]
|
ivs: [ 31, 31, 31, 31, 31, 31 ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
nickname: i18next.t(`${namespace}:cleffa_3_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
|
nickname: i18next.t(`${namespace}:cleffa_3_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
|
||||||
@ -413,8 +413,8 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
shiny: true,
|
shiny: true,
|
||||||
variant: 2,
|
variant: 2,
|
||||||
nature: Nature.BOLD,
|
nature: Nature.BOLD,
|
||||||
moveSet: [Moves.TRI_ATTACK, Moves.STORED_POWER, Moves.TAKE_HEART, Moves.MOONLIGHT],
|
moveSet: [ Moves.TRI_ATTACK, Moves.STORED_POWER, Moves.TAKE_HEART, Moves.MOONLIGHT ],
|
||||||
ivs: [31, 31, 31, 31, 31, 31]
|
ivs: [ 31, 31, 31, 31, 31, 31 ]
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Second member from pool 1
|
// Second member from pool 1
|
||||||
@ -425,12 +425,12 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
baseConfig.pokemonConfigs!.push({
|
baseConfig.pokemonConfigs!.push({
|
||||||
species: getPokemonSpecies(pool1Species),
|
species: getPokemonSpecies(pool1Species),
|
||||||
isBoss: false,
|
isBoss: false,
|
||||||
ivs: [31, 31, 31, 31, 31, 31]
|
ivs: [ 31, 31, 31, 31, 31, 31 ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
species: getPokemonSpecies(pool2Species),
|
species: getPokemonSpecies(pool2Species),
|
||||||
isBoss: false,
|
isBoss: false,
|
||||||
ivs: [31, 31, 31, 31, 31, 31]
|
ivs: [ 31, 31, 31, 31, 31, 31 ]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,7 +468,7 @@ function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number]
|
|||||||
// 1 Common egg for every point leftover
|
// 1 Common egg for every point leftover
|
||||||
const numCommons = totalPoints % 6;
|
const numCommons = totalPoints % 6;
|
||||||
|
|
||||||
return [numCommons, numRares];
|
return [ numCommons, numRares ];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEggOptions(scene: BattleScene, commonEggs: number, rareEggs: number) {
|
function getEggOptions(scene: BattleScene, commonEggs: number, rareEggs: number) {
|
||||||
|
@ -59,12 +59,12 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
.withOnInit((scene: BattleScene) => {
|
.withOnInit((scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
let species = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5], undefined, undefined, false, false, false));
|
let species = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false));
|
||||||
let tries = 0;
|
let tries = 0;
|
||||||
|
|
||||||
// Reroll any species that don't have HAs
|
// Reroll any species that don't have HAs
|
||||||
while ((isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) && tries < 5) {
|
while ((isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) && tries < 5) {
|
||||||
species = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5], undefined, undefined, false, false, false));
|
species = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false));
|
||||||
tries++;
|
tries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,37 +81,37 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
bossSegments: 5,
|
bossSegments: 5,
|
||||||
mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ spriteScale: 1.25 }),
|
mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ spriteScale: 1.25 }),
|
||||||
nature: Nature.BOLD,
|
nature: Nature.BOLD,
|
||||||
moveSet: [Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER],
|
moveSet: [ Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.APICOT]) as PokemonHeldItemModifierType
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.APICOT ]) as PokemonHeldItemModifierType
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.GANLON ]) as PokemonHeldItemModifierType
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2
|
stackCount: 2
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}:option.2.stat_boost`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.2.stat_boost`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [Stat.DEF, Stat.SPDEF], 2));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.DEF, Stat.SPDEF ], 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
|
|
||||||
loadCustomMovesForEncounter(scene, [Moves.GASTRO_ACID, Moves.STEALTH_ROCK]);
|
loadCustomMovesForEncounter(scene, [ Moves.GASTRO_ACID, Moves.STEALTH_ROCK ]);
|
||||||
|
|
||||||
encounter.setDialogueToken("shuckleName", getPokemonSpecies(Species.SHUCKLE).getName());
|
encounter.setDialogueToken("shuckleName", getPokemonSpecies(Species.SHUCKLE).getName());
|
||||||
|
|
||||||
@ -184,17 +184,17 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Pick battle
|
// Pick battle
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SOUL_DEW], fillRemaining: true });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SOUL_DEW ], fillRemaining: true });
|
||||||
encounter.startOfBattleEffects.push(
|
encounter.startOfBattleEffects.push(
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.PLAYER],
|
targets: [ BattlerIndex.PLAYER ],
|
||||||
move: new PokemonMove(Moves.GASTRO_ACID),
|
move: new PokemonMove(Moves.GASTRO_ACID),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.PLAYER],
|
targets: [ BattlerIndex.PLAYER ],
|
||||||
move: new PokemonMove(Moves.STEALTH_ROCK),
|
move: new PokemonMove(Moves.STEALTH_ROCK),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
});
|
});
|
||||||
|
@ -131,7 +131,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
|
|||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Refuse the challenge, they full heal the party and give the player a Rarer Candy
|
// Refuse the challenge, they full heal the party and give the player a Rarer Candy
|
||||||
scene.unshiftPhase(new PartyHealPhase(scene, true));
|
scene.unshiftPhase(new PartyHealPhase(scene, true));
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.RARER_CANDY], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.RARER_CANDY ], fillRemaining: false });
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -154,7 +154,7 @@ async function spawnNextTrainerOrEndEncounter(scene: BattleScene) {
|
|||||||
scene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in
|
scene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in
|
||||||
const machoBrace = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!;
|
const machoBrace = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!;
|
||||||
machoBrace.type.tier = ModifierTier.MASTER;
|
machoBrace.type.tier = ModifierTier.MASTER;
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [machoBrace], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ machoBrace ], fillRemaining: false });
|
||||||
encounter.doContinueEncounter = undefined;
|
encounter.doContinueEncounter = undefined;
|
||||||
leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.NO_BATTLE);
|
leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.NO_BATTLE);
|
||||||
} else {
|
} else {
|
||||||
@ -232,7 +232,7 @@ function getVictorTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 0, // Guts
|
abilityIndex: 0, // Guts
|
||||||
nature: Nature.ADAMANT,
|
nature: Nature.ADAMANT,
|
||||||
moveSet: [Moves.FACADE, Moves.BRAVE_BIRD, Moves.PROTECT, Moves.QUICK_ATTACK],
|
moveSet: [ Moves.FACADE, Moves.BRAVE_BIRD, Moves.PROTECT, Moves.QUICK_ATTACK ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
|
||||||
@ -250,7 +250,7 @@ function getVictorTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 1, // Guts
|
abilityIndex: 1, // Guts
|
||||||
nature: Nature.ADAMANT,
|
nature: Nature.ADAMANT,
|
||||||
moveSet: [Moves.FACADE, Moves.OBSTRUCT, Moves.NIGHT_SLASH, Moves.FIRE_PUNCH],
|
moveSet: [ Moves.FACADE, Moves.OBSTRUCT, Moves.NIGHT_SLASH, Moves.FIRE_PUNCH ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
|
||||||
@ -276,7 +276,7 @@ function getVictoriaTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 0, // Natural Cure
|
abilityIndex: 0, // Natural Cure
|
||||||
nature: Nature.CALM,
|
nature: Nature.CALM,
|
||||||
moveSet: [Moves.SYNTHESIS, Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.SLEEP_POWDER],
|
moveSet: [ Moves.SYNTHESIS, Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.SLEEP_POWDER ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType,
|
||||||
@ -294,15 +294,15 @@ function getVictoriaTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
formIndex: 1,
|
formIndex: 1,
|
||||||
nature: Nature.TIMID,
|
nature: Nature.TIMID,
|
||||||
moveSet: [Moves.PSYSHOCK, Moves.MOONBLAST, Moves.SHADOW_BALL, Moves.WILL_O_WISP],
|
moveSet: [ Moves.PSYSHOCK, Moves.MOONBLAST, Moves.SHADOW_BALL, Moves.WILL_O_WISP ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.PSYCHIC]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.PSYCHIC ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 1,
|
stackCount: 1,
|
||||||
isTransferable: false
|
isTransferable: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FAIRY]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.FAIRY ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 1,
|
stackCount: 1,
|
||||||
isTransferable: false
|
isTransferable: false
|
||||||
}
|
}
|
||||||
@ -321,15 +321,15 @@ function getViviTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 3, // Lightning Rod
|
abilityIndex: 3, // Lightning Rod
|
||||||
nature: Nature.ADAMANT,
|
nature: Nature.ADAMANT,
|
||||||
moveSet: [Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST],
|
moveSet: [ Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
isTransferable: false
|
isTransferable: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [ Stat.HP ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 4,
|
stackCount: 4,
|
||||||
isTransferable: false
|
isTransferable: false
|
||||||
}
|
}
|
||||||
@ -340,10 +340,10 @@ function getViviTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 1, // Poison Heal
|
abilityIndex: 1, // Poison Heal
|
||||||
nature: Nature.JOLLY,
|
nature: Nature.JOLLY,
|
||||||
moveSet: [Moves.SPORE, Moves.SWORDS_DANCE, Moves.SEED_BOMB, Moves.DRAIN_PUNCH],
|
moveSet: [ Moves.SPORE, Moves.SWORDS_DANCE, Moves.SEED_BOMB, Moves.DRAIN_PUNCH ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [ Stat.HP ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 4,
|
stackCount: 4,
|
||||||
isTransferable: false
|
isTransferable: false
|
||||||
},
|
},
|
||||||
@ -358,7 +358,7 @@ function getViviTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
formIndex: 1,
|
formIndex: 1,
|
||||||
nature: Nature.CALM,
|
nature: Nature.CALM,
|
||||||
moveSet: [Moves.EARTH_POWER, Moves.FIRE_BLAST, Moves.YAWN, Moves.PROTECT],
|
moveSet: [ Moves.EARTH_POWER, Moves.FIRE_BLAST, Moves.YAWN, Moves.PROTECT ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
|
||||||
@ -380,7 +380,7 @@ function getVickyTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
formIndex: 1,
|
formIndex: 1,
|
||||||
nature: Nature.IMPISH,
|
nature: Nature.IMPISH,
|
||||||
moveSet: [Moves.AXE_KICK, Moves.ICE_PUNCH, Moves.ZEN_HEADBUTT, Moves.BULLET_PUNCH],
|
moveSet: [ Moves.AXE_KICK, Moves.ICE_PUNCH, Moves.ZEN_HEADBUTT, Moves.BULLET_PUNCH ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType,
|
||||||
@ -401,10 +401,10 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 0, // Soundproof
|
abilityIndex: 0, // Soundproof
|
||||||
nature: Nature.MODEST,
|
nature: Nature.MODEST,
|
||||||
moveSet: [Moves.THUNDERBOLT, Moves.GIGA_DRAIN, Moves.FOUL_PLAY, Moves.THUNDER_WAVE],
|
moveSet: [ Moves.THUNDERBOLT, Moves.GIGA_DRAIN, Moves.FOUL_PLAY, Moves.THUNDER_WAVE ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [Stat.SPD]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [ Stat.SPD ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
isTransferable: false
|
isTransferable: false
|
||||||
}
|
}
|
||||||
@ -415,50 +415,50 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 2, // Gluttony
|
abilityIndex: 2, // Gluttony
|
||||||
nature: Nature.QUIET,
|
nature: Nature.QUIET,
|
||||||
moveSet: [Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.ICE_BEAM, Moves.EARTHQUAKE],
|
moveSet: [ Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.ICE_BEAM, Moves.EARTHQUAKE ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.APICOT]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.APICOT ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.GANLON ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.STARF]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.STARF ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SALAC]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SALAC ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LANSAT]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LANSAT ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LIECHI]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LIECHI ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.PETAYA]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.PETAYA ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LEPPA]) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LEPPA ]) as PokemonHeldItemModifierType,
|
||||||
stackCount: 2,
|
stackCount: 2,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -468,7 +468,7 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 2, // Tangled Feet
|
abilityIndex: 2, // Tangled Feet
|
||||||
nature: Nature.JOLLY,
|
nature: Nature.JOLLY,
|
||||||
moveSet: [Moves.DRILL_PECK, Moves.QUICK_ATTACK, Moves.THRASH, Moves.KNOCK_OFF],
|
moveSet: [ Moves.DRILL_PECK, Moves.QUICK_ATTACK, Moves.THRASH, Moves.KNOCK_OFF ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.KINGS_ROCK) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.KINGS_ROCK) as PokemonHeldItemModifierType,
|
||||||
@ -482,7 +482,7 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
formIndex: 1,
|
formIndex: 1,
|
||||||
nature: Nature.BOLD,
|
nature: Nature.BOLD,
|
||||||
moveSet: [Moves.PSYCHIC, Moves.SHADOW_BALL, Moves.FOCUS_BLAST, Moves.THUNDERBOLT],
|
moveSet: [ Moves.PSYCHIC, Moves.SHADOW_BALL, Moves.FOCUS_BLAST, Moves.THUNDERBOLT ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.WIDE_LENS) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.WIDE_LENS) as PokemonHeldItemModifierType,
|
||||||
@ -496,7 +496,7 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
|
|||||||
isBoss: false,
|
isBoss: false,
|
||||||
abilityIndex: 0, // Sheer Force
|
abilityIndex: 0, // Sheer Force
|
||||||
nature: Nature.IMPISH,
|
nature: Nature.IMPISH,
|
||||||
moveSet: [Moves.EARTHQUAKE, Moves.U_TURN, Moves.FLARE_BLITZ, Moves.ROCK_SLIDE],
|
moveSet: [ Moves.EARTHQUAKE, Moves.U_TURN, Moves.FLARE_BLITZ, Moves.ROCK_SLIDE ],
|
||||||
modifierConfigs: [
|
modifierConfigs: [
|
||||||
{
|
{
|
||||||
modifier: generateModifierType(scene, modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
|
modifier: generateModifierType(scene, modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
|
||||||
|
@ -67,17 +67,17 @@ export const TrashToTreasureEncounter: MysteryEncounter =
|
|||||||
isBoss: true,
|
isBoss: true,
|
||||||
formIndex: 1, // Gmax
|
formIndex: 1, // Gmax
|
||||||
bossSegmentModifier: 1, // +1 Segment from normal
|
bossSegmentModifier: 1, // +1 Segment from normal
|
||||||
moveSet: [Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH]
|
moveSet: [ Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH ]
|
||||||
};
|
};
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
levelAdditiveModifier: 1,
|
levelAdditiveModifier: 1,
|
||||||
pokemonConfigs: [pokemonConfig],
|
pokemonConfigs: [ pokemonConfig ],
|
||||||
disableSwitch: true
|
disableSwitch: true
|
||||||
};
|
};
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
|
|
||||||
// Load animations/sfx for Garbodor fight start moves
|
// Load animations/sfx for Garbodor fight start moves
|
||||||
loadCustomMovesForEncounter(scene, [Moves.TOXIC, Moves.AMNESIA]);
|
loadCustomMovesForEncounter(scene, [ Moves.TOXIC, Moves.AMNESIA ]);
|
||||||
|
|
||||||
scene.loadSe("PRSFX- Dig2", "battle_anims", "PRSFX- Dig2.wav");
|
scene.loadSe("PRSFX- Dig2", "battle_anims", "PRSFX- Dig2.wav");
|
||||||
scene.loadSe("PRSFX- Venom Drench", "battle_anims", "PRSFX- Venom Drench.wav");
|
scene.loadSe("PRSFX- Venom Drench", "battle_anims", "PRSFX- Venom Drench.wav");
|
||||||
@ -107,7 +107,7 @@ export const TrashToTreasureEncounter: MysteryEncounter =
|
|||||||
transitionMysteryEncounterIntroVisuals(scene);
|
transitionMysteryEncounterIntroVisuals(scene);
|
||||||
await tryApplyDigRewardItems(scene);
|
await tryApplyDigRewardItems(scene);
|
||||||
|
|
||||||
const blackSludge = generateModifierType(scene, modifierTypes.MYSTERY_ENCOUNTER_BLACK_SLUDGE, [SHOP_ITEM_COST_MULTIPLIER]);
|
const blackSludge = generateModifierType(scene, modifierTypes.MYSTERY_ENCOUNTER_BLACK_SLUDGE, [ SHOP_ITEM_COST_MULTIPLIER ]);
|
||||||
const modifier = blackSludge?.newModifier();
|
const modifier = blackSludge?.newModifier();
|
||||||
if (modifier) {
|
if (modifier) {
|
||||||
await scene.addModifier(modifier, false, false, false, true);
|
await scene.addModifier(modifier, false, false, false, true);
|
||||||
@ -139,17 +139,17 @@ export const TrashToTreasureEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true });
|
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT ], fillRemaining: true });
|
||||||
encounter.startOfBattleEffects.push(
|
encounter.startOfBattleEffects.push(
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.PLAYER],
|
targets: [ BattlerIndex.PLAYER ],
|
||||||
move: new PokemonMove(Moves.TOXIC),
|
move: new PokemonMove(Moves.TOXIC),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.ENEMY],
|
targets: [ BattlerIndex.ENEMY ],
|
||||||
move: new PokemonMove(Moves.AMNESIA),
|
move: new PokemonMove(Moves.AMNESIA),
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
});
|
});
|
||||||
|
@ -74,8 +74,8 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
|
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
|
||||||
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
|
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
|
||||||
[Stat.DEF, Stat.SPDEF, Stat.SPD] :
|
[ Stat.DEF, Stat.SPDEF, Stat.SPD ] :
|
||||||
[Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD];
|
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
|
||||||
|
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
pokemonConfigs: [{
|
pokemonConfigs: [{
|
||||||
@ -83,14 +83,14 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
species: species,
|
species: species,
|
||||||
dataSource: new PokemonData(pokemon),
|
dataSource: new PokemonData(pokemon),
|
||||||
isBoss: false,
|
isBoss: false,
|
||||||
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`);
|
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`);
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [ config ];
|
||||||
|
|
||||||
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(pokemon);
|
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(pokemon);
|
||||||
encounter.spriteConfigs = [
|
encounter.spriteConfigs = [
|
||||||
@ -152,7 +152,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
encounter.startOfBattleEffects.push(
|
encounter.startOfBattleEffects.push(
|
||||||
{
|
{
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [target],
|
targets: [ target ],
|
||||||
move: pokemonMove,
|
move: pokemonMove,
|
||||||
ignorePp: true
|
ignorePp: true
|
||||||
});
|
});
|
||||||
@ -181,7 +181,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Remove 4 random berries from player's party
|
// Remove 4 random berries from player's party
|
||||||
// Get all player berry items, remove from party, and store reference
|
// Get all player berry items, remove from party, and store reference
|
||||||
const berryItems: BerryModifier[]= scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
|
const berryItems: BerryModifier[] = scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
|
||||||
for (let i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
const index = randSeedInt(berryItems.length);
|
const index = randSeedInt(berryItems.length);
|
||||||
const randBerry = berryItems[index];
|
const randBerry = berryItems[index];
|
||||||
|
@ -89,12 +89,12 @@ const PERCENT_LEVEL_LOSS_ON_REFUSE = 12.5;
|
|||||||
* Value ranges of the resulting species BST transformations after adding values to original species
|
* Value ranges of the resulting species BST transformations after adding values to original species
|
||||||
* 2 Pokemon in the party use this range
|
* 2 Pokemon in the party use this range
|
||||||
*/
|
*/
|
||||||
const HIGH_BST_TRANSFORM_BASE_VALUES: [number, number] = [90, 110];
|
const HIGH_BST_TRANSFORM_BASE_VALUES: [number, number] = [ 90, 110 ];
|
||||||
/**
|
/**
|
||||||
* Value ranges of the resulting species BST transformations after adding values to original species
|
* Value ranges of the resulting species BST transformations after adding values to original species
|
||||||
* All remaining Pokemon in the party use this range
|
* All remaining Pokemon in the party use this range
|
||||||
*/
|
*/
|
||||||
const STANDARD_BST_TRANSFORM_BASE_VALUES: [number, number] = [40, 50];
|
const STANDARD_BST_TRANSFORM_BASE_VALUES: [number, number] = [ 40, 50 ];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Weird Dream encounter.
|
* Weird Dream encounter.
|
||||||
@ -192,7 +192,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||||||
await showEncounterText(scene, `${namespace}:option.1.dream_complete`);
|
await showEncounterText(scene, `${namespace}:option.1.dream_complete`);
|
||||||
|
|
||||||
await doNewTeamPostProcess(scene, transformations);
|
await doNewTeamPostProcess(scene, transformations);
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.ROGUE_BALL, modifierTypes.MINT, modifierTypes.MINT]});
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM, modifierTypes.ROGUE_BALL, modifierTypes.MINT, modifierTypes.MINT ]});
|
||||||
leaveEncounterWithoutBattle(scene, true);
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
@ -372,7 +372,7 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
|
|||||||
|
|
||||||
// Randomize the second type of the pokemon
|
// Randomize the second type of the pokemon
|
||||||
// If the pokemon does not normally have a second type, it will gain 1
|
// If the pokemon does not normally have a second type, it will gain 1
|
||||||
const newTypes = [newPokemon.getTypes()[0]];
|
const newTypes = [ newPokemon.getTypes()[0] ];
|
||||||
let newType = randSeedInt(18) as Type;
|
let newType = randSeedInt(18) as Type;
|
||||||
while (newType === newTypes[0]) {
|
while (newType === newTypes[0]) {
|
||||||
newType = randSeedInt(18) as Type;
|
newType = randSeedInt(18) as Type;
|
||||||
@ -390,14 +390,14 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
|
|||||||
|
|
||||||
// Any pokemon that is at or below 450 BST gets +20 permanent BST to 3 stats: HP (halved, +10), lowest of Atk/SpAtk, and lowest of Def/SpDef
|
// Any pokemon that is at or below 450 BST gets +20 permanent BST to 3 stats: HP (halved, +10), lowest of Atk/SpAtk, and lowest of Def/SpDef
|
||||||
if (newPokemon.getSpeciesForm().getBaseStatTotal() <= GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD) {
|
if (newPokemon.getSpeciesForm().getBaseStatTotal() <= GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD) {
|
||||||
const stats: Stat[] = [Stat.HP];
|
const stats: Stat[] = [ Stat.HP ];
|
||||||
const baseStats = newPokemon.getSpeciesForm().baseStats.slice(0);
|
const baseStats = newPokemon.getSpeciesForm().baseStats.slice(0);
|
||||||
// Attack or SpAtk
|
// Attack or SpAtk
|
||||||
stats.push(baseStats[Stat.ATK] < baseStats[Stat.SPATK] ? Stat.ATK : Stat.SPATK);
|
stats.push(baseStats[Stat.ATK] < baseStats[Stat.SPATK] ? Stat.ATK : Stat.SPATK);
|
||||||
// Def or SpDef
|
// Def or SpDef
|
||||||
stats.push(baseStats[Stat.DEF] < baseStats[Stat.SPDEF] ? Stat.DEF : Stat.SPDEF);
|
stats.push(baseStats[Stat.DEF] < baseStats[Stat.SPDEF] ? Stat.DEF : Stat.SPDEF);
|
||||||
const modType = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU()
|
const modType = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU()
|
||||||
.generateType(scene.getParty(), [20, stats])
|
.generateType(scene.getParty(), [ 20, stats ])
|
||||||
?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU);
|
?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU);
|
||||||
const modifier = modType?.newModifier(newPokemon);
|
const modifier = modType?.newModifier(newPokemon);
|
||||||
if (modifier) {
|
if (modifier) {
|
||||||
@ -553,7 +553,7 @@ async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Pla
|
|||||||
let eggMoveIndex: null | number = null;
|
let eggMoveIndex: null | number = null;
|
||||||
const eggMoves = newPokemon.getEggMoves()?.slice(0);
|
const eggMoves = newPokemon.getEggMoves()?.slice(0);
|
||||||
if (eggMoves) {
|
if (eggMoves) {
|
||||||
const eggMoveIndices = randSeedShuffle([0, 1, 2, 3]);
|
const eggMoveIndices = randSeedShuffle([ 0, 1, 2, 3 ]);
|
||||||
let randomEggMoveIndex = eggMoveIndices.pop();
|
let randomEggMoveIndex = eggMoveIndices.pop();
|
||||||
let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null;
|
let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null;
|
||||||
let retries = 0;
|
let retries = 0;
|
||||||
|
@ -147,7 +147,7 @@ export class PreviousEncounterRequirement extends EncounterSceneRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["previousEncounter", scene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? ""];
|
return [ "previousEncounter", scene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ export class WaveRangeRequirement extends EncounterSceneRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["waveIndex", scene.currentBattle.waveIndex.toString()];
|
return [ "waveIndex", scene.currentBattle.waveIndex.toString() ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ export class WaveModulusRequirement extends EncounterSceneRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["waveIndex", scene.currentBattle.waveIndex.toString()];
|
return [ "waveIndex", scene.currentBattle.waveIndex.toString() ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
|
|||||||
|
|
||||||
constructor(timeOfDay: TimeOfDay | TimeOfDay[]) {
|
constructor(timeOfDay: TimeOfDay | TimeOfDay[]) {
|
||||||
super();
|
super();
|
||||||
this.requiredTimeOfDay = Array.isArray(timeOfDay) ? timeOfDay : [timeOfDay];
|
this.requiredTimeOfDay = Array.isArray(timeOfDay) ? timeOfDay : [ timeOfDay ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -226,7 +226,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["timeOfDay", TimeOfDay[scene.arena.getTimeOfDay()].toLocaleLowerCase()];
|
return [ "timeOfDay", TimeOfDay[scene.arena.getTimeOfDay()].toLocaleLowerCase() ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
|
|||||||
|
|
||||||
constructor(weather: WeatherType | WeatherType[]) {
|
constructor(weather: WeatherType | WeatherType[]) {
|
||||||
super();
|
super();
|
||||||
this.requiredWeather = Array.isArray(weather) ? weather : [weather];
|
this.requiredWeather = Array.isArray(weather) ? weather : [ weather ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -253,7 +253,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
|
|||||||
if (!isNullOrUndefined(currentWeather)) {
|
if (!isNullOrUndefined(currentWeather)) {
|
||||||
token = WeatherType[currentWeather].replace("_", " ").toLocaleLowerCase();
|
token = WeatherType[currentWeather].replace("_", " ").toLocaleLowerCase();
|
||||||
}
|
}
|
||||||
return ["weather", token];
|
return [ "weather", token ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ export class PartySizeRequirement extends EncounterSceneRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["partySize", scene.getParty().length.toString()];
|
return [ "partySize", scene.getParty().length.toString() ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
|
|||||||
constructor(heldItem: string | string[], minNumberOfItems: number = 1) {
|
constructor(heldItem: string | string[], minNumberOfItems: number = 1) {
|
||||||
super();
|
super();
|
||||||
this.minNumberOfItems = minNumberOfItems;
|
this.minNumberOfItems = minNumberOfItems;
|
||||||
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
|
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [ heldItem ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -318,7 +318,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["requiredItem", this.requiredHeldItemModifiers[0]];
|
return [ "requiredItem", this.requiredHeldItemModifiers[0] ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +346,7 @@ export class MoneyRequirement extends EncounterSceneRequirement {
|
|||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
const value = this.scalingMultiplier > 0 ? scene.getWaveMoneyAmount(this.scalingMultiplier).toString() : this.requiredMoney.toString();
|
const value = this.scalingMultiplier > 0 ? scene.getWaveMoneyAmount(this.scalingMultiplier).toString() : this.requiredMoney.toString();
|
||||||
return ["money", value];
|
return [ "money", value ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredSpecies = Array.isArray(species) ? species : [species];
|
this.requiredSpecies = Array.isArray(species) ? species : [ species ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -381,9 +381,9 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
|
|||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
if (pokemon?.species.speciesId && this.requiredSpecies.includes(pokemon.species.speciesId)) {
|
if (pokemon?.species.speciesId && this.requiredSpecies.includes(pokemon.species.speciesId)) {
|
||||||
return ["species", Species[pokemon.species.speciesId]];
|
return [ "species", Species[pokemon.species.speciesId] ];
|
||||||
}
|
}
|
||||||
return ["species", ""];
|
return [ "species", "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +397,7 @@ export class NatureRequirement extends EncounterPokemonRequirement {
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredNature = Array.isArray(nature) ? nature : [nature];
|
this.requiredNature = Array.isArray(nature) ? nature : [ nature ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -419,9 +419,9 @@ export class NatureRequirement extends EncounterPokemonRequirement {
|
|||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
if (!isNullOrUndefined(pokemon?.nature) && this.requiredNature.includes(pokemon.nature)) {
|
if (!isNullOrUndefined(pokemon?.nature) && this.requiredNature.includes(pokemon.nature)) {
|
||||||
return ["nature", Nature[pokemon.nature]];
|
return [ "nature", Nature[pokemon.nature] ];
|
||||||
}
|
}
|
||||||
return ["nature", ""];
|
return [ "nature", "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +436,7 @@ export class TypeRequirement extends EncounterPokemonRequirement {
|
|||||||
this.excludeFainted = excludeFainted;
|
this.excludeFainted = excludeFainted;
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredType = Array.isArray(type) ? type : [type];
|
this.requiredType = Array.isArray(type) ? type : [ type ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -465,9 +465,9 @@ export class TypeRequirement extends EncounterPokemonRequirement {
|
|||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
const includedTypes = this.requiredType.filter((ty) => pokemon?.getTypes().includes(ty));
|
const includedTypes = this.requiredType.filter((ty) => pokemon?.getTypes().includes(ty));
|
||||||
if (includedTypes.length > 0) {
|
if (includedTypes.length > 0) {
|
||||||
return ["type", Type[includedTypes[0]]];
|
return [ "type", Type[includedTypes[0]] ];
|
||||||
}
|
}
|
||||||
return ["type", ""];
|
return [ "type", "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,7 +481,7 @@ export class MoveRequirement extends EncounterPokemonRequirement {
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredMoves = Array.isArray(moves) ? moves : [moves];
|
this.requiredMoves = Array.isArray(moves) ? moves : [ moves ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -504,9 +504,9 @@ export class MoveRequirement extends EncounterPokemonRequirement {
|
|||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
const includedMoves = pokemon?.moveset.filter((move) => move?.moveId && this.requiredMoves.includes(move.moveId));
|
const includedMoves = pokemon?.moveset.filter((move) => move?.moveId && this.requiredMoves.includes(move.moveId));
|
||||||
if (includedMoves && includedMoves.length > 0 && includedMoves[0]) {
|
if (includedMoves && includedMoves.length > 0 && includedMoves[0]) {
|
||||||
return ["move", includedMoves[0].getName()];
|
return [ "move", includedMoves[0].getName() ];
|
||||||
}
|
}
|
||||||
return ["move", ""];
|
return [ "move", "" ];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -525,7 +525,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredMoves = Array.isArray(learnableMove) ? learnableMove : [learnableMove];
|
this.requiredMoves = Array.isArray(learnableMove) ? learnableMove : [ learnableMove ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -548,9 +548,9 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
const includedCompatMoves = this.requiredMoves.filter((reqMove) => pokemon?.compatibleTms.filter((tm) => !pokemon.moveset.find(m => m?.moveId === tm)).includes(reqMove));
|
const includedCompatMoves = this.requiredMoves.filter((reqMove) => pokemon?.compatibleTms.filter((tm) => !pokemon.moveset.find(m => m?.moveId === tm)).includes(reqMove));
|
||||||
if (includedCompatMoves.length > 0) {
|
if (includedCompatMoves.length > 0) {
|
||||||
return ["compatibleMove", Moves[includedCompatMoves[0]]];
|
return [ "compatibleMove", Moves[includedCompatMoves[0]] ];
|
||||||
}
|
}
|
||||||
return ["compatibleMove", ""];
|
return [ "compatibleMove", "" ];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -564,7 +564,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredAbilities = Array.isArray(abilities) ? abilities : [abilities];
|
this.requiredAbilities = Array.isArray(abilities) ? abilities : [ abilities ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -586,9 +586,9 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
|
|||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
if (pokemon?.getAbility().id && this.requiredAbilities.some(a => pokemon.getAbility().id === a)) {
|
if (pokemon?.getAbility().id && this.requiredAbilities.some(a => pokemon.getAbility().id === a)) {
|
||||||
return ["ability", pokemon.getAbility().name];
|
return [ "ability", pokemon.getAbility().name ];
|
||||||
}
|
}
|
||||||
return ["ability", ""];
|
return [ "ability", "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,7 +601,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredStatusEffect = Array.isArray(statusEffect) ? statusEffect : [statusEffect];
|
this.requiredStatusEffect = Array.isArray(statusEffect) ? statusEffect : [ statusEffect ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -649,9 +649,9 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
|||||||
return pokemon!.status?.effect === a;
|
return pokemon!.status?.effect === a;
|
||||||
});
|
});
|
||||||
if (reqStatus.length > 0) {
|
if (reqStatus.length > 0) {
|
||||||
return ["status", StatusEffect[reqStatus[0]]];
|
return [ "status", StatusEffect[reqStatus[0]] ];
|
||||||
}
|
}
|
||||||
return ["status", ""];
|
return [ "status", "" ];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -670,7 +670,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredFormChangeItem = Array.isArray(formChangeItem) ? formChangeItem : [formChangeItem];
|
this.requiredFormChangeItem = Array.isArray(formChangeItem) ? formChangeItem : [ formChangeItem ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -706,9 +706,9 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
|||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
const requiredItems = this.requiredFormChangeItem.filter((formChangeItem) => this.filterByForm(pokemon, formChangeItem));
|
const requiredItems = this.requiredFormChangeItem.filter((formChangeItem) => this.filterByForm(pokemon, formChangeItem));
|
||||||
if (requiredItems.length > 0) {
|
if (requiredItems.length > 0) {
|
||||||
return ["formChangeItem", FormChangeItem[requiredItems[0]]];
|
return [ "formChangeItem", FormChangeItem[requiredItems[0]] ];
|
||||||
}
|
}
|
||||||
return ["formChangeItem", ""];
|
return [ "formChangeItem", "" ];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -722,7 +722,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredEvolutionItem = Array.isArray(evolutionItems) ? evolutionItems : [evolutionItems];
|
this.requiredEvolutionItem = Array.isArray(evolutionItems) ? evolutionItems : [ evolutionItems ];
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -756,9 +756,9 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
|
|||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
const requiredItems = this.requiredEvolutionItem.filter((evoItem) => this.filterByEvo(pokemon, evoItem));
|
const requiredItems = this.requiredEvolutionItem.filter((evoItem) => this.filterByEvo(pokemon, evoItem));
|
||||||
if (requiredItems.length > 0) {
|
if (requiredItems.length > 0) {
|
||||||
return ["evolutionItem", EvolutionItem[requiredItems[0]]];
|
return [ "evolutionItem", EvolutionItem[requiredItems[0]] ];
|
||||||
}
|
}
|
||||||
return ["evolutionItem", ""];
|
return [ "evolutionItem", "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,7 +772,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
|
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [ heldItem ];
|
||||||
this.requireTransferable = requireTransferable;
|
this.requireTransferable = requireTransferable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,9 +807,9 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
|||||||
&& (!this.requireTransferable || it.isTransferable);
|
&& (!this.requireTransferable || it.isTransferable);
|
||||||
});
|
});
|
||||||
if (requiredItems && requiredItems.length > 0) {
|
if (requiredItems && requiredItems.length > 0) {
|
||||||
return ["heldItem", requiredItems[0].type.name];
|
return [ "heldItem", requiredItems[0].type.name ];
|
||||||
}
|
}
|
||||||
return ["heldItem", ""];
|
return [ "heldItem", "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,7 +823,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
|
|||||||
super();
|
super();
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [heldItemTypes];
|
this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [ heldItemTypes ];
|
||||||
this.requireTransferable = requireTransferable;
|
this.requireTransferable = requireTransferable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,9 +864,9 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
|
|||||||
&& (!this.requireTransferable || it.isTransferable);
|
&& (!this.requireTransferable || it.isTransferable);
|
||||||
});
|
});
|
||||||
if (requiredItems && requiredItems.length > 0) {
|
if (requiredItems && requiredItems.length > 0) {
|
||||||
return ["heldItem", requiredItems[0].type.name];
|
return [ "heldItem", requiredItems[0].type.name ];
|
||||||
}
|
}
|
||||||
return ["heldItem", ""];
|
return [ "heldItem", "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -904,7 +904,7 @@ export class LevelRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["level", pokemon?.level.toString() ?? ""];
|
return [ "level", pokemon?.level.toString() ?? "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,7 +942,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["friendship", pokemon?.friendship.toString() ?? ""];
|
return [ "friendship", pokemon?.friendship.toString() ?? "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,9 +989,9 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
|||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
const hpRatio = pokemon?.getHpRatio();
|
const hpRatio = pokemon?.getHpRatio();
|
||||||
if (!isNullOrUndefined(hpRatio)) {
|
if (!isNullOrUndefined(hpRatio)) {
|
||||||
return ["healthRatio", Math.floor(hpRatio * 100).toString() + "%"];
|
return [ "healthRatio", Math.floor(hpRatio * 100).toString() + "%" ];
|
||||||
}
|
}
|
||||||
return ["healthRatio", ""];
|
return [ "healthRatio", "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1029,8 +1029,7 @@ export class WeightRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["weight", pokemon?.getWeight().toString() ?? ""];
|
return [ "weight", pokemon?.getWeight().toString() ?? "" ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
}
|
}
|
||||||
this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON;
|
this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON;
|
||||||
this.dialogue = this.dialogue ?? {};
|
this.dialogue = this.dialogue ?? {};
|
||||||
this.spriteConfigs = this.spriteConfigs ? [...this.spriteConfigs] : [];
|
this.spriteConfigs = this.spriteConfigs ? [ ...this.spriteConfigs ] : [];
|
||||||
// Default max is 1 for ROGUE encounters, 2 for others
|
// Default max is 1 for ROGUE encounters, 2 for others
|
||||||
this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? DEFAULT_MAX_ALLOWED_ROGUE_ENCOUNTERS : DEFAULT_MAX_ALLOWED_ENCOUNTERS;
|
this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? DEFAULT_MAX_ALLOWED_ROGUE_ENCOUNTERS : DEFAULT_MAX_ALLOWED_ENCOUNTERS;
|
||||||
this.encounterMode = MysteryEncounterMode.DEFAULT;
|
this.encounterMode = MysteryEncounterMode.DEFAULT;
|
||||||
@ -573,7 +573,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
*/
|
*/
|
||||||
withOption(option: MysteryEncounterOption): this & Pick<IMysteryEncounter, "options"> {
|
withOption(option: MysteryEncounterOption): this & Pick<IMysteryEncounter, "options"> {
|
||||||
if (!this.options) {
|
if (!this.options) {
|
||||||
const options = [option];
|
const options = [ option ];
|
||||||
return Object.assign(this, { options });
|
return Object.assign(this, { options });
|
||||||
} else {
|
} else {
|
||||||
this.options.push(option);
|
this.options.push(option);
|
||||||
@ -624,11 +624,11 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []): this {
|
withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []): this {
|
||||||
this.dialogue = {...this.dialogue, intro: dialogue };
|
this.dialogue = { ...this.dialogue, intro: dialogue };
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
withIntro({spriteConfigs, dialogue} : {spriteConfigs: MysteryEncounterSpriteConfig[], dialogue?: MysteryEncounterDialogue["intro"]}) {
|
withIntro({ spriteConfigs, dialogue } : {spriteConfigs: MysteryEncounterSpriteConfig[], dialogue?: MysteryEncounterDialogue["intro"]}) {
|
||||||
return this.withIntroSpriteConfigs(spriteConfigs).withIntroDialogue(dialogue);
|
return this.withIntroSpriteConfigs(spriteConfigs).withIntroDialogue(dialogue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,7 +660,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withAnimations(...encounterAnimations: EncounterAnim[]): this & Required<Pick<IMysteryEncounter, "encounterAnimations">> {
|
withAnimations(...encounterAnimations: EncounterAnim[]): this & Required<Pick<IMysteryEncounter, "encounterAnimations">> {
|
||||||
const animations = Array.isArray(encounterAnimations) ? encounterAnimations : [encounterAnimations];
|
const animations = Array.isArray(encounterAnimations) ? encounterAnimations : [ encounterAnimations ];
|
||||||
return Object.assign(this, { encounterAnimations: animations });
|
return Object.assign(this, { encounterAnimations: animations });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,7 +670,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
* @param disallowedGameModes
|
* @param disallowedGameModes
|
||||||
*/
|
*/
|
||||||
withDisallowedGameModes(...disallowedGameModes: GameModes[]): this & Required<Pick<IMysteryEncounter, "disallowedGameModes">> {
|
withDisallowedGameModes(...disallowedGameModes: GameModes[]): this & Required<Pick<IMysteryEncounter, "disallowedGameModes">> {
|
||||||
const gameModes = Array.isArray(disallowedGameModes) ? disallowedGameModes : [disallowedGameModes];
|
const gameModes = Array.isArray(disallowedGameModes) ? disallowedGameModes : [ disallowedGameModes ];
|
||||||
return Object.assign(this, { disallowedGameModes: gameModes });
|
return Object.assign(this, { disallowedGameModes: gameModes });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,7 +680,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
* @param disallowedChallenges
|
* @param disallowedChallenges
|
||||||
*/
|
*/
|
||||||
withDisallowedChallenges(...disallowedChallenges: Challenges[]): this & Required<Pick<IMysteryEncounter, "disallowedChallenges">> {
|
withDisallowedChallenges(...disallowedChallenges: Challenges[]): this & Required<Pick<IMysteryEncounter, "disallowedChallenges">> {
|
||||||
const challenges = Array.isArray(disallowedChallenges) ? disallowedChallenges : [disallowedChallenges];
|
const challenges = Array.isArray(disallowedChallenges) ? disallowedChallenges : [ disallowedChallenges ];
|
||||||
return Object.assign(this, { disallowedChallenges: challenges });
|
return Object.assign(this, { disallowedChallenges: challenges });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,7 +755,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withSceneWaveRangeRequirement(min: number, max?: number): this & Required<Pick<IMysteryEncounter, "requirements">> {
|
withSceneWaveRangeRequirement(min: number, max?: number): this & Required<Pick<IMysteryEncounter, "requirements">> {
|
||||||
return this.withSceneRequirement(new WaveRangeRequirement([min, max ?? min]));
|
return this.withSceneRequirement(new WaveRangeRequirement([ min, max ?? min ]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -767,7 +767,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withScenePartySizeRequirement(min: number, max?: number, excludeDisallowedPokemon: boolean = false): this & Required<Pick<IMysteryEncounter, "requirements">> {
|
withScenePartySizeRequirement(min: number, max?: number, excludeDisallowedPokemon: boolean = false): this & Required<Pick<IMysteryEncounter, "requirements">> {
|
||||||
return this.withSceneRequirement(new PartySizeRequirement([min, max ?? min], excludeDisallowedPokemon));
|
return this.withSceneRequirement(new PartySizeRequirement([ min, max ?? min ], excludeDisallowedPokemon));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -982,7 +982,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withOutroDialogue(dialogue: MysteryEncounterDialogue["outro"] = []): this {
|
withOutroDialogue(dialogue: MysteryEncounterDialogue["outro"] = []): this {
|
||||||
this.dialogue = {...this.dialogue, outro: dialogue };
|
this.dialogue = { ...this.dialogue, outro: dialogue };
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,72 +224,72 @@ const anyBiomeEncounters: MysteryEncounterType[] = [
|
|||||||
* that biome groups do not cover
|
* that biome groups do not cover
|
||||||
*/
|
*/
|
||||||
export const mysteryEncountersByBiome = new Map<Biome, MysteryEncounterType[]>([
|
export const mysteryEncountersByBiome = new Map<Biome, MysteryEncounterType[]>([
|
||||||
[Biome.TOWN, []],
|
[ Biome.TOWN, []],
|
||||||
[Biome.PLAINS, [
|
[ Biome.PLAINS, [
|
||||||
MysteryEncounterType.SLUMBERING_SNORLAX,
|
MysteryEncounterType.SLUMBERING_SNORLAX,
|
||||||
MysteryEncounterType.ABSOLUTE_AVARICE
|
MysteryEncounterType.ABSOLUTE_AVARICE
|
||||||
]],
|
]],
|
||||||
[Biome.GRASS, [
|
[ Biome.GRASS, [
|
||||||
MysteryEncounterType.SLUMBERING_SNORLAX,
|
MysteryEncounterType.SLUMBERING_SNORLAX,
|
||||||
MysteryEncounterType.ABSOLUTE_AVARICE
|
MysteryEncounterType.ABSOLUTE_AVARICE
|
||||||
]],
|
]],
|
||||||
[Biome.TALL_GRASS, [
|
[ Biome.TALL_GRASS, [
|
||||||
MysteryEncounterType.ABSOLUTE_AVARICE
|
MysteryEncounterType.ABSOLUTE_AVARICE
|
||||||
]],
|
]],
|
||||||
[Biome.METROPOLIS, []],
|
[ Biome.METROPOLIS, []],
|
||||||
[Biome.FOREST, [
|
[ Biome.FOREST, [
|
||||||
MysteryEncounterType.SAFARI_ZONE,
|
MysteryEncounterType.SAFARI_ZONE,
|
||||||
MysteryEncounterType.ABSOLUTE_AVARICE
|
MysteryEncounterType.ABSOLUTE_AVARICE
|
||||||
]],
|
]],
|
||||||
[Biome.SEA, [
|
[ Biome.SEA, [
|
||||||
MysteryEncounterType.LOST_AT_SEA
|
MysteryEncounterType.LOST_AT_SEA
|
||||||
]],
|
]],
|
||||||
[Biome.SWAMP, [
|
[ Biome.SWAMP, [
|
||||||
MysteryEncounterType.SAFARI_ZONE
|
MysteryEncounterType.SAFARI_ZONE
|
||||||
]],
|
]],
|
||||||
[Biome.BEACH, []],
|
[ Biome.BEACH, []],
|
||||||
[Biome.LAKE, []],
|
[ Biome.LAKE, []],
|
||||||
[Biome.SEABED, []],
|
[ Biome.SEABED, []],
|
||||||
[Biome.MOUNTAIN, []],
|
[ Biome.MOUNTAIN, []],
|
||||||
[Biome.BADLANDS, [
|
[ Biome.BADLANDS, [
|
||||||
MysteryEncounterType.DANCING_LESSONS
|
MysteryEncounterType.DANCING_LESSONS
|
||||||
]],
|
]],
|
||||||
[Biome.CAVE, [
|
[ Biome.CAVE, [
|
||||||
MysteryEncounterType.THE_STRONG_STUFF
|
MysteryEncounterType.THE_STRONG_STUFF
|
||||||
]],
|
]],
|
||||||
[Biome.DESERT, [
|
[ Biome.DESERT, [
|
||||||
MysteryEncounterType.DANCING_LESSONS
|
MysteryEncounterType.DANCING_LESSONS
|
||||||
]],
|
]],
|
||||||
[Biome.ICE_CAVE, []],
|
[ Biome.ICE_CAVE, []],
|
||||||
[Biome.MEADOW, []],
|
[ Biome.MEADOW, []],
|
||||||
[Biome.POWER_PLANT, []],
|
[ Biome.POWER_PLANT, []],
|
||||||
[Biome.VOLCANO, [
|
[ Biome.VOLCANO, [
|
||||||
MysteryEncounterType.FIERY_FALLOUT,
|
MysteryEncounterType.FIERY_FALLOUT,
|
||||||
MysteryEncounterType.DANCING_LESSONS
|
MysteryEncounterType.DANCING_LESSONS
|
||||||
]],
|
]],
|
||||||
[Biome.GRAVEYARD, []],
|
[ Biome.GRAVEYARD, []],
|
||||||
[Biome.DOJO, []],
|
[ Biome.DOJO, []],
|
||||||
[Biome.FACTORY, []],
|
[ Biome.FACTORY, []],
|
||||||
[Biome.RUINS, []],
|
[ Biome.RUINS, []],
|
||||||
[Biome.WASTELAND, [
|
[ Biome.WASTELAND, [
|
||||||
MysteryEncounterType.DANCING_LESSONS
|
MysteryEncounterType.DANCING_LESSONS
|
||||||
]],
|
]],
|
||||||
[Biome.ABYSS, [
|
[ Biome.ABYSS, [
|
||||||
MysteryEncounterType.DANCING_LESSONS
|
MysteryEncounterType.DANCING_LESSONS
|
||||||
]],
|
]],
|
||||||
[Biome.SPACE, [
|
[ Biome.SPACE, [
|
||||||
MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER
|
MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER
|
||||||
]],
|
]],
|
||||||
[Biome.CONSTRUCTION_SITE, []],
|
[ Biome.CONSTRUCTION_SITE, []],
|
||||||
[Biome.JUNGLE, [
|
[ Biome.JUNGLE, [
|
||||||
MysteryEncounterType.SAFARI_ZONE
|
MysteryEncounterType.SAFARI_ZONE
|
||||||
]],
|
]],
|
||||||
[Biome.FAIRY_CAVE, []],
|
[ Biome.FAIRY_CAVE, []],
|
||||||
[Biome.TEMPLE, []],
|
[ Biome.TEMPLE, []],
|
||||||
[Biome.SLUM, []],
|
[ Biome.SLUM, []],
|
||||||
[Biome.SNOWY_FOREST, []],
|
[ Biome.SNOWY_FOREST, []],
|
||||||
[Biome.ISLAND, []],
|
[ Biome.ISLAND, []],
|
||||||
[Biome.LABORATORY, []]
|
[ Biome.LABORATORY, []]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export function initMysteryEncounters() {
|
export function initMysteryEncounters() {
|
||||||
|
@ -28,7 +28,7 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
|
|
||||||
constructor(requiredMoves: Moves | Moves[], options: CanLearnMoveRequirementOptions = {}) {
|
constructor(requiredMoves: Moves | Moves[], options: CanLearnMoveRequirementOptions = {}) {
|
||||||
super();
|
super();
|
||||||
this.requiredMoves = Array.isArray(requiredMoves) ? requiredMoves : [requiredMoves];
|
this.requiredMoves = Array.isArray(requiredMoves) ? requiredMoves : [ requiredMoves ];
|
||||||
|
|
||||||
this.excludeLevelMoves = options.excludeLevelMoves ?? false;
|
this.excludeLevelMoves = options.excludeLevelMoves ?? false;
|
||||||
this.excludeTmMoves = options.excludeTmMoves ?? false;
|
this.excludeTmMoves = options.excludeTmMoves ?? false;
|
||||||
@ -64,11 +64,11 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(_scene: BattleScene, _pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(_scene: BattleScene, _pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["requiredMoves", this.requiredMoves.map(m => new PokemonMove(m).getName()).join(", ")];
|
return [ "requiredMoves", this.requiredMoves.map(m => new PokemonMove(m).getName()).join(", ") ];
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPokemonLevelMoves(pkm: PlayerPokemon): Moves[] {
|
private getPokemonLevelMoves(pkm: PlayerPokemon): Moves[] {
|
||||||
return pkm.getLevelMoves().map(([_level, move]) => move);
|
return pkm.getLevelMoves().map(([ _level, move ]) => move);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getAllPokemonMoves(pkm: PlayerPokemon): Moves[] {
|
private getAllPokemonMoves(pkm: PlayerPokemon): Moves[] {
|
||||||
|
@ -373,7 +373,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
* @param moves
|
* @param moves
|
||||||
*/
|
*/
|
||||||
export function loadCustomMovesForEncounter(scene: BattleScene, moves: Moves | Moves[]) {
|
export function loadCustomMovesForEncounter(scene: BattleScene, moves: Moves | Moves[]) {
|
||||||
moves = Array.isArray(moves) ? moves : [moves];
|
moves = Array.isArray(moves) ? moves : [ moves ];
|
||||||
return Promise.all(moves.map(move => initMoveAnim(scene, move)))
|
return Promise.all(moves.map(move => initMoveAnim(scene, move)))
|
||||||
.then(() => loadMoveAnimAssets(scene, moves));
|
.then(() => loadMoveAnimAssets(scene, moves));
|
||||||
}
|
}
|
||||||
@ -663,7 +663,7 @@ export function setEncounterRewards(scene: BattleScene, customShopRewards?: Cust
|
|||||||
* @param useWaveIndex - set to false when directly passing the the full exp value instead of baseExpValue
|
* @param useWaveIndex - set to false when directly passing the the full exp value instead of baseExpValue
|
||||||
*/
|
*/
|
||||||
export function setEncounterExp(scene: BattleScene, participantId: number | number[], baseExpValue: number, useWaveIndex: boolean = true) {
|
export function setEncounterExp(scene: BattleScene, participantId: number | number[], baseExpValue: number, useWaveIndex: boolean = true) {
|
||||||
const participantIds = Array.isArray(participantId) ? participantId : [participantId];
|
const participantIds = Array.isArray(participantId) ? participantId : [ participantId ];
|
||||||
|
|
||||||
scene.currentBattle.mysteryEncounter!.doEncounterExp = (scene: BattleScene) => {
|
scene.currentBattle.mysteryEncounter!.doEncounterExp = (scene: BattleScene) => {
|
||||||
scene.unshiftPhase(new PartyExpPhase(scene, baseExpValue, useWaveIndex, new Set(participantIds)));
|
scene.unshiftPhase(new PartyExpPhase(scene, baseExpValue, useWaveIndex, new Set(participantIds)));
|
||||||
@ -800,8 +800,8 @@ export function transitionMysteryEncounterIntroVisuals(scene: BattleScene, hide:
|
|||||||
|
|
||||||
// Transition
|
// Transition
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: [introVisuals, enemyPokemon],
|
targets: [ introVisuals, enemyPokemon ],
|
||||||
x: `${hide? "+" : "-"}=16`,
|
x: `${hide ? "+" : "-"}=16`,
|
||||||
y: `${hide ? "-" : "+"}=16`,
|
y: `${hide ? "-" : "+"}=16`,
|
||||||
alpha: hide ? 0 : 1,
|
alpha: hide ? 0 : 1,
|
||||||
ease: "Sine.easeInOut",
|
ease: "Sine.easeInOut",
|
||||||
@ -888,14 +888,14 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
const numRuns = 1000;
|
const numRuns = 1000;
|
||||||
let run = 0;
|
let run = 0;
|
||||||
const biomes = Object.keys(Biome).filter(key => isNaN(Number(key)));
|
const biomes = Object.keys(Biome).filter(key => isNaN(Number(key)));
|
||||||
const alwaysPickTheseBiomes = [Biome.ISLAND, Biome.ABYSS, Biome.WASTELAND, Biome.FAIRY_CAVE, Biome.TEMPLE, Biome.LABORATORY, Biome.SPACE, Biome.WASTELAND];
|
const alwaysPickTheseBiomes = [ Biome.ISLAND, Biome.ABYSS, Biome.WASTELAND, Biome.FAIRY_CAVE, Biome.TEMPLE, Biome.LABORATORY, Biome.SPACE, Biome.WASTELAND ];
|
||||||
|
|
||||||
const calculateNumEncounters = (): any[] => {
|
const calculateNumEncounters = (): any[] => {
|
||||||
let encounterRate = baseSpawnWeight; // BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT
|
let encounterRate = baseSpawnWeight; // BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT
|
||||||
const numEncounters = [0, 0, 0, 0];
|
const numEncounters = [ 0, 0, 0, 0 ];
|
||||||
let mostRecentEncounterWave = 0;
|
let mostRecentEncounterWave = 0;
|
||||||
const encountersByBiome = new Map<string, number>(biomes.map(b => [b, 0]));
|
const encountersByBiome = new Map<string, number>(biomes.map(b => [ b, 0 ]));
|
||||||
const validMEfloorsByBiome = new Map<string, number>(biomes.map(b => [b, 0]));
|
const validMEfloorsByBiome = new Map<string, number>(biomes.map(b => [ b, 0 ]));
|
||||||
let currentBiome = Biome.TOWN;
|
let currentBiome = Biome.TOWN;
|
||||||
let currentArena = scene.newArena(currentBiome);
|
let currentArena = scene.newArena(currentBiome);
|
||||||
scene.setSeed(Utils.randomString(24));
|
scene.setSeed(Utils.randomString(24));
|
||||||
@ -968,7 +968,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
|
|
||||||
// Calculate encounter rarity
|
// Calculate encounter rarity
|
||||||
// Common / Uncommon / Rare / Super Rare (base is out of 128)
|
// Common / Uncommon / Rare / Super Rare (base is out of 128)
|
||||||
const tierWeights = [66, 40, 19, 3];
|
const tierWeights = [ 66, 40, 19, 3 ];
|
||||||
|
|
||||||
// Adjust tier weights by currently encountered events (pity system that lowers odds of multiple Common/Great)
|
// Adjust tier weights by currently encountered events (pity system that lowers odds of multiple Common/Great)
|
||||||
tierWeights[0] = tierWeights[0] - 6 * numEncounters[0];
|
tierWeights[0] = tierWeights[0] - 6 * numEncounters[0];
|
||||||
@ -987,7 +987,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [numEncounters, encountersByBiome, validMEfloorsByBiome];
|
return [ numEncounters, encountersByBiome, validMEfloorsByBiome ];
|
||||||
};
|
};
|
||||||
|
|
||||||
const encounterRuns: number[][] = [];
|
const encounterRuns: number[][] = [];
|
||||||
@ -995,7 +995,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
const validFloorsByBiome: Map<string, number>[] = [];
|
const validFloorsByBiome: Map<string, number>[] = [];
|
||||||
while (run < numRuns) {
|
while (run < numRuns) {
|
||||||
scene.executeWithSeedOffset(() => {
|
scene.executeWithSeedOffset(() => {
|
||||||
const [numEncounters, encountersByBiome, validMEfloorsByBiome] = calculateNumEncounters();
|
const [ numEncounters, encountersByBiome, validMEfloorsByBiome ] = calculateNumEncounters();
|
||||||
encounterRuns.push(numEncounters);
|
encounterRuns.push(numEncounters);
|
||||||
encountersByBiomeRuns.push(encountersByBiome);
|
encountersByBiomeRuns.push(encountersByBiome);
|
||||||
validFloorsByBiome.push(validMEfloorsByBiome);
|
validFloorsByBiome.push(validMEfloorsByBiome);
|
||||||
@ -1036,7 +1036,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
|
|
||||||
let stats = `Starting weight: ${baseSpawnWeight}\nAverage MEs per run: ${totalMean}\nStandard Deviation: ${totalStd}\nAvg Commons: ${commonMean}\nAvg Greats: ${uncommonMean}\nAvg Ultras: ${rareMean}\nAvg Rogues: ${superRareMean}\n`;
|
let stats = `Starting weight: ${baseSpawnWeight}\nAverage MEs per run: ${totalMean}\nStandard Deviation: ${totalStd}\nAvg Commons: ${commonMean}\nAvg Greats: ${uncommonMean}\nAvg Ultras: ${rareMean}\nAvg Rogues: ${superRareMean}\n`;
|
||||||
|
|
||||||
const meanEncountersPerRunPerBiomeSorted = [...meanEncountersPerRunPerBiome.entries()].sort((e1, e2) => e2[1] - e1[1]);
|
const meanEncountersPerRunPerBiomeSorted = [ ...meanEncountersPerRunPerBiome.entries() ].sort((e1, e2) => e2[1] - e1[1]);
|
||||||
meanEncountersPerRunPerBiomeSorted.forEach(value => stats = stats + `${value[0]}: avg valid floors ${meanMEFloorsPerRunPerBiome.get(value[0])}, avg MEs ${value[1]},\n`);
|
meanEncountersPerRunPerBiomeSorted.forEach(value => stats = stats + `${value[0]}: avg valid floors ${meanMEFloorsPerRunPerBiome.get(value[0])}, avg MEs ${value[1]},\n`);
|
||||||
|
|
||||||
console.log(stats);
|
console.log(stats);
|
||||||
@ -1054,7 +1054,7 @@ export function calculateRareSpawnAggregateStats(scene: BattleScene, luckValue:
|
|||||||
let run = 0;
|
let run = 0;
|
||||||
|
|
||||||
const calculateNumRareEncounters = (): any[] => {
|
const calculateNumRareEncounters = (): any[] => {
|
||||||
const bossEncountersByRarity = [0, 0, 0, 0];
|
const bossEncountersByRarity = [ 0, 0, 0, 0 ];
|
||||||
scene.setSeed(Utils.randomString(24));
|
scene.setSeed(Utils.randomString(24));
|
||||||
scene.resetSeed();
|
scene.resetSeed();
|
||||||
// There are 12 wild boss floors
|
// There are 12 wild boss floors
|
||||||
|
@ -208,7 +208,7 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu
|
|||||||
let max = Array.isArray(starterTiers) ? starterTiers[1] : starterTiers;
|
let max = Array.isArray(starterTiers) ? starterTiers[1] : starterTiers;
|
||||||
|
|
||||||
let filteredSpecies: [PokemonSpecies, number][] = Object.keys(speciesStarterCosts)
|
let filteredSpecies: [PokemonSpecies, number][] = Object.keys(speciesStarterCosts)
|
||||||
.map(s => [parseInt(s) as Species, speciesStarterCosts[s] as number])
|
.map(s => [ parseInt(s) as Species, speciesStarterCosts[s] as number ])
|
||||||
.filter(s => {
|
.filter(s => {
|
||||||
const pokemonSpecies = getPokemonSpecies(s[0]);
|
const pokemonSpecies = getPokemonSpecies(s[0]);
|
||||||
return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0]))
|
return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0]))
|
||||||
@ -216,7 +216,7 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu
|
|||||||
&& (allowLegendary || !pokemonSpecies.legendary)
|
&& (allowLegendary || !pokemonSpecies.legendary)
|
||||||
&& (allowMythical || !pokemonSpecies.mythical);
|
&& (allowMythical || !pokemonSpecies.mythical);
|
||||||
})
|
})
|
||||||
.map(s => [getPokemonSpecies(s[0]), s[1]]);
|
.map(s => [ getPokemonSpecies(s[0]), s[1] ]);
|
||||||
|
|
||||||
if (types && types.length > 0) {
|
if (types && types.length > 0) {
|
||||||
filteredSpecies = filteredSpecies.filter(s => types.includes(s[0].type1) || (!isNullOrUndefined(s[0].type2) && types.includes(s[0].type2)));
|
filteredSpecies = filteredSpecies.filter(s => types.includes(s[0].type1) || (!isNullOrUndefined(s[0].type2) && types.includes(s[0].type2)));
|
||||||
@ -313,7 +313,7 @@ export function applyHealToPokemon(scene: BattleScene, pokemon: PlayerPokemon, h
|
|||||||
*/
|
*/
|
||||||
export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: number) {
|
export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: number) {
|
||||||
const modType = modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE()
|
const modType = modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE()
|
||||||
.generateType(pokemon.scene.getParty(), [value])
|
.generateType(pokemon.scene.getParty(), [ value ])
|
||||||
?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE);
|
?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE);
|
||||||
const modifier = modType?.newModifier(pokemon);
|
const modifier = modType?.newModifier(pokemon);
|
||||||
if (modifier) {
|
if (modifier) {
|
||||||
@ -602,7 +602,7 @@ export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, po
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Promise.all([pokemon.hideInfo(), scene.gameData.setPokemonCaught(pokemon)]).then(() => {
|
Promise.all([ pokemon.hideInfo(), scene.gameData.setPokemonCaught(pokemon) ]).then(() => {
|
||||||
if (scene.getParty().length === 6) {
|
if (scene.getParty().length === 6) {
|
||||||
const promptRelease = () => {
|
const promptRelease = () => {
|
||||||
scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
|
scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
|
||||||
@ -728,33 +728,33 @@ export function doPlayerFlee(scene: BattleScene, pokemon: EnemyPokemon): Promise
|
|||||||
* Bug Species and their corresponding weights
|
* Bug Species and their corresponding weights
|
||||||
*/
|
*/
|
||||||
const GOLDEN_BUG_NET_SPECIES_POOL: [Species, number][] = [
|
const GOLDEN_BUG_NET_SPECIES_POOL: [Species, number][] = [
|
||||||
[Species.SCYTHER, 40],
|
[ Species.SCYTHER, 40 ],
|
||||||
[Species.SCIZOR, 40],
|
[ Species.SCIZOR, 40 ],
|
||||||
[Species.KLEAVOR, 40],
|
[ Species.KLEAVOR, 40 ],
|
||||||
[Species.PINSIR, 40],
|
[ Species.PINSIR, 40 ],
|
||||||
[Species.HERACROSS, 40],
|
[ Species.HERACROSS, 40 ],
|
||||||
[Species.YANMA, 40],
|
[ Species.YANMA, 40 ],
|
||||||
[Species.YANMEGA, 40],
|
[ Species.YANMEGA, 40 ],
|
||||||
[Species.SHUCKLE, 40],
|
[ Species.SHUCKLE, 40 ],
|
||||||
[Species.ANORITH, 40],
|
[ Species.ANORITH, 40 ],
|
||||||
[Species.ARMALDO, 40],
|
[ Species.ARMALDO, 40 ],
|
||||||
[Species.ESCAVALIER, 40],
|
[ Species.ESCAVALIER, 40 ],
|
||||||
[Species.ACCELGOR, 40],
|
[ Species.ACCELGOR, 40 ],
|
||||||
[Species.JOLTIK, 40],
|
[ Species.JOLTIK, 40 ],
|
||||||
[Species.GALVANTULA, 40],
|
[ Species.GALVANTULA, 40 ],
|
||||||
[Species.DURANT, 40],
|
[ Species.DURANT, 40 ],
|
||||||
[Species.LARVESTA, 40],
|
[ Species.LARVESTA, 40 ],
|
||||||
[Species.VOLCARONA, 40],
|
[ Species.VOLCARONA, 40 ],
|
||||||
[Species.DEWPIDER, 40],
|
[ Species.DEWPIDER, 40 ],
|
||||||
[Species.ARAQUANID, 40],
|
[ Species.ARAQUANID, 40 ],
|
||||||
[Species.WIMPOD, 40],
|
[ Species.WIMPOD, 40 ],
|
||||||
[Species.GOLISOPOD, 40],
|
[ Species.GOLISOPOD, 40 ],
|
||||||
[Species.SIZZLIPEDE, 40],
|
[ Species.SIZZLIPEDE, 40 ],
|
||||||
[Species.CENTISKORCH, 40],
|
[ Species.CENTISKORCH, 40 ],
|
||||||
[Species.NYMBLE, 40],
|
[ Species.NYMBLE, 40 ],
|
||||||
[Species.LOKIX, 40],
|
[ Species.LOKIX, 40 ],
|
||||||
[Species.BUZZWOLE, 1],
|
[ Species.BUZZWOLE, 1 ],
|
||||||
[Species.PHEROMOSA, 1],
|
[ Species.PHEROMOSA, 1 ],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -640,18 +640,18 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.ALTARIA, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALTARIANITE))
|
new SpeciesFormChange(Species.ALTARIA, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALTARIANITE))
|
||||||
],
|
],
|
||||||
[Species.CASTFORM]: [
|
[Species.CASTFORM]: [
|
||||||
new SpeciesFormChange(Species.CASTFORM, "", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.SUNNY, WeatherType.HARSH_SUN]), true),
|
new SpeciesFormChange(Species.CASTFORM, "", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "rainy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.SUNNY, WeatherType.HARSH_SUN]), true),
|
new SpeciesFormChange(Species.CASTFORM, "rainy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "snowy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.SUNNY, WeatherType.HARSH_SUN]), true),
|
new SpeciesFormChange(Species.CASTFORM, "snowy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.RAIN, WeatherType.HEAVY_RAIN]), true),
|
new SpeciesFormChange(Species.CASTFORM, "", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "sunny", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.RAIN, WeatherType.HEAVY_RAIN]), true),
|
new SpeciesFormChange(Species.CASTFORM, "sunny", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "snowy", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.RAIN, WeatherType.HEAVY_RAIN]), true),
|
new SpeciesFormChange(Species.CASTFORM, "snowy", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.HAIL, WeatherType.SNOW]), true),
|
new SpeciesFormChange(Species.CASTFORM, "", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.HAIL, WeatherType.SNOW ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "sunny", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.HAIL, WeatherType.SNOW]), true),
|
new SpeciesFormChange(Species.CASTFORM, "sunny", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.HAIL, WeatherType.SNOW ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "rainy", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.HAIL, WeatherType.SNOW]), true),
|
new SpeciesFormChange(Species.CASTFORM, "rainy", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.HAIL, WeatherType.SNOW ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG]), true),
|
new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG]), true),
|
new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG]), true),
|
new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG ]), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeActiveTrigger(), true),
|
new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeActiveTrigger(), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeActiveTrigger(), true),
|
new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeActiveTrigger(), true),
|
||||||
new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeActiveTrigger(), true)
|
new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeActiveTrigger(), true)
|
||||||
|
@ -484,6 +484,8 @@ export abstract class PokemonSpeciesForm {
|
|||||||
frameRate: 12,
|
frameRate: 12,
|
||||||
repeat: -1
|
repeat: -1
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
scene.anims.get(spriteKey).frameRate = 12;
|
||||||
}
|
}
|
||||||
let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace("variant/", "").replace(/_[1-3]$/, "");
|
let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace("variant/", "").replace(/_[1-3]$/, "");
|
||||||
const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey);
|
const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey);
|
||||||
@ -649,7 +651,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
return i18next.t(`battlePokemonForm:${key}`, {pokemonName: this.name});
|
return i18next.t(`battlePokemonForm:${key}`, { pokemonName: this.name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.name;
|
return this.name;
|
||||||
@ -913,7 +915,7 @@ export class PokemonForm extends PokemonSpeciesForm {
|
|||||||
public formSpriteKey: string | null;
|
public formSpriteKey: string | null;
|
||||||
|
|
||||||
// This is a collection of form keys that have in-run form changes, but should still be separately selectable from the start screen
|
// This is a collection of form keys that have in-run form changes, but should still be separately selectable from the start screen
|
||||||
private starterSelectableKeys: string[] = ["10", "50", "10-pc", "50-pc", "red", "orange", "yellow", "green", "blue", "indigo", "violet"];
|
private starterSelectableKeys: string[] = [ "10", "50", "10-pc", "50-pc", "red", "orange", "yellow", "green", "blue", "indigo", "violet" ];
|
||||||
|
|
||||||
constructor(formName: string, formKey: string, type1: Type, type2: Type | null, height: number, weight: number, ability1: Abilities, ability2: Abilities, abilityHidden: Abilities,
|
constructor(formName: string, formKey: string, type1: Type, type2: Type | null, height: number, weight: number, ability1: Abilities, ability2: Abilities, abilityHidden: Abilities,
|
||||||
baseTotal: integer, baseHp: integer, baseAtk: integer, baseDef: integer, baseSpatk: integer, baseSpdef: integer, baseSpd: integer,
|
baseTotal: integer, baseHp: integer, baseAtk: integer, baseDef: integer, baseSpatk: integer, baseSpdef: integer, baseSpd: integer,
|
||||||
|
@ -185,26 +185,26 @@ const seasonalSplashMessages: Season[] = [
|
|||||||
name: "Halloween",
|
name: "Halloween",
|
||||||
start: "09-15",
|
start: "09-15",
|
||||||
end: "10-31",
|
end: "10-31",
|
||||||
messages: ["halloween.pumpkabooAbout", "halloween.mayContainSpiders", "halloween.spookyScarySkeledirge", "halloween.gourgeistUsedTrickOrTreat", "halloween.letsSnuggleForever"],
|
messages: [ "halloween.pumpkabooAbout", "halloween.mayContainSpiders", "halloween.spookyScarySkeledirge", "halloween.gourgeistUsedTrickOrTreat", "halloween.letsSnuggleForever" ],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "XMAS",
|
name: "XMAS",
|
||||||
start: "12-01",
|
start: "12-01",
|
||||||
end: "12-26",
|
end: "12-26",
|
||||||
messages: ["xmas.happyHolidays", "xmas.unaffilicatedWithDelibirdServices", "xmas.delibirdSeason", "xmas.diamondsFromTheSky", "xmas.holidayStylePikachuNotIncluded"],
|
messages: [ "xmas.happyHolidays", "xmas.unaffilicatedWithDelibirdServices", "xmas.delibirdSeason", "xmas.diamondsFromTheSky", "xmas.holidayStylePikachuNotIncluded" ],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "New Year's",
|
name: "New Year's",
|
||||||
start: "01-01",
|
start: "01-01",
|
||||||
end: "01-31",
|
end: "01-31",
|
||||||
messages: ["newYears.happyNewYear"],
|
messages: [ "newYears.happyNewYear" ],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
export function getSplashMessages(): string[] {
|
export function getSplashMessages(): string[] {
|
||||||
const splashMessages: string[] = [...commonSplashMessages];
|
const splashMessages: string[] = [ ...commonSplashMessages ];
|
||||||
console.log("use seasonal splash messages", USE_SEASONAL_SPLASH_MESSAGES);
|
console.log("use seasonal splash messages", USE_SEASONAL_SPLASH_MESSAGES);
|
||||||
if (USE_SEASONAL_SPLASH_MESSAGES) {
|
if (USE_SEASONAL_SPLASH_MESSAGES) {
|
||||||
// add seasonal splash messages if the season is active
|
// add seasonal splash messages if the season is active
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -75,56 +75,56 @@ const trainerNameConfigs: TrainerNameConfigs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const trainerNamePools = {
|
export const trainerNamePools = {
|
||||||
[TrainerType.ACE_TRAINER]: [["Aaron", "Allen", "Blake", "Brian", "Gaven", "Jake", "Kevin", "Mike", "Nick", "Paul", "Ryan", "Sean", "Darin", "Albert", "Berke", "Clyde", "Edgar", "George", "Leroy", "Owen", "Parker", "Randall", "Ruben", "Samuel", "Vincent", "Warren", "Wilton", "Zane", "Alfred", "Braxton", "Felix", "Gerald", "Jonathan", "Leonel", "Marcel", "Mitchell", "Quincy", "Roderick", "Colby", "Rolando", "Yuji", "Abel", "Anton", "Arthur", "Cesar", "Dalton", "Dennis", "Ernest", "Garrett", "Graham", "Henry", "Isaiah", "Jonah", "Jose", "Keenan", "Micah", "Omar", "Quinn", "Rodolfo", "Saul", "Sergio", "Skylar", "Stefan", "Zachery", "Alton", "Arabella", "Bonita", "Cal", "Cody", "French", "Kobe", "Paulo", "Shaye", "Austin", "Beckett", "Charlie", "Corky", "David", "Dwayne", "Elmer", "Jesse", "Jared", "Johan", "Jordan", "Kipp", "Lou", "Terry", "Tom", "Webster", "Billy", "Doyle", "Enzio", "Geoff", "Grant", "Kelsey", "Miguel", "Pierce", "Ray", "Santino", "Shel", "Adelbert", "Bence", "Emil", "Evan", "Mathis", "Maxim", "Neil", "Rico", "Robbie", "Theo", "Viktor", "Benedict", "Cornelius", "Hisato", "Leopold", "Neville", "Vito", "Chase", "Cole", "Hiroshi", "Jackson", "Jim", "Kekoa", "Makana", "Yuki", "Elwood", "Seth", "Alvin", "Arjun", "Arnold", "Cameron", "Carl", "Carlton", "Christopher", "Dave", "Dax", "Dominic", "Edmund", "Finn", "Fred", "Garret", "Grayson", "Jace", "Jaxson", "Jay", "Jirard", "Johnson", "Kayden", "Kite", "Louis", "Mac", "Marty", "Percy", "Raymond", "Ronnie", "Satch", "Tim", "Zach", "Conner", "Vince", "Bedro", "Boda", "Botan", "Daras", "Dury", "Herton", "Rewn", "Stum", "Tock", "Trilo", "Berki", "Cruik", "Dazon", "Desid", "Dillot", "Farfin", "Forgon", "Hebel", "Morfon", "Moril", "Shadd", "Vanhub", "Bardo", "Carben", "Degin", "Gorps", "Klept", "Lask", "Malex", "Mopar", "Niled", "Noxon", "Teslor", "Tetil"], ["Beth", "Carol", "Cybil", "Emma", "Fran", "Gwen", "Irene", "Jenn", "Joyce", "Kate", "Kelly", "Lois", "Lola", "Megan", "Quinn", "Reena", "Cara", "Alexa", "Brooke", "Caroline", "Elaine", "Hope", "Jennifer", "Jody", "Julie", "Lori", "Mary", "Michelle", "Shannon", "Wendy", "Alexia", "Alicia", "Athena", "Carolina", "Cristin", "Darcy", "Dianne", "Halle", "Jazmyn", "Katelynn", "Keira", "Marley", "Allyson", "Kathleen", "Naomi", "Alyssa", "Ariana", "Brandi", "Breanna", "Brenda", "Brenna", "Catherine", "Clarice", "Dana", "Deanna", "Destiny", "Jamie", "Jasmin", "Kassandra", "Laura", "Maria", "Mariah", "Maya", "Meagan", "Mikayla", "Monique", "Natasha", "Olivia", "Sandra", "Savannah", "Sydney", "Moira", "Piper", "Salma", "Allison", "Beverly", "Cathy", "Cheyenne", "Clara", "Dara", "Eileen", "Glinda", "Junko", "Lena", "Lucille", "Mariana", "Olwen", "Shanta", "Stella", "Angi", "Belle", "Chandra", "Cora", "Eve", "Jacqueline", "Jeanne", "Juliet", "Kathrine", "Layla", "Lucca", "Melina", "Miki", "Nina", "Sable", "Shelly", "Summer", "Trish", "Vicki", "Alanza", "Cordelia", "Hilde", "Imelda", "Michele", "Mireille", "Claudia", "Constance", "Harriet", "Honor", "Melba", "Portia", "Alexis", "Angela", "Karla", "Lindsey", "Tori", "Sheri", "Jada", "Kailee", "Amanda", "Annie", "Kindra", "Kyla", "Sofia", "Yvette", "Becky", "Flora", "Gloria", "Buna", "Ferda", "Lehan", "Liqui", "Lomen", "Neira", "Atilo", "Detta", "Gilly", "Gosney", "Levens", "Moden", "Rask", "Rateis", "Rosno", "Tynan", "Veron", "Zoel", "Cida", "Dibsin", "Dodin", "Ebson", "Equin", "Flostin", "Gabsen", "Halsion", "Hileon", "Quelor", "Rapeel", "Roze", "Tensin"]],
|
[TrainerType.ACE_TRAINER]: [[ "Aaron", "Allen", "Blake", "Brian", "Gaven", "Jake", "Kevin", "Mike", "Nick", "Paul", "Ryan", "Sean", "Darin", "Albert", "Berke", "Clyde", "Edgar", "George", "Leroy", "Owen", "Parker", "Randall", "Ruben", "Samuel", "Vincent", "Warren", "Wilton", "Zane", "Alfred", "Braxton", "Felix", "Gerald", "Jonathan", "Leonel", "Marcel", "Mitchell", "Quincy", "Roderick", "Colby", "Rolando", "Yuji", "Abel", "Anton", "Arthur", "Cesar", "Dalton", "Dennis", "Ernest", "Garrett", "Graham", "Henry", "Isaiah", "Jonah", "Jose", "Keenan", "Micah", "Omar", "Quinn", "Rodolfo", "Saul", "Sergio", "Skylar", "Stefan", "Zachery", "Alton", "Arabella", "Bonita", "Cal", "Cody", "French", "Kobe", "Paulo", "Shaye", "Austin", "Beckett", "Charlie", "Corky", "David", "Dwayne", "Elmer", "Jesse", "Jared", "Johan", "Jordan", "Kipp", "Lou", "Terry", "Tom", "Webster", "Billy", "Doyle", "Enzio", "Geoff", "Grant", "Kelsey", "Miguel", "Pierce", "Ray", "Santino", "Shel", "Adelbert", "Bence", "Emil", "Evan", "Mathis", "Maxim", "Neil", "Rico", "Robbie", "Theo", "Viktor", "Benedict", "Cornelius", "Hisato", "Leopold", "Neville", "Vito", "Chase", "Cole", "Hiroshi", "Jackson", "Jim", "Kekoa", "Makana", "Yuki", "Elwood", "Seth", "Alvin", "Arjun", "Arnold", "Cameron", "Carl", "Carlton", "Christopher", "Dave", "Dax", "Dominic", "Edmund", "Finn", "Fred", "Garret", "Grayson", "Jace", "Jaxson", "Jay", "Jirard", "Johnson", "Kayden", "Kite", "Louis", "Mac", "Marty", "Percy", "Raymond", "Ronnie", "Satch", "Tim", "Zach", "Conner", "Vince", "Bedro", "Boda", "Botan", "Daras", "Dury", "Herton", "Rewn", "Stum", "Tock", "Trilo", "Berki", "Cruik", "Dazon", "Desid", "Dillot", "Farfin", "Forgon", "Hebel", "Morfon", "Moril", "Shadd", "Vanhub", "Bardo", "Carben", "Degin", "Gorps", "Klept", "Lask", "Malex", "Mopar", "Niled", "Noxon", "Teslor", "Tetil" ], [ "Beth", "Carol", "Cybil", "Emma", "Fran", "Gwen", "Irene", "Jenn", "Joyce", "Kate", "Kelly", "Lois", "Lola", "Megan", "Quinn", "Reena", "Cara", "Alexa", "Brooke", "Caroline", "Elaine", "Hope", "Jennifer", "Jody", "Julie", "Lori", "Mary", "Michelle", "Shannon", "Wendy", "Alexia", "Alicia", "Athena", "Carolina", "Cristin", "Darcy", "Dianne", "Halle", "Jazmyn", "Katelynn", "Keira", "Marley", "Allyson", "Kathleen", "Naomi", "Alyssa", "Ariana", "Brandi", "Breanna", "Brenda", "Brenna", "Catherine", "Clarice", "Dana", "Deanna", "Destiny", "Jamie", "Jasmin", "Kassandra", "Laura", "Maria", "Mariah", "Maya", "Meagan", "Mikayla", "Monique", "Natasha", "Olivia", "Sandra", "Savannah", "Sydney", "Moira", "Piper", "Salma", "Allison", "Beverly", "Cathy", "Cheyenne", "Clara", "Dara", "Eileen", "Glinda", "Junko", "Lena", "Lucille", "Mariana", "Olwen", "Shanta", "Stella", "Angi", "Belle", "Chandra", "Cora", "Eve", "Jacqueline", "Jeanne", "Juliet", "Kathrine", "Layla", "Lucca", "Melina", "Miki", "Nina", "Sable", "Shelly", "Summer", "Trish", "Vicki", "Alanza", "Cordelia", "Hilde", "Imelda", "Michele", "Mireille", "Claudia", "Constance", "Harriet", "Honor", "Melba", "Portia", "Alexis", "Angela", "Karla", "Lindsey", "Tori", "Sheri", "Jada", "Kailee", "Amanda", "Annie", "Kindra", "Kyla", "Sofia", "Yvette", "Becky", "Flora", "Gloria", "Buna", "Ferda", "Lehan", "Liqui", "Lomen", "Neira", "Atilo", "Detta", "Gilly", "Gosney", "Levens", "Moden", "Rask", "Rateis", "Rosno", "Tynan", "Veron", "Zoel", "Cida", "Dibsin", "Dodin", "Ebson", "Equin", "Flostin", "Gabsen", "Halsion", "Hileon", "Quelor", "Rapeel", "Roze", "Tensin" ]],
|
||||||
[TrainerType.ARTIST]: [["Ismael", "William", "Horton", "Pierre", "Zach", "Gough", "Salvador", "Vincent", "Duncan"], ["Georgia"]],
|
[TrainerType.ARTIST]: [[ "Ismael", "William", "Horton", "Pierre", "Zach", "Gough", "Salvador", "Vincent", "Duncan" ], [ "Georgia" ]],
|
||||||
[TrainerType.BACKERS]: [["Alf & Fred", "Hawk & Dar", "Joe & Ross", "Les & Web", "Masa & Yas", "Stu & Art"], ["Ai & Ciel", "Ami & Eira", "Cam & Abby", "Fey & Sue", "Kat & Phae", "Kay & Ali", "Ava & Aya", "Cleo & Rio", "May & Mal"]],
|
[TrainerType.BACKERS]: [[ "Alf & Fred", "Hawk & Dar", "Joe & Ross", "Les & Web", "Masa & Yas", "Stu & Art" ], [ "Ai & Ciel", "Ami & Eira", "Cam & Abby", "Fey & Sue", "Kat & Phae", "Kay & Ali", "Ava & Aya", "Cleo & Rio", "May & Mal" ]],
|
||||||
[TrainerType.BACKPACKER]: [["Alexander", "Carlos", "Herman", "Jerome", "Keane", "Kelsey", "Kiyo", "Michael", "Nate", "Peter", "Sam", "Stephen", "Talon", "Terrance", "Toru", "Waylon", "Boone", "Clifford", "Ivan", "Kendall", "Lowell", "Randall", "Reece", "Roland", "Shane", "Walt", "Farid", "Heike", "Joren", "Lane", "Roderick", "Darnell", "Deon", "Emory", "Graeme", "Grayson", "Aitor", "Alex", "Arturo", "Asier", "Jaime", "Jonathan", "Julio", "Kevin", "Kosuke", "Lander", "Markel", "Mateo", "Nil", "Pau", "Samuel"], ["Anna", "Corin", "Elaine", "Emi", "Jill", "Kumiko", "Liz", "Lois", "Lora", "Molly", "Patty", "Ruth", "Vicki", "Annie", "Blossom", "Clara", "Eileen", "Mae", "Myra", "Rachel", "Tami", "Ashley", "Mikiko", "Kiana", "Perdy", "Maria", "Yuho", "Peren", "Barbara", "Diane"]],
|
[TrainerType.BACKPACKER]: [[ "Alexander", "Carlos", "Herman", "Jerome", "Keane", "Kelsey", "Kiyo", "Michael", "Nate", "Peter", "Sam", "Stephen", "Talon", "Terrance", "Toru", "Waylon", "Boone", "Clifford", "Ivan", "Kendall", "Lowell", "Randall", "Reece", "Roland", "Shane", "Walt", "Farid", "Heike", "Joren", "Lane", "Roderick", "Darnell", "Deon", "Emory", "Graeme", "Grayson", "Aitor", "Alex", "Arturo", "Asier", "Jaime", "Jonathan", "Julio", "Kevin", "Kosuke", "Lander", "Markel", "Mateo", "Nil", "Pau", "Samuel" ], [ "Anna", "Corin", "Elaine", "Emi", "Jill", "Kumiko", "Liz", "Lois", "Lora", "Molly", "Patty", "Ruth", "Vicki", "Annie", "Blossom", "Clara", "Eileen", "Mae", "Myra", "Rachel", "Tami", "Ashley", "Mikiko", "Kiana", "Perdy", "Maria", "Yuho", "Peren", "Barbara", "Diane" ]],
|
||||||
[TrainerType.BAKER]: ["Chris", "Jenn", "Lilly"],
|
[TrainerType.BAKER]: [ "Chris", "Jenn", "Lilly" ],
|
||||||
[TrainerType.BEAUTY]: ["Cassie", "Julia", "Olivia", "Samantha", "Valerie", "Victoria", "Bridget", "Connie", "Jessica", "Johanna", "Melissa", "Sheila", "Shirley", "Tiffany", "Namiko", "Thalia", "Grace", "Lola", "Lori", "Maura", "Tamia", "Cyndy", "Devon", "Gabriella", "Harley", "Lindsay", "Nicola", "Callie", "Charlotte", "Kassandra", "December", "Fleming", "Nikola", "Aimee", "Anais", "Brigitte", "Cassandra", "Andrea", "Brittney", "Carolyn", "Krystal", "Alexis", "Alice", "Aina", "Anya", "Arianna", "Aubrey", "Beverly", "Camille", "Beauty", "Evette", "Hansol", "Haruka", "Jill", "Jo", "Lana", "Lois", "Lucy", "Mai", "Nickie", "Nicole", "Prita", "Rose", "Shelly", "Suzy", "Tessa", "Anita", "Alissa", "Rita", "Cudsy", "Eloff", "Miru", "Minot", "Nevah", "Niven", "Ogoin"],
|
[TrainerType.BEAUTY]: [ "Cassie", "Julia", "Olivia", "Samantha", "Valerie", "Victoria", "Bridget", "Connie", "Jessica", "Johanna", "Melissa", "Sheila", "Shirley", "Tiffany", "Namiko", "Thalia", "Grace", "Lola", "Lori", "Maura", "Tamia", "Cyndy", "Devon", "Gabriella", "Harley", "Lindsay", "Nicola", "Callie", "Charlotte", "Kassandra", "December", "Fleming", "Nikola", "Aimee", "Anais", "Brigitte", "Cassandra", "Andrea", "Brittney", "Carolyn", "Krystal", "Alexis", "Alice", "Aina", "Anya", "Arianna", "Aubrey", "Beverly", "Camille", "Beauty", "Evette", "Hansol", "Haruka", "Jill", "Jo", "Lana", "Lois", "Lucy", "Mai", "Nickie", "Nicole", "Prita", "Rose", "Shelly", "Suzy", "Tessa", "Anita", "Alissa", "Rita", "Cudsy", "Eloff", "Miru", "Minot", "Nevah", "Niven", "Ogoin" ],
|
||||||
[TrainerType.BIKER]: ["Charles", "Dwayne", "Glenn", "Harris", "Joel", "Riley", "Zeke", "Alex", "Billy", "Ernest", "Gerald", "Hideo", "Isaac", "Jared", "Jaren", "Jaxon", "Jordy", "Lao", "Lukas", "Malik", "Nikolas", "Ricardo", "Ruben", "Virgil", "William", "Aiden", "Dale", "Dan", "Jacob", "Markey", "Reese", "Teddy", "Theron", "Jeremy", "Morgann", "Phillip", "Philip", "Stanley", "Dillon"],
|
[TrainerType.BIKER]: [ "Charles", "Dwayne", "Glenn", "Harris", "Joel", "Riley", "Zeke", "Alex", "Billy", "Ernest", "Gerald", "Hideo", "Isaac", "Jared", "Jaren", "Jaxon", "Jordy", "Lao", "Lukas", "Malik", "Nikolas", "Ricardo", "Ruben", "Virgil", "William", "Aiden", "Dale", "Dan", "Jacob", "Markey", "Reese", "Teddy", "Theron", "Jeremy", "Morgann", "Phillip", "Philip", "Stanley", "Dillon" ],
|
||||||
[TrainerType.BLACK_BELT]: [["Kenji", "Lao", "Lung", "Nob", "Wai", "Yoshi", "Atsushi", "Daisuke", "Hideki", "Hitoshi", "Kiyo", "Koichi", "Koji", "Yuji", "Cristian", "Rhett", "Takao", "Theodore", "Zander", "Aaron", "Hugh", "Mike", "Nicolas", "Shea", "Takashi", "Adam", "Carl", "Colby", "Darren", "David", "Davon", "Derek", "Eddie", "Gregory", "Griffin", "Jarrett", "Jeffery", "Kendal", "Kyle", "Luke", "Miles", "Nathaniel", "Philip", "Rafael", "Ray", "Ricky", "Sean", "Willie", "Ander", "Manford", "Benjamin", "Corey", "Edward", "Grant", "Jay", "Kendrew", "Kentaro", "Ryder", "Teppei", "Thomas", "Tyrone", "Andrey", "Donny", "Drago", "Gordon", "Grigor", "Jeriel", "Kenneth", "Martell", "Mathis", "Rich", "Rocky", "Rodrigo", "Wesley", "Zachery", "Alonzo", "Cadoc", "Gunnar", "Igor", "Killian", "Markus", "Ricardo", "Yanis", "Banting", "Clayton", "Duane", "Earl", "Greg", "Roy", "Terry", "Tracy", "Walter", "Alvaro", "Curtis", "Francis", "Ross", "Brice", "Cheng", "Dudley", "Eric", "Kano", "Masahiro", "Randy", "Ryuji", "Steve", "Tadashi", "Wong", "Yuen", "Brian", "Carter", "Reece", "Nick", "Yang"], ["Cora", "Cyndy", "Jill", "Laura", "Sadie", "Tessa", "Vivian", "Aisha", "Callie", "Danielle", "Helene", "Jocelyn", "Lilith", "Paula", "Reyna", "Helen", "Kelsey", "Tyler", "Amy", "Chandra", "Hillary", "Janie", "Lee", "Maggie", "Mikiko", "Miriam", "Sharon", "Susie", "Xiao", "Alize", "Azra", "Brenda", "Chalina", "Chan", "Glinda", "Maki", "Tia", "Tiffany", "Wendy", "Andrea", "Gabrielle", "Gerardine", "Hailey", "Hedvig", "Justine", "Kinsey", "Sigrid", "Veronique", "Tess"]],
|
[TrainerType.BLACK_BELT]: [[ "Kenji", "Lao", "Lung", "Nob", "Wai", "Yoshi", "Atsushi", "Daisuke", "Hideki", "Hitoshi", "Kiyo", "Koichi", "Koji", "Yuji", "Cristian", "Rhett", "Takao", "Theodore", "Zander", "Aaron", "Hugh", "Mike", "Nicolas", "Shea", "Takashi", "Adam", "Carl", "Colby", "Darren", "David", "Davon", "Derek", "Eddie", "Gregory", "Griffin", "Jarrett", "Jeffery", "Kendal", "Kyle", "Luke", "Miles", "Nathaniel", "Philip", "Rafael", "Ray", "Ricky", "Sean", "Willie", "Ander", "Manford", "Benjamin", "Corey", "Edward", "Grant", "Jay", "Kendrew", "Kentaro", "Ryder", "Teppei", "Thomas", "Tyrone", "Andrey", "Donny", "Drago", "Gordon", "Grigor", "Jeriel", "Kenneth", "Martell", "Mathis", "Rich", "Rocky", "Rodrigo", "Wesley", "Zachery", "Alonzo", "Cadoc", "Gunnar", "Igor", "Killian", "Markus", "Ricardo", "Yanis", "Banting", "Clayton", "Duane", "Earl", "Greg", "Roy", "Terry", "Tracy", "Walter", "Alvaro", "Curtis", "Francis", "Ross", "Brice", "Cheng", "Dudley", "Eric", "Kano", "Masahiro", "Randy", "Ryuji", "Steve", "Tadashi", "Wong", "Yuen", "Brian", "Carter", "Reece", "Nick", "Yang" ], [ "Cora", "Cyndy", "Jill", "Laura", "Sadie", "Tessa", "Vivian", "Aisha", "Callie", "Danielle", "Helene", "Jocelyn", "Lilith", "Paula", "Reyna", "Helen", "Kelsey", "Tyler", "Amy", "Chandra", "Hillary", "Janie", "Lee", "Maggie", "Mikiko", "Miriam", "Sharon", "Susie", "Xiao", "Alize", "Azra", "Brenda", "Chalina", "Chan", "Glinda", "Maki", "Tia", "Tiffany", "Wendy", "Andrea", "Gabrielle", "Gerardine", "Hailey", "Hedvig", "Justine", "Kinsey", "Sigrid", "Veronique", "Tess" ]],
|
||||||
[TrainerType.BREEDER]: [["Isaac", "Myles", "Salvadore", "Albert", "Kahlil", "Eustace", "Galen", "Owen", "Addison", "Marcus", "Foster", "Cory", "Glenn", "Jay", "Wesley", "William", "Adrian", "Bradley", "Jaime"], ["Allison", "Alize", "Bethany", "Lily", "Lydia", "Gabrielle", "Jayden", "Pat", "Veronica", "Amber", "Jennifer", "Kaylee", "Adelaide", "Brooke", "Ethel", "April", "Irene", "Magnolia", "Amala", "Mercy", "Amanda", "Ikue", "Savannah", "Yuka", "Chloe", "Debra", "Denise", "Elena"]],
|
[TrainerType.BREEDER]: [[ "Isaac", "Myles", "Salvadore", "Albert", "Kahlil", "Eustace", "Galen", "Owen", "Addison", "Marcus", "Foster", "Cory", "Glenn", "Jay", "Wesley", "William", "Adrian", "Bradley", "Jaime" ], [ "Allison", "Alize", "Bethany", "Lily", "Lydia", "Gabrielle", "Jayden", "Pat", "Veronica", "Amber", "Jennifer", "Kaylee", "Adelaide", "Brooke", "Ethel", "April", "Irene", "Magnolia", "Amala", "Mercy", "Amanda", "Ikue", "Savannah", "Yuka", "Chloe", "Debra", "Denise", "Elena" ]],
|
||||||
[TrainerType.CLERK]: [["Chaz", "Clemens", "Doug", "Fredric", "Ivan", "Isaac", "Nelson", "Wade", "Warren", "Augustin", "Gilligan", "Cody", "Jeremy", "Shane", "Dugal", "Royce", "Ronald"], ["Alberta", "Ingrid", "Katie", "Piper", "Trisha", "Wren", "Britney", "Lana", "Jessica", "Kristen", "Michelle", "Gabrielle"]],
|
[TrainerType.CLERK]: [[ "Chaz", "Clemens", "Doug", "Fredric", "Ivan", "Isaac", "Nelson", "Wade", "Warren", "Augustin", "Gilligan", "Cody", "Jeremy", "Shane", "Dugal", "Royce", "Ronald" ], [ "Alberta", "Ingrid", "Katie", "Piper", "Trisha", "Wren", "Britney", "Lana", "Jessica", "Kristen", "Michelle", "Gabrielle" ]],
|
||||||
[TrainerType.CYCLIST]: [["Axel", "James", "John", "Ryan", "Hector", "Jeremiah"], ["Kayla", "Megan", "Nicole", "Rachel", "Krissa", "Adelaide"]],
|
[TrainerType.CYCLIST]: [[ "Axel", "James", "John", "Ryan", "Hector", "Jeremiah" ], [ "Kayla", "Megan", "Nicole", "Rachel", "Krissa", "Adelaide" ]],
|
||||||
[TrainerType.DANCER]: ["Brian", "Davey", "Dirk", "Edmond", "Mickey", "Raymond", "Cara", "Julia", "Maika", "Mireille", "Ronda", "Zoe"],
|
[TrainerType.DANCER]: [ "Brian", "Davey", "Dirk", "Edmond", "Mickey", "Raymond", "Cara", "Julia", "Maika", "Mireille", "Ronda", "Zoe" ],
|
||||||
[TrainerType.DEPOT_AGENT]: ["Josh", "Hank", "Vincent"],
|
[TrainerType.DEPOT_AGENT]: [ "Josh", "Hank", "Vincent" ],
|
||||||
[TrainerType.DOCTOR]: [["Hank", "Jerry", "Jules", "Logan", "Wayne", "Braid", "Derek", "Heath", "Julius", "Kit", "Graham"], ["Kirsten", "Sachiko", "Shery", "Carol", "Dixie", "Mariah"]],
|
[TrainerType.DOCTOR]: [[ "Hank", "Jerry", "Jules", "Logan", "Wayne", "Braid", "Derek", "Heath", "Julius", "Kit", "Graham" ], [ "Kirsten", "Sachiko", "Shery", "Carol", "Dixie", "Mariah" ]],
|
||||||
[TrainerType.FIREBREATHER]: ["Bill", "Burt", "Cliff", "Dick", "Lyle", "Ned", "Otis", "Ray", "Richard", "Walt"],
|
[TrainerType.FIREBREATHER]: [ "Bill", "Burt", "Cliff", "Dick", "Lyle", "Ned", "Otis", "Ray", "Richard", "Walt" ],
|
||||||
[TrainerType.FISHERMAN]: ["Andre", "Arnold", "Barney", "Chris", "Edgar", "Henry", "Jonah", "Justin", "Kyle", "Martin", "Marvin", "Ralph", "Raymond", "Scott", "Stephen", "Wilton", "Tully", "Andrew", "Barny", "Carter", "Claude", "Dale", "Elliot", "Eugene", "Ivan", "Ned", "Nolan", "Roger", "Ronald", "Wade", "Wayne", "Darian", "Kai", "Chip", "Hank", "Kaden", "Tommy", "Tylor", "Alec", "Brett", "Cameron", "Cody", "Cole", "Cory", "Erick", "George", "Joseph", "Juan", "Kenneth", "Luc", "Miguel", "Travis", "Walter", "Zachary", "Josh", "Gideon", "Kyler", "Liam", "Murphy", "Bruce", "Damon", "Devon", "Hubert", "Jones", "Lydon", "Mick", "Pete", "Sean", "Sid", "Vince", "Bucky", "Dean", "Eustace", "Kenzo", "Leroy", "Mack", "Ryder", "Ewan", "Finn", "Murray", "Seward", "Shad", "Wharton", "Finley", "Fisher", "Fisk", "River", "Sheaffer", "Timin", "Carl", "Ernest", "Hal", "Herbert", "Hisato", "Mike", "Vernon", "Harriet", "Marina", "Chase"],
|
[TrainerType.FISHERMAN]: [ "Andre", "Arnold", "Barney", "Chris", "Edgar", "Henry", "Jonah", "Justin", "Kyle", "Martin", "Marvin", "Ralph", "Raymond", "Scott", "Stephen", "Wilton", "Tully", "Andrew", "Barny", "Carter", "Claude", "Dale", "Elliot", "Eugene", "Ivan", "Ned", "Nolan", "Roger", "Ronald", "Wade", "Wayne", "Darian", "Kai", "Chip", "Hank", "Kaden", "Tommy", "Tylor", "Alec", "Brett", "Cameron", "Cody", "Cole", "Cory", "Erick", "George", "Joseph", "Juan", "Kenneth", "Luc", "Miguel", "Travis", "Walter", "Zachary", "Josh", "Gideon", "Kyler", "Liam", "Murphy", "Bruce", "Damon", "Devon", "Hubert", "Jones", "Lydon", "Mick", "Pete", "Sean", "Sid", "Vince", "Bucky", "Dean", "Eustace", "Kenzo", "Leroy", "Mack", "Ryder", "Ewan", "Finn", "Murray", "Seward", "Shad", "Wharton", "Finley", "Fisher", "Fisk", "River", "Sheaffer", "Timin", "Carl", "Ernest", "Hal", "Herbert", "Hisato", "Mike", "Vernon", "Harriet", "Marina", "Chase" ],
|
||||||
[TrainerType.GUITARIST]: ["Anna", "Beverly", "January", "Tina", "Alicia", "Claudia", "Julia", "Lidia", "Mireia", "Noelia", "Sara", "Sheila", "Tatiana"],
|
[TrainerType.GUITARIST]: [ "Anna", "Beverly", "January", "Tina", "Alicia", "Claudia", "Julia", "Lidia", "Mireia", "Noelia", "Sara", "Sheila", "Tatiana" ],
|
||||||
[TrainerType.HARLEQUIN]: ["Charley", "Ian", "Jack", "Kerry", "Louis", "Pat", "Paul", "Rick", "Anders", "Clarence", "Gary"],
|
[TrainerType.HARLEQUIN]: [ "Charley", "Ian", "Jack", "Kerry", "Louis", "Pat", "Paul", "Rick", "Anders", "Clarence", "Gary" ],
|
||||||
[TrainerType.HIKER]: ["Anthony", "Bailey", "Benjamin", "Daniel", "Erik", "Jim", "Kenny", "Leonard", "Michael", "Parry", "Phillip", "Russell", "Sidney", "Tim", "Timothy", "Alan", "Brice", "Clark", "Eric", "Lenny", "Lucas", "Mike", "Trent", "Devan", "Eli", "Marc", "Sawyer", "Allen", "Daryl", "Dudley", "Earl", "Franklin", "Jeremy", "Marcos", "Nob", "Oliver", "Wayne", "Alexander", "Damon", "Jonathan", "Justin", "Kevin", "Lorenzo", "Louis", "Maurice", "Nicholas", "Reginald", "Robert", "Theodore", "Bruce", "Clarke", "Devin", "Dwight", "Edwin", "Eoin", "Noland", "Russel", "Andy", "Bret", "Darrell", "Gene", "Hardy", "Hugh", "Jebediah", "Jeremiah", "Kit", "Neil", "Terrell", "Don", "Doug", "Hunter", "Jared", "Jerome", "Keith", "Manuel", "Markus", "Otto", "Shelby", "Stephen", "Teppei", "Tobias", "Wade", "Zaiem", "Aaron", "Alain", "Bergin", "Bernard", "Brent", "Corwin", "Craig", "Delmon", "Dunstan", "Orestes", "Ross", "Davian", "Calhoun", "David", "Gabriel", "Ryan", "Thomas", "Travis", "Zachary", "Anuhea", "Barnaby", "Claus", "Collin", "Colson", "Dexter", "Dillan", "Eugine", "Farkas", "Hisato", "Julius", "Kenji", "Irwin", "Lionel", "Paul", "Richter", "Valentino", "Donald", "Douglas", "Kevyn", "Chester"], //["Angela","Carla","Celia","Daniela","Estela","Fatima","Helena","Leire","Lucia","Luna","Manuela","Mar","Marina","Miyu","Nancy","Nerea","Paula","Rocio","Yanira"]
|
[TrainerType.HIKER]: [ "Anthony", "Bailey", "Benjamin", "Daniel", "Erik", "Jim", "Kenny", "Leonard", "Michael", "Parry", "Phillip", "Russell", "Sidney", "Tim", "Timothy", "Alan", "Brice", "Clark", "Eric", "Lenny", "Lucas", "Mike", "Trent", "Devan", "Eli", "Marc", "Sawyer", "Allen", "Daryl", "Dudley", "Earl", "Franklin", "Jeremy", "Marcos", "Nob", "Oliver", "Wayne", "Alexander", "Damon", "Jonathan", "Justin", "Kevin", "Lorenzo", "Louis", "Maurice", "Nicholas", "Reginald", "Robert", "Theodore", "Bruce", "Clarke", "Devin", "Dwight", "Edwin", "Eoin", "Noland", "Russel", "Andy", "Bret", "Darrell", "Gene", "Hardy", "Hugh", "Jebediah", "Jeremiah", "Kit", "Neil", "Terrell", "Don", "Doug", "Hunter", "Jared", "Jerome", "Keith", "Manuel", "Markus", "Otto", "Shelby", "Stephen", "Teppei", "Tobias", "Wade", "Zaiem", "Aaron", "Alain", "Bergin", "Bernard", "Brent", "Corwin", "Craig", "Delmon", "Dunstan", "Orestes", "Ross", "Davian", "Calhoun", "David", "Gabriel", "Ryan", "Thomas", "Travis", "Zachary", "Anuhea", "Barnaby", "Claus", "Collin", "Colson", "Dexter", "Dillan", "Eugine", "Farkas", "Hisato", "Julius", "Kenji", "Irwin", "Lionel", "Paul", "Richter", "Valentino", "Donald", "Douglas", "Kevyn", "Chester" ], //["Angela","Carla","Celia","Daniela","Estela","Fatima","Helena","Leire","Lucia","Luna","Manuela","Mar","Marina","Miyu","Nancy","Nerea","Paula","Rocio","Yanira"]
|
||||||
[TrainerType.HOOLIGANS]: ["Jim & Cas", "Rob & Sal"],
|
[TrainerType.HOOLIGANS]: [ "Jim & Cas", "Rob & Sal" ],
|
||||||
[TrainerType.HOOPSTER]: ["Bobby", "John", "Lamarcus", "Derrick", "Nicolas"],
|
[TrainerType.HOOPSTER]: [ "Bobby", "John", "Lamarcus", "Derrick", "Nicolas" ],
|
||||||
[TrainerType.INFIELDER]: ["Alex", "Connor", "Todd"],
|
[TrainerType.INFIELDER]: [ "Alex", "Connor", "Todd" ],
|
||||||
[TrainerType.JANITOR]: ["Caleb", "Geoff", "Brady", "Felix", "Orville", "Melvin", "Shawn"],
|
[TrainerType.JANITOR]: [ "Caleb", "Geoff", "Brady", "Felix", "Orville", "Melvin", "Shawn" ],
|
||||||
[TrainerType.LINEBACKER]: ["Bob", "Dan", "Jonah"],
|
[TrainerType.LINEBACKER]: [ "Bob", "Dan", "Jonah" ],
|
||||||
[TrainerType.MAID]: ["Belinda", "Sophie", "Emily", "Elena", "Clare", "Alica", "Tanya", "Tammy"],
|
[TrainerType.MAID]: [ "Belinda", "Sophie", "Emily", "Elena", "Clare", "Alica", "Tanya", "Tammy" ],
|
||||||
[TrainerType.MUSICIAN]: ["Boris", "Preston", "Charles", "Clyde", "Vincent", "Dalton", "Kirk", "Shawn", "Fabian", "Fernando", "Joseph", "Marcos", "Arturo", "Jerry", "Lonnie", "Tony"],
|
[TrainerType.MUSICIAN]: [ "Boris", "Preston", "Charles", "Clyde", "Vincent", "Dalton", "Kirk", "Shawn", "Fabian", "Fernando", "Joseph", "Marcos", "Arturo", "Jerry", "Lonnie", "Tony" ],
|
||||||
[TrainerType.NURSERY_AIDE]: ["Autumn", "Briana", "Leah", "Miho", "Ethel", "Hollie", "Ilse", "June", "Kimya", "Rosalyn"],
|
[TrainerType.NURSERY_AIDE]: [ "Autumn", "Briana", "Leah", "Miho", "Ethel", "Hollie", "Ilse", "June", "Kimya", "Rosalyn" ],
|
||||||
[TrainerType.OFFICER]: ["Dirk", "Keith", "Alex", "Bobby", "Caleb", "Danny", "Dylan", "Thomas", "Daniel", "Jeff", "Braven", "Dell", "Neagle", "Haruki", "Mitchell", "Raymond"],
|
[TrainerType.OFFICER]: [ "Dirk", "Keith", "Alex", "Bobby", "Caleb", "Danny", "Dylan", "Thomas", "Daniel", "Jeff", "Braven", "Dell", "Neagle", "Haruki", "Mitchell", "Raymond" ],
|
||||||
[TrainerType.PARASOL_LADY]: ["Angelica", "Clarissa", "Madeline", "Akari", "Annabell", "Kayley", "Rachel", "Alexa", "Sabrina", "April", "Gwyneth", "Laura", "Lumi", "Mariah", "Melita", "Nicole", "Tihana", "Ingrid", "Tyra"],
|
[TrainerType.PARASOL_LADY]: [ "Angelica", "Clarissa", "Madeline", "Akari", "Annabell", "Kayley", "Rachel", "Alexa", "Sabrina", "April", "Gwyneth", "Laura", "Lumi", "Mariah", "Melita", "Nicole", "Tihana", "Ingrid", "Tyra" ],
|
||||||
[TrainerType.PILOT]: ["Chase", "Leonard", "Ted", "Elron", "Ewing", "Flynn", "Winslow"],
|
[TrainerType.PILOT]: [ "Chase", "Leonard", "Ted", "Elron", "Ewing", "Flynn", "Winslow" ],
|
||||||
[TrainerType.POKEFAN]: [["Alex", "Allan", "Brandon", "Carter", "Colin", "Derek", "Jeremy", "Joshua", "Rex", "Robert", "Trevor", "William", "Colton", "Miguel", "Francisco", "Kaleb", "Leonard", "Boone", "Elliot", "Jude", "Norbert", "Corey", "Gabe", "Baxter"], ["Beverly", "Georgia", "Jaime", "Ruth", "Isabel", "Marissa", "Vanessa", "Annika", "Bethany", "Kimberly", "Meredith", "Rebekah", "Eleanor", "Darcy", "Lydia", "Sachiko", "Abigail", "Agnes", "Lydie", "Roisin", "Tara", "Carmen", "Janet"]],
|
[TrainerType.POKEFAN]: [[ "Alex", "Allan", "Brandon", "Carter", "Colin", "Derek", "Jeremy", "Joshua", "Rex", "Robert", "Trevor", "William", "Colton", "Miguel", "Francisco", "Kaleb", "Leonard", "Boone", "Elliot", "Jude", "Norbert", "Corey", "Gabe", "Baxter" ], [ "Beverly", "Georgia", "Jaime", "Ruth", "Isabel", "Marissa", "Vanessa", "Annika", "Bethany", "Kimberly", "Meredith", "Rebekah", "Eleanor", "Darcy", "Lydia", "Sachiko", "Abigail", "Agnes", "Lydie", "Roisin", "Tara", "Carmen", "Janet" ]],
|
||||||
[TrainerType.PRESCHOOLER]: [["Billy", "Doyle", "Evan", "Homer", "Tully", "Albert", "Buster", "Greg", "Ike", "Jojo", "Tyrone", "Adrian", "Oliver", "Hayden", "Hunter", "Kaleb", "Liam", "Dylan"], ["Juliet", "Mia", "Sarah", "Wendy", "Winter", "Chrissy", "Eva", "Lin", "Samantha", "Ella", "Lily", "Natalie", "Ailey", "Hannah", "Malia", "Kindra", "Nancy"]],
|
[TrainerType.PRESCHOOLER]: [[ "Billy", "Doyle", "Evan", "Homer", "Tully", "Albert", "Buster", "Greg", "Ike", "Jojo", "Tyrone", "Adrian", "Oliver", "Hayden", "Hunter", "Kaleb", "Liam", "Dylan" ], [ "Juliet", "Mia", "Sarah", "Wendy", "Winter", "Chrissy", "Eva", "Lin", "Samantha", "Ella", "Lily", "Natalie", "Ailey", "Hannah", "Malia", "Kindra", "Nancy" ]],
|
||||||
[TrainerType.PSYCHIC]: [["Fidel", "Franklin", "Gilbert", "Greg", "Herman", "Jared", "Mark", "Nathan", "Norman", "Phil", "Richard", "Rodney", "Cameron", "Edward", "Fritz", "Joshua", "Preston", "Virgil", "William", "Alvaro", "Blake", "Cedric", "Keenan", "Nicholas", "Dario", "Johan", "Lorenzo", "Tyron", "Bryce", "Corbin", "Deandre", "Elijah", "Kody", "Landon", "Maxwell", "Mitchell", "Sterling", "Eli", "Nelson", "Vernon", "Gaven", "Gerard", "Low", "Micki", "Perry", "Rudolf", "Tommy", "Al", "Nandor", "Tully", "Arthur", "Emanuel", "Franz", "Harry", "Paschal", "Robert", "Sayid", "Angelo", "Anton", "Arin", "Avery", "Danny", "Frasier", "Harrison", "Jaime", "Ross", "Rui", "Vlad", "Mason"], ["Alexis", "Hannah", "Jacki", "Jaclyn", "Kayla", "Maura", "Samantha", "Alix", "Brandi", "Edie", "Macey", "Mariella", "Marlene", "Laura", "Rodette", "Abigail", "Brittney", "Chelsey", "Daisy", "Desiree", "Kendra", "Lindsey", "Rachael", "Valencia", "Belle", "Cybil", "Doreen", "Dua", "Future", "Lin", "Madhu", "Alia", "Ena", "Joyce", "Lynette", "Olesia", "Sarah"]],
|
[TrainerType.PSYCHIC]: [[ "Fidel", "Franklin", "Gilbert", "Greg", "Herman", "Jared", "Mark", "Nathan", "Norman", "Phil", "Richard", "Rodney", "Cameron", "Edward", "Fritz", "Joshua", "Preston", "Virgil", "William", "Alvaro", "Blake", "Cedric", "Keenan", "Nicholas", "Dario", "Johan", "Lorenzo", "Tyron", "Bryce", "Corbin", "Deandre", "Elijah", "Kody", "Landon", "Maxwell", "Mitchell", "Sterling", "Eli", "Nelson", "Vernon", "Gaven", "Gerard", "Low", "Micki", "Perry", "Rudolf", "Tommy", "Al", "Nandor", "Tully", "Arthur", "Emanuel", "Franz", "Harry", "Paschal", "Robert", "Sayid", "Angelo", "Anton", "Arin", "Avery", "Danny", "Frasier", "Harrison", "Jaime", "Ross", "Rui", "Vlad", "Mason" ], [ "Alexis", "Hannah", "Jacki", "Jaclyn", "Kayla", "Maura", "Samantha", "Alix", "Brandi", "Edie", "Macey", "Mariella", "Marlene", "Laura", "Rodette", "Abigail", "Brittney", "Chelsey", "Daisy", "Desiree", "Kendra", "Lindsey", "Rachael", "Valencia", "Belle", "Cybil", "Doreen", "Dua", "Future", "Lin", "Madhu", "Alia", "Ena", "Joyce", "Lynette", "Olesia", "Sarah" ]],
|
||||||
[TrainerType.RANGER]: [["Carlos", "Jackson", "Sebastian", "Gav", "Lorenzo", "Logan", "Nicolas", "Trenton", "Deshawn", "Dwayne", "Jeffery", "Kyler", "Taylor", "Alain", "Claude", "Crofton", "Forrest", "Harry", "Jaden", "Keith", "Lewis", "Miguel", "Pedro", "Ralph", "Richard", "Bret", "Daryl", "Eddie", "Johan", "Leaf", "Louis", "Maxwell", "Parker", "Rick", "Steve", "Bjorn", "Chaise", "Dean", "Lee", "Maurice", "Nash", "Ralf", "Reed", "Shinobu", "Silas"], ["Catherine", "Jenna", "Sophia", "Merdith", "Nora", "Beth", "Chelsea", "Katelyn", "Madeline", "Allison", "Ashlee", "Felicia", "Krista", "Annie", "Audra", "Brenda", "Chloris", "Eliza", "Heidi", "Irene", "Mary", "Mylene", "Shanti", "Shelly", "Thalia", "Anja", "Briana", "Dianna", "Elaine", "Elle", "Hillary", "Katie", "Lena", "Lois", "Malory", "Melita", "Mikiko", "Naoko", "Serenity", "Ambre", "Brooke", "Clementine", "Melina", "Petra", "Twiggy"]],
|
[TrainerType.RANGER]: [[ "Carlos", "Jackson", "Sebastian", "Gav", "Lorenzo", "Logan", "Nicolas", "Trenton", "Deshawn", "Dwayne", "Jeffery", "Kyler", "Taylor", "Alain", "Claude", "Crofton", "Forrest", "Harry", "Jaden", "Keith", "Lewis", "Miguel", "Pedro", "Ralph", "Richard", "Bret", "Daryl", "Eddie", "Johan", "Leaf", "Louis", "Maxwell", "Parker", "Rick", "Steve", "Bjorn", "Chaise", "Dean", "Lee", "Maurice", "Nash", "Ralf", "Reed", "Shinobu", "Silas" ], [ "Catherine", "Jenna", "Sophia", "Merdith", "Nora", "Beth", "Chelsea", "Katelyn", "Madeline", "Allison", "Ashlee", "Felicia", "Krista", "Annie", "Audra", "Brenda", "Chloris", "Eliza", "Heidi", "Irene", "Mary", "Mylene", "Shanti", "Shelly", "Thalia", "Anja", "Briana", "Dianna", "Elaine", "Elle", "Hillary", "Katie", "Lena", "Lois", "Malory", "Melita", "Mikiko", "Naoko", "Serenity", "Ambre", "Brooke", "Clementine", "Melina", "Petra", "Twiggy" ]],
|
||||||
[TrainerType.RICH]: [["Alfred", "Edward", "Gregory", "Preston", "Thomas", "Tucker", "Walter", "Clifford", "Everett", "Micah", "Nate", "Pierre", "Terrance", "Arthur", "Brooks", "Emanuel", "Lamar", "Jeremy", "Leonardo", "Milton", "Frederic", "Renaud", "Robert", "Yan", "Daniel", "Sheldon", "Stonewall", "Gerald", "Ronald", "Smith", "Stanley", "Reginald", "Orson", "Wilco", "Caden", "Glenn"], ["Rebecca", "Reina", "Cassandra", "Emilia", "Grace", "Marian", "Elizabeth", "Kathleen", "Sayuri", "Caroline", "Judy"]],
|
[TrainerType.RICH]: [[ "Alfred", "Edward", "Gregory", "Preston", "Thomas", "Tucker", "Walter", "Clifford", "Everett", "Micah", "Nate", "Pierre", "Terrance", "Arthur", "Brooks", "Emanuel", "Lamar", "Jeremy", "Leonardo", "Milton", "Frederic", "Renaud", "Robert", "Yan", "Daniel", "Sheldon", "Stonewall", "Gerald", "Ronald", "Smith", "Stanley", "Reginald", "Orson", "Wilco", "Caden", "Glenn" ], [ "Rebecca", "Reina", "Cassandra", "Emilia", "Grace", "Marian", "Elizabeth", "Kathleen", "Sayuri", "Caroline", "Judy" ]],
|
||||||
[TrainerType.RICH_KID]: [["Garret", "Winston", "Dawson", "Enrique", "Jason", "Roman", "Trey", "Liam", "Anthony", "Brad", "Cody", "Manuel", "Martin", "Pierce", "Rolan", "Keenan", "Filbert", "Antoin", "Cyus", "Diek", "Dugo", "Flitz", "Jurek", "Lond", "Perd", "Quint", "Basto", "Benit", "Brot", "Denc", "Guyit", "Marcon", "Perc", "Puros", "Roex", "Sainz", "Symin", "Tark", "Venak"], ["Anette", "Brianna", "Cindy", "Colleen", "Daphne", "Elizabeth", "Naomi", "Sarah", "Charlotte", "Gillian", "Jacki", "Lady", "Melissa", "Celeste", "Colette", "Elizandra", "Isabel", "Lynette", "Magnolia", "Sophie", "Lina", "Dulcie", "Auro", "Brin", "Caril", "Eloos", "Gwin", "Illa", "Kowly", "Rima", "Ristin", "Vesey", "Brena", "Deasy", "Denslon", "Kylet", "Nemi", "Rene", "Sanol", "Stouner", "Sturk", "Talmen", "Zoila"]],
|
[TrainerType.RICH_KID]: [[ "Garret", "Winston", "Dawson", "Enrique", "Jason", "Roman", "Trey", "Liam", "Anthony", "Brad", "Cody", "Manuel", "Martin", "Pierce", "Rolan", "Keenan", "Filbert", "Antoin", "Cyus", "Diek", "Dugo", "Flitz", "Jurek", "Lond", "Perd", "Quint", "Basto", "Benit", "Brot", "Denc", "Guyit", "Marcon", "Perc", "Puros", "Roex", "Sainz", "Symin", "Tark", "Venak" ], [ "Anette", "Brianna", "Cindy", "Colleen", "Daphne", "Elizabeth", "Naomi", "Sarah", "Charlotte", "Gillian", "Jacki", "Lady", "Melissa", "Celeste", "Colette", "Elizandra", "Isabel", "Lynette", "Magnolia", "Sophie", "Lina", "Dulcie", "Auro", "Brin", "Caril", "Eloos", "Gwin", "Illa", "Kowly", "Rima", "Ristin", "Vesey", "Brena", "Deasy", "Denslon", "Kylet", "Nemi", "Rene", "Sanol", "Stouner", "Sturk", "Talmen", "Zoila" ]],
|
||||||
[TrainerType.ROUGHNECK]: ["Camron", "Corey", "Gabriel", "Isaiah", "Jamal", "Koji", "Luke", "Paxton", "Raul", "Zeek", "Kirby", "Chance", "Dave", "Fletcher", "Johnny", "Reese", "Joey", "Ricky", "Silvester", "Martin"],
|
[TrainerType.ROUGHNECK]: [ "Camron", "Corey", "Gabriel", "Isaiah", "Jamal", "Koji", "Luke", "Paxton", "Raul", "Zeek", "Kirby", "Chance", "Dave", "Fletcher", "Johnny", "Reese", "Joey", "Ricky", "Silvester", "Martin" ],
|
||||||
[TrainerType.SAILOR]: ["Alberto", "Bost", "Brennan", "Brenden", "Claude", "Cory", "Damian", "Dirk", "Duncan", "Dwayne", "Dylan", "Eddie", "Edmond", "Elijah", "Ernest", "Eugene", "Garrett", "Golos", "Gratin", "Grestly", "Harry", "Hols", "Hudson", "Huey", "Jebol", "Jeff", "Leonald", "Luther", "Kelvin", "Kenneth", "Kent", "Knook", "Marc", "Mifis", "Monar", "Morkor", "Ordes", "Oxlin", "Parker", "Paul", "Philip", "Roberto", "Samson", "Skyler", "Stanly", "Tebu", "Terrell", "Trevor", "Yasu", "Zachariah"],
|
[TrainerType.SAILOR]: [ "Alberto", "Bost", "Brennan", "Brenden", "Claude", "Cory", "Damian", "Dirk", "Duncan", "Dwayne", "Dylan", "Eddie", "Edmond", "Elijah", "Ernest", "Eugene", "Garrett", "Golos", "Gratin", "Grestly", "Harry", "Hols", "Hudson", "Huey", "Jebol", "Jeff", "Leonald", "Luther", "Kelvin", "Kenneth", "Kent", "Knook", "Marc", "Mifis", "Monar", "Morkor", "Ordes", "Oxlin", "Parker", "Paul", "Philip", "Roberto", "Samson", "Skyler", "Stanly", "Tebu", "Terrell", "Trevor", "Yasu", "Zachariah" ],
|
||||||
[TrainerType.SCIENTIST]: [["Jed", "Marc", "Mitch", "Rich", "Ross", "Beau", "Braydon", "Connor", "Ed", "Ivan", "Jerry", "Jose", "Joshua", "Parker", "Rodney", "Taylor", "Ted", "Travis", "Zackery", "Darrius", "Emilio", "Fredrick", "Shaun", "Stefano", "Travon", "Daniel", "Garett", "Gregg", "Linden", "Lowell", "Trenton", "Dudley", "Luke", "Markus", "Nathan", "Orville", "Randall", "Ron", "Ronald", "Simon", "Steve", "William", "Franklin", "Clarke", "Jacques", "Terrance", "Ernst", "Justus", "Ikaika", "Jayson", "Kyle", "Reid", "Tyrone", "Adam", "Albert", "Alphonse", "Cory", "Donnie", "Elton", "Francis", "Gordon", "Herbert", "Humphrey", "Jordan", "Julian", "Keaton", "Levi", "Melvin", "Murray", "West", "Craig", "Coren", "Dubik", "Kotan", "Lethco", "Mante", "Mort", "Myron", "Odlow", "Ribek", "Roeck", "Vogi", "Vonder", "Zogo", "Doimo", "Doton", "Durel", "Hildon", "Kukla", "Messa", "Nanot", "Platen", "Raburn", "Reman", "Acrod", "Coffy", "Elrok", "Foss", "Hardig", "Hombol", "Hospel", "Kaller", "Klots", "Krilok", "Limar", "Loket", "Mesak", "Morbit", "Newin", "Orill", "Tabor", "Tekot"], ["Blythe", "Chan", "Kathrine", "Marie", "Maria", "Naoko", "Samantha", "Satomi", "Shannon", "Athena", "Caroline", "Lumi", "Lumina", "Marissa", "Sonia"]],
|
[TrainerType.SCIENTIST]: [[ "Jed", "Marc", "Mitch", "Rich", "Ross", "Beau", "Braydon", "Connor", "Ed", "Ivan", "Jerry", "Jose", "Joshua", "Parker", "Rodney", "Taylor", "Ted", "Travis", "Zackery", "Darrius", "Emilio", "Fredrick", "Shaun", "Stefano", "Travon", "Daniel", "Garett", "Gregg", "Linden", "Lowell", "Trenton", "Dudley", "Luke", "Markus", "Nathan", "Orville", "Randall", "Ron", "Ronald", "Simon", "Steve", "William", "Franklin", "Clarke", "Jacques", "Terrance", "Ernst", "Justus", "Ikaika", "Jayson", "Kyle", "Reid", "Tyrone", "Adam", "Albert", "Alphonse", "Cory", "Donnie", "Elton", "Francis", "Gordon", "Herbert", "Humphrey", "Jordan", "Julian", "Keaton", "Levi", "Melvin", "Murray", "West", "Craig", "Coren", "Dubik", "Kotan", "Lethco", "Mante", "Mort", "Myron", "Odlow", "Ribek", "Roeck", "Vogi", "Vonder", "Zogo", "Doimo", "Doton", "Durel", "Hildon", "Kukla", "Messa", "Nanot", "Platen", "Raburn", "Reman", "Acrod", "Coffy", "Elrok", "Foss", "Hardig", "Hombol", "Hospel", "Kaller", "Klots", "Krilok", "Limar", "Loket", "Mesak", "Morbit", "Newin", "Orill", "Tabor", "Tekot" ], [ "Blythe", "Chan", "Kathrine", "Marie", "Maria", "Naoko", "Samantha", "Satomi", "Shannon", "Athena", "Caroline", "Lumi", "Lumina", "Marissa", "Sonia" ]],
|
||||||
[TrainerType.SMASHER]: ["Aspen", "Elena", "Mari", "Amy", "Lizzy"],
|
[TrainerType.SMASHER]: [ "Aspen", "Elena", "Mari", "Amy", "Lizzy" ],
|
||||||
[TrainerType.SNOW_WORKER]: [["Braden", "Brendon", "Colin", "Conrad", "Dillan", "Gary", "Gerardo", "Holden", "Jackson", "Mason", "Quentin", "Willy", "Noel", "Arnold", "Brady", "Brand", "Cairn", "Cliff", "Don", "Eddie", "Felix", "Filipe", "Glenn", "Gus", "Heath", "Matthew", "Patton", "Rich", "Rob", "Ryan", "Scott", "Shelby", "Sterling", "Tyler", "Victor", "Zack", "Friedrich", "Herman", "Isaac", "Leo", "Maynard", "Mitchell", "Morgann", "Nathan", "Niel", "Pasqual", "Paul", "Tavarius", "Tibor", "Dimitri", "Narek", "Yusif", "Frank", "Jeff", "Vaclav", "Ovid", "Francis", "Keith", "Russel", "Sangon", "Toway", "Bomber", "Chean", "Demit", "Hubor", "Kebile", "Laber", "Ordo", "Retay", "Ronix", "Wagel", "Dobit", "Kaster", "Lobel", "Releo", "Saken", "Rustix"], ["Georgia", "Sandra", "Yvonne"]],
|
[TrainerType.SNOW_WORKER]: [[ "Braden", "Brendon", "Colin", "Conrad", "Dillan", "Gary", "Gerardo", "Holden", "Jackson", "Mason", "Quentin", "Willy", "Noel", "Arnold", "Brady", "Brand", "Cairn", "Cliff", "Don", "Eddie", "Felix", "Filipe", "Glenn", "Gus", "Heath", "Matthew", "Patton", "Rich", "Rob", "Ryan", "Scott", "Shelby", "Sterling", "Tyler", "Victor", "Zack", "Friedrich", "Herman", "Isaac", "Leo", "Maynard", "Mitchell", "Morgann", "Nathan", "Niel", "Pasqual", "Paul", "Tavarius", "Tibor", "Dimitri", "Narek", "Yusif", "Frank", "Jeff", "Vaclav", "Ovid", "Francis", "Keith", "Russel", "Sangon", "Toway", "Bomber", "Chean", "Demit", "Hubor", "Kebile", "Laber", "Ordo", "Retay", "Ronix", "Wagel", "Dobit", "Kaster", "Lobel", "Releo", "Saken", "Rustix" ], [ "Georgia", "Sandra", "Yvonne" ]],
|
||||||
[TrainerType.STRIKER]: ["Marco", "Roberto", "Tony"],
|
[TrainerType.STRIKER]: [ "Marco", "Roberto", "Tony" ],
|
||||||
[TrainerType.SCHOOL_KID]: [["Alan", "Billy", "Chad", "Danny", "Dudley", "Jack", "Joe", "Johnny", "Kipp", "Nate", "Ricky", "Tommy", "Jerry", "Paul", "Ted", "Chance", "Esteban", "Forrest", "Harrison", "Connor", "Sherman", "Torin", "Travis", "Al", "Carter", "Edgar", "Jem", "Sammy", "Shane", "Shayne", "Alvin", "Keston", "Neil", "Seymour", "William", "Carson", "Clark", "Nolan"], ["Georgia", "Karen", "Meiko", "Christine", "Mackenzie", "Tiera", "Ann", "Gina", "Lydia", "Marsha", "Millie", "Sally", "Serena", "Silvia", "Alberta", "Cassie", "Mara", "Rita", "Georgie", "Meena", "Nitzel"]],
|
[TrainerType.SCHOOL_KID]: [[ "Alan", "Billy", "Chad", "Danny", "Dudley", "Jack", "Joe", "Johnny", "Kipp", "Nate", "Ricky", "Tommy", "Jerry", "Paul", "Ted", "Chance", "Esteban", "Forrest", "Harrison", "Connor", "Sherman", "Torin", "Travis", "Al", "Carter", "Edgar", "Jem", "Sammy", "Shane", "Shayne", "Alvin", "Keston", "Neil", "Seymour", "William", "Carson", "Clark", "Nolan" ], [ "Georgia", "Karen", "Meiko", "Christine", "Mackenzie", "Tiera", "Ann", "Gina", "Lydia", "Marsha", "Millie", "Sally", "Serena", "Silvia", "Alberta", "Cassie", "Mara", "Rita", "Georgie", "Meena", "Nitzel" ]],
|
||||||
[TrainerType.SWIMMER]: [["Berke", "Cameron", "Charlie", "George", "Harold", "Jerome", "Kirk", "Mathew", "Parker", "Randall", "Seth", "Simon", "Tucker", "Austin", "Barry", "Chad", "Cody", "Darrin", "David", "Dean", "Douglas", "Franklin", "Gilbert", "Herman", "Jack", "Luis", "Matthew", "Reed", "Richard", "Rodney", "Roland", "Spencer", "Stan", "Tony", "Clarence", "Declan", "Dominik", "Harrison", "Kevin", "Leonardo", "Nolen", "Pete", "Santiago", "Axle", "Braden", "Finn", "Garrett", "Mymo", "Reece", "Samir", "Toby", "Adrian", "Colton", "Dillon", "Erik", "Evan", "Francisco", "Glenn", "Kurt", "Oscar", "Ricardo", "Sam", "Sheltin", "Troy", "Vincent", "Wade", "Wesley", "Duane", "Elmo", "Esteban", "Frankie", "Ronald", "Tyson", "Bart", "Matt", "Tim", "Wright", "Jeffery", "Kyle", "Alessandro", "Estaban", "Kieran", "Ramses", "Casey", "Dakota", "Jared", "Kalani", "Keoni", "Lawrence", "Logan", "Robert", "Roddy", "Yasu", "Derek", "Jacob", "Bruce", "Clayton"], ["Briana", "Dawn", "Denise", "Diana", "Elaine", "Kara", "Kaylee", "Lori", "Nicole", "Nikki", "Paula", "Susie", "Wendy", "Alice", "Beth", "Beverly", "Brenda", "Dana", "Debra", "Grace", "Jenny", "Katie", "Laurel", "Linda", "Missy", "Sharon", "Tanya", "Tara", "Tisha", "Carlee", "Imani", "Isabelle", "Kyla", "Sienna", "Abigail", "Amara", "Anya", "Connie", "Maria", "Melissa", "Nora", "Shirley", "Shania", "Tiffany", "Aubree", "Cassandra", "Claire", "Crystal", "Erica", "Gabrielle", "Haley", "Jessica", "Joanna", "Lydia", "Mallory", "Mary", "Miranda", "Paige", "Sophia", "Vanessa", "Chelan", "Debbie", "Joy", "Kendra", "Leona", "Mina", "Caroline", "Joyce", "Larissa", "Rebecca", "Tyra", "Dara", "Desiree", "Kaoru", "Ruth", "Coral", "Genevieve", "Isla", "Marissa", "Romy", "Sheryl", "Alexandria", "Alicia", "Chelsea", "Jade", "Kelsie", "Laura", "Portia", "Shelby", "Sara", "Tiare", "Kyra", "Natasha", "Layla", "Scarlett", "Cora"]],
|
[TrainerType.SWIMMER]: [[ "Berke", "Cameron", "Charlie", "George", "Harold", "Jerome", "Kirk", "Mathew", "Parker", "Randall", "Seth", "Simon", "Tucker", "Austin", "Barry", "Chad", "Cody", "Darrin", "David", "Dean", "Douglas", "Franklin", "Gilbert", "Herman", "Jack", "Luis", "Matthew", "Reed", "Richard", "Rodney", "Roland", "Spencer", "Stan", "Tony", "Clarence", "Declan", "Dominik", "Harrison", "Kevin", "Leonardo", "Nolen", "Pete", "Santiago", "Axle", "Braden", "Finn", "Garrett", "Mymo", "Reece", "Samir", "Toby", "Adrian", "Colton", "Dillon", "Erik", "Evan", "Francisco", "Glenn", "Kurt", "Oscar", "Ricardo", "Sam", "Sheltin", "Troy", "Vincent", "Wade", "Wesley", "Duane", "Elmo", "Esteban", "Frankie", "Ronald", "Tyson", "Bart", "Matt", "Tim", "Wright", "Jeffery", "Kyle", "Alessandro", "Estaban", "Kieran", "Ramses", "Casey", "Dakota", "Jared", "Kalani", "Keoni", "Lawrence", "Logan", "Robert", "Roddy", "Yasu", "Derek", "Jacob", "Bruce", "Clayton" ], [ "Briana", "Dawn", "Denise", "Diana", "Elaine", "Kara", "Kaylee", "Lori", "Nicole", "Nikki", "Paula", "Susie", "Wendy", "Alice", "Beth", "Beverly", "Brenda", "Dana", "Debra", "Grace", "Jenny", "Katie", "Laurel", "Linda", "Missy", "Sharon", "Tanya", "Tara", "Tisha", "Carlee", "Imani", "Isabelle", "Kyla", "Sienna", "Abigail", "Amara", "Anya", "Connie", "Maria", "Melissa", "Nora", "Shirley", "Shania", "Tiffany", "Aubree", "Cassandra", "Claire", "Crystal", "Erica", "Gabrielle", "Haley", "Jessica", "Joanna", "Lydia", "Mallory", "Mary", "Miranda", "Paige", "Sophia", "Vanessa", "Chelan", "Debbie", "Joy", "Kendra", "Leona", "Mina", "Caroline", "Joyce", "Larissa", "Rebecca", "Tyra", "Dara", "Desiree", "Kaoru", "Ruth", "Coral", "Genevieve", "Isla", "Marissa", "Romy", "Sheryl", "Alexandria", "Alicia", "Chelsea", "Jade", "Kelsie", "Laura", "Portia", "Shelby", "Sara", "Tiare", "Kyra", "Natasha", "Layla", "Scarlett", "Cora" ]],
|
||||||
[TrainerType.TWINS]: ["Amy & May", "Jo & Zoe", "Meg & Peg", "Ann & Anne", "Lea & Pia", "Amy & Liv", "Gina & Mia", "Miu & Yuki", "Tori & Tia", "Eli & Anne", "Jen & Kira", "Joy & Meg", "Kiri & Jan", "Miu & Mia", "Emma & Lil", "Liv & Liz", "Teri & Tia", "Amy & Mimi", "Clea & Gil", "Day & Dani", "Kay & Tia", "Tori & Til", "Saya & Aya", "Emy & Lin", "Kumi & Amy", "Mayo & May", "Ally & Amy", "Lia & Lily", "Rae & Ula", "Sola & Ana", "Tara & Val", "Faith & Joy", "Nana & Nina"],
|
[TrainerType.TWINS]: [ "Amy & May", "Jo & Zoe", "Meg & Peg", "Ann & Anne", "Lea & Pia", "Amy & Liv", "Gina & Mia", "Miu & Yuki", "Tori & Tia", "Eli & Anne", "Jen & Kira", "Joy & Meg", "Kiri & Jan", "Miu & Mia", "Emma & Lil", "Liv & Liz", "Teri & Tia", "Amy & Mimi", "Clea & Gil", "Day & Dani", "Kay & Tia", "Tori & Til", "Saya & Aya", "Emy & Lin", "Kumi & Amy", "Mayo & May", "Ally & Amy", "Lia & Lily", "Rae & Ula", "Sola & Ana", "Tara & Val", "Faith & Joy", "Nana & Nina" ],
|
||||||
[TrainerType.VETERAN]: [["Armando", "Brenden", "Brian", "Clayton", "Edgar", "Emanuel", "Grant", "Harlan", "Terrell", "Arlen", "Chester", "Hugo", "Martell", "Ray", "Shaun", "Abraham", "Carter", "Claude", "Jerry", "Lucius", "Murphy", "Rayne", "Ron", "Sinan", "Sterling", "Vincent", "Zach", "Gerard", "Gilles", "Louis", "Timeo", "Akira", "Don", "Eric", "Harry", "Leon", "Roger", "Angus", "Aristo", "Brone", "Johnny"], ["Julia", "Karla", "Kim", "Sayuri", "Tiffany", "Cathy", "Cecile", "Chloris", "Denae", "Gina", "Maya", "Oriana", "Portia", "Rhona", "Rosaline", "Catrina", "Inga", "Trisha", "Heather", "Lynn", "Sheri", "Alonsa", "Ella", "Leticia", "Kiara"]],
|
[TrainerType.VETERAN]: [[ "Armando", "Brenden", "Brian", "Clayton", "Edgar", "Emanuel", "Grant", "Harlan", "Terrell", "Arlen", "Chester", "Hugo", "Martell", "Ray", "Shaun", "Abraham", "Carter", "Claude", "Jerry", "Lucius", "Murphy", "Rayne", "Ron", "Sinan", "Sterling", "Vincent", "Zach", "Gerard", "Gilles", "Louis", "Timeo", "Akira", "Don", "Eric", "Harry", "Leon", "Roger", "Angus", "Aristo", "Brone", "Johnny" ], [ "Julia", "Karla", "Kim", "Sayuri", "Tiffany", "Cathy", "Cecile", "Chloris", "Denae", "Gina", "Maya", "Oriana", "Portia", "Rhona", "Rosaline", "Catrina", "Inga", "Trisha", "Heather", "Lynn", "Sheri", "Alonsa", "Ella", "Leticia", "Kiara" ]],
|
||||||
[TrainerType.WAITER]: [["Bert", "Clint", "Maxwell", "Lou"], ["Kati", "Aurora", "Bonita", "Flo", "Tia", "Jan", "Olwen", "Paget", "Paula", "Talia"]],
|
[TrainerType.WAITER]: [[ "Bert", "Clint", "Maxwell", "Lou" ], [ "Kati", "Aurora", "Bonita", "Flo", "Tia", "Jan", "Olwen", "Paget", "Paula", "Talia" ]],
|
||||||
[TrainerType.WORKER]: [["Braden", "Brendon", "Colin", "Conrad", "Dillan", "Gary", "Gerardo", "Holden", "Jackson", "Mason", "Quentin", "Willy", "Noel", "Arnold", "Brady", "Brand", "Cairn", "Cliff", "Don", "Eddie", "Felix", "Filipe", "Glenn", "Gus", "Heath", "Matthew", "Patton", "Rich", "Rob", "Ryan", "Scott", "Shelby", "Sterling", "Tyler", "Victor", "Zack", "Friedrich", "Herman", "Isaac", "Leo", "Maynard", "Mitchell", "Morgann", "Nathan", "Niel", "Pasqual", "Paul", "Tavarius", "Tibor", "Dimitri", "Narek", "Yusif", "Frank", "Jeff", "Vaclav", "Ovid", "Francis", "Keith", "Russel", "Sangon", "Toway", "Bomber", "Chean", "Demit", "Hubor", "Kebile", "Laber", "Ordo", "Retay", "Ronix", "Wagel", "Dobit", "Kaster", "Lobel", "Releo", "Saken", "Rustix"], ["Georgia", "Sandra", "Yvonne"]],
|
[TrainerType.WORKER]: [[ "Braden", "Brendon", "Colin", "Conrad", "Dillan", "Gary", "Gerardo", "Holden", "Jackson", "Mason", "Quentin", "Willy", "Noel", "Arnold", "Brady", "Brand", "Cairn", "Cliff", "Don", "Eddie", "Felix", "Filipe", "Glenn", "Gus", "Heath", "Matthew", "Patton", "Rich", "Rob", "Ryan", "Scott", "Shelby", "Sterling", "Tyler", "Victor", "Zack", "Friedrich", "Herman", "Isaac", "Leo", "Maynard", "Mitchell", "Morgann", "Nathan", "Niel", "Pasqual", "Paul", "Tavarius", "Tibor", "Dimitri", "Narek", "Yusif", "Frank", "Jeff", "Vaclav", "Ovid", "Francis", "Keith", "Russel", "Sangon", "Toway", "Bomber", "Chean", "Demit", "Hubor", "Kebile", "Laber", "Ordo", "Retay", "Ronix", "Wagel", "Dobit", "Kaster", "Lobel", "Releo", "Saken", "Rustix" ], [ "Georgia", "Sandra", "Yvonne" ]],
|
||||||
[TrainerType.YOUNGSTER]: [["Albert", "Gordon", "Ian", "Jason", "Jimmy", "Mikey", "Owen", "Samuel", "Warren", "Allen", "Ben", "Billy", "Calvin", "Dillion", "Eddie", "Joey", "Josh", "Neal", "Timmy", "Tommy", "Breyden", "Deandre", "Demetrius", "Dillon", "Jaylen", "Johnson", "Shigenobu", "Chad", "Cole", "Cordell", "Dan", "Dave", "Destin", "Nash", "Tyler", "Yasu", "Austin", "Dallas", "Darius", "Donny", "Jonathon", "Logan", "Michael", "Oliver", "Sebastian", "Tristan", "Wayne", "Norman", "Roland", "Regis", "Abe", "Astor", "Keita", "Kenneth", "Kevin", "Kyle", "Lester", "Masao", "Nicholas", "Parker", "Wes", "Zachary", "Cody", "Henley", "Jaye", "Karl", "Kenny", "Masahiro", "Pedro", "Petey", "Sinclair", "Terrell", "Waylon", "Aidan", "Anthony", "David", "Jacob", "Jayden", "Cutler", "Ham", "Caleb", "Kai", "Honus", "Kenway", "Bret", "Chris", "Cid", "Dennis", "Easton", "Ken", "Robby", "Ronny", "Shawn", "Benjamin", "Jake", "Travis", "Adan", "Aday", "Beltran", "Elian", "Hernan", "Julen", "Luka", "Roi", "Bernie", "Dustin", "Jonathan", "Wyatt"], ["Alice", "Bridget", "Carrie", "Connie", "Dana", "Ellen", "Krise", "Laura", "Linda", "Michelle", "Shannon", "Andrea", "Crissy", "Janice", "Robin", "Sally", "Tiana", "Haley", "Ali", "Ann", "Dalia", "Dawn", "Iris", "Joana", "Julia", "Kay", "Lisa", "Megan", "Mikaela", "Miriam", "Paige", "Reli", "Blythe", "Briana", "Caroline", "Cassidy", "Kaitlin", "Madeline", "Molly", "Natalie", "Samantha", "Sarah", "Cathy", "Dye", "Eri", "Eva", "Fey", "Kara", "Lurleen", "Maki", "Mali", "Maya", "Miki", "Sibyl", "Daya", "Diana", "Flo", "Helia", "Henrietta", "Isabel", "Mai", "Persephone", "Serena", "Anna", "Charlotte", "Elin", "Elsa", "Lise", "Sara", "Suzette", "Audrey", "Emmy", "Isabella", "Madison", "Rika", "Rylee", "Salla", "Ellie", "Alexandra", "Amy", "Lass", "Brittany", "Chel", "Cindy", "Dianne", "Emily", "Emma", "Evelyn", "Hana", "Harleen", "Hazel", "Jocelyn", "Katrina", "Kimberly", "Lina", "Marge", "Mila", "Mizuki", "Rena", "Sal", "Satoko", "Summer", "Tomoe", "Vicky", "Yue", "Yumi", "Lauren", "Rei", "Riley", "Lois", "Nancy", "Tammy", "Terry"]],
|
[TrainerType.YOUNGSTER]: [[ "Albert", "Gordon", "Ian", "Jason", "Jimmy", "Mikey", "Owen", "Samuel", "Warren", "Allen", "Ben", "Billy", "Calvin", "Dillion", "Eddie", "Joey", "Josh", "Neal", "Timmy", "Tommy", "Breyden", "Deandre", "Demetrius", "Dillon", "Jaylen", "Johnson", "Shigenobu", "Chad", "Cole", "Cordell", "Dan", "Dave", "Destin", "Nash", "Tyler", "Yasu", "Austin", "Dallas", "Darius", "Donny", "Jonathon", "Logan", "Michael", "Oliver", "Sebastian", "Tristan", "Wayne", "Norman", "Roland", "Regis", "Abe", "Astor", "Keita", "Kenneth", "Kevin", "Kyle", "Lester", "Masao", "Nicholas", "Parker", "Wes", "Zachary", "Cody", "Henley", "Jaye", "Karl", "Kenny", "Masahiro", "Pedro", "Petey", "Sinclair", "Terrell", "Waylon", "Aidan", "Anthony", "David", "Jacob", "Jayden", "Cutler", "Ham", "Caleb", "Kai", "Honus", "Kenway", "Bret", "Chris", "Cid", "Dennis", "Easton", "Ken", "Robby", "Ronny", "Shawn", "Benjamin", "Jake", "Travis", "Adan", "Aday", "Beltran", "Elian", "Hernan", "Julen", "Luka", "Roi", "Bernie", "Dustin", "Jonathan", "Wyatt" ], [ "Alice", "Bridget", "Carrie", "Connie", "Dana", "Ellen", "Krise", "Laura", "Linda", "Michelle", "Shannon", "Andrea", "Crissy", "Janice", "Robin", "Sally", "Tiana", "Haley", "Ali", "Ann", "Dalia", "Dawn", "Iris", "Joana", "Julia", "Kay", "Lisa", "Megan", "Mikaela", "Miriam", "Paige", "Reli", "Blythe", "Briana", "Caroline", "Cassidy", "Kaitlin", "Madeline", "Molly", "Natalie", "Samantha", "Sarah", "Cathy", "Dye", "Eri", "Eva", "Fey", "Kara", "Lurleen", "Maki", "Mali", "Maya", "Miki", "Sibyl", "Daya", "Diana", "Flo", "Helia", "Henrietta", "Isabel", "Mai", "Persephone", "Serena", "Anna", "Charlotte", "Elin", "Elsa", "Lise", "Sara", "Suzette", "Audrey", "Emmy", "Isabella", "Madison", "Rika", "Rylee", "Salla", "Ellie", "Alexandra", "Amy", "Lass", "Brittany", "Chel", "Cindy", "Dianne", "Emily", "Emma", "Evelyn", "Hana", "Harleen", "Hazel", "Jocelyn", "Katrina", "Kimberly", "Lina", "Marge", "Mila", "Mizuki", "Rena", "Sal", "Satoko", "Summer", "Tomoe", "Vicky", "Yue", "Yumi", "Lauren", "Rei", "Riley", "Lois", "Nancy", "Tammy", "Terry" ]],
|
||||||
[TrainerType.HEX_MANIAC]: ["Kindra", "Patricia", "Tammy", "Tasha", "Valerie", "Alaina", "Kathleen", "Leah", "Makie", "Sylvia", "Anina", "Arachna", "Carrie", "Desdemona", "Josette", "Luna", "Melanie", "Osanna", "Raziah"],
|
[TrainerType.HEX_MANIAC]: [ "Kindra", "Patricia", "Tammy", "Tasha", "Valerie", "Alaina", "Kathleen", "Leah", "Makie", "Sylvia", "Anina", "Arachna", "Carrie", "Desdemona", "Josette", "Luna", "Melanie", "Osanna", "Raziah" ],
|
||||||
};
|
};
|
||||||
|
|
||||||
// function used in a commented code
|
// function used in a commented code
|
||||||
@ -140,7 +140,7 @@ function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNam
|
|||||||
if (!trainerListHeader) {
|
if (!trainerListHeader) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const elements = [...(trainerListHeader?.parentElement?.childNodes ?? [])];
|
const elements = [ ...(trainerListHeader?.parentElement?.childNodes ?? []) ];
|
||||||
const startChildIndex = elements.indexOf(trainerListHeader);
|
const startChildIndex = elements.indexOf(trainerListHeader);
|
||||||
const endChildIndex = elements.findIndex(h => h.nodeName === "H2" && elements.indexOf(h) > startChildIndex);
|
const endChildIndex = elements.findIndex(h => h.nodeName === "H2" && elements.indexOf(h) > startChildIndex);
|
||||||
const tables = elements.filter(t => {
|
const tables = elements.filter(t => {
|
||||||
@ -152,7 +152,7 @@ function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNam
|
|||||||
}).map(t => t as Element);
|
}).map(t => t as Element);
|
||||||
console.log(url, tables);
|
console.log(url, tables);
|
||||||
for (const table of tables) {
|
for (const table of tables) {
|
||||||
const trainerRows = [...table.querySelectorAll("tr:not(:first-child)")].filter(r => r.children.length === 9);
|
const trainerRows = [ ...table.querySelectorAll("tr:not(:first-child)") ].filter(r => r.children.length === 9);
|
||||||
for (const row of trainerRows) {
|
for (const row of trainerRows) {
|
||||||
const nameCell = row.firstElementChild;
|
const nameCell = row.firstElementChild;
|
||||||
if (!nameCell) {
|
if (!nameCell) {
|
||||||
|
@ -171,9 +171,9 @@ export function getWeatherLapseMessage(weatherType: WeatherType): string | null
|
|||||||
export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokemon): string | null {
|
export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokemon): string | null {
|
||||||
switch (weatherType) {
|
switch (weatherType) {
|
||||||
case WeatherType.SANDSTORM:
|
case WeatherType.SANDSTORM:
|
||||||
return i18next.t("weather:sandstormDamageMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)});
|
return i18next.t("weather:sandstormDamageMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
|
||||||
case WeatherType.HAIL:
|
case WeatherType.HAIL:
|
||||||
return i18next.t("weather:hailDamageMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)});
|
return i18next.t("weather:hailDamageMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -238,9 +238,9 @@ export function getTerrainClearMessage(terrainType: TerrainType): string | null
|
|||||||
|
|
||||||
export function getTerrainBlockMessage(pokemon: Pokemon, terrainType: TerrainType): string {
|
export function getTerrainBlockMessage(pokemon: Pokemon, terrainType: TerrainType): string {
|
||||||
if (terrainType === TerrainType.MISTY) {
|
if (terrainType === TerrainType.MISTY) {
|
||||||
return i18next.t("terrain:mistyBlockMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)});
|
return i18next.t("terrain:mistyBlockMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
|
||||||
}
|
}
|
||||||
return i18next.t("terrain:defaultBlockMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), terrainName: getTerrainName(terrainType)});
|
return i18next.t("terrain:defaultBlockMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), terrainName: getTerrainName(terrainType) });
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WeatherPoolEntry {
|
interface WeatherPoolEntry {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum ArenaTagType {
|
export enum ArenaTagType {
|
||||||
NONE = "NONE",
|
NONE = "NONE",
|
||||||
MUD_SPORT = "MUD_SPORT",
|
MUD_SPORT = "MUD_SPORT",
|
||||||
@ -25,5 +24,8 @@ export enum ArenaTagType {
|
|||||||
SAFEGUARD = "SAFEGUARD",
|
SAFEGUARD = "SAFEGUARD",
|
||||||
NO_CRIT = "NO_CRIT",
|
NO_CRIT = "NO_CRIT",
|
||||||
IMPRISON = "IMPRISON",
|
IMPRISON = "IMPRISON",
|
||||||
PLASMA_FISTS = "PLASMA_FISTS",
|
ION_DELUGE = "ION_DELUGE",
|
||||||
|
FIRE_GRASS_PLEDGE = "FIRE_GRASS_PLEDGE",
|
||||||
|
WATER_FIRE_PLEDGE = "WATER_FIRE_PLEDGE",
|
||||||
|
GRASS_WATER_PLEDGE = "GRASS_WATER_PLEDGE",
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum BattlerTagType {
|
export enum BattlerTagType {
|
||||||
NONE = "NONE",
|
NONE = "NONE",
|
||||||
RECHARGING = "RECHARGING",
|
RECHARGING = "RECHARGING",
|
||||||
@ -86,4 +85,5 @@ export enum BattlerTagType {
|
|||||||
TAUNT = "TAUNT",
|
TAUNT = "TAUNT",
|
||||||
IMPRISON = "IMPRISON",
|
IMPRISON = "IMPRISON",
|
||||||
SYRUP_BOMB = "SYRUP_BOMB",
|
SYRUP_BOMB = "SYRUP_BOMB",
|
||||||
|
ELECTRIFIED = "ELECTRIFIED",
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum BerryType {
|
export enum BerryType {
|
||||||
SITRUS,
|
SITRUS,
|
||||||
LUM,
|
LUM,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum Biome {
|
export enum Biome {
|
||||||
TOWN,
|
TOWN,
|
||||||
PLAINS,
|
PLAINS,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export enum TimeOfDay {
|
export enum TimeOfDay {
|
||||||
ALL = -1,
|
ALL = -1,
|
||||||
DAWN,
|
DAWN,
|
||||||
|
@ -392,16 +392,16 @@ export class Arena {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
isMoveWeatherCancelled(user: Pokemon, move: Move) {
|
public isMoveWeatherCancelled(user: Pokemon, move: Move): boolean {
|
||||||
return this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(user, move);
|
return !!this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(user, move);
|
||||||
}
|
}
|
||||||
|
|
||||||
isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move) {
|
public isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move): boolean {
|
||||||
return this.terrain && this.terrain.isMoveTerrainCancelled(user, targets, move);
|
return !!this.terrain && this.terrain.isMoveTerrainCancelled(user, targets, move);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTerrainType() : TerrainType {
|
public getTerrainType(): TerrainType {
|
||||||
return this.terrain?.terrainType || TerrainType.NONE;
|
return this.terrain?.terrainType ?? TerrainType.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAttackTypeMultiplier(attackType: Type, grounded: boolean): number {
|
getAttackTypeMultiplier(attackType: Type, grounded: boolean): number {
|
||||||
|
@ -101,14 +101,14 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
|||||||
const getSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => {
|
const getSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => {
|
||||||
const ret = this.scene.addFieldSprite(0, 0, spriteKey);
|
const ret = this.scene.addFieldSprite(0, 0, spriteKey);
|
||||||
ret.setOrigin(0.5, 1);
|
ret.setOrigin(0.5, 1);
|
||||||
ret.setPipeline(this.scene.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
|
ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getItemSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => {
|
const getItemSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => {
|
||||||
const icon = this.scene.add.sprite(-19, 2, "items", spriteKey);
|
const icon = this.scene.add.sprite(-19, 2, "items", spriteKey);
|
||||||
icon.setOrigin(0.5, 1);
|
icon.setOrigin(0.5, 1);
|
||||||
icon.setPipeline(this.scene.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
|
icon.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
|
||||||
return icon;
|
return icon;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ export default class PokemonSpriteSparkleHandler {
|
|||||||
const ratioY = s.height / height;
|
const ratioY = s.height / height;
|
||||||
const pixel = texture.manager.getPixel(pixelX, pixelY, texture.key, "__BASE");
|
const pixel = texture.manager.getPixel(pixelX, pixelY, texture.key, "__BASE");
|
||||||
if (pixel?.alpha) {
|
if (pixel?.alpha) {
|
||||||
const [ xOffset, yOffset ] = [ -s.originX * s.width, -s.originY * s.height];
|
const [ xOffset, yOffset ] = [ -s.originX * s.width, -s.originY * s.height ];
|
||||||
const sparkle = (s.scene as BattleScene).addFieldSprite(((pokemon?.x || 0) + s.x + pixelX * ratioX + xOffset), ((pokemon?.y || 0) + s.y + pixelY * ratioY + yOffset), "tera_sparkle");
|
const sparkle = (s.scene as BattleScene).addFieldSprite(((pokemon?.x || 0) + s.x + pixelX * ratioX + xOffset), ((pokemon?.y || 0) + s.y + pixelY * ratioY + yOffset), "tera_sparkle");
|
||||||
sparkle.pipelineData["ignoreTimeTint"] = s.pipelineData["ignoreTimeTint"];
|
sparkle.pipelineData["ignoreTimeTint"] = s.pipelineData["ignoreTimeTint"];
|
||||||
sparkle.setName("sprite-tera-sparkle");
|
sparkle.setName("sprite-tera-sparkle");
|
||||||
|
@ -3,7 +3,7 @@ import BattleScene, { AnySound } from "#app/battle-scene";
|
|||||||
import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
|
import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
|
||||||
import { variantData } from "#app/data/variant";
|
import { variantData } from "#app/data/variant";
|
||||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "#app/ui/battle-info";
|
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "#app/ui/battle-info";
|
||||||
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget } from "#app/data/move";
|
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget, CombinedPledgeStabBoostAttr } from "#app/data/move";
|
||||||
import { default as PokemonSpecies, PokemonSpeciesForm, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
import { default as PokemonSpecies, PokemonSpeciesForm, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
||||||
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
|
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import { starterPassiveAbilities } from "#app/data/balance/passives";
|
import { starterPassiveAbilities } from "#app/data/balance/passives";
|
||||||
@ -696,7 +696,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @see {@linkcode getFieldPositionOffset}
|
* @see {@linkcode getFieldPositionOffset}
|
||||||
*/
|
*/
|
||||||
getSubstituteOffset(): [ number, number ] {
|
getSubstituteOffset(): [ number, number ] {
|
||||||
return this.isPlayer() ? [-30, 10] : [30, -10];
|
return this.isPlayer() ? [ -30, 10 ] : [ 30, -10 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -924,11 +924,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Stat.SPD:
|
case Stat.SPD:
|
||||||
// Check both the player and enemy to see if Tailwind should be multiplying the speed of the Pokemon
|
const side = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||||
if ((this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.PLAYER))
|
if (this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, side)) {
|
||||||
|| (!this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.ENEMY))) {
|
|
||||||
ret *= 2;
|
ret *= 2;
|
||||||
}
|
}
|
||||||
|
if (this.scene.arena.getTagOnSide(ArenaTagType.GRASS_WATER_PLEDGE, side)) {
|
||||||
|
ret >>= 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.getTag(BattlerTagType.SLOW_START)) {
|
if (this.getTag(BattlerTagType.SLOW_START)) {
|
||||||
ret >>= 1;
|
ret >>= 1;
|
||||||
@ -1087,6 +1089,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return !!this.fusionSpecies;
|
return !!this.fusionSpecies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the {@linkcode Pokemon} has a fusion with the specified {@linkcode Species}.
|
||||||
|
* @param species the pokemon {@linkcode Species} to check
|
||||||
|
* @returns `true` if the {@linkcode Pokemon} has a fusion with the specified {@linkcode Species}, `false` otherwise
|
||||||
|
*/
|
||||||
|
hasFusionSpecies(species: Species): boolean {
|
||||||
|
return this.fusionSpecies?.speciesId === species;
|
||||||
|
}
|
||||||
|
|
||||||
abstract isBoss(): boolean;
|
abstract isBoss(): boolean;
|
||||||
|
|
||||||
getMoveset(ignoreOverride?: boolean): (PokemonMove | null)[] {
|
getMoveset(ignoreOverride?: boolean): (PokemonMove | null)[] {
|
||||||
@ -1097,7 +1108,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
// Overrides moveset based on arrays specified in overrides.ts
|
// Overrides moveset based on arrays specified in overrides.ts
|
||||||
let overrideArray: Moves | Array<Moves> = this.isPlayer() ? Overrides.MOVESET_OVERRIDE : Overrides.OPP_MOVESET_OVERRIDE;
|
let overrideArray: Moves | Array<Moves> = this.isPlayer() ? Overrides.MOVESET_OVERRIDE : Overrides.OPP_MOVESET_OVERRIDE;
|
||||||
if (!Array.isArray(overrideArray)) {
|
if (!Array.isArray(overrideArray)) {
|
||||||
overrideArray = [overrideArray];
|
overrideArray = [ overrideArray ];
|
||||||
}
|
}
|
||||||
if (overrideArray.length > 0) {
|
if (overrideArray.length > 0) {
|
||||||
if (!this.isPlayer()) {
|
if (!this.isPlayer()) {
|
||||||
@ -1383,10 +1394,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
const suppressed = new Utils.BooleanHolder(false);
|
const suppressed = new Utils.BooleanHolder(false);
|
||||||
this.scene.getField(true).filter(p => p !== this).map(p => {
|
this.scene.getField(true).filter(p => p !== this).map(p => {
|
||||||
if (p.getAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility()) {
|
if (p.getAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility()) {
|
||||||
p.getAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, false, false, suppressed, [ability]));
|
p.getAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, false, false, suppressed, [ ability ]));
|
||||||
}
|
}
|
||||||
if (p.getPassiveAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility(true)) {
|
if (p.getPassiveAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility(true)) {
|
||||||
p.getPassiveAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, true, false, suppressed, [ability]));
|
p.getPassiveAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, true, false, suppressed, [ ability ]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (suppressed.value) {
|
if (suppressed.value) {
|
||||||
@ -1516,13 +1527,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
|
applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
|
||||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder);
|
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder);
|
||||||
|
|
||||||
this.scene.arena.applyTags(ArenaTagType.PLASMA_FISTS, moveTypeHolder);
|
this.scene.arena.applyTags(ArenaTagType.ION_DELUGE, moveTypeHolder);
|
||||||
|
if (this.getTag(BattlerTagType.ELECTRIFIED)) {
|
||||||
|
moveTypeHolder.value = Type.ELECTRIC;
|
||||||
|
}
|
||||||
|
|
||||||
return moveTypeHolder.value as Type;
|
return moveTypeHolder.value as Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the effectiveness of a move against the Pokémon.
|
* Calculates the effectiveness of a move against the Pokémon.
|
||||||
* This includes modifiers from move and ability attributes.
|
* This includes modifiers from move and ability attributes.
|
||||||
@ -1956,7 +1969,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
&& species.speciesId !== this.species.speciesId;
|
&& species.speciesId !== this.species.speciesId;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.fusionSpecies = this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true);
|
let fusionOverride: PokemonSpecies | undefined = undefined;
|
||||||
|
|
||||||
|
if (forStarter && this instanceof PlayerPokemon && Overrides.STARTER_FUSION_SPECIES_OVERRIDE) {
|
||||||
|
fusionOverride = getPokemonSpecies(Overrides.STARTER_FUSION_SPECIES_OVERRIDE);
|
||||||
|
} else if (this instanceof EnemyPokemon && Overrides.OPP_FUSION_SPECIES_OVERRIDE) {
|
||||||
|
fusionOverride = getPokemonSpecies(Overrides.OPP_FUSION_SPECIES_OVERRIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fusionSpecies = fusionOverride ?? this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true);
|
||||||
this.fusionAbilityIndex = (this.fusionSpecies.abilityHidden && hasHiddenAbility ? 2 : this.fusionSpecies.ability2 !== this.fusionSpecies.ability1 ? randAbilityIndex : 0);
|
this.fusionAbilityIndex = (this.fusionSpecies.abilityHidden && hasHiddenAbility ? 2 : this.fusionSpecies.ability2 !== this.fusionSpecies.ability1 ? randAbilityIndex : 0);
|
||||||
this.fusionShiny = this.shiny;
|
this.fusionShiny = this.shiny;
|
||||||
this.fusionVariant = this.variant;
|
this.fusionVariant = this.variant;
|
||||||
@ -2017,7 +2038,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
weight /= 100;
|
weight /= 100;
|
||||||
} // Unimplemented level up moves are possible to generate, but 1% of their normal chance.
|
} // Unimplemented level up moves are possible to generate, but 1% of their normal chance.
|
||||||
if (!movePool.some(m => m[0] === levelMove[1])) {
|
if (!movePool.some(m => m[0] === levelMove[1])) {
|
||||||
movePool.push([levelMove[1], weight]);
|
movePool.push([ levelMove[1], weight ]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2039,11 +2060,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
if (compatible && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
|
if (compatible && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
|
||||||
if (tmPoolTiers[moveId] === ModifierTier.COMMON && this.level >= 15) {
|
if (tmPoolTiers[moveId] === ModifierTier.COMMON && this.level >= 15) {
|
||||||
movePool.push([moveId, 4]);
|
movePool.push([ moveId, 4 ]);
|
||||||
} else if (tmPoolTiers[moveId] === ModifierTier.GREAT && this.level >= 30) {
|
} else if (tmPoolTiers[moveId] === ModifierTier.GREAT && this.level >= 30) {
|
||||||
movePool.push([moveId, 8]);
|
movePool.push([ moveId, 8 ]);
|
||||||
} else if (tmPoolTiers[moveId] === ModifierTier.ULTRA && this.level >= 50) {
|
} else if (tmPoolTiers[moveId] === ModifierTier.ULTRA && this.level >= 50) {
|
||||||
movePool.push([moveId, 14]);
|
movePool.push([ moveId, 14 ]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2052,23 +2073,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
const moveId = speciesEggMoves[this.species.getRootSpeciesId()][i];
|
const moveId = speciesEggMoves[this.species.getRootSpeciesId()][i];
|
||||||
if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
|
if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
|
||||||
movePool.push([moveId, 40]);
|
movePool.push([ moveId, 40 ]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const moveId = speciesEggMoves[this.species.getRootSpeciesId()][3];
|
const moveId = speciesEggMoves[this.species.getRootSpeciesId()][3];
|
||||||
if (this.level >= 170 && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)") && !this.isBoss()) { // No rare egg moves before e4
|
if (this.level >= 170 && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)") && !this.isBoss()) { // No rare egg moves before e4
|
||||||
movePool.push([moveId, 30]);
|
movePool.push([ moveId, 30 ]);
|
||||||
}
|
}
|
||||||
if (this.fusionSpecies) {
|
if (this.fusionSpecies) {
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][i];
|
const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][i];
|
||||||
if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
|
if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
|
||||||
movePool.push([moveId, 40]);
|
movePool.push([ moveId, 40 ]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][3];
|
const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][3];
|
||||||
if (this.level >= 170 && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)") && !this.isBoss()) {// No rare egg moves before e4
|
if (this.level >= 170 && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)") && !this.isBoss()) {// No rare egg moves before e4
|
||||||
movePool.push([moveId, 30]);
|
movePool.push([ moveId, 30 ]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2082,26 +2103,26 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
// Trainers never get OHKO moves
|
// Trainers never get OHKO moves
|
||||||
movePool = movePool.filter(m => !allMoves[m[0]].hasAttr(OneHitKOAttr));
|
movePool = movePool.filter(m => !allMoves[m[0]].hasAttr(OneHitKOAttr));
|
||||||
// Half the weight of self KO moves
|
// Half the weight of self KO moves
|
||||||
movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttr) ? 0.5 : 1)]);
|
movePool = movePool.map(m => [ m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttr) ? 0.5 : 1) ]);
|
||||||
movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttrOnHit) ? 0.5 : 1)]);
|
movePool = movePool.map(m => [ m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttrOnHit) ? 0.5 : 1) ]);
|
||||||
// Trainers get a weight bump to stat buffing moves
|
// Trainers get a weight bump to stat buffing moves
|
||||||
movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].getAttrs(StatStageChangeAttr).some(a => a.stages > 1 && a.selfTarget) ? 1.25 : 1)]);
|
movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].getAttrs(StatStageChangeAttr).some(a => a.stages > 1 && a.selfTarget) ? 1.25 : 1) ]);
|
||||||
// Trainers get a weight decrease to multiturn moves
|
// Trainers get a weight decrease to multiturn moves
|
||||||
movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(ChargeAttr) || !!allMoves[m[0]].hasAttr(RechargeAttr) ? 0.7 : 1)]);
|
movePool = movePool.map(m => [ m[0], m[1] * (!!allMoves[m[0]].hasAttr(ChargeAttr) || !!allMoves[m[0]].hasAttr(RechargeAttr) ? 0.7 : 1) ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Weight towards higher power moves, by reducing the power of moves below the highest power.
|
// Weight towards higher power moves, by reducing the power of moves below the highest power.
|
||||||
// Caps max power at 90 to avoid something like hyper beam ruining the stats.
|
// Caps max power at 90 to avoid something like hyper beam ruining the stats.
|
||||||
// This is a pretty soft weighting factor, although it is scaled with the weight multiplier.
|
// This is a pretty soft weighting factor, although it is scaled with the weight multiplier.
|
||||||
const maxPower = Math.min(movePool.reduce((v, m) => Math.max(allMoves[m[0]].power, v), 40), 90);
|
const maxPower = Math.min(movePool.reduce((v, m) => Math.max(allMoves[m[0]].power, v), 40), 90);
|
||||||
movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power/maxPower, 1), 0.5))]);
|
movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power / maxPower, 1), 0.5)) ]);
|
||||||
|
|
||||||
// Weight damaging moves against the lower stat
|
// Weight damaging moves against the lower stat
|
||||||
const atk = this.getStat(Stat.ATK);
|
const atk = this.getStat(Stat.ATK);
|
||||||
const spAtk = this.getStat(Stat.SPATK);
|
const spAtk = this.getStat(Stat.SPATK);
|
||||||
const worseCategory: MoveCategory = atk > spAtk ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL;
|
const worseCategory: MoveCategory = atk > spAtk ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL;
|
||||||
const statRatio = worseCategory === MoveCategory.PHYSICAL ? atk / spAtk : spAtk / atk;
|
const statRatio = worseCategory === MoveCategory.PHYSICAL ? atk / spAtk : spAtk / atk;
|
||||||
movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === worseCategory ? statRatio : 1)]);
|
movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === worseCategory ? statRatio : 1) ]);
|
||||||
|
|
||||||
let weightMultiplier = 0.9; // The higher this is the more the game weights towards higher level moves. At 0 all moves are equal weight.
|
let weightMultiplier = 0.9; // The higher this is the more the game weights towards higher level moves. At 0 all moves are equal weight.
|
||||||
if (this.hasTrainer()) {
|
if (this.hasTrainer()) {
|
||||||
@ -2110,7 +2131,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
if (this.isBoss()) {
|
if (this.isBoss()) {
|
||||||
weightMultiplier += 0.4;
|
weightMultiplier += 0.4;
|
||||||
}
|
}
|
||||||
const baseWeights: [Moves, number][] = movePool.map(m => [m[0], Math.ceil(Math.pow(m[1], weightMultiplier)*100)]);
|
const baseWeights: [Moves, number][] = movePool.map(m => [ m[0], Math.ceil(Math.pow(m[1], weightMultiplier) * 100) ]);
|
||||||
|
|
||||||
if (this.hasTrainer() || this.isBoss()) { // Trainers and bosses always force a stab move
|
if (this.hasTrainer() || this.isBoss()) { // Trainers and bosses always force a stab move
|
||||||
const stabMovePool = baseWeights.filter(m => allMoves[m[0]].category !== MoveCategory.STATUS && this.isOfType(allMoves[m[0]].type));
|
const stabMovePool = baseWeights.filter(m => allMoves[m[0]].category !== MoveCategory.STATUS && this.isOfType(allMoves[m[0]].type));
|
||||||
@ -2142,7 +2163,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
// Sqrt the weight of any damaging moves with overlapping types. This is about a 0.05 - 0.1 multiplier.
|
// Sqrt the weight of any damaging moves with overlapping types. This is about a 0.05 - 0.1 multiplier.
|
||||||
// Other damaging moves 2x weight if 0-1 damaging moves, 0.5x if 2, 0.125x if 3. These weights double if STAB.
|
// Other damaging moves 2x weight if 0-1 damaging moves, 0.5x if 2, 0.125x if 3. These weights double if STAB.
|
||||||
// Status moves remain unchanged on weight, this encourages 1-2
|
// Status moves remain unchanged on weight, this encourages 1-2
|
||||||
movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId)).map(m => [m[0], this.moveset.some(mo => mo?.getMove().category !== MoveCategory.STATUS && mo?.getMove().type === allMoves[m[0]].type) ? Math.ceil(Math.sqrt(m[1])) : allMoves[m[0]].category !== MoveCategory.STATUS ? Math.ceil(m[1]/Math.max(Math.pow(4, this.moveset.filter(mo => (mo?.getMove().power!) > 1).length)/8, 0.5) * (this.isOfType(allMoves[m[0]].type) ? 2 : 1)) : m[1]]); // TODO: is this bang correct?
|
movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId)).map(m => [ m[0], this.moveset.some(mo => mo?.getMove().category !== MoveCategory.STATUS && mo?.getMove().type === allMoves[m[0]].type) ? Math.ceil(Math.sqrt(m[1])) : allMoves[m[0]].category !== MoveCategory.STATUS ? Math.ceil(m[1] / Math.max(Math.pow(4, this.moveset.filter(mo => (mo?.getMove().power!) > 1).length) / 8, 0.5) * (this.isOfType(allMoves[m[0]].type) ? 2 : 1)) : m[1] ]); // TODO: is this bang correct?
|
||||||
} else { // Non-trainer pokemon just use normal weights
|
} else { // Non-trainer pokemon just use normal weights
|
||||||
movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId));
|
movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId));
|
||||||
}
|
}
|
||||||
@ -2546,6 +2567,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
if (matchesSourceType) {
|
if (matchesSourceType) {
|
||||||
stabMultiplier.value += 0.5;
|
stabMultiplier.value += 0.5;
|
||||||
}
|
}
|
||||||
|
applyMoveAttrs(CombinedPledgeStabBoostAttr, source, this, move, stabMultiplier);
|
||||||
if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === moveType) {
|
if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === moveType) {
|
||||||
stabMultiplier.value += 0.5;
|
stabMultiplier.value += 0.5;
|
||||||
}
|
}
|
||||||
@ -2680,7 +2702,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
if (critOnly.value || critAlways) {
|
if (critOnly.value || critAlways) {
|
||||||
isCritical = true;
|
isCritical = true;
|
||||||
} else {
|
} else {
|
||||||
const critChance = [24, 8, 2, 1][Math.max(0, Math.min(this.getCritStage(source, move), 3))];
|
const critChance = [ 24, 8, 2, 1 ][Math.max(0, Math.min(this.getCritStage(source, move), 3))];
|
||||||
isCritical = critChance === 1 || !this.scene.randBattleSeedInt(critChance);
|
isCritical = critChance === 1 || !this.scene.randBattleSeedInt(critChance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2865,7 +2887,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isMax(): boolean {
|
isMax(): boolean {
|
||||||
const maxForms = [SpeciesFormKey.GIGANTAMAX, SpeciesFormKey.GIGANTAMAX_RAPID, SpeciesFormKey.GIGANTAMAX_SINGLE, SpeciesFormKey.ETERNAMAX] as string[];
|
const maxForms = [ SpeciesFormKey.GIGANTAMAX, SpeciesFormKey.GIGANTAMAX_RAPID, SpeciesFormKey.GIGANTAMAX_SINGLE, SpeciesFormKey.ETERNAMAX ] as string[];
|
||||||
return maxForms.includes(this.getFormKey()) || (!!this.getFusionFormKey() && maxForms.includes(this.getFusionFormKey()!));
|
return maxForms.includes(this.getFormKey()) || (!!this.getFusionFormKey() && maxForms.includes(this.getFusionFormKey()!));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3353,7 +3375,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case StatusEffect.FREEZE:
|
case StatusEffect.FREEZE:
|
||||||
if (this.isOfType(Type.ICE) || (this.scene?.arena?.weather?.weatherType &&[WeatherType.SUNNY, WeatherType.HARSH_SUN].includes(this.scene.arena.weather.weatherType))) {
|
if (this.isOfType(Type.ICE) || (this.scene?.arena?.weather?.weatherType && [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(this.scene.arena.weather.weatherType))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3646,7 +3668,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
const pixel = pixelData[f].slice(i, i + 4);
|
const pixel = pixelData[f].slice(i, i + 4);
|
||||||
let [ r, g, b, a ] = pixel;
|
let [ r, g, b, a ] = pixel;
|
||||||
if (variantColors) {
|
if (variantColors) {
|
||||||
const color = Utils.rgbaToInt([r, g, b, a]);
|
const color = Utils.rgbaToInt([ r, g, b, a ]);
|
||||||
if (variantColorSet.has(color)) {
|
if (variantColorSet.has(color)) {
|
||||||
const mappedPixel = variantColorSet.get(color);
|
const mappedPixel = variantColorSet.get(color);
|
||||||
if (mappedPixel) {
|
if (mappedPixel) {
|
||||||
@ -3690,7 +3712,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
let [ r, g, b, a ] = [ pixelData[2 + f][i], pixelData[2 + f][i + 1], pixelData[2 + f][i + 2], pixelData[2 + f][i + 3] ];
|
let [ r, g, b, a ] = [ pixelData[2 + f][i], pixelData[2 + f][i + 1], pixelData[2 + f][i + 2], pixelData[2 + f][i + 3] ];
|
||||||
if (variantColors) {
|
if (variantColors) {
|
||||||
const color = Utils.rgbaToInt([r, g, b, a]);
|
const color = Utils.rgbaToInt([ r, g, b, a ]);
|
||||||
if (variantColorSet.has(color)) {
|
if (variantColorSet.has(color)) {
|
||||||
const mappedPixel = variantColorSet.get(color);
|
const mappedPixel = variantColorSet.get(color);
|
||||||
if (mappedPixel) {
|
if (mappedPixel) {
|
||||||
@ -3985,7 +4007,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
let compatible = false;
|
let compatible = false;
|
||||||
for (const p of tmSpecies[tm]) {
|
for (const p of tmSpecies[tm]) {
|
||||||
if (Array.isArray(p)) {
|
if (Array.isArray(p)) {
|
||||||
const [pkm, form] = p;
|
const [ pkm, form ] = p;
|
||||||
if ((pkm === this.species.speciesId || this.fusionSpecies && pkm === this.fusionSpecies.speciesId) && form === this.getFormKey()) {
|
if ((pkm === this.species.speciesId || this.fusionSpecies && pkm === this.fusionSpecies.speciesId) && form === this.getFormKey()) {
|
||||||
compatible = true;
|
compatible = true;
|
||||||
break;
|
break;
|
||||||
@ -4074,7 +4096,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
revivalBlessing(): Promise<void> {
|
revivalBlessing(): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
this.scene.ui.setMode(Mode.PARTY, PartyUiMode.REVIVAL_BLESSING, this.getFieldIndex(), (slotIndex:integer, option: PartyOption) => {
|
this.scene.ui.setMode(Mode.PARTY, PartyUiMode.REVIVAL_BLESSING, this.getFieldIndex(), (slotIndex:integer, option: PartyOption) => {
|
||||||
if (slotIndex >= 0 && slotIndex<6) {
|
if (slotIndex >= 0 && slotIndex < 6) {
|
||||||
const pokemon = this.scene.getParty()[slotIndex];
|
const pokemon = this.scene.getParty()[slotIndex];
|
||||||
if (!pokemon || !pokemon.isFainted()) {
|
if (!pokemon || !pokemon.isFainted()) {
|
||||||
resolve();
|
resolve();
|
||||||
@ -4083,11 +4105,11 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
pokemon.resetTurnData();
|
pokemon.resetTurnData();
|
||||||
pokemon.resetStatus();
|
pokemon.resetStatus();
|
||||||
pokemon.heal(Math.min(Utils.toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
|
pokemon.heal(Math.min(Utils.toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
|
||||||
this.scene.queueMessage(i18next.t("moveTriggers:revivalBlessing", {pokemonName: pokemon.name}), 0, true);
|
this.scene.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: pokemon.name }), 0, true);
|
||||||
|
|
||||||
if (this.scene.currentBattle.double && this.scene.getParty().length > 1) {
|
if (this.scene.currentBattle.double && this.scene.getParty().length > 1) {
|
||||||
const allyPokemon = this.getAlly();
|
const allyPokemon = this.getAlly();
|
||||||
if (slotIndex<=1) {
|
if (slotIndex <= 1) {
|
||||||
// Revived ally pokemon
|
// Revived ally pokemon
|
||||||
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, SwitchType.SWITCH, pokemon.getFieldIndex(), slotIndex, false, true));
|
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, SwitchType.SWITCH, pokemon.getFieldIndex(), slotIndex, false, true));
|
||||||
this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true));
|
this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true));
|
||||||
@ -4154,7 +4176,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
if (!isFusion) {
|
if (!isFusion) {
|
||||||
const abilityCount = this.getSpeciesForm().getAbilityCount();
|
const abilityCount = this.getSpeciesForm().getAbilityCount();
|
||||||
const preEvoAbilityCount = preEvolution.getAbilityCount();
|
const preEvoAbilityCount = preEvolution.getAbilityCount();
|
||||||
if ([0, 1, 2].includes(this.abilityIndex)) {
|
if ([ 0, 1, 2 ].includes(this.abilityIndex)) {
|
||||||
// Handles cases where a Pokemon with 3 abilities evolves into a Pokemon with 2 abilities (ie: Eevee -> any Eeveelution)
|
// Handles cases where a Pokemon with 3 abilities evolves into a Pokemon with 2 abilities (ie: Eevee -> any Eeveelution)
|
||||||
if (this.abilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) {
|
if (this.abilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) {
|
||||||
this.abilityIndex = 1;
|
this.abilityIndex = 1;
|
||||||
@ -4167,7 +4189,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
} else { // Do the same as above, but for fusions
|
} else { // Do the same as above, but for fusions
|
||||||
const abilityCount = this.getFusionSpeciesForm().getAbilityCount();
|
const abilityCount = this.getFusionSpeciesForm().getAbilityCount();
|
||||||
const preEvoAbilityCount = preEvolution.getAbilityCount();
|
const preEvoAbilityCount = preEvolution.getAbilityCount();
|
||||||
if ([0, 1, 2].includes(this.fusionAbilityIndex)) {
|
if ([ 0, 1, 2 ].includes(this.fusionAbilityIndex)) {
|
||||||
if (this.fusionAbilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) {
|
if (this.fusionAbilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) {
|
||||||
this.fusionAbilityIndex = 1;
|
this.fusionAbilityIndex = 1;
|
||||||
}
|
}
|
||||||
@ -4558,7 +4580,7 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
|
|
||||||
return move.category !== MoveCategory.STATUS
|
return move.category !== MoveCategory.STATUS
|
||||||
&& moveTargets.some(p => {
|
&& moveTargets.some(p => {
|
||||||
const doesNotFail = move.applyConditions(this, p, move) || [Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id);
|
const doesNotFail = move.applyConditions(this, p, move) || [ Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP ].includes(move.id);
|
||||||
return doesNotFail && p.getAttackDamage(this, move, !p.battleData.abilityRevealed, false, isCritical).damage >= p.hp;
|
return doesNotFail && p.getAttackDamage(this, move, !p.battleData.abilityRevealed, false, isCritical).damage >= p.hp;
|
||||||
});
|
});
|
||||||
}, this);
|
}, this);
|
||||||
@ -4601,7 +4623,7 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
* If this move is unimplemented, or the move is known to fail when used, set its
|
* If this move is unimplemented, or the move is known to fail when used, set its
|
||||||
* target score to -20
|
* target score to -20
|
||||||
*/
|
*/
|
||||||
if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id)) {
|
if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![ Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP ].includes(move.id)) {
|
||||||
targetScore = -20;
|
targetScore = -20;
|
||||||
} else if (move instanceof AttackMove) {
|
} else if (move instanceof AttackMove) {
|
||||||
/**
|
/**
|
||||||
@ -4697,7 +4719,7 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
// Set target to BattlerIndex.ATTACKER when using a counter move
|
// Set target to BattlerIndex.ATTACKER when using a counter move
|
||||||
// This is the same as when the player does so
|
// This is the same as when the player does so
|
||||||
if (move.hasAttr(CounterDamageAttr)) {
|
if (move.hasAttr(CounterDamageAttr)) {
|
||||||
return [BattlerIndex.ATTACKER];
|
return [ BattlerIndex.ATTACKER ];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
@ -5011,8 +5033,12 @@ export class PokemonBattleSummonData {
|
|||||||
export class PokemonTurnData {
|
export class PokemonTurnData {
|
||||||
public flinched: boolean = false;
|
public flinched: boolean = false;
|
||||||
public acted: boolean = false;
|
public acted: boolean = false;
|
||||||
public hitCount: number;
|
public hitCount: number = 0;
|
||||||
public hitsLeft: number;
|
/**
|
||||||
|
* - `-1` = Calculate how many hits are left
|
||||||
|
* - `0` = Move is finished
|
||||||
|
*/
|
||||||
|
public hitsLeft: number = -1;
|
||||||
public damageDealt: number = 0;
|
public damageDealt: number = 0;
|
||||||
public currDamageDealt: number = 0;
|
public currDamageDealt: number = 0;
|
||||||
public damageTaken: number = 0;
|
public damageTaken: number = 0;
|
||||||
@ -5021,6 +5047,7 @@ export class PokemonTurnData {
|
|||||||
public statStagesIncreased: boolean = false;
|
public statStagesIncreased: boolean = false;
|
||||||
public statStagesDecreased: boolean = false;
|
public statStagesDecreased: boolean = false;
|
||||||
public moveEffectiveness: TypeDamageMultiplier | null = null;
|
public moveEffectiveness: TypeDamageMultiplier | null = null;
|
||||||
|
public combiningPledge?: Moves;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AiType {
|
export enum AiType {
|
||||||
@ -5098,7 +5125,7 @@ export class PokemonMove {
|
|||||||
* @param {boolean} ignoreRestrictionTags If `true`, skips the check for move restriction tags (see {@link MoveRestrictionBattlerTag})
|
* @param {boolean} ignoreRestrictionTags If `true`, skips the check for move restriction tags (see {@link MoveRestrictionBattlerTag})
|
||||||
* @returns `true` if the move can be selected and used by the Pokemon, otherwise `false`.
|
* @returns `true` if the move can be selected and used by the Pokemon, otherwise `false`.
|
||||||
*/
|
*/
|
||||||
isUsable(pokemon: Pokemon, ignorePp?: boolean, ignoreRestrictionTags?: boolean): boolean {
|
isUsable(pokemon: Pokemon, ignorePp: boolean = false, ignoreRestrictionTags: boolean = false): boolean {
|
||||||
if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId)) {
|
if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import {pokemonPrevolutions} from "#app/data/balance/pokemon-evolutions";
|
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import PokemonSpecies, {getPokemonSpecies} from "#app/data/pokemon-species";
|
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import {
|
import {
|
||||||
TrainerConfig,
|
TrainerConfig,
|
||||||
TrainerPartyCompoundTemplate,
|
TrainerPartyCompoundTemplate,
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
trainerPartyTemplates,
|
trainerPartyTemplates,
|
||||||
signatureSpecies
|
signatureSpecies
|
||||||
} from "#app/data/trainer-config";
|
} from "#app/data/trainer-config";
|
||||||
import {EnemyPokemon} from "#app/field/pokemon";
|
import { EnemyPokemon } from "#app/field/pokemon";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import { PersistentModifier } from "#app/modifier/modifier";
|
import { PersistentModifier } from "#app/modifier/modifier";
|
||||||
import { trainerNamePools } from "#app/data/trainer-names";
|
import { trainerNamePools } from "#app/data/trainer-names";
|
||||||
@ -56,7 +56,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
if (partnerName) {
|
if (partnerName) {
|
||||||
this.partnerName = partnerName;
|
this.partnerName = partnerName;
|
||||||
} else {
|
} else {
|
||||||
[this.name, this.partnerName] = this.name.split(" & ");
|
[ this.name, this.partnerName ] = this.name.split(" & ");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool);
|
this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool);
|
||||||
@ -82,7 +82,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
const getSprite = (hasShadow?: boolean, forceFemale?: boolean) => {
|
const getSprite = (hasShadow?: boolean, forceFemale?: boolean) => {
|
||||||
const ret = this.scene.addFieldSprite(0, 0, this.config.getSpriteKey(variant === TrainerVariant.FEMALE || forceFemale, this.isDouble()));
|
const ret = this.scene.addFieldSprite(0, 0, this.config.getSpriteKey(variant === TrainerVariant.FEMALE || forceFemale, this.isDouble()));
|
||||||
ret.setOrigin(0.5, 1);
|
ret.setOrigin(0.5, 1);
|
||||||
ret.setPipeline(this.scene.spritePipeline, {tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow});
|
ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow });
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
// Determine the title to include based on the configuration and includeTitle flag.
|
// Determine the title to include based on the configuration and includeTitle flag.
|
||||||
let title = includeTitle && this.config.title ? this.config.title : null;
|
let title = includeTitle && this.config.title ? this.config.title : null;
|
||||||
const evilTeamTitles = ["grunt"];
|
const evilTeamTitles = [ "grunt" ];
|
||||||
if (this.name === "" && evilTeamTitles.some(t => name.toLocaleLowerCase().includes(t))) {
|
if (this.name === "" && evilTeamTitles.some(t => name.toLocaleLowerCase().includes(t))) {
|
||||||
// This is a evil team grunt so we localize it by only using the "name" as the title
|
// This is a evil team grunt so we localize it by only using the "name" as the title
|
||||||
title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`);
|
title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`);
|
||||||
@ -336,9 +336,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
if (!(index % 2)) {
|
if (!(index % 2)) {
|
||||||
// Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza
|
// Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza
|
||||||
if (index === 0 && (TrainerType[this.config.trainerType] === TrainerType[TrainerType.TATE])) {
|
if (index === 0 && (TrainerType[this.config.trainerType] === TrainerType[TrainerType.TATE])) {
|
||||||
newSpeciesPool = [Species.SOLROCK];
|
newSpeciesPool = [ Species.SOLROCK ];
|
||||||
} else if (index === 0 && (TrainerType[this.config.trainerType] === TrainerType[TrainerType.LIZA])) {
|
} else if (index === 0 && (TrainerType[this.config.trainerType] === TrainerType[TrainerType.LIZA])) {
|
||||||
newSpeciesPool = [Species.LUNATONE];
|
newSpeciesPool = [ Species.LUNATONE ];
|
||||||
} else {
|
} else {
|
||||||
newSpeciesPool = speciesPoolFiltered;
|
newSpeciesPool = speciesPoolFiltered;
|
||||||
}
|
}
|
||||||
@ -346,9 +346,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
// If the index is odd, use the species pool for the partner trainer (that way he only uses his own pokemon in battle)
|
// If the index is odd, use the species pool for the partner trainer (that way he only uses his own pokemon in battle)
|
||||||
// Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza
|
// Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza
|
||||||
if (index === 1 && (TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.TATE])) {
|
if (index === 1 && (TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.TATE])) {
|
||||||
newSpeciesPool = [Species.SOLROCK];
|
newSpeciesPool = [ Species.SOLROCK ];
|
||||||
} else if (index === 1 && (TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.LIZA])) {
|
} else if (index === 1 && (TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.LIZA])) {
|
||||||
newSpeciesPool = [Species.LUNATONE];
|
newSpeciesPool = [ Species.LUNATONE ];
|
||||||
} else {
|
} else {
|
||||||
newSpeciesPool = speciesPoolPartnerFiltered;
|
newSpeciesPool = speciesPoolPartnerFiltered;
|
||||||
}
|
}
|
||||||
@ -475,7 +475,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [party.indexOf(p), score];
|
return [ party.indexOf(p), score ];
|
||||||
}) as [integer, integer][];
|
}) as [integer, integer][];
|
||||||
|
|
||||||
return partyMemberScores;
|
return partyMemberScores;
|
||||||
|
@ -33,8 +33,8 @@ interface GameModeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Describes min and max waves for MEs in specific game modes
|
// Describes min and max waves for MEs in specific game modes
|
||||||
export const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
export const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [ 10, 180 ];
|
||||||
export const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
export const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [ 10, 180 ];
|
||||||
|
|
||||||
export class GameMode implements GameModeConfig {
|
export class GameMode implements GameModeConfig {
|
||||||
public modeId: GameModes;
|
public modeId: GameModes;
|
||||||
@ -330,7 +330,7 @@ export class GameMode implements GameModeConfig {
|
|||||||
getMysteryEncounterLegalWaves(): [number, number] {
|
getMysteryEncounterLegalWaves(): [number, number] {
|
||||||
switch (this.modeId) {
|
switch (this.modeId) {
|
||||||
default:
|
default:
|
||||||
return [0, 0];
|
return [ 0, 0 ];
|
||||||
case GameModes.CLASSIC:
|
case GameModes.CLASSIC:
|
||||||
return CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES;
|
return CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES;
|
||||||
case GameModes.CHALLENGE:
|
case GameModes.CHALLENGE:
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import * as Utils from "./utils";
|
import * as Utils from "./utils";
|
||||||
import {deepCopy} from "./utils";
|
import { deepCopy } from "./utils";
|
||||||
import pad_generic from "./configs/inputs/pad_generic";
|
import pad_generic from "./configs/inputs/pad_generic";
|
||||||
import pad_unlicensedSNES from "./configs/inputs/pad_unlicensedSNES";
|
import pad_unlicensedSNES from "./configs/inputs/pad_unlicensedSNES";
|
||||||
import pad_xbox360 from "./configs/inputs/pad_xbox360";
|
import pad_xbox360 from "./configs/inputs/pad_xbox360";
|
||||||
import pad_dualshock from "./configs/inputs/pad_dualshock";
|
import pad_dualshock from "./configs/inputs/pad_dualshock";
|
||||||
import pad_procon from "./configs/inputs/pad_procon";
|
import pad_procon from "./configs/inputs/pad_procon";
|
||||||
import {Mode} from "./ui/ui";
|
import { Mode } from "./ui/ui";
|
||||||
import SettingsGamepadUiHandler from "./ui/settings/settings-gamepad-ui-handler";
|
import SettingsGamepadUiHandler from "./ui/settings/settings-gamepad-ui-handler";
|
||||||
import SettingsKeyboardUiHandler from "./ui/settings/settings-keyboard-ui-handler";
|
import SettingsKeyboardUiHandler from "./ui/settings/settings-keyboard-ui-handler";
|
||||||
import cfg_keyboard_qwerty from "./configs/inputs/cfg_keyboard_qwerty";
|
import cfg_keyboard_qwerty from "./configs/inputs/cfg_keyboard_qwerty";
|
||||||
@ -16,8 +16,8 @@ import {
|
|||||||
getIconForLatestInput, swap,
|
getIconForLatestInput, swap,
|
||||||
} from "#app/configs/inputs/configHandler";
|
} from "#app/configs/inputs/configHandler";
|
||||||
import BattleScene from "./battle-scene";
|
import BattleScene from "./battle-scene";
|
||||||
import {SettingGamepad} from "#app/system/settings/settings-gamepad";
|
import { SettingGamepad } from "#app/system/settings/settings-gamepad";
|
||||||
import {SettingKeyboard} from "#app/system/settings/settings-keyboard";
|
import { SettingKeyboard } from "#app/system/settings/settings-keyboard";
|
||||||
import TouchControl from "#app/touch-controls";
|
import TouchControl from "#app/touch-controls";
|
||||||
import { Button } from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
import { Device } from "#enums/devices";
|
import { Device } from "#enums/devices";
|
||||||
@ -294,7 +294,7 @@ export class InputsController {
|
|||||||
this.setChosenGamepad(gamepadID);
|
this.setChosenGamepad(gamepadID);
|
||||||
}
|
}
|
||||||
const config = deepCopy(this.getConfig(gamepadID)) as InterfaceConfig;
|
const config = deepCopy(this.getConfig(gamepadID)) as InterfaceConfig;
|
||||||
config.custom = this.configs[gamepadID]?.custom || {...config.default};
|
config.custom = this.configs[gamepadID]?.custom || { ...config.default };
|
||||||
this.configs[gamepadID] = config;
|
this.configs[gamepadID] = config;
|
||||||
this.scene.gameData?.saveMappingConfigs(gamepadID, this.configs[gamepadID]);
|
this.scene.gameData?.saveMappingConfigs(gamepadID, this.configs[gamepadID]);
|
||||||
}
|
}
|
||||||
@ -307,9 +307,9 @@ export class InputsController {
|
|||||||
* Initializes or updates configurations for connected keyboards.
|
* Initializes or updates configurations for connected keyboards.
|
||||||
*/
|
*/
|
||||||
setupKeyboard(): void {
|
setupKeyboard(): void {
|
||||||
for (const layout of ["default"]) {
|
for (const layout of [ "default" ]) {
|
||||||
const config = deepCopy(this.getConfigKeyboard(layout)) as InterfaceConfig;
|
const config = deepCopy(this.getConfigKeyboard(layout)) as InterfaceConfig;
|
||||||
config.custom = this.configs[layout]?.custom || {...config.default};
|
config.custom = this.configs[layout]?.custom || { ...config.default };
|
||||||
this.configs[layout] = config;
|
this.configs[layout] = config;
|
||||||
this.scene.gameData?.saveMappingConfigs(this.selectedDevice[Device.KEYBOARD], this.configs[layout]);
|
this.scene.gameData?.saveMappingConfigs(this.selectedDevice[Device.KEYBOARD], this.configs[layout]);
|
||||||
}
|
}
|
||||||
@ -330,7 +330,7 @@ export class InputsController {
|
|||||||
return el !== null;
|
return el !== null;
|
||||||
}) ?? [];
|
}) ?? [];
|
||||||
|
|
||||||
for (const [index, thisGamepad] of this.gamepads.entries()) {
|
for (const [ index, thisGamepad ] of this.gamepads.entries()) {
|
||||||
thisGamepad.index = index; // Overwrite the gamepad index, in case we had undefined gamepads earlier
|
thisGamepad.index = index; // Overwrite the gamepad index, in case we had undefined gamepads earlier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import i18next from "i18next";
|
|||||||
import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
|
import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
|
||||||
import { initVouchers } from "#app/system/voucher";
|
import { initVouchers } from "#app/system/voucher";
|
||||||
import { Biome } from "#enums/biome";
|
import { Biome } from "#enums/biome";
|
||||||
import {initMysteryEncounters} from "#app/data/mystery-encounters/mystery-encounters";
|
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
|
||||||
|
|
||||||
export class LoadingScene extends SceneBase {
|
export class LoadingScene extends SceneBase {
|
||||||
public static readonly KEY = "loading";
|
public static readonly KEY = "loading";
|
||||||
@ -242,9 +242,9 @@ export class LoadingScene extends SceneBase {
|
|||||||
this.loadAtlas("statuses", "");
|
this.loadAtlas("statuses", "");
|
||||||
this.loadAtlas("types", "");
|
this.loadAtlas("types", "");
|
||||||
}
|
}
|
||||||
const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN"];
|
const availableLangs = [ "en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN" ];
|
||||||
if (lang && availableLangs.includes(lang)) {
|
if (lang && availableLangs.includes(lang)) {
|
||||||
this.loadImage("egg-update_"+lang, "events");
|
this.loadImage("egg-update_" + lang, "events");
|
||||||
} else {
|
} else {
|
||||||
this.loadImage("egg-update_en", "events");
|
this.loadImage("egg-update_en", "events");
|
||||||
}
|
}
|
||||||
|
@ -1014,10 +1014,10 @@ class TempStatStageBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
|||||||
class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
||||||
/** Object comprised of the currently available species-based stat boosting held items */
|
/** Object comprised of the currently available species-based stat boosting held items */
|
||||||
public static readonly items = {
|
public static readonly items = {
|
||||||
LIGHT_BALL: { stats: [Stat.ATK, Stat.SPATK], multiplier: 2, species: [Species.PIKACHU] },
|
LIGHT_BALL: { stats: [ Stat.ATK, Stat.SPATK ], multiplier: 2, species: [ Species.PIKACHU ]},
|
||||||
THICK_CLUB: { stats: [Stat.ATK], multiplier: 2, species: [Species.CUBONE, Species.MAROWAK, Species.ALOLA_MAROWAK] },
|
THICK_CLUB: { stats: [ Stat.ATK ], multiplier: 2, species: [ Species.CUBONE, Species.MAROWAK, Species.ALOLA_MAROWAK ]},
|
||||||
METAL_POWDER: { stats: [Stat.DEF], multiplier: 2, species: [Species.DITTO] },
|
METAL_POWDER: { stats: [ Stat.DEF ], multiplier: 2, species: [ Species.DITTO ]},
|
||||||
QUICK_POWDER: { stats: [Stat.SPD], multiplier: 2, species: [Species.DITTO] },
|
QUICK_POWDER: { stats: [ Stat.SPD ], multiplier: 2, species: [ Species.DITTO ]},
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -1132,7 +1132,7 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
|
|||||||
return new FormChangeItemModifierType(pregenArgs[0] as FormChangeItem);
|
return new FormChangeItemModifierType(pregenArgs[0] as FormChangeItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
const formChangeItemPool = [...new Set(party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => {
|
const formChangeItemPool = [ ...new Set(party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => {
|
||||||
const formChanges = pokemonFormChanges[p.species.speciesId];
|
const formChanges = pokemonFormChanges[p.species.speciesId];
|
||||||
let formChangeItemTriggers = formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || party[0].scene.getModifiers(MegaEvolutionAccessModifier).length)
|
let formChangeItemTriggers = formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || party[0].scene.getModifiers(MegaEvolutionAccessModifier).length)
|
||||||
&& ((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 && fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) || party[0].scene.getModifiers(GigantamaxAccessModifier).length)
|
&& ((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 && fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) || party[0].scene.getModifiers(GigantamaxAccessModifier).length)
|
||||||
@ -1507,9 +1507,9 @@ export const modifierTypes = {
|
|||||||
SOOTHE_BELL: () => new PokemonFriendshipBoosterModifierType("modifierType:ModifierType.SOOTHE_BELL", "soothe_bell"),
|
SOOTHE_BELL: () => new PokemonFriendshipBoosterModifierType("modifierType:ModifierType.SOOTHE_BELL", "soothe_bell"),
|
||||||
|
|
||||||
SCOPE_LENS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SCOPE_LENS", "scope_lens", (type, args) => new CritBoosterModifier(type, (args[0] as Pokemon).id, 1)),
|
SCOPE_LENS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SCOPE_LENS", "scope_lens", (type, args) => new CritBoosterModifier(type, (args[0] as Pokemon).id, 1)),
|
||||||
LEEK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEEK", "leek", (type, args) => new SpeciesCritBoosterModifier(type, (args[0] as Pokemon).id, 2, [Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD])),
|
LEEK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEEK", "leek", (type, args) => new SpeciesCritBoosterModifier(type, (args[0] as Pokemon).id, 2, [ Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD ])),
|
||||||
|
|
||||||
EVIOLITE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVIOLITE", "eviolite", (type, args) => new EvolutionStatBoosterModifier(type, (args[0] as Pokemon).id, [Stat.DEF, Stat.SPDEF], 1.5)),
|
EVIOLITE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVIOLITE", "eviolite", (type, args) => new EvolutionStatBoosterModifier(type, (args[0] as Pokemon).id, [ Stat.DEF, Stat.SPDEF ], 1.5)),
|
||||||
|
|
||||||
SOUL_DEW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SOUL_DEW", "soul_dew", (type, args) => new PokemonNatureWeightModifier(type, (args[0] as Pokemon).id)),
|
SOUL_DEW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SOUL_DEW", "soul_dew", (type, args) => new PokemonNatureWeightModifier(type, (args[0] as Pokemon).id)),
|
||||||
|
|
||||||
@ -1583,7 +1583,7 @@ export const modifierTypes = {
|
|||||||
if (pregenArgs) {
|
if (pregenArgs) {
|
||||||
return new PokemonBaseStatFlatModifierType(pregenArgs[0] as number, pregenArgs[1] as Stat[]);
|
return new PokemonBaseStatFlatModifierType(pregenArgs[0] as number, pregenArgs[1] as Stat[]);
|
||||||
}
|
}
|
||||||
return new PokemonBaseStatFlatModifierType(randSeedInt(20), [Stat.HP, Stat.ATK, Stat.DEF]);
|
return new PokemonBaseStatFlatModifierType(randSeedInt(20), [ Stat.HP, Stat.ATK, Stat.DEF ]);
|
||||||
}),
|
}),
|
||||||
MYSTERY_ENCOUNTER_BLACK_SLUDGE: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
|
MYSTERY_ENCOUNTER_BLACK_SLUDGE: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
|
||||||
if (pregenArgs) {
|
if (pregenArgs) {
|
||||||
@ -1733,22 +1733,22 @@ const modifierPool: ModifierPool = {
|
|||||||
|| (p.isFusion() && checkedSpecies.includes(p.getFusionSpeciesForm(true).speciesId)))) ? 12 : 0;
|
|| (p.isFusion() && checkedSpecies.includes(p.getFusionSpeciesForm(true).speciesId)))) ? 12 : 0;
|
||||||
}, 12),
|
}, 12),
|
||||||
new WeightedModifierType(modifierTypes.TOXIC_ORB, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.TOXIC_ORB, (party: Pokemon[]) => {
|
||||||
const checkedAbilities = [Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.TOXIC_BOOST, Abilities.POISON_HEAL, Abilities.MAGIC_GUARD];
|
const checkedAbilities = [ Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.TOXIC_BOOST, Abilities.POISON_HEAL, Abilities.MAGIC_GUARD ];
|
||||||
const checkedMoves = [Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT];
|
const checkedMoves = [ Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT ];
|
||||||
// If a party member doesn't already have one of these two orbs and has one of the above moves or abilities, the orb can appear
|
// If a party member doesn't already have one of these two orbs and has one of the above moves or abilities, the orb can appear
|
||||||
return party.some(p => !p.getHeldItems().some(i => i instanceof TurnStatusEffectModifier)
|
return party.some(p => !p.getHeldItems().some(i => i instanceof TurnStatusEffectModifier)
|
||||||
&& (checkedAbilities.some(a => p.hasAbility(a, false, true))
|
&& (checkedAbilities.some(a => p.hasAbility(a, false, true))
|
||||||
|| p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId)))) ? 10 : 0;
|
|| p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId)))) ? 10 : 0;
|
||||||
}, 10),
|
}, 10),
|
||||||
new WeightedModifierType(modifierTypes.FLAME_ORB, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.FLAME_ORB, (party: Pokemon[]) => {
|
||||||
const checkedAbilities = [Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.FLARE_BOOST, Abilities.MAGIC_GUARD];
|
const checkedAbilities = [ Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.FLARE_BOOST, Abilities.MAGIC_GUARD ];
|
||||||
const checkedMoves = [Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT];
|
const checkedMoves = [ Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT ];
|
||||||
// If a party member doesn't already have one of these two orbs and has one of the above moves or abilities, the orb can appear
|
// If a party member doesn't already have one of these two orbs and has one of the above moves or abilities, the orb can appear
|
||||||
return party.some(p => !p.getHeldItems().some(i => i instanceof TurnStatusEffectModifier)
|
return party.some(p => !p.getHeldItems().some(i => i instanceof TurnStatusEffectModifier)
|
||||||
&& (checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId)))) ? 10 : 0;
|
&& (checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId)))) ? 10 : 0;
|
||||||
}, 10),
|
}, 10),
|
||||||
new WeightedModifierType(modifierTypes.WHITE_HERB, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.WHITE_HERB, (party: Pokemon[]) => {
|
||||||
const checkedAbilities = [Abilities.WEAK_ARMOR, Abilities.CONTRARY, Abilities.MOODY, Abilities.ANGER_SHELL, Abilities.COMPETITIVE, Abilities.DEFIANT];
|
const checkedAbilities = [ Abilities.WEAK_ARMOR, Abilities.CONTRARY, Abilities.MOODY, Abilities.ANGER_SHELL, Abilities.COMPETITIVE, Abilities.DEFIANT ];
|
||||||
const weightMultiplier = party.filter(
|
const weightMultiplier = party.filter(
|
||||||
p => !p.getHeldItems().some(i => i instanceof ResetNegativeStatStageModifier && i.stackCount >= i.getMaxHeldItemCount(p)) &&
|
p => !p.getHeldItems().some(i => i instanceof ResetNegativeStatStageModifier && i.stackCount >= i.getMaxHeldItemCount(p)) &&
|
||||||
(checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && selfStatLowerMoves.includes(m.moveId)))).length;
|
(checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && selfStatLowerMoves.includes(m.moveId)))).length;
|
||||||
@ -2196,7 +2196,7 @@ export function overridePlayerModifierTypeOptions(options: ModifierTypeOption[],
|
|||||||
let modifierType: ModifierType | null = modifierFunc();
|
let modifierType: ModifierType | null = modifierFunc();
|
||||||
|
|
||||||
if (modifierType instanceof ModifierTypeGenerator) {
|
if (modifierType instanceof ModifierTypeGenerator) {
|
||||||
const pregenArgs = ("type" in override) && (override.type !== null) ? [override.type] : undefined;
|
const pregenArgs = ("type" in override) && (override.type !== null) ? [ override.type ] : undefined;
|
||||||
modifierType = modifierType.generateType(party, pregenArgs);
|
modifierType = modifierType.generateType(party, pregenArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ export abstract class LapsingPersistentModifier extends PersistentModifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getArgs(): any[] {
|
getArgs(): any[] {
|
||||||
return [this.maxBattles, this.battleCount];
|
return [ this.maxBattles, this.battleCount ];
|
||||||
}
|
}
|
||||||
|
|
||||||
getMaxStackCount(_scene: BattleScene, _forThreshold?: boolean): number {
|
getMaxStackCount(_scene: BattleScene, _forThreshold?: boolean): number {
|
||||||
@ -939,7 +939,7 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getArgs(): any[] {
|
getArgs(): any[] {
|
||||||
return super.getArgs().concat([this.species, this.required]);
|
return super.getArgs().concat([ this.species, this.required ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1860,7 +1860,7 @@ export class BerryModifier extends PokemonHeldItemModifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMaxHeldItemCount(pokemon: Pokemon): number {
|
getMaxHeldItemCount(pokemon: Pokemon): number {
|
||||||
if ([BerryType.LUM, BerryType.LEPPA, BerryType.SITRUS, BerryType.ENIGMA].includes(this.berryType)) {
|
if ([ BerryType.LUM, BerryType.LEPPA, BerryType.SITRUS, BerryType.ENIGMA ].includes(this.berryType)) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
return 3;
|
return 3;
|
||||||
@ -2204,7 +2204,7 @@ export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
|
|||||||
* @param levelCount The amount of levels to increment
|
* @param levelCount The amount of levels to increment
|
||||||
* @returns always `true`
|
* @returns always `true`
|
||||||
*/
|
*/
|
||||||
override apply(playerPokemon: PlayerPokemon, levelCount: NumberHolder): boolean {
|
override apply(playerPokemon: PlayerPokemon, levelCount: NumberHolder = new NumberHolder(1)): boolean {
|
||||||
playerPokemon.scene.applyModifiers(LevelIncrementBoosterModifier, true, levelCount);
|
playerPokemon.scene.applyModifiers(LevelIncrementBoosterModifier, true, levelCount);
|
||||||
|
|
||||||
playerPokemon.level += levelCount.value;
|
playerPokemon.level += levelCount.value;
|
||||||
@ -3602,7 +3602,7 @@ export function overrideModifiers(scene: BattleScene, isPlayer: boolean = true):
|
|||||||
let modifierType: ModifierType | null = modifierFunc();
|
let modifierType: ModifierType | null = modifierFunc();
|
||||||
|
|
||||||
if (modifierType instanceof ModifierTypeGenerator) {
|
if (modifierType instanceof ModifierTypeGenerator) {
|
||||||
const pregenArgs = ("type" in item) && (item.type !== null) ? [item.type] : undefined;
|
const pregenArgs = ("type" in item) && (item.type !== null) ? [ item.type ] : undefined;
|
||||||
modifierType = modifierType.generateType([], pregenArgs);
|
modifierType = modifierType.generateType([], pregenArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3643,7 +3643,7 @@ export function overrideHeldItems(scene: BattleScene, pokemon: Pokemon, isPlayer
|
|||||||
const qty = item.count || 1;
|
const qty = item.count || 1;
|
||||||
|
|
||||||
if (modifierType instanceof ModifierTypeGenerator) {
|
if (modifierType instanceof ModifierTypeGenerator) {
|
||||||
const pregenArgs = ("type" in item) && (item.type !== null) ? [item.type] : undefined;
|
const pregenArgs = ("type" in item) && (item.type !== null) ? [ item.type ] : undefined;
|
||||||
modifierType = modifierType.generateType([], pregenArgs);
|
modifierType = modifierType.generateType([], pregenArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +100,14 @@ class DefaultOverrides {
|
|||||||
* @example SPECIES_OVERRIDE = Species.Bulbasaur;
|
* @example SPECIES_OVERRIDE = Species.Bulbasaur;
|
||||||
*/
|
*/
|
||||||
readonly STARTER_SPECIES_OVERRIDE: Species | number = 0;
|
readonly STARTER_SPECIES_OVERRIDE: Species | number = 0;
|
||||||
|
/**
|
||||||
|
* This will force your starter to be a random fusion
|
||||||
|
*/
|
||||||
|
readonly STARTER_FUSION_OVERRIDE: boolean = false;
|
||||||
|
/**
|
||||||
|
* This will override the species of the fusion
|
||||||
|
*/
|
||||||
|
readonly STARTER_FUSION_SPECIES_OVERRIDE: Species | integer = 0;
|
||||||
readonly ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
readonly ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
||||||
readonly PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
readonly PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
||||||
readonly STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE;
|
readonly STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE;
|
||||||
@ -112,6 +120,14 @@ class DefaultOverrides {
|
|||||||
// OPPONENT / ENEMY OVERRIDES
|
// OPPONENT / ENEMY OVERRIDES
|
||||||
// --------------------------
|
// --------------------------
|
||||||
readonly OPP_SPECIES_OVERRIDE: Species | number = 0;
|
readonly OPP_SPECIES_OVERRIDE: Species | number = 0;
|
||||||
|
/**
|
||||||
|
* This will make all opponents fused Pokemon
|
||||||
|
*/
|
||||||
|
readonly OPP_FUSION_OVERRIDE: boolean = false;
|
||||||
|
/**
|
||||||
|
* This will override the species of the fusion only when the opponent is already a fusion
|
||||||
|
*/
|
||||||
|
readonly OPP_FUSION_SPECIES_OVERRIDE: Species | integer = 0;
|
||||||
readonly OPP_LEVEL_OVERRIDE: number = 0;
|
readonly OPP_LEVEL_OVERRIDE: number = 0;
|
||||||
readonly OPP_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
readonly OPP_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
||||||
readonly OPP_PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
readonly OPP_PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
|
||||||
|
@ -248,7 +248,7 @@ export class AttemptCapturePhase extends PokemonPhase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Promise.all([pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon)]).then(() => {
|
Promise.all([ pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon) ]).then(() => {
|
||||||
if (this.scene.getParty().length === 6) {
|
if (this.scene.getParty().length === 6) {
|
||||||
const promptRelease = () => {
|
const promptRelease = () => {
|
||||||
this.scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
|
this.scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
|
||||||
|
@ -33,7 +33,7 @@ export class AttemptRunPhase extends PokemonPhase {
|
|||||||
this.scene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);
|
this.scene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);
|
||||||
|
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: [this.scene.arenaEnemy, enemyField].flat(),
|
targets: [ this.scene.arenaEnemy, enemyField ].flat(),
|
||||||
alpha: 0,
|
alpha: 0,
|
||||||
duration: 250,
|
duration: 250,
|
||||||
ease: "Sine.easeIn",
|
ease: "Sine.easeIn",
|
||||||
|
@ -12,7 +12,7 @@ export class BattlePhase extends Phase {
|
|||||||
const tintSprites = this.scene.currentBattle.trainer?.getTintSprites()!; // TODO: is this bang correct?
|
const tintSprites = this.scene.currentBattle.trainer?.getTintSprites()!; // TODO: is this bang correct?
|
||||||
for (let i = 0; i < sprites.length; i++) {
|
for (let i = 0; i < sprites.length; i++) {
|
||||||
const visible = !trainerSlot || !i === (trainerSlot === TrainerSlot.TRAINER) || sprites.length < 2;
|
const visible = !trainerSlot || !i === (trainerSlot === TrainerSlot.TRAINER) || sprites.length < 2;
|
||||||
[sprites[i], tintSprites[i]].map(sprite => {
|
[ sprites[i], tintSprites[i] ].map(sprite => {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
sprite.x = trainerSlot || sprites.length < 2 ? 0 : i ? 16 : -16;
|
sprite.x = trainerSlot || sprites.length < 2 ? 0 : i ? 16 : -16;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ export class CommandPhase extends FieldPhase {
|
|||||||
const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args };
|
const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args };
|
||||||
const moveTargets: MoveTargetSet = args.length < 3 ? getMoveTargets(playerPokemon, moveId) : args[2];
|
const moveTargets: MoveTargetSet = args.length < 3 ? getMoveTargets(playerPokemon, moveId) : args[2];
|
||||||
if (!moveId) {
|
if (!moveId) {
|
||||||
turnCommand.targets = [this.fieldIndex];
|
turnCommand.targets = [ this.fieldIndex ];
|
||||||
}
|
}
|
||||||
console.log(moveTargets, getPokemonNameWithAffix(playerPokemon));
|
console.log(moveTargets, getPokemonNameWithAffix(playerPokemon));
|
||||||
if (moveTargets.targets.length > 1 && moveTargets.multiple) {
|
if (moveTargets.targets.length > 1 && moveTargets.multiple) {
|
||||||
|
@ -28,7 +28,7 @@ export class EggLapsePhase extends Phase {
|
|||||||
return Overrides.EGG_IMMEDIATE_HATCH_OVERRIDE ? true : --egg.hatchWaves < 1;
|
return Overrides.EGG_IMMEDIATE_HATCH_OVERRIDE ? true : --egg.hatchWaves < 1;
|
||||||
});
|
});
|
||||||
const eggsToHatchCount: number = eggsToHatch.length;
|
const eggsToHatchCount: number = eggsToHatch.length;
|
||||||
this.eggHatchData= [];
|
this.eggHatchData = [];
|
||||||
|
|
||||||
if (eggsToHatchCount > 0) {
|
if (eggsToHatchCount > 0) {
|
||||||
if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 1) {
|
if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 1) {
|
||||||
|
@ -259,7 +259,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
|
|
||||||
const enemyField = this.scene.getEnemyField();
|
const enemyField = this.scene.getEnemyField();
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: [this.scene.arenaEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.arenaPlayer, this.scene.trainer].flat(),
|
targets: [ this.scene.arenaEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.arenaPlayer, this.scene.trainer ].flat(),
|
||||||
x: (_target, _key, value, fieldIndex: integer) => fieldIndex < 2 + (enemyField.length) ? value + 300 : value - 300,
|
x: (_target, _key, value, fieldIndex: integer) => fieldIndex < 2 + (enemyField.length) ? value + 300 : value - 300,
|
||||||
duration: 2000,
|
duration: 2000,
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
@ -287,7 +287,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
const enemyField = this.scene.getEnemyField();
|
const enemyField = this.scene.getEnemyField();
|
||||||
|
|
||||||
if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
|
if (this.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
|
||||||
return i18next.t("battle:bossAppeared", { bossName: getPokemonNameWithAffix(enemyField[0])});
|
return i18next.t("battle:bossAppeared", { bossName: getPokemonNameWithAffix(enemyField[0]) });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.scene.currentBattle.battleType === BattleType.TRAINER) {
|
if (this.scene.currentBattle.battleType === BattleType.TRAINER) {
|
||||||
@ -436,7 +436,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (![BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.scene.currentBattle.battleType)) {
|
if (![ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(this.scene.currentBattle.battleType)) {
|
||||||
enemyField.map(p => this.scene.pushConditionalPhase(new PostSummonPhase(this.scene, p.getBattlerIndex()), () => {
|
enemyField.map(p => this.scene.pushConditionalPhase(new PostSummonPhase(this.scene, p.getBattlerIndex()), () => {
|
||||||
// if there is not a player party, we can't continue
|
// if there is not a player party, we can't continue
|
||||||
if (!this.scene.getParty()?.length) {
|
if (!this.scene.getParty()?.length) {
|
||||||
@ -505,7 +505,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
} else {
|
} else {
|
||||||
const count = 5643853 + this.scene.gameData.gameStats.classicSessionsPlayed;
|
const count = 5643853 + this.scene.gameData.gameStats.classicSessionsPlayed;
|
||||||
// The line below checks if an English ordinal is necessary or not based on whether an entry for encounterLocalizationKey exists in the language or not.
|
// The line below checks if an English ordinal is necessary or not based on whether an entry for encounterLocalizationKey exists in the language or not.
|
||||||
const ordinalUsed = !i18next.exists(localizationKey, {fallbackLng: []}) || i18next.resolvedLanguage === "en" ? i18next.t("battleSpecDialogue:key", { count: count, ordinal: true }) : "";
|
const ordinalUsed = !i18next.exists(localizationKey, { fallbackLng: []}) || i18next.resolvedLanguage === "en" ? i18next.t("battleSpecDialogue:key", { count: count, ordinal: true }) : "";
|
||||||
const cycleCount = count.toLocaleString() + ordinalUsed;
|
const cycleCount = count.toLocaleString() + ordinalUsed;
|
||||||
const genderIndex = this.scene.gameData.gender ?? PlayerGender.UNSET;
|
const genderIndex = this.scene.gameData.gender ?? PlayerGender.UNSET;
|
||||||
const genderStr = PlayerGender[genderIndex].toLowerCase();
|
const genderStr = PlayerGender[genderIndex].toLowerCase();
|
||||||
|
@ -61,7 +61,7 @@ export class EnemyCommandPhase extends FieldPhase {
|
|||||||
const index = trainer.getNextSummonIndex(enemyPokemon.trainerSlot, partyMemberScores);
|
const index = trainer.getNextSummonIndex(enemyPokemon.trainerSlot, partyMemberScores);
|
||||||
|
|
||||||
battle.turnCommands[this.fieldIndex + BattlerIndex.ENEMY] =
|
battle.turnCommands[this.fieldIndex + BattlerIndex.ENEMY] =
|
||||||
{ command: Command.POKEMON, cursor: index, args: [false], skip: this.skipTurn };
|
{ command: Command.POKEMON, cursor: index, args: [ false ], skip: this.skipTurn };
|
||||||
|
|
||||||
battle.enemySwitchCounter++;
|
battle.enemySwitchCounter++;
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ export class FaintPhase extends PokemonPhase {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.scene.unshiftPhase(new VictoryPhase(this.scene, this.battlerIndex));
|
this.scene.unshiftPhase(new VictoryPhase(this.scene, this.battlerIndex));
|
||||||
if ([BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.scene.currentBattle.battleType)) {
|
if ([ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(this.scene.currentBattle.battleType)) {
|
||||||
const hasReservePartyMember = !!this.scene.getEnemyParty().filter(p => p.isActive() && !p.isOnField() && p.trainerSlot === (pokemon as EnemyPokemon).trainerSlot).length;
|
const hasReservePartyMember = !!this.scene.getEnemyParty().filter(p => p.isActive() && !p.isOnField() && p.trainerSlot === (pokemon as EnemyPokemon).trainerSlot).length;
|
||||||
if (hasReservePartyMember) {
|
if (hasReservePartyMember) {
|
||||||
this.scene.pushPhase(new SwitchSummonPhase(this.scene, SwitchType.SWITCH, this.fieldIndex, -1, false, false));
|
this.scene.pushPhase(new SwitchSummonPhase(this.scene, SwitchType.SWITCH, this.fieldIndex, -1, false, false));
|
||||||
|
@ -59,7 +59,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
|||||||
const learnMovePrompt = i18next.t("battle:learnMovePrompt", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name });
|
const learnMovePrompt = i18next.t("battle:learnMovePrompt", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name });
|
||||||
const moveLimitReached = i18next.t("battle:learnMoveLimitReached", { pokemonName: getPokemonNameWithAffix(pokemon) });
|
const moveLimitReached = i18next.t("battle:learnMoveLimitReached", { pokemonName: getPokemonNameWithAffix(pokemon) });
|
||||||
const shouldReplaceQ = i18next.t("battle:learnMoveReplaceQuestion", { moveName: move.name });
|
const shouldReplaceQ = i18next.t("battle:learnMoveReplaceQuestion", { moveName: move.name });
|
||||||
const preQText = [learnMovePrompt, moveLimitReached].join("$");
|
const preQText = [ learnMovePrompt, moveLimitReached ].join("$");
|
||||||
await this.scene.ui.showTextPromise(preQText);
|
await this.scene.ui.showTextPromise(preQText);
|
||||||
await this.scene.ui.showTextPromise(shouldReplaceQ, undefined, false);
|
await this.scene.ui.showTextPromise(shouldReplaceQ, undefined, false);
|
||||||
await this.scene.ui.setModeWithoutClear(Mode.CONFIRM,
|
await this.scene.ui.setModeWithoutClear(Mode.CONFIRM,
|
||||||
@ -91,7 +91,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const forgetSuccessText = i18next.t("battle:learnMoveForgetSuccess", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: pokemon.moveset[moveIndex]!.getName() });
|
const forgetSuccessText = i18next.t("battle:learnMoveForgetSuccess", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: pokemon.moveset[moveIndex]!.getName() });
|
||||||
const fullText = [i18next.t("battle:countdownPoof"), forgetSuccessText, i18next.t("battle:learnMoveAnd")].join("$");
|
const fullText = [ i18next.t("battle:countdownPoof"), forgetSuccessText, i18next.t("battle:learnMoveAnd") ].join("$");
|
||||||
this.scene.ui.setMode(this.messageMode).then(() => this.learnMove(moveIndex, move, pokemon, fullText));
|
this.scene.ui.setMode(this.messageMode).then(() => this.learnMove(moveIndex, move, pokemon, fullText));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -144,12 +144,12 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
|||||||
}
|
}
|
||||||
pokemon.setMove(index, this.moveId);
|
pokemon.setMove(index, this.moveId);
|
||||||
initMoveAnim(this.scene, this.moveId).then(() => {
|
initMoveAnim(this.scene, this.moveId).then(() => {
|
||||||
loadMoveAnimAssets(this.scene, [this.moveId], true);
|
loadMoveAnimAssets(this.scene, [ this.moveId ], true);
|
||||||
this.scene.playSound("level_up_fanfare"); // Sound loaded into game as is
|
this.scene.playSound("level_up_fanfare"); // Sound loaded into game as is
|
||||||
});
|
});
|
||||||
this.scene.ui.setMode(this.messageMode);
|
this.scene.ui.setMode(this.messageMode);
|
||||||
const learnMoveText = i18next.t("battle:learnMove", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name });
|
const learnMoveText = i18next.t("battle:learnMove", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name });
|
||||||
textMessage = textMessage ? textMessage+"$"+learnMoveText : learnMoveText;
|
textMessage = textMessage ? textMessage + "$" + learnMoveText : learnMoveText;
|
||||||
await this.scene.ui.showTextPromise(textMessage, this.messageMode === Mode.EVOLUTION_SCENE ? 1000 : undefined, true);
|
await this.scene.ui.showTextPromise(textMessage, this.messageMode === Mode.EVOLUTION_SCENE ? 1000 : undefined, true);
|
||||||
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeMoveLearnedTrigger, true);
|
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeMoveLearnedTrigger, true);
|
||||||
this.end();
|
this.end();
|
||||||
|
@ -22,7 +22,7 @@ export class LoginPhase extends Phase {
|
|||||||
|
|
||||||
const hasSession = !!Utils.getCookie(Utils.sessionIdKey);
|
const hasSession = !!Utils.getCookie(Utils.sessionIdKey);
|
||||||
|
|
||||||
this.scene.ui.setMode(Mode.LOADING, { buttonActions: [] });
|
this.scene.ui.setMode(Mode.LOADING, { buttonActions: []});
|
||||||
Utils.executeIf(bypassLogin || hasSession, updateUserInfo).then(response => {
|
Utils.executeIf(bypassLogin || hasSession, updateUserInfo).then(response => {
|
||||||
const success = response ? response[0] : false;
|
const success = response ? response[0] : false;
|
||||||
const statusCode = response ? response[1] : null;
|
const statusCode = response ? response[1] : null;
|
||||||
|
@ -29,7 +29,7 @@ export class MoveAnimTestPhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initMoveAnim(this.scene, moveId).then(() => {
|
initMoveAnim(this.scene, moveId).then(() => {
|
||||||
loadMoveAnimAssets(this.scene, [moveId], true)
|
loadMoveAnimAssets(this.scene, [ moveId ], true)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const user = player ? this.scene.getPlayerPokemon()! : this.scene.getEnemyPokemon()!;
|
const user = player ? this.scene.getPlayerPokemon()! : this.scene.getEnemyPokemon()!;
|
||||||
const target = (player !== (allMoves[moveId] instanceof SelfStatusMove)) ? this.scene.getEnemyPokemon()! : this.scene.getPlayerPokemon()!;
|
const target = (player !== (allMoves[moveId] instanceof SelfStatusMove)) ? this.scene.getEnemyPokemon()! : this.scene.getPlayerPokemon()!;
|
||||||
|
@ -70,7 +70,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* resolve the move's total hit count. This block combines the
|
* resolve the move's total hit count. This block combines the
|
||||||
* effects of the move itself, Parental Bond, and Multi-Lens to do so.
|
* effects of the move itself, Parental Bond, and Multi-Lens to do so.
|
||||||
*/
|
*/
|
||||||
if (user.turnData.hitsLeft === undefined) {
|
if (user.turnData.hitsLeft === -1) {
|
||||||
const hitCount = new Utils.IntegerHolder(1);
|
const hitCount = new Utils.IntegerHolder(1);
|
||||||
// Assume single target for multi hit
|
// Assume single target for multi hit
|
||||||
applyMoveAttrs(MultiHitAttr, user, this.getTarget() ?? null, move, hitCount);
|
applyMoveAttrs(MultiHitAttr, user, this.getTarget() ?? null, move, hitCount);
|
||||||
@ -96,7 +96,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* Stores results of hit checks of the invoked move against all targets, organized by battler index.
|
* Stores results of hit checks of the invoked move against all targets, organized by battler index.
|
||||||
* @see {@linkcode hitCheck}
|
* @see {@linkcode hitCheck}
|
||||||
*/
|
*/
|
||||||
const targetHitChecks = Object.fromEntries(targets.map(p => [p.getBattlerIndex(), this.hitCheck(p)]));
|
const targetHitChecks = Object.fromEntries(targets.map(p => [ p.getBattlerIndex(), this.hitCheck(p) ]));
|
||||||
const hasActiveTargets = targets.some(t => t.isActive(true));
|
const hasActiveTargets = targets.some(t => t.isActive(true));
|
||||||
|
|
||||||
/** Check if the target is immune via ability to the attacking move */
|
/** Check if the target is immune via ability to the attacking move */
|
||||||
@ -111,7 +111,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]] && !targets[0].getTag(ProtectedTag) && !isImmune)) {
|
if (!hasActiveTargets || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]] && !targets[0].getTag(ProtectedTag) && !isImmune)) {
|
||||||
this.stopMultiHit();
|
this.stopMultiHit();
|
||||||
if (hasActiveTargets) {
|
if (hasActiveTargets) {
|
||||||
this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: this.getTarget()? getPokemonNameWithAffix(this.getTarget()!) : "" }));
|
this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: this.getTarget() ? getPokemonNameWithAffix(this.getTarget()!) : "" }));
|
||||||
moveHistoryEntry.result = MoveResult.MISS;
|
moveHistoryEntry.result = MoveResult.MISS;
|
||||||
applyMoveAttrs(MissEffectAttr, user, null, move);
|
applyMoveAttrs(MissEffectAttr, user, null, move);
|
||||||
} else {
|
} else {
|
||||||
@ -376,7 +376,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
*/
|
*/
|
||||||
hitCheck(target: Pokemon): boolean {
|
hitCheck(target: Pokemon): boolean {
|
||||||
// Moves targeting the user and entry hazards can't miss
|
// Moves targeting the user and entry hazards can't miss
|
||||||
if ([MoveTarget.USER, MoveTarget.ENEMY_SIDE].includes(this.move.getMove().moveTarget)) {
|
if ([ MoveTarget.USER, MoveTarget.ENEMY_SIDE ].includes(this.move.getMove().moveTarget)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +407,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
const semiInvulnerableTag = target.getTag(SemiInvulnerableTag);
|
const semiInvulnerableTag = target.getTag(SemiInvulnerableTag);
|
||||||
if (semiInvulnerableTag
|
if (semiInvulnerableTag
|
||||||
&& !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType)
|
&& !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType)
|
||||||
&& !(this.move.getMove().getAttrs(ToxicAccuracyAttr) && user.isOfType(Type.POISON))
|
&& !(this.move.getMove().hasAttr(ToxicAccuracyAttr) && user.isOfType(Type.POISON))
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
import { applyAbAttrs, applyPostMoveUsedAbAttrs, applyPreAttackAbAttrs, BlockRedirectAbAttr, IncreasePpAbAttr, PokemonTypeChangeAbAttr, PostMoveUsedAbAttr, RedirectMoveAbAttr } from "#app/data/ability";
|
import { applyAbAttrs, applyPostMoveUsedAbAttrs, applyPreAttackAbAttrs, BlockRedirectAbAttr, IncreasePpAbAttr, PokemonTypeChangeAbAttr, PostMoveUsedAbAttr, RedirectMoveAbAttr } from "#app/data/ability";
|
||||||
import { CommonAnim } from "#app/data/battle-anims";
|
import { CommonAnim } from "#app/data/battle-anims";
|
||||||
import { BattlerTagLapseType, CenterOfAttentionTag } from "#app/data/battler-tags";
|
import { BattlerTagLapseType, CenterOfAttentionTag } from "#app/data/battler-tags";
|
||||||
@ -15,236 +15,149 @@ import { StatusEffect } from "#app/enums/status-effect";
|
|||||||
import { MoveUsedEvent } from "#app/events/battle-scene";
|
import { MoveUsedEvent } from "#app/events/battle-scene";
|
||||||
import Pokemon, { MoveResult, PokemonMove, TurnMove } from "#app/field/pokemon";
|
import Pokemon, { MoveResult, PokemonMove, TurnMove } from "#app/field/pokemon";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { BattlePhase } from "#app/phases/battle-phase";
|
||||||
|
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
|
||||||
|
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
|
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
||||||
|
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { BattlePhase } from "./battle-phase";
|
|
||||||
import { CommonAnimPhase } from "./common-anim-phase";
|
|
||||||
import { MoveEffectPhase } from "./move-effect-phase";
|
|
||||||
import { MoveEndPhase } from "./move-end-phase";
|
|
||||||
import { ShowAbilityPhase } from "./show-ability-phase";
|
|
||||||
|
|
||||||
export class MovePhase extends BattlePhase {
|
export class MovePhase extends BattlePhase {
|
||||||
public pokemon: Pokemon;
|
protected _pokemon: Pokemon;
|
||||||
public move: PokemonMove;
|
protected _move: PokemonMove;
|
||||||
public targets: BattlerIndex[];
|
protected _targets: BattlerIndex[];
|
||||||
protected followUp: boolean;
|
protected followUp: boolean;
|
||||||
protected ignorePp: boolean;
|
protected ignorePp: boolean;
|
||||||
protected failed: boolean;
|
protected failed: boolean = false;
|
||||||
protected cancelled: boolean;
|
protected cancelled: boolean = false;
|
||||||
|
|
||||||
constructor(scene: BattleScene, pokemon: Pokemon, targets: BattlerIndex[], move: PokemonMove, followUp?: boolean, ignorePp?: boolean) {
|
public get pokemon(): Pokemon {
|
||||||
|
return this._pokemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected set pokemon(pokemon: Pokemon) {
|
||||||
|
this._pokemon = pokemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get move(): PokemonMove {
|
||||||
|
return this._move;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected set move(move: PokemonMove) {
|
||||||
|
this._move = move;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get targets(): BattlerIndex[] {
|
||||||
|
return this._targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected set targets(targets: BattlerIndex[]) {
|
||||||
|
this._targets = targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param followUp Indicates that the move being uses is a "follow-up" - for example, a move being used by Metronome or Dancer.
|
||||||
|
* Follow-ups bypass a few failure conditions, including flinches, sleep/paralysis/freeze and volatile status checks, etc.
|
||||||
|
*/
|
||||||
|
constructor(scene: BattleScene, pokemon: Pokemon, targets: BattlerIndex[], move: PokemonMove, followUp: boolean = false, ignorePp: boolean = false) {
|
||||||
super(scene);
|
super(scene);
|
||||||
|
|
||||||
this.pokemon = pokemon;
|
this.pokemon = pokemon;
|
||||||
this.targets = targets;
|
this.targets = targets;
|
||||||
this.move = move;
|
this.move = move;
|
||||||
this.followUp = followUp ?? false;
|
this.followUp = followUp;
|
||||||
this.ignorePp = ignorePp ?? false;
|
this.ignorePp = ignorePp;
|
||||||
this.failed = false;
|
|
||||||
this.cancelled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canMove(ignoreDisableTags?: boolean): boolean {
|
/**
|
||||||
|
* Checks if the pokemon is active, if the move is usable, and that the move is targetting something.
|
||||||
|
* @param ignoreDisableTags `true` to not check if the move is disabled
|
||||||
|
* @returns `true` if all the checks pass
|
||||||
|
*/
|
||||||
|
public canMove(ignoreDisableTags: boolean = false): boolean {
|
||||||
return this.pokemon.isActive(true) && this.move.isUsable(this.pokemon, this.ignorePp, ignoreDisableTags) && !!this.targets.length;
|
return this.pokemon.isActive(true) && this.move.isUsable(this.pokemon, this.ignorePp, ignoreDisableTags) && !!this.targets.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Signifies the current move should fail but still use PP */
|
/**Signifies the current move should fail but still use PP */
|
||||||
fail(): void {
|
public fail(): void {
|
||||||
this.failed = true;
|
this.failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Signifies the current move should cancel and retain PP */
|
/**Signifies the current move should cancel and retain PP */
|
||||||
cancel(): void {
|
public cancel(): void {
|
||||||
this.cancelled = true;
|
this.cancelled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
public start() {
|
||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
console.log(Moves[this.move.moveId]);
|
console.log(Moves[this.move.moveId]);
|
||||||
|
|
||||||
|
// Check if move is unusable (e.g. because it's out of PP due to a mid-turn Spite).
|
||||||
if (!this.canMove(true)) {
|
if (!this.canMove(true)) {
|
||||||
if (this.pokemon.isActive(true) && this.move.ppUsed >= this.move.getMovePp()) { // if the move PP was reduced from Spite or otherwise, the move fails
|
if (this.pokemon.isActive(true) && this.move.ppUsed >= this.move.getMovePp()) {
|
||||||
this.fail();
|
this.fail();
|
||||||
this.showMoveText();
|
this.showMoveText();
|
||||||
this.showFailedText();
|
this.showFailedText();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.end();
|
return this.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.pokemon.turnData.acted = true;
|
||||||
|
|
||||||
|
// Reset hit-related turn data when starting follow-up moves (e.g. Metronomed moves, Dancer repeats)
|
||||||
|
if (this.followUp) {
|
||||||
|
this.pokemon.turnData.hitsLeft = -1;
|
||||||
|
this.pokemon.turnData.hitCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check move to see if arena.ignoreAbilities should be true.
|
||||||
if (!this.followUp) {
|
if (!this.followUp) {
|
||||||
if (this.move.getMove().checkFlag(MoveFlags.IGNORE_ABILITIES, this.pokemon, null)) {
|
if (this.move.getMove().checkFlag(MoveFlags.IGNORE_ABILITIES, this.pokemon, null)) {
|
||||||
this.scene.arena.setIgnoreAbilities(true, this.pokemon.getBattlerIndex());
|
this.scene.arena.setIgnoreAbilities(true, this.pokemon.getBattlerIndex());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resolveRedirectTarget();
|
||||||
|
|
||||||
|
this.resolveCounterAttackTarget();
|
||||||
|
|
||||||
|
this.resolvePreMoveStatusEffects();
|
||||||
|
|
||||||
|
this.lapsePreMoveAndMoveTags();
|
||||||
|
|
||||||
|
this.resolveFinalPreMoveCancellationChecks();
|
||||||
|
|
||||||
|
if (this.cancelled || this.failed) {
|
||||||
|
this.handlePreMoveFailures();
|
||||||
} else {
|
} else {
|
||||||
this.pokemon.turnData.hitsLeft = 0; // TODO: is `0` correct?
|
this.useMove();
|
||||||
this.pokemon.turnData.hitCount = 0; // TODO: is `0` correct?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move redirection abilities (ie. Storm Drain) only support single target moves
|
this.end();
|
||||||
const moveTarget = this.targets.length === 1
|
}
|
||||||
? new Utils.IntegerHolder(this.targets[0])
|
|
||||||
: null;
|
/** Check for cancellation edge cases - no targets remaining, or {@linkcode Moves.NONE} is in the queue */
|
||||||
if (moveTarget) {
|
protected resolveFinalPreMoveCancellationChecks() {
|
||||||
const oldTarget = moveTarget.value;
|
const targets = this.getActiveTargetPokemon();
|
||||||
this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, moveTarget));
|
const moveQueue = this.pokemon.getMoveQueue();
|
||||||
this.pokemon.getOpponents().forEach(p => {
|
|
||||||
const redirectTag = p.getTag(CenterOfAttentionTag) as CenterOfAttentionTag;
|
if (targets.length === 0 || (moveQueue.length && moveQueue[0].move === Moves.NONE)) {
|
||||||
if (redirectTag && (!redirectTag.powder || (!this.pokemon.isOfType(Type.GRASS) && !this.pokemon.hasAbility(Abilities.OVERCOAT)))) {
|
this.showFailedText();
|
||||||
moveTarget.value = p.getBattlerIndex();
|
this.cancelled = true;
|
||||||
}
|
|
||||||
});
|
|
||||||
//Check if this move is immune to being redirected, and restore its target to the intended target if it is.
|
|
||||||
if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) || this.move.getMove().hasAttr(BypassRedirectAttr))) {
|
|
||||||
//If an ability prevented this move from being redirected, display its ability pop up.
|
|
||||||
if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) && !this.move.getMove().hasAttr(BypassRedirectAttr)) && oldTarget !== moveTarget.value) {
|
|
||||||
this.scene.unshiftPhase(new ShowAbilityPhase(this.scene, this.pokemon.getBattlerIndex(), this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr)));
|
|
||||||
}
|
|
||||||
moveTarget.value = oldTarget;
|
|
||||||
}
|
|
||||||
this.targets[0] = moveTarget.value;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for counterattack moves to switch target
|
public getActiveTargetPokemon() {
|
||||||
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
|
return this.scene.getField(true).filter(p => this.targets.includes(p.getBattlerIndex()));
|
||||||
if (this.pokemon.turnData.attacksReceived.length) {
|
}
|
||||||
const attack = this.pokemon.turnData.attacksReceived[0];
|
|
||||||
this.targets[0] = attack.sourceBattlerIndex;
|
|
||||||
|
|
||||||
// account for metal burst and comeuppance hitting remaining targets in double battles
|
|
||||||
// counterattack will redirect to remaining ally if original attacker faints
|
|
||||||
if (this.scene.currentBattle.double && this.move.getMove().hasFlag(MoveFlags.REDIRECT_COUNTER)) {
|
|
||||||
if (this.scene.getField()[this.targets[0]].hp === 0) {
|
|
||||||
const opposingField = this.pokemon.isPlayer() ? this.scene.getEnemyField() : this.scene.getPlayerField();
|
|
||||||
//@ts-ignore
|
|
||||||
this.targets[0] = opposingField.find(p => p.hp > 0)?.getBattlerIndex(); //TODO: fix ts-ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.targets[0] === BattlerIndex.ATTACKER) {
|
|
||||||
this.fail(); // Marks the move as failed for later in doMove
|
|
||||||
this.showMoveText();
|
|
||||||
this.showFailedText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const targets = this.scene.getField(true).filter(p => {
|
|
||||||
if (this.targets.indexOf(p.getBattlerIndex()) > -1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const doMove = () => {
|
|
||||||
this.pokemon.turnData.acted = true; // Record that the move was attempted, even if it fails
|
|
||||||
|
|
||||||
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
|
|
||||||
|
|
||||||
let ppUsed = 1;
|
|
||||||
// Filter all opponents to include only those this move is targeting
|
|
||||||
const targetedOpponents = this.pokemon.getOpponents().filter(o => this.targets.includes(o.getBattlerIndex()));
|
|
||||||
for (const opponent of targetedOpponents) {
|
|
||||||
if (this.move.ppUsed + ppUsed >= this.move.getMovePp()) { // If we're already at max PP usage, stop checking
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (opponent.hasAbilityWithAttr(IncreasePpAbAttr)) { // Accounting for abilities like Pressure
|
|
||||||
ppUsed++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.followUp && this.canMove() && !this.cancelled) {
|
|
||||||
this.pokemon.lapseTags(BattlerTagLapseType.MOVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
const moveQueue = this.pokemon.getMoveQueue();
|
|
||||||
if (this.cancelled || this.failed) {
|
|
||||||
if (this.failed) {
|
|
||||||
this.move.usePp(ppUsed); // Only use PP if the move failed
|
|
||||||
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record a failed move so Abilities like Truant don't trigger next turn and soft-lock
|
|
||||||
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
|
||||||
|
|
||||||
this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); // Remove any tags from moves like Fly/Dive/etc.
|
|
||||||
this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE);
|
|
||||||
moveQueue.shift(); // Remove the second turn of charge moves
|
|
||||||
return this.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.scene.triggerPokemonFormChange(this.pokemon, SpeciesFormChangePreMoveTrigger);
|
|
||||||
|
|
||||||
if (this.move.moveId) {
|
|
||||||
this.showMoveText();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should only happen when there are no valid targets left on the field
|
|
||||||
if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || !targets.length) {
|
|
||||||
this.showFailedText();
|
|
||||||
this.cancel();
|
|
||||||
|
|
||||||
// Record a failed move so Abilities like Truant don't trigger next turn and soft-lock
|
|
||||||
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
|
||||||
|
|
||||||
this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); // Remove any tags from moves like Fly/Dive/etc.
|
|
||||||
this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE);
|
|
||||||
|
|
||||||
moveQueue.shift();
|
|
||||||
return this.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!moveQueue.length || !moveQueue.shift()?.ignorePP) && !this.ignorePp) { // using .shift here clears out two turn moves once they've been used
|
|
||||||
this.move.usePp(ppUsed);
|
|
||||||
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allMoves[this.move.moveId].hasAttr(CopyMoveAttr)) {
|
|
||||||
this.scene.currentBattle.lastMove = this.move.moveId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assume conditions affecting targets only apply to moves with a single target
|
|
||||||
let success = this.move.getMove().applyConditions(this.pokemon, targets[0], this.move.getMove());
|
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
|
||||||
let failedText = this.move.getMove().getFailedText(this.pokemon, targets[0], this.move.getMove(), cancelled);
|
|
||||||
if (success && this.scene.arena.isMoveWeatherCancelled(this.pokemon, this.move.getMove())) {
|
|
||||||
success = false;
|
|
||||||
} else if (success && this.scene.arena.isMoveTerrainCancelled(this.pokemon, this.targets, this.move.getMove())) {
|
|
||||||
success = false;
|
|
||||||
if (failedText === null) {
|
|
||||||
failedText = getTerrainBlockMessage(targets[0], this.scene.arena.terrain?.terrainType!); // TODO: is this bang correct?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trigger pokemon type change before playing the move animation
|
|
||||||
* Will still change the user's type when using Roar, Whirlwind, Trick-or-Treat, and Forest's Curse,
|
|
||||||
* regardless of whether the move successfully executes or not.
|
|
||||||
*/
|
|
||||||
if (success || [Moves.ROAR, Moves.WHIRLWIND, Moves.TRICK_OR_TREAT, Moves.FORESTS_CURSE].includes(this.move.moveId)) {
|
|
||||||
applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
this.scene.unshiftPhase(this.getEffectPhase());
|
|
||||||
} else {
|
|
||||||
this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual });
|
|
||||||
if (!cancelled.value) {
|
|
||||||
this.showFailedText(failedText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Checks if Dancer ability is triggered
|
|
||||||
if (this.move.getMove().hasFlag(MoveFlags.DANCE_MOVE) && !this.followUp) {
|
|
||||||
// Pokemon with Dancer can be on either side of the battle so we check in both cases
|
|
||||||
this.scene.getPlayerField().forEach(pokemon => {
|
|
||||||
applyPostMoveUsedAbAttrs(PostMoveUsedAbAttr, pokemon, this.move, this.pokemon, this.targets);
|
|
||||||
});
|
|
||||||
this.scene.getEnemyField().forEach(pokemon => {
|
|
||||||
applyPostMoveUsedAbAttrs(PostMoveUsedAbAttr, pokemon, this.move, this.pokemon, this.targets);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.end();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles {@link StatusEffect.SLEEP Sleep}/{@link StatusEffect.PARALYSIS Paralysis}/{@link StatusEffect.FREEZE Freeze} rolls and side effects.
|
||||||
|
*/
|
||||||
|
protected resolvePreMoveStatusEffects() {
|
||||||
if (!this.followUp && this.pokemon.status && !this.pokemon.status.isPostTurn()) {
|
if (!this.followUp && this.pokemon.status && !this.pokemon.status.isPostTurn()) {
|
||||||
this.pokemon.status.incrementTurn();
|
this.pokemon.status.incrementTurn();
|
||||||
let activated = false;
|
let activated = false;
|
||||||
@ -273,25 +186,265 @@ export class MovePhase extends BattlePhase {
|
|||||||
if (activated) {
|
if (activated) {
|
||||||
this.scene.queueMessage(getStatusEffectActivationText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon)));
|
this.scene.queueMessage(getStatusEffectActivationText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon)));
|
||||||
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, this.pokemon.getBattlerIndex(), undefined, CommonAnim.POISON + (this.pokemon.status.effect - 1)));
|
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, this.pokemon.getBattlerIndex(), undefined, CommonAnim.POISON + (this.pokemon.status.effect - 1)));
|
||||||
doMove();
|
} else if (healed) {
|
||||||
} else {
|
this.scene.queueMessage(getStatusEffectHealText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon)));
|
||||||
if (healed) {
|
this.pokemon.resetStatus();
|
||||||
this.scene.queueMessage(getStatusEffectHealText(this.pokemon.status.effect, getPokemonNameWithAffix(this.pokemon)));
|
this.pokemon.updateInfo();
|
||||||
this.pokemon.resetStatus();
|
|
||||||
this.pokemon.updateInfo();
|
|
||||||
}
|
|
||||||
doMove();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
doMove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getEffectPhase(): MoveEffectPhase {
|
/**
|
||||||
return new MoveEffectPhase(this.scene, this.pokemon.getBattlerIndex(), this.targets, this.move);
|
* Lapse {@linkcode BattlerTagLapseType.PRE_MOVE PRE_MOVE} tags that trigger before a move is used, regardless of whether or not it failed.
|
||||||
|
* Also lapse {@linkcode BattlerTagLapseType.MOVE MOVE} tags if the move should be successful.
|
||||||
|
*/
|
||||||
|
protected lapsePreMoveAndMoveTags() {
|
||||||
|
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
|
||||||
|
|
||||||
|
// TODO: does this intentionally happen before the no targets/Moves.NONE on queue cancellation case is checked?
|
||||||
|
if (!this.followUp && this.canMove() && !this.cancelled) {
|
||||||
|
this.pokemon.lapseTags(BattlerTagLapseType.MOVE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showMoveText(): void {
|
protected useMove() {
|
||||||
|
const targets = this.getActiveTargetPokemon();
|
||||||
|
const moveQueue = this.pokemon.getMoveQueue();
|
||||||
|
|
||||||
|
// form changes happen even before we know that the move wll execute.
|
||||||
|
this.scene.triggerPokemonFormChange(this.pokemon, SpeciesFormChangePreMoveTrigger);
|
||||||
|
|
||||||
|
this.showMoveText();
|
||||||
|
|
||||||
|
// TODO: Clean up implementation of two-turn moves.
|
||||||
|
if (moveQueue.length > 0) { // Using .shift here clears out two turn moves once they've been used
|
||||||
|
this.ignorePp = moveQueue.shift()?.ignorePP ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "commit" to using the move, deducting PP.
|
||||||
|
if (!this.ignorePp) {
|
||||||
|
const ppUsed = 1 + this.getPpIncreaseFromPressure(targets);
|
||||||
|
|
||||||
|
this.move.usePp(ppUsed);
|
||||||
|
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the battle's "last move" pointer, unless we're currently mimicking a move.
|
||||||
|
if (!allMoves[this.move.moveId].hasAttr(CopyMoveAttr)) {
|
||||||
|
this.scene.currentBattle.lastMove = this.move.moveId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the move is successful (meaning that its damage/effects can be attempted)
|
||||||
|
* by checking that all of the following are true:
|
||||||
|
* - Conditional attributes of the move are all met
|
||||||
|
* - The target's `ForceSwitchOutImmunityAbAttr` is not triggered (see {@linkcode Move.prototype.applyConditions})
|
||||||
|
* - Weather does not block the move
|
||||||
|
* - Terrain does not block the move
|
||||||
|
*
|
||||||
|
* TODO: These steps are straightforward, but the implementation below is extremely convoluted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const move = this.move.getMove();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move conditions assume the move has a single target
|
||||||
|
* TODO: is this sustainable?
|
||||||
|
*/
|
||||||
|
const passesConditions = move.applyConditions(this.pokemon, targets[0], move);
|
||||||
|
const failedDueToWeather: boolean = this.scene.arena.isMoveWeatherCancelled(this.pokemon, move);
|
||||||
|
const failedDueToTerrain: boolean = this.scene.arena.isMoveTerrainCancelled(this.pokemon, this.targets, move);
|
||||||
|
|
||||||
|
const success = passesConditions && !failedDueToWeather && !failedDueToTerrain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the move has not failed, trigger ability-based user type changes and then execute it.
|
||||||
|
*
|
||||||
|
* Notably, Roar, Whirlwind, Trick-or-Treat, and Forest's Curse will trigger these type changes even
|
||||||
|
* if the move fails.
|
||||||
|
*/
|
||||||
|
if (success) {
|
||||||
|
applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove());
|
||||||
|
this.scene.unshiftPhase(new MoveEffectPhase(this.scene, this.pokemon.getBattlerIndex(), this.targets, this.move));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if ([ Moves.ROAR, Moves.WHIRLWIND, Moves.TRICK_OR_TREAT, Moves.FORESTS_CURSE ].includes(this.move.moveId)) {
|
||||||
|
applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual });
|
||||||
|
|
||||||
|
let failedText: string | undefined;
|
||||||
|
const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new Utils.BooleanHolder(false));
|
||||||
|
|
||||||
|
if (failureMessage) {
|
||||||
|
failedText = failureMessage;
|
||||||
|
} else if (failedDueToTerrain) {
|
||||||
|
failedText = getTerrainBlockMessage(this.pokemon, this.scene.arena.getTerrainType());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showFailedText(failedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Dancer, which triggers immediately after a move is used (rather than waiting on `this.end()`).
|
||||||
|
// Note that the `!this.followUp` check here prevents an infinite Dancer loop.
|
||||||
|
if (this.move.getMove().hasFlag(MoveFlags.DANCE_MOVE) && !this.followUp) {
|
||||||
|
this.scene.getField(true).forEach(pokemon => {
|
||||||
|
applyPostMoveUsedAbAttrs(PostMoveUsedAbAttr, pokemon, this.move, this.pokemon, this.targets);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queues a {@linkcode MoveEndPhase} if the move wasn't a {@linkcode followUp} and {@linkcode canMove()} returns `true`,
|
||||||
|
* then ends the phase.
|
||||||
|
*/
|
||||||
|
public end() {
|
||||||
|
if (!this.followUp && this.canMove()) {
|
||||||
|
this.scene.unshiftPhase(new MoveEndPhase(this.scene, this.pokemon.getBattlerIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
super.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies PP increasing abilities (currently only {@link Abilities.PRESSURE Pressure}) if they exist on the target pokemon.
|
||||||
|
* Note that targets must include only active pokemon.
|
||||||
|
*
|
||||||
|
* TODO: This hardcodes the PP increase at 1 per opponent, rather than deferring to the ability.
|
||||||
|
*/
|
||||||
|
public getPpIncreaseFromPressure(targets: Pokemon[]) {
|
||||||
|
const foesWithPressure = this.pokemon.getOpponents().filter(o => targets.includes(o) && o.isActive(true) && o.hasAbilityWithAttr(IncreasePpAbAttr));
|
||||||
|
return foesWithPressure.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies `this.targets` in place, based upon:
|
||||||
|
* - Move redirection abilities, effects, etc.
|
||||||
|
* - Counterattacks, which pass a special value into the `targets` constructor param (`[`{@linkcode BattlerIndex.ATTACKER}`]`).
|
||||||
|
*/
|
||||||
|
protected resolveRedirectTarget() {
|
||||||
|
if (this.targets.length === 1) {
|
||||||
|
const currentTarget = this.targets[0];
|
||||||
|
const redirectTarget = new Utils.NumberHolder(currentTarget);
|
||||||
|
|
||||||
|
// check move redirection abilities of every pokemon *except* the user.
|
||||||
|
this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, redirectTarget));
|
||||||
|
|
||||||
|
/** `true` if an Ability is responsible for redirecting the move to another target; `false` otherwise */
|
||||||
|
let redirectedByAbility = (currentTarget !== redirectTarget.value);
|
||||||
|
|
||||||
|
// check for center-of-attention tags (note that this will override redirect abilities)
|
||||||
|
this.pokemon.getOpponents().forEach(p => {
|
||||||
|
const redirectTag = p.getTag(CenterOfAttentionTag);
|
||||||
|
|
||||||
|
// TODO: don't hardcode this interaction.
|
||||||
|
// Handle interaction between the rage powder center-of-attention tag and moves used by grass types/overcoat-havers (which are immune to RP's redirect)
|
||||||
|
if (redirectTag && (!redirectTag.powder || (!this.pokemon.isOfType(Type.GRASS) && !this.pokemon.hasAbility(Abilities.OVERCOAT)))) {
|
||||||
|
redirectTarget.value = p.getBattlerIndex();
|
||||||
|
redirectedByAbility = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (currentTarget !== redirectTarget.value) {
|
||||||
|
const bypassRedirectAttrs = this.move.getMove().getAttrs(BypassRedirectAttr);
|
||||||
|
bypassRedirectAttrs.forEach((attr) => {
|
||||||
|
if (!attr.abilitiesOnly || redirectedByAbility) {
|
||||||
|
redirectTarget.value = currentTarget;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr)) {
|
||||||
|
redirectTarget.value = currentTarget;
|
||||||
|
this.scene.unshiftPhase(new ShowAbilityPhase(this.scene, this.pokemon.getBattlerIndex(), this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.targets[0] = redirectTarget.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counter-attacking moves pass in `[`{@linkcode BattlerIndex.ATTACKER}`]` into the constructor's `targets` param.
|
||||||
|
* This function modifies `this.targets` to reflect the actual battler index of the user's last
|
||||||
|
* attacker.
|
||||||
|
*
|
||||||
|
* If there is no last attacker, or they are no longer on the field, a message is displayed and the
|
||||||
|
* move is marked for failure.
|
||||||
|
*/
|
||||||
|
protected resolveCounterAttackTarget() {
|
||||||
|
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
|
||||||
|
if (this.pokemon.turnData.attacksReceived.length) {
|
||||||
|
const attacker = this.pokemon.scene.getPokemonById(this.pokemon.turnData.attacksReceived[0].sourceId);
|
||||||
|
|
||||||
|
if (attacker?.isActive(true)) {
|
||||||
|
this.targets[0] = attacker.getBattlerIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
// account for metal burst and comeuppance hitting remaining targets in double battles
|
||||||
|
// counterattack will redirect to remaining ally if original attacker faints
|
||||||
|
if (this.scene.currentBattle.double && this.move.getMove().hasFlag(MoveFlags.REDIRECT_COUNTER)) {
|
||||||
|
if (this.scene.getField()[this.targets[0]].hp === 0) {
|
||||||
|
const opposingField = this.pokemon.isPlayer() ? this.scene.getEnemyField() : this.scene.getPlayerField();
|
||||||
|
this.targets[0] = opposingField.find(p => p.hp > 0)?.getBattlerIndex() ?? BattlerIndex.ATTACKER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.targets[0] === BattlerIndex.ATTACKER) {
|
||||||
|
this.fail();
|
||||||
|
this.showMoveText();
|
||||||
|
this.showFailedText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the case where the move was cancelled or failed:
|
||||||
|
* - Uses PP if the move failed (not cancelled) and should use PP (failed moves are not affected by {@link Abilities.PRESSURE Pressure})
|
||||||
|
* - Records a cancelled OR failed move in move history, so abilities like {@link Abilities.TRUANT Truant} don't trigger on the
|
||||||
|
* next turn and soft-lock.
|
||||||
|
* - Lapses `MOVE_EFFECT` tags:
|
||||||
|
* - Semi-invulnerable battler tags (Fly/Dive/etc.) are intended to lapse on move effects, but also need
|
||||||
|
* to lapse on move failure/cancellation.
|
||||||
|
*
|
||||||
|
* TODO: ...this seems weird.
|
||||||
|
* - Lapses `AFTER_MOVE` tags:
|
||||||
|
* - This handles the effects of {@link Moves.SUBSTITUTE Substitute}
|
||||||
|
* - Removes the second turn of charge moves
|
||||||
|
*
|
||||||
|
* TODO: handle charge moves more gracefully
|
||||||
|
*/
|
||||||
|
protected handlePreMoveFailures() {
|
||||||
|
if (this.cancelled || this.failed) {
|
||||||
|
if (this.failed) {
|
||||||
|
const ppUsed = this.ignorePp ? 0 : 1;
|
||||||
|
|
||||||
|
if (ppUsed) {
|
||||||
|
this.move.usePp();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
|
||||||
|
|
||||||
|
this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT);
|
||||||
|
this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE);
|
||||||
|
|
||||||
|
this.pokemon.getMoveQueue().shift();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the move's usage text to the player, unless it's a charge turn (ie: {@link Moves.SOLAR_BEAM Solar Beam}),
|
||||||
|
* the pokemon is on a recharge turn (ie: {@link Moves.HYPER_BEAM Hyper Beam}), or a 2-turn move was interrupted (ie: {@link Moves.FLY Fly}).
|
||||||
|
*/
|
||||||
|
protected showMoveText(): void {
|
||||||
|
if (this.move.moveId === Moves.NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.move.getMove().hasAttr(ChargeAttr)) {
|
if (this.move.getMove().hasAttr(ChargeAttr)) {
|
||||||
const lastMove = this.pokemon.getLastXMoves() as TurnMove[];
|
const lastMove = this.pokemon.getLastXMoves() as TurnMove[];
|
||||||
if (!lastMove.length || lastMove[0].move !== this.move.getMove().id || lastMove[0].result !== MoveResult.OTHER) {
|
if (!lastMove.length || lastMove[0].move !== this.move.getMove().id || lastMove[0].result !== MoveResult.OTHER) {
|
||||||
@ -311,18 +464,10 @@ export class MovePhase extends BattlePhase {
|
|||||||
pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon),
|
pokemonNameWithAffix: getPokemonNameWithAffix(this.pokemon),
|
||||||
moveName: this.move.getName()
|
moveName: this.move.getName()
|
||||||
}), 500);
|
}), 500);
|
||||||
applyMoveAttrs(PreMoveMessageAttr, this.pokemon, this.pokemon.getOpponents().find(() => true)!, this.move.getMove()); //TODO: is the bang correct here?
|
applyMoveAttrs(PreMoveMessageAttr, this.pokemon, this.pokemon.getOpponents()[0], this.move.getMove());
|
||||||
}
|
}
|
||||||
|
|
||||||
showFailedText(failedText: string | null = null): void {
|
protected showFailedText(failedText?: string): void {
|
||||||
this.scene.queueMessage(failedText || i18next.t("battle:attackFailed"));
|
this.scene.queueMessage(failedText ?? i18next.t("battle:attackFailed"));
|
||||||
}
|
|
||||||
|
|
||||||
end() {
|
|
||||||
if (!this.followUp && this.canMove()) {
|
|
||||||
this.scene.unshiftPhase(new MoveEndPhase(this.scene, this.pokemon.getBattlerIndex()));
|
|
||||||
}
|
|
||||||
|
|
||||||
super.end();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
|||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
// Lapse any residual flinches/endures but ignore all other turn-end battle tags
|
// Lapse any residual flinches/endures but ignore all other turn-end battle tags
|
||||||
const includedLapseTags = [BattlerTagType.FLINCHED, BattlerTagType.ENDURING];
|
const includedLapseTags = [ BattlerTagType.FLINCHED, BattlerTagType.ENDURING ];
|
||||||
const field = this.scene.getField(true).filter(p => p.summonData);
|
const field = this.scene.getField(true).filter(p => p.summonData);
|
||||||
field.forEach(pokemon => {
|
field.forEach(pokemon => {
|
||||||
const tags = pokemon.summonData.tags;
|
const tags = pokemon.summonData.tags;
|
||||||
|
@ -22,7 +22,7 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const enemyField = this.scene.getEnemyField();
|
const enemyField = this.scene.getEnemyField();
|
||||||
const moveTargets: any[] = [this.scene.arenaEnemy, enemyField];
|
const moveTargets: any[] = [ this.scene.arenaEnemy, enemyField ];
|
||||||
const mysteryEncounter = this.scene.currentBattle?.mysteryEncounter?.introVisuals;
|
const mysteryEncounter = this.scene.currentBattle?.mysteryEncounter?.introVisuals;
|
||||||
if (mysteryEncounter) {
|
if (mysteryEncounter) {
|
||||||
moveTargets.push(mysteryEncounter);
|
moveTargets.push(mysteryEncounter);
|
||||||
|
@ -23,7 +23,7 @@ export class NextEncounterPhase extends EncounterPhase {
|
|||||||
this.scene.arenaNextEnemy.setVisible(true);
|
this.scene.arenaNextEnemy.setVisible(true);
|
||||||
|
|
||||||
const enemyField = this.scene.getEnemyField();
|
const enemyField = this.scene.getEnemyField();
|
||||||
const moveTargets: any[] = [this.scene.arenaEnemy, this.scene.arenaNextEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.lastEnemyTrainer];
|
const moveTargets: any[] = [ this.scene.arenaEnemy, this.scene.arenaNextEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.lastEnemyTrainer ];
|
||||||
const lastEncounterVisuals = this.scene.lastMysteryEncounter?.introVisuals;
|
const lastEncounterVisuals = this.scene.lastMysteryEncounter?.introVisuals;
|
||||||
if (lastEncounterVisuals) {
|
if (lastEncounterVisuals) {
|
||||||
moveTargets.push(lastEncounterVisuals);
|
moveTargets.push(lastEncounterVisuals);
|
||||||
|
@ -5,7 +5,6 @@ import Pokemon from "#app/field/pokemon";
|
|||||||
import { BattlePhase } from "#app/phases/battle-phase";
|
import { BattlePhase } from "#app/phases/battle-phase";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class PokemonAnimPhase extends BattlePhase {
|
export class PokemonAnimPhase extends BattlePhase {
|
||||||
/** The type of animation to play in this phase */
|
/** The type of animation to play in this phase */
|
||||||
private key: PokemonAnimType;
|
private key: PokemonAnimType;
|
||||||
@ -53,7 +52,7 @@ export class PokemonAnimPhase extends BattlePhase {
|
|||||||
const sprite = this.scene.addFieldSprite(
|
const sprite = this.scene.addFieldSprite(
|
||||||
this.pokemon.x + this.pokemon.getSprite().x,
|
this.pokemon.x + this.pokemon.getSprite().x,
|
||||||
this.pokemon.y + this.pokemon.getSprite().y,
|
this.pokemon.y + this.pokemon.getSprite().y,
|
||||||
`pkmn${this.pokemon.isPlayer() ? "__back": ""}__sub`
|
`pkmn${this.pokemon.isPlayer() ? "__back" : ""}__sub`
|
||||||
);
|
);
|
||||||
sprite.setOrigin(0.5, 1);
|
sprite.setOrigin(0.5, 1);
|
||||||
this.scene.field.add(sprite);
|
this.scene.field.add(sprite);
|
||||||
@ -179,7 +178,7 @@ export class PokemonAnimPhase extends BattlePhase {
|
|||||||
const sprite = this.scene.addFieldSprite(
|
const sprite = this.scene.addFieldSprite(
|
||||||
subSprite.x,
|
subSprite.x,
|
||||||
subSprite.y,
|
subSprite.y,
|
||||||
`pkmn${this.pokemon.isPlayer() ? "__back": ""}__sub`
|
`pkmn${this.pokemon.isPlayer() ? "__back" : ""}__sub`
|
||||||
);
|
);
|
||||||
sprite.setOrigin(0.5, 1);
|
sprite.setOrigin(0.5, 1);
|
||||||
this.scene.field.add(sprite);
|
this.scene.field.add(sprite);
|
||||||
|
@ -45,7 +45,7 @@ export class SelectBiomePhase extends BattlePhase {
|
|||||||
let biomeChoices: Biome[] = [];
|
let biomeChoices: Biome[] = [];
|
||||||
this.scene.executeWithSeedOffset(() => {
|
this.scene.executeWithSeedOffset(() => {
|
||||||
biomeChoices = (!Array.isArray(biomeLinks[currentBiome])
|
biomeChoices = (!Array.isArray(biomeLinks[currentBiome])
|
||||||
? [biomeLinks[currentBiome] as Biome]
|
? [ biomeLinks[currentBiome] as Biome ]
|
||||||
: biomeLinks[currentBiome] as (Biome | [Biome, integer])[])
|
: biomeLinks[currentBiome] as (Biome | [Biome, integer])[])
|
||||||
.filter((b, i) => !Array.isArray(b) || !Utils.randSeedInt(b[1]))
|
.filter((b, i) => !Array.isArray(b) || !Utils.randSeedInt(b[1]))
|
||||||
.map(b => Array.isArray(b) ? b[0] : b);
|
.map(b => Array.isArray(b) ? b[0] : b);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user