Compare commits
No commits in common. "516c9a7d62138c08f973048c9eac6e3bb64ef12e" and "ef8a2b3cc85a197f51045ce93c4229387d882e3f" have entirely different histories.
516c9a7d62
...
ef8a2b3cc8
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -5,29 +5,29 @@
|
|||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 78,
|
||||
"h": 86
|
||||
"h": 87
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 78,
|
||||
"h": 86
|
||||
"w": 80,
|
||||
"h": 87
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 78,
|
||||
"h": 86
|
||||
"h": 87
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 78,
|
||||
"h": 86
|
||||
"h": 87
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -36,6 +36,6 @@
|
|||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:65266da62e9d2953511c0d68ae431345:c1ca63690bed8dd5af71bb443910c830:56468b7a2883e66dadcd2af13ebd8010$"
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:d3cce87ee0e3a880d840bffe9373d5d4:7c776d33b75abad1fe36b14a5e5734af:56468b7a2883e66dadcd2af13ebd8010$"
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
@ -1911,19 +1911,6 @@ export default class BattleScene extends SceneBase {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fades out current track for `delay` ms, then fades in new track.
|
||||
* @param newBgmKey
|
||||
* @param destroy
|
||||
* @param delay
|
||||
*/
|
||||
fadeAndSwitchBgm(newBgmKey: string, destroy: boolean = false, delay: number = 2000) {
|
||||
this.fadeOutBgm(delay, destroy);
|
||||
this.time.delayedCall(delay, () => {
|
||||
this.playBgm(newBgmKey);
|
||||
});
|
||||
}
|
||||
|
||||
playSound(sound: string | AnySound, config?: object): AnySound {
|
||||
const key = typeof sound === "string" ? sound : sound.key;
|
||||
config = config ?? {};
|
||||
|
@ -2170,16 +2157,6 @@ export default class BattleScene extends SceneBase {
|
|||
return 13.13;
|
||||
case "battle_macro_boss": //SWSH Rose Battle
|
||||
return 11.42;
|
||||
case "mystery_encounter_gen_5_gts": // BW GTS
|
||||
return 8.52;
|
||||
case "mystery_encounter_gen_6_gts": // XY GTS
|
||||
return 9.24;
|
||||
case "mystery_encounter_fun_and_games": // EoS Guildmaster Wigglytuff
|
||||
return 4.78;
|
||||
case "mystery_encounter_weird_dream": // EoS Temporal Spire
|
||||
return 41.42;
|
||||
case "mystery_encounter_delibirdy": // Firel Delibirdy
|
||||
return 82.28;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2626,7 +2603,7 @@ export default class BattleScene extends SceneBase {
|
|||
}
|
||||
|
||||
party.forEach((enemyPokemon: EnemyPokemon, i: integer) => {
|
||||
if (heldModifiersConfigs && i < heldModifiersConfigs.length && heldModifiersConfigs[i]) {
|
||||
if (heldModifiersConfigs && i < heldModifiersConfigs.length && heldModifiersConfigs[i] && heldModifiersConfigs[i].length > 0) {
|
||||
heldModifiersConfigs[i].forEach(mt => {
|
||||
let modifier: PokemonHeldItemModifier;
|
||||
if (mt.modifier instanceof PokemonHeldItemModifierType) {
|
||||
|
@ -2637,7 +2614,8 @@ export default class BattleScene extends SceneBase {
|
|||
}
|
||||
const stackCount = mt.stackCount ?? 1;
|
||||
modifier.stackCount = stackCount;
|
||||
modifier.isTransferable = mt.isTransferable ?? modifier.isTransferable;
|
||||
// TODO: set isTransferable
|
||||
// modifier.isTransferrable = mt.isTransferable ?? true;
|
||||
this.addEnemyModifier(modifier, true);
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -14,7 +14,7 @@ import { PlayerGender } from "#enums/player-gender";
|
|||
import { Species } from "#enums/species";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import i18next from "#app/plugins/i18n";
|
||||
import MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter from "./data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
|
||||
export enum BattleType {
|
||||
|
@ -157,7 +157,7 @@ export default class Battle {
|
|||
}
|
||||
|
||||
addPostBattleLoot(enemyPokemon: EnemyPokemon): void {
|
||||
this.postBattleLoot.push(...enemyPokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id && m.isTransferable, false).map(i => {
|
||||
this.postBattleLoot.push(...enemyPokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id && m.isTransferrable, false).map(i => {
|
||||
const ret = i as PokemonHeldItemModifier;
|
||||
//@ts-ignore - this is awful to fix/change
|
||||
ret.pokemonId = null;
|
||||
|
|
|
@ -1670,7 +1670,7 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
|||
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.stealCondition || this.stealCondition(pokemon, defender, move))) {
|
||||
const heldItems = this.getTargetHeldItems(defender).filter(i => i.isTransferable);
|
||||
const heldItems = this.getTargetHeldItems(defender).filter(i => i.isTransferrable);
|
||||
if (heldItems.length) {
|
||||
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
||||
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
|
||||
|
@ -1763,7 +1763,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
|||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) {
|
||||
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable);
|
||||
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferrable);
|
||||
if (heldItems.length) {
|
||||
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
||||
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { ChargeAnim, initMoveAnim, loadMoveAnimAssets, MoveChargeAnim } from "./battle-anims";
|
||||
import { EncoreTag, GulpMissileTag, HelpingHandTag, SemiInvulnerableTag, ShellTrapTag, StockpilingTag, SubstituteTag, TrappedTag, TypeBoostTag } from "./battler-tags";
|
||||
import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims";
|
||||
import { EncoreTag, GulpMissileTag, HelpingHandTag, SemiInvulnerableTag, ShellTrapTag, StockpilingTag, TrappedTag, SubstituteTag, TypeBoostTag } from "./battler-tags";
|
||||
import { getPokemonNameWithAffix } from "../messages";
|
||||
import Pokemon, { AttackMoveResult, EnemyPokemon, HitResult, MoveResult, PlayerPokemon, PokemonMove, TurnMove } from "../field/pokemon";
|
||||
import { getNonVolatileStatusEffects, getStatusEffectHealText, isNonVolatileStatusEffect, StatusEffect } from "./status-effect";
|
||||
import { StatusEffect, getStatusEffectHealText, isNonVolatileStatusEffect, getNonVolatileStatusEffects } from "./status-effect";
|
||||
import { getTypeDamageMultiplier, Type } from "./type";
|
||||
import { Constructor, NumberHolder } from "#app/utils";
|
||||
import { Constructor } from "#app/utils";
|
||||
import * as Utils from "../utils";
|
||||
import { WeatherType } from "./weather";
|
||||
import { ArenaTagSide, ArenaTrapTag, WeakenMoveTypeTag } from "./arena-tag";
|
||||
import { allAbilities, AllyMoveCategoryPowerBoostAbAttr, applyAbAttrs, applyPostAttackAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, BlockItemTheftAbAttr, BlockNonDirectDamageAbAttr, BlockOneHitKOAbAttr, BlockRecoilDamageAttr, ConfusionOnStatusEffectAbAttr, FieldMoveTypePowerBoostAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, HealFromBerryUseAbAttr, IgnoreContactAbAttr, IgnoreMoveEffectsAbAttr, IgnoreProtectOnContactAbAttr, MaxMultiHitAbAttr, MoveAbilityBypassAbAttr, MoveEffectChanceMultiplierAbAttr, MoveTypeChangeAbAttr, ReverseDrainAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, UnswappableAbilityAbAttr, UserFieldMoveTypePowerBoostAbAttr, VariableMovePowerAbAttr, WonderSkinAbAttr } from "./ability";
|
||||
import { AttackTypeBoosterModifier, BerryModifier, PokemonHeldItemModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PreserveBerryModifier } from "../modifier/modifier";
|
||||
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, BlockItemTheftAbAttr, applyPostAttackAbAttrs, ConfusionOnStatusEffectAbAttr, HealFromBerryUseAbAttr, IgnoreProtectOnContactAbAttr, IgnoreMoveEffectsAbAttr, applyPreDefendAbAttrs, MoveEffectChanceMultiplierAbAttr, WonderSkinAbAttr, applyPreAttackAbAttrs, MoveTypeChangeAbAttr, UserFieldMoveTypePowerBoostAbAttr, FieldMoveTypePowerBoostAbAttr, AllyMoveCategoryPowerBoostAbAttr, VariableMovePowerAbAttr } from "./ability";
|
||||
import { allAbilities } from "./ability";
|
||||
import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier, PokemonMoveAccuracyBoosterModifier, AttackTypeBoosterModifier, PokemonMultiHitModifier } from "../modifier/modifier";
|
||||
import { BattlerIndex, BattleType } from "../battle";
|
||||
import { TerrainType } from "./terrain";
|
||||
import { ModifierPoolType } from "#app/modifier/modifier-type";
|
||||
|
@ -24,7 +25,7 @@ import { Biome } from "#enums/biome";
|
|||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import { MoveUsedEvent } from "#app/events/battle-scene";
|
||||
import { BATTLE_STATS, type BattleStat, EFFECTIVE_STATS, type EffectiveStat, getStatKey, Stat } from "#app/enums/stat";
|
||||
import { Stat, type BattleStat, type EffectiveStat, BATTLE_STATS, EFFECTIVE_STATS, getStatKey } from "#app/enums/stat";
|
||||
import { PartyStatusCurePhase } from "#app/phases/party-status-cure-phase";
|
||||
import { BattleEndPhase } from "#app/phases/battle-end-phase";
|
||||
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
||||
|
@ -35,6 +36,7 @@ import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
|||
import { SwitchPhase } from "#app/phases/switch-phase";
|
||||
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
|
||||
import { SpeciesFormChangeRevertWeatherFormTrigger } from "./pokemon-forms";
|
||||
import { NumberHolder } from "#app/utils";
|
||||
import { GameMode } from "#app/game-mode";
|
||||
import { applyChallenges, ChallengeType } from "./challenge";
|
||||
|
||||
|
@ -2134,7 +2136,7 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
|
|||
if (rand >= this.chance) {
|
||||
return resolve(false);
|
||||
}
|
||||
const heldItems = this.getTargetHeldItems(target).filter(i => i.isTransferable);
|
||||
const heldItems = this.getTargetHeldItems(target).filter(i => i.isTransferrable);
|
||||
if (heldItems.length) {
|
||||
const poolType = target.isPlayer() ? ModifierPoolType.PLAYER : target.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD;
|
||||
const highestItemTier = heldItems.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier!, highestTier), 0); // TODO: is the bang after tier correct?
|
||||
|
@ -2211,7 +2213,7 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
|
|||
}
|
||||
|
||||
// Considers entire transferrable item pool by default (Knock Off). Otherwise berries only if specified (Incinerate).
|
||||
let heldItems = this.getTargetHeldItems(target).filter(i => i.isTransferable);
|
||||
let heldItems = this.getTargetHeldItems(target).filter(i => i.isTransferrable);
|
||||
|
||||
if (this.berriesOnly) {
|
||||
heldItems = heldItems.filter(m => m instanceof BerryModifier && m.pokemonId === target.id, target.isPlayer());
|
||||
|
@ -2415,16 +2417,6 @@ export class BypassSleepAttr extends MoveAttr {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns arbitrarily high score when Pokemon is asleep, otherwise shouldn't be used
|
||||
* @param user
|
||||
* @param target
|
||||
* @param move
|
||||
*/
|
||||
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
||||
return user.status && user.status.effect === StatusEffect.SLEEP ? 200 : -10;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4859,18 +4851,16 @@ export class RemoveAllSubstitutesAttr extends MoveEffectAttr {
|
|||
}
|
||||
|
||||
/**
|
||||
* Attribute used when a move can deal damage to {@linkcode BattlerTagType}
|
||||
* Moves that always hit but do not deal double damage: Thunder, Fissure, Sky Uppercut,
|
||||
* Smack Down, Hurricane, Thousand Arrows
|
||||
* Attribute used when a move hits a {@linkcode BattlerTagType} for double damage
|
||||
* @extends MoveAttr
|
||||
*/
|
||||
export class HitsTagAttr extends MoveAttr {
|
||||
export class DealsDoubleDamageToTagAttr extends MoveAttr {
|
||||
/** The {@linkcode BattlerTagType} this move hits */
|
||||
public tagType: BattlerTagType;
|
||||
/** Should this move deal double damage against {@linkcode HitsTagAttr.tagType}? */
|
||||
/** Should this move deal double damage against {@linkcode DealsDoubleDamageToTagAttr.tagType}? */
|
||||
public doubleDamage: boolean;
|
||||
|
||||
constructor(tagType: BattlerTagType, doubleDamage: boolean = false) {
|
||||
constructor(tagType: BattlerTagType, doubleDamage?: boolean) {
|
||||
super();
|
||||
|
||||
this.tagType = tagType;
|
||||
|
@ -4882,17 +4872,6 @@ export class HitsTagAttr extends MoveAttr {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for moves that will always hit for a given tag but also doubles damage.
|
||||
* Moves include: Gust, Stomp, Body Slam, Surf, Earthquake, Magnitude, Twister,
|
||||
* Whirlpool, Dragon Rush, Heat Crash, Steam Roller, Flying Press
|
||||
*/
|
||||
export class HitsTagForDoubleDamageAttr extends HitsTagAttr {
|
||||
constructor(tagType: BattlerTagType) {
|
||||
super(tagType, true);
|
||||
}
|
||||
}
|
||||
|
||||
export class AddArenaTagAttr extends MoveEffectAttr {
|
||||
public tagType: ArenaTagType;
|
||||
public turnCount: integer;
|
||||
|
@ -6413,7 +6392,7 @@ export class AttackedByItemAttr extends MoveAttr {
|
|||
*/
|
||||
getCondition(): MoveConditionFunc {
|
||||
return (user: Pokemon, target: Pokemon, move: Move) => {
|
||||
const heldItems = target.getHeldItems().filter(i => i.isTransferable);
|
||||
const heldItems = target.getHeldItems().filter(i => i.isTransferrable);
|
||||
if (heldItems.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -6772,7 +6751,7 @@ export function initMoves() {
|
|||
new AttackMove(Moves.CUT, Type.NORMAL, MoveCategory.PHYSICAL, 50, 95, 30, -1, 0, 1)
|
||||
.slicingMove(),
|
||||
new AttackMove(Moves.GUST, Type.FLYING, MoveCategory.SPECIAL, 40, 100, 35, -1, 0, 1)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.FLYING)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.FLYING, true)
|
||||
.windMove(),
|
||||
new AttackMove(Moves.WING_ATTACK, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 35, -1, 0, 1),
|
||||
new StatusMove(Moves.WHIRLWIND, Type.NORMAL, -1, 20, -1, -6, 1)
|
||||
|
@ -6790,7 +6769,7 @@ export function initMoves() {
|
|||
new AttackMove(Moves.VINE_WHIP, Type.GRASS, MoveCategory.PHYSICAL, 45, 100, 25, -1, 0, 1),
|
||||
new AttackMove(Moves.STOMP, Type.NORMAL, MoveCategory.PHYSICAL, 65, 100, 20, 30, 0, 1)
|
||||
.attr(AlwaysHitMinimizeAttr)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.MINIMIZED)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.MINIMIZED, true)
|
||||
.attr(FlinchAttr),
|
||||
new AttackMove(Moves.DOUBLE_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 30, 100, 30, -1, 0, 1)
|
||||
.attr(MultiHitAttr, MultiHitType._2),
|
||||
|
@ -6815,7 +6794,7 @@ export function initMoves() {
|
|||
new AttackMove(Moves.TACKLE, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 35, -1, 0, 1),
|
||||
new AttackMove(Moves.BODY_SLAM, Type.NORMAL, MoveCategory.PHYSICAL, 85, 100, 15, 30, 0, 1)
|
||||
.attr(AlwaysHitMinimizeAttr)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.MINIMIZED)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.MINIMIZED, true)
|
||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS),
|
||||
new AttackMove(Moves.WRAP, Type.NORMAL, MoveCategory.PHYSICAL, 15, 90, 20, -1, 0, 1)
|
||||
.attr(TrapAttr, BattlerTagType.WRAP),
|
||||
|
@ -6883,7 +6862,7 @@ export function initMoves() {
|
|||
new AttackMove(Moves.HYDRO_PUMP, Type.WATER, MoveCategory.SPECIAL, 110, 80, 5, -1, 0, 1),
|
||||
new AttackMove(Moves.SURF, Type.WATER, MoveCategory.SPECIAL, 90, 100, 15, -1, 0, 1)
|
||||
.target(MoveTarget.ALL_NEAR_OTHERS)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.UNDERWATER)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.UNDERWATER, true)
|
||||
.attr(GulpMissileTagAttr),
|
||||
new AttackMove(Moves.ICE_BEAM, Type.ICE, MoveCategory.SPECIAL, 90, 100, 10, 10, 0, 1)
|
||||
.attr(StatusEffectAttr, StatusEffect.FREEZE),
|
||||
|
@ -6966,18 +6945,18 @@ export function initMoves() {
|
|||
new AttackMove(Moves.THUNDER, Type.ELECTRIC, MoveCategory.SPECIAL, 110, 70, 10, 30, 0, 1)
|
||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS)
|
||||
.attr(ThunderAccuracyAttr)
|
||||
.attr(HitsTagAttr, BattlerTagType.FLYING),
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.FLYING, false),
|
||||
new AttackMove(Moves.ROCK_THROW, Type.ROCK, MoveCategory.PHYSICAL, 50, 90, 15, -1, 0, 1)
|
||||
.makesContact(false),
|
||||
new AttackMove(Moves.EARTHQUAKE, Type.GROUND, MoveCategory.PHYSICAL, 100, 100, 10, -1, 0, 1)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.UNDERGROUND)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.UNDERGROUND, true)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.GRASSY && target.isGrounded() ? 0.5 : 1)
|
||||
.makesContact(false)
|
||||
.target(MoveTarget.ALL_NEAR_OTHERS),
|
||||
new AttackMove(Moves.FISSURE, Type.GROUND, MoveCategory.PHYSICAL, 200, 30, 5, -1, 0, 1)
|
||||
.attr(OneHitKOAttr)
|
||||
.attr(OneHitKOAccuracyAttr)
|
||||
.attr(HitsTagAttr, BattlerTagType.UNDERGROUND)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.UNDERGROUND, false)
|
||||
.makesContact(false),
|
||||
new AttackMove(Moves.DIG, Type.GROUND, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 1)
|
||||
.attr(ChargeAttr, ChargeAnim.DIG_CHARGING, i18next.t("moveTriggers:dugAHole", {pokemonName: "{USER}"}), BattlerTagType.UNDERGROUND)
|
||||
|
@ -7366,7 +7345,7 @@ export function initMoves() {
|
|||
.attr(PreMoveMessageAttr, magnitudeMessageFunc)
|
||||
.attr(MagnitudePowerAttr)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.GRASSY && target.isGrounded() ? 0.5 : 1)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.UNDERGROUND)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.UNDERGROUND, true)
|
||||
.makesContact(false)
|
||||
.target(MoveTarget.ALL_NEAR_OTHERS),
|
||||
new AttackMove(Moves.DYNAMIC_PUNCH, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 50, 5, 100, 0, 2)
|
||||
|
@ -7422,7 +7401,7 @@ export function initMoves() {
|
|||
new AttackMove(Moves.CROSS_CHOP, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 80, 5, -1, 0, 2)
|
||||
.attr(HighCritAttr),
|
||||
new AttackMove(Moves.TWISTER, Type.DRAGON, MoveCategory.SPECIAL, 40, 100, 20, 20, 0, 2)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.FLYING)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.FLYING, true)
|
||||
.attr(FlinchAttr)
|
||||
.windMove()
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||
|
@ -7454,7 +7433,7 @@ export function initMoves() {
|
|||
.attr(StatStageChangeAttr, [ Stat.DEF ], -1),
|
||||
new AttackMove(Moves.WHIRLPOOL, Type.WATER, MoveCategory.SPECIAL, 35, 85, 15, -1, 0, 2)
|
||||
.attr(TrapAttr, BattlerTagType.WHIRLPOOL)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.UNDERWATER),
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.UNDERWATER, true),
|
||||
new AttackMove(Moves.BEAT_UP, Type.DARK, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 2)
|
||||
.attr(MultiHitAttr, MultiHitType.BEAT_UP)
|
||||
.attr(BeatUpAttr)
|
||||
|
@ -7552,7 +7531,7 @@ export function initMoves() {
|
|||
.attr(AddBattlerTagAttr, BattlerTagType.DROWSY, false, true)
|
||||
.condition((user, target, move) => !target.status && !target.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY)),
|
||||
new AttackMove(Moves.KNOCK_OFF, Type.DARK, MoveCategory.PHYSICAL, 65, 100, 20, -1, 0, 3)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getHeldItems().filter(i => i.isTransferable).length > 0 ? 1.5 : 1)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getHeldItems().filter(i => i.isTransferrable).length > 0 ? 1.5 : 1)
|
||||
.attr(RemoveHeldItemAttr, false),
|
||||
new AttackMove(Moves.ENDEAVOR, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 3)
|
||||
.attr(MatchHpAttr)
|
||||
|
@ -7677,7 +7656,7 @@ export function initMoves() {
|
|||
new AttackMove(Moves.EXTRASENSORY, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 20, 10, 0, 3)
|
||||
.attr(FlinchAttr),
|
||||
new AttackMove(Moves.SKY_UPPERCUT, Type.FIGHTING, MoveCategory.PHYSICAL, 85, 90, 15, -1, 0, 3)
|
||||
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.FLYING)
|
||||
.punchingMove(),
|
||||
new AttackMove(Moves.SAND_TOMB, Type.GROUND, MoveCategory.PHYSICAL, 35, 85, 15, -1, 0, 3)
|
||||
.attr(TrapAttr, BattlerTagType.SAND_TOMB)
|
||||
|
@ -7909,7 +7888,7 @@ export function initMoves() {
|
|||
.pulseMove(),
|
||||
new AttackMove(Moves.DRAGON_RUSH, Type.DRAGON, MoveCategory.PHYSICAL, 100, 75, 10, 20, 0, 4)
|
||||
.attr(AlwaysHitMinimizeAttr)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.MINIMIZED)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.MINIMIZED, true)
|
||||
.attr(FlinchAttr),
|
||||
new AttackMove(Moves.POWER_GEM, Type.ROCK, MoveCategory.SPECIAL, 80, 100, 20, -1, 0, 4),
|
||||
new AttackMove(Moves.DRAIN_PUNCH, Type.FIGHTING, MoveCategory.PHYSICAL, 75, 100, 10, -1, 0, 4)
|
||||
|
@ -8106,7 +8085,7 @@ export function initMoves() {
|
|||
.attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
|
||||
.attr(RemoveBattlerTagAttr, [BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN])
|
||||
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.FLYING, false)
|
||||
.makesContact(false),
|
||||
new AttackMove(Moves.STORM_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5)
|
||||
.attr(CritOnlyAttr),
|
||||
|
@ -8121,7 +8100,7 @@ export function initMoves() {
|
|||
new AttackMove(Moves.HEAVY_SLAM, Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 5)
|
||||
.attr(AlwaysHitMinimizeAttr)
|
||||
.attr(CompareWeightPowerAttr)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.MINIMIZED),
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.MINIMIZED, true),
|
||||
new AttackMove(Moves.SYNCHRONOISE, Type.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 5)
|
||||
.target(MoveTarget.ALL_NEAR_OTHERS)
|
||||
.condition(unknownTypeCondition)
|
||||
|
@ -8204,7 +8183,7 @@ export function initMoves() {
|
|||
new StatusMove(Moves.QUASH, Type.DARK, 100, 15, -1, 0, 5)
|
||||
.unimplemented(),
|
||||
new AttackMove(Moves.ACROBATICS, Type.FLYING, MoveCategory.PHYSICAL, 55, 100, 15, -1, 0, 5)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => Math.max(1, 2 - 0.2 * user.getHeldItems().filter(i => i.isTransferable).reduce((v, m) => v + m.stackCount, 0))),
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => Math.max(1, 2 - 0.2 * user.getHeldItems().filter(i => i.isTransferrable).reduce((v, m) => v + m.stackCount, 0))),
|
||||
new StatusMove(Moves.REFLECT_TYPE, Type.NORMAL, -1, 15, -1, 0, 5)
|
||||
.ignoresSubstitute()
|
||||
.attr(CopyTypeAttr),
|
||||
|
@ -8274,12 +8253,12 @@ export function initMoves() {
|
|||
new AttackMove(Moves.HEAT_CRASH, Type.FIRE, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 5)
|
||||
.attr(AlwaysHitMinimizeAttr)
|
||||
.attr(CompareWeightPowerAttr)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.MINIMIZED),
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.MINIMIZED, true),
|
||||
new AttackMove(Moves.LEAF_TORNADO, Type.GRASS, MoveCategory.SPECIAL, 65, 90, 10, 50, 0, 5)
|
||||
.attr(StatStageChangeAttr, [ Stat.ACC ], -1),
|
||||
new AttackMove(Moves.STEAMROLLER, Type.BUG, MoveCategory.PHYSICAL, 65, 100, 20, 30, 0, 5)
|
||||
.attr(AlwaysHitMinimizeAttr)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.MINIMIZED)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.MINIMIZED, true)
|
||||
.attr(FlinchAttr),
|
||||
new SelfStatusMove(Moves.COTTON_GUARD, Type.GRASS, -1, 10, -1, 0, 5)
|
||||
.attr(StatStageChangeAttr, [ Stat.DEF ], 3, true),
|
||||
|
@ -8292,7 +8271,7 @@ export function initMoves() {
|
|||
new AttackMove(Moves.HURRICANE, Type.FLYING, MoveCategory.SPECIAL, 110, 70, 10, 30, 0, 5)
|
||||
.attr(ThunderAccuracyAttr)
|
||||
.attr(ConfuseAttr)
|
||||
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.FLYING, false)
|
||||
.windMove(),
|
||||
new AttackMove(Moves.HEAD_CHARGE, Type.NORMAL, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 5)
|
||||
.attr(RecoilAttr)
|
||||
|
@ -8348,7 +8327,7 @@ export function initMoves() {
|
|||
new AttackMove(Moves.FLYING_PRESS, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 95, 10, -1, 0, 6)
|
||||
.attr(AlwaysHitMinimizeAttr)
|
||||
.attr(FlyingTypeMultiplierAttr)
|
||||
.attr(HitsTagForDoubleDamageAttr, BattlerTagType.MINIMIZED)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.MINIMIZED, true)
|
||||
.condition(failOnGravityCondition),
|
||||
new StatusMove(Moves.MAT_BLOCK, Type.FIGHTING, -1, 10, -1, 0, 6)
|
||||
.target(MoveTarget.USER_SIDE)
|
||||
|
@ -8519,8 +8498,8 @@ export function initMoves() {
|
|||
new AttackMove(Moves.THOUSAND_ARROWS, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6)
|
||||
.attr(NeutralDamageAgainstFlyingTypeMultiplierAttr)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true)
|
||||
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
||||
.attr(HitsTagAttr, BattlerTagType.MAGNET_RISEN)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.FLYING, false)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.MAGNET_RISEN, false)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
|
||||
.attr(RemoveBattlerTagAttr, [BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN])
|
||||
.makesContact(false)
|
||||
|
@ -8778,7 +8757,7 @@ export function initMoves() {
|
|||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.MALICIOUS_MOONSAULT, Type.DARK, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7)
|
||||
.attr(AlwaysHitMinimizeAttr)
|
||||
.attr(HitsTagAttr, BattlerTagType.MINIMIZED, true)
|
||||
.attr(DealsDoubleDamageToTagAttr, BattlerTagType.MINIMIZED, true)
|
||||
.partial()
|
||||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.OCEANIC_OPERETTA, Type.WATER, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
|
||||
|
|
|
@ -2,7 +2,7 @@ import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattl
|
|||
import { trainerConfigs, } from "#app/data/trainer-config";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { Species } from "#enums/species";
|
||||
|
@ -99,7 +99,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||
const trainerConfig = trainerConfigs[trainerType].clone();
|
||||
const trainerSpriteKey = trainerConfig.getSpriteKey();
|
||||
encounter.enemyPartyConfigs.push({
|
||||
levelAdditiveModifier: 1,
|
||||
levelAdditiveMultiplier: 1,
|
||||
trainerConfig: trainerConfig
|
||||
});
|
||||
|
||||
|
@ -152,6 +152,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||
};
|
||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.epic`));
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SACRED_ASH], guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ULTRA], fillRemaining: true }, [eggOptions]);
|
||||
|
||||
return initBattleWithEnemyConfig(scene, config);
|
||||
}
|
||||
)
|
||||
|
@ -179,7 +180,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||
)
|
||||
.withOutroDialogue([
|
||||
{
|
||||
text: `${namespace}.outro`
|
||||
}
|
||||
text: `${namespace}.outro`,
|
||||
},
|
||||
])
|
||||
.build();
|
||||
|
|
|
@ -4,9 +4,9 @@ import { BerryModifierType, modifierTypes, PokemonHeldItemModifierType } from "#
|
|||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { Species } from "#enums/species";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { PersistentModifierRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { PersistentModifierRequirement } from "../mystery-encounter-requirements";
|
||||
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
|
@ -208,7 +208,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||
|
||||
// Calculate boss mon
|
||||
const config: EnemyPartyConfig = {
|
||||
levelAdditiveModifier: 1,
|
||||
levelAdditiveMultiplier: 1,
|
||||
pokemonConfigs: [
|
||||
{
|
||||
species: getPokemonSpecies(Species.GREEDENT),
|
||||
|
@ -291,7 +291,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||
const berryMap = encounter.misc.berryItemsMap;
|
||||
|
||||
// Returns 2/5 of the berries stolen to each Pokemon
|
||||
// Returns 2/5 of the berries stolen from each Pokemon
|
||||
const party = scene.getParty();
|
||||
party.forEach(pokemon => {
|
||||
const stolenBerries: BerryModifier[] = berryMap.get(pokemon.id);
|
||||
|
@ -310,7 +310,6 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||
}
|
||||
}
|
||||
});
|
||||
await scene.updateModifiers(true);
|
||||
|
||||
transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
|
||||
leaveEncounterWithoutBattle(scene, true);
|
||||
|
|
|
@ -3,9 +3,9 @@ import { modifierTypes } from "#app/modifier/modifier-type";
|
|||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { Species } from "#enums/species";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { AbilityRequirement, CombinationPokemonRequirement, MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { AbilityRequirement, CombinationPokemonRequirement, MoveRequirement } from "../mystery-encounter-requirements";
|
||||
import { getHighestStatTotalPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { EXTORTION_ABILITIES, EXTORTION_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
|
|
|
@ -17,13 +17,13 @@ import { randSeedInt } from "#app/utils";
|
|||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { TrainerSlot } from "#app/data/trainer-config";
|
||||
import { applyModifierTypeToPlayerPokemon, getEncounterPokemonLevelForWave, getHighestStatPlayerPokemon, getSpriteKeysFromPokemon, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { applyModifierTypeToPlayerPokemon, getHighestStatPlayerPokemon, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { BerryModifier } from "#app/modifier/modifier";
|
||||
import i18next from "#app/plugins/i18n";
|
||||
|
@ -56,11 +56,12 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||
|
||||
// Calculate boss mon
|
||||
const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||
const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0);
|
||||
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true);
|
||||
const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true);
|
||||
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
|
||||
const config: EnemyPartyConfig = {
|
||||
levelAdditiveMultiplier: 1,
|
||||
pokemonConfigs: [{
|
||||
level: level,
|
||||
species: bossSpecies,
|
||||
|
|
|
@ -19,7 +19,7 @@ import { PartyMemberStrength } from "#enums/party-member-strength";
|
|||
import BattleScene from "#app/battle-scene";
|
||||
import * as Utils from "#app/utils";
|
||||
import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#app/utils";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { Species } from "#enums/species";
|
||||
|
@ -192,7 +192,6 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
||||
new TypeRequirement(Type.BUG, false, 1)
|
||||
))
|
||||
.withMaxAllowedEncounters(1)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||
.withAutoHideIntroVisuals(false)
|
||||
|
@ -287,8 +286,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||
|
||||
// Player gets different rewards depending on the number of bug types they have
|
||||
const numBugTypes = scene.getParty().filter(p => p.isOfType(Type.BUG, true)).length;
|
||||
const numBugTypesText = i18next.t(`${namespace}.numBugTypes`, { count: numBugTypes });
|
||||
encounter.setDialogueToken("numBugTypes", numBugTypesText);
|
||||
encounter.setDialogueToken("numBugTypes", numBugTypes.toString());
|
||||
|
||||
if (numBugTypes < 2) {
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL], fillRemaining: false });
|
||||
|
|
|
@ -5,7 +5,7 @@ import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifi
|
|||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { Species } from "#enums/species";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
|
@ -246,12 +246,12 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||
const party = scene.getParty();
|
||||
let mostHeldItemsPokemon = party[0];
|
||||
let count = mostHeldItemsPokemon.getHeldItems()
|
||||
.filter(m => m.isTransferable && !(m instanceof BerryModifier))
|
||||
.filter(m => m.isTransferrable && !(m instanceof BerryModifier))
|
||||
.reduce((v, m) => v + m.stackCount, 0);
|
||||
|
||||
party.forEach(pokemon => {
|
||||
const nextCount = pokemon.getHeldItems()
|
||||
.filter(m => m.isTransferable && !(m instanceof BerryModifier))
|
||||
.filter(m => m.isTransferrable && !(m instanceof BerryModifier))
|
||||
.reduce((v, m) => v + m.stackCount, 0);
|
||||
if (nextCount > count) {
|
||||
mostHeldItemsPokemon = pokemon;
|
||||
|
@ -276,7 +276,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||
// Shuffle Transferable held items in the same tier (only shuffles Ultra and Rogue atm)
|
||||
let numUltra = 0;
|
||||
let numRogue = 0;
|
||||
items.filter(m => m.isTransferable && !(m instanceof BerryModifier))
|
||||
items.filter(m => m.isTransferrable && !(m instanceof BerryModifier))
|
||||
.forEach(m => {
|
||||
const type = m.type.withTierFromPool();
|
||||
const tier = type.tier ?? ModifierTier.ULTRA;
|
||||
|
|
|
@ -3,8 +3,8 @@ import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/po
|
|||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { Species } from "#enums/species";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
|
@ -19,7 +19,7 @@ import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-
|
|||
import { DANCING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { catchPokemon, getEncounterPokemonLevelForWave, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { catchPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||
|
@ -107,7 +107,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||
|
||||
const species = getPokemonSpecies(Species.ORICORIO);
|
||||
const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||
const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0);
|
||||
const enemyPokemon = new EnemyPokemon(scene, species, level, TrainerSlot.NONE, false);
|
||||
if (!enemyPokemon.moveset.some(m => m && m.getMove().id === Moves.REVELATION_DANCE)) {
|
||||
if (enemyPokemon.moveset.length < 4) {
|
||||
|
@ -146,6 +146,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||
encounter.loadAssets.push(oricorio.loadAssets());
|
||||
|
||||
const config: EnemyPartyConfig = {
|
||||
levelAdditiveMultiplier: 1,
|
||||
pokemonConfigs: [{
|
||||
species: species,
|
||||
dataSource: oricorioData,
|
||||
|
|
|
@ -5,8 +5,8 @@ import { Species } from "#enums/species";
|
|||
import BattleScene from "#app/battle-scene";
|
||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { EnemyPartyConfig, EnemyPokemonConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, } from "../utils/encounter-phase-utils";
|
||||
import { getRandomPlayerPokemon, getRandomSpeciesByStarterTier } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
|
@ -18,7 +18,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||
/** i18n namespace for encounter */
|
||||
const namespace = "mysteryEncounter:darkDeal";
|
||||
|
||||
/** Exclude Ultra Beasts (inludes Cosmog/Solgaleo/Lunala/Necrozma), Paradox (includes Miraidon/Koraidon), Eternatus, and Mythicals */
|
||||
/** Exclude Ultra Beasts (inludes Cosmog/Solgaleo/Lunala/Necrozma), Paradox (includes Miraidon/Koraidon), Eternatus, and egg-locked mythicals */
|
||||
const excludedBosses = [
|
||||
Species.NECROZMA,
|
||||
Species.COSMOG,
|
||||
|
@ -63,24 +63,11 @@ const excludedBosses = [
|
|||
Species.CELEBI,
|
||||
Species.DEOXYS,
|
||||
Species.JIRACHI,
|
||||
Species.DARKRAI,
|
||||
Species.PHIONE,
|
||||
Species.MANAPHY,
|
||||
Species.ARCEUS,
|
||||
Species.SHAYMIN,
|
||||
Species.VICTINI,
|
||||
Species.MELOETTA,
|
||||
Species.KELDEO,
|
||||
Species.GENESECT,
|
||||
Species.DIANCIE,
|
||||
Species.HOOPA,
|
||||
Species.VOLCANION,
|
||||
Species.MAGEARNA,
|
||||
Species.MARSHADOW,
|
||||
Species.ZERAORA,
|
||||
Species.ZARUDE,
|
||||
Species.MELTAN,
|
||||
Species.MELMETAL,
|
||||
Species.PECHARUNT,
|
||||
];
|
||||
|
||||
|
@ -164,7 +151,7 @@ export const DarkDealEncounter: MysteryEncounter =
|
|||
// Starter egg tier, 35/50/10/5 %odds for tiers 6/7/8/9+
|
||||
const roll = randSeedInt(100);
|
||||
const starterTier: number | [number, number] =
|
||||
roll >= 65 ? 6 : roll >= 15 ? 7 : roll >= 5 ? 8 : [9, 10];
|
||||
roll > 65 ? 6 : roll > 15 ? 7 : roll > 5 ? 8 : [9, 10];
|
||||
const bossSpecies = getPokemonSpecies(getRandomSpeciesByStarterTier(starterTier, excludedBosses, bossTypes));
|
||||
const pokemonConfig: EnemyPokemonConfig = {
|
||||
species: bossSpecies,
|
||||
|
|
|
@ -4,9 +4,9 @@ import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifi
|
|||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { Species } from "#enums/species";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { CombinationPokemonRequirement, HeldItemRequirement, MoneyRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { CombinationPokemonRequirement, HeldItemRequirement, MoneyRequirement } from "../mystery-encounter-requirements";
|
||||
import { getEncounterText, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
|
@ -33,8 +33,6 @@ const OPTION_3_DISALLOWED_MODIFIERS = [
|
|||
"PokemonBaseStatTotalModifier"
|
||||
];
|
||||
|
||||
const DELIBIRDY_MONEY_PRICE_MULTIPLIER = 1.5;
|
||||
|
||||
/**
|
||||
* Delibird-y encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3804 | GitHub Issue #3804}
|
||||
|
@ -44,7 +42,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DELIBIRDY)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new MoneyRequirement(0, DELIBIRDY_MONEY_PRICE_MULTIPLIER)) // Must have enough money for it to spawn at the very least
|
||||
.withSceneRequirement(new MoneyRequirement(0, 2)) // Must have enough money for it to spawn at the very least
|
||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement( // Must also have either option 2 or 3 available to spawn
|
||||
new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS),
|
||||
new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true)
|
||||
|
@ -95,18 +93,12 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||
.withOnInit((scene: BattleScene) => {
|
||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||
encounter.setDialogueToken("delibirdName", getPokemonSpecies(Species.DELIBIRD).getName());
|
||||
|
||||
scene.loadBgm("mystery_encounter_delibirdy", "mystery_encounter_delibirdy.mp3");
|
||||
return true;
|
||||
})
|
||||
.withOnVisualsStart((scene: BattleScene) => {
|
||||
scene.fadeAndSwitchBgm("mystery_encounter_delibirdy");
|
||||
return true;
|
||||
})
|
||||
.withOption(
|
||||
MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||
.withSceneMoneyRequirement(0, DELIBIRDY_MONEY_PRICE_MULTIPLIER) // Must have money to spawn
|
||||
.withSceneMoneyRequirement(0, 2) // Must have money to spawn
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}.option.1.label`,
|
||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Species } from "#enums/species";
|
|||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, {
|
||||
MysteryEncounterBuilder,
|
||||
} from "#app/data/mystery-encounters/mystery-encounter";
|
||||
} from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import { modifierTypes } from "#app/modifier/modifier-type";
|
|||
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { Stat } from "#enums/stat";
|
||||
|
|
|
@ -3,8 +3,8 @@ import { EnemyPartyConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounte
|
|||
import { AttackTypeBoosterModifierType, modifierTypes, } from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { TypeRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { TypeRequirement } from "../mystery-encounter-requirements";
|
||||
import { Species } from "#enums/species";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import { Gender } from "#app/data/gender";
|
||||
|
|
|
@ -17,12 +17,12 @@ import {
|
|||
} from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MoveRequirement } from "../mystery-encounter-requirements";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { TrainerSlot } from "#app/data/trainer-config";
|
||||
import { getEncounterPokemonLevelForWave, getSpriteKeysFromPokemon, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
|
@ -54,11 +54,12 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||
|
||||
// Calculate boss mon
|
||||
const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||
const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0);
|
||||
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true);
|
||||
const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true);
|
||||
encounter.setDialogueToken("enemyPokemon", bossPokemon.getNameToRender());
|
||||
const config: EnemyPartyConfig = {
|
||||
levelAdditiveMultiplier: 1,
|
||||
pokemonConfigs: [{
|
||||
level: level,
|
||||
species: bossSpecies,
|
||||
|
@ -68,7 +69,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||
queueEncounterMessage(pokemon.scene, `${namespace}.option.1.stat_boost`);
|
||||
// Randomly boost 1 stat 2 stages
|
||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [randSeedInt(4, 1)], 2));
|
||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [randSeedInt(5)], 2));
|
||||
}
|
||||
}],
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterRewards, transitionMysteryEncounterIntroVisuals, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { TrainerSlot } from "#app/data/trainer-config";
|
||||
import Pokemon, { FieldPosition, PlayerPokemon } from "#app/field/pokemon";
|
||||
|
@ -84,7 +84,12 @@ export const FunAndGamesEncounter: MysteryEncounter =
|
|||
return true;
|
||||
})
|
||||
.withOnVisualsStart((scene: BattleScene) => {
|
||||
scene.fadeAndSwitchBgm("mystery_encounter_fun_and_games");
|
||||
// Change the bgm
|
||||
scene.fadeOutBgm(2000, false);
|
||||
scene.time.delayedCall(2000, () => {
|
||||
scene.playBgm("mystery_encounter_fun_and_games");
|
||||
});
|
||||
|
||||
return true;
|
||||
})
|
||||
.withOption(MysteryEncounterOptionBuilder
|
||||
|
@ -170,9 +175,7 @@ async function summonPlayerPokemon(scene: BattleScene) {
|
|||
const party = scene.getParty();
|
||||
const chosenIndex = party.indexOf(playerPokemon);
|
||||
if (chosenIndex !== 0) {
|
||||
const leadPokemon = party[0];
|
||||
party[0] = playerPokemon;
|
||||
party[chosenIndex] = leadPokemon;
|
||||
[party[chosenIndex], party[0]] = [party[chosenIndex], party[chosenIndex]];
|
||||
}
|
||||
|
||||
// Do trainer summon animation
|
||||
|
|
|
@ -4,7 +4,7 @@ import { ModifierTier } from "#app/modifier/modifier-tier";
|
|||
import { getPlayerModifierTypeOptions, ModifierPoolType, ModifierTypeOption, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { Species } from "#enums/species";
|
||||
import PokemonSpecies, { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
|
@ -23,7 +23,6 @@ import { getPokeballAtlasKey, getPokeballTintColor, PokeballType } from "#app/da
|
|||
import { getEncounterText, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { trainerNamePools } from "#app/data/trainer-names";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
import { addPokemonDataToDexAndValidateAchievements } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:globalTradeSystem";
|
||||
|
@ -119,13 +118,17 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||
return true;
|
||||
})
|
||||
.withOnVisualsStart((scene: BattleScene) => {
|
||||
scene.fadeAndSwitchBgm(scene.currentBattle.mysteryEncounter!.misc.bgmKey);
|
||||
// Change the bgm
|
||||
scene.fadeOutBgm(1500, false);
|
||||
scene.time.delayedCall(1500, () => {
|
||||
scene.playBgm(scene.currentBattle.mysteryEncounter!.misc.bgmKey);
|
||||
});
|
||||
|
||||
return true;
|
||||
})
|
||||
.withOption(
|
||||
MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||
.withHasDexProgress(true)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}.option.1.label`,
|
||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||
|
@ -197,7 +200,6 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||
await doPokemonTradeSequence(scene, tradedPokemon, newPlayerPokemon);
|
||||
await showEncounterText(scene, `${namespace}.trade_received`, null, 0, true, 4000);
|
||||
scene.playBgm(encounter.misc.bgmKey);
|
||||
await addPokemonDataToDexAndValidateAchievements(scene, newPlayerPokemon);
|
||||
await hideTradeBackground(scene);
|
||||
tradedPokemon.destroy();
|
||||
|
||||
|
@ -208,7 +210,6 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||
.withOption(
|
||||
MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||
.withHasDexProgress(true)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}.option.2.label`,
|
||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||
|
@ -217,7 +218,8 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||
// Randomly generate a Wonder Trade pokemon
|
||||
const randomTradeOption = generateTradeOption(scene.getParty().map(p => p.species));
|
||||
// const randomTradeOption = generateTradeOption(scene.getParty().map(p => p.species));
|
||||
const randomTradeOption = getPokemonSpecies(Species.BURMY);
|
||||
const tradePokemon = new EnemyPokemon(scene, randomTradeOption, pokemon.level, TrainerSlot.NONE, false);
|
||||
// Extra shiny roll at 1/128 odds (boosted by events and charms)
|
||||
if (!tradePokemon.shiny) {
|
||||
|
@ -278,8 +280,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(encounter.misc.bgmKey);
|
||||
await addPokemonDataToDexAndValidateAchievements(scene, newPlayerPokemon);
|
||||
scene.playBgm(scene.currentBattle.mysteryEncounter!.misc.bgmKey);
|
||||
await hideTradeBackground(scene);
|
||||
tradedPokemon.destroy();
|
||||
|
||||
|
@ -300,7 +301,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||
// Get Pokemon held items and filter for valid ones
|
||||
const validItems = pokemon.getHeldItems().filter((it) => {
|
||||
return it.isTransferable;
|
||||
return it.isTransferrable;
|
||||
});
|
||||
|
||||
return validItems.map((modifier: PokemonHeldItemModifier) => {
|
||||
|
@ -321,7 +322,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
// If pokemon has items to trade
|
||||
const meetsReqs = pokemon.getHeldItems().filter((it) => {
|
||||
return it.isTransferable;
|
||||
return it.isTransferrable;
|
||||
}).length > 0;
|
||||
if (!meetsReqs) {
|
||||
return getEncounterText(scene, `${namespace}.option.3.invalid_selection`) ?? null;
|
||||
|
|
|
@ -3,8 +3,8 @@ import { Moves } from "#app/enums/moves";
|
|||
import { Species } from "#app/enums/species";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { leaveEncounterWithoutBattle, setEncounterExp } from "../utils/encounter-phase-utils";
|
||||
import { applyDamageToPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
|
|
|
@ -15,7 +15,7 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
|||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import * as Utils from "#app/utils";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
|
@ -75,7 +75,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||
const hardSpriteKey = hardConfig.getSpriteKey(female, hardConfig.doubleOnly);
|
||||
encounter.enemyPartyConfigs.push({
|
||||
trainerConfig: hardConfig,
|
||||
levelAdditiveModifier: 1,
|
||||
levelAdditiveMultiplier: 1,
|
||||
female: female,
|
||||
});
|
||||
|
||||
|
@ -98,7 +98,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||
const brutalSpriteKey = brutalConfig.getSpriteKey(female, brutalConfig.doubleOnly);
|
||||
encounter.enemyPartyConfigs.push({
|
||||
trainerConfig: brutalConfig,
|
||||
levelAdditiveModifier: 1.5,
|
||||
levelAdditiveMultiplier: 1.5,
|
||||
female: female,
|
||||
});
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ import { ModifierTier } from "#app/modifier/modifier-tier";
|
|||
import { randSeedInt } from "#app/utils";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
|
@ -68,7 +68,7 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||
|
||||
// Calculate boss mon
|
||||
const config: EnemyPartyConfig = {
|
||||
levelAdditiveModifier: 0.5,
|
||||
levelAdditiveMultiplier: 0.5,
|
||||
disableSwitch: true,
|
||||
pokemonConfigs: [
|
||||
{
|
||||
|
@ -179,7 +179,6 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||
encounter.setDialogueToken("pokeName", highestLevelPokemon.getNameToRender());
|
||||
await showEncounterText(scene, `${namespace}.option.1.bad`);
|
||||
transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
|
||||
setEncounterRewards(scene, { fillRemaining: true });
|
||||
await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/myst
|
|||
import { leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals, updatePlayerMoney } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MoveRequirement } from "../mystery-encounter-requirements";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { Stat } from "#enums/stat";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { initSubsequentOptionSelect, leaveEncounterWithoutBattle, transitionMysteryEncounterIntroVisuals, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import MysteryEncounterOption, { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { TrainerSlot } from "#app/data/trainer-config";
|
||||
import { HiddenAbilityRateBoosterModifier, IvScannerModifier } from "#app/modifier/modifier";
|
||||
|
@ -25,7 +25,7 @@ const namespace = "mysteryEncounter:safariZone";
|
|||
|
||||
const TRAINER_THROW_ANIMATION_TIMES = [512, 184, 768];
|
||||
|
||||
const SAFARI_MONEY_MULTIPLIER = 2;
|
||||
const SAFARI_MONEY_MULTIPLIER = 2.75;
|
||||
|
||||
/**
|
||||
* Safari Zone encounter.
|
||||
|
|
|
@ -5,9 +5,9 @@ import { randSeedInt } from "#app/utils";
|
|||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { Species } from "#enums/species";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { MoneyRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { MoneyRequirement } from "../mystery-encounter-requirements";
|
||||
import { getEncounterText, queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { applyDamageToPokemon, applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
|
@ -19,9 +19,6 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:shadyVitaminDealer";
|
||||
|
||||
const VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER = 1.5;
|
||||
const VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER = 3.5;
|
||||
|
||||
/**
|
||||
* Shady Vitamin Dealer encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3798 | GitHub Issue #3798}
|
||||
|
@ -31,7 +28,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SHADY_VITAMIN_DEALER)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new MoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER)) // Must have the money for at least the cheap deal
|
||||
.withSceneRequirement(new MoneyRequirement(0, 1.5)) // Must have the money for at least the cheap deal
|
||||
.withPrimaryPokemonHealthRatioRequirement([0.5, 1]) // At least 1 Pokemon must have above half HP
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
|
@ -67,7 +64,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||
.withOption(
|
||||
MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||
.withSceneMoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER)
|
||||
.withSceneMoneyRequirement(0, 1.5)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}.option.1.label`,
|
||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||
|
@ -118,7 +115,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||
await applyModifierTypeToPlayerPokemon(scene, chosenPokemon, modType);
|
||||
}
|
||||
|
||||
leaveEncounterWithoutBattle(scene, true);
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
})
|
||||
.withPostOptionPhase(async (scene: BattleScene) => {
|
||||
// Damage and status applied after dealer leaves (to make thematic sense)
|
||||
|
@ -145,7 +142,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||
.withOption(
|
||||
MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||
.withSceneMoneyRequirement(0, VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER)
|
||||
.withSceneMoneyRequirement(0, 3.5)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}.option.2.label`,
|
||||
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||
|
@ -196,7 +193,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||
await applyModifierTypeToPlayerPokemon(scene, chosenPokemon, modType);
|
||||
}
|
||||
|
||||
leaveEncounterWithoutBattle(scene, true);
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
})
|
||||
.withPostOptionPhase(async (scene: BattleScene) => {
|
||||
// Status applied after dealer leaves (to make thematic sense)
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { Species } from "#enums/species";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { StatusEffect } from "#app/data/status-effect";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import { EnemyPartyConfig, EnemyPokemonConfig, generateModifierType, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, loadCustomMovesForEncounter, setEncounterExp, setEncounterRewards, } from "../utils/encounter-phase-utils";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { MoveRequirement } from "../mystery-encounter-requirements";
|
||||
import { EnemyPartyConfig, EnemyPokemonConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, } from "../utils/encounter-phase-utils";
|
||||
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { AiType, PokemonMove } from "#app/field/pokemon";
|
||||
import { PokemonMove } from "#app/field/pokemon";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { PartyHealPhase } from "#app/phases/party-heal-phase";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
import { BerryType } from "#enums/berry-type";
|
||||
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
||||
|
||||
/** i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:slumberingSnorlax";
|
||||
|
@ -40,7 +38,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||
fileRoot: "pokemon",
|
||||
hasShadow: true,
|
||||
tint: 0.25,
|
||||
scale: 1.25,
|
||||
scale: 1.5,
|
||||
repeat: true,
|
||||
y: 5,
|
||||
},
|
||||
|
@ -60,22 +58,10 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||
species: bossSpecies,
|
||||
isBoss: true,
|
||||
status: [StatusEffect.SLEEP, 5], // Extra turns on timer for Snorlax's start of fight moves
|
||||
moveSet: [Moves.REST, Moves.SLEEP_TALK, Moves.CRUNCH, Moves.GIGA_IMPACT],
|
||||
modifierConfigs: [
|
||||
{
|
||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2
|
||||
},
|
||||
{
|
||||
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType,
|
||||
stackCount: 2
|
||||
},
|
||||
],
|
||||
mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ spriteScale: 1.25 }),
|
||||
aiType: AiType.SMART // Required to ensure Snorlax uses Sleep Talk while it is asleep
|
||||
moveSet: [Moves.REST, Moves.SLEEP_TALK, Moves.CRUNCH, Moves.GIGA_IMPACT]
|
||||
};
|
||||
const config: EnemyPartyConfig = {
|
||||
levelAdditiveModifier: 0.5,
|
||||
levelAdditiveMultiplier: 0.5,
|
||||
pokemonConfigs: [pokemonConfig],
|
||||
};
|
||||
encounter.enemyPartyConfigs = [config];
|
||||
|
|
|
@ -2,8 +2,8 @@ import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig
|
|||
import { randSeedInt } from "#app/utils";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MoneyRequirement, WaveModulusRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MoneyRequirement, WaveModulusRequirement } from "../mystery-encounter-requirements";
|
||||
import Pokemon, { EnemyPokemon } from "#app/field/pokemon";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
|
@ -20,13 +20,12 @@ import { getPokemonNameWithAffix } from "#app/messages";
|
|||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
import { getEncounterPokemonLevelForWave, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:teleportingHijinks";
|
||||
|
||||
const MONEY_COST_MULTIPLIER = 1.75;
|
||||
const BIOME_CANDIDATES = [Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND, Biome.WASTELAND, Biome.DOJO];
|
||||
const MONEY_COST_MULTIPLIER = 2.5;
|
||||
const BIOME_CANDIDATES = [Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND];
|
||||
const MACHINE_INTERFACING_TYPES = [Type.ELECTRIC, Type.STEEL];
|
||||
|
||||
/**
|
||||
|
@ -131,7 +130,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
|
|||
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||
|
||||
// Init enemy
|
||||
const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||
const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0);
|
||||
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true);
|
||||
const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true);
|
||||
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
|
||||
|
@ -167,7 +166,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
|
|||
await showEncounterText(scene, `${namespace}.attacked`);
|
||||
|
||||
// Init enemy
|
||||
const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||
const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0);
|
||||
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true);
|
||||
const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true);
|
||||
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
|
||||
|
|
|
@ -2,8 +2,8 @@ import { leaveEncounterWithoutBattle, transitionMysteryEncounterIntroVisuals, up
|
|||
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MoneyRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MoneyRequirement } from "../mystery-encounter-requirements";
|
||||
import { catchPokemon, getRandomSpeciesByStarterTier, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
|
||||
import { Species } from "#enums/species";
|
||||
|
@ -15,15 +15,11 @@ import PokemonData from "#app/system/pokemon-data";
|
|||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:pokemonSalesman";
|
||||
|
||||
const MAX_POKEMON_PRICE_MULTIPLIER = 4;
|
||||
|
||||
/** Odds of shiny magikarp will be 1/value */
|
||||
const SHINY_MAGIKARP_WEIGHT = 100;
|
||||
const MAX_POKEMON_PRICE_MULTIPLIER = 6;
|
||||
|
||||
/**
|
||||
* Pokemon Salesman encounter.
|
||||
|
@ -62,12 +58,12 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||
const tries = 0;
|
||||
|
||||
// Reroll any species that don't have HAs
|
||||
while ((isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) && tries < 5) {
|
||||
while (isNullOrUndefined(species.abilityHidden) && tries < 5) {
|
||||
species = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5]));
|
||||
}
|
||||
|
||||
let pokemon: PlayerPokemon;
|
||||
if (randSeedInt(SHINY_MAGIKARP_WEIGHT) === 0 || isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) {
|
||||
if (isNullOrUndefined(species.abilityHidden) || randSeedInt(100) === 0) {
|
||||
// If no HA mon found or you roll 1%, give shiny Magikarp
|
||||
species = getPokemonSpecies(Species.MAGIKARP);
|
||||
const hiddenIndex = species.ability2 ? 2 : 1;
|
||||
|
|
|
@ -2,7 +2,7 @@ import { EnemyPartyConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounte
|
|||
import { modifierTypes, PokemonHeldItemModifierType, } from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import { Species } from "#enums/species";
|
||||
import { Nature } from "#app/data/nature";
|
||||
|
@ -36,7 +36,6 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withScenePartySizeRequirement(3, 6) // Must have at least 3 pokemon in party
|
||||
.withMaxAllowedEncounters(1)
|
||||
.withHideWildIntroMessage(true)
|
||||
.withAutoHideIntroVisuals(false)
|
||||
.withIntroSpriteConfigs([
|
||||
|
@ -71,7 +70,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||
|
||||
// Calculate boss mon
|
||||
const config: EnemyPartyConfig = {
|
||||
levelAdditiveModifier: 1,
|
||||
levelAdditiveMultiplier: 1,
|
||||
disableSwitch: true,
|
||||
pokemonConfigs: [
|
||||
{
|
||||
|
@ -160,11 +159,6 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||
encounter.setDialogueToken("increaseValue", BST_INCREASE_VALUE.toString());
|
||||
await showEncounterText(scene, `${namespace}.option.1.selected_2`, null, undefined, true);
|
||||
|
||||
encounter.dialogue.outro = [
|
||||
{
|
||||
text: `${namespace}.outro`,
|
||||
}
|
||||
];
|
||||
setEncounterRewards(scene, { fillRemaining: true });
|
||||
leaveEncounterWithoutBattle(scene, true);
|
||||
return true;
|
||||
|
@ -198,7 +192,6 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||
ignorePp: true
|
||||
});
|
||||
|
||||
encounter.dialogue.outro = [];
|
||||
transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
|
||||
await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { EnemyPartyConfig, generateModifierType, generateModifierTypeOption, ini
|
|||
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { Species } from "#enums/species";
|
||||
|
@ -146,7 +146,7 @@ async function spawnNextTrainerOrEndEncounter(scene: BattleScene) {
|
|||
|
||||
// Give 10x Voucher
|
||||
const newModifier = modifierTypes.VOUCHER_PREMIUM().newModifier();
|
||||
await scene.addModifier(newModifier);
|
||||
scene.addModifier(newModifier);
|
||||
scene.playSound("item_fanfare");
|
||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }));
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattl
|
|||
import { getNatureName, Nature } from "#app/data/nature";
|
||||
import { speciesStarters } from "#app/data/pokemon-species";
|
||||
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||
import { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||
import { AbilityAttr } from "#app/system/game-data";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||
|
@ -11,8 +11,8 @@ import { isNullOrUndefined, randSeedShuffle } from "#app/utils";
|
|||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { getEncounterText, queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
|
@ -34,7 +34,6 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withScenePartySizeRequirement(2, 6, true) // Must have at least 2 unfainted pokemon in party
|
||||
.withFleeAllowed(false)
|
||||
.withHideWildIntroMessage(true)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
|
@ -98,7 +97,12 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||
5
|
||||
);
|
||||
const modifiers = new ModifiersHolder();
|
||||
const config = getEnemyConfig(scene, playerPokemon, segments, modifiers);
|
||||
const config = getEnemyConfig(
|
||||
scene,
|
||||
playerPokemon,
|
||||
segments,
|
||||
modifiers
|
||||
);
|
||||
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
||||
|
||||
const onBeforeRewardsPhase = () => {
|
||||
|
@ -159,7 +163,6 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||
// Add pokemon and mods back
|
||||
scene.getParty().push(playerPokemon);
|
||||
for (const mod of modifiers.value) {
|
||||
mod.pokemonId = playerPokemon.id;
|
||||
scene.addModifier(mod, true, false, false, true);
|
||||
}
|
||||
scene.updateModifiers(true);
|
||||
|
@ -227,9 +230,17 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||
|
||||
// Spawn medium training session with chosen pokemon
|
||||
// Every 40 waves, add +1 boss segment, capping at 6
|
||||
const segments = Math.min(2 + Math.floor(scene.currentBattle.waveIndex / 40), 6);
|
||||
const segments = Math.min(
|
||||
2 + Math.floor(scene.currentBattle.waveIndex / 40),
|
||||
6
|
||||
);
|
||||
const modifiers = new ModifiersHolder();
|
||||
const config = getEnemyConfig(scene, playerPokemon, segments, modifiers);
|
||||
const config = getEnemyConfig(
|
||||
scene,
|
||||
playerPokemon,
|
||||
segments,
|
||||
modifiers
|
||||
);
|
||||
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
||||
|
||||
const onBeforeRewardsPhase = () => {
|
||||
|
@ -366,7 +377,6 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||
// Add pokemon and mods back
|
||||
scene.getParty().push(playerPokemon);
|
||||
for (const mod of modifiers.value) {
|
||||
mod.pokemonId = playerPokemon.id;
|
||||
scene.addModifier(mod, true, false, false, true);
|
||||
}
|
||||
scene.updateModifiers(true);
|
||||
|
@ -400,12 +410,10 @@ function getEnemyConfig(scene: BattleScene, playerPokemon: PlayerPokemon, segmen
|
|||
playerPokemon.resetSummonData();
|
||||
|
||||
// Passes modifiers by reference
|
||||
modifiers.value = playerPokemon.getHeldItems();
|
||||
modifiers.value = playerPokemon.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier));
|
||||
const modifierConfigs = modifiers.value.map((mod) => {
|
||||
return {
|
||||
modifier: mod.clone(),
|
||||
isTransferable: false,
|
||||
stackCount: mod.stackCount
|
||||
modifier: mod
|
||||
};
|
||||
}) as HeldModifierConfig[];
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ import { EnemyPartyConfig, EnemyPokemonConfig, generateModifierType, initBattleW
|
|||
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { Species } from "#enums/species";
|
||||
|
@ -67,7 +67,7 @@ export const TrashToTreasureEncounter: MysteryEncounter =
|
|||
moveSet: [Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH]
|
||||
};
|
||||
const config: EnemyPartyConfig = {
|
||||
levelAdditiveModifier: 1,
|
||||
levelAdditiveMultiplier: 1,
|
||||
pokemonConfigs: [pokemonConfig],
|
||||
disableSwitch: true
|
||||
};
|
||||
|
|
|
@ -5,8 +5,8 @@ import Pokemon, { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
|
|||
import { getPartyLuckValue } from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MoveRequirement, PersistentModifierRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MoveRequirement, PersistentModifierRequirement } from "../mystery-encounter-requirements";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { TrainerSlot } from "#app/data/trainer-config";
|
||||
|
|
|
@ -2,8 +2,8 @@ import { Type } from "#app/data/type";
|
|||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { Species } from "#enums/species";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import { leaveEncounterWithoutBattle, setEncounterRewards, } from "../utils/encounter-phase-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
|
@ -14,7 +14,7 @@ import { HiddenAbilityRateBoosterModifier, PokemonFormChangeItemModifier, Pokemo
|
|||
import { achvs } from "#app/system/achv";
|
||||
import { speciesEggMoves } from "#app/data/egg-moves";
|
||||
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
||||
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||
import i18next from "#app/plugins/i18n";
|
||||
import { doPokemonTransformationSequence, TransformationScreenPosition } from "#app/data/mystery-encounters/utils/encounter-transformation-sequence";
|
||||
|
@ -130,7 +130,12 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||
return true;
|
||||
})
|
||||
.withOnVisualsStart((scene: BattleScene) => {
|
||||
scene.fadeAndSwitchBgm("mystery_encounter_weird_dream");
|
||||
// Change the bgm
|
||||
scene.fadeOutBgm(3000, false);
|
||||
scene.time.delayedCall(3000, () => {
|
||||
scene.playBgm("mystery_encounter_weird_dream");
|
||||
});
|
||||
|
||||
return true;
|
||||
})
|
||||
.withOption(
|
||||
|
@ -335,7 +340,7 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
|
|||
const newStarterUnlocked = await scene.gameData.setPokemonCaught(newPokemon, true, false, false);
|
||||
if (newStarterUnlocked) {
|
||||
atLeastOneNewStarter = true;
|
||||
await showEncounterText(scene, i18next.t("battle:addedAsAStarter", { pokemonName: getPokemonSpecies(speciesRootForm).getName() }));
|
||||
queueEncounterMessage(scene, i18next.t("battle:addedAsAStarter", { pokemonName: getPokemonSpecies(speciesRootForm).getName() }));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Moves } from "#app/enums/moves";
|
|||
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { Type } from "../type";
|
||||
import { EncounterPokemonRequirement, EncounterSceneRequirement, MoneyRequirement, TypeRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import { EncounterPokemonRequirement, EncounterSceneRequirement, MoneyRequirement, TypeRequirement } from "./mystery-encounter-requirements";
|
||||
import { CanLearnMoveRequirement, CanLearnMoveRequirementOptions } from "./requirements/can-learn-move-requirement";
|
||||
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
|
|
|
@ -25,9 +25,6 @@ export interface EncounterStartOfBattleEffect {
|
|||
followUp?: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_MAX_ALLOWED_ENCOUNTERS = 2;
|
||||
const DEFAULT_MAX_ALLOWED_ROGUE_ENCOUNTERS = 1;
|
||||
|
||||
/**
|
||||
* Used by {@linkcode MysteryEncounterBuilder} class to define required/optional properties on the {@linkcode MysteryEncounter} class when building.
|
||||
*
|
||||
|
@ -45,7 +42,6 @@ export interface IMysteryEncounter {
|
|||
autoHideIntroVisuals: boolean;
|
||||
enterIntroVisualsFromRight: boolean;
|
||||
catchAllowed: boolean;
|
||||
fleeAllowed: boolean;
|
||||
continuousEncounter: boolean;
|
||||
maxAllowedEncounters: number;
|
||||
hasBattleAnimationsWithoutTargets: boolean;
|
||||
|
@ -114,11 +110,6 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||
* Default false
|
||||
*/
|
||||
catchAllowed: boolean;
|
||||
/**
|
||||
* If true, allows fleeing from a wild encounter (trainer battle MEs auto-disable fleeing)
|
||||
* Default true
|
||||
*/
|
||||
fleeAllowed: boolean;
|
||||
/**
|
||||
* 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
|
||||
|
@ -255,8 +246,8 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||
this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON;
|
||||
this.dialogue = this.dialogue ?? {};
|
||||
this.spriteConfigs = this.spriteConfigs ? [...this.spriteConfigs] : [];
|
||||
// Default max is 1 for ROGUE encounters, 2 for others
|
||||
this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? DEFAULT_MAX_ALLOWED_ROGUE_ENCOUNTERS : DEFAULT_MAX_ALLOWED_ENCOUNTERS;
|
||||
// Default max is 1 for ROGUE encounters, 3 for others
|
||||
this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? 1 : 3;
|
||||
this.encounterMode = MysteryEncounterMode.DEFAULT;
|
||||
this.requirements = this.requirements ? this.requirements : [];
|
||||
this.hideBattleIntroMessage = this.hideBattleIntroMessage ?? false;
|
||||
|
@ -529,7 +520,6 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
enterIntroVisualsFromRight: boolean = false;
|
||||
continuousEncounter: boolean = false;
|
||||
catchAllowed: boolean = false;
|
||||
fleeAllowed: boolean = true;
|
||||
lockEncounterRewardTiers: boolean = false;
|
||||
startOfBattleEffectsComplete: boolean = false;
|
||||
hasBattleAnimationsWithoutTargets: boolean = false;
|
||||
|
@ -590,8 +580,8 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
* There should be at least 2 options defined and no more than 4.
|
||||
* If complex use {@linkcode MysteryEncounterBuilder.withOption}
|
||||
*
|
||||
* @param dialogue {@linkcode OptionTextDisplay}
|
||||
* @param callback {@linkcode OptionPhaseCallback}
|
||||
* @param dialogue - {@linkcode OptionTextDisplay}
|
||||
* @param callback - {@linkcode OptionPhaseCallback}
|
||||
* @returns
|
||||
*/
|
||||
withSimpleDexProgressOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback): this & Pick<IMysteryEncounter, "options"> {
|
||||
|
@ -742,7 +732,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
*
|
||||
* @param min min wave (or exact size if only min is given)
|
||||
* @param max optional max size. If not given, defaults to min => exact wave
|
||||
* @param excludeFainted if true, only counts unfainted mons
|
||||
* @param excludeFainted - if true, only counts unfainted mons
|
||||
* @returns
|
||||
*/
|
||||
withScenePartySizeRequirement(min: number, max?: number, excludeFainted: boolean = false): this & Required<Pick<IMysteryEncounter, "requirements">> {
|
||||
|
@ -808,7 +798,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
* NOTE: If rewards are dependent on options selected, runtime data, etc.,
|
||||
* It may be better to programmatically set doEncounterRewards elsewhere.
|
||||
* There is a helper function in mystery-encounter utils, setEncounterRewards(), which can be called programmatically to set rewards
|
||||
* @param doEncounterRewards Synchronous callback function to perform during rewards phase of the encounter
|
||||
* @param doEncounterRewards - synchronous callback function to perform during rewards phase of the encounter
|
||||
* @returns
|
||||
*/
|
||||
withRewards(doEncounterRewards: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterRewards">> {
|
||||
|
@ -822,7 +812,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
* NOTE: If rewards are dependent on options selected, runtime data, etc.,
|
||||
* It may be better to programmatically set doEncounterExp elsewhere.
|
||||
* There is a helper function in mystery-encounter utils, setEncounterExp(), which can be called programmatically to set rewards
|
||||
* @param doEncounterExp Synchronous callback function to perform during rewards phase of the encounter
|
||||
* @param doEncounterExp - synchronous callback function to perform during rewards phase of the encounter
|
||||
* @returns
|
||||
*/
|
||||
withExp(doEncounterExp: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterExp">> {
|
||||
|
@ -833,7 +823,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
* Can be used to perform init logic before intro visuals are shown and before the MysteryEncounterPhase begins
|
||||
* Useful for performing things like procedural generation of intro sprites, etc.
|
||||
*
|
||||
* @param onInit Synchronous callback function to perform as soon as the encounter is selected for the next phase
|
||||
* @param onInit - synchronous callback function to perform as soon as the encounter is selected for the next phase
|
||||
* @returns
|
||||
*/
|
||||
withOnInit(onInit: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "onInit">> {
|
||||
|
@ -843,7 +833,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
/**
|
||||
* Can be used to perform some extra logic (usually animations) when the enemy field is finished sliding in
|
||||
*
|
||||
* @param onVisualsStart Synchronous callback function to perform as soon as the enemy field finishes sliding in
|
||||
* @param onVisualsStart - synchronous callback function to perform as soon as the enemy field finishes sliding in
|
||||
* @returns
|
||||
*/
|
||||
withOnVisualsStart(onVisualsStart: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "onVisualsStart">> {
|
||||
|
@ -853,7 +843,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
/**
|
||||
* Can set whether catching is allowed or not on the encounter
|
||||
* This flag can also be programmatically set inside option event functions or elsewhere
|
||||
* @param catchAllowed If `true`, allows enemy pokemon to be caught during the encounter
|
||||
* @param catchAllowed - if true, allows enemy pokemon to be caught during the encounter
|
||||
* @returns
|
||||
*/
|
||||
withCatchAllowed(catchAllowed: boolean): this & Required<Pick<IMysteryEncounter, "catchAllowed">> {
|
||||
|
@ -861,16 +851,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Can set whether fleeing is allowed or not on the encounter
|
||||
* @param fleeAllowed If `false`, prevents fleeing from a wild battle (trainer battle MEs already have flee disabled)
|
||||
* @returns
|
||||
*/
|
||||
withFleeAllowed(fleeAllowed: boolean): this & Required<Pick<IMysteryEncounter, "fleeAllowed">> {
|
||||
return Object.assign(this, { fleeAllowed });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hideBattleIntroMessage If `true`, will not show the trainerAppeared/wildAppeared/bossAppeared message for an encounter
|
||||
* @param hideBattleIntroMessage - if true, will not show the trainerAppeared/wildAppeared/bossAppeared message for an encounter
|
||||
* @returns
|
||||
*/
|
||||
withHideWildIntroMessage(hideBattleIntroMessage: boolean): this & Required<Pick<IMysteryEncounter, "hideBattleIntroMessage">> {
|
||||
|
@ -878,7 +859,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param autoHideIntroVisuals If `false`, will not hide the intro visuals that are displayed at the beginning of encounter
|
||||
* @param autoHideIntroVisuals - if false, will not hide the intro visuals that are displayed at the beginning of encounter
|
||||
* @returns
|
||||
*/
|
||||
withAutoHideIntroVisuals(autoHideIntroVisuals: boolean): this & Required<Pick<IMysteryEncounter, "autoHideIntroVisuals">> {
|
||||
|
@ -886,7 +867,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param enterIntroVisualsFromRight If `true`, will slide in intro visuals from the right side of the screen. If false, slides in from left, as normal
|
||||
* @param enterIntroVisualsFromRight - If true, will slide in intro visuals from the right side of the screen. If false, slides in from left, as normal
|
||||
* Default false
|
||||
* @returns
|
||||
*/
|
||||
|
@ -897,7 +878,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
/**
|
||||
* Add a title for the encounter
|
||||
*
|
||||
* @param title Title of the encounter
|
||||
* @param title - title of the encounter
|
||||
* @returns
|
||||
*/
|
||||
withTitle(title: string): this {
|
||||
|
@ -917,7 +898,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
/**
|
||||
* Add a description of the encounter
|
||||
*
|
||||
* @param description Description of the encounter
|
||||
* @param description - description of the encounter
|
||||
* @returns
|
||||
*/
|
||||
withDescription(description: string): this {
|
||||
|
@ -937,7 +918,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
/**
|
||||
* Add a query for the encounter
|
||||
*
|
||||
* @param query Query to use for the encounter
|
||||
* @param query - query to use for the encounter
|
||||
* @returns
|
||||
*/
|
||||
withQuery(query: string): this {
|
||||
|
@ -957,7 +938,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||
/**
|
||||
* Add outro dialogue/s for the encounter
|
||||
*
|
||||
* @param dialogue Outro dialogue(s)
|
||||
* @param dialogue - outro dialogue/s
|
||||
* @returns
|
||||
*/
|
||||
withOutroDialogue(dialogue: MysteryEncounterDialogue["outro"] = []): this {
|
||||
|
|
|
@ -2,7 +2,7 @@ import BattleScene from "#app/battle-scene";
|
|||
import { Moves } from "#app/enums/moves";
|
||||
import { PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||
import { isNullOrUndefined } from "#app/utils";
|
||||
import { EncounterPokemonRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
import { EncounterPokemonRequirement } from "../mystery-encounter-requirements";
|
||||
|
||||
/**
|
||||
* {@linkcode CanLearnMoveRequirement} options
|
||||
|
|
|
@ -3,7 +3,7 @@ import { biomeLinks, BiomePoolTier } from "#app/data/biomes";
|
|||
import MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import { AVERAGE_ENCOUNTERS_PER_RUN_TARGET, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
|
||||
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import Pokemon, { AiType, FieldPosition, PlayerPokemon, PokemonMove, PokemonSummonData } from "#app/field/pokemon";
|
||||
import Pokemon, { FieldPosition, PlayerPokemon, PokemonMove, PokemonSummonData } from "#app/field/pokemon";
|
||||
import { CustomModifierSettings, ModifierPoolType, ModifierType, ModifierTypeGenerator, ModifierTypeOption, modifierTypes, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type";
|
||||
import { MysteryEncounterBattlePhase, MysteryEncounterBattleStartCleanupPhase, MysteryEncounterPhase, MysteryEncounterRewardsPhase } from "#app/phases/mystery-encounter-phases";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
|
@ -85,24 +85,21 @@ export interface EnemyPokemonConfig {
|
|||
modifierConfigs?: HeldModifierConfig[];
|
||||
tags?: BattlerTagType[];
|
||||
dataSource?: PokemonData;
|
||||
aiType?: AiType;
|
||||
}
|
||||
|
||||
export interface EnemyPartyConfig {
|
||||
/** Formula for enemy level: level += waveIndex / 10 * levelAdditiveModifier */
|
||||
levelAdditiveModifier?: number;
|
||||
/** Formula for enemy: level += waveIndex / 10 * levelAdditive */
|
||||
levelAdditiveMultiplier?: number;
|
||||
doubleBattle?: boolean;
|
||||
/** Generates trainer battle solely off trainer type */
|
||||
trainerType?: TrainerType;
|
||||
/** More customizable option for configuring trainer battle */
|
||||
trainerConfig?: TrainerConfig;
|
||||
pokemonConfigs?: EnemyPokemonConfig[];
|
||||
/** `true` for female trainer, false for male */
|
||||
/** True for female trainer, false for male */
|
||||
female?: boolean;
|
||||
/** `true` will prevent player from switching */
|
||||
/** True will prevent player from switching */
|
||||
disableSwitch?: boolean;
|
||||
/** `true` or leaving undefined will increment dex seen count for the encounter battle, `false` will not */
|
||||
countAsSeen?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -159,10 +156,10 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||
|
||||
// ME levels are modified by an additive value that scales with wave index
|
||||
// Base scaling: Every 10 waves, modifier gets +1 level
|
||||
// This can be amplified or counteracted by setting levelAdditiveModifier in config
|
||||
// levelAdditiveModifier value of 0.5 will halve the modifier scaling, 2 will double it, etc.
|
||||
// This can be amplified or counteracted by setting levelAdditiveMultiplier in config
|
||||
// levelAdditiveMultiplier value of 0.5 will halve the modifier scaling, 2 will double it, etc.
|
||||
// Leaving null/undefined will disable level scaling
|
||||
const mult: number = !isNullOrUndefined(partyConfig.levelAdditiveModifier) ? partyConfig.levelAdditiveModifier! : 0;
|
||||
const mult: number = !isNullOrUndefined(partyConfig.levelAdditiveMultiplier) ? partyConfig.levelAdditiveMultiplier! : 0;
|
||||
const additive = Math.max(Math.round((scene.currentBattle.waveIndex / 10) * mult), 0);
|
||||
battle.enemyLevels = battle.enemyLevels.map(level => level + additive);
|
||||
|
||||
|
@ -213,7 +210,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||
enemyPokemon.resetSummonData();
|
||||
}
|
||||
|
||||
if (!loaded && isNullOrUndefined(partyConfig.countAsSeen) || partyConfig.countAsSeen) {
|
||||
if (!loaded) {
|
||||
scene.gameData.setPokemonSeen(enemyPokemon, true, !!(trainerType || trainerConfig));
|
||||
}
|
||||
|
||||
|
@ -289,11 +286,6 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||
enemyPokemon.summonData.gender = config.gender!;
|
||||
}
|
||||
|
||||
// Set AI type
|
||||
if (!isNullOrUndefined(config.aiType)) {
|
||||
enemyPokemon.aiType = config.aiType!;
|
||||
}
|
||||
|
||||
// Set moves
|
||||
if (config?.moveSet && config.moveSet.length > 0) {
|
||||
const moves = config.moveSet.map(m => new PokemonMove(m));
|
||||
|
@ -710,19 +702,19 @@ export function handleMysteryEncounterVictory(scene: BattleScene, addHealPhase:
|
|||
if (encounter.continuousEncounter || doNotContinue) {
|
||||
return;
|
||||
} else if (encounter.encounterMode === MysteryEncounterMode.NO_BATTLE) {
|
||||
scene.pushPhase(new MysteryEncounterRewardsPhase(scene, addHealPhase));
|
||||
scene.pushPhase(new EggLapsePhase(scene));
|
||||
scene.pushPhase(new MysteryEncounterRewardsPhase(scene, addHealPhase));
|
||||
} else if (!scene.getEnemyParty().find(p => encounter.encounterMode !== MysteryEncounterMode.TRAINER_BATTLE ? p.isOnField() : !p?.isFainted(true))) {
|
||||
scene.pushPhase(new BattleEndPhase(scene));
|
||||
if (encounter.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
|
||||
scene.pushPhase(new TrainerVictoryPhase(scene));
|
||||
}
|
||||
if (scene.gameMode.isEndless || !scene.gameMode.isWaveFinal(scene.currentBattle.waveIndex)) {
|
||||
scene.pushPhase(new MysteryEncounterRewardsPhase(scene, addHealPhase));
|
||||
if (!encounter.doContinueEncounter) {
|
||||
// Only lapse eggs once for multi-battle encounters
|
||||
scene.pushPhase(new EggLapsePhase(scene));
|
||||
}
|
||||
scene.pushPhase(new MysteryEncounterRewardsPhase(scene, addHealPhase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,6 @@ import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifi
|
|||
import { Gender } from "#app/data/gender";
|
||||
import { PermanentStat } from "#enums/stat";
|
||||
import { VictoryPhase } from "#app/phases/victory-phase";
|
||||
import { SummaryUiMode } from "#app/ui/summary-ui-handler";
|
||||
|
||||
/** Will give +1 level every 10 waves */
|
||||
export const STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER = 1;
|
||||
|
||||
/**
|
||||
* Gets the sprite key and file root for a given PokemonSpecies (accounts for gender, shiny, variants, forms, and experimental)
|
||||
|
@ -293,12 +289,10 @@ export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: numb
|
|||
*/
|
||||
export async function applyModifierTypeToPlayerPokemon(scene: BattleScene, pokemon: PlayerPokemon, modType: PokemonHeldItemModifierType, fallbackModifierType?: PokemonHeldItemModifierType) {
|
||||
// Check if the Pokemon has max stacks of that item already
|
||||
const modifier = modType.newModifier(pokemon);
|
||||
const existing = scene.findModifier(m => (
|
||||
m instanceof PokemonHeldItemModifier &&
|
||||
m.type.id === modType.id &&
|
||||
m.pokemonId === pokemon.id &&
|
||||
m.matchType(modifier)
|
||||
m.pokemonId === pokemon.id
|
||||
)) as PokemonHeldItemModifier;
|
||||
|
||||
// At max stacks
|
||||
|
@ -311,6 +305,7 @@ export async function applyModifierTypeToPlayerPokemon(scene: BattleScene, pokem
|
|||
return applyModifierTypeToPlayerPokemon(scene, pokemon, fallbackModifierType);
|
||||
}
|
||||
|
||||
const modifier = modType.newModifier(pokemon);
|
||||
await scene.addModifier(modifier, false, false, false, true);
|
||||
}
|
||||
|
||||
|
@ -332,7 +327,7 @@ export function trainerThrowPokeball(scene: BattleScene, pokemon: EnemyPokemon,
|
|||
const _3m = 3 * pokemon.getMaxHp();
|
||||
const _2h = 2 * pokemon.hp;
|
||||
const catchRate = pokemon.species.catchRate;
|
||||
const pokeballMultiplier = getPokeballCatchMultiplier(pokeballType);
|
||||
const pokeballMultiplier = getPokeballCatchMultiplier(this.pokeballType);
|
||||
const statusMultiplier = pokemon.status ? getStatusEffectCatchRateMultiplier(pokemon.status.effect) : 1;
|
||||
const x = Math.round((((_3m - _2h) * catchRate * pokeballMultiplier) / _3m) * statusMultiplier);
|
||||
ballTwitchRate = Math.round(65536 / Math.sqrt(Math.sqrt(255 / x)));
|
||||
|
@ -506,6 +501,8 @@ function failCatch(scene: BattleScene, pokemon: EnemyPokemon, originalY: number,
|
|||
* @param isObtain
|
||||
*/
|
||||
export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, pokeball: Phaser.GameObjects.Sprite | null, pokeballType: PokeballType, showCatchObtainMessage: boolean = true, isObtain: boolean = false): Promise<void> {
|
||||
scene.unshiftPhase(new VictoryPhase(scene, pokemon.id, true));
|
||||
|
||||
const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm();
|
||||
|
||||
if (speciesForm.abilityHidden && (pokemon.fusionSpecies ? pokemon.fusionAbilityIndex : pokemon.abilityIndex) === speciesForm.getAbilityCount() - 1) {
|
||||
|
@ -531,11 +528,6 @@ export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, po
|
|||
return new Promise(resolve => {
|
||||
const doPokemonCatchMenu = () => {
|
||||
const end = () => {
|
||||
// Ensure the pokemon is in the enemy party in all situations
|
||||
if (!scene.getEnemyParty().some(p => p.id === pokemon.id)) {
|
||||
scene.getEnemyParty().push(pokemon);
|
||||
}
|
||||
scene.unshiftPhase(new VictoryPhase(scene, pokemon.id, true));
|
||||
scene.pokemonInfoContainer.hide();
|
||||
if (pokeball) {
|
||||
removePb(scene, pokeball);
|
||||
|
@ -547,8 +539,8 @@ export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, po
|
|||
scene.field.remove(pokemon, true);
|
||||
}
|
||||
};
|
||||
const addToParty = (slotIndex?: number) => {
|
||||
const newPokemon = pokemon.addToParty(pokeballType, slotIndex);
|
||||
const addToParty = () => {
|
||||
const newPokemon = pokemon.addToParty(pokeballType);
|
||||
const modifiers = scene.findModifiers(m => m instanceof PokemonHeldItemModifier, false);
|
||||
if (scene.getParty().filter(p => p.isShiny()).length === 6) {
|
||||
scene.validateAchv(achvs.SHINY_PARTY);
|
||||
|
@ -567,19 +559,12 @@ export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, po
|
|||
if (scene.getParty().length === 6) {
|
||||
const promptRelease = () => {
|
||||
scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
|
||||
scene.pokemonInfoContainer.makeRoomForConfirmUi(1, true);
|
||||
scene.pokemonInfoContainer.makeRoomForConfirmUi();
|
||||
scene.ui.setMode(Mode.CONFIRM, () => {
|
||||
const newPokemon = scene.addPlayerPokemon(pokemon.species, pokemon.level, pokemon.abilityIndex, pokemon.formIndex, pokemon.gender, pokemon.shiny, pokemon.variant, pokemon.ivs, pokemon.nature, pokemon);
|
||||
scene.ui.setMode(Mode.SUMMARY, newPokemon, 0, SummaryUiMode.DEFAULT, () => {
|
||||
scene.ui.setMode(Mode.MESSAGE).then(() => {
|
||||
promptRelease();
|
||||
});
|
||||
}, false);
|
||||
}, () => {
|
||||
scene.ui.setMode(Mode.PARTY, PartyUiMode.RELEASE, 0, (slotIndex: integer, _option: PartyOption) => {
|
||||
scene.ui.setMode(Mode.PARTY, PartyUiMode.RELEASE, 0, (slotIndex: number, _option: PartyOption) => {
|
||||
scene.ui.setMode(Mode.MESSAGE).then(() => {
|
||||
if (slotIndex < 6) {
|
||||
addToParty(slotIndex);
|
||||
addToParty();
|
||||
} else {
|
||||
promptRelease();
|
||||
}
|
||||
|
@ -590,7 +575,7 @@ export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, po
|
|||
removePokemon();
|
||||
end();
|
||||
});
|
||||
}, "fullParty");
|
||||
});
|
||||
});
|
||||
};
|
||||
promptRelease();
|
||||
|
@ -726,50 +711,13 @@ export function getGoldenBugNetSpecies(): PokemonSpecies {
|
|||
const roll = randSeedInt(totalWeight);
|
||||
|
||||
let w = 0;
|
||||
for (const speciesWeightPair of GOLDEN_BUG_NET_SPECIES_POOL) {
|
||||
w += speciesWeightPair[1];
|
||||
for (const species of GOLDEN_BUG_NET_SPECIES_POOL) {
|
||||
w += species[1];
|
||||
if (roll < w) {
|
||||
return getPokemonSpecies(speciesWeightPair[0]);
|
||||
return getPokemonSpecies(species);
|
||||
}
|
||||
}
|
||||
|
||||
// Defaults to Scyther
|
||||
return getPokemonSpecies(Species.SCYTHER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Pokemon level for a given wave, with an option to increase/decrease by a scaling modifier
|
||||
* @param scene
|
||||
* @param levelAdditiveModifier Default 0. will add +(1 level / 10 waves * levelAdditiveModifier) to the level calculation
|
||||
*/
|
||||
export function getEncounterPokemonLevelForWave(scene: BattleScene, levelAdditiveModifier: number = 0) {
|
||||
const currentBattle = scene.currentBattle;
|
||||
// Default to use the first generated level from enemyLevels, or generate a new one if it DNE
|
||||
const baseLevel = currentBattle.enemyLevels && currentBattle.enemyLevels?.length > 0 ? currentBattle.enemyLevels[0] : currentBattle.getLevelForWave();
|
||||
|
||||
// Add a level scaling modifier that is (+1 level per 10 waves) * levelAdditiveModifier
|
||||
return baseLevel + Math.max(Math.round((currentBattle.waveIndex / 10) * levelAdditiveModifier), 0);
|
||||
}
|
||||
|
||||
export async function addPokemonDataToDexAndValidateAchievements(scene: BattleScene, pokemon: PlayerPokemon) {
|
||||
const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm();
|
||||
|
||||
if (speciesForm.abilityHidden && (pokemon.fusionSpecies ? pokemon.fusionAbilityIndex : pokemon.abilityIndex) === speciesForm.getAbilityCount() - 1) {
|
||||
scene.validateAchv(achvs.HIDDEN_ABILITY);
|
||||
}
|
||||
|
||||
if (pokemon.species.subLegendary) {
|
||||
scene.validateAchv(achvs.CATCH_SUB_LEGENDARY);
|
||||
}
|
||||
|
||||
if (pokemon.species.legendary) {
|
||||
scene.validateAchv(achvs.CATCH_LEGENDARY);
|
||||
}
|
||||
|
||||
if (pokemon.species.mythical) {
|
||||
scene.validateAchv(achvs.CATCH_MYTHICAL);
|
||||
}
|
||||
|
||||
scene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
|
||||
return scene.gameData.setPokemonCaught(pokemon, true, false, false);
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ export function doPokemonTransformationSequence(scene: BattleScene, previousPoke
|
|||
scene.time.delayedCall(1000, () => {
|
||||
pokemonEvoTintSprite.setScale(0.25);
|
||||
pokemonEvoTintSprite.setVisible(true);
|
||||
doCycle(scene, 1.5, 6, pokemonTintSprite, pokemonEvoTintSprite).then(() => {
|
||||
doCycle(scene, 2, 6, pokemonTintSprite, pokemonEvoTintSprite).then(() => {
|
||||
pokemonEvoSprite.setVisible(true);
|
||||
doCircleInward(scene, transformationBaseBg, transformationContainer, xOffset, yOffset);
|
||||
|
||||
|
@ -115,7 +115,7 @@ export function doPokemonTransformationSequence(scene: BattleScene, previousPoke
|
|||
delay: 150,
|
||||
easing: "Sine.easeIn",
|
||||
onComplete: () => {
|
||||
scene.time.delayedCall(3000, () => {
|
||||
scene.time.delayedCall(2500, () => {
|
||||
resolve();
|
||||
scene.tweens.add({
|
||||
targets: pokemonEvoSprite,
|
||||
|
|
|
@ -3,7 +3,7 @@ import BattleScene, { AnySound } from "../battle-scene";
|
|||
import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
|
||||
import { variantData } from "#app/data/variant";
|
||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
|
||||
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget } from "../data/move";
|
||||
import Move, { HighCritAttr, DealsDoubleDamageToTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget } from "../data/move";
|
||||
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
|
||||
import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||
import * as Utils from "../utils";
|
||||
|
@ -1513,7 +1513,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
|
||||
const immuneTags = this.findTags(tag => tag instanceof TypeImmuneTag && tag.immuneType === moveType);
|
||||
for (const tag of immuneTags) {
|
||||
if (move && !move.getAttrs(HitsTagAttr).some(attr => attr.tagType === tag.tagType)) {
|
||||
if (move && !move.getAttrs(DealsDoubleDamageToTagAttr).some(attr => attr.tagType === tag.tagType)) {
|
||||
typeMultiplier.value = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -2515,13 +2515,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
this.scene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, move.category, this.scene.currentBattle.double, screenMultiplier);
|
||||
|
||||
/**
|
||||
* For each {@linkcode HitsTagAttr} the move has, doubles the damage of the move if:
|
||||
* For each {@linkcode DealsDoubleDamageToTagAttr} the move has, doubles the damage of the move if:
|
||||
* The target has a {@linkcode BattlerTagType} that this move interacts with
|
||||
* AND
|
||||
* The move doubles damage when used against that tag
|
||||
*/
|
||||
const hitsTagMultiplier = new Utils.NumberHolder(1);
|
||||
move.getAttrs(HitsTagAttr).filter(hta => hta.doubleDamage).forEach(hta => {
|
||||
move.getAttrs(DealsDoubleDamageToTagAttr).filter(hta => hta.doubleDamage).forEach(hta => {
|
||||
if (this.getTag(hta.tagType)) {
|
||||
hitsTagMultiplier.value *= 2;
|
||||
}
|
||||
|
|
|
@ -3121,11 +3121,11 @@
|
|||
},
|
||||
"behemothBlade": {
|
||||
"name": "Gigantenhieb",
|
||||
"effect": "Der Anwender wird zu einem riesigen Schwert und greift das Ziel an."
|
||||
"effect": "Der Anwender wird zu einem riesigen Schwert und greift das Ziel an. Dynamaximierte Ziele erleiden doppelten Schaden."
|
||||
},
|
||||
"behemothBash": {
|
||||
"name": "Gigantenstoß",
|
||||
"effect": "Der Anwender wird zu einem riesigen Schild und greift das Ziel an."
|
||||
"effect": "Der Anwender wird zu einem riesigen Schild und greift das Ziel an. Dynamaximierte Ziele erleiden doppelten Schaden."
|
||||
},
|
||||
"auraWheel": {
|
||||
"name": "Aura-Rad",
|
||||
|
|
|
@ -151,6 +151,5 @@
|
|||
"mystery_encounter_weird_dream": "PMD EoS Temporal Spire",
|
||||
"mystery_encounter_fun_and_games": "PMD EoS Guildmaster Wigglytuff",
|
||||
"mystery_encounter_gen_5_gts": "BW GTS",
|
||||
"mystery_encounter_gen_6_gts": "XY GTS",
|
||||
"mystery_encounter_delibirdy": "Firel - DeliDelivery!"
|
||||
"mystery_encounter_gen_6_gts": "XY GTS"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"intro": "You're stopped by a rich looking boy.",
|
||||
"speaker": "Rich Boy",
|
||||
"intro_dialogue": "Good day to you.$I can't help but notice that your\n{{strongestPokemon}} looks positively divine!$I've always wanted to have a Pokémon like that!$I'd pay you handsomely,\nand also give you this old bauble!",
|
||||
"intro_dialogue": "Good day to you.$I can't help but notice that your\n{{strongestPokemon}} looks positively divine!$I've always wanted to have a pet like that!$I'd pay you handsomely,\nand also give you this old bauble!",
|
||||
"title": "An Offer You Can't Refuse",
|
||||
"description": "You're being offered a @[TOOLTIP_TITLE]{Shiny Charm} and {{price, money}} for your {{strongestPokemon}}!\n\nIt's an extremely good deal, but can you really bear to part with such a strong team member?",
|
||||
"query": "What will you do?",
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
"disabled_tooltip": "You need at least 1 Bug Type Pokémon on your team to select this.",
|
||||
"selected": "You show the trainer all your Bug Type Pokémon...",
|
||||
"selected_0_to_1": "Huh? You only have {{numBugTypes}}...$Guess I'm wasting my breath on someone like you...",
|
||||
"selected_2_to_3": "Hey, you've got {{numBugTypes}}!\nNot bad.$Here, this might help you on your journey to catch more!",
|
||||
"selected_4_to_5": "What? You have {{numBugTypes}}?\nNice!$You're not quite at my level, but I can see shades of myself in you!\n$Take this, my young apprentice!",
|
||||
"selected_6": "Whoa! {{numBugTypes}}!\n$You must love Bug Types almost as much as I do!$Here, take this as a token of our camaraderie!"
|
||||
"selected_2_to_3": "Hey, you've got {{numBugTypes}} Bug Types!\nNot bad.$Here, this might help you on your journey to catch more!",
|
||||
"selected_4_to_5": "What? You have {{numBugTypes}} Bug Types?\nNice!$You're not quite at my level, but I can see shades of myself in you!\n$Take this, my young apprentice!",
|
||||
"selected_6": "Whoa! {{numBugTypes}} Bug Types!\n$You must love Bug Types almost as much as I do!$Here, take this as a token of our camaraderie!"
|
||||
},
|
||||
"3": {
|
||||
"label": "Gift a Bug Item",
|
||||
|
@ -34,7 +34,5 @@
|
|||
"battle_won": "Your knowledge and skill were perfect at exploiting our weaknesses!$In exchange for the valuable lesson,\nallow me to teach one of your Pokémon a Bug Type Move!",
|
||||
"teach_move_prompt": "Select a move to teach a Pokémon.",
|
||||
"confirm_no_teach": "You sure you don't want to learn one of these great moves?",
|
||||
"outro": "I see great Bug Pokémon in your future!\nMay our paths cross again!$Bug out!",
|
||||
"numBugTypes_one": "{{count}} Bug Type",
|
||||
"numBugTypes_other": "{{count}} Bug Types"
|
||||
"outro": "I see great Bug Pokémon in your future!\nMay our paths cross again!$Bug out!"
|
||||
}
|
|
@ -3121,11 +3121,11 @@
|
|||
},
|
||||
"behemothBlade": {
|
||||
"name": "Gladius Maximus",
|
||||
"effect": "Le lanceur se transforme en une immense épée et pourfend sa cible."
|
||||
"effect": "Le lanceur se transforme en une immense épée et pourfend sa cible. Cette capacité inflige le double de dégâts aux Pokémon Dynamax."
|
||||
},
|
||||
"behemothBash": {
|
||||
"name": "Aegis Maxima",
|
||||
"effect": "Le lanceur se transforme en un immense bouclier et charge sa cible."
|
||||
"effect": "Le lanceur se transforme en un immense bouclier et charge sa cible. Cette capacité inflige le double de dégâts aux Pokémon Dynamax."
|
||||
},
|
||||
"auraWheel": {
|
||||
"name": "Roue Libre",
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"ALL": "Tout",
|
||||
"PASS_BATON": "Relais",
|
||||
"UNPAUSE_EVOLUTION": "Réactiver Évolution",
|
||||
"PAUSE_EVOLUTION": "Empêcher Évolution",
|
||||
"PAUSE_EVOLUTION": "Interrompre Évolution",
|
||||
"REVIVE": "Ranimer",
|
||||
"RENAME": "Renommer",
|
||||
"choosePokemon": "Sélectionnez un Pokémon.",
|
||||
|
|
|
@ -600,7 +600,7 @@ export class TerastallizeAccessModifier extends PersistentModifier {
|
|||
|
||||
export abstract class PokemonHeldItemModifier extends PersistentModifier {
|
||||
public pokemonId: integer;
|
||||
public isTransferable: boolean = true;
|
||||
readonly isTransferrable: boolean = true;
|
||||
|
||||
constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) {
|
||||
super(type, stackCount);
|
||||
|
@ -699,7 +699,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
|
|||
|
||||
export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModifier {
|
||||
protected battlesLeft: integer;
|
||||
public isTransferable: boolean = false;
|
||||
readonly isTransferrable: boolean = false;
|
||||
|
||||
constructor(type: ModifierTypes.ModifierType, pokemonId: integer, battlesLeft?: integer, stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
@ -736,7 +736,7 @@ export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModi
|
|||
|
||||
export class TerastallizeModifier extends LapsingPokemonHeldItemModifier {
|
||||
public teraType: Type;
|
||||
public isTransferable: boolean = false;
|
||||
readonly isTransferrable: boolean = false;
|
||||
|
||||
constructor(type: ModifierTypes.TerastallizeModifierType, pokemonId: integer, teraType: Type, battlesLeft?: integer, stackCount?: integer) {
|
||||
super(type, pokemonId, battlesLeft || 10, stackCount);
|
||||
|
@ -799,7 +799,7 @@ export class TerastallizeModifier extends LapsingPokemonHeldItemModifier {
|
|||
*/
|
||||
export class BaseStatModifier extends PokemonHeldItemModifier {
|
||||
protected stat: PermanentStat;
|
||||
public isTransferable: boolean = false;
|
||||
readonly isTransferrable: boolean = false;
|
||||
|
||||
constructor(type: ModifierType, pokemonId: integer, stat: PermanentStat, stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
@ -843,7 +843,7 @@ export class BaseStatModifier extends PokemonHeldItemModifier {
|
|||
export class EvoTrackerModifier extends PokemonHeldItemModifier {
|
||||
protected species: Species;
|
||||
protected required: integer;
|
||||
public isTransferable: boolean = false;
|
||||
readonly isTransferrable: boolean = false;
|
||||
|
||||
constructor(type: ModifierType, pokemonId: integer, species: Species, required: integer, stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
@ -880,7 +880,7 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier {
|
|||
*/
|
||||
export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier {
|
||||
private statModifier: integer;
|
||||
public isTransferable: boolean = false;
|
||||
readonly isTransferrable: boolean = false;
|
||||
|
||||
constructor(type: ModifierTypes.PokemonBaseStatTotalModifierType, pokemonId: integer, statModifier: integer, stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
@ -929,7 +929,7 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier {
|
|||
export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier {
|
||||
private statModifier: integer;
|
||||
private stats: Stat[];
|
||||
public isTransferable: boolean = false;
|
||||
readonly isTransferrable: boolean = false;
|
||||
|
||||
constructor (type: ModifierType, pokemonId: integer, statModifier: integer, stats: Stat[], stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
@ -979,7 +979,7 @@ export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier {
|
|||
* Currently used by Macho Brace item
|
||||
*/
|
||||
export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier {
|
||||
public isTransferable: boolean = false;
|
||||
readonly isTransferrable: boolean = false;
|
||||
|
||||
constructor (type: ModifierType, pokemonId: integer, stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
@ -2346,7 +2346,7 @@ export class PokemonMultiHitModifier extends PokemonHeldItemModifier {
|
|||
export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier {
|
||||
public formChangeItem: FormChangeItem;
|
||||
public active: boolean;
|
||||
public isTransferable: boolean = false;
|
||||
readonly isTransferrable: boolean = false;
|
||||
|
||||
constructor(type: ModifierTypes.FormChangeItemModifierType, pokemonId: integer, formChangeItem: FormChangeItem, active: boolean, stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
|
@ -2691,7 +2691,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
|
|||
|
||||
const transferredModifierTypes: ModifierTypes.ModifierType[] = [];
|
||||
const itemModifiers = pokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === targetPokemon.id && m.isTransferable, targetPokemon.isPlayer()) as PokemonHeldItemModifier[];
|
||||
&& m.pokemonId === targetPokemon.id && m.isTransferrable, targetPokemon.isPlayer()) as PokemonHeldItemModifier[];
|
||||
let highestItemTier = itemModifiers.map(m => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier!, highestTier), 0); // TODO: is this bang correct?
|
||||
let tierItemModifiers = itemModifiers.filter(m => m.type.getOrInferTier(poolType) === highestItemTier);
|
||||
|
||||
|
@ -2736,7 +2736,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
|
|||
* @see {@linkcode modifierTypes[MINI_BLACK_HOLE]}
|
||||
*/
|
||||
export class TurnHeldItemTransferModifier extends HeldItemTransferModifier {
|
||||
isTransferable: boolean = true;
|
||||
isTransferrable: boolean = true;
|
||||
constructor(type: ModifierType, pokemonId: integer, stackCount?: integer) {
|
||||
super(type, pokemonId, stackCount);
|
||||
}
|
||||
|
@ -2762,7 +2762,7 @@ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier {
|
|||
}
|
||||
|
||||
setTransferrableFalse(): void {
|
||||
this.isTransferable = false;
|
||||
this.isTransferrable = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ import i18next from "i18next";
|
|||
import { FieldPhase } from "./field-phase";
|
||||
import { SelectTargetPhase } from "./select-target-phase";
|
||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
import { isNullOrUndefined } from "#app/utils";
|
||||
|
||||
export class CommandPhase extends FieldPhase {
|
||||
protected fieldIndex: integer;
|
||||
|
@ -180,16 +179,14 @@ export class CommandPhase extends FieldPhase {
|
|||
case Command.POKEMON:
|
||||
case Command.RUN:
|
||||
const isSwitch = command === Command.POKEMON;
|
||||
const { currentBattle, arena } = this.scene;
|
||||
const mysteryEncounterFleeAllowed = currentBattle.mysteryEncounter?.fleeAllowed;
|
||||
if (!isSwitch && (arena.biomeType === Biome.END || (!isNullOrUndefined(mysteryEncounterFleeAllowed) && !mysteryEncounterFleeAllowed))) {
|
||||
if (!isSwitch && this.scene.arena.biomeType === Biome.END) {
|
||||
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.scene.ui.showText(i18next.t("battle:noEscapeForce"), null, () => {
|
||||
this.scene.ui.showText("", 0);
|
||||
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
|
||||
}, null, true);
|
||||
} else if (!isSwitch && (currentBattle.battleType === BattleType.TRAINER || currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE)) {
|
||||
} else if (!isSwitch && (this.scene.currentBattle.battleType === BattleType.TRAINER || this.scene.currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE)) {
|
||||
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
this.scene.ui.showText(i18next.t("battle:noEscapeTrainer"), null, () => {
|
||||
|
@ -200,12 +197,12 @@ export class CommandPhase extends FieldPhase {
|
|||
const batonPass = isSwitch && args[0] as boolean;
|
||||
const trappedAbMessages: string[] = [];
|
||||
if (batonPass || !playerPokemon.isTrapped(trappedAbMessages)) {
|
||||
currentBattle.turnCommands[this.fieldIndex] = isSwitch
|
||||
this.scene.currentBattle.turnCommands[this.fieldIndex] = isSwitch
|
||||
? { command: Command.POKEMON, cursor: cursor, args: args }
|
||||
: { command: Command.RUN };
|
||||
success = true;
|
||||
if (!isSwitch && this.fieldIndex) {
|
||||
currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true;
|
||||
this.scene.currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true;
|
||||
}
|
||||
} else if (trappedAbMessages.length > 0) {
|
||||
if (!isSwitch) {
|
||||
|
@ -222,7 +219,7 @@ export class CommandPhase extends FieldPhase {
|
|||
|
||||
// trapTag should be defined at this point, but just in case...
|
||||
if (!trapTag) {
|
||||
currentBattle.turnCommands[this.fieldIndex] = isSwitch
|
||||
this.scene.currentBattle.turnCommands[this.fieldIndex] = isSwitch
|
||||
? { command: Command.POKEMON, cursor: cursor, args: args }
|
||||
: { command: Command.RUN };
|
||||
break;
|
||||
|
|
|
@ -60,11 +60,6 @@ export class GameOverPhase extends BattlePhase {
|
|||
this.scene.ui.fadeOut(1250).then(() => {
|
||||
this.scene.reset();
|
||||
this.scene.clearPhaseQueue();
|
||||
// If this is a ME, clear any residual visual sprites before reloading
|
||||
const encounter = this.scene.currentBattle.mysteryEncounter;
|
||||
if (encounter?.introVisuals) {
|
||||
this.scene.field.remove(encounter.introVisuals, true);
|
||||
}
|
||||
this.scene.gameData.loadSession(this.scene, this.scene.sessionSlotId).then(() => {
|
||||
this.scene.pushPhase(new EncounterPhase(this.scene, true));
|
||||
|
||||
|
@ -243,7 +238,7 @@ export class GameOverPhase extends BattlePhase {
|
|||
gameVersion: this.scene.game.config.gameVersion,
|
||||
timestamp: new Date().getTime(),
|
||||
challenges: this.scene.gameMode.challenges.map(c => new ChallengeData(c)),
|
||||
mysteryEncounterType: this.scene.currentBattle.mysteryEncounter?.encounterType ?? -1,
|
||||
mysteryEncounterType: this.scene.currentBattle.mysteryEncounter?.encounterType,
|
||||
mysteryEncounterSaveData: this.scene.mysteryEncounterSaveData
|
||||
} as SessionSaveData;
|
||||
}
|
||||
|
|
|
@ -6,16 +6,14 @@ export class MessagePhase extends Phase {
|
|||
private callbackDelay: integer | null;
|
||||
private prompt: boolean | null;
|
||||
private promptDelay: integer | null;
|
||||
private speaker?: string;
|
||||
|
||||
constructor(scene: BattleScene, text: string, callbackDelay?: integer | null, prompt?: boolean | null, promptDelay?: integer | null, speaker?: string) {
|
||||
constructor(scene: BattleScene, text: string, callbackDelay?: integer | null, prompt?: boolean | null, promptDelay?: integer | null) {
|
||||
super(scene);
|
||||
|
||||
this.text = text;
|
||||
this.callbackDelay = callbackDelay!; // TODO: is this bang correct?
|
||||
this.prompt = prompt!; // TODO: is this bang correct?
|
||||
this.promptDelay = promptDelay!; // TODO: is this bang correct?
|
||||
this.speaker = speaker;
|
||||
}
|
||||
|
||||
start() {
|
||||
|
@ -23,15 +21,11 @@ export class MessagePhase extends Phase {
|
|||
|
||||
if (this.text.indexOf("$") > -1) {
|
||||
const pageIndex = this.text.indexOf("$");
|
||||
this.scene.unshiftPhase(new MessagePhase(this.scene, this.text.slice(pageIndex + 1), this.callbackDelay, this.prompt, this.promptDelay, this.speaker));
|
||||
this.scene.unshiftPhase(new MessagePhase(this.scene, this.text.slice(pageIndex + 1), this.callbackDelay, this.prompt, this.promptDelay));
|
||||
this.text = this.text.slice(0, pageIndex).trim();
|
||||
}
|
||||
|
||||
if (this.speaker) {
|
||||
this.scene.ui.showDialogue(this.text, this.speaker, null, () => this.end(), this.callbackDelay || (this.prompt ? 0 : 1500), this.promptDelay ?? 0);
|
||||
} else {
|
||||
this.scene.ui.showText(this.text, null, () => this.end(), this.callbackDelay || (this.prompt ? 0 : 1500), this.prompt, this.promptDelay);
|
||||
}
|
||||
this.scene.ui.showText(this.text, null, () => this.end(), this.callbackDelay || (this.prompt ? 0 : 1500), this.prompt, this.promptDelay);
|
||||
}
|
||||
|
||||
end() {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr,
|
|||
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag";
|
||||
import { MoveAnim } from "#app/data/battle-anims";
|
||||
import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags";
|
||||
import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr } from "#app/data/move";
|
||||
import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, DealsDoubleDamageToTagAttr } from "#app/data/move";
|
||||
import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms";
|
||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
||||
import { Moves } from "#app/enums/moves";
|
||||
|
@ -394,7 +394,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||
}
|
||||
|
||||
const semiInvulnerableTag = target.getTag(SemiInvulnerableTag);
|
||||
if (semiInvulnerableTag && !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType)) {
|
||||
if (semiInvulnerableTag && !this.move.getMove().getAttrs(DealsDoubleDamageToTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import BattleScene from "../battle-scene";
|
|||
import { Phase } from "../phase";
|
||||
import { Mode } from "../ui/ui";
|
||||
import { transitionMysteryEncounterIntroVisuals, OptionSelectSettings } from "../data/mystery-encounters/utils/encounter-phase-utils";
|
||||
import MysteryEncounterOption, { OptionPhaseCallback } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import MysteryEncounterOption, { OptionPhaseCallback } from "../data/mystery-encounters/mystery-encounter-option";
|
||||
import { getCharVariantFromDialogue } from "../data/dialogue";
|
||||
import { TrainerSlot } from "../data/trainer-config";
|
||||
import { BattleSpec } from "#enums/battle-spec";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import BattleScene from "#app/battle-scene";
|
||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||
import { regenerateModifierPoolThresholds, ModifierTypeOption, ModifierType, getPlayerShopModifierTypeOptionsForWave, PokemonModifierType, FusePokemonModifierType, PokemonMoveModifierType, TmModifierType, RememberMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, ModifierPoolType, getPlayerModifierTypeOptions } from "#app/modifier/modifier-type";
|
||||
import { ExtraModifierModifier, HealShopCostModifier, Modifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||
import { ExtraModifierModifier, Modifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||
import ModifierSelectUiHandler, { SHOP_OPTIONS_ROW_LIMIT } from "#app/ui/modifier-select-ui-handler";
|
||||
import PartyUiHandler, { PartyUiMode, PartyOption } from "#app/ui/party-ui-handler";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
|
@ -10,7 +10,7 @@ import * as Utils from "#app/utils";
|
|||
import { BattlePhase } from "./battle-phase";
|
||||
import Overrides from "#app/overrides";
|
||||
import { CustomModifierSettings } from "#app/modifier/modifier-type";
|
||||
import { isNullOrUndefined, NumberHolder } from "#app/utils";
|
||||
import { isNullOrUndefined } from "#app/utils";
|
||||
|
||||
export class SelectModifierPhase extends BattlePhase {
|
||||
private rerollCount: integer;
|
||||
|
@ -69,11 +69,11 @@ export class SelectModifierPhase extends BattlePhase {
|
|||
}
|
||||
let modifierType: ModifierType;
|
||||
let cost: integer;
|
||||
const rerollCost = this.getRerollCost(typeOptions, this.scene.lockModifierTiers);
|
||||
switch (rowCursor) {
|
||||
case 0:
|
||||
switch (cursor) {
|
||||
case 0:
|
||||
const rerollCost = this.getRerollCost(typeOptions, this.scene.lockModifierTiers);
|
||||
if (rerollCost < 0 || this.scene.money < rerollCost) {
|
||||
this.scene.ui.playError();
|
||||
return false;
|
||||
|
@ -94,7 +94,7 @@ export class SelectModifierPhase extends BattlePhase {
|
|||
this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, itemQuantity: integer, toSlotIndex: integer) => {
|
||||
if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) {
|
||||
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& m.isTransferable && m.pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[];
|
||||
&& m.isTransferrable && m.pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[];
|
||||
const itemModifier = itemModifiers[itemIndex];
|
||||
this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, itemQuantity);
|
||||
} else {
|
||||
|
@ -108,11 +108,6 @@ export class SelectModifierPhase extends BattlePhase {
|
|||
});
|
||||
break;
|
||||
case 3:
|
||||
if (rerollCost < 0) {
|
||||
// Reroll lock button is also disabled when reroll is disabled
|
||||
this.scene.ui.playError();
|
||||
return false;
|
||||
}
|
||||
this.scene.lockModifierTiers = !this.scene.lockModifierTiers;
|
||||
const uiHandler = this.scene.ui.getHandler() as ModifierSelectUiHandler;
|
||||
uiHandler.setRerollCost(this.getRerollCost(typeOptions, this.scene.lockModifierTiers));
|
||||
|
@ -138,10 +133,7 @@ export class SelectModifierPhase extends BattlePhase {
|
|||
if (shopOption.type) {
|
||||
modifierType = shopOption.type;
|
||||
}
|
||||
// Apply Black Sludge to healing item cost
|
||||
const healingItemCost = new NumberHolder(shopOption.cost);
|
||||
this.scene.applyModifier(HealShopCostModifier, true, healingItemCost);
|
||||
cost = healingItemCost.value;
|
||||
cost = shopOption.cost;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||
|
||||
const config = BerriesAboundEncounter.enemyPartyConfigs[0];
|
||||
expect(config).toBeDefined();
|
||||
expect(config.levelAdditiveMultiplier).toBe(1);
|
||||
expect(config.pokemonConfigs?.[0].isBoss).toBe(true);
|
||||
expect(onInitResult).toBe(true);
|
||||
});
|
||||
|
@ -133,7 +134,7 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||
});
|
||||
|
||||
// TODO: there is some severe test flakiness occurring for this file, needs to be looked at/addressed in separate issue
|
||||
it("should reward the player with X berries based on wave", async () => {
|
||||
it.skip("should reward the player with X berries based on wave", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
||||
|
||||
const numBerries = game.scene.currentBattle.mysteryEncounter!.misc.numBerries;
|
||||
|
|
|
@ -96,6 +96,7 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
|||
|
||||
const config = FightOrFlightEncounter.enemyPartyConfigs[0];
|
||||
expect(config).toBeDefined();
|
||||
expect(config.levelAdditiveMultiplier).toBe(1);
|
||||
expect(config.pokemonConfigs?.[0].isBoss).toBe(true);
|
||||
expect(onInitResult).toBe(true);
|
||||
});
|
||||
|
|
|
@ -117,12 +117,12 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
|
|||
},
|
||||
{
|
||||
trainerConfig: expect.any(TrainerConfig),
|
||||
levelAdditiveModifier: 1,
|
||||
levelAdditiveMultiplier: 1,
|
||||
female: expect.any(Boolean),
|
||||
},
|
||||
{
|
||||
trainerConfig: expect.any(TrainerConfig),
|
||||
levelAdditiveModifier: 1.5,
|
||||
levelAdditiveMultiplier: 1.5,
|
||||
female: expect.any(Boolean),
|
||||
}
|
||||
]);
|
||||
|
|
|
@ -21,8 +21,6 @@ const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA];
|
|||
const defaultBiome = Biome.CAVE;
|
||||
const defaultWave = 45;
|
||||
|
||||
const TRANSPORT_BIOMES = [Biome.SPACE, Biome.ISLAND, Biome.LABORATORY, Biome.FAIRY_CAVE, Biome.WASTELAND, Biome.DOJO];
|
||||
|
||||
describe("Teleporting Hijinks - Mystery Encounter", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
@ -185,7 +183,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => {
|
|||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
expect(previousBiome).not.toBe(scene.arena.biomeType);
|
||||
expect(TRANSPORT_BIOMES).toContain(scene.arena.biomeType);
|
||||
expect([Biome.SPACE, Biome.ISLAND, Biome.LABORATORY, Biome.FAIRY_CAVE]).toContain(scene.arena.biomeType);
|
||||
});
|
||||
|
||||
it("should start a battle against an enraged boss", { retry: 5 }, async () => {
|
||||
|
@ -248,7 +246,7 @@ describe("Teleporting Hijinks - Mystery Encounter", () => {
|
|||
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||
|
||||
expect(previousBiome).not.toBe(scene.arena.biomeType);
|
||||
expect(TRANSPORT_BIOMES).toContain(scene.arena.biomeType);
|
||||
expect([Biome.SPACE, Biome.ISLAND, Biome.LABORATORY, Biome.FAIRY_CAVE]).toContain(scene.arena.biomeType);
|
||||
});
|
||||
|
||||
it("should start a battle against an enraged boss", async () => {
|
||||
|
|
|
@ -114,7 +114,7 @@ describe("The Strong Stuff - Mystery Encounter", () => {
|
|||
|
||||
expect(TheStrongStuffEncounter.enemyPartyConfigs).toEqual([
|
||||
{
|
||||
levelAdditiveModifier: 1,
|
||||
levelAdditiveMultiplier: 1,
|
||||
disableSwitch: true,
|
||||
pokemonConfigs: [
|
||||
{
|
||||
|
|
|
@ -102,7 +102,7 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
|||
|
||||
expect(TrashToTreasureEncounter.enemyPartyConfigs).toEqual([
|
||||
{
|
||||
levelAdditiveModifier: 1,
|
||||
levelAdditiveMultiplier: 1,
|
||||
disableSwitch: true,
|
||||
pokemonConfigs: [
|
||||
{
|
||||
|
|
|
@ -107,7 +107,7 @@ describe("Uncommon Breed - Mystery Encounter", () => {
|
|||
expect(onInitResult).toBe(true);
|
||||
});
|
||||
|
||||
describe("Option 1 - Fight", () => {
|
||||
describe.skip("Option 1 - Fight", () => {
|
||||
it("should have the correct properties", () => {
|
||||
const option = UncommonBreedEncounter.options[0];
|
||||
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
||||
|
@ -123,7 +123,7 @@ describe("Uncommon Breed - Mystery Encounter", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it.skip("should start a fight against the boss", async () => {
|
||||
it("should start a fight against the boss", async () => {
|
||||
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
||||
const unshiftPhaseSpy = vi.spyOn(scene, "unshiftPhase");
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.UNCOMMON_BREED, defaultParty);
|
||||
|
|
|
@ -160,7 +160,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||
|
||||
this.player = args[0];
|
||||
|
||||
const partyHasHeldItem = this.player && !!this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.isTransferable).length;
|
||||
const partyHasHeldItem = this.player && !!this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.isTransferrable).length;
|
||||
const canLockRarities = !!this.scene.findModifier(m => m instanceof LockModifierTiersModifier);
|
||||
|
||||
this.transferButtonContainer.setVisible(false);
|
||||
|
@ -277,13 +277,13 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||
this.lockRarityButtonContainer.setVisible(canLockRarities);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: [ this.checkButtonContainer, this.continueButtonContainer ],
|
||||
targets: [ this.lockRarityButtonContainer, this.checkButtonContainer, this.continueButtonContainer ],
|
||||
alpha: 1,
|
||||
duration: 250
|
||||
});
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: [this.rerollButtonContainer, this.lockRarityButtonContainer],
|
||||
targets: [this.rerollButtonContainer],
|
||||
alpha: this.rerollCost < 0 ? 0.5 : 1,
|
||||
duration: 250
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Button } from "#enums/buttons";
|
|||
import { addWindow, WindowVariant } from "./ui-theme";
|
||||
import { MysteryEncounterPhase } from "../phases/mystery-encounter-phases";
|
||||
import { PartyUiMode } from "./party-ui-handler";
|
||||
import MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||
import MysteryEncounterOption from "../data/mystery-encounters/mystery-encounter-option";
|
||||
import * as Utils from "../utils";
|
||||
import { isNullOrUndefined } from "../utils";
|
||||
import { getPokeballAtlasKey } from "../data/pokeball";
|
||||
|
@ -42,8 +42,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||
private encounterOptions: MysteryEncounterOption[] = [];
|
||||
private optionsMeetsReqs: boolean[];
|
||||
|
||||
protected viewPartyIndex: number = 0;
|
||||
protected viewPartyXPosition: number = 0;
|
||||
protected viewPartyIndex: integer = 0;
|
||||
|
||||
protected blockInput: boolean = true;
|
||||
|
||||
|
@ -301,11 +300,11 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||
}
|
||||
}
|
||||
|
||||
override getCursor(): number {
|
||||
override getCursor(): integer {
|
||||
return this.cursor ? this.cursor : 0;
|
||||
}
|
||||
|
||||
override setCursor(cursor: number): boolean {
|
||||
override setCursor(cursor: integer): boolean {
|
||||
const prevCursor = this.getCursor();
|
||||
const changed = prevCursor !== cursor;
|
||||
if (changed) {
|
||||
|
@ -320,7 +319,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||
}
|
||||
|
||||
if (cursor === this.viewPartyIndex) {
|
||||
this.cursorObj.setPosition(this.viewPartyXPosition, -17);
|
||||
this.cursorObj.setPosition(246, -17);
|
||||
} else if (this.optionsContainer.getAll()?.length === 3) { // 2 Options
|
||||
this.cursorObj.setPosition(-10.5 + (cursor % 2 === 1 ? 100 : 0), 15);
|
||||
} else if (this.optionsContainer.getAll()?.length === 4) { // 3 Options
|
||||
|
@ -420,10 +419,8 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||
}
|
||||
|
||||
// View Party Button
|
||||
const viewPartyText = addBBCodeTextObject(this.scene, (this.scene.game.canvas.width) / 6, -24, getBBCodeFrag(i18next.t("mysteryEncounterMessages:view_party_button"), TextStyle.PARTY), TextStyle.PARTY);
|
||||
const viewPartyText = addBBCodeTextObject(this.scene, 256, -24, getBBCodeFrag(i18next.t("mysteryEncounterMessages:view_party_button"), TextStyle.PARTY), TextStyle.PARTY);
|
||||
this.optionsContainer.add(viewPartyText);
|
||||
viewPartyText.x -= (viewPartyText.displayWidth + 16);
|
||||
this.viewPartyXPosition = viewPartyText.x - 10;
|
||||
|
||||
// Description Window
|
||||
const titleTextObject = addBBCodeTextObject(this.scene, 0, 0, titleText ?? "", TextStyle.TOOLTIP_TITLE, { wordWrap: { width: 750 }, align: "center", lineSpacing: -8 });
|
||||
|
|
|
@ -355,7 +355,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
const newPokemon = this.scene.getParty()[p];
|
||||
// this next line gets all of the transferable items from pokemon [p]; it does this by getting all the held modifiers that are transferable and checking to see if they belong to pokemon [p]
|
||||
const getTransferrableItemsFromPokemon = (newPokemon: PlayerPokemon) =>
|
||||
this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).isTransferable && (m as PokemonHeldItemModifier).pokemonId === newPokemon.id) as PokemonHeldItemModifier[];
|
||||
this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).isTransferrable && (m as PokemonHeldItemModifier).pokemonId === newPokemon.id) as PokemonHeldItemModifier[];
|
||||
// this next bit checks to see if the the selected item from the original transfer pokemon exists on the new pokemon [p]; this returns undefined if the new pokemon doesn't have the item at all, otherwise it returns the pokemonHeldItemModifier for that item
|
||||
const matchingModifier = newPokemon.scene.findModifier(m => m instanceof PokemonHeldItemModifier && m.pokemonId === newPokemon.id && m.matchType(getTransferrableItemsFromPokemon(pokemon)[this.transferOptionCursor])) as PokemonHeldItemModifier;
|
||||
const partySlot = this.partySlots.filter(m => m.getPokemon() === newPokemon)[0]; // this gets pokemon [p] for us
|
||||
|
@ -399,7 +399,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
|| (option === PartyOption.RELEASE && this.partyUiMode === PartyUiMode.RELEASE)) {
|
||||
let filterResult: string | null;
|
||||
const getTransferrableItemsFromPokemon = (pokemon: PlayerPokemon) =>
|
||||
this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.isTransferable && m.pokemonId === pokemon.id) as PokemonHeldItemModifier[];
|
||||
this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.isTransferrable && m.pokemonId === pokemon.id) as PokemonHeldItemModifier[];
|
||||
if (option !== PartyOption.TRANSFER && option !== PartyOption.SPLICE) {
|
||||
filterResult = (this.selectFilter as PokemonSelectFilter)(pokemon);
|
||||
if (filterResult === null && (option === PartyOption.SEND_OUT || option === PartyOption.PASS_BATON)) {
|
||||
|
@ -596,7 +596,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode) {
|
||||
/** Initialize item quantities for the selected Pokemon */
|
||||
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& m.isTransferable && m.pokemonId === this.scene.getParty()[this.cursor].id) as PokemonHeldItemModifier[];
|
||||
&& m.isTransferrable && m.pokemonId === this.scene.getParty()[this.cursor].id) as PokemonHeldItemModifier[];
|
||||
this.transferQuantities = itemModifiers.map(item => item.getStackCount());
|
||||
this.transferQuantitiesMax = itemModifiers.map(item => item.getStackCount());
|
||||
}
|
||||
|
@ -813,7 +813,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||
|
||||
const itemModifiers = this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER
|
||||
? this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& m.isTransferable && m.pokemonId === pokemon.id) as PokemonHeldItemModifier[]
|
||||
&& m.isTransferrable && m.pokemonId === pokemon.id) as PokemonHeldItemModifier[]
|
||||
: [];
|
||||
|
||||
if (this.options.length) {
|
||||
|
|
|
@ -281,7 +281,7 @@ class RunEntryContainer extends Phaser.GameObjects.Container {
|
|||
const genderIndex = this.scene.gameData.gender ?? PlayerGender.UNSET;
|
||||
const genderStr = PlayerGender[genderIndex].toLowerCase();
|
||||
// Defeats from wild Pokemon battles will show the Pokemon responsible by the text of the run result.
|
||||
if (data.battleType === BattleType.WILD || (data.battleType === BattleType.MYSTERY_ENCOUNTER && !data.trainer)) {
|
||||
if (data.battleType === BattleType.WILD) {
|
||||
const enemyContainer = this.scene.add.container(8, 5);
|
||||
const gameOutcomeLabel = addTextObject(this.scene, 0, 0, `${i18next.t("runHistory:defeatedWild", { context: genderStr })}`, TextStyle.WINDOW);
|
||||
enemyContainer.add(gameOutcomeLabel);
|
||||
|
@ -302,7 +302,7 @@ class RunEntryContainer extends Phaser.GameObjects.Container {
|
|||
enemy.destroy();
|
||||
});
|
||||
this.add(enemyContainer);
|
||||
} else if (data.battleType === BattleType.TRAINER || (data.battleType === BattleType.MYSTERY_ENCOUNTER && data.trainer)) { // Defeats from Trainers show the trainer's title and name
|
||||
} else if (data.battleType === BattleType.TRAINER) { // Defeats from Trainers show the trainer's title and name
|
||||
const tObj = data.trainer.toTrainer(this.scene);
|
||||
// Because of the interesting mechanics behind rival names, the rival name and title have to be retrieved differently
|
||||
const RIVAL_TRAINER_ID_THRESHOLD = 375;
|
||||
|
|
|
@ -211,7 +211,7 @@ export default class RunInfoUiHandler extends UiHandler {
|
|||
if (!this.isVictory) {
|
||||
const enemyContainer = this.scene.add.container(0, 0);
|
||||
// Wild - Single and Doubles
|
||||
if (this.runInfo.battleType === BattleType.WILD || (this.runInfo.battleType === BattleType.MYSTERY_ENCOUNTER && !this.runInfo.trainer)) {
|
||||
if (this.runInfo.battleType === BattleType.WILD) {
|
||||
switch (this.runInfo.enemyParty.length) {
|
||||
case 1:
|
||||
// Wild - Singles
|
||||
|
@ -222,7 +222,7 @@ export default class RunInfoUiHandler extends UiHandler {
|
|||
this.parseWildDoubleDefeat(enemyContainer);
|
||||
break;
|
||||
}
|
||||
} else if (this.runInfo.battleType === BattleType.TRAINER || (this.runInfo.battleType === BattleType.MYSTERY_ENCOUNTER && this.runInfo.trainer)) {
|
||||
} else if (this.runInfo.battleType === BattleType.TRAINER) {
|
||||
this.parseTrainerDefeat(enemyContainer);
|
||||
}
|
||||
this.runResultContainer.add(enemyContainer);
|
||||
|
@ -381,6 +381,10 @@ export default class RunInfoUiHandler extends UiHandler {
|
|||
break;
|
||||
case GameModes.SPLICED_ENDLESS:
|
||||
modeText.appendText(`${i18next.t("gameMode:endlessSpliced")}`, false);
|
||||
if (this.runInfo.waveIndex === this.scene.gameData.gameStats.highestEndlessWave) {
|
||||
modeText.appendText(` [${i18next.t("runHistory:personalBest")}]`, false);
|
||||
modeText.setTint(0xffef5c, 0x47ff69, 0x6b6bff, 0xff6969);
|
||||
}
|
||||
break;
|
||||
case GameModes.CHALLENGE:
|
||||
modeText.appendText(`${i18next.t("gameMode:challenge")}`, false);
|
||||
|
@ -399,18 +403,17 @@ export default class RunInfoUiHandler extends UiHandler {
|
|||
break;
|
||||
case GameModes.ENDLESS:
|
||||
modeText.appendText(`${i18next.t("gameMode:endless")}`, false);
|
||||
// If the player achieves a personal best in Endless, the mode text will be tinted similarly to SSS luck to celebrate their achievement.
|
||||
if (this.runInfo.waveIndex === this.scene.gameData.gameStats.highestEndlessWave) {
|
||||
modeText.appendText(` [${i18next.t("runHistory:personalBest")}]`, false);
|
||||
modeText.setTint(0xffef5c, 0x47ff69, 0x6b6bff, 0xff6969);
|
||||
}
|
||||
break;
|
||||
case GameModes.CLASSIC:
|
||||
modeText.appendText(`${i18next.t("gameMode:classic")}`, false);
|
||||
break;
|
||||
}
|
||||
|
||||
// If the player achieves a personal best in Endless, the mode text will be tinted similarly to SSS luck to celebrate their achievement.
|
||||
if ((this.runInfo.gameMode === GameModes.ENDLESS || this.runInfo.gameMode === GameModes.SPLICED_ENDLESS) && this.runInfo.waveIndex === this.scene.gameData.gameStats.highestEndlessWave) {
|
||||
modeText.appendText(` [${i18next.t("runHistory:personalBest")}]`);
|
||||
modeText.setTint(0xffef5c, 0x47ff69, 0x6b6bff, 0xff6969);
|
||||
}
|
||||
|
||||
// Duration + Money
|
||||
const runInfoTextContainer = this.scene.add.container(0, 0);
|
||||
// Japanese is set to a greater line spacing of 35px in addBBCodeTextObject() if lineSpacing < 12.
|
||||
|
|
|
@ -83,7 +83,7 @@ const languageSettings: { [key: string]: LanguageSetting } = {
|
|||
},
|
||||
"fr":{
|
||||
starterInfoTextSize: "54px",
|
||||
instructionTextSize: "38px",
|
||||
instructionTextSize: "35px",
|
||||
},
|
||||
"it":{
|
||||
starterInfoTextSize: "56px",
|
||||
|
|
Loading…
Reference in New Issue