Resolve merge issues

This commit is contained in:
NightKev 2024-12-01 17:38:48 -08:00
parent 15280c0879
commit 9d5a318448
24 changed files with 83 additions and 93 deletions

View File

@ -5775,7 +5775,7 @@ export function initAbilities() {
.ignorable(), .ignorable(),
new Ability(Abilities.ANALYTIC, 5) new Ability(Abilities.ANALYTIC, 5)
.attr(MovePowerBoostAbAttr, (user, target, move) => { .attr(MovePowerBoostAbAttr, (user, target, move) => {
const movePhase = globalScene.findPhase((phase) => phase instanceof MovePhase && phase.pokemon.id !== user.id); const movePhase = globalScene.findPhase((phase) => phase instanceof MovePhase && phase.pokemon.id !== user?.id);
return Utils.isNullOrUndefined(movePhase); return Utils.isNullOrUndefined(movePhase);
}, 1.3), }, 1.3),
new Ability(Abilities.ILLUSION, 5) new Ability(Abilities.ILLUSION, 5)

View File

@ -870,7 +870,7 @@ export class PowderTag extends BattlerTag {
super.onAdd(pokemon); super.onAdd(pokemon);
// "{Pokemon} is covered in powder!" // "{Pokemon} is covered in powder!"
pokemon.scene.queueMessage(i18next.t("battlerTags:powderOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); globalScene.queueMessage(i18next.t("battlerTags:powderOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
} }
/** /**
@ -882,13 +882,13 @@ export class PowderTag extends BattlerTag {
*/ */
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.PRE_MOVE) { if (lapseType === BattlerTagLapseType.PRE_MOVE) {
const movePhase = pokemon.scene.getCurrentPhase(); const movePhase = globalScene.getCurrentPhase();
if (movePhase instanceof MovePhase) { if (movePhase instanceof MovePhase) {
const move = movePhase.move.getMove(); const move = movePhase.move.getMove();
if (pokemon.getMoveType(move) === Type.FIRE) { if (pokemon.getMoveType(move) === Type.FIRE) {
movePhase.cancel(); movePhase.cancel();
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.POWDER)); globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.POWDER));
const cancelDamage = new BooleanHolder(false); const cancelDamage = new BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelDamage); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelDamage);
@ -897,7 +897,7 @@ export class PowderTag extends BattlerTag {
} }
// "When the flame touched the powder\non the Pokémon, it exploded!" // "When the flame touched the powder\non the Pokémon, it exploded!"
pokemon.scene.queueMessage(i18next.t("battlerTags:powderLapse", { moveName: move.name })); globalScene.queueMessage(i18next.t("battlerTags:powderLapse", { moveName: move.name }));
} }
} }
return true; return true;

View File

@ -6041,7 +6041,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
} }
} }
return false; return false;
} else if (user.scene.currentBattle.battleType !== BattleType.WILD) { // Switch out logic for enemy trainers } else if (globalScene.currentBattle.battleType !== BattleType.WILD) { // Switch out logic for enemy trainers
// Find indices of off-field Pokemon that are eligible to be switched into // Find indices of off-field Pokemon that are eligible to be switched into
const eligibleNewIndices: number[] = []; const eligibleNewIndices: number[] = [];
globalScene.getEnemyParty().forEach((pokemon, index) => { globalScene.getEnemyParty().forEach((pokemon, index) => {
@ -6074,7 +6074,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
new SwitchSummonPhase( new SwitchSummonPhase(
this.switchType, this.switchType,
switchOutTarget.getFieldIndex(), switchOutTarget.getFieldIndex(),
(user.scene.currentBattle.trainer ? user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot) : 0), (globalScene.currentBattle.trainer ? globalScene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot) : 0),
false, false,
false false
), ),
@ -6750,13 +6750,13 @@ export class RepeatMoveAttr extends MoveEffectAttr {
const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move)!; const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move)!;
const moveTargets = lastMove.targets ?? []; const moveTargets = lastMove.targets ?? [];
user.scene.queueMessage(i18next.t("moveTriggers:instructingMove", { globalScene.queueMessage(i18next.t("moveTriggers:instructingMove", {
userPokemonName: getPokemonNameWithAffix(user), userPokemonName: getPokemonNameWithAffix(user),
targetPokemonName: getPokemonNameWithAffix(target) targetPokemonName: getPokemonNameWithAffix(target)
})); }));
target.getMoveQueue().unshift({ move: lastMove.move, targets: moveTargets, ignorePP: false }); target.getMoveQueue().unshift({ move: lastMove.move, targets: moveTargets, ignorePP: false });
target.turnData.extraTurns++; target.turnData.extraTurns++;
target.scene.appendToPhase(new MovePhase(target.scene, target, moveTargets, movesetMove), MoveEndPhase); globalScene.appendToPhase(new MovePhase(target, moveTargets, movesetMove), MoveEndPhase);
return true; return true;
} }

View File

