diff --git a/public/images/mystery-encounters/girawitch.png b/public/images/mystery-encounters/girawitch.png deleted file mode 100644 index a1cc7e8448d..00000000000 Binary files a/public/images/mystery-encounters/girawitch.png and /dev/null differ diff --git a/public/images/mystery-encounters/girawitch.json b/public/images/mystery-encounters/global_trade_system.json similarity index 58% rename from public/images/mystery-encounters/girawitch.json rename to public/images/mystery-encounters/global_trade_system.json index 98830a00a72..ae5d96127b7 100644 --- a/public/images/mystery-encounters/girawitch.json +++ b/public/images/mystery-encounters/global_trade_system.json @@ -1,11 +1,11 @@ { "textures": [ { - "image": "girawitch.png", + "image": "global_trade_system.png", "format": "RGBA8888", "size": { - "w": 46, - "h": 76 + "w": 77, + "h": 78 }, "scale": 1, "frames": [ @@ -14,20 +14,20 @@ "rotated": false, "trimmed": false, "sourceSize": { - "w": 46, - "h": 76 + "w": 77, + "h": 78 }, "spriteSourceSize": { "x": 0, "y": 0, - "w": 46, - "h": 76 + "w": 77, + "h": 78 }, "frame": { "x": 0, "y": 0, - "w": 46, - "h": 76 + "w": 77, + "h": 78 } } ] @@ -36,6 +36,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:e68bbc186f511d505c53b2beec3c3741:7108795fc29d953a1d3729ad93d70936:1661aeeeb2f0e4561c644aff254770b3$" + "smartupdate": "$TexturePacker:SmartUpdate:8a51d7a17b3d8c32f0e5e4a0f15daeb4:6eba29c5345847f735d8b69a05fc49d1:98ad8b8b8d8c4865d7d23ec97b516594$" } } diff --git a/public/images/mystery-encounters/global_trade_system.png b/public/images/mystery-encounters/global_trade_system.png new file mode 100644 index 00000000000..cb0ffb0ab20 Binary files /dev/null and b/public/images/mystery-encounters/global_trade_system.png differ diff --git a/public/images/mystery-encounters/gts_placeholder.png b/public/images/mystery-encounters/gts_placeholder.png deleted file mode 100644 index aef027525c8..00000000000 Binary files a/public/images/mystery-encounters/gts_placeholder.png and /dev/null differ diff --git a/public/images/mystery-encounters/gts_placeholder.json b/public/images/mystery-encounters/warehouse_crate.json similarity index 53% rename from public/images/mystery-encounters/gts_placeholder.json rename to public/images/mystery-encounters/warehouse_crate.json index dd96e5892cd..fa86d1a511d 100644 --- a/public/images/mystery-encounters/gts_placeholder.json +++ b/public/images/mystery-encounters/warehouse_crate.json @@ -1,33 +1,33 @@ { "textures": [ { - "image": "gts_placeholder.png", + "image": "warehouse_crate.png", "format": "RGBA8888", "size": { - "w": 47, - "h": 79 + "w": 71, + "h": 52 }, "scale": 1, "frames": [ { - "filename": "0000.png", + "filename": "0001.png", "rotated": false, "trimmed": true, "sourceSize": { "w": 80, - "h": 80 + "h": 56 }, "spriteSourceSize": { - "x": 17, - "y": 1, - "w": 47, - "h": 79 + "x": 5, + "y": 4, + "w": 71, + "h": 52 }, "frame": { "x": 0, "y": 0, - "w": 47, - "h": 79 + "w": 71, + "h": 52 } } ] @@ -36,6 +36,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4e95cf5cd2b0329629c40dfe871e5ae0:cf1cd6aef867fcde2439177ebb561178:39ec800be807afcf5dd13b9cc59fc386$" + "smartupdate": "$TexturePacker:SmartUpdate:c8df5f0b35fb9c2a69b0e4aaa9fa9f91:f1d4643c26f2aed86ad77d354e669aaf:0c073e3c2048ea0779db9429e5e1d8bc$" } } diff --git a/public/images/mystery-encounters/warehouse_crate.png b/public/images/mystery-encounters/warehouse_crate.png new file mode 100644 index 00000000000..fb70a6e534a Binary files /dev/null and b/public/images/mystery-encounters/warehouse_crate.png differ diff --git a/public/images/mystery-encounters/weird_dream_woman.json b/public/images/mystery-encounters/weird_dream_woman.json new file mode 100644 index 00000000000..66a9b8d68db --- /dev/null +++ b/public/images/mystery-encounters/weird_dream_woman.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "weird_dream_woman.png", + "format": "RGBA8888", + "size": { + "w": 78, + "h": 87 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 87 + }, + "spriteSourceSize": { + "x": 1, + "y": 0, + "w": 78, + "h": 87 + }, + "frame": { + "x": 0, + "y": 0, + "w": 78, + "h": 87 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:d3cce87ee0e3a880d840bffe9373d5d4:7c776d33b75abad1fe36b14a5e5734af:56468b7a2883e66dadcd2af13ebd8010$" + } +} diff --git a/public/images/mystery-encounters/weird_dream_woman.png b/public/images/mystery-encounters/weird_dream_woman.png new file mode 100644 index 00000000000..1b8d142ed5b Binary files /dev/null and b/public/images/mystery-encounters/weird_dream_woman.png differ diff --git a/public/images/pokemon/327.png b/public/images/pokemon/327.png index 81e636db632..c103de3916d 100644 Binary files a/public/images/pokemon/327.png and b/public/images/pokemon/327.png differ diff --git a/public/images/pokemon/shiny/327.png b/public/images/pokemon/shiny/327.png index f875dea77cd..56a473a8416 100644 Binary files a/public/images/pokemon/shiny/327.png and b/public/images/pokemon/shiny/327.png differ diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 17d2df63046..55509f1e7b1 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -180,6 +180,13 @@ export default class BattleScene extends SceneBase { public moveAnimations: boolean = true; public expGainsSpeed: integer = 0; public skipSeenDialogues: boolean = false; + /** + * Determines if the egg hatching animation should be skipped + * - 0 = Never (never skip animation) + * - 1 = Ask (ask to skip animation when hatching 2 or more eggs) + * - 2 = Always (automatically skip animation when hatching 2 or more eggs) + */ + public eggSkipPreference: number = 0; /** * Defines the experience gain display mode. @@ -1170,8 +1177,7 @@ export default class BattleScene extends SceneBase { // Check for mystery encounter // Can only occur in place of a standard (non-boss) wild battle, waves 10-180 - const highestMysteryEncounterWave = this.gameMode.maxMysteryEncounterWave; - const lowestMysteryEncounterWave = this.gameMode.minMysteryEncounterWave; + const [lowestMysteryEncounterWave, highestMysteryEncounterWave] = this.gameMode.getMysteryEncounterLegalWaves(); if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(newWaveIndex) && newWaveIndex < highestMysteryEncounterWave && newWaveIndex > lowestMysteryEncounterWave) { const roll = Utils.randSeedInt(MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT); @@ -3104,6 +3110,10 @@ export default class BattleScene extends SceneBase { if (encounterCandidate.encounterTier !== tier) { // Encounter is in tier return false; } + const disabledModes = encounterCandidate.disabledGameModes; + if (disabledModes && disabledModes.length > 0 && disabledModes.includes(this.gameMode.modeId)) { // Encounter is enabled for game mode + return false; + } if (!encounterCandidate.meetsRequirements!(this)) { // Meets encounter requirements return false; } diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index d4e2666cb88..7afcdc45aab 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1885,11 +1885,18 @@ export class CursedTag extends BattlerTag { return ret; } } +/** + * Battler tag for attacks that remove a type post use. + */ +export class RemovedTypeTag extends BattlerTag { + constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: Moves) { + super(tagType, lapseType, 1, sourceMove); + } +} /** - * Battler tag for effects that ground the source, allowing Ground-type moves to hit them. Encompasses two tag types: - * @item `IGNORE_FLYING`: Persistent grounding effects (i.e. from Smack Down and Thousand Waves) - * @item `ROOSTED`: One-turn grounding effects (i.e. from Roost) + * Battler tag for effects that ground the source, allowing Ground-type moves to hit them. + * @description `IGNORE_FLYING`: Persistent grounding effects (i.e. from Smack Down and Thousand Waves) */ export class GroundedTag extends BattlerTag { constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: Moves) { @@ -1897,6 +1904,70 @@ export class GroundedTag extends BattlerTag { } } +/** + * @description `ROOSTED`: Tag for temporary grounding if only source of ungrounding is flying and pokemon uses Roost. + * Roost removes flying type from a pokemon for a single turn. + */ + +export class RoostedTag extends BattlerTag { + private isBaseFlying : boolean; + private isBasePureFlying : boolean; + + constructor() { + super(BattlerTagType.ROOSTED, BattlerTagLapseType.TURN_END, 1, Moves.ROOST); + } + + onRemove(pokemon: Pokemon): void { + const currentTypes = pokemon.getTypes(); + const baseTypes = pokemon.getTypes(false, false, true); + + const forestsCurseApplied: boolean = currentTypes.includes(Type.GRASS) && !baseTypes.includes(Type.GRASS); + const trickOrTreatApplied: boolean = currentTypes.includes(Type.GHOST) && !baseTypes.includes(Type.GHOST); + + if (this.isBaseFlying) { + let modifiedTypes: Type[] = []; + if (this.isBasePureFlying) { + if (forestsCurseApplied || trickOrTreatApplied) { + modifiedTypes = currentTypes.filter(type => type !== Type.NORMAL); + modifiedTypes.push(Type.FLYING); + } else { + modifiedTypes = [Type.FLYING]; + } + } else { + modifiedTypes = [...currentTypes]; + modifiedTypes.push(Type.FLYING); + } + pokemon.summonData.types = modifiedTypes; + pokemon.updateInfo(); + } + } + + onAdd(pokemon: Pokemon): void { + const currentTypes = pokemon.getTypes(); + const baseTypes = pokemon.getTypes(false, false, true); + + const isOriginallyDualType = baseTypes.length === 2; + const isCurrentlyDualType = currentTypes.length === 2; + this.isBaseFlying = baseTypes.includes(Type.FLYING); + this.isBasePureFlying = baseTypes[0] === Type.FLYING && baseTypes.length === 1; + + if (this.isBaseFlying) { + let modifiedTypes: Type[]; + if (this.isBasePureFlying && !isCurrentlyDualType) { + modifiedTypes = [Type.NORMAL]; + } else { + if (!!pokemon.getTag(RemovedTypeTag) && isOriginallyDualType && !isCurrentlyDualType) { + modifiedTypes = [Type.UNKNOWN]; + } else { + modifiedTypes = currentTypes.filter(type => type !== Type.FLYING); + } + } + pokemon.summonData.types = modifiedTypes; + pokemon.updateInfo(); + } + } +} + /** Common attributes of form change abilities that block damage */ export class FormBlockDamageTag extends BattlerTag { constructor(tagType: BattlerTagType) { @@ -2295,7 +2366,11 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source case BattlerTagType.IGNORE_FLYING: return new GroundedTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); case BattlerTagType.ROOSTED: - return new GroundedTag(tagType, BattlerTagLapseType.TURN_END, sourceMove); + return new RoostedTag(); + case BattlerTagType.BURNED_UP: + return new RemovedTypeTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); + case BattlerTagType.DOUBLE_SHOCKED: + return new RemovedTypeTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); case BattlerTagType.SALT_CURED: return new SaltCuredTag(sourceId); case BattlerTagType.CURSED: diff --git a/src/data/move.ts b/src/data/move.ts index 672a1154a0e..f09f8db7487 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -8532,6 +8532,7 @@ export function initMoves() { return userTypes.includes(Type.FIRE); }) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) + .attr(AddBattlerTagAttr, BattlerTagType.BURNED_UP, true, false) .attr(RemoveTypeAttr, Type.FIRE, (user) => { user.scene.queueMessage(i18next.t("moveTriggers:burnedItselfOut", {pokemonName: getPokemonNameWithAffix(user)})); }), @@ -9315,6 +9316,7 @@ export function initMoves() { const userTypes = user.getTypes(true); return userTypes.includes(Type.ELECTRIC); }) + .attr(AddBattlerTagAttr, BattlerTagType.DOUBLE_SHOCKED, true, false) .attr(RemoveTypeAttr, Type.ELECTRIC, (user) => { user.scene.queueMessage(i18next.t("moveTriggers:usedUpAllElectricity", {pokemonName: getPokemonNameWithAffix(user)})); }), diff --git a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts index 0d26036120f..e00a9c1ad38 100644 --- a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts +++ b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts @@ -266,7 +266,7 @@ async function tryGiveBerry(scene: BattleScene, prioritizedPokemon?: PlayerPokem if (!heldBerriesOfType || heldBerriesOfType.getStackCount() < heldBerriesOfType.getMaxStackCount(scene)) { await applyModifierTypeToPlayerPokemon(scene, pokemon, berry); - break; + return; } } } diff --git a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts index 5266ff4859f..9a94ac9bbbe 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -424,7 +424,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = scene.updateModifiers(true, true); const bugNet = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!; - bugNet.type.tier = ModifierTier.MASTER; + bugNet.type.tier = ModifierTier.ROGUE; setEncounterRewards(scene, { guaranteedModifierTypeOptions: [bugNet], guaranteedModifierTypeFuncs: [modifierTypes.REVIVER_SEED], fillRemaining: false }); leaveEncounterWithoutBattle(scene, true); diff --git a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts index 4fb33a982ff..7c8503c3921 100644 --- a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts +++ b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts @@ -29,6 +29,7 @@ import { Moves } from "#enums/moves"; import { EncounterAnim, EncounterBattleAnim } from "#app/data/battle-anims"; import { MoveCategory } from "#app/data/move"; import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { GameModes } from "#app/game-mode"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounter:clowningAround"; @@ -59,6 +60,7 @@ const RANDOM_ABILITY_POOL = [ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.CLOWNING_AROUND) .withEncounterTier(MysteryEncounterTier.ULTRA) + .withDisabledGameModes(GameModes.CHALLENGE) .withSceneWaveRangeRequirement(80, 180) .withAnimations(EncounterAnim.SMOKESCREEN) .withAutoHideIntroVisuals(false) diff --git a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts index 6484cab184a..0b8f590e3ba 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -19,7 +19,7 @@ import PokemonData from "#app/system/pokemon-data"; import i18next from "i18next"; import { Gender, getGenderSymbol } from "#app/data/gender"; import { getNatureName } from "#app/data/nature"; -import { getPokeballAtlasKey, getPokeballTintColor } from "#app/data/pokeball"; +import { getPokeballAtlasKey, getPokeballTintColor, PokeballType } from "#app/data/pokeball"; import { getEncounterText, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { trainerNamePools } from "#app/data/trainer-names"; @@ -74,10 +74,13 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = .withAutoHideIntroVisuals(false) .withIntroSpriteConfigs([ { - spriteKey: "gts_placeholder", + spriteKey: "global_trade_system", fileRoot: "mystery-encounters", - hasShadow: false, - disableAnimation: true + hasShadow: true, + disableAnimation: true, + x: 3, + y: 5, + yShadow: 1 } ]) .withIntroDialogue([ @@ -92,11 +95,14 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; // Load bgm + let bgmKey: string; if (scene.musicPreference === 0) { - scene.loadBgm("mystery_encounter_gen_5_gts", "mystery_encounter_gen_5_gts.mp3"); + bgmKey = "mystery_encounter_gen_5_gts"; + scene.loadBgm(bgmKey, `${bgmKey}.mp3`); } else { // Mixed option - scene.loadBgm("mystery_encounter_gen_6_gts", "mystery_encounter_gen_6_gts.mp3"); + bgmKey = "mystery_encounter_gen_6_gts"; + scene.loadBgm(bgmKey, `${bgmKey}.mp3`); } // Load possible trade options @@ -104,7 +110,8 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = // None of the trade options can be the same species const tradeOptionsMap: Map = getPokemonTradeOptions(scene); encounter.misc = { - tradeOptionsMap + tradeOptionsMap, + bgmKey }; return true; @@ -113,11 +120,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = // Change the bgm scene.fadeOutBgm(1500, false); scene.time.delayedCall(1500, () => { - if (scene.musicPreference === 0) { - scene.playBgm("mystery_encounter_gen_5_gts"); - } else { - scene.playBgm("mystery_encounter_gen_6_gts"); - } + scene.playBgm(scene.currentBattle.mysteryEncounter!.misc.bgmKey); }); return true; @@ -147,17 +150,15 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = // Pokemon trade selected encounter.setDialogueToken("tradedPokemon", pokemon.getNameToRender()); encounter.setDialogueToken("received", tradePokemon.getNameToRender()); - encounter.misc = { - tradedPokemon: pokemon, - receivedPokemon: tradePokemon, - }; + encounter.misc.tradedPokemon = pokemon; + encounter.misc.receivedPokemon = tradePokemon; return true; }, onHover: () => { const formName = tradePokemon.species.forms?.[pokemon.formIndex]?.formName; const line1 = i18next.t("pokemonInfoContainer:ability") + " " + tradePokemon.getAbility().name + (tradePokemon.getGender() !== Gender.GENDERLESS ? " | " + i18next.t("pokemonInfoContainer:gender") + " " + getGenderSymbol(tradePokemon.getGender()) : ""); const line2 = i18next.t("pokemonInfoContainer:nature") + " " + getNatureName(tradePokemon.getNature()) + (formName ? " | " + i18next.t("pokemonInfoContainer:form") + " " + formName : ""); - showEncounterText(scene, `${line1}\n${line2}`, 0); + showEncounterText(scene, `${line1}\n${line2}`, 0, 0, false); }, }; return option; @@ -181,7 +182,8 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = // Set data properly, then generate the new Pokemon's assets receivedPokemonData.passive = tradedPokemon.passive; - receivedPokemonData.pokeball = randSeedInt(5); + // Pokeball to Ultra ball, randomly + receivedPokemonData.pokeball = randInt(4) as PokeballType; const dataSource = new PokemonData(receivedPokemonData); const newPlayerPokemon = scene.addPlayerPokemon(receivedPokemonData.species, receivedPokemonData.level, dataSource.abilityIndex, dataSource.formIndex, dataSource.gender, dataSource.shiny, dataSource.variant, dataSource.ivs, dataSource.nature, dataSource); scene.getParty().push(newPlayerPokemon); @@ -196,7 +198,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = await showTradeBackground(scene); await doPokemonTradeSequence(scene, tradedPokemon, newPlayerPokemon); await showEncounterText(scene, `${namespace}.trade_received`, null, 0, true, 4000); - scene.playBgm("mystery_encounter_gts"); + scene.playBgm(encounter.misc.bgmKey); await hideTradeBackground(scene); tradedPokemon.destroy(); @@ -241,10 +243,8 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = encounter.setDialogueToken("tradedPokemon", pokemon.getNameToRender()); encounter.setDialogueToken("received", tradePokemon.getNameToRender()); - encounter.misc = { - tradedPokemon: pokemon, - receivedPokemon: tradePokemon, - }; + encounter.misc.tradedPokemon = pokemon; + encounter.misc.receivedPokemon = tradePokemon; }; return selectPokemonForOption(scene, onPokemonSelected); @@ -264,7 +264,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = // Set data properly, then generate the new Pokemon's assets receivedPokemonData.passive = tradedPokemon.passive; - receivedPokemonData.pokeball = randSeedInt(5); + receivedPokemonData.pokeball = randInt(4) as PokeballType; const dataSource = new PokemonData(receivedPokemonData); const newPlayerPokemon = scene.addPlayerPokemon(receivedPokemonData.species, receivedPokemonData.level, dataSource.abilityIndex, dataSource.formIndex, dataSource.gender, dataSource.shiny, dataSource.variant, dataSource.ivs, dataSource.nature, dataSource); scene.getParty().push(newPlayerPokemon); @@ -279,7 +279,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = await showTradeBackground(scene); await doPokemonTradeSequence(scene, tradedPokemon, newPlayerPokemon); await showEncounterText(scene, `${namespace}.trade_received`, null, 0, true, 4000); - scene.playBgm("mystery_encounter_gts"); + scene.playBgm(scene.currentBattle.mysteryEncounter!.misc.bgmKey); await hideTradeBackground(scene); tradedPokemon.destroy(); @@ -309,9 +309,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = handler: () => { // Pokemon and item selected encounter.setDialogueToken("chosenItem", modifier.type.name); - encounter.misc = { - chosenModifier: modifier, - }; + encounter.misc.chosenModifier = modifier; return true; }, }; diff --git a/src/data/mystery-encounters/encounters/part-timer-encounter.ts b/src/data/mystery-encounters/encounters/part-timer-encounter.ts index 8dffeac6cb2..dff12a18cd3 100644 --- a/src/data/mystery-encounters/encounters/part-timer-encounter.ts +++ b/src/data/mystery-encounters/encounters/part-timer-encounter.ts @@ -25,19 +25,19 @@ export const PartTimerEncounter: MysteryEncounter = .withEncounterTier(MysteryEncounterTier.COMMON) .withSceneWaveRangeRequirement(10, 180) .withIntroSpriteConfigs([ + { + spriteKey: "warehouse_crate", + fileRoot: "mystery-encounters", + hasShadow: false, + y: 6, + x: 15 + }, { spriteKey: "worker_f", fileRoot: "trainer", hasShadow: true, - x: -20 - }, - { - spriteKey: "training_gear", - fileRoot: "mystery-encounters", - hasShadow: true, - y: 6, - x: 20, - yShadow: -2 + x: -18, + y: 4 } ]) .withAutoHideIntroVisuals(false) diff --git a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts index 05ce57b5e47..06a1de56fae 100644 --- a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts @@ -1,4 +1,4 @@ -import { EnemyPartyConfig, generateModifierType, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { EnemyPartyConfig, generateModifierType, generateModifierTypeOption, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "#app/battle-scene"; @@ -21,6 +21,7 @@ import { PartyHealPhase } from "#app/phases/party-heal-phase"; import { ShowTrainerPhase } from "#app/phases/show-trainer-phase"; import { ReturnPhase } from "#app/phases/return-phase"; import i18next from "i18next"; +import { ModifierTier } from "#app/modifier/modifier-tier"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounter:theWinstrateChallenge"; @@ -149,9 +150,12 @@ async function spawnNextTrainerOrEndEncounter(scene: BattleScene) { await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name })); await showEncounterDialogue(scene, `${namespace}.victory_2`, `${namespace}.speaker`); - setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE], fillRemaining: false }); + scene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in + const machoBrace = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!; + machoBrace.type.tier = ModifierTier.MASTER; + setEncounterRewards(scene, { guaranteedModifierTypeOptions: [machoBrace], fillRemaining: false }); encounter.doContinueEncounter = undefined; - leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.TRAINER_BATTLE); + leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.NO_BATTLE); } else { await initBattleWithEnemyConfig(scene, nextConfig); } diff --git a/src/data/mystery-encounters/encounters/training-session-encounter.ts b/src/data/mystery-encounters/encounters/training-session-encounter.ts index 92308594f79..1416ad971e0 100644 --- a/src/data/mystery-encounters/encounters/training-session-encounter.ts +++ b/src/data/mystery-encounters/encounters/training-session-encounter.ts @@ -305,7 +305,7 @@ export const TrainingSessionEncounter: MysteryEncounter = return true; }, onHover: () => { - showEncounterText(scene, ability.description, 0); + showEncounterText(scene, ability.description, 0, 0, false); }, }; optionSelectItems.push(option); diff --git a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts index 27e82a37f2d..3b7b507af75 100644 --- a/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts +++ b/src/data/mystery-encounters/encounters/uncommon-breed-encounter.ts @@ -53,16 +53,15 @@ export const UncommonBreedEncounter: MysteryEncounter = const species = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true); const pokemon = new EnemyPokemon(scene, species, level, TrainerSlot.NONE, true); const speciesRootForm = pokemon.species.getRootSpeciesId(); - encounter.misc = { - pokemon - }; // Pokemon will always have one of its egg moves in its moveset if (speciesEggMoves.hasOwnProperty(speciesRootForm)) { const eggMoves: Moves[] = speciesEggMoves[speciesRootForm]; const eggMoveIndex = randSeedInt(4); const randomEggMove: Moves = eggMoves[eggMoveIndex]; - encounter.misc.eggMove = randomEggMove; + encounter.misc = { + eggMove: randomEggMove + }; if (pokemon.moveset.length < 4) { pokemon.moveset.push(new PokemonMove(randomEggMove)); } else { @@ -70,6 +69,8 @@ export const UncommonBreedEncounter: MysteryEncounter = } } + encounter.misc.pokemon = pokemon; + const config: EnemyPartyConfig = { pokemonConfigs: [{ level: level, @@ -184,7 +185,7 @@ export const UncommonBreedEncounter: MysteryEncounter = berryItems.splice(index, 1); } } - scene.updateModifiers(true, true); + await scene.updateModifiers(true, true); // Pokemon joins the team, with 2 egg moves const encounter = scene.currentBattle.mysteryEncounter!; diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index 5ece733b7f5..7cdf1e12ded 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -20,6 +20,7 @@ import i18next from "#app/plugins/i18n"; import { doPokemonTransformationSequence, TransformationScreenPosition } from "#app/data/mystery-encounters/utils/encounter-transformation-sequence"; import { getLevelTotalExp } from "#app/data/exp"; import { Stat } from "#enums/stat"; +import { GameModes } from "#app/game-mode"; /** i18n namespace for encounter */ const namespace = "mysteryEncounter:weirdDream"; @@ -94,13 +95,16 @@ const STANDARD_BST_TRANSFORM_BASE_VALUES = [40, 50]; export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.WEIRD_DREAM) .withEncounterTier(MysteryEncounterTier.ROGUE) + .withDisabledGameModes(GameModes.CHALLENGE) .withSceneWaveRangeRequirement(10, 180) .withIntroSpriteConfigs([ { - spriteKey: "girawitch", + spriteKey: "weird_dream_woman", fileRoot: "mystery-encounters", - hasShadow: false, - y: 4 + hasShadow: true, + y: 11, + yShadow: 6, + x: 4 }, ]) .withIntroDialogue([ diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts index 7871c459fae..9b7a1635794 100644 --- a/src/data/mystery-encounters/mystery-encounter.ts +++ b/src/data/mystery-encounters/mystery-encounter.ts @@ -14,6 +14,7 @@ import { EncounterAnim } from "#app/data/battle-anims"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterMode } from "#enums/mystery-encounter-mode"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; +import { GameModes } from "#app/game-mode"; export interface EncounterStartOfBattleEffect { sourcePokemon?: Pokemon; @@ -36,6 +37,7 @@ export interface IMysteryEncounter { spriteConfigs: MysteryEncounterSpriteConfig[]; encounterTier: MysteryEncounterTier; encounterAnimations?: EncounterAnim[]; + disabledGameModes?: GameModes[]; hideBattleIntroMessage: boolean; autoHideIntroVisuals: boolean; enterIntroVisualsFromRight: boolean; @@ -85,6 +87,10 @@ export default class MysteryEncounter implements IMysteryEncounter { * Specify here so that assets are loaded on initialization of encounter */ encounterAnimations?: EncounterAnim[]; + /** + * If specified, defines any game modes where the MysteryEncounter should *NOT* spawn + */ + disabledGameModes?: GameModes[]; /** * If true, hides "A Wild X Appeared" etc. messages * Default true @@ -630,6 +636,16 @@ export class MysteryEncounterBuilder implements Partial { return Object.assign(this, { encounterAnimations: animations }); } + /** + * Defines any game modes where the Mystery Encounter should *NOT* spawn + * @returns + * @param disabledGameModes + */ + withDisabledGameModes(...disabledGameModes: GameModes[]): this & Required> { + const gameModes = Array.isArray(disabledGameModes) ? disabledGameModes : [disabledGameModes]; + return Object.assign(this, { disabledGameModes: gameModes }); + } + /** * If true, encounter will continuously run through multiple battles/puzzles/etc. instead of going to next wave * MUST EVENTUALLY BE DISABLED TO CONTINUE TO NEXT WAVE diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index f3997706f16..55d3a598d0c 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -456,7 +456,7 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p return true; }, onHover: () => { - showEncounterText(scene, i18next.t("mysteryEncounterMessages:cancel_option"), 0); + showEncounterText(scene, i18next.t("mysteryEncounterMessages:cancel_option"), 0, 0, false); } }); @@ -570,7 +570,7 @@ export function selectOptionThenPokemon(scene: BattleScene, options: OptionSelec if (onHoverOverCancelOption) { onHoverOverCancelOption(); } - scene.ui.showText(i18next.t("mysteryEncounterMessages:cancel_option")); + showEncounterText(scene, i18next.t("mysteryEncounterMessages:cancel_option"), 0, 0, false); } }); diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index d6b30522a7b..64e180d0f9b 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -665,6 +665,24 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali return this.getSpeciesForLevel(level, allowEvolving, true, strength, currentWave); } + /** + * @see {@linkcode getSpeciesForLevel} uses an ease in and ease out sine function: + * @see {@link https://easings.net/#easeInSine} + * @see {@link https://easings.net/#easeOutSine} + * Ease in is similar to an exponential function with slower growth, as in, x is directly related to y, and increase in y is higher for higher x. + * Ease out looks more similar to a logarithmic function shifted to the left. It's still a direct relation but it plateaus instead of increasing in growth. + * + * This function is used to calculate the x given to these functions, which is used for evolution chance. + * + * First is maxLevelDiff, which is a denominator for evolution chance for mons without wild evolution delay. + * This means a lower value of x will lead to a higher evolution chance. + * + * It's also used for preferredMinLevel, which is used when an evolution delay exists. + * The calculation with evolution delay is a weighted average of the easeIn and easeOut functions where preferredMinLevel is the denominator. + * This also means a lower value of x will lead to a higher evolution chance. + * @param strength {@linkcode PartyMemberStrength} The strength of the party member in question + * @returns {@linkcode integer} The level difference from expected evolution level tolerated for a mon to be unevolved. Lower value = higher evolution chance. + */ private getStrengthLevelDiff(strength: PartyMemberStrength): integer { switch (Math.min(strength, PartyMemberStrength.STRONGER)) { case PartyMemberStrength.WEAKEST: @@ -674,9 +692,9 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali case PartyMemberStrength.WEAK: return 20; case PartyMemberStrength.AVERAGE: - return 10; + return 8; case PartyMemberStrength.STRONG: - return 5; + return 4; default: return 0; } @@ -724,7 +742,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali if (strength === PartyMemberStrength.STRONGER) { evolutionChance = 1; } else { - const maxLevelDiff = this.getStrengthLevelDiff(strength); + const maxLevelDiff = this.getStrengthLevelDiff(strength); //The maximum distance from the evolution level tolerated for the mon to not evolve const minChance: number = 0.875 - 0.125 * strength; evolutionChance = Math.min(minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance), 1); @@ -743,11 +761,6 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali evolutionChance = Math.min(0.65 * easeInFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel) / preferredMinLevel) + 0.35 * easeOutFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel * 2.5) / (preferredMinLevel * 2.5)), 1); } } - /* (Most) Trainers shouldn't be using unevolved Pokemon by the third gym leader / wave 80. Exceptions to this include Breeders, whose large teams are balanced by the use of weaker pokemon */ - if (currentWave >= 80 && forTrainer && strength > PartyMemberStrength.WEAKER) { - evolutionChance = 1; - noEvolutionChance = 0; - } if (evolutionChance > 0) { if (isRegionalEvolution) { diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 411a37ed4c8..66d0d5464ad 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -556,64 +556,64 @@ export class TrainerConfig { switch (team) { case "rocket": { return { - [TrainerPoolTier.COMMON]: [Species.RATTATA, Species.KOFFING, Species.EKANS, Species.GYARADOS, Species.TAUROS, Species.SCYTHER, Species.CUBONE, Species.GROWLITHE, Species.MURKROW, Species.GASTLY, Species.EXEGGCUTE, Species.VOLTORB], - [TrainerPoolTier.UNCOMMON]: [Species.PORYGON, Species.ALOLA_RATTATA, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE], + [TrainerPoolTier.COMMON]: [Species.RATTATA, Species.KOFFING, Species.EKANS, Species.ZUBAT, Species.MAGIKARP, Species.HOUNDOUR, Species.ONIX, Species.CUBONE, Species.GROWLITHE, Species.MURKROW, Species.GASTLY, Species.EXEGGCUTE, Species.VOLTORB, Species.DROWZEE, Species.VILEPLUME], + [TrainerPoolTier.UNCOMMON]: [Species.PORYGON, Species.MANKEY, Species.MAGNEMITE, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE, Species.PALDEA_TAUROS, Species.OMANYTE, Species.KABUTO, Species.MAGBY, Species.ELEKID], [TrainerPoolTier.RARE]: [Species.DRATINI, Species.LARVITAR] }; } case "magma": { return { - [TrainerPoolTier.COMMON]: [Species.NUMEL, Species.POOCHYENA, Species.SLUGMA, Species.SOLROCK, Species.HIPPOPOTAS, Species.SANDACONDA, Species.PHANPY, Species.ROLYCOLY, Species.GLIGAR], - [TrainerPoolTier.UNCOMMON]: [Species.TRAPINCH, Species.HEATMOR], + [TrainerPoolTier.COMMON]: [Species.GROWLITHE, Species.SLUGMA, Species.SOLROCK, Species.HIPPOPOTAS, Species.BALTOY, Species.ROLYCOLY, Species.GLIGAR, Species.TORKOAL, Species.HOUNDOUR, Species.MAGBY], + [TrainerPoolTier.UNCOMMON]: [Species.TRAPINCH, Species.SILICOBRA, Species.RHYHORN, Species.ANORITH, Species.LILEEP, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON, Species.BARBOACH], [TrainerPoolTier.RARE]: [Species.CAPSAKID, Species.CHARCADET] }; } case "aqua": { return { - [TrainerPoolTier.COMMON]: [Species.CARVANHA, Species.CORPHISH, Species.ZIGZAGOON, Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.QWILFISH], - [TrainerPoolTier.UNCOMMON]: [Species.MANTINE, Species.BASCULEGION, Species.REMORAID, Species.ARROKUDA], - [TrainerPoolTier.RARE]: [Species.DONDOZO] + [TrainerPoolTier.COMMON]: [Species.CORPHISH, Species.SPHEAL, Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.AZURILL, Species.LOTAD, Species.WAILMER, Species.REMORAID], + [TrainerPoolTier.UNCOMMON]: [Species.MANTYKE, Species.HISUI_QWILFISH, Species.ARROKUDA, Species.DHELMISE, Species.CLOBBOPUS, Species.FEEBAS, Species.PALDEA_WOOPER, Species.HORSEA, Species.SKRELP], + [TrainerPoolTier.RARE]: [Species.DONDOZO, Species.BASCULEGION] }; } case "galactic": { return { - [TrainerPoolTier.COMMON]: [Species.GLAMEOW, Species.STUNKY, Species.BRONZOR, Species.CARNIVINE, Species.GROWLITHE, Species.QWILFISH, Species.SNEASEL], - [TrainerPoolTier.UNCOMMON]: [Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.HISUI_SNEASEL], - [TrainerPoolTier.RARE]: [Species.HISUI_ZORUA, Species.HISUI_SLIGGOO] + [TrainerPoolTier.COMMON]: [Species.BRONZOR, Species.SWINUB, Species.YANMA, Species.LICKITUNG, Species.TANGELA, Species.MAGBY, Species.ELEKID, Species.SKORUPI, Species.ZUBAT, Species.MURKROW, Species.MAGIKARP, Species.VOLTORB], + [TrainerPoolTier.UNCOMMON]: [Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.SNEASEL, Species.DUSKULL, Species.ROTOM, Species.HISUI_VOLTORB, Species.GLIGAR, Species.ABRA], + [TrainerPoolTier.RARE]: [Species.URSALUNA, Species.HISUI_LILLIGANT, Species.SPIRITOMB, Species.HISUI_SNEASEL] }; } case "plasma": { return { - [TrainerPoolTier.COMMON]: [Species.SCRAFTY, Species.LILLIPUP, Species.PURRLOIN, Species.FRILLISH, Species.VENIPEDE, Species.GOLETT, Species.TIMBURR, Species.DARUMAKA, Species.AMOONGUSS], - [TrainerPoolTier.UNCOMMON]: [Species.PAWNIARD, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.KLINK], - [TrainerPoolTier.RARE]: [Species.DRUDDIGON, Species.BOUFFALANT, Species.AXEW, Species.DEINO, Species.DURANT] + [TrainerPoolTier.COMMON]: [Species.YAMASK, Species.ROGGENROLA, Species.JOLTIK, Species.TYMPOLE, Species.FRILLISH, Species.FERROSEED, Species.SANDILE, Species.TIMBURR, Species.DARUMAKA, Species.FOONGUS, Species.CUBCHOO, Species.VANILLITE], + [TrainerPoolTier.UNCOMMON]: [Species.PAWNIARD, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.KLINK, Species.TYNAMO, Species.GALAR_DARUMAKA, Species.GOLETT, Species.MIENFOO, Species.DURANT, Species.SIGILYPH], + [TrainerPoolTier.RARE]: [Species.HISUI_ZORUA, Species.AXEW, Species.DEINO, Species.HISUI_BRAVIARY] }; } case "flare": { return { - [TrainerPoolTier.COMMON]: [Species.FLETCHLING, Species.LITLEO, Species.INKAY, Species.HELIOPTILE, Species.ELECTRIKE, Species.SKRELP, Species.GULPIN, Species.PURRLOIN, Species.POOCHYENA, Species.SCATTERBUG], - [TrainerPoolTier.UNCOMMON]: [Species.LITWICK, Species.SNEASEL, Species.PANCHAM, Species.PAWNIARD], - [TrainerPoolTier.RARE]: [Species.NOIVERN, Species.DRUDDIGON] + [TrainerPoolTier.COMMON]: [Species.FLETCHLING, Species.LITLEO, Species.INKAY, Species.HELIOPTILE, Species.ELECTRIKE, Species.SKORUPI, Species.PURRLOIN, Species.CLAWITZER, Species.PANCHAM, Species.ESPURR, Species.BUNNELBY], + [TrainerPoolTier.UNCOMMON]: [Species.LITWICK, Species.SNEASEL, Species.PUMPKABOO, Species.PHANTUMP, Species.HONEDGE, Species.BINACLE, Species.BERGMITE, Species.HOUNDOUR, Species.SKRELP, Species.SLIGGOO], + [TrainerPoolTier.RARE]: [Species.NOIVERN, Species.HISUI_AVALUGG, Species.HISUI_SLIGGOO] }; } case "aether": { return { - [TrainerPoolTier.COMMON]: [ Species.BRUXISH, Species.SLOWPOKE, Species.BALTOY, Species.EXEGGCUTE, Species.ABRA, Species.ALOLA_RAICHU, Species.ELGYEM, Species.NATU], - [TrainerPoolTier.UNCOMMON]: [Species.GALAR_SLOWKING, Species.MEDITITE, Species.BELDUM, Species.ORANGURU, Species.HATTERENE, Species.INKAY, Species.RALTS], - [TrainerPoolTier.RARE]: [Species.ARMAROUGE, Species.GIRAFARIG, Species.PORYGON] + [TrainerPoolTier.COMMON]: [ Species.BRUXISH, Species.SLOWPOKE, Species.BALTOY, Species.EXEGGCUTE, Species.ABRA, Species.ALOLA_RAICHU, Species.ELGYEM, Species.NATU, Species.BLIPBUG, Species.GIRAFARIG, Species.ORANGURU], + [TrainerPoolTier.UNCOMMON]: [Species.GALAR_SLOWPOKE, Species.MEDITITE, Species.BELDUM, Species.HATENNA, Species.INKAY, Species.RALTS, Species.GALAR_MR_MIME], + [TrainerPoolTier.RARE]: [Species.ARMAROUGE, Species.HISUI_BRAVIARY, Species.PORYGON] }; } case "skull": { return { - [TrainerPoolTier.COMMON]: [ Species.MAREANIE, Species.ALOLA_GRIMER, Species.GASTLY, Species.ZUBAT, Species.LURANTIS, Species.VENIPEDE, Species.BUDEW, Species.KOFFING], - [TrainerPoolTier.UNCOMMON]: [Species.GALAR_SLOWBRO, Species.SKORUPI, Species.PALDEA_WOOPER, Species.NIDORAN_F, Species.CROAGUNK, Species.MANDIBUZZ], - [TrainerPoolTier.RARE]: [Species.DRAGALGE, Species.HISUI_SNEASEL] + [TrainerPoolTier.COMMON]: [ Species.MAREANIE, Species.ALOLA_GRIMER, Species.GASTLY, Species.ZUBAT, Species.FOMANTIS, Species.VENIPEDE, Species.BUDEW, Species.KOFFING, Species.STUNKY, Species.CROAGUNK, Species.NIDORAN_F], + [TrainerPoolTier.UNCOMMON]: [Species.GALAR_SLOWPOKE, Species.SKORUPI, Species.PALDEA_WOOPER, Species.VULLABY, Species.HISUI_QWILFISH, Species.GLIMMET], + [TrainerPoolTier.RARE]: [Species.SKRELP, Species.HISUI_SNEASEL] }; } case "macro": { return { - [TrainerPoolTier.COMMON]: [ Species.HATTERENE, Species.MILOTIC, Species.TSAREENA, Species.SALANDIT, Species.GALAR_PONYTA, Species.GOTHITA, Species.FROSLASS], - [TrainerPoolTier.UNCOMMON]: [Species.MANDIBUZZ, Species.MAREANIE, Species.ALOLA_VULPIX, Species.TOGEPI, Species.GALAR_CORSOLA, Species.SINISTEA, Species.APPLIN], + [TrainerPoolTier.COMMON]: [ Species.HATENNA, Species.FEEBAS, Species.BOUNSWEET, Species.SALANDIT, Species.GALAR_PONYTA, Species.GOTHITA, Species.FROSLASS, Species.VULPIX, Species.FRILLISH, Species.ODDISH, Species.SINISTEA], + [TrainerPoolTier.UNCOMMON]: [Species.VULLABY, Species.MAREANIE, Species.ALOLA_VULPIX, Species.TOGEPI, Species.GALAR_CORSOLA, Species.APPLIN], [TrainerPoolTier.RARE]: [Species.TINKATINK, Species.HISUI_LILLIGANT] }; } @@ -1425,9 +1425,9 @@ export const trainerConfigs: TrainerConfigs = { ), [TrainerType.ROCKET_GRUNT]: new TrainerConfig(++t).setHasGenders("Rocket Grunt Female").setHasDouble("Rocket Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.WEEDLE, Species.RATTATA, Species.EKANS, Species.SANDSHREW, Species.ZUBAT, Species.GEODUDE, Species.KOFFING, Species.GRIMER, Species.ODDISH], - [TrainerPoolTier.UNCOMMON]: [Species.GYARADOS, Species.TAUROS, Species.SCYTHER, Species.CUBONE, Species.GROWLITHE, Species.MURKROW, Species.GASTLY, Species.EXEGGCUTE, Species.VOLTORB], - [TrainerPoolTier.RARE]: [Species.PORYGON, Species.ALOLA_RATTATA, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE], + [TrainerPoolTier.COMMON]: [Species.WEEDLE, Species.RATTATA, Species.EKANS, Species.SANDSHREW, Species.ZUBAT, Species.GEODUDE, Species.KOFFING, Species.GRIMER, Species.ODDISH, Species.SLOWPOKE], + [TrainerPoolTier.UNCOMMON]: [Species.GYARADOS, Species.LICKITUNG, Species.TAUROS, Species.MANKEY, Species.SCYTHER, Species.ELEKID, Species.MAGBY, Species.CUBONE, Species.GROWLITHE, Species.MURKROW, Species.GASTLY, Species.EXEGGCUTE, Species.VOLTORB, Species.MAGNEMITE], + [TrainerPoolTier.RARE]: [Species.PORYGON, Species.ALOLA_RATTATA, Species.ALOLA_SANDSHREW, Species.ALOLA_MEOWTH, Species.ALOLA_GRIMER, Species.ALOLA_GEODUDE, Species.PALDEA_TAUROS, Species.OMANYTE, Species.KABUTO], [TrainerPoolTier.SUPER_RARE]: [Species.DRATINI, Species.LARVITAR] }), [TrainerType.ARCHER]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin", "rocket", [Species.HOUNDOOM]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), @@ -1436,63 +1436,63 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.PETREL]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("rocket_admin", "rocket", [Species.WEEZING]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_rocket_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.MAGMA_GRUNT]: new TrainerConfig(++t).setHasGenders("Magma Grunt Female").setHasDouble("Magma Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.SLUGMA, Species.POOCHYENA, Species.NUMEL, Species.ZIGZAGOON, Species.DIGLETT, Species.MAGBY, Species.TORKOAL, Species.BALTOY, Species.BARBOACH], - [TrainerPoolTier.UNCOMMON]: [Species.SOLROCK, Species.HIPPOPOTAS, Species.SANDACONDA, Species.PHANPY, Species.ROLYCOLY, Species.GLIGAR], - [TrainerPoolTier.RARE]: [Species.TRAPINCH, Species.HEATMOR], + [TrainerPoolTier.COMMON]: [Species.SLUGMA, Species.POOCHYENA, Species.NUMEL, Species.ZIGZAGOON, Species.DIGLETT, Species.MAGBY, Species.TORKOAL, Species.GROWLITHE, Species.BALTOY], + [TrainerPoolTier.UNCOMMON]: [Species.SOLROCK, Species.HIPPOPOTAS, Species.SANDACONDA, Species.PHANPY, Species.ROLYCOLY, Species.GLIGAR, Species.RHYHORN, Species.HEATMOR], + [TrainerPoolTier.RARE]: [Species.TRAPINCH, Species.LILEEP, Species.ANORITH, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON], [TrainerPoolTier.SUPER_RARE]: [Species.CAPSAKID, Species.CHARCADET] }), [TrainerType.TABITHA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("magma_admin", "magma", [Species.CAMERUPT]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.COURTNEY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("magma_admin_female", "magma", [Species.CAMERUPT]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.AQUA_GRUNT]: new TrainerConfig(++t).setHasGenders("Aqua Grunt Female").setHasDouble("Aqua Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.CARVANHA, Species.WAILMER, Species.ZIGZAGOON, Species.LOTAD, Species.CORPHISH, Species.SPHEAL], - [TrainerPoolTier.UNCOMMON]: [Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.QWILFISH], - [TrainerPoolTier.RARE]: [Species.MANTINE, Species.BASCULEGION, Species.REMORAID, Species.ARROKUDA], - [TrainerPoolTier.SUPER_RARE]: [Species.DONDOZO] + [TrainerPoolTier.COMMON]: [Species.CARVANHA, Species.WAILMER, Species.ZIGZAGOON, Species.LOTAD, Species.CORPHISH, Species.SPHEAL, Species.REMORAID, Species.QWILFISH, Species.BARBOACH], + [TrainerPoolTier.UNCOMMON]: [Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.AZURILL, Species.CLOBBOPUS, Species.HORSEA], + [TrainerPoolTier.RARE]: [Species.MANTINE, Species.DHELMISE, Species.HISUI_QWILFISH, Species.ARROKUDA, Species.PALDEA_WOOPER, Species.SKRELP], + [TrainerPoolTier.SUPER_RARE]: [Species.DONDOZO, Species.BASCULEGION] }), [TrainerType.MATT]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("aqua_admin", "aqua", [Species.SHARPEDO]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.SHELLY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("aqua_admin_female", "aqua", [Species.SHARPEDO]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.GALACTIC_GRUNT]: new TrainerConfig(++t).setHasGenders("Galactic Grunt Female").setHasDouble("Galactic Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.GLAMEOW, Species.STUNKY, Species.CROAGUNK, Species.SHINX, Species.WURMPLE, Species.BRONZOR, Species.DRIFLOON, Species.BURMY], - [TrainerPoolTier.UNCOMMON]: [Species.CARNIVINE, Species.GROWLITHE, Species.QWILFISH, Species.SNEASEL], - [TrainerPoolTier.RARE]: [Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.HISUI_SNEASEL], - [TrainerPoolTier.SUPER_RARE]: [Species.HISUI_ZORUA, Species.HISUI_SLIGGOO] + [TrainerPoolTier.COMMON]: [Species.GLAMEOW, Species.STUNKY, Species.CROAGUNK, Species.SHINX, Species.WURMPLE, Species.BRONZOR, Species.DRIFLOON, Species.BURMY, Species.CARNIVINE], + [TrainerPoolTier.UNCOMMON]: [Species.LICKITUNG, Species.RHYHORN, Species.TANGELA, Species.ZUBAT, Species.YANMA, Species.SKORUPI, Species.GLIGAR, Species.SWINUB], + [TrainerPoolTier.RARE]: [Species.HISUI_GROWLITHE, Species.HISUI_QWILFISH, Species.SNEASEL, Species.ELEKID, Species.MAGBY, Species.DUSKULL], + [TrainerPoolTier.SUPER_RARE]: [Species.ROTOM, Species.SPIRITOMB, Species.HISUI_SNEASEL] }), [TrainerType.JUPITER]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("galactic_commander_female", "galactic", [Species.SKUNTANK]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.MARS]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("galactic_commander_female", "galactic", [Species.PURUGLY]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.SATURN]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("galactic_commander", "galactic", [Species.TOXICROAK]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_galactic_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.PLASMA_GRUNT]: new TrainerConfig(++t).setHasGenders("Plasma Grunt Female").setHasDouble("Plasma Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.PATRAT, Species.LILLIPUP, Species.PURRLOIN, Species.SCRAFTY, Species.WOOBAT, Species.VANILLITE, Species.SANDILE, Species.TRUBBISH], - [TrainerPoolTier.UNCOMMON]: [Species.FRILLISH, Species.VENIPEDE, Species.GOLETT, Species.TIMBURR, Species.DARUMAKA, Species.AMOONGUSS], - [TrainerPoolTier.RARE]: [Species.PAWNIARD, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.KLINK], - [TrainerPoolTier.SUPER_RARE]: [Species.DRUDDIGON, Species.BOUFFALANT, Species.AXEW, Species.DEINO, Species.DURANT] + [TrainerPoolTier.COMMON]: [Species.PATRAT, Species.LILLIPUP, Species.PURRLOIN, Species.SCRAFTY, Species.WOOBAT, Species.VANILLITE, Species.SANDILE, Species.TRUBBISH, Species.TYMPOLE], + [TrainerPoolTier.UNCOMMON]: [Species.FRILLISH, Species.VENIPEDE, Species.GOLETT, Species.TIMBURR, Species.DARUMAKA, Species.FOONGUS, Species.JOLTIK], + [TrainerPoolTier.RARE]: [Species.PAWNIARD, Species.RUFFLET, Species.VULLABY, Species.ZORUA, Species.DRILBUR, Species.KLINK, Species.CUBCHOO, Species.MIENFOO, Species.DURANT, Species.BOUFFALANT], + [TrainerPoolTier.SUPER_RARE]: [Species.DRUDDIGON, Species.HISUI_ZORUA, Species.AXEW, Species.DEINO] }), [TrainerType.ZINZOLIN]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("plasma_sage", "plasma", [Species.CRYOGONAL]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.ROOD]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("plasma_sage", "plasma", [Species.SWOOBAT]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_plasma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.FLARE_GRUNT]: new TrainerConfig(++t).setHasGenders("Flare Grunt Female").setHasDouble("Flare Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [Species.FLETCHLING, Species.LITLEO, Species.PONYTA, Species.INKAY, Species.HOUNDOUR, Species.SKORUPI, Species.SCRAFTY, Species.CROAGUNK], - [TrainerPoolTier.UNCOMMON]: [Species.HELIOPTILE, Species.ELECTRIKE, Species.SKRELP, Species.GULPIN, Species.PURRLOIN, Species.POOCHYENA, Species.SCATTERBUG], - [TrainerPoolTier.RARE]: [Species.LITWICK, Species.SNEASEL, Species.PANCHAM, Species.PAWNIARD], - [TrainerPoolTier.SUPER_RARE]: [Species.NOIVERN, Species.DRUDDIGON] + [TrainerPoolTier.COMMON]: [Species.FLETCHLING, Species.LITLEO, Species.PONYTA, Species.INKAY, Species.HOUNDOUR, Species.SKORUPI, Species.SCRAFTY, Species.CROAGUNK, Species.SCATTERBUG, Species.ESPURR], + [TrainerPoolTier.UNCOMMON]: [Species.HELIOPTILE, Species.ELECTRIKE, Species.SKRELP, Species.PANCHAM, Species.PURRLOIN, Species.POOCHYENA, Species.BINACLE, Species.CLAUNCHER, Species.PUMPKABOO, Species.PHANTUMP], + [TrainerPoolTier.RARE]: [Species.LITWICK, Species.SNEASEL, Species.PAWNIARD, Species.BERGMITE, Species.SLIGGOO], + [TrainerPoolTier.SUPER_RARE]: [Species.NOIVERN, Species.HISUI_SLIGGOO, Species.HISUI_AVALUGG] }), [TrainerType.BRYONY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("flare_admin_female", "flare", [Species.LIEPARD]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.XEROSIC]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("flare_admin", "flare", [Species.MALAMAR]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.AETHER_GRUNT]: new TrainerConfig(++t).setHasGenders("Aether Grunt Female").setHasDouble("Aether Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aether_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [ Species.PIKIPEK, Species.ROCKRUFF, Species.ALOLA_DIGLETT, Species.YUNGOOS, Species.CORSOLA, Species.ALOLA_GEODUDE, Species.BOUNSWEET, Species.LILLIPUP, Species.ALOLA_MAROWAK], - [TrainerPoolTier.UNCOMMON]: [ Species.POLIWAG, Species.STUFFUL, Species.ALOLA_EXEGGUTOR, Species.CRABRAWLER, Species.CUTIEFLY, Species.ALOLA_RAICHU, Species.ORICORIO, Species.MUDBRAY], - [TrainerPoolTier.RARE]: [ Species.ORANGURU, Species.PASSIMIAN, Species.GALAR_CORSOLA, Species.ALOLA_SANDSHREW, Species.ALOLA_VULPIX, Species.TURTONATOR, Species.DRAMPA], + [TrainerPoolTier.COMMON]: [ Species.PIKIPEK, Species.ROCKRUFF, Species.ALOLA_DIGLETT, Species.ALOLA_EXEGGUTOR, Species.YUNGOOS, Species.CORSOLA, Species.ALOLA_GEODUDE, Species.ALOLA_RAICHU, Species.BOUNSWEET, Species.LILLIPUP, Species.KOMALA, Species.MORELULL, Species.COMFEY, Species.TOGEDEMARU], + [TrainerPoolTier.UNCOMMON]: [ Species.POLIWAG, Species.STUFFUL, Species.ORANGURU, Species.PASSIMIAN, Species.BRUXISH, Species.MINIOR, Species.WISHIWASHI, Species.CRABRAWLER, Species.CUTIEFLY, Species.ORICORIO, Species.MUDBRAY, Species.PYUKUMUKU, Species.ALOLA_MAROWAK], + [TrainerPoolTier.RARE]: [ Species.GALAR_CORSOLA, Species.ALOLA_SANDSHREW, Species.ALOLA_VULPIX, Species.TURTONATOR, Species.DRAMPA], [TrainerPoolTier.SUPER_RARE]: [Species.JANGMO_O, Species.PORYGON] }), [TrainerType.FABA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("aether_admin", "aether", [Species.HYPNO]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aether_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.SKULL_GRUNT]: new TrainerConfig(++t).setHasGenders("Skull Grunt Female").setHasDouble("Skull Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_skull_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ - [TrainerPoolTier.COMMON]: [ Species.SALANDIT, Species.ALOLA_RATTATA, Species.ALOLA_MEOWTH, Species.SCRAGGY, Species.KOFFING, Species.ALOLA_GRIMER, Species.MAREANIE, Species.SPINARAK, Species.TRUBBISH], - [TrainerPoolTier.UNCOMMON]: [ Species.FOMANTIS, Species.SABLEYE, Species.SANDILE, Species.ALOLA_MAROWAK, Species.PANCHAM, Species.DROWZEE, Species.ZUBAT, Species.VENIPEDE, Species.VULLABY], - [TrainerPoolTier.RARE]: [Species.SANDYGAST, Species.PAWNIARD, Species.MIMIKYU, Species.DHELMISE, Species.GASTLY, Species.WISHIWASHI], + [TrainerPoolTier.COMMON]: [ Species.SALANDIT, Species.ALOLA_RATTATA, Species.EKANS, Species.ALOLA_MEOWTH, Species.SCRAGGY, Species.KOFFING, Species.ALOLA_GRIMER, Species.MAREANIE, Species.SPINARAK, Species.TRUBBISH], + [TrainerPoolTier.UNCOMMON]: [ Species.FOMANTIS, Species.SABLEYE, Species.SANDILE, Species.HOUNDOUR, Species.ALOLA_MAROWAK, Species.GASTLY, Species.PANCHAM, Species.DROWZEE, Species.ZUBAT, Species.VENIPEDE, Species.VULLABY], + [TrainerPoolTier.RARE]: [Species.SANDYGAST, Species.PAWNIARD, Species.MIMIKYU, Species.DHELMISE, Species.WISHIWASHI, Species.NYMBLE], [TrainerPoolTier.SUPER_RARE]: [Species.GRUBBIN, Species.DEWPIDER] }), [TrainerType.PLUMERIA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("skull_admin", "skull", [Species.SALAZZLE]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_skull_admin").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), @@ -1795,10 +1795,10 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.ROCKET_BOSS_GIOVANNI_1]: new TrainerConfig(t = TrainerType.ROCKET_BOSS_GIOVANNI_1).setName("Giovanni").initForEvilTeamLeader("Rocket Boss", []).setMixedBattleBgm("battle_rocket_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PERSIAN, Species.ALOLA_PERSIAN])) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.NIDOKING, Species.NIDOQUEEN])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.RHYPERIOR])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.DUGTRIO, Species.ALOLA_DUGTRIO])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.MAROWAK, Species.ALOLA_MAROWAK])) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.DUGTRIO, Species.ALOLA_DUGTRIO])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.HONCHKROW])) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.NIDOKING, Species.NIDOQUEEN])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.RHYPERIOR])) .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.KANGASKHAN], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); @@ -1813,7 +1813,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.HIPPOWDON])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.EXCADRILL])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.EXCADRILL, Species.GARCHOMP])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.KANGASKHAN], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); @@ -1821,7 +1821,7 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = 1; p.generateName(); })) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.GASTRODON])) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.GASTRODON, Species.SEISMITOAD])) .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.MEWTWO], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); @@ -1939,7 +1939,7 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = 1; p.generateName(); })) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.WEAVILE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.WEAVILE, Species.SNEASLER], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; @@ -1970,7 +1970,7 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BASCULEGION, Species.JELLICENT ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; - p.formIndex = 1; + p.formIndex = 0; })) .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.KINGAMBIT ])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.VOLCARONA, Species.SLITHER_WING ])) diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 279c3cf401b..61a8fbc7905 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -76,5 +76,7 @@ export enum BattlerTagType { GORILLA_TACTICS = "GORILLA_TACTICS", THROAT_CHOPPED = "THROAT_CHOPPED", TAR_SHOT = "TAR_SHOT", + BURNED_UP = "BURNED_UP", + DOUBLE_SHOCKED = "DOUBLE_SHOCKED", MYSTERY_ENCOUNTER_POST_SUMMON = "MYSTERY_ENCOUNTER_POST_SUMMON", } diff --git a/src/game-mode.ts b/src/game-mode.ts index 0a35e60057c..f3140445d85 100644 --- a/src/game-mode.ts +++ b/src/game-mode.ts @@ -30,10 +30,12 @@ interface GameModeConfig { isSplicedOnly?: boolean; isChallenge?: boolean; hasMysteryEncounters?: boolean; - minMysteryEncounterWave?: number; - maxMysteryEncounterWave?: number; } +// Describes min and max waves for MEs in specific game modes +const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180]; +const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180]; + export class GameMode implements GameModeConfig { public modeId: GameModes; public isClassic: boolean; @@ -60,8 +62,6 @@ export class GameMode implements GameModeConfig { this.challenges = allChallenges.map(c => copyChallenge(c)); } this.battleConfig = battleConfig || {}; - this.minMysteryEncounterWave = this.minMysteryEncounterWave ?? 0; - this.maxMysteryEncounterWave = this.maxMysteryEncounterWave ?? 100000; } /** @@ -325,6 +325,17 @@ export class GameMode implements GameModeConfig { } } + getMysteryEncounterLegalWaves(): [number, number] { + switch (this.modeId) { + default: + return [0, 0]; + case GameModes.CLASSIC: + return CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES; + case GameModes.CHALLENGE: + return CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES; + } + } + static getModeName(modeId: GameModes): string { switch (modeId) { case GameModes.CLASSIC: @@ -344,7 +355,7 @@ export class GameMode implements GameModeConfig { export function getGameMode(gameMode: GameModes): GameMode { switch (gameMode) { case GameModes.CLASSIC: - return new GameMode(GameModes.CLASSIC, { isClassic: true, hasTrainers: true, hasMysteryEncounters: true, maxMysteryEncounterWave: 180, minMysteryEncounterWave: 10 }, classicFixedBattles); + return new GameMode(GameModes.CLASSIC, { isClassic: true, hasTrainers: true, hasMysteryEncounters: true }, classicFixedBattles); case GameModes.ENDLESS: return new GameMode(GameModes.ENDLESS, { isEndless: true, hasShortBiomes: true, hasRandomBosses: true }); case GameModes.SPLICED_ENDLESS: @@ -352,6 +363,6 @@ export function getGameMode(gameMode: GameModes): GameMode { case GameModes.DAILY: return new GameMode(GameModes.DAILY, { isDaily: true, hasTrainers: true, hasNoShop: true }); case GameModes.CHALLENGE: - return new GameMode(GameModes.CHALLENGE, { isClassic: true, hasTrainers: true, isChallenge: true }, classicFixedBattles); + return new GameMode(GameModes.CHALLENGE, { isClassic: true, hasTrainers: true, isChallenge: true, hasMysteryEncounters: true }, classicFixedBattles); } } diff --git a/src/locales/ca_ES/arena-flyout.json b/src/locales/ca_ES/arena-flyout.json index 9e26dfeeb6e..21a02c789e8 100644 --- a/src/locales/ca_ES/arena-flyout.json +++ b/src/locales/ca_ES/arena-flyout.json @@ -1 +1,40 @@ -{} \ No newline at end of file +{ + "activeBattleEffects": "Efectes d'Arena Activa", + "player": "Jugador", + "neutral": "Neutre", + "enemy": "Enemic", + "sunny": "Assolellat", + "rain": "Plujós", + "sandstorm": "Tempesta Sorra", + "hail": "Calamarsa", + "snow": "Neu", + "fog": "Boira", + "heavyRain": "Diluvi", + "harshSun": "Sol Abrasador", + "strongWinds": "Vents Forts", + "misty": "Camp de Boira", + "electric": "Camp Elèctric", + "grassy": "Camp d'Herba", + "psychic": "Camp Psíquic", + "mudSport": "Xipollejo Fang", + "waterSport": "Hidrorraig", + "spikes": "Pues", + "toxicSpikes": "Pues Tòxiques", + "mist": "Boirina", + "futureSight": "Premonició", + "doomDesire": "Desig Ocult", + "wish": "Desig", + "stealthRock": "Trampa Roques", + "stickyWeb": "Xarxa Viscosa", + "trickRoom": "Espai Rar", + "gravity": "Gravetat", + "reflect": "Reflex", + "lightScreen": "Pantalla de Llum", + "auroraVeil": "Vel Aurora", + "quickGuard": "Anticipi", + "wideGuard": "Vasta Guàrdia", + "matBlock": "Escut Tatami", + "craftyShield": "Truc Defensa", + "tailwind": "Vent Afí", + "happyHour": "Paga Extra" +} diff --git a/src/locales/ca_ES/biome.json b/src/locales/ca_ES/biome.json index 9e26dfeeb6e..e570195e4c8 100644 --- a/src/locales/ca_ES/biome.json +++ b/src/locales/ca_ES/biome.json @@ -1 +1,38 @@ -{} \ No newline at end of file +{ + "unknownLocation": "En algun lloc que no recordes", + "TOWN": "Poble", + "PLAINS": "Vall", + "GRASS": "Camp", + "TALL_GRASS": "Herba Alta", + "METROPOLIS": "Metròpoli", + "FOREST": "Bosc", + "SEA": "Mar", + "SWAMP": "Pantà", + "BEACH": "Platja", + "LAKE": "Llac", + "SEABED": "Fons Marí", + "MOUNTAIN": "Muntanya", + "BADLANDS": "Badlands", + "CAVE": "Cova", + "DESERT": "Desert", + "ICE_CAVE": "Cova Gelada", + "MEADOW": "Prat", + "POWER_PLANT": "Planta d'Energia", + "VOLCANO": "Volcà", + "GRAVEYARD": "Cementiri", + "DOJO": "Dojo", + "FACTORY": "Fàbrica", + "RUINS": "Ruïnes Antigues", + "WASTELAND": "Terra Erma", + "ABYSS": "Avenc", + "SPACE": "Espai", + "CONSTRUCTION_SITE": "Obra", + "JUNGLE": "Jungla", + "FAIRY_CAVE": "Cova de Fades", + "TEMPLE": "Temple", + "SLUM": "Suburbi", + "SNOWY_FOREST": "Bosc Nevat", + "ISLAND": "Illa", + "LABORATORY": "Laboratori", + "END": "???" +} diff --git a/src/locales/ca_ES/common.json b/src/locales/ca_ES/common.json index 9e26dfeeb6e..8fd27cf486f 100644 --- a/src/locales/ca_ES/common.json +++ b/src/locales/ca_ES/common.json @@ -1 +1,8 @@ -{} \ No newline at end of file +{ + "start": "Començar", + "luckIndicator": "Sort:", + "shinyOnHover": "Variocolor", + "commonShiny": "Comú", + "rareShiny": "Rar", + "epicShiny": "Èpica" +} diff --git a/src/locales/ca_ES/menu.json b/src/locales/ca_ES/menu.json index 9e26dfeeb6e..42b0847b2f2 100644 --- a/src/locales/ca_ES/menu.json +++ b/src/locales/ca_ES/menu.json @@ -1 +1,55 @@ -{} \ No newline at end of file +{ + "cancel": "Cancel-la", + "continue": "Continuar", + "dailyRun": "Repte Diari (Beta)", + "loadGame": "Carregar Partida", + "newGame": "Nova Partida", + "settings": "Opcions", + "selectGameMode": "Trieu un mode de joc", + "logInOrCreateAccount": "Inicieu sessió o creeu un compte per començar. No cal correu electrònic!", + "username": "Usuari", + "password": "Contrasenya", + "login": "Iniciar Sessió", + "orUse": "O Usa", + "register": "Registrar-se", + "emptyUsername": "L'usuari no pot estar buit", + "invalidLoginUsername": "L'usuari no és vàlid", + "invalidRegisterUsername": "L'usuari només pot contenir lletres, números i guions baixos", + "invalidLoginPassword": "La contrasenya no és vàlida", + "invalidRegisterPassword": "La Contrasenya ha de tenir 6 o més caràcters", + "usernameAlreadyUsed": "L'usuari ja està en ús", + "accountNonExistent": "L'usuari no existeix", + "unmatchingPassword": "La contrasenya no coincideix", + "passwordNotMatchingConfirmPassword": "La contrasenya ha de coincidir amb la contrasenya de confirmació", + "confirmPassword": "Confirmeu la Contrasenya", + "registrationAgeWarning": "En registrar-te, confirmes que tens 13 anys o més.", + "backToLogin": "Torna a Iniciar Sessió", + "failedToLoadSaveData": "No s'han pogut carregar les dades desades. Torneu a carregar la pàgina.\nSi això continua, comproveu #announcements a Discord.", + "sessionSuccess": "Sessió carregada amb èxit.", + "failedToLoadSession": "No s'han pogut carregar les dades de la sessió.\nÉs possible que estiguin malmeses.", + "boyOrGirl": "Ets Nen o Nena?", + "evolving": "Que?\n{{pokemonName}} està evolucionant!", + "stoppedEvolving": "Prou?\nL'evolució de {{pokemonName}} s'ha aturat!", + "pauseEvolutionsQuestion": "Vols aturar les evolucions de {{pokémon Name}}?\nSempre poden ser activades des de la pantalla del teu equip.", + "evolutionsPaused": "L'evolució s'ha posat en pausa per a ", + "evolutionDone": "Enhorabona!\n{{pokemonName}} ha evolucionat a {{evolvedPokemonName}}!", + "dailyRankings": "Rànquings Diaris", + "weeklyRankings": "Rànquings Setmanals", + "noRankings": "Sense Rànquings", + "positionIcon": "#", + "usernameScoreboard": "Usuari", + "score": "Puntuació", + "wave": "Onada", + "loading": "Carregant…", + "loadingAsset": "Carregant actius: {{assetName}}", + "playersOnline": "Jugadors en Línia", + "yes":"sí", + "no":"No", + "disclaimer": "AVÍS", + "disclaimerDescription": "Aquest joc encara no s'ha completat; podríeu tenir problemes de joc (inclosa la possible pèrdua de dades desades),\n el joc pot canviar sense previ avís, i el joc es pot actualitzar o completar o no.", + "choosePokemon": "Elegir un Pokémon.", + "renamePokemon": "Rebatejar Pokémon", + "rename": "Rebatejar", + "nickname": "Sobrenom", + "errorServerDown": "Vaja! S'ha produït un problema en contactar amb el servidor.\n\nPots deixar aquesta pestanya oberta,\nel joc es tornarà a connectar automàticament." +} diff --git a/src/locales/ca_ES/nature.json b/src/locales/ca_ES/nature.json index 9e26dfeeb6e..b07413683db 100644 --- a/src/locales/ca_ES/nature.json +++ b/src/locales/ca_ES/nature.json @@ -1 +1,27 @@ -{} \ No newline at end of file +{ + "Hardy": "Forta", + "Lonely": "Esquerpa", + "Brave": "Audaç", + "Adamant": "Ferma", + "Naughty": "Múrria", + "Bold": "Agosarada", + "Docile": "Dòcil", + "Relaxed": "Relaxat", + "Impish": "Frenètic", + "Lax": "Despreocupat", + "Timid": "Poruc", + "Hasty": "Àvid", + "Serious": "Seriós", + "Jolly": "Jovial", + "Naive": "Ingenu", + "Modest": "Modesta", + "Mild": "Suau", + "Quiet": "Tranquil", + "Bashful": "Vergonyós", + "Rash": "Imprudent", + "Calm": "Serena", + "Gentle": "Amable", + "Sassy": "Descarat", + "Careful": "Cautelós", + "Quirky": "Estrany" +} diff --git a/src/locales/ca_ES/pokemon-info.json b/src/locales/ca_ES/pokemon-info.json index 9e26dfeeb6e..421ea6a88f7 100644 --- a/src/locales/ca_ES/pokemon-info.json +++ b/src/locales/ca_ES/pokemon-info.json @@ -1 +1,40 @@ -{} \ No newline at end of file +{ + "Stat": { + "HP": "PS", + "HPshortened": "PS", + "ATK": "Atac", + "ATKshortened": "Ata", + "DEF": "Defensa", + "DEFshortened": "Def", + "SPATK": "At. Esp.", + "SPATKshortened": "AtEsp", + "SPDEF": "Def. Esp.", + "SPDEFshortened": "DefEsp", + "SPD": "Velocitat", + "SPDshortened": "Veloc.", + "ACC": "Precisió", + "EVA": "Evació" + }, + "Type": { + "UNKNOWN": "???", + "NORMAL": "Normal", + "FIGHTING": "Lluita", + "FLYING": "Volador", + "POISON": "Verí", + "GROUND": "Terra", + "ROCK": "Roca", + "BUG": "Bestiola", + "GHOST": "Fantasma", + "STEEL": "Acer", + "FIRE": "Foc", + "WATER": "Aigua", + "GRASS": "Planta", + "ELECTRIC": "Elèctric", + "PSYCHIC": "Psíquic", + "ICE": "Gel", + "DRAGON": "Drac", + "DARK": "Sinistre", + "FAIRY": "Fada", + "STELLAR": "Astral" + } +} diff --git a/src/locales/en/settings.json b/src/locales/en/settings.json index 301ebea9b2b..ee8a43d7510 100644 --- a/src/locales/en/settings.json +++ b/src/locales/en/settings.json @@ -11,6 +11,10 @@ "expGainsSpeed": "EXP Gains Speed", "expPartyDisplay": "Show EXP Party", "skipSeenDialogues": "Skip Seen Dialogues", + "eggSkip": "Egg Skip", + "never": "Never", + "always": "Always", + "ask": "Ask", "battleStyle": "Battle Style", "enableRetries": "Enable Retries", "hideIvs": "Hide IV scanner", diff --git a/src/locales/ja/modifier-type.json b/src/locales/ja/modifier-type.json index e78ffaf652e..a2e62bd941e 100644 --- a/src/locales/ja/modifier-type.json +++ b/src/locales/ja/modifier-type.json @@ -2,424 +2,258 @@ "ModifierType": { "AddPokeballModifierType": { "name": "{{modifierCount}}x {{pokeballName}}", - "description": "{{pokeballName}} x{{modifierCount}}こ てにいれる (インベントリ: {{pokeballAmount}}) \nほそくりつ: {{catchRate}}" + "description": "{{pokeballName}}を {{modifierCount}}個 手に入れる (所有: {{pokeballAmount}})\n捕捉率:{{catchRate}}" }, "AddVoucherModifierType": { "name": "{{modifierCount}}x {{voucherTypeName}}", - "description": "{{voucherTypeName}} x{{modifierCount}}こ てにいれる" + "description": "{{voucherTypeName}}を {{modifierCount}}個 手に入れる" }, "PokemonHeldItemModifierType": { "extra": { - "inoperable": "{{pokemonName}} はこのアイテムを\nもつことができません!", - "tooMany": "{{pokemonName}} はこのアイテムを\nもちすぎています!" + "inoperable": "{{pokemonName}}は このアイテムを\n持つ ことが できません!", + "tooMany": "{{pokemonName}}は このアイテムを\n持ちすぎています!" } }, "PokemonHpRestoreModifierType": { - "description": "ポケモンの HPを {{restorePoints}} または {{restorePercent}}%のどちらか たかいほうを かいふくする", + "description": "ポケモン 一匹の {{restorePoints}}HP、または {{restorePercent}}% のどちらか 高い方を 回復する", "extra": { - "fully": "ポケモンのHPをすべてかいふくする", - "fullyWithStatus": "ポケモンの HPと じょうたいいじょうを かいふくする" + "fully": "ポケモン 1匹の HPを すべて 回復する", + "fullyWithStatus": "ポケモン 1匹の HPと 状態異常を すべて 回復する" } }, "PokemonReviveModifierType": { - "description": "ひんしになってしまったポケモンの HP {{restorePercent}}%を かいふくする" + "description": "ひんしに なった ポケモン 1匹を 元気にした上で\nHPを {{restorePercent}}% 回復する" }, "PokemonStatusHealModifierType": { - "description": "すべてのじょうたいいじょうを なおす" + "description": "ポケモン 1匹の 状態の 異常を すべて 回復する" }, "PokemonPpRestoreModifierType": { - "description": "ポケモンが おぼえている わざの PPを {{restorePoints}}ずつ かいふくする", + "description": "ポケモンが 覚えている 技のうち\n1つの PPを 10だけ 回復する", "extra": { - "fully": "ポケモンが おぼえている わざの PPを すべて かいふくする" + "fully": "ポケモンが 覚えている 技のうち\n1つの PPを すべて 回復する" } }, "PokemonAllMovePpRestoreModifierType": { - "description": "ポケモンが おぼえている 4つの わざの PPを {{restorePoints}}ずつ かいふくする", + "description": "ポケモンが 覚えている 4つの 技の PPを {{restorePoints}}ずつ 回復する", "extra": { - "fully": "ポケモンが おぼえている 4つの わざの PPを すべて かいふくする" + "fully": "ポケモンが 覚えている 4つの 技の PPを すべて 回復する" } }, "PokemonPpUpModifierType": { - "description": "ポケモンのわざのさいだいPPを さいだいPP 5ごとに {{upPoints}} ポイントずつ ふやします(さいだい3)" + "description": "ポケモンが 覚えている 技のうち 1つの PPの 最大値を 5ごとに {{upPoints}}ポイントずつ 上げる(最大3)" }, "PokemonNatureChangeModifierType": { - "name": "{{natureName}} Mint", - "description": "ポケモンのせいかくを {{natureName}}にかえて スターターのせいかくをえいきゅうにかいじょする" + "name": "{{natureName}}ミント", + "description": "ポケモン 1匹の 性格を 「{{natureName}}」に 変える。\nその上、スターター画面でも {{natureName}}が 選べるように なる。" }, "DoubleBattleChanceBoosterModifierType": { "description": "バトル{{battleCount}}回の間  ダブルバトルになる  確率を 4倍に する" }, "TempStatStageBoosterModifierType": { - "description": "全員の 手持ちポケモンの {{stat}}を 最大5回の バトルの間に {{amount}}あげる.", + "description": "全員の 手持ちポケモンの {{stat}}を 最大5回の バトルの間に {{amount}} 上げる", "extra": { - "stage": "1段階", - "percentage": "30%" + "stage": "1段階", + "percentage": "30%" } }, "AttackTypeBoosterModifierType": { - "description": "ポケモンの {{moveType}}タイプのわざのいりょくを20パーセントあげる" + "description": "ポケモンの {{moveType}}タイプの 技の 威力を 20% 上げる" }, "PokemonLevelIncrementModifierType": { - "description": "ポケモンのレベルを1あげる" + "description": "ポケモンの レベルを {{levels}} 上げる" }, "AllPokemonLevelIncrementModifierType": { - "description": "すべてのパーティメンバーのレベルを1あげる" + "description": "手持ちポケモンの 全員のレベルを {{levels}} 上げる" }, "BaseStatBoosterModifierType": { - "description": "ポケモンの{{stat}}のきほんステータスを10パーセントあげる。こたいちがたかいほどスタックのげんかいもたかくなる。" + "description": "ポケモンの 基本の{{stat}}を 10% あげる。\n個体値が 高けば高いほど 持てる限界が 上がる" }, "AllPokemonFullHpRestoreModifierType": { - "description": "すべてのポケモンのHPを100パーセントかいふくする" + "description": "手持ちポケモン 全員の HPを すべて 回復する" }, "AllPokemonFullReviveModifierType": { - "description": "ひんしになったすべてのポケモンをふっかつさせ HPをぜんかいふくする" + "description": "ひんしに なってしまった ポケモン 全員の HPを すべて 回復する" }, "MoneyRewardModifierType": { - "description": "{{moneyMultiplier}}ぶんのきんがくをあたえる (₽{{moneyAmount}})", + "description": "{{moneyMultiplier}}額の 円を 与える({{moneyAmount}}円)", "extra": { - "small": "すくない", - "moderate": "ふつう", - "large": "おおい" + "small": "小", + "moderate": "ある金", + "large": "多" } }, "ExpBoosterModifierType": { - "description": "もらえるけいけんちを {{boostPercent}}パーセントふやす" + "description": "もらえる 経験値を {{boostPercent}}% 増やす" }, "PokemonExpBoosterModifierType": { - "description": "もっているポケモンのけいけんちを {{boostPercent}}パーセントふやす" + "description": "持っているポケモンの もらう経験値を {{boostPercent}}% 増やす" }, "PokemonFriendshipBoosterModifierType": { - "description": "しょうりごとに 50%パーセント なかよく なりやすくなる" + "description": "持っているポケモンの なかよし度の収穫が 勝利ごとに 50% 上がる" }, "PokemonMoveAccuracyBoosterModifierType": { - "description": "わざのめいちゅうりつを{{accuracyAmount}}ふやす (さいだい100)" + "description": "技の 命中率を {{accuracyAmount}} 増やす(最大 100)" }, "PokemonMultiHitModifierType": { - "description": "こうげきがもういちどあたる。そのたびにいりょくがそれぞれ60/75/82.5%へる" + "description": "持たせると 攻撃が もう一度 当たるが、\n威力が 減る(1個:60%減る/2個:75%減る/3個:82.5%減る)" }, "TmModifierType": { - "name": "TM{{moveId}} - {{moveName}}", - "description": "ポケモンに {{moveName}} をおしえる" + "name": "TM{{moveId}}\n{{moveName}}", + "description": "ポケモンに {{moveName}}を 教える" }, "TmModifierTypeWithInfo": { - "name": "TM{{moveId}} - {{moveName}}", - "description": "ポケモンに {{moveName}} をおしえる\n(Hold C or Shift for more info)" + "name": "TM{{moveId}}\n{{moveName}}", + "description": "ポケモンに {{moveName}}を 教える\n(Cキー/Shiftキーを押すと 技情報が見える)" }, "EvolutionItemModifierType": { - "description": "とくていのポケモンをしんかさせる" + "description": "ある特定の ポケモンを 進化させる" }, "FormChangeItemModifierType": { - "description": "とくていのポケモンをフォームチェンジさせる" + "description": "ある特定の ポケモンを フォームチェンジさせる" }, "FusePokemonModifierType": { - "description": "2匹のポケモンをけつごうする (とくせいをいどうし、きほんステータスとタイプをわけ、わざプールをきょうゆうする)" + "description": "2匹の ポケモンを 吸収合体する(特性が移動し、基本能力とタイプを分け、覚える技を共有する)" }, "TerastallizeModifierType": { - "name": "{{teraType}} Tera Shard", - "description": "ポケモンを{{teraType}}タイプにテラスタル(10かいのバトルまで)" + "name": "テラピース{{teraType}}", + "description": "ポケモンを {{teraType}}タイプに テラスタルさせる(最大10回のバトルの間)" }, "ContactHeldItemTransferChanceModifierType": { - "description": "こうげきするとき あいてがもっているアイテムを {{chancePercent}}パーセントのかくりつでぬすむ" + "description": "持っているポケモンが 攻撃すると 相手の持っている\nアイテムを {{chancePercent}}%の 確率で 盗む" }, "TurnHeldItemTransferModifierType": { - "description": "まいターン あいてからひとつのもちものをてにいれる" + "description": "毎ターン 相手から 一つの 持っている\nアイテム を吸い込んで 盗む" }, "EnemyAttackStatusEffectChanceModifierType": { - "description": "こうげきわざに {{chancePercent}}パーセントのかくりつで {{statusEffect}}をあたえる" + "description": "攻撃技に {{chancePercent}}%の 確率で {{statusEffect}}を 与える" }, "EnemyEndureChanceModifierType": { - "description": "こうげきをこらえるかくりつを{{chancePercent}}パーセントふやす" - }, - "RARE_CANDY": { - "name": "ふしぎなアメ" - }, - "RARER_CANDY": { - "name": "もっとふしぎなアメ" - }, - "MEGA_BRACELET": { - "name": "メガバングル", - "description": "メガストーンがつかえるようになる" - }, - "DYNAMAX_BAND": { - "name": "ダイマックスバンド", - "description": "ダイスープがつかえるようになる" - }, - "TERA_ORB": { - "name": "テラスタルオーブ", - "description": "テラピースがつかえるようになる" - }, - "MAP": { - "name": "ちず", - "description": "わかれみちでいきさきをえらべるようになる" - }, - "POTION": { - "name": "キズぐすり" - }, - "SUPER_POTION": { - "name": "いいキズぐすり" - }, - "HYPER_POTION": { - "name": "すごいキズぐすり" - }, - "MAX_POTION": { - "name": "まんたんのくすり" - }, - "FULL_RESTORE": { - "name": "かいふくのくすり" - }, - "REVIVE": { - "name": "げんきのかけら" - }, - "MAX_REVIVE": { - "name": "げんきのかたまり" - }, - "FULL_HEAL": { - "name": "なんでもなおし" - }, - "SACRED_ASH": { - "name": "せいなるはい" - }, - "REVIVER_SEED": { - "name": "ふっかつのタネ", - "description": "ひんしになったときもっているポケモンをHPはんぶんでふっかつさせる" - }, - "WHITE_HERB": { - "name": "White Herb", - "description": "An item to be held by a Pokémon. It will restore any lowered stat in battle." - }, - "ETHER": { - "name": "ピーピーエイド" - }, - "MAX_ETHER": { - "name": "ピーピーリカバー" - }, - "ELIXIR": { - "name": "ピーピーエイダー" - }, - "MAX_ELIXIR": { - "name": "ピーピーマックス" - }, - "PP_UP": { - "name": "ポイントアップ" - }, - "PP_MAX": { - "name": "ポイントマックス" - }, - "LURE": { - "name": "ダブルバトルコロン" - }, - "SUPER_LURE": { - "name": "シルバーコロン" - }, - "MAX_LURE": { - "name": "ゴールドコロン" - }, - "MEMORY_MUSHROOM": { - "name": "きおくキノコ", - "description": "ポケモンのわすれたわざをおぼえさせる" - }, - "EXP_SHARE": { - "name": "がくしゅうそうち", - "description": "バトルにさんかしていないポケモンが けいけんちの20パーセントをもらう" - }, - "EXP_BALANCE": { - "name": "バランスそうち", - "description": "レベルがひくいパーティメンバーがもらうけいけんちがふえる" - }, - "OVAL_CHARM": { - "name": "まるいおまもり", - "description": "バトルにふくすうのポケモンがさんかするとけいけんちが10パーセントふえる" - }, - "EXP_CHARM": { - "name": "けいけんちおまもり" - }, - "SUPER_EXP_CHARM": { - "name": "いいけいけんちおまもり" - }, - "GOLDEN_EXP_CHARM": { - "name": "ゴールドけいけんちおまもり" - }, - "LUCKY_EGG": { - "name": "しあわせタマゴ" - }, - "GOLDEN_EGG": { - "name": "おうごんタマゴ" - }, - "SOOTHE_BELL": { - "name": "やすらぎのすず" - }, - "SCOPE_LENS": { - "name": "ピントレンズ", - "description": "弱点が 見える レンズ。持たせた ポケモンの技が 急所に 当たりやすくなる。" - }, - "DIRE_HIT": { - "name": "クリティカット", - "extra": { - "raises": "きゅうしょりつ" - } - }, - "LEEK": { - "name": "ながねぎ", - "description": "とても長くて 硬いクキ。カモネギに 持たせると 技が 急所に 当たりやすくなる。" - }, - "EVIOLITE": { - "name": "しんかのきせき", - "description": "進化の不思議な かたまり。持たせると 進化前ポケモンの 防御と 特防が あがる。" - }, - "SOUL_DEW": { - "name": "こころのしずく", - "description": "ポケモンのせいかくがステータスにあたえるえいきょうを10%ふやす(合算)" - }, - "NUGGET": { - "name": "きんのたま" - }, - "BIG_NUGGET": { - "name": "でかいきんのたま" - }, - "RELIC_GOLD": { - "name": "こだいのきんか" - }, - "AMULET_COIN": { - "name": "おまもりこばん", - "description": "もらえる おかねが 20パーセント ふえる" - }, - "GOLDEN_PUNCH": { - "name": "ゴールドパンチ", - "description": "あたえたちょくせつダメージの50パーセントをおかねとしてもらえる" - }, - "COIN_CASE": { - "name": "コインケース", - "description": "10かいのバトルごとにもちきんの10パーセントをりしとしてうけとる" - }, - "LOCK_CAPSULE": { - "name": "ロックカプセル", - "description": "リロールするときにアイテムのレアリティをロックできる" - }, - "GRIP_CLAW": { - "name": "ねばりのかぎづめ" - }, - "WIDE_LENS": { - "name": "こうかくレンズ" - }, - "MULTI_LENS": { - "name": "マルチレンズ" - }, - "HEALING_CHARM": { - "name": "ヒーリングチャーム", - "description": "HPをかいふくするわざとアイテムのこうかを10パーセントあげる (ふっかつはのぞく)" - }, - "CANDY_JAR": { - "name": "アメボトル", - "description": "ふしぎなアメのアイテムでふえるレベルが1ふえる" - }, - "BERRY_POUCH": { - "name": "きのみぶくろ", - "description": "つかったきのみがつかわれないかくりつを30パーセントふやす" - }, - "FOCUS_BAND": { - "name": "きあいのハチマキ", - "description": "ひんしになるダメージをうけてもHP1でたえるかくりつを10パーセントふやす" - }, - "QUICK_CLAW": { - "name": "せんせいのツメ", - "description": "すばやさにかかわらず さきにこうどうするかくりつを10パーセントふやす (ゆうせんどのあと)" - }, - "KINGS_ROCK": { - "name": "おうじゃのしるし", - "description": "こうげきわざがあいてをひるませるかくりつを10パーセントふやす" - }, - "LEFTOVERS": { - "name": "たべのこし", - "description": "ポケモンのさいだいHPの1/16をまいターンかいふくする" - }, - "SHELL_BELL": { - "name": "かいがらのすず", - "description": "ポケモンがあたえたダメージの1/8をかいふくする" - }, - "TOXIC_ORB": { - "name": "どくどくだま", - "description": "ターンの終わりに すでに じょうたいじょうしょうが なければ もうどくの じょうたいに なる" - }, - "FLAME_ORB": { - "name": "かえんだま", - "description": "ターンの終わりに すでに じょうたいじょうしょうが なければ やけどの じょうたいに なる" - }, - "BATON": { - "name": "バトン", - "description": "ポケモンをこうたいするときにこうかをひきつぎ わなをかいひすることもできる" - }, - "SHINY_CHARM": { - "name": "ひかるおまもり", - "description": "やせいのポケモンがいろちがいポケモンであるかくりつをおおきくふやす" - }, - "ABILITY_CHARM": { - "name": "とくせいおまもり", - "description": "やせいのポケモンがかくれとくせいをもつかくりつをおおきくふやす" - }, - "IV_SCANNER": { - "name": "こたいちスキャナー", - "description": "やせいのポケモンのこたいちをスキャンできる。スタックごとに2つのこたいちがあきらかになる。もっともたかいこたいちがさいしょにひょうじされる" - }, - "DNA_SPLICERS": { - "name": "いでんしのくさび" - }, - "MINI_BLACK_HOLE": { - "name": "ミニブラックホール" - }, - "GOLDEN_POKEBALL": { - "name": "ゴールドモンスターボール", - "description": "バトルごとに1つのアイテムオプションをふやす" - }, - "ENEMY_DAMAGE_BOOSTER": { - "name": "ダメージトークン", - "description": "ダメージを5%ふやす" - }, - "ENEMY_DAMAGE_REDUCTION": { - "name": "プロテクショントークン", - "description": "うけるダメージを2.5%へらす" - }, - "ENEMY_HEAL": { - "name": "かいふくトークン", - "description": "まいターンさいだいHPの2%をかいふくする" - }, - "ENEMY_ATTACK_POISON_CHANCE": { - "name": "どくトークン" - }, - "ENEMY_ATTACK_PARALYZE_CHANCE": { - "name": "まひトークン" - }, - "ENEMY_ATTACK_BURN_CHANCE": { - "name": "やけどトークン" - }, - "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { - "name": "なおしトークン", - "description": "まいターン2.5%のかくりつでじょうたいじょうしょうをかいふくする" - }, - "ENEMY_ENDURE_CHANCE": { - "name": "こらえるトークン" - }, - "ENEMY_FUSED_CHANCE": { - "name": "フュージョントークン", - "description": "やせいのポケモンがフュージョンするかくりつを1%ふやす" - } + "description": "ひんしに なりそうな 技を 受けても\n{{chancePercent}}%の 確率で HPを 1だけ 残して 耐える" + }, + + "RARE_CANDY": { "name": "ふしぎなアメ" }, + "RARER_CANDY": { "name": "ふかしぎなアメ" }, + + "MEGA_BRACELET": { "name": "メガバングル", "description": "メガストーンが 見つけられる ように なる" }, + "DYNAMAX_BAND": { "name": "ダイマックスバンド", "description": "ダイキノコが 見つけられる ように なる" }, + "TERA_ORB": { "name": "テラスタルオーブ", "description": "テラピースが 見つけられる ように なる" }, + + "MAP": { "name": "ちず", "description": "分かれ道で 行き先が 選べる よう になる" }, + + "POTION": { "name": "キズぐすり" }, + "SUPER_POTION": { "name": "いいキズぐすり" }, + "HYPER_POTION": { "name": "すごいキズぐすり" }, + "MAX_POTION": { "name": "まんたんのくすり" }, + "FULL_RESTORE": { "name": "かいふくのくすり" }, + + "REVIVE": { "name": "げんきのかけら" }, + "MAX_REVIVE": { "name": "げんきのかたまり" }, + + "FULL_HEAL": { "name": "なんでもなおし" }, + + "SACRED_ASH": { "name": "せいなるはい" }, + + "REVIVER_SEED": { "name": "ふっかつのタネ", "description": "持たせると 直接攻撃から ひんしに なれば\n復活して HPを 50% 回復する" }, + + "WHITE_HERB":{ "name": "しろいハーブ", "description": "持たせた ポケモンの能力が さがったとき 1度だけ 元の状態に 戻す" }, + + "ETHER": { "name": "ピーピーエイド" }, + "MAX_ETHER": { "name": "ピーピーリカバー" }, + + "ELIXIR": { "name": "ピーピーエイダー" }, + "MAX_ELIXIR": { "name": "ピーピーマックス" }, + + "PP_UP": { "name": "ポイントアップ" }, + "PP_MAX": { "name": "ポイントマックス" }, + + "LURE": { "name": "むしよせコロン" }, + "SUPER_LURE": { "name": "シルバーコロン" }, + "MAX_LURE": { "name": "ゴールドコロン" }, + + "MEMORY_MUSHROOM": { "name": "きおくのキノコ", "description": "1匹の ポケモンの 忘れた技を 1つ 覚えさせる" }, + + "EXP_SHARE": { "name": "がくしゅうそうち", "description": "バトルに 参加していない ポケモンが 参加したポケモンの 経験値を 20% もらう" }, + "EXP_BALANCE": { "name": "バランスそうち", "description": "レベルが低い 手持ちポケモンの もらう 経験値が 増える" }, + + "OVAL_CHARM": { "name": "まるいおまもり", "description": "バトルに 複数の ポケモンが 参加すると、\n経験値が 参加したポケモンずつ 10% 増える" }, + + "EXP_CHARM": { "name": "けいけんおまもり" }, + "SUPER_EXP_CHARM": { "name": "いいけいけんおまもり" }, + "GOLDEN_EXP_CHARM": { "name": "ゴールドけいけんちおまもり" }, + + "LUCKY_EGG": { "name": "しあわせタマゴ" }, + "GOLDEN_EGG": { "name": "ゴールドタマゴ" }, + + "SOOTHE_BELL": { "name": "やすらぎのすず" }, + + "SCOPE_LENS": { "name": "ピントレンズ", "description": "弱点が 見える レンズ。\n持たせた ポケモンの技が 急所に 当たりやすくなる"}, + "DIRE_HIT": { "name": "クリティカット", "extra": { "raises": "急所率" } }, + "LEEK": { "name": "ながねぎ", "description": "とても長くて 硬いクキ。\nカモネギに 持たせると 技が 急所に 当たりやすくなる"}, + + "EVIOLITE": { "name": "しんかのきせき", "description": "進化の不思議な かたまり。\n持たせると 進化前ポケモンの 防御と 特防が あがる" }, + + "SOUL_DEW": { "name": "こころのしずく", "description": "持たせると ポケモンの 性格が 能力に与える 影響は 10% 増える(合算)" }, + + "NUGGET": { "name": "きんのたま" }, + "BIG_NUGGET": { "name": "でかいきんのたま" }, + "RELIC_GOLD": { "name": "こだいのきんか" }, + + "AMULET_COIN": { "name": "おまもりこばん", "description": "もらえる お金が 20% 増える" }, + "GOLDEN_PUNCH": { "name": "ゴールドパンチ", "description": "持たせると 与える 直接なダメージの 50%が お金として もらえる" }, + "COIN_CASE": { "name": "コインケース", "description": "10回の バトルごとに 持ち金の 10%を 利子として 受け取れる" }, + + "LOCK_CAPSULE": { "name": "ロックカプセル", "description": "ご褒美の 選択肢変更するとき アイテムの レア度を固定できる ように なる" }, + + "GRIP_CLAW": { "name": "ねばりのかぎづめ" }, + "WIDE_LENS": { "name": "こうかくレンズ" }, + + "MULTI_LENS": { "name": "マルチレンズ" }, + + "HEALING_CHARM": { "name": "かいふくおまもり", "description": "回復する 技や アイテムの 効果を 10% あげる(復活アイテムは除く)" }, + "CANDY_JAR": { "name": "アメボトル", "description": "ふしぎなアメや ふかしぎなアメで あげるレベルを 1 増える" }, + + "BERRY_POUCH": { "name": "きのみぶくろ", "description": "使ったきのみは 無くならない 30%の可能性を 加える" }, + + "FOCUS_BAND": { "name": "きあいのハチマキ", "description": "持たせると ひんしに なりそうな 技を 受けても\n10%の可能性で HPを 1だけ 残して 耐える" }, + + "QUICK_CLAW": { "name": "せんせいのツメ", "description": "持たせると 10%の可能性で 相手より 先に 行動できる (優先技のあと)" }, + + "KINGS_ROCK": { "name": "おうじゃのしるし", "description": "持たせると 攻撃して ダメージを 与えたときに\n10%の可能性で 相手を ひるませる" }, + + "LEFTOVERS": { "name": "たべのこし", "description": "持たせると 毎ターン 最大HPの 1/16を 回復する" }, + "SHELL_BELL": { "name": "かいがらのすず", "description": "持たせると ポケモンが 相手に 与えたダメージの 1/8をHPとして 回復する." }, + + "TOXIC_ORB": { "name": "どくどくだま", "description": "触ると 毒をだす 不思議な玉。\n持たせると 戦闘中に 猛毒の状態に なる" }, + "FLAME_ORB": { "name": "かえんだま", "description": "触ると 熱をだす 不思議な玉。\n持たせると 戦闘中に やけどの状態に なる。" }, + + "BATON": { "name": "バトン", "description": "持たせると 入れ替えるとき 控えのポケモンが\n能力変化を 受けつげる (逃げられなくする 技や 特性も 回避する)" }, + + "SHINY_CHARM": { "name": "ひかるおまもり", "description": "色違いの ポケモンと 大きく 出会いやすくなる" }, + "ABILITY_CHARM": { "name": "とくせいおまもり", "description": "隠れ特性がある ポケモンと 大きく 出会いやすくなる" }, + + "IV_SCANNER": { "name": "こたいちスキャナー", "description": "野生ポケモンの 個体値を 検査できる。 一つのスキャナーあたり\n個体値が 2つ 見える。 最高の 個体値が 最初に 見える。" }, + + "DNA_SPLICERS": { "name": "いでんしのくさび" }, + + "MINI_BLACK_HOLE": { "name": "ミニブラックホール" }, + + "GOLDEN_POKEBALL": { "name": "ゴールドモンスターボール", "description": "バトル後に もう 一つの ご褒美の 選択肢を 加える" }, + + "ENEMY_DAMAGE_BOOSTER": { "name": "ダメージトークン", "description": "ダメージを 5% あげる" }, + "ENEMY_DAMAGE_REDUCTION": { "name": "ぼうごトークン", "description": "受けたダメージを 2.5% さげる" }, + "ENEMY_HEAL": { "name": "かいふくトークン", "description": "毎ターン 最大HPの 2%を 回復する" }, + "ENEMY_ATTACK_POISON_CHANCE": { "name": "どくトークン" }, + "ENEMY_ATTACK_PARALYZE_CHANCE": { "name": "まひトークン" }, + "ENEMY_ATTACK_BURN_CHANCE": { "name": "やけどトークン" }, + "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "name": "なんでもなおしトークン", "description": "毎ターン 状態異常を 治せる 2.5%の可能性を 加える" }, + "ENEMY_ENDURE_CHANCE": { "name": "こらえるトークン" }, + "ENEMY_FUSED_CHANCE": { "name": "がったいトークン", "description": "野生ポケモンは 吸収合体している 1%の可能性を 加える" } }, "SpeciesBoosterItem": { - "LIGHT_BALL": { - "name": "でんきだま", - "description": "ピカチュウに 持たせると 攻撃と 特攻が あがる 不思議な玉。" - }, - "THICK_CLUB": { - "name": "ふといホネ", - "description": "なにかの 硬いホネ。カラカラ または ガラガラに 持たせると 攻撃が あがる。" - }, - "METAL_POWDER": { - "name": "メタルパウダー", - "description": "メタモンに 持たせると 防御が あがる 不思議な粉。とても こまかくて 硬い。" - }, - "QUICK_POWDER": { - "name": "スピードパウダー", - "description": "メタモンに 持たせると 素早さが あがる 不思議 粉。とても こまかくて 硬い。" - } + "LIGHT_BALL": { "name": "でんきだま", "description": "ピカチュウに 持たせると 攻撃と 特攻が あがる 不思議な玉" }, + "THICK_CLUB": { "name": "ふといホネ", "description": "なにかの 硬いホネ。 カラカラ または ガラガラに 持たせると 攻撃が あがる" }, + "METAL_POWDER": { "name": "メタルパウダー", "description": "メタモンに 持たせると 防御が あがる 不思議な粉。 とても こまかくて 硬い" }, + "QUICK_POWDER": { "name": "スピードパウダー", "description": "メタモンに 持たせると 素早さが あがる 不思議な粉。 とても こまかくて 硬い" } }, "TempStatStageBoosterItem": { "x_attack": "プラスパワー", @@ -458,7 +292,8 @@ "carbos": "インドメタシン" }, "EvolutionItem": { - "NONE": "None", + "NONE": "なし", + "LINKING_CORD": "つながりのヒモ", "SUN_STONE": "たいようのいし", "MOON_STONE": "つきのいし", @@ -475,6 +310,7 @@ "TART_APPLE": "すっぱいりんご", "STRAWBERRY_SWEET": "いちごアメざいく", "UNREMARKABLE_TEACUP": "ボンサクのちゃわん", + "CHIPPED_POT": "かけたポット", "BLACK_AUGURITE": "くろのきせき", "GALARICA_CUFF": "ガラナツブレス", @@ -489,7 +325,8 @@ "SYRUPY_APPLE": "みついりりんご" }, "FormChangeItem": { - "NONE": "None", + "NONE": "なし", + "ABOMASITE": "ユキノオナイト", "ABSOLITE": "アブソルナイト", "AERODACTYLITE": "プテラナイト", @@ -538,6 +375,7 @@ "SWAMPERTITE": "ラグラージナイト", "TYRANITARITE": "バンギラスナイト", "VENUSAURITE": "フシギバナイト", + "BLUE_ORB": "あいいろのたま", "RED_ORB": "べにいろのたま", "SHARP_METEORITE": "シャープなうんせき", @@ -565,6 +403,44 @@ "BURN_DRIVE": "ブレイズカセット", "CHILL_DRIVE": "フリーズカセット", "DOUSE_DRIVE": "アクアカセット", - "ULTRANECROZIUM_Z": "ウルトラネクロZ" + "ULTRANECROZIUM_Z": "ウルトラネクロZ", + + "FIST_PLATE": "こぶしのプレート", + "SKY_PLATE": "あおぞらプレート", + "TOXIC_PLATE": "もうどくプレート", + "EARTH_PLATE": "だいちのプレート", + "STONE_PLATE": "がんせきプレート", + "INSECT_PLATE": "たまむしプレート", + "SPOOKY_PLATE": "もののけプレート", + "IRON_PLATE": "こうてつプレート", + "FLAME_PLATE": "ひのたまプレート", + "SPLASH_PLATE": "しずくプレート", + "MEADOW_PLATE": "みどりのプレート", + "ZAP_PLATE": "いかずちプレート", + "MIND_PLATE": "ふしぎのプレート", + "ICICLE_PLATE": "つららのプレート", + "DRACO_PLATE": "りゅうのプレート", + "DREAD_PLATE": "こわもてプレート", + "PIXIE_PLATE": "せいれいプレート", + "BLANK_PLATE": "まっさらプレート", + "LEGEND_PLATE": "レジェンドプレート", + "FIGHTING_MEMORY": "ファイトメモリ", + "FLYING_MEMORY": "フライングメモリ", + "POISON_MEMORY": "ポイズンメモリ", + "GROUND_MEMORY": "グラウンドメモリ", + "ROCK_MEMORY": "ロックメモリ", + "BUG_MEMORY": "バグメモリ", + "GHOST_MEMORY": "ゴーストメモリ", + "STEEL_MEMORY": "スチールメモリ", + "FIRE_MEMORY": "ファイヤーメモリ", + "WATER_MEMORY": "ウオーターメモリ", + "GRASS_MEMORY": "グラスメモリ", + "ELECTRIC_MEMORY": "エレクトロメモリ", + "PSYCHIC_MEMORY": "サイキックメモリ", + "ICE_MEMORY": "アイスメモリ", + "DRAGON_MEMORY": "ドラゴンメモリ", + "DARK_MEMORY": "ダークメモリ", + "FAIRY_MEMORY": "フェアリーメモリ", + "NORMAL_MEMORY": "ノーマルメモリ" } } diff --git a/src/locales/ko/battle.json b/src/locales/ko/battle.json index fd715fd0e7e..154ca04fd49 100644 --- a/src/locales/ko/battle.json +++ b/src/locales/ko/battle.json @@ -44,7 +44,10 @@ "moveNotImplemented": "{{moveName}}[[는]] 아직 구현되지 않아 사용할 수 없다…", "moveNoPP": "기술의 남은 포인트가 없다!", "moveDisabled": "{{moveName}}[[를]] 쓸 수 없다!", + "canOnlyUseMove": "{{pokemonName}}[[는]]\n{{moveName}}밖에 쓸 수 없다!", + "moveCannotBeSelected": "{{moveName}}[[를]] 쓸 수 없다!", "disableInterruptedMove": "{{pokemonNameWithAffix}}의 {{moveName}}[[는]]\n사용할 수 없다.", + "throatChopInterruptedMove": "{{pokemonName}}[[는]]\n지옥찌르기 효과로 기술을 쓸 수 없다!", "noPokeballForce": "본 적 없는 힘이\n볼을 사용하지 못하게 한다.", "noPokeballTrainer": "다른 트레이너의 포켓몬은 잡을 수 없다!", "noPokeballMulti": "안돼! 2마리 있어서\n목표를 정할 수가 없어…!", @@ -62,6 +65,7 @@ "skipItemQuestion": "아이템을 받지 않고 넘어가시겠습니까?", "itemStackFull": "{{fullItemName}}의 소지 한도에 도달했습니다.\n{{itemname}}[[를]] 대신 받습니다.", "eggHatching": "어라…?", + "eggSkipPrompt": "알 부화 요약 화면으로 바로 넘어가시겠습니까?", "ivScannerUseQuestion": "{{pokemonName}}에게 개체값탐지기를 사용하시겠습니까?", "wildPokemonWithAffix": "야생 {{pokemonName}}", "foePokemonWithAffix": "상대 {{pokemonName}}", @@ -90,7 +94,7 @@ "statSeverelyFell_other": "{{pokemonNameWithAffix}}의\n{{stats}}[[가]] 매우 크게 떨어졌다!", "statWontGoAnyLower_one": "{{pokemonNameWithAffix}}의\n{{stats}}[[는]] 더 떨어지지 않는다!", "statWontGoAnyLower_other": "{{pokemonNameWithAffix}}의\n{{stats}}[[는]] 더 떨어지지 않는다!", - "transformedIntoType": "{{pokemonName}} transformed\ninto the {{type}} type!", + "transformedIntoType": "{{pokemonName}}[[는]]\n{{type}}타입이 됐다!", "retryBattle": "이 배틀의 처음부터 재도전하시겠습니까?", "unlockedSomething": "{{unlockedThing}}[[가]]\n해금되었다.", "congratulations": "축하합니다!", diff --git a/src/locales/ko/challenges.json b/src/locales/ko/challenges.json index 7efdfef3570..07a9052eebf 100644 --- a/src/locales/ko/challenges.json +++ b/src/locales/ko/challenges.json @@ -1,6 +1,7 @@ { "title": "챌린지 조건 설정", "illegalEvolution": "{{pokemon}}[[는]] 현재의 챌린지에\n부적합한 포켓몬이 되었습니다!", + "noneSelected": "미선택", "singleGeneration": { "name": "단일 세대", "desc": "{{gen}}의 포켓몬만 사용할 수 있습니다.", diff --git a/src/locales/ko/modifier.json b/src/locales/ko/modifier.json index 281ecf61943..b04e51f30cb 100644 --- a/src/locales/ko/modifier.json +++ b/src/locales/ko/modifier.json @@ -3,7 +3,7 @@ "turnHealApply": "{{pokemonNameWithAffix}}[[는]]\n{{typeName}}[[로]] 인해 조금 회복했다.", "hitHealApply": "{{pokemonNameWithAffix}}[[는]]\n{{typeName}}[[로]] 인해 조금 회복했다.", "pokemonInstantReviveApply": "{{pokemonNameWithAffix}}[[는]] {{typeName}}[[로]]\n정신을 차려 싸울 수 있게 되었다!", - "pokemonResetNegativeStatStageApply": "{{pokemonNameWithAffix}}[[는]] {{typeName}}[[로]]\n상태를 원래대로 되돌렸다!", + "resetNegativeStatStageApply": "{{pokemonNameWithAffix}}[[는]] {{typeName}}[[로]]\n상태를 원래대로 되돌렸다!", "moneyInterestApply": "{{typeName}}[[로]]부터\n₽{{moneyAmount}}[[를]] 받았다!", "turnHeldItemTransferApply": "{{pokemonName}}의 {{typeName}}[[는]]\n{{pokemonNameWithAffix}}의 {{itemName}}[[를]] 흡수했다!", "contactHeldItemTransferApply": "{{pokemonName}}의 {{typeName}}[[는]]\n{{pokemonNameWithAffix}}의 {{itemName}}[[를]] 가로챘다!", diff --git a/src/locales/ko/move-trigger.json b/src/locales/ko/move-trigger.json index 8a3a699d628..a8a6c0cf86f 100644 --- a/src/locales/ko/move-trigger.json +++ b/src/locales/ko/move-trigger.json @@ -4,9 +4,10 @@ "absorbedElectricity": "{{pokemonName}}는(은)\n전기를 흡수했다!", "switchedStatChanges": "{{pokemonName}}[[는]] 상대와 자신의\n능력 변화를 바꿨다!", "switchedTwoStatChanges": "{{pokemonName}} 상대와 자신의 {{firstStat}}과 {{secondStat}}의 능력 변화를 바꿨다!", - "switchedStat": "{{pokemonName}} 서로의 {{stat}}를 교체했다!", - "sharedGuard": "{{pokemonName}} 서로의 가드를 셰어했다!", - "sharedPower": "{{pokemonName}} 서로의 파워를 셰어했다!", + "switchedStat": "{{pokemonName}}[[는]] 서로의 {{stat}}[[를]] 교체했다!", + "sharedGuard": "{{pokemonName}}[[는]] 서로의 가드를 셰어했다!", + "sharedPower": "{{pokemonName}}[[는]] 서로의 파워를 셰어했다!", + "shiftedStats": "{{pokemonName}}[[는]] {{statToSwitch}}[[와]] {{statToSwitchWith}}[[를]] 바꿨다!", "goingAllOutForAttack": "{{pokemonName}}[[는]]\n전력을 다하기 시작했다!", "regainedHealth": "{{pokemonName}}[[는]]\n기력을 회복했다!", "keptGoingAndCrashed": "{{pokemonName}}[[는]]\n의욕이 넘쳐서 땅에 부딪쳤다!", diff --git a/src/locales/ko/pokemon-info.json b/src/locales/ko/pokemon-info.json index 1e26af64d0f..c708ee93c6e 100644 --- a/src/locales/ko/pokemon-info.json +++ b/src/locales/ko/pokemon-info.json @@ -13,8 +13,7 @@ "SPD": "스피드", "SPDshortened": "스피드", "ACC": "명중률", - "EVA": "회피율", - "HPStat": "HP" + "EVA": "회피율" }, "Type": { "UNKNOWN": "Unknown", diff --git a/src/phases/egg-lapse-phase.ts b/src/phases/egg-lapse-phase.ts index 1adb1568166..65426846bb3 100644 --- a/src/phases/egg-lapse-phase.ts +++ b/src/phases/egg-lapse-phase.ts @@ -17,14 +17,13 @@ import { EggHatchData } from "#app/data/egg-hatch-data"; export class EggLapsePhase extends Phase { private eggHatchData: EggHatchData[] = []; - private readonly minEggsToPromptSkip: number = 5; + private readonly minEggsToSkip: number = 2; constructor(scene: BattleScene) { super(scene); } start() { super.start(); - const eggsToHatch: Egg[] = this.scene.gameData.eggs.filter((egg: Egg) => { return Overrides.EGG_IMMEDIATE_HATCH_OVERRIDE ? true : --egg.hatchWaves < 1; }); @@ -32,8 +31,7 @@ export class EggLapsePhase extends Phase { this.eggHatchData= []; if (eggsToHatchCount > 0) { - - if (eggsToHatchCount >= this.minEggsToPromptSkip) { + if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 1) { this.scene.ui.showText(i18next.t("battle:eggHatching"), 0, () => { // show prompt for skip this.scene.ui.showText(i18next.t("battle:eggSkipPrompt"), 0); @@ -46,6 +44,10 @@ export class EggLapsePhase extends Phase { } ); }, 100, true); + } else if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 2) { + this.scene.queueMessage(i18next.t("battle:eggHatching")); + this.hatchEggsSkipped(eggsToHatch); + this.showSummary(); } else { // regular hatches, no summary this.scene.queueMessage(i18next.t("battle:eggHatching")); diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index bc88c21e1e1..66021845c29 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -126,6 +126,7 @@ export const SettingKeys = { EXP_Gains_Speed: "EXP_GAINS_SPEED", EXP_Party_Display: "EXP_PARTY_DISPLAY", Skip_Seen_Dialogues: "SKIP_SEEN_DIALOGUES", + Egg_Skip: "EGG_SKIP", Battle_Style: "BATTLE_STYLE", Enable_Retries: "ENABLE_RETRIES", Hide_IVs: "HIDE_IVS", @@ -281,6 +282,26 @@ export const Setting: Array = [ default: 0, type: SettingType.GENERAL }, + { + key: SettingKeys.Egg_Skip, + label: i18next.t("settings:eggSkip"), + options: [ + { + value: "Never", + label: i18next.t("settings:never") + }, + { + value: "Ask", + label: i18next.t("settings:ask") + }, + { + value: "Always", + label: i18next.t("settings:always") + } + ], + default: 1, + type: SettingType.GENERAL + }, { key: SettingKeys.Battle_Style, label: i18next.t("settings:battleStyle"), @@ -727,6 +748,9 @@ export function setSetting(scene: BattleScene, setting: string, value: integer): case SettingKeys.Skip_Seen_Dialogues: scene.skipSeenDialogues = Setting[index].options[value].value === "On"; break; + case SettingKeys.Egg_Skip: + scene.eggSkipPreference = value; + break; case SettingKeys.Battle_Style: scene.battleStyle = value; break; diff --git a/src/test/moves/roost.test.ts b/src/test/moves/roost.test.ts index cf07a3485e7..df7fc7096b0 100644 --- a/src/test/moves/roost.test.ts +++ b/src/test/moves/roost.test.ts @@ -1,4 +1,4 @@ -import { Abilities } from "#app/enums/abilities"; +import { Type } from "#app/data/type"; import { BattlerTagType } from "#app/enums/battler-tag-type"; import { Moves } from "#app/enums/moves"; import { Species } from "#app/enums/species"; @@ -27,33 +27,234 @@ describe("Moves - Roost", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override.battleType("single"); - game.override.enemySpecies(Species.STARAPTOR); - game.override.enemyAbility(Abilities.INSOMNIA); + game.override.enemySpecies(Species.RELICANTH); game.override.startingLevel(100); - game.override.enemyLevel(100); - game.override.moveset([Moves.STOMPING_TANTRUM]); - game.override.enemyMoveset([Moves.ROOST, Moves.ROOST, Moves.ROOST, Moves.ROOST]); + game.override.enemyLevel(60); + game.override.enemyMoveset(Moves.EARTHQUAKE); + game.override.moveset([Moves.ROOST, Moves.BURN_UP, Moves.DOUBLE_SHOCK]); + game.override.starterForms({ [Species.ROTOM]: 4 }); }); + /** + * Roost's behavior should be defined as: + * The pokemon loses its flying type for a turn. If the pokemon was ungroundd solely due to being a flying type, it will be grounded until end of turn. + * 1. Pure Flying type pokemon -> become normal type until end of turn + * 2. Dual Flying/X type pokemon -> become type X until end of turn + * 3. Pokemon that use burn up into roost (ex. Moltres) -> become flying due to burn up, then typeless until end of turn after using roost + * 4. If a pokemon is afflicted with Forest's Curse or Trick or treat, dual type pokemon will become 3 type pokemon after the flying type is regained + * Pure flying types become (Grass or Ghost) and then back to flying/ (Grass or Ghost), + * and pokemon post Burn up become () + * 5. If a pokemon is also ungrounded due to other reasons (such as levitate), it will stay ungrounded post roost, despite not being flying type. + * 6. Non flying types using roost (such as dunsparce) are already grounded, so this move will only heal and have no other effects. + */ + test( - "move should ground the user until the end of turn", + "Non flying type uses roost -> no type change, took damage", async () => { - await game.startBattle([Species.MAGIKARP]); - - const enemyPokemon = game.scene.getEnemyPokemon()!; - - const enemyStartingHp = enemyPokemon.hp; - - game.move.select(Moves.STOMPING_TANTRUM); - + await game.classicMode.startBattle([Species.DUNSPARCE]); + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerPokemonStartingHP = playerPokemon.hp; + game.move.select(Moves.ROOST); await game.phaseInterceptor.to(MoveEffectPhase); - expect(enemyPokemon.getTag(BattlerTagType.ROOSTED)).toBeDefined(); + // Should only be normal type, and NOT flying type + let playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemonTypes[0] === Type.NORMAL).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeTruthy(); await game.phaseInterceptor.to(TurnEndPhase); - expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); - expect(enemyPokemon.getTag(BattlerTagType.ROOSTED)).toBeUndefined(); + // Lose HP, still normal type + playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemon.hp).toBeLessThan(playerPokemonStartingHP); + expect(playerPokemonTypes[0] === Type.NORMAL).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeTruthy(); }, TIMEOUT ); + + test( + "Pure flying type -> becomes normal after roost and takes damage from ground moves -> regains flying", + async () => { + await game.classicMode.startBattle([Species.TORNADUS]); + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerPokemonStartingHP = playerPokemon.hp; + game.move.select(Moves.ROOST); + await game.phaseInterceptor.to(MoveEffectPhase); + + // Should only be normal type, and NOT flying type + let playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemonTypes[0] === Type.NORMAL).toBeTruthy(); + expect(playerPokemonTypes[0] === Type.FLYING).toBeFalsy(); + expect(playerPokemon.isGrounded()).toBeTruthy(); + + await game.phaseInterceptor.to(TurnEndPhase); + + // Should have lost HP and is now back to being pure flying + playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemon.hp).toBeLessThan(playerPokemonStartingHP); + expect(playerPokemonTypes[0] === Type.NORMAL).toBeFalsy(); + expect(playerPokemonTypes[0] === Type.FLYING).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeFalsy(); + + }, TIMEOUT + ); + + test( + "Dual X/flying type -> becomes type X after roost and takes damage from ground moves -> regains flying", + async () => { + await game.classicMode.startBattle([Species.HAWLUCHA]); + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerPokemonStartingHP = playerPokemon.hp; + game.move.select(Moves.ROOST); + await game.phaseInterceptor.to(MoveEffectPhase); + + // Should only be pure fighting type and grounded + let playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemonTypes[0] === Type.FIGHTING).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeTruthy(); + + await game.phaseInterceptor.to(TurnEndPhase); + + // Should have lost HP and is now back to being fighting/flying + playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemon.hp).toBeLessThan(playerPokemonStartingHP); + expect(playerPokemonTypes[0] === Type.FIGHTING).toBeTruthy(); + expect(playerPokemonTypes[1] === Type.FLYING).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeFalsy(); + + }, TIMEOUT + ); + + test( + "Pokemon with levitate after using roost should lose flying type but still be unaffected by ground moves", + async () => { + await game.classicMode.startBattle([Species.ROTOM]); + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerPokemonStartingHP = playerPokemon.hp; + game.move.select(Moves.ROOST); + await game.phaseInterceptor.to(MoveEffectPhase); + + // Should only be pure fighting type and grounded + let playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemonTypes[0] === Type.ELECTRIC).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeFalsy(); + + await game.phaseInterceptor.to(TurnEndPhase); + + // Should have lost HP and is now back to being fighting/flying + playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemon.hp).toBe(playerPokemonStartingHP); + expect(playerPokemonTypes[0] === Type.ELECTRIC).toBeTruthy(); + expect(playerPokemonTypes[1] === Type.FLYING).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeFalsy(); + + }, TIMEOUT + ); + + test( + "A fire/flying type that uses burn up, then roost should be typeless until end of turn", + async () => { + await game.classicMode.startBattle([Species.MOLTRES]); + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerPokemonStartingHP = playerPokemon.hp; + game.move.select(Moves.BURN_UP); + await game.phaseInterceptor.to(MoveEffectPhase); + + // Should only be pure flying type after burn up + let playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemonTypes[0] === Type.FLYING).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + + await game.phaseInterceptor.to(TurnEndPhase); + game.move.select(Moves.ROOST); + await game.phaseInterceptor.to(MoveEffectPhase); + + // Should only be typeless type after roost and is grounded + playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemon.getTag(BattlerTagType.ROOSTED)).toBeDefined(); + expect(playerPokemonTypes[0] === Type.UNKNOWN).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeTruthy(); + + await game.phaseInterceptor.to(TurnEndPhase); + + // Should go back to being pure flying and have taken damage from earthquake, and is ungrounded again + playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemon.hp).toBeLessThan(playerPokemonStartingHP); + expect(playerPokemonTypes[0] === Type.FLYING).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeFalsy(); + + }, TIMEOUT + ); + + test( + "An electric/flying type that uses double shock, then roost should be typeless until end of turn", + async () => { + game.override.enemySpecies(Species.ZEKROM); + await game.classicMode.startBattle([Species.ZAPDOS]); + const playerPokemon = game.scene.getPlayerPokemon()!; + const playerPokemonStartingHP = playerPokemon.hp; + game.move.select(Moves.DOUBLE_SHOCK); + await game.phaseInterceptor.to(MoveEffectPhase); + + // Should only be pure flying type after burn up + let playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemonTypes[0] === Type.FLYING).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + + await game.phaseInterceptor.to(TurnEndPhase); + game.move.select(Moves.ROOST); + await game.phaseInterceptor.to(MoveEffectPhase); + + // Should only be typeless type after roost and is grounded + playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemon.getTag(BattlerTagType.ROOSTED)).toBeDefined(); + expect(playerPokemonTypes[0] === Type.UNKNOWN).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeTruthy(); + + await game.phaseInterceptor.to(TurnEndPhase); + + // Should go back to being pure flying and have taken damage from earthquake, and is ungrounded again + playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemon.hp).toBeLessThan(playerPokemonStartingHP); + expect(playerPokemonTypes[0] === Type.FLYING).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeFalsy(); + + }, TIMEOUT + ); + + test( + "Dual Type Pokemon afflicted with Forests Curse/Trick or Treat and post roost will become dual type and then become 3 type at end of turn", + async () => { + game.override.enemyMoveset([Moves.TRICK_OR_TREAT, Moves.TRICK_OR_TREAT, Moves.TRICK_OR_TREAT, Moves.TRICK_OR_TREAT]); + await game.classicMode.startBattle([Species.MOLTRES]); + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.ROOST); + await game.phaseInterceptor.to(MoveEffectPhase); + + let playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemonTypes[0] === Type.FIRE).toBeTruthy(); + expect(playerPokemonTypes.length === 1).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeTruthy(); + + await game.phaseInterceptor.to(TurnEndPhase); + + // Should be fire/flying/ghost + playerPokemonTypes = playerPokemon.getTypes(); + expect(playerPokemonTypes.filter(type => type === Type.FLYING)).toHaveLength(1); + expect(playerPokemonTypes.filter(type => type === Type.FIRE)).toHaveLength(1); + expect(playerPokemonTypes.filter(type => type === Type.GHOST)).toHaveLength(1); + expect(playerPokemonTypes.length === 3).toBeTruthy(); + expect(playerPokemon.isGrounded()).toBeFalsy(); + + }, TIMEOUT + ); + }); diff --git a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts index 52ee49faee0..3bad3e0d0da 100644 --- a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -36,6 +36,7 @@ describe("Berries Abound - Mystery Encounter", () => { game = new GameManager(phaserGame); scene = game.scene; game.override.mysteryEncounterChance(100); + game.override.mysteryEncounterTier(MysteryEncounterTier.COMMON); game.override.startingWave(defaultWave); game.override.startingBiome(defaultBiome); game.override.disableTrainerWaves(); @@ -132,7 +133,7 @@ describe("Berries Abound - Mystery Encounter", () => { expect(enemyField[0].species.speciesId).toBe(speciesToSpawn); }); - it("should reward the player with X berries based on wave", async () => { + it("should reward the player with X berries based on wave", { retry: 5 }, async () => { await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); const numBerries = game.scene.currentBattle.mysteryEncounter!.misc.numBerries; diff --git a/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts b/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts index 86ba0b8161b..5f424ffea2c 100644 --- a/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/uncommon-breed-encounter.test.ts @@ -12,6 +12,7 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; import { CommandPhase } from "#app/phases/command-phase"; import { UncommonBreedEncounter } from "#app/data/mystery-encounters/encounters/uncommon-breed-encounter"; @@ -22,7 +23,6 @@ import { BerryType } from "#enums/berry-type"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { Stat } from "#enums/stat"; import { BerryModifier } from "#app/modifier/modifier"; -import { generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { modifierTypes } from "#app/modifier/modifier-type"; const namespace = "mysteryEncounter:uncommonBreed"; @@ -43,6 +43,7 @@ describe("Uncommon Breed - Mystery Encounter", () => { game = new GameManager(phaserGame); scene = game.scene; game.override.mysteryEncounterChance(100); + game.override.mysteryEncounterTier(MysteryEncounterTier.COMMON); game.override.startingWave(defaultWave); game.override.startingBiome(defaultBiome); game.override.disableTrainerWaves(); @@ -166,12 +167,13 @@ describe("Uncommon Breed - Mystery Encounter", () => { }); }); - it("should NOT be selectable if the player doesn't have enough berries", async () => { + it("should NOT be selectable if the player doesn't have enough berries", { retry: 5 }, async () => { await game.runToMysteryEncounter(MysteryEncounterType.UNCOMMON_BREED, defaultParty); // Clear out any pesky mods that slipped through test spin-up scene.modifiers.forEach(mod => { scene.removeModifier(mod); }); + await scene.updateModifiers(true); await game.phaseInterceptor.to(MysteryEncounterPhase, false); const encounterPhase = scene.getCurrentPhase(); @@ -189,7 +191,7 @@ describe("Uncommon Breed - Mystery Encounter", () => { expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled(); }); - it("Should skip fight when player meets requirements", async () => { + it("Should skip fight when player meets requirements", { retry: 5 }, async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.UNCOMMON_BREED, defaultParty); diff --git a/src/ui/modal-ui-handler.ts b/src/ui/modal-ui-handler.ts index 2aeafa68b23..80a39d7bf7f 100644 --- a/src/ui/modal-ui-handler.ts +++ b/src/ui/modal-ui-handler.ts @@ -92,13 +92,13 @@ export abstract class ModalUiHandler extends UiHandler { if (args[0].hasOwnProperty("fadeOut") && typeof args[0].fadeOut === "function") { const [ marginTop, marginRight, marginBottom, marginLeft ] = this.getMargin(); - const overlay = this.scene.add.rectangle(( this.getWidth() + marginLeft + marginRight) / 2, (this.getHeight() + marginTop + marginBottom) / 2,this.scene.game.canvas.width / 6,this.scene.game.canvas.height /6, 0); - overlay.setOrigin(0.5,0.5); + const overlay = this.scene.add.rectangle(( this.getWidth() + marginLeft + marginRight) / 2, (this.getHeight() + marginTop + marginBottom) / 2, this.scene.game.canvas.width / 6, this.scene.game.canvas.height /6, 0); + overlay.setOrigin(0.5, 0.5); overlay.setName("rect-ui-overlay-modal"); overlay.setAlpha(0); this.modalContainer.add(overlay); - this.modalContainer.moveTo(overlay,0); + this.modalContainer.moveTo(overlay, 0); this.scene.tweens.add({ targets: overlay,