@ -92,7 +92,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
.withCatchAllowed(true) .withCatchAllowed(true)
.withFleeAllowed(false) .withFleeAllowed(false)
.withOnVisualsStart(() => { .withOnVisualsStart(() => {
const oricorio = globalSscene.getEnemyPokemon()!; const oricorio = globalScene.getEnemyPokemon()!;
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, oricorio, globalScene.getPlayerPokemon()!); const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, oricorio, globalScene.getPlayerPokemon()!);
danceAnim.play(false, () => { danceAnim.play(false, () => {
if (oricorio.shiny) { if (oricorio.shiny) {

View File

@ -812,7 +812,7 @@ function doTradeReceivedSequence(receivedPokemon: PlayerPokemon, receivedPokemon
// Received pokemon sparkles // Received pokemon sparkles
let pokemonShinySparkle: Phaser.GameObjects.Sprite; let pokemonShinySparkle: Phaser.GameObjects.Sprite;
if (receivedPokemon.shiny) { if (receivedPokemon.shiny) {
pokemonShinySparkle = scene.add.sprite(receivedPokemonSprite.x, receivedPokemonSprite.y, "shiny"); pokemonShinySparkle = globalScene.add.sprite(receivedPokemonSprite.x, receivedPokemonSprite.y, "shiny");
pokemonShinySparkle.setVisible(false); pokemonShinySparkle.setVisible(false);
tradeContainer.add(pokemonShinySparkle); tradeContainer.add(pokemonShinySparkle);
} }
@ -856,8 +856,8 @@ function doTradeReceivedSequence(receivedPokemon: PlayerPokemon, receivedPokemon
alpha: 0, alpha: 0,
onComplete: () => { onComplete: () => {
if (receivedPokemon.shiny) { if (receivedPokemon.shiny) {
scene.time.delayedCall(500, () => { globalScene.time.delayedCall(500, () => {
doShinySparkleAnim(scene, pokemonShinySparkle, receivedPokemon.variant); doShinySparkleAnim(pokemonShinySparkle, receivedPokemon.variant);
}); });
} }
receivedPokeballSprite.destroy(); receivedPokeballSprite.destroy();

View File

@ -114,7 +114,6 @@ export interface EnemyPartyConfig {
* Generates an enemy party for a mystery encounter battle * Generates an enemy party for a mystery encounter battle
* This will override and replace any standard encounter generation logic * This will override and replace any standard encounter generation logic
* Useful for tailoring specific battles to mystery encounters * Useful for tailoring specific battles to mystery encounters
* @param scene Battle Scene
* @param partyConfig Can pass various customizable attributes for the enemy party, see EnemyPartyConfig * @param partyConfig Can pass various customizable attributes for the enemy party, see EnemyPartyConfig
*/ */
export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): Promise<void> { export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): Promise<void> {
@ -370,7 +369,6 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
* See: [startOfBattleEffects](IMysteryEncounter.startOfBattleEffects) for more details * See: [startOfBattleEffects](IMysteryEncounter.startOfBattleEffects) for more details
* *
* This promise does not need to be awaited on if called in an encounter onInit (will just load lazily) * This promise does not need to be awaited on if called in an encounter onInit (will just load lazily)
* @param scene
* @param moves * @param moves
*/ */
export function loadCustomMovesForEncounter(moves: Moves | Moves[]) { export function loadCustomMovesForEncounter(moves: Moves | Moves[]) {
@ -381,7 +379,6 @@ export function loadCustomMovesForEncounter(moves: Moves | Moves[]) {
/** /**
* Will update player money, and animate change (sound optional) * Will update player money, and animate change (sound optional)
* @param scene
* @param changeValue * @param changeValue
* @param playSound * @param playSound
* @param showMessage * @param showMessage
@ -404,7 +401,6 @@ export function updatePlayerMoney(changeValue: number, playSound: boolean = true
/** /**
* Converts modifier bullshit to an actual item * Converts modifier bullshit to an actual item
* @param scene Battle Scene
* @param modifier * @param modifier
* @param pregenArgs Can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc. * @param pregenArgs Can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
*/ */
@ -426,7 +422,6 @@ export function generateModifierType(modifier: () => ModifierType, pregenArgs?:
/** /**
* Converts modifier bullshit to an actual item * Converts modifier bullshit to an actual item
* @param scene - Battle Scene
* @param modifier * @param modifier
* @param pregenArgs - can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc. * @param pregenArgs - can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
*/ */
@ -440,7 +435,6 @@ export function generateModifierTypeOption(modifier: () => ModifierType, pregenA
/** /**
* This function is intended for use inside onPreOptionPhase() of an encounter option * This function is intended for use inside onPreOptionPhase() of an encounter option
* @param scene
* @param onPokemonSelected - Any logic that needs to be performed when Pokemon is chosen * @param onPokemonSelected - Any logic that needs to be performed when Pokemon is chosen
* If a second option needs to be selected, onPokemonSelected should return a OptionSelectItem[] object * If a second option needs to be selected, onPokemonSelected should return a OptionSelectItem[] object
* @param onPokemonNotSelected - Any logic that needs to be performed if no Pokemon is chosen * @param onPokemonNotSelected - Any logic that needs to be performed if no Pokemon is chosen
@ -529,9 +523,9 @@ interface PokemonAndOptionSelected {
} }
/** /**
* This function is intended for use inside onPreOptionPhase() of an encounter option * This function is intended for use inside `onPreOptionPhase()` of an encounter option
* @param scene *
* If a second option needs to be selected, onPokemonSelected should return a OptionSelectItem[] object * If a second option needs to be selected, `onPokemonSelected` should return a {@linkcode OptionSelectItem}`[]` object
* @param options * @param options
* @param optionSelectPromptKey * @param optionSelectPromptKey
* @param selectablePokemonFilter * @param selectablePokemonFilter
@ -617,7 +611,6 @@ export function selectOptionThenPokemon(options: OptionSelectItem[], optionSelec
/** /**
* Will initialize reward phases to follow the mystery encounter * Will initialize reward phases to follow the mystery encounter
* Can have shop displayed or skipped * Can have shop displayed or skipped
* @param scene - Battle Scene
* @param customShopRewards - adds a shop phase with the specified rewards / reward tiers * @param customShopRewards - adds a shop phase with the specified rewards / reward tiers
* @param eggRewards * @param eggRewards
* @param preRewardsCallback - can execute an arbitrary callback before the new phases if necessary (useful for updating items/party/injecting new phases before {@linkcode MysteryEncounterRewardsPhase}) * @param preRewardsCallback - can execute an arbitrary callback before the new phases if necessary (useful for updating items/party/injecting new phases before {@linkcode MysteryEncounterRewardsPhase})
@ -648,10 +641,11 @@ export function setEncounterRewards(customShopRewards?: CustomModifierSettings,
/** /**
* Will initialize exp phases into the phase queue (these are in addition to any combat or other exp earned) * Will initialize exp phases into the phase queue (these are in addition to any combat or other exp earned)
* Exp Share and Exp Balance will still function as normal * Exp Share and Exp Balance will still function as normal
* @param scene - Battle Scene
* @param participantId - id/s of party pokemon that get full exp value. Other party members will receive Exp Share amounts * @param participantId - id/s of party pokemon that get full exp value. Other party members will receive Exp Share amounts
* @param baseExpValue - gives exp equivalent to a pokemon of the wave index's level. * @param baseExpValue - gives exp equivalent to a pokemon of the wave index's level.
*
* Guidelines: * Guidelines:
* ```md
* 36 - Sunkern (lowest in game) * 36 - Sunkern (lowest in game)
* 62-64 - regional starter base evos * 62-64 - regional starter base evos
* 100 - Scyther * 100 - Scyther
@ -660,6 +654,7 @@ export function setEncounterRewards(customShopRewards?: CustomModifierSettings,
* 290 - trio legendaries * 290 - trio legendaries
* 340 - box legendaries * 340 - box legendaries
* 608 - Blissey (highest in game) * 608 - Blissey (highest in game)
* ```
* https://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_by_effort_value_yield_(Generation_IX) * https://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_by_effort_value_yield_(Generation_IX)
* @param useWaveIndex - set to false when directly passing the the full exp value instead of baseExpValue * @param useWaveIndex - set to false when directly passing the the full exp value instead of baseExpValue
*/ */
@ -686,7 +681,6 @@ export class OptionSelectSettings {
/** /**
* Can be used to queue a new series of Options to select for an Encounter * Can be used to queue a new series of Options to select for an Encounter
* MUST be used only in onOptionPhase, will not work in onPreOptionPhase or onPostOptionPhase * MUST be used only in onOptionPhase, will not work in onPreOptionPhase or onPostOptionPhase
* @param scene
* @param optionSelectSettings * @param optionSelectSettings
*/ */
export function initSubsequentOptionSelect(optionSelectSettings: OptionSelectSettings) { export function initSubsequentOptionSelect(optionSelectSettings: OptionSelectSettings) {
@ -696,7 +690,6 @@ export function initSubsequentOptionSelect(optionSelectSettings: OptionSelectSet
/** /**
* Can be used to exit an encounter without any battles or followup * Can be used to exit an encounter without any battles or followup
* Will skip any shops and rewards, and queue the next encounter phase as normal * Will skip any shops and rewards, and queue the next encounter phase as normal
* @param scene
* @param addHealPhase - when true, will add a shop phase to end of encounter with 0 rewards but healing items are available * @param addHealPhase - when true, will add a shop phase to end of encounter with 0 rewards but healing items are available
* @param encounterMode - Can set custom encounter mode if necessary (may be required for forcing Pokemon to return before next phase) * @param encounterMode - Can set custom encounter mode if necessary (may be required for forcing Pokemon to return before next phase)
*/ */
@ -709,7 +702,6 @@ export function leaveEncounterWithoutBattle(addHealPhase: boolean = false, encou
/** /**
* *
* @param scene
* @param addHealPhase - Adds an empty shop phase to allow player to purchase healing items * @param addHealPhase - Adds an empty shop phase to allow player to purchase healing items
* @param doNotContinue - default `false`. If set to true, will not end the battle and continue to next wave * @param doNotContinue - default `false`. If set to true, will not end the battle and continue to next wave
*/ */
@ -747,7 +739,6 @@ export function handleMysteryEncounterVictory(addHealPhase: boolean = false, doN
/** /**
* Similar to {@linkcode handleMysteryEncounterVictory}, but for cases where the player lost a battle or failed a challenge * Similar to {@linkcode handleMysteryEncounterVictory}, but for cases where the player lost a battle or failed a challenge
* @param scene
* @param addHealPhase * @param addHealPhase
*/ */
export function handleMysteryEncounterBattleFailed(addHealPhase: boolean = false, doNotContinue: boolean = false) { export function handleMysteryEncounterBattleFailed(addHealPhase: boolean = false, doNotContinue: boolean = false) {
@ -778,7 +769,6 @@ export function handleMysteryEncounterBattleFailed(addHealPhase: boolean = false
/** /**
* *
* @param scene
* @param hide - If true, performs ease out and hide visuals. If false, eases in visuals. Defaults to true * @param hide - If true, performs ease out and hide visuals. If false, eases in visuals. Defaults to true
* @param destroy - If true, will destroy visuals ONLY ON HIDE TRANSITION. Does nothing on show. Defaults to true * @param destroy - If true, will destroy visuals ONLY ON HIDE TRANSITION. Does nothing on show. Defaults to true
* @param duration * @param duration
@ -829,7 +819,6 @@ export function transitionMysteryEncounterIntroVisuals(hide: boolean = true, des
/** /**
* Will queue moves for any pokemon to use before the first CommandPhase of a battle * Will queue moves for any pokemon to use before the first CommandPhase of a battle
* Mostly useful for allowing {@linkcode MysteryEncounter} enemies to "cheat" and use moves before the first turn * Mostly useful for allowing {@linkcode MysteryEncounter} enemies to "cheat" and use moves before the first turn
* @param scene
*/ */
export function handleMysteryEncounterBattleStartEffects() { export function handleMysteryEncounterBattleStartEffects() {
const encounter = globalScene.currentBattle.mysteryEncounter; const encounter = globalScene.currentBattle.mysteryEncounter;
@ -867,7 +856,6 @@ export function handleMysteryEncounterBattleStartEffects() {
/** /**
* Can queue extra phases or logic during {@linkcode TurnInitPhase} * Can queue extra phases or logic during {@linkcode TurnInitPhase}
* Should mostly just be used for injecting custom phases into the battle system on turn start * Should mostly just be used for injecting custom phases into the battle system on turn start
* @param scene
* @return boolean - if true, will skip the remainder of the {@linkcode TurnInitPhase} * @return boolean - if true, will skip the remainder of the {@linkcode TurnInitPhase}
*/ */
export function handleMysteryEncounterTurnStartEffects(): boolean { export function handleMysteryEncounterTurnStartEffects(): boolean {
@ -882,7 +870,6 @@ export function handleMysteryEncounterTurnStartEffects(): boolean {
/** /**
* TODO: remove once encounter spawn rate is finalized * TODO: remove once encounter spawn rate is finalized
* Just a helper function to calculate aggregate stats for MEs in a Classic run * Just a helper function to calculate aggregate stats for MEs in a Classic run
* @param scene
* @param baseSpawnWeight * @param baseSpawnWeight
*/ */
export function calculateMEAggregateStats(baseSpawnWeight: number) { export function calculateMEAggregateStats(baseSpawnWeight: number) {
@ -1047,7 +1034,6 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
/** /**
* TODO: remove once encounter spawn rate is finalized * TODO: remove once encounter spawn rate is finalized
* Just a helper function to calculate aggregate stats for MEs in a Classic run * Just a helper function to calculate aggregate stats for MEs in a Classic run
* @param scene
* @param luckValue - 0 to 14 * @param luckValue - 0 to 14
*/ */
export function calculateRareSpawnAggregateStats(luckValue: number) { export function calculateRareSpawnAggregateStats(luckValue: number) {

View File

@ -1191,7 +1191,7 @@ function getSpeciesFilterRandomPartyMemberFunc(
}; };
return (level: number, strength: PartyMemberStrength) => { return (level: number, strength: PartyMemberStrength) => {
const waveIndex = scene.currentBattle.waveIndex; const waveIndex = globalScene.currentBattle.waveIndex;
const species = getPokemonSpecies(globalScene.randomSpecies(waveIndex, level, false, speciesFilter) const species = getPokemonSpecies(globalScene.randomSpecies(waveIndex, level, false, speciesFilter)
.getTrainerSpeciesForLevel(level, true, strength, waveIndex)); .getTrainerSpeciesForLevel(level, true, strength, waveIndex));

View File

@ -193,15 +193,15 @@ export function cos(index: integer, amplitude: integer): number {
* @param sparkleSprite the Sprite to play the animation on * @param sparkleSprite the Sprite to play the animation on
* @param variant which shiny {@linkcode variant} to play the animation for * @param variant which shiny {@linkcode variant} to play the animation for
*/ */
export function doShinySparkleAnim(scene: BattleScene, sparkleSprite: Phaser.GameObjects.Sprite, variant: Variant) { export function doShinySparkleAnim(sparkleSprite: Phaser.GameObjects.Sprite, variant: Variant) {
const keySuffix = variant ? `_${variant + 1}` : ""; const keySuffix = variant ? `_${variant + 1}` : "";
const spriteKey = `shiny${keySuffix}`; const spriteKey = `shiny${keySuffix}`;
const animationKey = `sparkle${keySuffix}`; const animationKey = `sparkle${keySuffix}`;
// Make sure the animation exists, and create it if not // Make sure the animation exists, and create it if not
if (!scene.anims.exists(animationKey)) { if (!globalScene.anims.exists(animationKey)) {
const frameNames = scene.anims.generateFrameNames(spriteKey, { suffix: ".png", end: 34 }); const frameNames = globalScene.anims.generateFrameNames(spriteKey, { suffix: ".png", end: 34 });
scene.anims.create({ globalScene.anims.create({
key: `sparkle${keySuffix}`, key: `sparkle${keySuffix}`,
frames: frameNames, frames: frameNames,
frameRate: 32, frameRate: 32,
@ -212,5 +212,5 @@ export function doShinySparkleAnim(scene: BattleScene, sparkleSprite: Phaser.Gam
// Play the animation // Play the animation
sparkleSprite.play(animationKey); sparkleSprite.play(animationKey);
scene.playSound("se/sparkle"); globalScene.playSound("se/sparkle");
} }

View File

@ -4,9 +4,10 @@ import MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { isNullOrUndefined } from "#app/utils"; import { isNullOrUndefined } from "#app/utils";
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import PlayAnimationConfig = Phaser.Types.Animations.PlayAnimationConfig;
import { Variant } from "#app/data/variant"; import { Variant } from "#app/data/variant";
import { doShinySparkleAnim } from "#app/field/anims"; import { doShinySparkleAnim } from "#app/field/anims";
import type BattleScene from "#app/battle-scene";
import PlayAnimationConfig = Phaser.Types.Animations.PlayAnimationConfig;
type KnownFileRoot = type KnownFileRoot =
| "arenas" | "arenas"
@ -128,7 +129,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
const spacingValue = Math.round((maxX - minX) / Math.max(this.spriteConfigs.filter(s => !s.x && !s.y).length, 1)); const spacingValue = Math.round((maxX - minX) / Math.max(this.spriteConfigs.filter(s => !s.x && !s.y).length, 1));
this.shinySparkleSprites = []; this.shinySparkleSprites = [];
const shinySparkleSprites = scene.add.container(0, 0); const shinySparkleSprites = globalScene.add.container(0, 0);
this.spriteConfigs?.forEach((config) => { this.spriteConfigs?.forEach((config) => {
const { spriteKey, isItem, hasShadow, scale, x, y, yShadow, alpha, isPokemon, isShiny, variant } = config; const { spriteKey, isItem, hasShadow, scale, x, y, yShadow, alpha, isPokemon, isShiny, variant } = config;
@ -151,7 +152,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
tintSprite.setPipelineData("shiny", true); tintSprite.setPipelineData("shiny", true);
tintSprite.setPipelineData("variant", variant); tintSprite.setPipelineData("variant", variant);
// Create Sprite for shiny Sparkle // Create Sprite for shiny Sparkle
pokemonShinySparkle = scene.add.sprite(sprite.x, sprite.y, "shiny"); pokemonShinySparkle = globalScene.add.sprite(sprite.x, sprite.y, "shiny");
pokemonShinySparkle.setOrigin(0.5, 1); pokemonShinySparkle.setOrigin(0.5, 1);
pokemonShinySparkle.setVisible(false); pokemonShinySparkle.setVisible(false);
this.shinySparkleSprites.push({ sprite: pokemonShinySparkle, variant: variant ?? 0 }); this.shinySparkleSprites.push({ sprite: pokemonShinySparkle, variant: variant ?? 0 });
@ -338,7 +339,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
playShinySparkles() { playShinySparkles() {
for (const sparkleConfig of this.shinySparkleSprites) { for (const sparkleConfig of this.shinySparkleSprites) {
this.scene.time.delayedCall(500, () => { this.scene.time.delayedCall(500, () => {
doShinySparkleAnim(this.scene, sparkleConfig.sprite, sparkleConfig.variant); doShinySparkleAnim(sparkleConfig.sprite, sparkleConfig.variant);
}); });
} }
} }

View File

@ -2636,7 +2636,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
applyMoveAttrs(FixedDamageAttr, source, this, move, fixedDamage); applyMoveAttrs(FixedDamageAttr, source, this, move, fixedDamage);
if (fixedDamage.value) { if (fixedDamage.value) {
const multiLensMultiplier = new Utils.NumberHolder(1); const multiLensMultiplier = new Utils.NumberHolder(1);
source.scene.applyModifiers(PokemonMultiHitModifier, source.isPlayer(), source, move.id, null, multiLensMultiplier); globalScene.applyModifiers(PokemonMultiHitModifier, source.isPlayer(), source, move.id, null, multiLensMultiplier);
fixedDamage.value = Utils.toDmgValue(fixedDamage.value * multiLensMultiplier.value); fixedDamage.value = Utils.toDmgValue(fixedDamage.value * multiLensMultiplier.value);
return { return {
@ -3565,7 +3565,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
break; break;
case StatusEffect.FREEZE: case StatusEffect.FREEZE:
if (this.isOfType(Type.ICE) || (!ignoreField && (globalScene?.arena?.weather?.weatherType && [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(this.scene.arena.weather.weatherType)))) { if (this.isOfType(Type.ICE) || (!ignoreField && (globalScene?.arena?.weather?.weatherType && [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(globalScene.arena.weather.weatherType)))) {
return false; return false;
} }
break; break;

View File

@ -17,9 +17,9 @@ export class BattleEndPhase extends BattlePhase {
start() { start() {
super.start(); super.start();
this.scene.gameData.gameStats.battles++; globalScene.gameData.gameStats.battles++;
if (this.scene.gameMode.isEndless && this.scene.currentBattle.waveIndex + 1 > this.scene.gameData.gameStats.highestEndlessWave) { if (globalScene.gameMode.isEndless && globalScene.currentBattle.waveIndex + 1 > globalScene.gameData.gameStats.highestEndlessWave) {
this.scene.gameData.gameStats.highestEndlessWave = this.scene.currentBattle.waveIndex + 1; globalScene.gameData.gameStats.highestEndlessWave = globalScene.currentBattle.waveIndex + 1;
} }
if (this.isVictory) { if (this.isVictory) {

View File

@ -217,9 +217,9 @@ export class EncounterPhase extends BattlePhase {
if (!this.loaded && battle.battleType !== BattleType.MYSTERY_ENCOUNTER) { if (!this.loaded && battle.battleType !== BattleType.MYSTERY_ENCOUNTER) {
regenerateModifierPoolThresholds(globalScene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD); regenerateModifierPoolThresholds(globalScene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD);
globalScene.generateEnemyModifiers(); globalScene.generateEnemyModifiers();
overrideModifiers(this.scene, false); overrideModifiers(false);
this.scene.getEnemyField().forEach(enemy => { globalScene.getEnemyField().forEach(enemy => {
overrideHeldItems(this.scene, enemy, false); overrideHeldItems(enemy, false);
}); });
} }
@ -443,12 +443,12 @@ export class EncounterPhase extends BattlePhase {
globalScene.unshiftPhase(new ShinySparklePhase(BattlerIndex.ENEMY + e)); globalScene.unshiftPhase(new ShinySparklePhase(BattlerIndex.ENEMY + e));
} }
/** This sets Eternatus' held item to be untransferrable, preventing it from being stolen */ /** This sets Eternatus' held item to be untransferrable, preventing it from being stolen */
if (enemyPokemon.species.speciesId === Species.ETERNATUS && (this.scene.gameMode.isBattleClassicFinalBoss(this.scene.currentBattle.waveIndex) || this.scene.gameMode.isEndlessMajorBoss(this.scene.currentBattle.waveIndex))) { if (enemyPokemon.species.speciesId === Species.ETERNATUS && (globalScene.gameMode.isBattleClassicFinalBoss(globalScene.currentBattle.waveIndex) || globalScene.gameMode.isEndlessMajorBoss(globalScene.currentBattle.waveIndex))) {
const enemyMBH = this.scene.findModifier(m => m instanceof TurnHeldItemTransferModifier, false) as TurnHeldItemTransferModifier; const enemyMBH = globalScene.findModifier(m => m instanceof TurnHeldItemTransferModifier, false) as TurnHeldItemTransferModifier;
if (enemyMBH) { if (enemyMBH) {
this.scene.removeModifier(enemyMBH, true); globalScene.removeModifier(enemyMBH, true);
enemyMBH.setTransferrableFalse(); enemyMBH.setTransferrableFalse();
this.scene.addEnemyModifier(enemyMBH); globalScene.addEnemyModifier(enemyMBH);
} }
} }
}); });

View File

@ -222,32 +222,33 @@ export class GameOverPhase extends BattlePhase {
} }
} }
// TODO: Make function use existing getSessionSaveData() function and then modify the values from there.
/** /**
* Slightly modified version of {@linkcode GameData.getSessionSaveData}. * Slightly modified version of {@linkcode GameData.getSessionSaveData}.
* @returns A promise containing the {@linkcode SessionSaveData} * @returns A promise containing the {@linkcode SessionSaveData}
*/ */
private async getRunHistoryEntry(): Promise<SessionSaveData> { private async getRunHistoryEntry(): Promise<SessionSaveData> {
const preWaveSessionData = await this.scene.gameData.getSession(this.scene.sessionSlotId); const preWaveSessionData = await globalScene.gameData.getSession(globalScene.sessionSlotId);
return { return {
seed: this.scene.seed, seed: globalScene.seed,
playTime: this.scene.sessionPlayTime, playTime: globalScene.sessionPlayTime,
gameMode: this.scene.gameMode.modeId, gameMode: globalScene.gameMode.modeId,
party: this.scene.getPlayerParty().map(p => new PokemonData(p)), party: globalScene.getPlayerParty().map(p => new PokemonData(p)),
enemyParty: this.scene.getEnemyParty().map(p => new PokemonData(p)), enemyParty: globalScene.getEnemyParty().map(p => new PokemonData(p)),
modifiers: preWaveSessionData ? preWaveSessionData.modifiers : this.scene.findModifiers(() => true).map(m => new PersistentModifierData(m, true)), modifiers: preWaveSessionData ? preWaveSessionData.modifiers : globalScene.findModifiers(() => true).map(m => new PersistentModifierData(m, true)),
enemyModifiers: preWaveSessionData ? preWaveSessionData.enemyModifiers : this.scene.findModifiers(() => true, false).map(m => new PersistentModifierData(m, false)), enemyModifiers: preWaveSessionData ? preWaveSessionData.enemyModifiers : globalScene.findModifiers(() => true, false).map(m => new PersistentModifierData(m, false)),
arena: new ArenaData(this.scene.arena), arena: new ArenaData(globalScene.arena),
pokeballCounts: this.scene.pokeballCounts, pokeballCounts: globalScene.pokeballCounts,
money: Math.floor(this.scene.money), money: Math.floor(globalScene.money),
score: this.scene.score, score: globalScene.score,
waveIndex: this.scene.currentBattle.waveIndex, waveIndex: globalScene.currentBattle.waveIndex,
battleType: this.scene.currentBattle.battleType, battleType: globalScene.currentBattle.battleType,
trainer: this.scene.currentBattle.trainer ? new TrainerData(this.scene.currentBattle.trainer) : null, trainer: globalScene.currentBattle.trainer ? new TrainerData(globalScene.currentBattle.trainer) : null,
gameVersion: this.scene.game.config.gameVersion, gameVersion: globalScene.game.config.gameVersion,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
challenges: this.scene.gameMode.challenges.map(c => new ChallengeData(c)), challenges: globalScene.gameMode.challenges.map(c => new ChallengeData(c)),
mysteryEncounterType: this.scene.currentBattle.mysteryEncounter?.encounterType ?? -1, mysteryEncounterType: globalScene.currentBattle.mysteryEncounter?.encounterType ?? -1,
mysteryEncounterSaveData: this.scene.mysteryEncounterSaveData mysteryEncounterSaveData: globalScene.mysteryEncounterSaveData
} as SessionSaveData; } as SessionSaveData;
} }
} }

View File

@ -29,7 +29,7 @@ export class PostSummonPhase extends PokemonPhase {
applyPostSummonAbAttrs(PostSummonAbAttr, pokemon) applyPostSummonAbAttrs(PostSummonAbAttr, pokemon)
.then(() => { .then(() => {
const field = pokemon.isPlayer() ? this.scene.getPlayerField() : this.scene.getEnemyField(); const field = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
field.forEach((p) => applyAbAttrs(CommanderAbAttr, p, null, false)); field.forEach((p) => applyAbAttrs(CommanderAbAttr, p, null, false));
this.end(); this.end();

View File

@ -66,7 +66,7 @@ export class SwitchPhase extends BattlePhase {
if (slotIndex >= globalScene.currentBattle.getBattlerCount() && slotIndex < 6) { if (slotIndex >= globalScene.currentBattle.getBattlerCount() && slotIndex < 6) {
// Remove any pre-existing PostSummonPhase under the same field index. // Remove any pre-existing PostSummonPhase under the same field index.
// Pre-existing PostSummonPhases may occur when this phase is invoked during a prompt to switch at the start of a wave. // Pre-existing PostSummonPhases may occur when this phase is invoked during a prompt to switch at the start of a wave.
this.scene.tryRemovePhase(p => p instanceof PostSummonPhase && p.player && p.fieldIndex === this.fieldIndex); globalScene.tryRemovePhase(p => p instanceof PostSummonPhase && p.player && p.fieldIndex === this.fieldIndex);
const switchType = (option === PartyOption.PASS_BATON) ? SwitchType.BATON_PASS : this.switchType; const switchType = (option === PartyOption.PASS_BATON) ? SwitchType.BATON_PASS : this.switchType;
globalScene.unshiftPhase(new SwitchSummonPhase(switchType, fieldIndex, slotIndex, this.doReturn)); globalScene.unshiftPhase(new SwitchSummonPhase(switchType, fieldIndex, slotIndex, this.doReturn));
} }

View File

@ -43,9 +43,11 @@ export class TrainerVictoryPhase extends BattlePhase {
} }
} }
// Breeders in Space achievement // Breeders in Space achievement
if (this.scene.arena.biomeType === Biome.SPACE if (
&& (trainerType === TrainerType.BREEDER || trainerType === TrainerType.EXPERT_POKEMON_BREEDER)) { globalScene.arena.biomeType === Biome.SPACE
this.scene.validateAchv(achvs.BREEDERS_IN_SPACE); && (trainerType === TrainerType.BREEDER || trainerType === TrainerType.EXPERT_POKEMON_BREEDER)
) {
globalScene.validateAchv(achvs.BREEDERS_IN_SPACE);
} }
globalScene.ui.showText(i18next.t("battle:trainerDefeated", { trainerName: globalScene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) }), null, () => { globalScene.ui.showText(i18next.t("battle:trainerDefeated", { trainerName: globalScene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) }), null, () => {

View File

@ -29,7 +29,7 @@ export class TurnEndPhase extends FieldPhase {
globalScene.applyModifiers(TurnHealModifier, pokemon.isPlayer(), pokemon); globalScene.applyModifiers(TurnHealModifier, pokemon.isPlayer(), pokemon);
if (globalScene.arena.terrain?.terrainType === TerrainType.GRASSY && pokemon.isGrounded()) { if (globalScene.arena.terrain?.terrainType === TerrainType.GRASSY && pokemon.isGrounded()) {
this.scene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(), globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
Math.max(pokemon.getMaxHp() >> 4, 1), i18next.t("battle:turnEndHpRestore", { pokemonName: getPokemonNameWithAffix(pokemon) }), true)); Math.max(pokemon.getMaxHp() >> 4, 1), i18next.t("battle:turnEndHpRestore", { pokemonName: getPokemonNameWithAffix(pokemon) }), true));
} }

View File

@ -23,7 +23,7 @@ function testMoveEffectiveness(game: GameManager, move: Moves, targetSpecies: Sp
const target = game.scene.addEnemyPokemon(getPokemonSpecies(targetSpecies), 5, TrainerSlot.NONE); const target = game.scene.addEnemyPokemon(getPokemonSpecies(targetSpecies), 5, TrainerSlot.NONE);
if (teraType !== undefined) { if (teraType !== undefined) {
overrideHeldItems(game.scene, target, false); overrideHeldItems(target, false);
} }
expect(target.getMoveEffectiveness(user, allMoves[move])).toBe(expected); expect(target.getMoveEffectiveness(user, allMoves[move])).toBe(expected);

View File

@ -267,7 +267,7 @@ describe("Clowning Around - Mystery Encounter", () => {
itemType = generateModifierType(modifierTypes.LUCKY_EGG) as PokemonHeldItemModifierType; itemType = generateModifierType(modifierTypes.LUCKY_EGG) as PokemonHeldItemModifierType;
await addItemToPokemon(scene, scene.getPlayerParty()[0], 5, itemType); await addItemToPokemon(scene, scene.getPlayerParty()[0], 5, itemType);
// 3 Soothe Bell on lead (great tier, but counted as ultra by this ME) // 3 Soothe Bell on lead (great tier, but counted as ultra by this ME)
itemType = generateModifierType(scene, modifierTypes.SOOTHE_BELL) as PokemonHeldItemModifierType; itemType = generateModifierType(modifierTypes.SOOTHE_BELL) as PokemonHeldItemModifierType;
await addItemToPokemon(scene, scene.getPlayerParty()[0], 3, itemType); await addItemToPokemon(scene, scene.getPlayerParty()[0], 3, itemType);
// 5 Soul Dew on lead (rogue) // 5 Soul Dew on lead (rogue)
itemType = generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType; itemType = generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType;

View File

@ -85,8 +85,8 @@ describe("Safari Zone - Mystery Encounter", () => {
expect(encounter.onInit).toBeDefined(); expect(encounter.onInit).toBeDefined();
encounter.populateDialogueTokensFromRequirements(scene); encounter.populateDialogueTokensFromRequirements();
const onInitResult = onInit!(scene); const onInitResult = onInit!();
expect(onInitResult).toBe(true); expect(onInitResult).toBe(true);
}); });

View File

@ -306,10 +306,10 @@ export default class RunInfoUiHandler extends UiHandler {
const windowCenterX = runResultWindow.getTopCenter().x; const windowCenterX = runResultWindow.getTopCenter().x;
const windowBottomY = runResultWindow.getBottomCenter().y; const windowBottomY = runResultWindow.getBottomCenter().y;
const runStatusText = addTextObject(this.scene, windowCenterX, 5, `${i18next.t("saveSlotSelectUiHandler:wave")} ${this.runInfo.waveIndex}`, TextStyle.WINDOW, { fontSize : "60px", lineSpacing: 0.1 }); const runStatusText = addTextObject(windowCenterX, 5, `${i18next.t("saveSlotSelectUiHandler:wave")} ${this.runInfo.waveIndex}`, TextStyle.WINDOW, { fontSize : "60px", lineSpacing: 0.1 });
runStatusText.setOrigin(0.5, 0); runStatusText.setOrigin(0.5, 0);
const currentBiomeText = addTextObject(this.scene, windowCenterX, windowBottomY - 5, `${getBiomeName(this.runInfo.arena.biome)}`, TextStyle.WINDOW, { fontSize: "60px" }); const currentBiomeText = addTextObject(windowCenterX, windowBottomY - 5, `${getBiomeName(this.runInfo.arena.biome)}`, TextStyle.WINDOW, { fontSize: "60px" });
currentBiomeText.setOrigin(0.5, 1); currentBiomeText.setOrigin(0.5, 1);
this.runResultContainer.add([ runStatusText, currentBiomeText ]); this.runResultContainer.add([ runStatusText, currentBiomeText ]);
@ -527,7 +527,7 @@ export default class RunInfoUiHandler extends UiHandler {
const runTime = Utils.getPlayTimeString(this.runInfo.playTime); const runTime = Utils.getPlayTimeString(this.runInfo.playTime);
runInfoText.appendText(`${i18next.t("runHistory:runLength")}: ${runTime}`, false); runInfoText.appendText(`${i18next.t("runHistory:runLength")}: ${runTime}`, false);
const runMoney = Utils.formatMoney(globalScene.moneyFormat, this.runInfo.money); const runMoney = Utils.formatMoney(globalScene.moneyFormat, this.runInfo.money);
const moneyTextColor = getTextColor(TextStyle.MONEY_WINDOW, false, this.scene.uiTheme); const moneyTextColor = getTextColor(TextStyle.MONEY_WINDOW, false, globalScene.uiTheme);
runInfoText.appendText(`[color=${moneyTextColor}]${i18next.t("battleScene:moneyOwned", { formattedMoney : runMoney })}[/color]`); runInfoText.appendText(`[color=${moneyTextColor}]${i18next.t("battleScene:moneyOwned", { formattedMoney : runMoney })}[/color]`);
runInfoText.setPosition(7, 70); runInfoText.setPosition(7, 70);
runInfoTextContainer.add(runInfoText); runInfoTextContainer.add(runInfoText);

View File

@ -136,16 +136,16 @@ export default class AbstractSettingsUiHandler extends MessageUiHandler {
this.scrollBar.setTotalRows(this.settings.length); this.scrollBar.setTotalRows(this.settings.length);
// Two-lines message box // Two-lines message box
this.messageBoxContainer = this.scene.add.container(0, this.scene.scaledCanvas.height); this.messageBoxContainer = globalScene.add.container(0, globalScene.scaledCanvas.height);
this.messageBoxContainer.setName("settings-message-box"); this.messageBoxContainer.setName("settings-message-box");
this.messageBoxContainer.setVisible(false); this.messageBoxContainer.setVisible(false);
const settingsMessageBox = addWindow(this.scene, 0, -1, this.scene.scaledCanvas.width - 2, 48); const settingsMessageBox = addWindow(0, -1, globalScene.scaledCanvas.width - 2, 48);
settingsMessageBox.setOrigin(0, 1); settingsMessageBox.setOrigin(0, 1);
this.messageBoxContainer.add(settingsMessageBox); this.messageBoxContainer.add(settingsMessageBox);
const messageText = addTextObject(this.scene, 8, -40, "", TextStyle.WINDOW, { maxLines: 2 }); const messageText = addTextObject(8, -40, "", TextStyle.WINDOW, { maxLines: 2 });
messageText.setWordWrapWidth(this.scene.game.canvas.width - 60); messageText.setWordWrapWidth(globalScene.game.canvas.width - 60);
messageText.setName("settings-message"); messageText.setName("settings-message");
messageText.setOrigin(0, 0); messageText.setOrigin(0, 0);

View File

@ -1074,7 +1074,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.starterSelectMessageBoxContainer.setY(0); this.starterSelectMessageBoxContainer.setY(0);
this.message.setY(4); this.message.setY(4);
} else { } else {
this.starterSelectMessageBoxContainer.setY(this.scene.game.canvas.height / 6); this.starterSelectMessageBoxContainer.setY(globalScene.game.canvas.height / 6);
this.starterSelectMessageBox.setOrigin(0, 1); this.starterSelectMessageBox.setOrigin(0, 1);
this.message.setY(singleLine ? -22 : -37); this.message.setY(singleLine ? -22 : -37);
} }

View File

@ -44,7 +44,7 @@ export default class TargetSelectUiHandler extends UiHandler {
this.fieldIndex = args[0] as integer; this.fieldIndex = args[0] as integer;
this.move = args[1] as Moves; this.move = args[1] as Moves;
this.targetSelectCallback = args[2] as TargetSelectCallback; this.targetSelectCallback = args[2] as TargetSelectCallback;
const user = this.scene.getPlayerField()[this.fieldIndex]; const user = globalScene.getPlayerField()[this.fieldIndex];
const moveTargets = getMoveTargets(user, this.move); const moveTargets = getMoveTargets(user, this.move);
this.targets = moveTargets.targets; this.targets = moveTargets.targets;