Rename gScene to globalScene

This commit is contained in:
NightKev 2024-11-10 18:45:37 -08:00
parent 510ffd40ee
commit e2cfb40d46
241 changed files with 5483 additions and 5541 deletions

View File

@ -99,7 +99,7 @@ import { FRIENDSHIP_GAIN_FROM_BATTLE } from "#app/data/balance/starters";
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
export let gScene: BattleScene;
export let globalScene: BattleScene;
const DEBUG_RNG = false;
@ -326,7 +326,7 @@ export default class BattleScene extends SceneBase {
this.phaseQueuePrependSpliceIndex = -1;
this.nextCommandPhaseQueue = [];
this.updateGameInfo();
gScene = this;
globalScene = this;
}
loadPokemonAtlas(key: string, atlasPath: string, experimental?: boolean) {
@ -348,10 +348,10 @@ export default class BattleScene extends SceneBase {
const originalRealInRange = Phaser.Math.RND.realInRange;
Phaser.Math.RND.realInRange = function (min: number, max: number): number {
const ret = originalRealInRange.apply(this, [ min, max ]);
const args = [ "RNG", ++gScene.rngCounter, ret / (max - min), `min: ${min} / max: ${max}` ];
args.push(`seed: ${gScene.rngSeedOverride || gScene.waveSeed || gScene.seed}`);
if (gScene.rngOffset) {
args.push(`offset: ${gScene.rngOffset}`);
const args = [ "RNG", ++globalScene.rngCounter, ret / (max - min), `min: ${min} / max: ${max}` ];
args.push(`seed: ${globalScene.rngSeedOverride || globalScene.waveSeed || globalScene.seed}`);
if (globalScene.rngOffset) {
args.push(`offset: ${globalScene.rngOffset}`);
}
console.log(...args);
return ret;
@ -364,7 +364,7 @@ export default class BattleScene extends SceneBase {
}
create() {
gScene.scene.remove(LoadingScene.KEY);
globalScene.scene.remove(LoadingScene.KEY);
initGameSpeed.apply(this);
this.inputController = new InputsController();
this.uiInputs = new UiInputs(this.inputController);
@ -2822,7 +2822,7 @@ export default class BattleScene extends SceneBase {
*/
applyShuffledModifiers<T extends PersistentModifier>(modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T[] {
let modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
const shuffleModifiers = mods => {
if (mods.length < 1) {
return mods;
@ -2831,7 +2831,7 @@ export default class BattleScene extends SceneBase {
return [ mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand)) ];
};
modifiers = shuffleModifiers(modifiers);
}, gScene.currentBattle.turn << 4, gScene.waveSeed);
}, globalScene.currentBattle.turn << 4, globalScene.waveSeed);
return this.applyModifiersInternal(modifiers, player, args);
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { Command } from "./ui/command-ui-handler";
import * as Utils from "./utils";
import Trainer, { TrainerVariant } from "./field/trainer";
@ -167,7 +167,7 @@ export default class Battle {
}
addPostBattleLoot(enemyPokemon: EnemyPokemon): void {
this.postBattleLoot.push(...gScene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id && m.isTransferable, false).map(i => {
this.postBattleLoot.push(...globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id && m.isTransferable, false).map(i => {
const ret = i as PokemonHeldItemModifier;
//@ts-ignore - this is awful to fix/change
ret.pokemonId = null;
@ -176,39 +176,39 @@ export default class Battle {
}
pickUpScatteredMoney(): void {
const moneyAmount = new Utils.IntegerHolder(gScene.currentBattle.moneyScattered);
gScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
const moneyAmount = new Utils.IntegerHolder(globalScene.currentBattle.moneyScattered);
globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
if (gScene.arena.getTag(ArenaTagType.HAPPY_HOUR)) {
if (globalScene.arena.getTag(ArenaTagType.HAPPY_HOUR)) {
moneyAmount.value *= 2;
}
gScene.addMoney(moneyAmount.value);
globalScene.addMoney(moneyAmount.value);
const userLocale = navigator.language || "en-US";
const formattedMoneyAmount = moneyAmount.value.toLocaleString(userLocale);
const message = i18next.t("battle:moneyPickedUp", { moneyAmount: formattedMoneyAmount });
gScene.queueMessage(message, undefined, true);
globalScene.queueMessage(message, undefined, true);
gScene.currentBattle.moneyScattered = 0;
globalScene.currentBattle.moneyScattered = 0;
}
addBattleScore(): void {
let partyMemberTurnMultiplier = gScene.getEnemyParty().length / 2 + 0.5;
let partyMemberTurnMultiplier = globalScene.getEnemyParty().length / 2 + 0.5;
if (this.double) {
partyMemberTurnMultiplier /= 1.5;
}
for (const p of gScene.getEnemyParty()) {
for (const p of globalScene.getEnemyParty()) {
if (p.isBoss()) {
partyMemberTurnMultiplier *= (p.bossSegments / 1.5) / gScene.getEnemyParty().length;
partyMemberTurnMultiplier *= (p.bossSegments / 1.5) / globalScene.getEnemyParty().length;
}
}
const turnMultiplier = Phaser.Tweens.Builders.GetEaseFunction("Sine.easeIn")(1 - Math.min(this.turn - 2, 10 * partyMemberTurnMultiplier) / (10 * partyMemberTurnMultiplier));
const finalBattleScore = Math.ceil(this.battleScore * turnMultiplier);
gScene.score += finalBattleScore;
globalScene.score += finalBattleScore;
console.log(`Battle Score: ${finalBattleScore} (${this.turn - 1} Turns x${Math.floor(turnMultiplier * 100) / 100})`);
console.log(`Total Score: ${gScene.score}`);
gScene.updateScoreText();
console.log(`Total Score: ${globalScene.score}`);
globalScene.updateScoreText();
}
getBgmOverride(): string | null {
@ -221,7 +221,7 @@ export default class Battle {
if (!this.started && this.trainer?.config.encounterBgm && this.trainer?.getEncounterMessages()?.length) {
return `encounter_${this.trainer?.getEncounterBgm()}`;
}
if (gScene.musicPreference === 0) {
if (globalScene.musicPreference === 0) {
return this.trainer?.getBattleBgm() ?? null;
} else {
return this.trainer?.getMixedBattleBgm() ?? null;
@ -237,7 +237,7 @@ export default class Battle {
return "battle_final_encounter";
}
if (pokemon.species.legendary || pokemon.species.subLegendary || pokemon.species.mythical) {
if (gScene.musicPreference === 0) {
if (globalScene.musicPreference === 0) {
if (pokemon.species.speciesId === Species.REGIROCK || pokemon.species.speciesId === Species.REGICE || pokemon.species.speciesId === Species.REGISTEEL || pokemon.species.speciesId === Species.REGIGIGAS || pokemon.species.speciesId === Species.REGIELEKI || pokemon.species.speciesId === Species.REGIDRAGO) {
return "battle_legendary_regis_g5";
}
@ -374,7 +374,7 @@ export default class Battle {
}
}
if (gScene.gameMode.isClassic && this.waveIndex <= 4) {
if (globalScene.gameMode.isClassic && this.waveIndex <= 4) {
return "battle_wild";
}
@ -391,8 +391,8 @@ export default class Battle {
if (range <= 1) {
return min;
}
const tempRngCounter = gScene.rngCounter;
const tempSeedOverride = gScene.rngSeedOverride;
const tempRngCounter = globalScene.rngCounter;
const tempSeedOverride = globalScene.rngSeedOverride;
const state = Phaser.Math.RND.state();
if (this.battleSeedState) {
Phaser.Math.RND.state(this.battleSeedState);
@ -400,13 +400,13 @@ export default class Battle {
Phaser.Math.RND.sow([ Utils.shiftCharCodes(this.battleSeed, this.turn << 6) ]);
console.log("Battle Seed:", this.battleSeed);
}
gScene.rngCounter = this.rngCounter++;
gScene.rngSeedOverride = this.battleSeed;
globalScene.rngCounter = this.rngCounter++;
globalScene.rngSeedOverride = this.battleSeed;
const ret = Utils.randSeedInt(range, min);
this.battleSeedState = Phaser.Math.RND.state();
Phaser.Math.RND.state(state);
gScene.rngCounter = tempRngCounter;
gScene.rngSeedOverride = tempSeedOverride;
globalScene.rngCounter = tempRngCounter;
globalScene.rngSeedOverride = tempSeedOverride;
return ret;
}
@ -420,7 +420,7 @@ export default class Battle {
export class FixedBattle extends Battle {
constructor(waveIndex: number, config: FixedBattleConfig) {
super(gScene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer() : undefined, config.double);
super(globalScene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer() : undefined, config.double);
if (config.getEnemyParty) {
this.enemyParty = config.getEnemyParty();
}
@ -482,7 +482,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand
const rand = Utils.randSeedInt(trainerPool.length);
const trainerTypes: TrainerType[] = [];
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
for (const trainerPoolEntry of trainerPool) {
const trainerType = Array.isArray(trainerPoolEntry)
? Utils.randSeedItem(trainerPoolEntry)
@ -524,14 +524,14 @@ export const classicFixedBattles: FixedBattleConfigs = {
[5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(() => new Trainer(TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[8]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL, gScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_2, gScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_2, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
[35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_3, gScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_3, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
[62]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
@ -540,7 +540,7 @@ export const classicFixedBattles: FixedBattleConfigs = {
[66]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true)),
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_4, gScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_4, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
[112]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
@ -550,7 +550,7 @@ export const classicFixedBattles: FixedBattleConfigs = {
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE, TrainerType.PENNY ]))
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_5, gScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_5, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
[ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2, TrainerType.PENNY_2 ]))
@ -566,6 +566,6 @@ export const classicFixedBattles: FixedBattleConfigs = {
[190]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN ])),
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_6, gScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_6, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false })
};

View File

@ -28,7 +28,7 @@ import { MovePhase } from "#app/phases/move-phase";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export class Ability implements Localizable {
public id: Abilities;
@ -217,7 +217,7 @@ export class PostBattleInitFormChangeAbAttr extends PostBattleInitAbAttr {
applyPostBattleInit(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex && !simulated) {
return gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
return globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return false;
@ -251,9 +251,9 @@ export class PostBattleInitStatStageChangeAbAttr extends PostBattleInitAbAttr {
for (const statStageChangePhase of statStageChangePhases) {
if (!this.selfTarget && !statStageChangePhase.getPokemon()?.summonData) {
gScene.pushPhase(statStageChangePhase);
globalScene.pushPhase(statStageChangePhase);
} else { // TODO: This causes the ability bar to be shown at the wrong time
gScene.unshiftPhase(statStageChangePhase);
globalScene.unshiftPhase(statStageChangePhase);
}
}
}
@ -438,7 +438,7 @@ export class TypeImmunityHealAbAttr extends TypeImmunityAbAttr {
if (ret) {
if (!pokemon.isFullHp() && !simulated) {
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
gScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
Utils.toDmgValue(pokemon.getMaxHp() / 4), i18next.t("abilityTriggers:typeImmunityHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true));
cancelled.value = true; // Suppresses "No Effect" message
}
@ -466,7 +466,7 @@ class TypeImmunityStatStageChangeAbAttr extends TypeImmunityAbAttr {
if (ret) {
cancelled.value = true; // Suppresses "No Effect" message
if (!simulated) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
}
}
@ -649,7 +649,7 @@ export class MoveImmunityStatStageChangeAbAttr extends MoveImmunityAbAttr {
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const ret = super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
if (ret && !simulated) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
}
return ret;
@ -676,7 +676,7 @@ export class ReverseDrainAbAttr extends PostDefendAbAttr {
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
if (move.hasAttr(HitHealAttr) && !move.hitsSubstitute(attacker, pokemon)) {
if (!simulated) {
gScene.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) }));
globalScene.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) }));
}
return true;
}
@ -710,11 +710,11 @@ export class PostDefendStatStageChangeAbAttr extends PostDefendAbAttr {
if (this.allOthers) {
const otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents();
for (const other of otherPokemon) {
gScene.unshiftPhase(new StatStageChangePhase((other).getBattlerIndex(), false, [ this.stat ], this.stages));
globalScene.unshiftPhase(new StatStageChangePhase((other).getBattlerIndex(), false, [ this.stat ], this.stages));
}
return true;
}
gScene.unshiftPhase(new StatStageChangePhase((this.selfTarget ? pokemon : attacker).getBattlerIndex(), this.selfTarget, [ this.stat ], this.stages));
globalScene.unshiftPhase(new StatStageChangePhase((this.selfTarget ? pokemon : attacker).getBattlerIndex(), this.selfTarget, [ this.stat ], this.stages));
return true;
}
@ -746,7 +746,7 @@ export class PostDefendHpGatedStatStageChangeAbAttr extends PostDefendAbAttr {
if (this.condition(pokemon, attacker, move) && (pokemon.hp <= hpGateFlat && (pokemon.hp + damageReceived) > hpGateFlat) && !move.hitsSubstitute(attacker, pokemon)) {
if (!simulated) {
gScene.unshiftPhase(new StatStageChangePhase((this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages));
globalScene.unshiftPhase(new StatStageChangePhase((this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages));
}
return true;
}
@ -768,10 +768,10 @@ export class PostDefendApplyArenaTrapTagAbAttr extends PostDefendAbAttr {
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
const tag = gScene.arena.getTag(this.tagType) as ArenaTrapTag;
if (!gScene.arena.getTag(this.tagType) || tag.layers < tag.maxLayers) {
const tag = globalScene.arena.getTag(this.tagType) as ArenaTrapTag;
if (!globalScene.arena.getTag(this.tagType) || tag.layers < tag.maxLayers) {
if (!simulated) {
gScene.arena.addTag(this.tagType, 0, undefined, pokemon.id, pokemon.isPlayer() ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER);
globalScene.arena.addTag(this.tagType, 0, undefined, pokemon.id, pokemon.isPlayer() ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER);
}
return true;
}
@ -794,7 +794,7 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr {
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
if (!pokemon.getTag(this.tagType) && !simulated) {
pokemon.addTag(this.tagType, undefined, undefined, pokemon.id);
gScene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }));
globalScene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }));
}
return true;
}
@ -840,9 +840,9 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr {
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean {
if (hitResult < HitResult.NO_EFFECT && !move.hitsSubstitute(attacker, pokemon)) {
if (simulated) {
return gScene.arena.terrain?.terrainType !== (this.terrainType || undefined);
return globalScene.arena.terrain?.terrainType !== (this.terrainType || undefined);
} else {
return gScene.arena.trySetTerrain(this.terrainType, true);
return globalScene.arena.trySetTerrain(this.terrainType, true);
}
}
@ -932,7 +932,7 @@ export class PostDefendCritStatStageChangeAbAttr extends PostDefendAbAttr {
}
if (!simulated) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
}
return true;
@ -1021,11 +1021,11 @@ export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
if (this.condition && !this.condition(pokemon, attacker, move) || move.hitsSubstitute(attacker, pokemon)) {
return false;
}
if (!gScene.arena.weather?.isImmutable()) {
if (!globalScene.arena.weather?.isImmutable()) {
if (simulated) {
return gScene.arena.weather?.weatherType !== this.weatherType;
return globalScene.arena.weather?.weatherType !== this.weatherType;
}
return gScene.arena.trySetWeather(this.weatherType, true);
return globalScene.arena.trySetWeather(this.weatherType, true);
}
return false;
@ -1129,7 +1129,7 @@ export class PostStatStageChangeStatStageChangeAbAttr extends PostStatStageChang
applyPostStatStageChange(pokemon: Pokemon, simulated: boolean, statStagesChanged: BattleStat[], stagesChanged: number, selfTarget: boolean, args: any[]): boolean {
if (this.condition(pokemon, statStagesChanged, stagesChanged) && !selfTarget) {
if (!simulated) {
gScene.unshiftPhase(new StatStageChangePhase((pokemon).getBattlerIndex(), true, this.statsToChange, this.stages));
globalScene.unshiftPhase(new StatStageChangePhase((pokemon).getBattlerIndex(), true, this.statsToChange, this.stages));
}
return true;
}
@ -1687,9 +1687,9 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
const heldItems = this.getTargetHeldItems(defender).filter(i => i.isTransferable);
if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
gScene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
globalScene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
if (success) {
gScene.queueMessage(i18next.t("abilityTriggers:postAttackStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), defenderName: defender.name, stolenItemType: stolenItem.type.name }));
globalScene.queueMessage(i18next.t("abilityTriggers:postAttackStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), defenderName: defender.name, stolenItemType: stolenItem.type.name }));
}
resolve(success);
});
@ -1701,7 +1701,7 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
}
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
return gScene.findModifiers(m => m instanceof PokemonHeldItemModifier
return globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier[];
}
}
@ -1780,9 +1780,9 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable);
if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
gScene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
globalScene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => {
if (success) {
gScene.queueMessage(i18next.t("abilityTriggers:postDefendStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), attackerName: attacker.name, stolenItemType: stolenItem.type.name }));
globalScene.queueMessage(i18next.t("abilityTriggers:postDefendStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), attackerName: attacker.name, stolenItemType: stolenItem.type.name }));
}
resolve(success);
});
@ -1794,7 +1794,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
}
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
return gScene.findModifiers(m => m instanceof PokemonHeldItemModifier
return globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& m.pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier[];
}
}
@ -1876,7 +1876,7 @@ class PostVictoryStatStageChangeAbAttr extends PostVictoryAbAttr {
? this.stat(pokemon)
: this.stat;
if (!simulated) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], this.stages));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], this.stages));
}
return true;
}
@ -1895,7 +1895,7 @@ export class PostVictoryFormChangeAbAttr extends PostVictoryAbAttr {
const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex) {
if (!simulated) {
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return true;
}
@ -1926,7 +1926,7 @@ export class PostKnockOutStatStageChangeAbAttr extends PostKnockOutAbAttr {
? this.stat(pokemon)
: this.stat;
if (!simulated) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], this.stages));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], this.stages));
}
return true;
}
@ -1941,7 +1941,7 @@ export class CopyFaintedAllyAbilityAbAttr extends PostKnockOutAbAttr {
if (pokemon.isPlayer() === knockedOut.isPlayer() && !knockedOut.getAbility().hasAttr(UncopiableAbilityAbAttr)) {
if (!simulated) {
pokemon.summonData.ability = knockedOut.getAbility().id;
gScene.queueMessage(i18next.t("abilityTriggers:copyFaintedAllyAbility", { pokemonNameWithAffix: getPokemonNameWithAffix(knockedOut), abilityName: allAbilities[knockedOut.getAbility().id].name }));
globalScene.queueMessage(i18next.t("abilityTriggers:copyFaintedAllyAbility", { pokemonNameWithAffix: getPokemonNameWithAffix(knockedOut), abilityName: allAbilities[knockedOut.getAbility().id].name }));
}
return true;
}
@ -2000,7 +2000,7 @@ export class PostIntimidateStatStageChangeAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, simulated:boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!simulated) {
gScene.pushPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, this.stats, this.stages));
globalScene.pushPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, this.stats, this.stages));
}
cancelled.value = this.overwrites;
return true;
@ -2042,7 +2042,7 @@ export class PostSummonRemoveArenaTagAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise<boolean> {
if (!simulated) {
for (const arenaTag of this.arenaTags) {
gScene.arena.removeTag(arenaTag);
globalScene.arena.removeTag(arenaTag);
}
}
return true;
@ -2060,7 +2060,7 @@ export class PostSummonMessageAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if (!simulated) {
gScene.queueMessage(this.messageFunc(pokemon));
globalScene.queueMessage(this.messageFunc(pokemon));
}
return true;
@ -2079,7 +2079,7 @@ export class PostSummonUnnamedMessageAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if (!simulated) {
gScene.queueMessage(this.message);
globalScene.queueMessage(this.message);
}
return true;
@ -2130,7 +2130,7 @@ export class PostSummonStatStageChangeAbAttr extends PostSummonAbAttr {
if (this.selfTarget) {
// we unshift the StatStageChangePhase to put it right after the showAbility and not at the end of the
// phase list (which could be after CommandPhase for example)
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
return true;
}
for (const opponent of pokemon.getOpponents()) {
@ -2144,7 +2144,7 @@ export class PostSummonStatStageChangeAbAttr extends PostSummonAbAttr {
}
}
if (!cancelled.value) {
gScene.unshiftPhase(new StatStageChangePhase(opponent.getBattlerIndex(), false, this.stats, this.stages));
globalScene.unshiftPhase(new StatStageChangePhase(opponent.getBattlerIndex(), false, this.stats, this.stages));
}
}
return true;
@ -2166,7 +2166,7 @@ export class PostSummonAllyHealAbAttr extends PostSummonAbAttr {
const target = pokemon.getAlly();
if (target?.isActive(true)) {
if (!simulated) {
gScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
Utils.toDmgValue(pokemon.getMaxHp() / this.healRatio), i18next.t("abilityTriggers:postSummonAllyHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(target), pokemonName: pokemon.name }), true, !this.showAnim));
}
@ -2198,7 +2198,7 @@ export class PostSummonClearAllyStatStagesAbAttr extends PostSummonAbAttr {
target.setStatStage(s, 0);
}
gScene.queueMessage(i18next.t("abilityTriggers:postSummonClearAllyStats", { pokemonNameWithAffix: getPokemonNameWithAffix(target) }));
globalScene.queueMessage(i18next.t("abilityTriggers:postSummonClearAllyStats", { pokemonNameWithAffix: getPokemonNameWithAffix(target) }));
}
return true;
@ -2250,7 +2250,7 @@ export class DownloadAbAttr extends PostSummonAbAttr {
if (this.enemyDef > 0 && this.enemySpDef > 0) { // only activate if there's actually an enemy to download from
if (!simulated) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, this.stats, 1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, this.stats, 1));
}
return true;
}
@ -2271,11 +2271,11 @@ export class PostSummonWeatherChangeAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if ((this.weatherType === WeatherType.HEAVY_RAIN ||
this.weatherType === WeatherType.HARSH_SUN ||
this.weatherType === WeatherType.STRONG_WINDS) || !gScene.arena.weather?.isImmutable()) {
this.weatherType === WeatherType.STRONG_WINDS) || !globalScene.arena.weather?.isImmutable()) {
if (simulated) {
return gScene.arena.weather?.weatherType !== this.weatherType;
return globalScene.arena.weather?.weatherType !== this.weatherType;
} else {
return gScene.arena.trySetWeather(this.weatherType, true);
return globalScene.arena.trySetWeather(this.weatherType, true);
}
}
@ -2294,9 +2294,9 @@ export class PostSummonTerrainChangeAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if (simulated) {
return gScene.arena.terrain?.terrainType !== this.terrainType;
return globalScene.arena.terrain?.terrainType !== this.terrainType;
} else {
return gScene.arena.trySetTerrain(this.terrainType, true);
return globalScene.arena.trySetTerrain(this.terrainType, true);
}
}
}
@ -2313,7 +2313,7 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex) {
return simulated || gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
return simulated || globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return false;
@ -2333,7 +2333,7 @@ export class PostSummonCopyAbilityAbAttr extends PostSummonAbAttr {
let target: Pokemon;
if (targets.length > 1) {
gScene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), gScene.currentBattle.waveIndex);
globalScene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), globalScene.currentBattle.waveIndex);
} else {
target = targets[0];
}
@ -2390,7 +2390,7 @@ export class PostSummonUserFieldRemoveStatusEffectAbAttr extends PostSummonAbAtt
* @returns A boolean or a promise that resolves to a boolean indicating the result of the ability application.
*/
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise<boolean> {
const party = pokemon instanceof PlayerPokemon ? gScene.getPlayerField() : gScene.getEnemyField();
const party = pokemon instanceof PlayerPokemon ? globalScene.getPlayerField() : globalScene.getEnemyField();
const allowedParty = party.filter(p => p.isAllowedInBattle());
if (allowedParty.length < 1) {
@ -2400,7 +2400,7 @@ export class PostSummonUserFieldRemoveStatusEffectAbAttr extends PostSummonAbAtt
if (!simulated) {
for (const pokemon of allowedParty) {
if (pokemon.status && this.statusEffect.includes(pokemon.status.effect)) {
gScene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
globalScene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
pokemon.resetStatus(false);
pokemon.updateInfo();
}
@ -2414,7 +2414,7 @@ export class PostSummonUserFieldRemoveStatusEffectAbAttr extends PostSummonAbAtt
/** Attempt to copy the stat changes on an ally pokemon */
export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if (!gScene.currentBattle.double) {
if (!globalScene.currentBattle.double) {
return false;
}
@ -2455,7 +2455,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
let target: Pokemon;
if (targets.length > 1) {
gScene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), gScene.currentBattle.waveIndex);
globalScene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), globalScene.currentBattle.waveIndex);
} else {
target = targets[0];
}
@ -2489,8 +2489,8 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
pokemon.summonData.types = target.getTypes();
promises.push(pokemon.updateInfo());
gScene.queueMessage(i18next.t("abilityTriggers:postSummonTransform", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), targetName: target.name, }));
gScene.playSound("battle_anims/PRSFX- Transform");
globalScene.queueMessage(i18next.t("abilityTriggers:postSummonTransform", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), targetName: target.name, }));
globalScene.playSound("battle_anims/PRSFX- Transform");
promises.push(pokemon.loadAssets(false).then(() => {
pokemon.playAnim();
pokemon.updateInfo();
@ -2523,7 +2523,7 @@ export class PostSummonWeatherSuppressedFormChangeAbAttr extends PostSummonAbAtt
}
if (!simulated) {
gScene.arena.triggerWeatherBasedFormChangesToNormal();
globalScene.arena.triggerWeatherBasedFormChangesToNormal();
}
return true;
@ -2563,8 +2563,8 @@ export class PostSummonFormChangeByWeatherAbAttr extends PostSummonAbAttr {
return simulated;
}
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeWeatherTrigger);
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeRevertWeatherFormTrigger);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeWeatherTrigger);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeRevertWeatherFormTrigger);
queueShowAbility(pokemon, passive);
return true;
}
@ -2609,26 +2609,26 @@ export class PreSwitchOutClearWeatherAbAttr extends PreSwitchOutAbAttr {
* @returns {boolean} Returns true if the weather clears, otherwise false.
*/
applyPreSwitchOut(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise<boolean> {
const weatherType = gScene.arena.weather?.weatherType;
const weatherType = globalScene.arena.weather?.weatherType;
let turnOffWeather = false;
// Clear weather only if user's ability matches the weather and no other pokemon has the ability.
switch (weatherType) {
case (WeatherType.HARSH_SUN):
if (pokemon.hasAbility(Abilities.DESOLATE_LAND)
&& gScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) {
&& globalScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) {
turnOffWeather = true;
}
break;
case (WeatherType.HEAVY_RAIN):
if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA)
&& gScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) {
&& globalScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) {
turnOffWeather = true;
}
break;
case (WeatherType.STRONG_WINDS):
if (pokemon.hasAbility(Abilities.DELTA_STREAM)
&& gScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) {
&& globalScene.getField(true).filter(p => p !== pokemon).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) {
turnOffWeather = true;
}
break;
@ -2639,7 +2639,7 @@ export class PreSwitchOutClearWeatherAbAttr extends PreSwitchOutAbAttr {
}
if (turnOffWeather) {
gScene.arena.trySetWeather(WeatherType.NONE, false);
globalScene.arena.trySetWeather(WeatherType.NONE, false);
return true;
}
@ -2688,7 +2688,7 @@ export class PreSwitchOutFormChangeAbAttr extends PreSwitchOutAbAttr {
const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex) {
if (!simulated) {
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return true;
}
@ -3120,13 +3120,13 @@ function getSheerForceHitDisableAbCondition(): AbAttrCondition {
function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
return () => {
if (!gScene?.arena) {
if (!globalScene?.arena) {
return false;
}
if (gScene.arena.weather?.isEffectSuppressed()) {
if (globalScene.arena.weather?.isEffectSuppressed()) {
return false;
}
const weatherType = gScene.arena.weather?.weatherType;
const weatherType = globalScene.arena.weather?.weatherType;
return !!weatherType && weatherTypes.indexOf(weatherType) > -1;
};
}
@ -3215,7 +3215,7 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
}
}
if (!simulated) {
gScene.queueMessage(i18next.t("abilityTriggers:forewarn", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: maxMove }));
globalScene.queueMessage(i18next.t("abilityTriggers:forewarn", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: maxMove }));
}
return true;
}
@ -3229,7 +3229,7 @@ export class FriskAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if (!simulated) {
for (const opponent of pokemon.getOpponents()) {
gScene.queueMessage(i18next.t("abilityTriggers:frisk", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), opponentName: opponent.name, opponentAbilityName: opponent.getAbility().name }));
globalScene.queueMessage(i18next.t("abilityTriggers:frisk", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), opponentName: opponent.name, opponentAbilityName: opponent.getAbility().name }));
setAbilityRevealed(opponent);
}
}
@ -3277,12 +3277,12 @@ export class PostWeatherChangeFormChangeAbAttr extends PostWeatherChangeAbAttr {
return simulated;
}
const weatherType = gScene.arena.weather?.weatherType;
const weatherType = globalScene.arena.weather?.weatherType;
if (weatherType && this.formRevertingWeathers.includes(weatherType)) {
gScene.arena.triggerWeatherBasedFormChangesToNormal();
globalScene.arena.triggerWeatherBasedFormChangesToNormal();
} else {
gScene.arena.triggerWeatherBasedFormChanges();
globalScene.arena.triggerWeatherBasedFormChanges();
}
return true;
}
@ -3348,7 +3348,7 @@ export class PostWeatherLapseHealAbAttr extends PostWeatherLapseAbAttr {
if (!pokemon.isFullHp()) {
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
if (!simulated) {
gScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
Utils.toDmgValue(pokemon.getMaxHp() / (16 / this.healFactor)), i18next.t("abilityTriggers:postWeatherLapseHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true));
}
return true;
@ -3374,7 +3374,7 @@ export class PostWeatherLapseDamageAbAttr extends PostWeatherLapseAbAttr {
if (!simulated) {
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
gScene.queueMessage(i18next.t("abilityTriggers:postWeatherLapseDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }));
globalScene.queueMessage(i18next.t("abilityTriggers:postWeatherLapseDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }));
pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / (16 / this.damageFactor)), HitResult.OTHER);
}
@ -3416,7 +3416,7 @@ export class PostTerrainChangeAddBattlerTagAttr extends PostTerrainChangeAbAttr
function getTerrainCondition(...terrainTypes: TerrainType[]): AbAttrCondition {
return (pokemon: Pokemon) => {
const terrainType = gScene.arena.terrain?.terrainType;
const terrainType = globalScene.arena.terrain?.terrainType;
return !!terrainType && terrainTypes.indexOf(terrainType) > -1;
};
}
@ -3453,7 +3453,7 @@ export class PostTurnStatusHealAbAttr extends PostTurnAbAttr {
if (!pokemon.isFullHp()) {
if (!simulated) {
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
gScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
Utils.toDmgValue(pokemon.getMaxHp() / 8), i18next.t("abilityTriggers:poisonHeal", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName }), true));
}
return true;
@ -3484,7 +3484,7 @@ export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
}
if (this.target?.status) {
if (!simulated) {
gScene.queueMessage(getStatusEffectHealText(this.target.status?.effect, getPokemonNameWithAffix(this.target)));
globalScene.queueMessage(getStatusEffectHealText(this.target.status?.effect, getPokemonNameWithAffix(this.target)));
this.target.resetStatus(false);
this.target.updateInfo();
}
@ -3549,7 +3549,7 @@ export class PostTurnLootAbAttr extends PostTurnAbAttr {
const chosenBerry = new BerryModifierType(chosenBerryType);
berriesEaten.splice(randomIdx); // Remove berry from memory
const berryModifier = gScene.findModifier(
const berryModifier = globalScene.findModifier(
(m) => m instanceof BerryModifier && m.berryType === chosenBerryType,
pokemon.isPlayer()
) as BerryModifier | undefined;
@ -3557,16 +3557,16 @@ export class PostTurnLootAbAttr extends PostTurnAbAttr {
if (!berryModifier) {
const newBerry = new BerryModifier(chosenBerry, pokemon.id, chosenBerryType, 1);
if (pokemon.isPlayer()) {
gScene.addModifier(newBerry);
globalScene.addModifier(newBerry);
} else {
gScene.addEnemyModifier(newBerry);
globalScene.addEnemyModifier(newBerry);
}
} else if (berryModifier.stackCount < berryModifier.getMaxHeldItemCount(pokemon)) {
berryModifier.stackCount++;
}
gScene.queueMessage(i18next.t("abilityTriggers:postTurnLootCreateEatenBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: chosenBerry.name }));
gScene.updateModifiers(pokemon.isPlayer());
globalScene.queueMessage(i18next.t("abilityTriggers:postTurnLootCreateEatenBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: chosenBerry.name }));
globalScene.updateModifiers(pokemon.isPlayer());
return true;
}
@ -3599,11 +3599,11 @@ export class MoodyAbAttr extends PostTurnAbAttr {
if (canRaise.length > 0) {
const raisedStat = canRaise[pokemon.randSeedInt(canRaise.length)];
canLower = canRaise.filter(s => s !== raisedStat);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ raisedStat ], 2));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ raisedStat ], 2));
}
if (canLower.length > 0) {
const loweredStat = canLower[pokemon.randSeedInt(canLower.length)];
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ loweredStat ], -1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ loweredStat ], -1));
}
}
@ -3620,7 +3620,7 @@ export class SpeedBoostAbAttr extends PostTurnAbAttr {
applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if (!simulated) {
if (!pokemon.turnData.switchedInThisTurn && !pokemon.turnData.failedRunAway) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPD ], 1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPD ], 1));
} else {
return false;
}
@ -3634,7 +3634,7 @@ export class PostTurnHealAbAttr extends PostTurnAbAttr {
if (!pokemon.isFullHp()) {
if (!simulated) {
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
gScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
Utils.toDmgValue(pokemon.getMaxHp() / 16), i18next.t("abilityTriggers:postTurnHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true));
}
@ -3658,7 +3658,7 @@ export class PostTurnFormChangeAbAttr extends PostTurnAbAttr {
const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex) {
if (!simulated) {
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return true;
@ -3688,7 +3688,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
if (!simulated) {
opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER);
gScene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) }));
globalScene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) }));
}
hadEffect = true;
}
@ -3718,11 +3718,11 @@ export class FetchBallAbAttr extends PostTurnAbAttr {
if (simulated) {
return false;
}
const lastUsed = gScene.currentBattle.lastUsedPokeball;
const lastUsed = globalScene.currentBattle.lastUsedPokeball;
if (lastUsed !== null && !!pokemon.isPlayer) {
gScene.pokeballCounts[lastUsed]++;
gScene.currentBattle.lastUsedPokeball = null;
gScene.queueMessage(i18next.t("abilityTriggers:fetchBall", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), pokeballName: getPokeballName(lastUsed) }));
globalScene.pokeballCounts[lastUsed]++;
globalScene.currentBattle.lastUsedPokeball = null;
globalScene.queueMessage(i18next.t("abilityTriggers:fetchBall", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), pokeballName: getPokeballName(lastUsed) }));
return true;
}
return false;
@ -3741,11 +3741,11 @@ export class PostBiomeChangeWeatherChangeAbAttr extends PostBiomeChangeAbAttr {
}
apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!gScene.arena.weather?.isImmutable()) {
if (!globalScene.arena.weather?.isImmutable()) {
if (simulated) {
return gScene.arena.weather?.weatherType !== this.weatherType;
return globalScene.arena.weather?.weatherType !== this.weatherType;
} else {
return gScene.arena.trySetWeather(this.weatherType, true);
return globalScene.arena.trySetWeather(this.weatherType, true);
}
}
@ -3764,9 +3764,9 @@ export class PostBiomeChangeTerrainChangeAbAttr extends PostBiomeChangeAbAttr {
apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (simulated) {
return gScene.arena.terrain?.terrainType !== this.terrainType;
return globalScene.arena.terrain?.terrainType !== this.terrainType;
} else {
return gScene.arena.trySetTerrain(this.terrainType, true);
return globalScene.arena.trySetTerrain(this.terrainType, true);
}
}
}
@ -3808,10 +3808,10 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
// If the move is an AttackMove or a StatusMove the Dancer must replicate the move on the source of the Dance
if (move.getMove() instanceof AttackMove || move.getMove() instanceof StatusMove) {
const target = this.getTarget(dancer, source, targets);
gScene.unshiftPhase(new MovePhase(dancer, target, move, true, true));
globalScene.unshiftPhase(new MovePhase(dancer, target, move, true, true));
} else if (move.getMove() instanceof SelfStatusMove) {
// If the move is a SelfStatusMove (ie. Swords Dance) the Dancer should replicate it on itself
gScene.unshiftPhase(new MovePhase(dancer, [ dancer.getBattlerIndex() ], move, true, true));
globalScene.unshiftPhase(new MovePhase(dancer, [ dancer.getBattlerIndex() ], move, true, true));
}
}
return true;
@ -3853,7 +3853,7 @@ export class StatStageChangeMultiplierAbAttr extends AbAttr {
export class StatStageChangeCopyAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
if (!simulated) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, (args[0] as BattleStat[]), (args[1] as number), true, false, false));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, (args[0] as BattleStat[]), (args[1] as number), true, false, false));
}
return true;
}
@ -3930,7 +3930,7 @@ export class HealFromBerryUseAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, simulated: boolean, ...args: [Utils.BooleanHolder, any[]]): boolean {
const { name: abilityName } = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
if (!simulated) {
gScene.unshiftPhase(
globalScene.unshiftPhase(
new PokemonHealPhase(
pokemon.getBattlerIndex(),
Utils.toDmgValue(pokemon.getMaxHp() * this.healPercent),
@ -4033,13 +4033,13 @@ export class PostBattleAbAttr extends AbAttr {
export class PostBattleLootAbAttr extends PostBattleAbAttr {
applyPostBattle(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
const postBattleLoot = gScene.currentBattle.postBattleLoot;
const postBattleLoot = globalScene.currentBattle.postBattleLoot;
if (!simulated && postBattleLoot.length) {
const randItem = Utils.randSeedItem(postBattleLoot);
//@ts-ignore - TODO see below
if (gScene.tryTransferHeldItemModifier(randItem, pokemon, true, 1, true)) { // TODO: fix. This is a promise!?
if (globalScene.tryTransferHeldItemModifier(randItem, pokemon, true, 1, true)) { // TODO: fix. This is a promise!?
postBattleLoot.splice(postBattleLoot.indexOf(randItem), 1);
gScene.queueMessage(i18next.t("abilityTriggers:postBattleLoot", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), itemName: randItem.type.name }));
globalScene.queueMessage(i18next.t("abilityTriggers:postBattleLoot", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), itemName: randItem.type.name }));
return true;
}
}
@ -4079,7 +4079,7 @@ export class PostFaintUnsuppressedWeatherFormChangeAbAttr extends PostFaintAbAtt
}
if (!simulated) {
gScene.arena.triggerWeatherBasedFormChanges();
globalScene.arena.triggerWeatherBasedFormChanges();
}
return true;
@ -4101,26 +4101,26 @@ export class PostFaintClearWeatherAbAttr extends PostFaintAbAttr {
* @returns {boolean} Returns true if the weather clears, otherwise false.
*/
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean {
const weatherType = gScene.arena.weather?.weatherType;
const weatherType = globalScene.arena.weather?.weatherType;
let turnOffWeather = false;
// Clear weather only if user's ability matches the weather and no other pokemon has the ability.
switch (weatherType) {
case (WeatherType.HARSH_SUN):
if (pokemon.hasAbility(Abilities.DESOLATE_LAND)
&& gScene.getField(true).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) {
&& globalScene.getField(true).filter(p => p.hasAbility(Abilities.DESOLATE_LAND)).length === 0) {
turnOffWeather = true;
}
break;
case (WeatherType.HEAVY_RAIN):
if (pokemon.hasAbility(Abilities.PRIMORDIAL_SEA)
&& gScene.getField(true).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) {
&& globalScene.getField(true).filter(p => p.hasAbility(Abilities.PRIMORDIAL_SEA)).length === 0) {
turnOffWeather = true;
}
break;
case (WeatherType.STRONG_WINDS):
if (pokemon.hasAbility(Abilities.DELTA_STREAM)
&& gScene.getField(true).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) {
&& globalScene.getField(true).filter(p => p.hasAbility(Abilities.DELTA_STREAM)).length === 0) {
turnOffWeather = true;
}
break;
@ -4131,7 +4131,7 @@ export class PostFaintClearWeatherAbAttr extends PostFaintAbAttr {
}
if (turnOffWeather) {
gScene.arena.trySetWeather(WeatherType.NONE, false);
globalScene.arena.trySetWeather(WeatherType.NONE, false);
return true;
}
@ -4151,7 +4151,7 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
applyPostFaint(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker?: Pokemon, move?: Move, hitResult?: HitResult, ...args: any[]): boolean {
if (move !== undefined && attacker !== undefined && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { //If the mon didn't die to indirect damage
const cancelled = new Utils.BooleanHolder(false);
gScene.getField(true).map(p => applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled, simulated));
globalScene.getField(true).map(p => applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled, simulated));
if (cancelled.value || attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
return false;
}
@ -4282,7 +4282,7 @@ export class FlinchStatStageChangeAbAttr extends FlinchEffectAbAttr {
apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!simulated) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, this.stats, this.stages));
}
return true;
}
@ -4500,7 +4500,7 @@ export class MoneyAbAttr extends PostBattleAbAttr {
*/
applyPostBattle(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if (!simulated) {
gScene.currentBattle.moneyScattered += gScene.getWaveMoneyAmount(0.2);
globalScene.currentBattle.moneyScattered += globalScene.getWaveMoneyAmount(0.2);
}
return true;
}
@ -4543,7 +4543,7 @@ export class PostSummonStatStageChangeOnArenaAbAttr extends PostSummonStatStageC
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
const side = pokemon.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
if (gScene.arena.getTagOnSide(this.tagType, side)) {
if (globalScene.arena.getTagOnSide(this.tagType, side)) {
return super.applyPostSummon(pokemon, passive, simulated, args);
}
return false;
@ -4641,7 +4641,7 @@ export class BypassSpeedChanceAbAttr extends AbAttr {
if (!bypassSpeed.value && pokemon.randSeedInt(100) < this.chance) {
const turnCommand =
gScene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
const isCommandFight = turnCommand?.command === Command.FIGHT;
const move = turnCommand?.move?.move ? allMoves[turnCommand.move.move] : null;
const isDamageMove = move?.category === MoveCategory.PHYSICAL || move?.category === MoveCategory.SPECIAL;
@ -4683,7 +4683,7 @@ export class PreventBypassSpeedChanceAbAttr extends AbAttr {
const bypassSpeed = args[0] as Utils.BooleanHolder;
const canCheckHeldItems = args[1] as Utils.BooleanHolder;
const turnCommand = gScene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
const turnCommand = globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
const isCommandFight = turnCommand?.command === Command.FIGHT;
const move = turnCommand?.move?.move ? allMoves[turnCommand.move.move] : null;
if (this.condition(pokemon, move!) && isCommandFight) {
@ -4708,7 +4708,7 @@ export class TerrainEventTypeChangeAbAttr extends PostSummonAbAttr {
if (pokemon.isTerastallized()) {
return false;
}
const currentTerrain = gScene.arena.getTerrainType();
const currentTerrain = globalScene.arena.getTerrainType();
const typeChange: Type[] = this.determineTypeChange(pokemon, currentTerrain);
if (typeChange.length !== 0) {
if (pokemon.summonData.addedType && typeChange.includes(pokemon.summonData.addedType)) {
@ -4755,14 +4755,14 @@ export class TerrainEventTypeChangeAbAttr extends PostSummonAbAttr {
* @returns `true` if there is an active terrain requiring a type change | `false` if not
*/
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean | Promise<boolean> {
if (gScene.arena.getTerrainType() !== TerrainType.NONE) {
if (globalScene.arena.getTerrainType() !== TerrainType.NONE) {
return this.apply(pokemon, passive, simulated, new Utils.BooleanHolder(false), []);
}
return false;
}
override getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) {
const currentTerrain = gScene.arena.getTerrainType();
const currentTerrain = globalScene.arena.getTerrainType();
const pokemonNameWithAffix = getPokemonNameWithAffix(pokemon);
if (currentTerrain === TerrainType.NONE) {
return i18next.t("abilityTriggers:pokemonTypeChangeRevert", { pokemonNameWithAffix });
@ -4794,7 +4794,7 @@ async function applyAbAttrsInternal<TAttr extends AbAttr>(
continue;
}
gScene.setPhaseQueueSplice();
globalScene.setPhaseQueueSplice();
let result = applyFunc(attr, passive);
// TODO Remove this when promises get reworked
@ -4810,7 +4810,7 @@ async function applyAbAttrsInternal<TAttr extends AbAttr>(
}
if (attr.showAbility && !simulated) {
if (showAbilityInstant) {
gScene.abilityBar.showAbility(pokemon, passive);
globalScene.abilityBar.showAbility(pokemon, passive);
} else {
queueShowAbility(pokemon, passive);
}
@ -4818,13 +4818,13 @@ async function applyAbAttrsInternal<TAttr extends AbAttr>(
const message = attr.getTriggerMessage(pokemon, ability.name, args);
if (message) {
if (!simulated) {
gScene.queueMessage(message);
globalScene.queueMessage(message);
}
}
messages.push(message!);
}
}
gScene.clearPhaseQueueSplice();
globalScene.clearPhaseQueueSplice();
}
}
@ -4967,8 +4967,8 @@ export function applyPostFaintAbAttrs(attrType: Constructor<PostFaintAbAttr>,
}
function queueShowAbility(pokemon: Pokemon, passive: boolean): void {
gScene.unshiftPhase(new ShowAbilityPhase(pokemon.id, passive));
gScene.clearPhaseQueueSplice();
globalScene.unshiftPhase(new ShowAbilityPhase(pokemon.id, passive));
globalScene.clearPhaseQueueSplice();
}
/**
@ -4986,7 +4986,7 @@ function setAbilityRevealed(pokemon: Pokemon): void {
* Returns the Pokemon with weather-based forms
*/
function getPokemonWithWeatherBasedForms() {
return gScene.getField(true).filter(p =>
return globalScene.getField(true).filter(p =>
(p.hasAbility(Abilities.FORECAST) && p.species.speciesId === Species.CASTFORM)
|| (p.hasAbility(Abilities.FLOWER_GIFT) && p.species.speciesId === Species.CHERRIM)
);
@ -5082,7 +5082,7 @@ export function initAbilities() {
.attr(UnswappableAbilityAbAttr)
.ignorable(),
new Ability(Abilities.LEVITATE, 3)
.attr(AttackTypeImmunityAbAttr, Type.GROUND, (pokemon: Pokemon) => !pokemon.getTag(GroundedTag) && !gScene.arena.getTag(ArenaTagType.GRAVITY))
.attr(AttackTypeImmunityAbAttr, Type.GROUND, (pokemon: Pokemon) => !pokemon.getTag(GroundedTag) && !globalScene.arena.getTag(ArenaTagType.GRAVITY))
.ignorable(),
new Ability(Abilities.EFFECT_SPORE, 3)
.attr(EffectSporeAbAttr),
@ -5174,10 +5174,10 @@ export function initAbilities() {
new Ability(Abilities.CUTE_CHARM, 3)
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
new Ability(Abilities.PLUS, 3)
.conditionalAttr(p => gScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
.ignorable(),
new Ability(Abilities.MINUS, 3)
.conditionalAttr(p => gScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
.ignorable(),
new Ability(Abilities.FORECAST, 3)
.attr(UncopiableAbilityAbAttr)
@ -5454,8 +5454,8 @@ export function initAbilities() {
.ignorable(),
new Ability(Abilities.ANALYTIC, 5)
.attr(MovePowerBoostAbAttr, (user, target, move) =>
!!target?.getLastXMoves(1).find(m => m.turn === gScene.currentBattle.turn)
|| gScene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command !== Command.FIGHT, 1.3),
!!target?.getLastXMoves(1).find(m => m.turn === globalScene.currentBattle.turn)
|| globalScene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command !== Command.FIGHT, 1.3),
new Ability(Abilities.ILLUSION, 5)
.attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr)
@ -5576,9 +5576,9 @@ export function initAbilities() {
.attr(FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 4 / 3),
new Ability(Abilities.AURA_BREAK, 6)
.ignorable()
.conditionalAttr(pokemon => gScene.getField(true).some(p => p.hasAbility(Abilities.DARK_AURA)), FieldMoveTypePowerBoostAbAttr, Type.DARK, 9 / 16)
.conditionalAttr(pokemon => gScene.getField(true).some(p => p.hasAbility(Abilities.FAIRY_AURA)), FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 9 / 16)
.conditionalAttr(pokemon => gScene.getField(true).some(p => p.hasAbility(Abilities.DARK_AURA) || p.hasAbility(Abilities.FAIRY_AURA)),
.conditionalAttr(pokemon => globalScene.getField(true).some(p => p.hasAbility(Abilities.DARK_AURA)), FieldMoveTypePowerBoostAbAttr, Type.DARK, 9 / 16)
.conditionalAttr(pokemon => globalScene.getField(true).some(p => p.hasAbility(Abilities.FAIRY_AURA)), FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 9 / 16)
.conditionalAttr(pokemon => globalScene.getField(true).some(p => p.hasAbility(Abilities.DARK_AURA) || p.hasAbility(Abilities.FAIRY_AURA)),
PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonAuraBreak", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })),
new Ability(Abilities.PRIMORDIAL_SEA, 6)
.attr(PostSummonWeatherChangeAbAttr, WeatherType.HEAVY_RAIN)
@ -5621,7 +5621,7 @@ export function initAbilities() {
.bypassFaint()
.partial(), // Meteor form should protect against status effects and yawn
new Ability(Abilities.STAKEOUT, 7)
.attr(MovePowerBoostAbAttr, (user, target, move) => gScene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command === Command.POKEMON, 2),
.attr(MovePowerBoostAbAttr, (user, target, move) => globalScene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command === Command.POKEMON, 2),
new Ability(Abilities.WATER_BUBBLE, 7)
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5)
.attr(MoveTypePowerBoostAbAttr, Type.WATER, 2)
@ -5992,7 +5992,7 @@ export function initAbilities() {
new Ability(Abilities.SHARPNESS, 9)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.SLICING_MOVE), 1.5),
new Ability(Abilities.SUPREME_OVERLORD, 9)
.attr(VariableMovePowerBoostAbAttr, (user, target, move) => 1 + 0.1 * Math.min(user.isPlayer() ? gScene.currentBattle.playerFaints : gScene.currentBattle.enemyFaints, 5))
.attr(VariableMovePowerBoostAbAttr, (user, target, move) => 1 + 0.1 * Math.min(user.isPlayer() ? globalScene.currentBattle.playerFaints : globalScene.currentBattle.enemyFaints, 5))
.partial(), // Counter resets every wave instead of on arena reset
new Ability(Abilities.COSTAR, 9)
.attr(PostSummonCopyAllyStatsAbAttr),

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { Arena } from "#app/field/arena";
import { Type } from "#app/data/type";
import { BooleanHolder, NumberHolder, toDmgValue } from "#app/utils";
@ -44,7 +44,7 @@ export abstract class ArenaTag {
onRemove(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
gScene.queueMessage(i18next.t(`arenaTag:arenaOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`, { moveName: this.getMoveName() }));
globalScene.queueMessage(i18next.t(`arenaTag:arenaOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`, { moveName: this.getMoveName() }));
}
}
@ -78,7 +78,7 @@ export abstract class ArenaTag {
* @returns The source {@linkcode Pokemon} or `null` if none is found
*/
public getSourcePokemon(): Pokemon | null {
return this.sourceId ? gScene.getPokemonById(this.sourceId) : null;
return this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
}
/**
@ -89,12 +89,12 @@ export abstract class ArenaTag {
public getAffectedPokemon(): Pokemon[] {
switch (this.side) {
case ArenaTagSide.PLAYER:
return gScene.getPlayerField() ?? [];
return globalScene.getPlayerField() ?? [];
case ArenaTagSide.ENEMY:
return gScene.getEnemyField() ?? [];
return globalScene.getEnemyField() ?? [];
case ArenaTagSide.BOTH:
default:
return gScene.getField(true) ?? [];
return globalScene.getField(true) ?? [];
}
}
}
@ -112,10 +112,10 @@ export class MistTag extends ArenaTag {
super.onAdd(arena);
if (this.sourceId) {
const source = gScene.getPokemonById(this.sourceId);
const source = globalScene.getPokemonById(this.sourceId);
if (!quiet && source) {
gScene.queueMessage(i18next.t("arenaTag:mistOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) }));
globalScene.queueMessage(i18next.t("arenaTag:mistOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) }));
} else if (!quiet) {
console.warn("Failed to get source for MistTag onAdd");
}
@ -146,7 +146,7 @@ export class MistTag extends ArenaTag {
cancelled.value = true;
if (!simulated) {
gScene.queueMessage(i18next.t("arenaTag:mistApply"));
globalScene.queueMessage(i18next.t("arenaTag:mistApply"));
}
return true;
@ -193,7 +193,7 @@ export class WeakenMoveScreenTag extends ArenaTag {
if (bypassed.value) {
return false;
}
damageMultiplier.value = gScene.currentBattle.double ? 2732 / 4096 : 0.5;
damageMultiplier.value = globalScene.currentBattle.double ? 2732 / 4096 : 0.5;
return true;
}
return false;
@ -211,7 +211,7 @@ class ReflectTag extends WeakenMoveScreenTag {
onAdd(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
gScene.queueMessage(i18next.t(`arenaTag:reflectOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:reflectOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
}
}
@ -227,7 +227,7 @@ class LightScreenTag extends WeakenMoveScreenTag {
onAdd(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
gScene.queueMessage(i18next.t(`arenaTag:lightScreenOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:lightScreenOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
}
}
@ -243,7 +243,7 @@ class AuroraVeilTag extends WeakenMoveScreenTag {
onAdd(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
gScene.queueMessage(i18next.t(`arenaTag:auroraVeilOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:auroraVeilOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
}
}
@ -268,7 +268,7 @@ export class ConditionalProtectTag extends ArenaTag {
}
onAdd(arena: Arena): void {
gScene.queueMessage(i18next.t(`arenaTag:conditionalProtectOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`, { moveName: super.getMoveName() }));
globalScene.queueMessage(i18next.t(`arenaTag:conditionalProtectOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`, { moveName: super.getMoveName() }));
}
// Removes default message for effect removal
@ -297,7 +297,7 @@ export class ConditionalProtectTag extends ArenaTag {
attacker.stopMultiHit(defender);
new CommonBattleAnim(CommonAnim.PROTECT, defender).play();
gScene.queueMessage(i18next.t("arenaTag:conditionalProtectApply", { moveName: super.getMoveName(), pokemonNameWithAffix: getPokemonNameWithAffix(defender) }));
globalScene.queueMessage(i18next.t("arenaTag:conditionalProtectApply", { moveName: super.getMoveName(), pokemonNameWithAffix: getPokemonNameWithAffix(defender) }));
}
}
@ -319,7 +319,7 @@ export class ConditionalProtectTag extends ArenaTag {
const QuickGuardConditionFunc: ProtectConditionFunc = (arena, moveId) => {
const move = allMoves[moveId];
const priority = new NumberHolder(move.priority);
const effectPhase = gScene.getCurrentPhase();
const effectPhase = globalScene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase) {
const attacker = effectPhase.getUserPokemon()!;
@ -393,9 +393,9 @@ class MatBlockTag extends ConditionalProtectTag {
onAdd(arena: Arena) {
if (this.sourceId) {
const source = gScene.getPokemonById(this.sourceId);
const source = globalScene.getPokemonById(this.sourceId);
if (source) {
gScene.queueMessage(i18next.t("arenaTag:matBlockOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) }));
globalScene.queueMessage(i18next.t("arenaTag:matBlockOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) }));
} else {
console.warn("Failed to get source for MatBlockTag onAdd");
}
@ -448,15 +448,15 @@ export class NoCritTag extends ArenaTag {
/** Queues a message upon adding this effect to the field */
onAdd(arena: Arena): void {
gScene.queueMessage(i18next.t(`arenaTag:noCritOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : "Enemy"}`, {
globalScene.queueMessage(i18next.t(`arenaTag:noCritOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : "Enemy"}`, {
moveName: this.getMoveName()
}));
}
/** Queues a message upon removing this effect from the field */
onRemove(arena: Arena): void {
const source = gScene.getPokemonById(this.sourceId!); // TODO: is this bang correct?
gScene.queueMessage(i18next.t("arenaTag:noCritOnRemove", {
const source = globalScene.getPokemonById(this.sourceId!); // TODO: is this bang correct?
globalScene.queueMessage(i18next.t("arenaTag:noCritOnRemove", {
pokemonNameWithAffix: getPokemonNameWithAffix(source ?? undefined),
moveName: this.getMoveName()
}));
@ -478,7 +478,7 @@ class WishTag extends ArenaTag {
onAdd(arena: Arena): void {
if (this.sourceId) {
const user = gScene.getPokemonById(this.sourceId);
const user = globalScene.getPokemonById(this.sourceId);
if (user) {
this.battlerIndex = user.getBattlerIndex();
this.triggerMessage = i18next.t("arenaTag:wishTagOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(user) });
@ -490,10 +490,10 @@ class WishTag extends ArenaTag {
}
onRemove(arena: Arena): void {
const target = gScene.getField()[this.battlerIndex];
const target = globalScene.getField()[this.battlerIndex];
if (target?.isActive(true)) {
gScene.queueMessage(this.triggerMessage);
gScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(), this.healHp, null, true, false));
globalScene.queueMessage(this.triggerMessage);
globalScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(), this.healHp, null, true, false));
}
}
}
@ -546,11 +546,11 @@ class MudSportTag extends WeakenMoveTypeTag {
}
onAdd(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:mudSportOnAdd"));
globalScene.queueMessage(i18next.t("arenaTag:mudSportOnAdd"));
}
onRemove(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:mudSportOnRemove"));
globalScene.queueMessage(i18next.t("arenaTag:mudSportOnRemove"));
}
}
@ -564,11 +564,11 @@ class WaterSportTag extends WeakenMoveTypeTag {
}
onAdd(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:waterSportOnAdd"));
globalScene.queueMessage(i18next.t("arenaTag:waterSportOnAdd"));
}
onRemove(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:waterSportOnRemove"));
globalScene.queueMessage(i18next.t("arenaTag:waterSportOnRemove"));
}
}
@ -584,7 +584,7 @@ export class IonDelugeTag extends ArenaTag {
/** Queues an on-add message */
onAdd(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd"));
globalScene.queueMessage(i18next.t("arenaTag:plasmaFistsOnAdd"));
}
onRemove(arena: Arena): void { } // Removes default on-remove message
@ -679,9 +679,9 @@ class SpikesTag extends ArenaTrapTag {
onAdd(arena: Arena, quiet: boolean = false): void {
super.onAdd(arena);
const source = this.sourceId ? gScene.getPokemonById(this.sourceId) : null;
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
if (!quiet && source) {
gScene.queueMessage(i18next.t("arenaTag:spikesOnAdd", { moveName: this.getMoveName(), opponentDesc: source.getOpponentDescriptor() }));
globalScene.queueMessage(i18next.t("arenaTag:spikesOnAdd", { moveName: this.getMoveName(), opponentDesc: source.getOpponentDescriptor() }));
}
}
@ -698,7 +698,7 @@ class SpikesTag extends ArenaTrapTag {
const damageHpRatio = 1 / (10 - 2 * this.layers);
const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio);
gScene.queueMessage(i18next.t("arenaTag:spikesActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("arenaTag:spikesActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
pokemon.damageAndUpdate(damage, HitResult.OTHER);
if (pokemon.turnData) {
pokemon.turnData.damageTaken += damage;
@ -728,9 +728,9 @@ class ToxicSpikesTag extends ArenaTrapTag {
onAdd(arena: Arena, quiet: boolean = false): void {
super.onAdd(arena);
const source = this.sourceId ? gScene.getPokemonById(this.sourceId) : null;
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
if (!quiet && source) {
gScene.queueMessage(i18next.t("arenaTag:toxicSpikesOnAdd", { moveName: this.getMoveName(), opponentDesc: source.getOpponentDescriptor() }));
globalScene.queueMessage(i18next.t("arenaTag:toxicSpikesOnAdd", { moveName: this.getMoveName(), opponentDesc: source.getOpponentDescriptor() }));
}
}
@ -747,8 +747,8 @@ class ToxicSpikesTag extends ArenaTrapTag {
}
if (pokemon.isOfType(Type.POISON)) {
this.neutralized = true;
if (gScene.arena.removeTag(this.tagType)) {
gScene.queueMessage(i18next.t("arenaTag:toxicSpikesActivateTrapPoison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: this.getMoveName() }));
if (globalScene.arena.removeTag(this.tagType)) {
globalScene.queueMessage(i18next.t("arenaTag:toxicSpikesActivateTrapPoison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: this.getMoveName() }));
return true;
}
} else if (!pokemon.status) {
@ -791,7 +791,7 @@ class DelayedAttackTag extends ArenaTag {
const ret = super.lapse(arena);
if (!ret) {
gScene.unshiftPhase(new MoveEffectPhase(this.sourceId!, [ this.targetIndex ], new PokemonMove(this.sourceMove!, 0, 0, true))); // TODO: are those bangs correct?
globalScene.unshiftPhase(new MoveEffectPhase(this.sourceId!, [ this.targetIndex ], new PokemonMove(this.sourceMove!, 0, 0, true))); // TODO: are those bangs correct?
}
return ret;
@ -813,9 +813,9 @@ class StealthRockTag extends ArenaTrapTag {
onAdd(arena: Arena, quiet: boolean = false): void {
super.onAdd(arena);
const source = this.sourceId ? gScene.getPokemonById(this.sourceId) : null;
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
if (!quiet && source) {
gScene.queueMessage(i18next.t("arenaTag:stealthRockOnAdd", { opponentDesc: source.getOpponentDescriptor() }));
globalScene.queueMessage(i18next.t("arenaTag:stealthRockOnAdd", { opponentDesc: source.getOpponentDescriptor() }));
}
}
@ -863,7 +863,7 @@ class StealthRockTag extends ArenaTrapTag {
return true;
}
const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio);
gScene.queueMessage(i18next.t("arenaTag:stealthRockActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("arenaTag:stealthRockActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
pokemon.damageAndUpdate(damage, HitResult.OTHER);
if (pokemon.turnData) {
pokemon.turnData.damageTaken += damage;
@ -892,9 +892,9 @@ class StickyWebTag extends ArenaTrapTag {
onAdd(arena: Arena, quiet: boolean = false): void {
super.onAdd(arena);
const source = this.sourceId ? gScene.getPokemonById(this.sourceId) : null;
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
if (!quiet && source) {
gScene.queueMessage(i18next.t("arenaTag:stickyWebOnAdd", { moveName: this.getMoveName(), opponentDesc: source.getOpponentDescriptor() }));
globalScene.queueMessage(i18next.t("arenaTag:stickyWebOnAdd", { moveName: this.getMoveName(), opponentDesc: source.getOpponentDescriptor() }));
}
}
@ -908,9 +908,9 @@ class StickyWebTag extends ArenaTrapTag {
}
if (!cancelled.value) {
gScene.queueMessage(i18next.t("arenaTag:stickyWebActivateTrap", { pokemonName: pokemon.getNameToRender() }));
globalScene.queueMessage(i18next.t("arenaTag:stickyWebActivateTrap", { pokemonName: pokemon.getNameToRender() }));
const stages = new NumberHolder(-1);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, [ Stat.SPD ], stages.value));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, [ Stat.SPD ], stages.value));
return true;
}
}
@ -944,14 +944,14 @@ export class TrickRoomTag extends ArenaTag {
}
onAdd(arena: Arena): void {
const source = this.sourceId ? gScene.getPokemonById(this.sourceId) : null;
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
if (source) {
gScene.queueMessage(i18next.t("arenaTag:trickRoomOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) }));
globalScene.queueMessage(i18next.t("arenaTag:trickRoomOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) }));
}
}
onRemove(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:trickRoomOnRemove"));
globalScene.queueMessage(i18next.t("arenaTag:trickRoomOnRemove"));
}
}
@ -966,8 +966,8 @@ export class GravityTag extends ArenaTag {
}
onAdd(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:gravityOnAdd"));
gScene.getField(true).forEach((pokemon) => {
globalScene.queueMessage(i18next.t("arenaTag:gravityOnAdd"));
globalScene.getField(true).forEach((pokemon) => {
if (pokemon !== null) {
pokemon.removeTag(BattlerTagType.FLOATING);
pokemon.removeTag(BattlerTagType.TELEKINESIS);
@ -979,7 +979,7 @@ export class GravityTag extends ArenaTag {
}
onRemove(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:gravityOnRemove"));
globalScene.queueMessage(i18next.t("arenaTag:gravityOnRemove"));
}
}
@ -995,29 +995,29 @@ class TailwindTag extends ArenaTag {
onAdd(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
gScene.queueMessage(i18next.t(`arenaTag:tailwindOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:tailwindOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
const source = gScene.getPokemonById(this.sourceId!); //TODO: this bang is questionable!
const party = (source?.isPlayer() ? gScene.getPlayerField() : gScene.getEnemyField()) ?? [];
const source = globalScene.getPokemonById(this.sourceId!); //TODO: this bang is questionable!
const party = (source?.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField()) ?? [];
for (const pokemon of party) {
// Apply the CHARGED tag to party members with the WIND_POWER ability
if (pokemon.hasAbility(Abilities.WIND_POWER) && !pokemon.getTag(BattlerTagType.CHARGED)) {
pokemon.addTag(BattlerTagType.CHARGED);
gScene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: this.getMoveName() }));
globalScene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: this.getMoveName() }));
}
// Raise attack by one stage if party member has WIND_RIDER ability
if (pokemon.hasAbility(Abilities.WIND_RIDER)) {
gScene.unshiftPhase(new ShowAbilityPhase(pokemon.getBattlerIndex()));
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.ATK ], 1, true));
globalScene.unshiftPhase(new ShowAbilityPhase(pokemon.getBattlerIndex()));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.ATK ], 1, true));
}
}
}
onRemove(arena: Arena, quiet: boolean = false): void {
if (!quiet) {
gScene.queueMessage(i18next.t(`arenaTag:tailwindOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:tailwindOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
}
}
@ -1032,11 +1032,11 @@ class HappyHourTag extends ArenaTag {
}
onAdd(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:happyHourOnAdd"));
globalScene.queueMessage(i18next.t("arenaTag:happyHourOnAdd"));
}
onRemove(arena: Arena): void {
gScene.queueMessage(i18next.t("arenaTag:happyHourOnRemove"));
globalScene.queueMessage(i18next.t("arenaTag:happyHourOnRemove"));
}
}
@ -1046,11 +1046,11 @@ class SafeguardTag extends ArenaTag {
}
onAdd(arena: Arena): void {
gScene.queueMessage(i18next.t(`arenaTag:safeguardOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:safeguardOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
onRemove(arena: Arena): void {
gScene.queueMessage(i18next.t(`arenaTag:safeguardOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:safeguardOnRemove${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
}
@ -1082,7 +1082,7 @@ class ImprisonTag extends ArenaTrapTag {
p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId);
}
});
gScene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) }));
globalScene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) }));
}
}
@ -1135,19 +1135,19 @@ class FireGrassPledgeTag extends ArenaTag {
override onAdd(arena: Arena): void {
// "A sea of fire enveloped your/the opposing team!"
gScene.queueMessage(i18next.t(`arenaTag:fireGrassPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:fireGrassPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
override lapse(arena: Arena): boolean {
const field: Pokemon[] = (this.side === ArenaTagSide.PLAYER)
? gScene.getPlayerField()
: gScene.getEnemyField();
? globalScene.getPlayerField()
: globalScene.getEnemyField();
field.filter(pokemon => !pokemon.isOfType(Type.FIRE)).forEach(pokemon => {
// "{pokemonNameWithAffix} was hurt by the sea of fire!"
gScene.queueMessage(i18next.t("arenaTag:fireGrassPledgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("arenaTag:fireGrassPledgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
// TODO: Replace this with a proper animation
gScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.MAGMA_STORM));
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.MAGMA_STORM));
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8));
});
@ -1169,7 +1169,7 @@ class WaterFirePledgeTag extends ArenaTag {
override onAdd(arena: Arena): void {
// "A rainbow appeared in the sky on your/the opposing team's side!"
gScene.queueMessage(i18next.t(`arenaTag:waterFirePledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:waterFirePledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
/**
@ -1199,7 +1199,7 @@ class GrassWaterPledgeTag extends ArenaTag {
override onAdd(arena: Arena): void {
// "A swamp enveloped your/the opposing team!"
gScene.queueMessage(i18next.t(`arenaTag:grassWaterPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
globalScene.queueMessage(i18next.t(`arenaTag:grassWaterPledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`));
}
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { Gender } from "#app/data/gender";
import { PokeballType } from "#app/data/pokeball";
import Pokemon from "#app/field/pokemon";
@ -267,8 +267,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.ELECTRODE, 30, null, null)
],
[Species.CUBONE]: [
new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.MAROWAK, 28, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.MAROWAK, 28, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.TYROGUE]: [
/**
@ -288,8 +288,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
)),
],
[Species.KOFFING]: [
new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.WEEZING, 35, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.WEEZING, 35, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.RHYHORN]: [
new SpeciesEvolution(Species.RHYDON, 42, null, null)
@ -334,8 +334,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.QUILAVA, 14, null, null)
],
[Species.QUILAVA]: [
new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.TOTODILE]: [
new SpeciesEvolution(Species.CROCONAW, 18, null, null)
@ -437,8 +437,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.LINOONE, 20, null, null)
],
[Species.WURMPLE]: [
new SpeciesEvolution(Species.SILCOON, 7, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY)),
new SpeciesEvolution(Species.CASCOON, 7, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
new SpeciesEvolution(Species.SILCOON, 7, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)),
new SpeciesEvolution(Species.CASCOON, 7, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
],
[Species.SILCOON]: [
new SpeciesEvolution(Species.BEAUTIFLY, 10, null, null)
@ -479,7 +479,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
],
[Species.NINCADA]: [
new SpeciesEvolution(Species.NINJASK, 20, null, null),
new SpeciesEvolution(Species.SHEDINJA, 20, null, new SpeciesEvolutionCondition(p => gScene.getParty().length < 6 && gScene.pokeballCounts[PokeballType.POKEBALL] > 0))
new SpeciesEvolution(Species.SHEDINJA, 20, null, new SpeciesEvolutionCondition(p => globalScene.getParty().length < 6 && globalScene.pokeballCounts[PokeballType.POKEBALL] > 0))
],
[Species.WHISMUR]: [
new SpeciesEvolution(Species.LOUDRED, 20, null, null)
@ -661,7 +661,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.LUMINEON, 31, null, null)
],
[Species.MANTYKE]: [
new SpeciesEvolution(Species.MANTINE, 32, null, new SpeciesEvolutionCondition(p => !!gScene.gameData.dexData[Species.REMORAID].caughtAttr), SpeciesWildEvolutionDelay.MEDIUM)
new SpeciesEvolution(Species.MANTINE, 32, null, new SpeciesEvolutionCondition(p => !!globalScene.gameData.dexData[Species.REMORAID].caughtAttr), SpeciesWildEvolutionDelay.MEDIUM)
],
[Species.SNOVER]: [
new SpeciesEvolution(Species.ABOMASNOW, 40, null, null)
@ -682,8 +682,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DEWOTT, 17, null, null)
],
[Species.DEWOTT]: [
new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.PATRAT]: [
new SpeciesEvolution(Species.WATCHOG, 20, null, null)
@ -833,8 +833,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.KINGAMBIT, 1, EvolutionItem.LEADERS_CREST, null, SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.RUFFLET]: [
new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.VULLABY]: [
new SpeciesEvolution(Species.MANDIBUZZ, 54, null, null)
@ -891,7 +891,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.GOGOAT, 32, null, null)
],
[Species.PANCHAM]: [
new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!gScene.getParty().find(p => p.getTypes(false, false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM)
new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!globalScene.getParty().find(p => p.getTypes(false, false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM)
],
[Species.ESPURR]: [
new SpeciesFormEvolution(Species.MEOWSTIC, "", "female", 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)),
@ -913,21 +913,21 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CLAWITZER, 37, null, null)
],
[Species.TYRUNT]: [
new SpeciesEvolution(Species.TYRANTRUM, 39, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.TYRANTRUM, 39, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.AMAURA]: [
new SpeciesEvolution(Species.AURORUS, 39, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
new SpeciesEvolution(Species.AURORUS, 39, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
],
[Species.GOOMY]: [
new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.SLIGGOO]: [
new SpeciesEvolution(Species.GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(gScene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG)
new SpeciesEvolution(Species.GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(globalScene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG)
],
[Species.BERGMITE]: [
new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.AVALUGG, 37, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.AVALUGG, 37, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.NOIBAT]: [
new SpeciesEvolution(Species.NOIVERN, 48, null, null)
@ -936,8 +936,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DARTRIX, 17, null, null)
],
[Species.DARTRIX]: [
new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.DECIDUEYE, 34, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
new SpeciesEvolution(Species.DECIDUEYE, 34, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.LITTEN]: [
new SpeciesEvolution(Species.TORRACAT, 17, null, null)
@ -958,7 +958,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.TOUCANNON, 28, null, null)
],
[Species.YUNGOOS]: [
new SpeciesEvolution(Species.GUMSHOOS, 20, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.GUMSHOOS, 20, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.GRUBBIN]: [
new SpeciesEvolution(Species.CHARJABUG, 20, null, null)
@ -976,7 +976,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.ARAQUANID, 22, null, null)
],
[Species.FOMANTIS]: [
new SpeciesEvolution(Species.LURANTIS, 34, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY))
new SpeciesEvolution(Species.LURANTIS, 34, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
],
[Species.MORELULL]: [
new SpeciesEvolution(Species.SHIINOTIC, 24, null, null)
@ -1013,7 +1013,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.MELMETAL, 48, null, null)
],
[Species.ALOLA_RATTATA]: [
new SpeciesEvolution(Species.ALOLA_RATICATE, 20, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
new SpeciesEvolution(Species.ALOLA_RATICATE, 20, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
],
[Species.ALOLA_DIGLETT]: [
new SpeciesEvolution(Species.ALOLA_DUGTRIO, 26, null, null)
@ -1136,7 +1136,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.GALAR_LINOONE, 20, null, null)
],
[Species.GALAR_LINOONE]: [
new SpeciesEvolution(Species.OBSTAGOON, 35, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
new SpeciesEvolution(Species.OBSTAGOON, 35, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
],
[Species.GALAR_YAMASK]: [
new SpeciesEvolution(Species.RUNERIGUS, 34, null, null)
@ -1145,7 +1145,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.HISUI_ZOROARK, 30, null, null)
],
[Species.HISUI_SLIGGOO]: [
new SpeciesEvolution(Species.HISUI_GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(gScene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG)
new SpeciesEvolution(Species.HISUI_GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(globalScene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG)
],
[Species.SPRIGATITO]: [
new SpeciesEvolution(Species.FLORAGATO, 16, null, null)
@ -1184,7 +1184,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
[Species.TANDEMAUS]: [
new SpeciesFormEvolution(Species.MAUSHOLD, "", "three", 25, null, new SpeciesEvolutionCondition(p => {
let ret = false;
gScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
return ret;
})),
new SpeciesEvolution(Species.MAUSHOLD, 25, null, null)
@ -1244,7 +1244,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.GLIMMORA, 35, null, null)
],
[Species.GREAVARD]: [
new SpeciesEvolution(Species.HOUNDSTONE, 30, null, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
new SpeciesEvolution(Species.HOUNDSTONE, 30, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
],
[Species.FRIGIBAX]: [
new SpeciesEvolution(Species.ARCTIBAX, 35, null, null)
@ -1312,10 +1312,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
[Species.EEVEE]: [
new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.SYLVEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => gScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => gScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.UMBREON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.UMBREON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.VAPOREON, "", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.VAPOREON, "partner", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.JOLTEON, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG),
@ -1352,17 +1352,17 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new SpeciesEvolutionCondition(p => {
let ret = false;
if (p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0) {
gScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
}
return ret;
}), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0), SpeciesWildEvolutionDelay.LONG)
],
[Species.GLIGAR]: [
new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.VERY_LONG)
new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.SNEASEL]: [
new SpeciesEvolution(Species.WEAVILE, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor claw at night*/), SpeciesWildEvolutionDelay.VERY_LONG)
new SpeciesEvolution(Species.WEAVILE, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor claw at night*/), SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.URSARING]: [
new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna
@ -1392,8 +1392,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.SUDOWOODO, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM)
],
[Species.MIME_JR]: [
new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), SpeciesWildEvolutionDelay.MEDIUM),
new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY)), SpeciesWildEvolutionDelay.MEDIUM)
new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), SpeciesWildEvolutionDelay.MEDIUM),
new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)), SpeciesWildEvolutionDelay.MEDIUM)
],
[Species.PANSAGE]: [
new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1443,9 +1443,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CRABOMINABLE, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
],
[Species.ROCKRUFF]: [
new SpeciesFormEvolution(Species.LYCANROC, "", "midday", 25, null, new SpeciesEvolutionCondition(p => (gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY) && (p.formIndex === 0))),
new SpeciesFormEvolution(Species.LYCANROC, "", "midday", 25, null, new SpeciesEvolutionCondition(p => (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY) && (p.formIndex === 0))),
new SpeciesFormEvolution(Species.LYCANROC, "own-tempo", "dusk", 25, null, new SpeciesEvolutionCondition(p => p.formIndex === 1)),
new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new SpeciesEvolutionCondition(p => (gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)))
new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new SpeciesEvolutionCondition(p => (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)))
],
[Species.STEENEE]: [
new SpeciesEvolution(Species.TSAREENA, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.STOMP).length > 0), SpeciesWildEvolutionDelay.LONG)
@ -1472,15 +1472,15 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesFormEvolution(Species.POLTEAGEIST, "antique", "antique", 1, EvolutionItem.CHIPPED_POT, null, SpeciesWildEvolutionDelay.LONG)
],
[Species.MILCERY]: [
new SpeciesFormEvolution(Species.ALCREMIE, "", "vanilla-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => gScene.arena.biomeType === Biome.TOWN || gScene.arena.biomeType === Biome.PLAINS || gScene.arena.biomeType === Biome.GRASS || gScene.arena.biomeType === Biome.TALL_GRASS || gScene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => gScene.arena.biomeType === Biome.BADLANDS || gScene.arena.biomeType === Biome.VOLCANO || gScene.arena.biomeType === Biome.GRAVEYARD || gScene.arena.biomeType === Biome.FACTORY || gScene.arena.biomeType === Biome.SLUM), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "matcha-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => gScene.arena.biomeType === Biome.FOREST || gScene.arena.biomeType === Biome.SWAMP || gScene.arena.biomeType === Biome.MEADOW || gScene.arena.biomeType === Biome.JUNGLE), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "mint-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => gScene.arena.biomeType === Biome.SEA || gScene.arena.biomeType === Biome.BEACH || gScene.arena.biomeType === Biome.LAKE || gScene.arena.biomeType === Biome.SEABED), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "lemon-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => gScene.arena.biomeType === Biome.DESERT || gScene.arena.biomeType === Biome.POWER_PLANT || gScene.arena.biomeType === Biome.DOJO || gScene.arena.biomeType === Biome.RUINS || gScene.arena.biomeType === Biome.CONSTRUCTION_SITE), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "salted-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => gScene.arena.biomeType === Biome.MOUNTAIN || gScene.arena.biomeType === Biome.CAVE || gScene.arena.biomeType === Biome.ICE_CAVE || gScene.arena.biomeType === Biome.FAIRY_CAVE || gScene.arena.biomeType === Biome.SNOWY_FOREST), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => gScene.arena.biomeType === Biome.WASTELAND || gScene.arena.biomeType === Biome.LABORATORY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "caramel-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => gScene.arena.biomeType === Biome.TEMPLE || gScene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "rainbow-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => gScene.arena.biomeType === Biome.ABYSS || gScene.arena.biomeType === Biome.SPACE || gScene.arena.biomeType === Biome.END), SpeciesWildEvolutionDelay.LONG)
new SpeciesFormEvolution(Species.ALCREMIE, "", "vanilla-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.TOWN || globalScene.arena.biomeType === Biome.PLAINS || globalScene.arena.biomeType === Biome.GRASS || globalScene.arena.biomeType === Biome.TALL_GRASS || globalScene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.BADLANDS || globalScene.arena.biomeType === Biome.VOLCANO || globalScene.arena.biomeType === Biome.GRAVEYARD || globalScene.arena.biomeType === Biome.FACTORY || globalScene.arena.biomeType === Biome.SLUM), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "matcha-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.FOREST || globalScene.arena.biomeType === Biome.SWAMP || globalScene.arena.biomeType === Biome.MEADOW || globalScene.arena.biomeType === Biome.JUNGLE), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "mint-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.SEA || globalScene.arena.biomeType === Biome.BEACH || globalScene.arena.biomeType === Biome.LAKE || globalScene.arena.biomeType === Biome.SEABED), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "lemon-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.DESERT || globalScene.arena.biomeType === Biome.POWER_PLANT || globalScene.arena.biomeType === Biome.DOJO || globalScene.arena.biomeType === Biome.RUINS || globalScene.arena.biomeType === Biome.CONSTRUCTION_SITE), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "salted-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.MOUNTAIN || globalScene.arena.biomeType === Biome.CAVE || globalScene.arena.biomeType === Biome.ICE_CAVE || globalScene.arena.biomeType === Biome.FAIRY_CAVE || globalScene.arena.biomeType === Biome.SNOWY_FOREST), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.WASTELAND || globalScene.arena.biomeType === Biome.LABORATORY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "caramel-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.TEMPLE || globalScene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, "", "rainbow-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.ABYSS || globalScene.arena.biomeType === Biome.SPACE || globalScene.arena.biomeType === Biome.END), SpeciesWildEvolutionDelay.LONG)
],
[Species.DURALUDON]: [
new SpeciesFormEvolution(Species.ARCHALUDON, "", "", 1, EvolutionItem.METAL_ALLOY, null, SpeciesWildEvolutionDelay.VERY_LONG)
@ -1502,7 +1502,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.OVERQWIL, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.BARB_BARRAGE).length > 0), SpeciesWildEvolutionDelay.LONG)
],
[Species.HISUI_SNEASEL]: [
new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY /* Razor claw at day*/), SpeciesWildEvolutionDelay.VERY_LONG)
new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY /* Razor claw at day*/), SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.CHARCADET]: [
new SpeciesEvolution(Species.ARMAROUGE, 1, EvolutionItem.AUSPICIOUS_ARMOR, null, SpeciesWildEvolutionDelay.LONG),
@ -1582,10 +1582,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CONKELDURR, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.KARRABLAST]: [
new SpeciesEvolution(Species.ESCAVALIER, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => !!gScene.gameData.dexData[Species.SHELMET].caughtAttr), SpeciesWildEvolutionDelay.VERY_LONG)
new SpeciesEvolution(Species.ESCAVALIER, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => !!globalScene.gameData.dexData[Species.SHELMET].caughtAttr), SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.SHELMET]: [
new SpeciesEvolution(Species.ACCELGOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => !!gScene.gameData.dexData[Species.KARRABLAST].caughtAttr), SpeciesWildEvolutionDelay.VERY_LONG)
new SpeciesEvolution(Species.ACCELGOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => !!globalScene.gameData.dexData[Species.KARRABLAST].caughtAttr), SpeciesWildEvolutionDelay.VERY_LONG)
],
[Species.SPRITZEE]: [
new SpeciesEvolution(Species.AROMATISSE, 1, EvolutionItem.SACHET, null, SpeciesWildEvolutionDelay.VERY_LONG)
@ -1628,13 +1628,13 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.MARILL, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT)
],
[Species.BUDEW]: [
new SpeciesEvolution(Species.ROSELIA, 1, null, new SpeciesFriendshipEvolutionCondition(70, p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.SHORT)
new SpeciesEvolution(Species.ROSELIA, 1, null, new SpeciesFriendshipEvolutionCondition(70, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.SHORT)
],
[Species.BUNEARY]: [
new SpeciesEvolution(Species.LOPUNNY, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.MEDIUM)
],
[Species.CHINGLING]: [
new SpeciesEvolution(Species.CHIMECHO, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
new SpeciesEvolution(Species.CHIMECHO, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
],
[Species.HAPPINY]: [
new SpeciesEvolution(Species.CHANSEY, 1, null, new SpeciesFriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT)
@ -1643,7 +1643,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.SNORLAX, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG)
],
[Species.RIOLU]: [
new SpeciesEvolution(Species.LUCARIO, 1, null, new SpeciesFriendshipEvolutionCondition(120, p => gScene.arena.getTimeOfDay() === TimeOfDay.DAWN || gScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG)
new SpeciesEvolution(Species.LUCARIO, 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG)
],
[Species.WOOBAT]: [
new SpeciesEvolution(Species.SWOOBAT, 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.MEDIUM)
@ -1658,16 +1658,16 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.ALOLA_PERSIAN, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG)
],
[Species.SNOM]: [
new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => gScene.arena.getTimeOfDay() === TimeOfDay.DUSK || gScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
],
[Species.GIMMIGHOUL]: [
new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter
+ p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
+ gScene.findModifiers(m => m instanceof MoneyMultiplierModifier
+ globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier
|| m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG),
new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter
+ p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
+ gScene.findModifiers(m => m instanceof MoneyMultiplierModifier
+ globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier
|| m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG)
]
};

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { AttackMove, BeakBlastHeaderAttr, DelayedAttackAttr, MoveFlags, SelfStatusMove, allMoves } from "./move";
import Pokemon from "../field/pokemon";
import * as Utils from "../utils";
@ -327,11 +327,11 @@ class AnimTimedSoundEvent extends AnimTimedEvent {
const soundConfig = { rate: (this.pitch * 0.01), volume: (this.volume * 0.01) };
if (this.resourceName) {
try {
gScene.playSound(`battle_anims/${this.resourceName}`, soundConfig);
globalScene.playSound(`battle_anims/${this.resourceName}`, soundConfig);
} catch (err) {
console.error(err);
}
return Math.ceil((gScene.sound.get(`battle_anims/${this.resourceName}`).totalDuration * 1000) / 33.33);
return Math.ceil((globalScene.sound.get(`battle_anims/${this.resourceName}`).totalDuration * 1000) / 33.33);
} else {
return Math.ceil((battleAnim.user!.cry(soundConfig).totalDuration * 1000) / 33.33); // TODO: is the bang behind user correct?
}
@ -397,7 +397,7 @@ class AnimTimedUpdateBgEvent extends AnimTimedBgEvent {
tweenProps["alpha"] = (this.opacity || 0) / 255;
}
if (Object.keys(tweenProps).length) {
gScene.tweens.add(Object.assign({
globalScene.tweens.add(Object.assign({
targets: moveAnim.bgSprite,
duration: Utils.getFrameMs(this.duration * 3)
}, tweenProps));
@ -420,20 +420,20 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
moveAnim.bgSprite.destroy();
}
moveAnim.bgSprite = this.resourceName
? gScene.add.tileSprite(this.bgX - 320, this.bgY - 284, 896, 576, this.resourceName)
: gScene.add.rectangle(this.bgX - 320, this.bgY - 284, 896, 576, 0);
? globalScene.add.tileSprite(this.bgX - 320, this.bgY - 284, 896, 576, this.resourceName)
: globalScene.add.rectangle(this.bgX - 320, this.bgY - 284, 896, 576, 0);
moveAnim.bgSprite.setOrigin(0, 0);
moveAnim.bgSprite.setScale(1.25);
moveAnim.bgSprite.setAlpha(this.opacity / 255);
gScene.field.add(moveAnim.bgSprite);
const fieldPokemon = gScene.getNonSwitchedEnemyPokemon() || gScene.getNonSwitchedPlayerPokemon();
globalScene.field.add(moveAnim.bgSprite);
const fieldPokemon = globalScene.getNonSwitchedEnemyPokemon() || globalScene.getNonSwitchedPlayerPokemon();
if (!isNullOrUndefined(priority)) {
gScene.field.moveTo(moveAnim.bgSprite as Phaser.GameObjects.GameObject, priority);
globalScene.field.moveTo(moveAnim.bgSprite as Phaser.GameObjects.GameObject, priority);
} else if (fieldPokemon?.isOnField()) {
gScene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon);
globalScene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon);
}
gScene.tweens.add({
globalScene.tweens.add({
targets: moveAnim.bgSprite,
duration: Utils.getFrameMs(this.duration * 3)
});
@ -458,7 +458,7 @@ export function initCommonAnims(): Promise<void> {
const commonAnimFetches: Promise<Map<CommonAnim, AnimConfig>>[] = [];
for (let ca = 0; ca < commonAnimIds.length; ca++) {
const commonAnimId = commonAnimIds[ca];
commonAnimFetches.push(gScene.cachedFetch(`./battle-anims/common-${commonAnimNames[ca].toLowerCase().replace(/\_/g, "-")}.json`)
commonAnimFetches.push(globalScene.cachedFetch(`./battle-anims/common-${commonAnimNames[ca].toLowerCase().replace(/\_/g, "-")}.json`)
.then(response => response.json())
.then(cas => commonAnims.set(commonAnimId, new AnimConfig(cas))));
}
@ -491,7 +491,7 @@ export function initMoveAnim(move: Moves): Promise<void> {
const defaultMoveAnim = allMoves[move] instanceof AttackMove ? Moves.TACKLE : allMoves[move] instanceof SelfStatusMove ? Moves.FOCUS_ENERGY : Moves.TAIL_WHIP;
const fetchAnimAndResolve = (move: Moves) => {
gScene.cachedFetch(`./battle-anims/${Utils.animationFileName(move)}.json`)
globalScene.cachedFetch(`./battle-anims/${Utils.animationFileName(move)}.json`)
.then(response => {
const contentType = response.headers.get("content-type");
if (!response.ok || contentType?.indexOf("application/json") === -1) {
@ -565,7 +565,7 @@ export async function initEncounterAnims(encounterAnim: EncounterAnim | Encounte
if (encounterAnims.has(anim) && !isNullOrUndefined(encounterAnims.get(anim))) {
continue;
}
encounterAnimFetches.push(gScene.cachedFetch(`./battle-anims/encounter-${encounterAnimNames[anim].toLowerCase().replace(/\_/g, "-")}.json`)
encounterAnimFetches.push(globalScene.cachedFetch(`./battle-anims/encounter-${encounterAnimNames[anim].toLowerCase().replace(/\_/g, "-")}.json`)
.then(response => response.json())
.then(cas => encounterAnims.set(anim, new AnimConfig(cas))));
}
@ -587,7 +587,7 @@ export function initMoveChargeAnim(chargeAnim: ChargeAnim): Promise<void> {
}
} else {
chargeAnims.set(chargeAnim, null);
gScene.cachedFetch(`./battle-anims/${ChargeAnim[chargeAnim].toLowerCase().replace(/\_/g, "-")}.json`)
globalScene.cachedFetch(`./battle-anims/${ChargeAnim[chargeAnim].toLowerCase().replace(/\_/g, "-")}.json`)
.then(response => response.json())
.then(ca => {
if (Array.isArray(ca)) {
@ -673,19 +673,19 @@ function loadAnimAssets(anims: AnimConfig[], startLoad?: boolean): Promise<void>
backgrounds.add(abg);
}
if (a.graphic) {
gScene.loadSpritesheet(a.graphic, "battle_anims", 96);
globalScene.loadSpritesheet(a.graphic, "battle_anims", 96);
}
}
for (const bg of backgrounds) {
gScene.loadImage(bg, "battle_anims");
globalScene.loadImage(bg, "battle_anims");
}
for (const s of sounds) {
gScene.loadSe(s, "battle_anims", s);
globalScene.loadSe(s, "battle_anims", s);
}
if (startLoad) {
gScene.load.once(Phaser.Loader.Events.COMPLETE, () => resolve());
if (!gScene.load.isLoading()) {
gScene.load.start();
globalScene.load.once(Phaser.Loader.Events.COMPLETE, () => resolve());
if (!globalScene.load.isLoading()) {
globalScene.load.start();
}
} else {
resolve();
@ -904,7 +904,7 @@ export abstract class BattleAnim {
}
};
if (!gScene.moveAnimations && !this.playRegardlessOfIssues) {
if (!globalScene.moveAnimations && !this.playRegardlessOfIssues) {
return cleanUpAndComplete();
}
@ -921,7 +921,7 @@ export abstract class BattleAnim {
let r = anim?.frames.length ?? 0;
let f = 0;
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
duration: Utils.getFrameMs(3),
repeat: anim?.frames.length ?? 0,
onRepeat: () => {
@ -947,19 +947,19 @@ export abstract class BattleAnim {
const spriteSource = isUser ? userSprite : targetSprite;
if ((isUser ? u : t) === sprites.length) {
if (isUser || !targetSubstitute) {
const sprite = gScene.addPokemonSprite(isUser ? user! : target, 0, 0, spriteSource!.texture, spriteSource!.frame.name, true); // TODO: are those bangs correct?
const sprite = globalScene.addPokemonSprite(isUser ? user! : target, 0, 0, spriteSource!.texture, spriteSource!.frame.name, true); // TODO: are those bangs correct?
[ "spriteColors", "fusionSpriteColors" ].map(k => sprite.pipelineData[k] = (isUser ? user! : target).getSprite().pipelineData[k]); // TODO: are those bangs correct?
sprite.setPipelineData("spriteKey", (isUser ? user! : target).getBattleSpriteKey());
sprite.setPipelineData("shiny", (isUser ? user : target).shiny);
sprite.setPipelineData("variant", (isUser ? user : target).variant);
sprite.setPipelineData("ignoreFieldPos", true);
spriteSource.on("animationupdate", (_anim, frame) => sprite.setFrame(frame.textureFrame));
gScene.field.add(sprite);
globalScene.field.add(sprite);
sprites.push(sprite);
} else {
const sprite = gScene.addFieldSprite(spriteSource.x, spriteSource.y, spriteSource.texture);
const sprite = globalScene.addFieldSprite(spriteSource.x, spriteSource.y, spriteSource.texture);
spriteSource.on("animationupdate", (_anim, frame) => sprite.setFrame(frame.textureFrame));
gScene.field.add(sprite);
globalScene.field.add(sprite);
sprites.push(sprite);
}
}
@ -984,9 +984,9 @@ export abstract class BattleAnim {
} else {
const sprites = spriteCache[AnimFrameTarget.GRAPHIC];
if (g === sprites.length) {
const newSprite: Phaser.GameObjects.Sprite = gScene.addFieldSprite(0, 0, anim!.graphic, 1); // TODO: is the bang correct?
const newSprite: Phaser.GameObjects.Sprite = globalScene.addFieldSprite(0, 0, anim!.graphic, 1); // TODO: is the bang correct?
sprites.push(newSprite);
gScene.field.add(newSprite);
globalScene.field.add(newSprite);
spritePriorities.push(1);
}
@ -997,22 +997,22 @@ export abstract class BattleAnim {
const setSpritePriority = (priority: integer) => {
switch (priority) {
case 0:
gScene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, gScene.getNonSwitchedEnemyPokemon() || gScene.getNonSwitchedPlayerPokemon()!); // This bang assumes that if (the EnemyPokemon is undefined, then the PlayerPokemon function must return an object), correct assumption?
globalScene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, globalScene.getNonSwitchedEnemyPokemon() || globalScene.getNonSwitchedPlayerPokemon()!); // This bang assumes that if (the EnemyPokemon is undefined, then the PlayerPokemon function must return an object), correct assumption?
break;
case 1:
gScene.field.moveTo(moveSprite, gScene.field.getAll().length - 1);
globalScene.field.moveTo(moveSprite, globalScene.field.getAll().length - 1);
break;
case 2:
switch (frame.focus) {
case AnimFocus.USER:
if (this.bgSprite) {
gScene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.bgSprite);
globalScene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.bgSprite);
} else {
gScene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.user!); // TODO: is this bang correct?
globalScene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.user!); // TODO: is this bang correct?
}
break;
case AnimFocus.TARGET:
gScene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.target!); // TODO: is this bang correct?
globalScene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, this.target!); // TODO: is this bang correct?
break;
default:
setSpritePriority(1);
@ -1022,10 +1022,10 @@ export abstract class BattleAnim {
case 3:
switch (frame.focus) {
case AnimFocus.USER:
gScene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.user!); // TODO: is this bang correct?
globalScene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.user!); // TODO: is this bang correct?
break;
case AnimFocus.TARGET:
gScene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.target!); // TODO: is this bang correct?
globalScene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, this.target!); // TODO: is this bang correct?
break;
default:
setSpritePriority(1);
@ -1083,7 +1083,7 @@ export abstract class BattleAnim {
}
}
if (r) {
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
duration: Utils.getFrameMs(r),
onComplete: () => cleanUpAndComplete()
});
@ -1153,7 +1153,7 @@ export abstract class BattleAnim {
}
};
if (!gScene.moveAnimations && !this.playRegardlessOfIssues) {
if (!globalScene.moveAnimations && !this.playRegardlessOfIssues) {
return cleanUpAndComplete();
}
@ -1165,13 +1165,13 @@ export abstract class BattleAnim {
let totalFrames = anim!.frames.length;
let frameCount = 0;
let existingFieldSprites = gScene.field.getAll().slice(0);
let existingFieldSprites = globalScene.field.getAll().slice(0);
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
duration: Utils.getFrameMs(3) * frameTimeMult,
repeat: anim!.frames.length,
onRepeat: () => {
existingFieldSprites = gScene.field.getAll().slice(0);
existingFieldSprites = globalScene.field.getAll().slice(0);
const spriteFrames = anim!.frames[frameCount];
const frameData = this.getGraphicFrameDataWithoutTarget(anim!.frames[frameCount], targetInitialX, targetInitialY);
let graphicFrameCount = 0;
@ -1183,9 +1183,9 @@ export abstract class BattleAnim {
const sprites = spriteCache[AnimFrameTarget.GRAPHIC];
if (graphicFrameCount === sprites.length) {
const newSprite: Phaser.GameObjects.Sprite = gScene.addFieldSprite(0, 0, anim!.graphic, 1);
const newSprite: Phaser.GameObjects.Sprite = globalScene.addFieldSprite(0, 0, anim!.graphic, 1);
sprites.push(newSprite);
gScene.field.add(newSprite);
globalScene.field.add(newSprite);
}
const graphicIndex = graphicFrameCount++;
@ -1194,11 +1194,11 @@ export abstract class BattleAnim {
const setSpritePriority = (priority: integer) => {
if (existingFieldSprites.length > priority) {
// Move to specified priority index
const index = gScene.field.getIndex(existingFieldSprites[priority]);
gScene.field.moveTo(moveSprite, index);
const index = globalScene.field.getIndex(existingFieldSprites[priority]);
globalScene.field.moveTo(moveSprite, index);
} else {
// Move to top of scene
gScene.field.moveTo(moveSprite, gScene.field.getAll().length - 1);
globalScene.field.moveTo(moveSprite, globalScene.field.getAll().length - 1);
}
};
setSpritePriority(frame.priority);
@ -1245,7 +1245,7 @@ export abstract class BattleAnim {
}
}
if (totalFrames) {
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
duration: Utils.getFrameMs(totalFrames),
onComplete: () => cleanUpAndComplete()
});
@ -1279,7 +1279,7 @@ export class MoveAnim extends BattleAnim {
public move: Moves;
constructor(move: Moves, user: Pokemon, target: BattlerIndex, playOnEmptyField: boolean = false) {
super(user, gScene.getField()[target], playOnEmptyField);
super(user, globalScene.getField()[target], playOnEmptyField);
this.move = move;
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import {
allAbilities,
applyAbAttrs,
@ -113,7 +113,7 @@ export class BattlerTag {
* @returns The source {@linkcode Pokemon} or `null` if none is found
*/
public getSourcePokemon(): Pokemon | null {
return this.sourceId ? gScene.getPokemonById(this.sourceId) : null;
return this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
}
}
@ -142,12 +142,12 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag {
override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
// Cancel the affected pokemon's selected move
const phase = gScene.getCurrentPhase() as MovePhase;
const phase = globalScene.getCurrentPhase() as MovePhase;
const move = phase.move;
if (this.isMoveRestricted(move.moveId, pokemon)) {
if (this.interruptedText(pokemon, move.moveId)) {
gScene.queueMessage(this.interruptedText(pokemon, move.moveId));
globalScene.queueMessage(this.interruptedText(pokemon, move.moveId));
}
phase.cancel();
}
@ -279,14 +279,14 @@ export class DisabledTag extends MoveRestrictionBattlerTag {
this.moveId = move.move;
gScene.queueMessage(i18next.t("battlerTags:disabledOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
globalScene.queueMessage(i18next.t("battlerTags:disabledOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
}
/** @override */
override onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battlerTags:disabledLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
globalScene.queueMessage(i18next.t("battlerTags:disabledLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
}
/** @override */
@ -405,8 +405,8 @@ export class RechargingTag extends BattlerTag {
/** Cancels the source's move this turn and queues a "__ must recharge!" message */
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
gScene.queueMessage(i18next.t("battlerTags:rechargingLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
(gScene.getCurrentPhase() as MovePhase).cancel();
globalScene.queueMessage(i18next.t("battlerTags:rechargingLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
(globalScene.getCurrentPhase() as MovePhase).cancel();
pokemon.getMoveQueue().shift();
}
return super.lapse(pokemon, lapseType);
@ -428,7 +428,7 @@ export class BeakBlastChargingTag extends BattlerTag {
new MoveChargeAnim(ChargeAnim.BEAK_BLAST_CHARGING, this.sourceMove, pokemon).play();
// Queue Beak Blast's header message
gScene.queueMessage(i18next.t("moveTriggers:startedHeatingUpBeak", { pokemonName: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("moveTriggers:startedHeatingUpBeak", { pokemonName: getPokemonNameWithAffix(pokemon) }));
}
/**
@ -463,7 +463,7 @@ export class ShellTrapTag extends BattlerTag {
}
onAdd(pokemon: Pokemon): void {
gScene.queueMessage(i18next.t("moveTriggers:setUpShellTrap", { pokemonName: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("moveTriggers:setUpShellTrap", { pokemonName: getPokemonNameWithAffix(pokemon) }));
}
/**
@ -478,17 +478,17 @@ export class ShellTrapTag extends BattlerTag {
// Trap should only be triggered by opponent's Physical moves
if (phaseData?.move.category === MoveCategory.PHYSICAL && pokemon.isOpponent(phaseData.attacker)) {
const shellTrapPhaseIndex = gScene.phaseQueue.findIndex(
const shellTrapPhaseIndex = globalScene.phaseQueue.findIndex(
phase => phase instanceof MovePhase && phase.pokemon === pokemon
);
const firstMovePhaseIndex = gScene.phaseQueue.findIndex(
const firstMovePhaseIndex = globalScene.phaseQueue.findIndex(
phase => phase instanceof MovePhase
);
// Only shift MovePhase timing if it's not already next up
if (shellTrapPhaseIndex !== -1 && shellTrapPhaseIndex !== firstMovePhaseIndex) {
const shellTrapMovePhase = gScene.phaseQueue.splice(shellTrapPhaseIndex, 1)[0];
gScene.prependToPhase(shellTrapMovePhase, MovePhase);
const shellTrapMovePhase = globalScene.phaseQueue.splice(shellTrapPhaseIndex, 1)[0];
globalScene.prependToPhase(shellTrapMovePhase, MovePhase);
}
this.activated = true;
@ -507,7 +507,7 @@ export class TrappedTag extends BattlerTag {
}
canAdd(pokemon: Pokemon): boolean {
const source = gScene.getPokemonById(this.sourceId!)!;
const source = globalScene.getPokemonById(this.sourceId!)!;
const move = allMoves[this.sourceMove];
const isGhost = pokemon.isOfType(Type.GHOST);
@ -520,13 +520,13 @@ export class TrappedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(this.getTrapMessage(pokemon));
globalScene.queueMessage(this.getTrapMessage(pokemon));
}
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battlerTags:trappedOnRemove", {
globalScene.queueMessage(i18next.t("battlerTags:trappedOnRemove", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
moveName: this.getMoveName()
}));
@ -584,8 +584,8 @@ export class FlinchedTag extends BattlerTag {
*/
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
(gScene.getCurrentPhase() as MovePhase).cancel();
gScene.queueMessage(i18next.t("battlerTags:flinchedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
(globalScene.getCurrentPhase() as MovePhase).cancel();
globalScene.queueMessage(i18next.t("battlerTags:flinchedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
return super.lapse(pokemon, lapseType);
@ -613,7 +613,7 @@ export class InterruptedTag extends BattlerTag {
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
(gScene.getCurrentPhase() as MovePhase).cancel();
(globalScene.getCurrentPhase() as MovePhase).cancel();
return super.lapse(pokemon, lapseType);
}
}
@ -627,44 +627,44 @@ export class ConfusedTag extends BattlerTag {
}
canAdd(pokemon: Pokemon): boolean {
return gScene.arena.terrain?.terrainType !== TerrainType.MISTY || !pokemon.isGrounded();
return globalScene.arena.terrain?.terrainType !== TerrainType.MISTY || !pokemon.isGrounded();
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
gScene.queueMessage(i18next.t("battlerTags:confusedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
globalScene.queueMessage(i18next.t("battlerTags:confusedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battlerTags:confusedOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:confusedOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon);
gScene.queueMessage(i18next.t("battlerTags:confusedOnOverlap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:confusedOnOverlap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType);
if (ret) {
gScene.queueMessage(i18next.t("battlerTags:confusedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
gScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
globalScene.queueMessage(i18next.t("battlerTags:confusedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
// 1/3 chance of hitting self with a 40 base power move
if (pokemon.randSeedInt(3) === 0) {
const atk = pokemon.getEffectiveStat(Stat.ATK);
const def = pokemon.getEffectiveStat(Stat.DEF);
const damage = toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedIntRange(85, 100) / 100));
gScene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself"));
globalScene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself"));
pokemon.damageAndUpdate(damage);
pokemon.battleData.hitCount++;
(gScene.getCurrentPhase() as MovePhase).cancel();
(globalScene.getCurrentPhase() as MovePhase).cancel();
}
}
@ -699,7 +699,7 @@ export class DestinyBondTag extends BattlerTag {
if (lapseType !== BattlerTagLapseType.CUSTOM) {
return super.lapse(pokemon, lapseType);
}
const source = this.sourceId ? gScene.getPokemonById(this.sourceId) : null;
const source = this.sourceId ? globalScene.getPokemonById(this.sourceId) : null;
if (!source?.isFainted()) {
return true;
}
@ -709,11 +709,11 @@ export class DestinyBondTag extends BattlerTag {
}
if (pokemon.isBossImmune()) {
gScene.queueMessage(i18next.t("battlerTags:destinyBondLapseIsBoss", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:destinyBondLapseIsBoss", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
return false;
}
gScene.queueMessage(
globalScene.queueMessage(
i18next.t("battlerTags:destinyBondLapse", {
pokemonNameWithAffix: getPokemonNameWithAffix(source),
pokemonNameWithAffix2: getPokemonNameWithAffix(pokemon)
@ -731,7 +731,7 @@ export class InfatuatedTag extends BattlerTag {
canAdd(pokemon: Pokemon): boolean {
if (this.sourceId) {
const pkm = gScene.getPokemonById(this.sourceId);
const pkm = globalScene.getPokemonById(this.sourceId);
if (pkm) {
return pokemon.isOppositeGender(pkm);
@ -748,10 +748,10 @@ export class InfatuatedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(
globalScene.queueMessage(
i18next.t("battlerTags:infatuatedOnAdd", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
sourcePokemonName: getPokemonNameWithAffix(gScene.getPokemonById(this.sourceId!) ?? undefined) // TODO: is that bang correct?
sourcePokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined) // TODO: is that bang correct?
})
);
}
@ -759,24 +759,24 @@ export class InfatuatedTag extends BattlerTag {
onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon);
gScene.queueMessage(i18next.t("battlerTags:infatuatedOnOverlap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:infatuatedOnOverlap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) {
gScene.queueMessage(
globalScene.queueMessage(
i18next.t("battlerTags:infatuatedLapse", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
sourcePokemonName: getPokemonNameWithAffix(gScene.getPokemonById(this.sourceId!) ?? undefined) // TODO: is that bang correct?
sourcePokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined) // TODO: is that bang correct?
})
);
gScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT));
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT));
if (pokemon.randSeedInt(2)) {
gScene.queueMessage(i18next.t("battlerTags:infatuatedLapseImmobilize", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
(gScene.getCurrentPhase() as MovePhase).cancel();
globalScene.queueMessage(i18next.t("battlerTags:infatuatedLapseImmobilize", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
(globalScene.getCurrentPhase() as MovePhase).cancel();
}
}
@ -786,7 +786,7 @@ export class InfatuatedTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battlerTags:infatuatedOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:infatuatedOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
isSourceLinked(): boolean {
@ -821,8 +821,8 @@ export class SeedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:seededOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
this.sourceIndex = gScene.getPokemonById(this.sourceId!)!.getBattlerIndex(); // TODO: are those bangs correct?
globalScene.queueMessage(i18next.t("battlerTags:seededOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
this.sourceIndex = globalScene.getPokemonById(this.sourceId!)!.getBattlerIndex(); // TODO: are those bangs correct?
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -835,11 +835,11 @@ export class SeedTag extends BattlerTag {
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (!cancelled.value) {
gScene.unshiftPhase(new CommonAnimPhase(source.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.LEECH_SEED));
globalScene.unshiftPhase(new CommonAnimPhase(source.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.LEECH_SEED));
const damage = pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8));
const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr, false);
gScene.unshiftPhase(new PokemonHealPhase(source.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(source.getBattlerIndex(),
!reverseDrain ? damage : damage * -1,
!reverseDrain ? i18next.t("battlerTags:seededLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }) : i18next.t("battlerTags:seededLapseShed", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }),
false, true));
@ -863,21 +863,21 @@ export class NightmareTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:nightmareOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:nightmareOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon);
gScene.queueMessage(i18next.t("battlerTags:nightmareOnOverlap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:nightmareOnOverlap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) {
gScene.queueMessage(i18next.t("battlerTags:nightmareLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
gScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE)); // TODO: Update animation type
globalScene.queueMessage(i18next.t("battlerTags:nightmareLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE)); // TODO: Update animation type
const cancelled = new BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
@ -956,14 +956,14 @@ export class EncoreTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battlerTags:encoreOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:encoreOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
const movePhase = gScene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon);
const movePhase = globalScene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon);
if (movePhase) {
const movesetMove = pokemon.getMoveset().find(m => m!.moveId === this.moveId); // TODO: is this bang correct?
if (movesetMove) {
const lastMove = pokemon.getLastXMoves(1)[0];
gScene.tryReplacePhase((m => m instanceof MovePhase && m.pokemon === pokemon),
globalScene.tryReplacePhase((m => m instanceof MovePhase && m.pokemon === pokemon),
new MovePhase(pokemon, lastMove.targets!, movesetMove)); // TODO: is this bang correct?
}
}
@ -972,7 +972,7 @@ export class EncoreTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battlerTags:encoreOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:encoreOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
@ -982,9 +982,9 @@ export class HelpingHandTag extends BattlerTag {
}
onAdd(pokemon: Pokemon): void {
gScene.queueMessage(
globalScene.queueMessage(
i18next.t("battlerTags:helpingHandOnAdd", {
pokemonNameWithAffix: getPokemonNameWithAffix(gScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
pokemonNameWithAffix: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
pokemonName: getPokemonNameWithAffix(pokemon)
})
);
@ -1015,7 +1015,7 @@ export class IngrainTag extends TrappedTag {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) {
gScene.unshiftPhase(
globalScene.unshiftPhase(
new PokemonHealPhase(
pokemon.getBattlerIndex(),
toDmgValue(pokemon.getMaxHp() / 16),
@ -1054,7 +1054,7 @@ export class OctolockTag extends TrappedTag {
const shouldLapse = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (shouldLapse) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, [ Stat.DEF, Stat.SPDEF ], -1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), false, [ Stat.DEF, Stat.SPDEF ], -1));
return true;
}
@ -1070,14 +1070,14 @@ export class AquaRingTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:aquaRingOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:aquaRingOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) {
gScene.unshiftPhase(
globalScene.unshiftPhase(
new PokemonHealPhase(
pokemon.getBattlerIndex(),
toDmgValue(pokemon.getMaxHp() / 16),
@ -1117,13 +1117,13 @@ export class DrowsyTag extends BattlerTag {
}
canAdd(pokemon: Pokemon): boolean {
return gScene.arena.terrain?.terrainType !== TerrainType.ELECTRIC || !pokemon.isGrounded();
return globalScene.arena.terrain?.terrainType !== TerrainType.ELECTRIC || !pokemon.isGrounded();
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:drowsyOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:drowsyOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -1166,13 +1166,13 @@ export abstract class DamagingTrapTag extends TrappedTag {
const ret = super.lapse(pokemon, lapseType);
if (ret) {
gScene.queueMessage(
globalScene.queueMessage(
i18next.t("battlerTags:damagingTrapLapse", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
moveName: this.getMoveName()
})
);
gScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, this.commonAnim));
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, this.commonAnim));
const cancelled = new BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
@ -1194,7 +1194,7 @@ export class BindTag extends DamagingTrapTag {
getTrapMessage(pokemon: Pokemon): string {
return i18next.t("battlerTags:bindOnTrap", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
sourcePokemonName: getPokemonNameWithAffix(gScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
sourcePokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
moveName: this.getMoveName()
});
}
@ -1208,7 +1208,7 @@ export class WrapTag extends DamagingTrapTag {
getTrapMessage(pokemon: Pokemon): string {
return i18next.t("battlerTags:wrapOnTrap", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
sourcePokemonName: getPokemonNameWithAffix(gScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
sourcePokemonName: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
});
}
}
@ -1242,7 +1242,7 @@ export class ClampTag extends DamagingTrapTag {
getTrapMessage(pokemon: Pokemon): string {
return i18next.t("battlerTags:clampOnTrap", {
sourcePokemonNameWithAffix: getPokemonNameWithAffix(gScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
sourcePokemonNameWithAffix: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
pokemonName: getPokemonNameWithAffix(pokemon),
});
}
@ -1289,7 +1289,7 @@ export class ThunderCageTag extends DamagingTrapTag {
getTrapMessage(pokemon: Pokemon): string {
return i18next.t("battlerTags:thunderCageOnTrap", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
sourcePokemonNameWithAffix: getPokemonNameWithAffix(gScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
sourcePokemonNameWithAffix: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
});
}
}
@ -1302,7 +1302,7 @@ export class InfestationTag extends DamagingTrapTag {
getTrapMessage(pokemon: Pokemon): string {
return i18next.t("battlerTags:infestationOnTrap", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
sourcePokemonNameWithAffix: getPokemonNameWithAffix(gScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
sourcePokemonNameWithAffix: getPokemonNameWithAffix(globalScene.getPokemonById(this.sourceId!) ?? undefined), // TODO: is that bang correct?
});
}
}
@ -1316,16 +1316,16 @@ export class ProtectedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:protectedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:protectedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) {
new CommonBattleAnim(CommonAnim.PROTECT, pokemon).play();
gScene.queueMessage(i18next.t("battlerTags:protectedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:protectedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
// Stop multi-hit moves early
const effectPhase = gScene.getCurrentPhase();
const effectPhase = globalScene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase) {
effectPhase.stopMultiHit(pokemon);
}
@ -1365,7 +1365,7 @@ export class ContactDamageProtectedTag extends ProtectedTag {
const ret = super.lapse(pokemon, lapseType);
if (lapseType === BattlerTagLapseType.CUSTOM) {
const effectPhase = gScene.getCurrentPhase();
const effectPhase = globalScene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
const attacker = effectPhase.getPokemon();
if (!attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
@ -1407,10 +1407,10 @@ export class ContactStatStageChangeProtectedTag extends DamageProtectedTag {
const ret = super.lapse(pokemon, lapseType);
if (lapseType === BattlerTagLapseType.CUSTOM) {
const effectPhase = gScene.getCurrentPhase();
const effectPhase = globalScene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
const attacker = effectPhase.getPokemon();
gScene.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [ this.stat ], this.levels));
globalScene.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [ this.stat ], this.levels));
}
}
@ -1427,7 +1427,7 @@ export class ContactPoisonProtectedTag extends ProtectedTag {
const ret = super.lapse(pokemon, lapseType);
if (lapseType === BattlerTagLapseType.CUSTOM) {
const effectPhase = gScene.getCurrentPhase();
const effectPhase = globalScene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
const attacker = effectPhase.getPokemon();
attacker.trySetStatus(StatusEffect.POISON, true, pokemon);
@ -1451,7 +1451,7 @@ export class ContactBurnProtectedTag extends DamageProtectedTag {
const ret = super.lapse(pokemon, lapseType);
if (lapseType === BattlerTagLapseType.CUSTOM) {
const effectPhase = gScene.getCurrentPhase();
const effectPhase = globalScene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
const attacker = effectPhase.getPokemon();
attacker.trySetStatus(StatusEffect.BURN, true);
@ -1470,12 +1470,12 @@ export class EnduringTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:enduringOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:enduringOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) {
gScene.queueMessage(i18next.t("battlerTags:enduringLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:enduringLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
return true;
}
@ -1490,7 +1490,7 @@ export class SturdyTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) {
gScene.queueMessage(i18next.t("battlerTags:sturdyLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:sturdyLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
return true;
}
@ -1511,7 +1511,7 @@ export class PerishSongTag extends BattlerTag {
const ret = super.lapse(pokemon, lapseType);
if (ret) {
gScene.queueMessage(
globalScene.queueMessage(
i18next.t("battlerTags:perishSongLapse", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
turnCount: this.turnCount
@ -1540,7 +1540,7 @@ export class CenterOfAttentionTag extends BattlerTag {
/** "Center of Attention" can't be added if an ally is already the Center of Attention. */
canAdd(pokemon: Pokemon): boolean {
const activeTeam = pokemon.isPlayer() ? gScene.getPlayerField() : gScene.getEnemyField();
const activeTeam = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
return !activeTeam.find(p => p.getTag(BattlerTagType.CENTER_OF_ATTENTION));
}
@ -1548,7 +1548,7 @@ export class CenterOfAttentionTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:centerOfAttentionOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:centerOfAttentionOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
@ -1585,9 +1585,9 @@ export class TruantTag extends AbilityBattlerTag {
const lastMove = pokemon.getLastXMoves().find(() => true);
if (lastMove && lastMove.move !== Moves.NONE) {
(gScene.getCurrentPhase() as MovePhase).cancel();
gScene.unshiftPhase(new ShowAbilityPhase(pokemon.id, passive));
gScene.queueMessage(i18next.t("battlerTags:truantLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
(globalScene.getCurrentPhase() as MovePhase).cancel();
globalScene.unshiftPhase(new ShowAbilityPhase(pokemon.id, passive));
globalScene.queueMessage(i18next.t("battlerTags:truantLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
return true;
@ -1602,7 +1602,7 @@ export class SlowStartTag extends AbilityBattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:slowStartOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, false, null, true);
globalScene.queueMessage(i18next.t("battlerTags:slowStartOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, false, null, true);
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -1616,7 +1616,7 @@ export class SlowStartTag extends AbilityBattlerTag {
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battlerTags:slowStartOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, false, null);
globalScene.queueMessage(i18next.t("battlerTags:slowStartOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, false, null);
}
}
@ -1662,13 +1662,13 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
break;
}
gScene.queueMessage(i18next.t("battlerTags:highestStatBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), statName: i18next.t(getStatKey(highestStat)) }), null, false, null, true);
globalScene.queueMessage(i18next.t("battlerTags:highestStatBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), statName: i18next.t(getStatKey(highestStat)) }), null, false, null, true);
}
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battlerTags:highestStatBoostOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: allAbilities[this.ability].name }));
globalScene.queueMessage(i18next.t("battlerTags:highestStatBoostOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: allAbilities[this.ability].name }));
}
}
@ -1721,7 +1721,7 @@ export class SemiInvulnerableTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
// Wait 2 frames before setting visible for battle animations that don't immediately show the sprite invisible
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
duration: getFrameMs(2),
onComplete: () => pokemon.setVisible(true)
});
@ -1761,7 +1761,7 @@ export class FloatingTag extends TypeImmuneTag {
super.onAdd(pokemon);
if (this.sourceMove === Moves.MAGNET_RISE) {
gScene.queueMessage(i18next.t("battlerTags:magnetRisenOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:magnetRisenOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
@ -1769,7 +1769,7 @@ export class FloatingTag extends TypeImmuneTag {
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
if (this.sourceMove === Moves.MAGNET_RISE) {
gScene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
}
@ -1811,7 +1811,7 @@ export class CritBoostTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:critBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:critBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -1821,7 +1821,7 @@ export class CritBoostTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battlerTags:critBoostOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:critBoostOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
@ -1863,15 +1863,15 @@ export class SaltCuredTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:saltCuredOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
this.sourceIndex = gScene.getPokemonById(this.sourceId!)!.getBattlerIndex(); // TODO: are those bangs correct?
globalScene.queueMessage(i18next.t("battlerTags:saltCuredOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
this.sourceIndex = globalScene.getPokemonById(this.sourceId!)!.getBattlerIndex(); // TODO: are those bangs correct?
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) {
gScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.SALT_CURE));
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.SALT_CURE));
const cancelled = new BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
@ -1880,7 +1880,7 @@ export class SaltCuredTag extends BattlerTag {
const pokemonSteelOrWater = pokemon.isOfType(Type.STEEL) || pokemon.isOfType(Type.WATER);
pokemon.damageAndUpdate(toDmgValue(pokemonSteelOrWater ? pokemon.getMaxHp() / 4 : pokemon.getMaxHp() / 8));
gScene.queueMessage(
globalScene.queueMessage(
i18next.t("battlerTags:saltCuredLapse", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
moveName: this.getMoveName()
@ -1911,21 +1911,21 @@ export class CursedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
this.sourceIndex = gScene.getPokemonById(this.sourceId!)!.getBattlerIndex(); // TODO: are those bangs correct?
this.sourceIndex = globalScene.getPokemonById(this.sourceId!)!.getBattlerIndex(); // TODO: are those bangs correct?
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) {
gScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.SALT_CURE));
globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.SALT_CURE));
const cancelled = new BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (!cancelled.value) {
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 4));
gScene.queueMessage(i18next.t("battlerTags:cursedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:cursedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
@ -2039,7 +2039,7 @@ export class FormBlockDamageTag extends BattlerTag {
super.onAdd(pokemon);
if (pokemon.formIndex !== 0) {
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
}
}
@ -2051,7 +2051,7 @@ export class FormBlockDamageTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
}
}
/** Provides the additional weather-based effects of the Ice Face ability */
@ -2066,7 +2066,7 @@ export class IceFaceBlockDamageTag extends FormBlockDamageTag {
* @returns {boolean} True if the tag can be added, false otherwise.
*/
canAdd(pokemon: Pokemon): boolean {
const weatherType = gScene.arena.weather?.weatherType;
const weatherType = globalScene.arena.weather?.weatherType;
const isWeatherSnowOrHail = weatherType === WeatherType.HAIL || weatherType === WeatherType.SNOW;
return super.canAdd(pokemon) || isWeatherSnowOrHail;
@ -2125,13 +2125,13 @@ export class StockpilingTag extends BattlerTag {
if (this.stockpiledCount < 3) {
this.stockpiledCount++;
gScene.queueMessage(i18next.t("battlerTags:stockpilingOnAdd", {
globalScene.queueMessage(i18next.t("battlerTags:stockpilingOnAdd", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
stockpiledCount: this.stockpiledCount
}));
// Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes.
gScene.unshiftPhase(new StatStageChangePhase(
globalScene.unshiftPhase(new StatStageChangePhase(
pokemon.getBattlerIndex(), true,
[ Stat.SPDEF, Stat.DEF ], 1, true, false, true, this.onStatStagesChanged
));
@ -2151,11 +2151,11 @@ export class StockpilingTag extends BattlerTag {
const spDefChange = this.statChangeCounts[Stat.SPDEF];
if (defChange) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.DEF ], -defChange, true, false, true));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.DEF ], -defChange, true, false, true));
}
if (spDefChange) {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPDEF ], -spDefChange, true, false, true));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPDEF ], -spDefChange, true, false, true));
}
}
}
@ -2174,7 +2174,7 @@ export class GulpMissileTag extends BattlerTag {
return true;
}
const moveEffectPhase = gScene.getCurrentPhase();
const moveEffectPhase = globalScene.getCurrentPhase();
if (moveEffectPhase instanceof MoveEffectPhase) {
const attacker = moveEffectPhase.getUserPokemon();
@ -2194,7 +2194,7 @@ export class GulpMissileTag extends BattlerTag {
}
if (this.tagType === BattlerTagType.GULP_MISSILE_ARROKUDA) {
gScene.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [ Stat.DEF ], -1));
globalScene.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [ Stat.DEF ], -1));
} else {
attacker.trySetStatus(StatusEffect.PARALYSIS, true, pokemon);
}
@ -2217,12 +2217,12 @@ export class GulpMissileTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
}
onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
}
}
@ -2330,7 +2330,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag {
override onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
gScene.queueMessage(i18next.t("battle:battlerTagsHealBlockOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, false, null);
globalScene.queueMessage(i18next.t("battle:battlerTagsHealBlockOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, false, null);
}
}
@ -2353,7 +2353,7 @@ export class TarShotTag extends BattlerTag {
}
override onAdd(pokemon: Pokemon): void {
gScene.queueMessage(i18next.t("battlerTags:tarShotOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:tarShotOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
@ -2368,7 +2368,7 @@ export class ElectrifiedTag extends BattlerTag {
override onAdd(pokemon: Pokemon): void {
// "{pokemonNameWithAffix}'s moves have been electrified!"
gScene.queueMessage(i18next.t("battlerTags:electrifiedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:electrifiedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
@ -2390,7 +2390,7 @@ export class AutotomizedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
const minWeight = 0.1;
if (pokemon.getWeight() > minWeight) {
gScene.queueMessage(i18next.t("battlerTags:autotomizeOnAdd", {
globalScene.queueMessage(i18next.t("battlerTags:autotomizeOnAdd", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)
}));
}
@ -2421,15 +2421,15 @@ export class SubstituteTag extends BattlerTag {
/** Sets the Substitute's HP and queues an on-add battle animation that initializes the Substitute's sprite. */
onAdd(pokemon: Pokemon): void {
this.hp = Math.floor(gScene.getPokemonById(this.sourceId!)!.getMaxHp() / 4);
this.hp = Math.floor(globalScene.getPokemonById(this.sourceId!)!.getMaxHp() / 4);
this.sourceInFocus = false;
// Queue battle animation and message
gScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_ADD);
globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_ADD);
if (this.sourceMove === Moves.SHED_TAIL) {
gScene.queueMessage(i18next.t("battlerTags:shedTailOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500);
globalScene.queueMessage(i18next.t("battlerTags:shedTailOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500);
} else {
gScene.queueMessage(i18next.t("battlerTags:substituteOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500);
globalScene.queueMessage(i18next.t("battlerTags:substituteOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500);
}
// Remove any binding effects from the user
@ -2440,11 +2440,11 @@ export class SubstituteTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
// Only play the animation if the cause of removal isn't from the source's own move
if (!this.sourceInFocus) {
gScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_REMOVE, [ this.sprite ]);
globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_REMOVE, [ this.sprite ]);
} else {
this.sprite.destroy();
}
gScene.queueMessage(i18next.t("battlerTags:substituteOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:substituteOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -2464,26 +2464,26 @@ export class SubstituteTag extends BattlerTag {
/** Triggers an animation that brings the Pokemon into focus before it uses a move */
onPreMove(pokemon: Pokemon): void {
gScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_PRE_MOVE, [ this.sprite ]);
globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_PRE_MOVE, [ this.sprite ]);
this.sourceInFocus = true;
}
/** Triggers an animation that brings the Pokemon out of focus after it uses a move */
onAfterMove(pokemon: Pokemon): void {
gScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_POST_MOVE, [ this.sprite ]);
globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_POST_MOVE, [ this.sprite ]);
this.sourceInFocus = false;
}
/** If the Substitute redirects damage, queue a message to indicate it. */
onHit(pokemon: Pokemon): void {
const moveEffectPhase = gScene.getCurrentPhase();
const moveEffectPhase = globalScene.getCurrentPhase();
if (moveEffectPhase instanceof MoveEffectPhase) {
const attacker = moveEffectPhase.getUserPokemon()!;
const move = moveEffectPhase.move.getMove();
const firstHit = (attacker.turnData.hitCount === attacker.turnData.hitsLeft);
if (firstHit && move.hitsSubstitute(attacker, pokemon)) {
gScene.queueMessage(i18next.t("battlerTags:substituteOnHit", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:substituteOnHit", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
}
@ -2555,7 +2555,7 @@ export class TormentTag extends MoveRestrictionBattlerTag {
*/
override onAdd(pokemon: Pokemon) {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:tormentOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500);
globalScene.queueMessage(i18next.t("battlerTags:tormentOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500);
}
/**
@ -2609,7 +2609,7 @@ export class TauntTag extends MoveRestrictionBattlerTag {
override onAdd(pokemon: Pokemon) {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:tauntOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500);
globalScene.queueMessage(i18next.t("battlerTags:tauntOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500);
}
/**
@ -2698,7 +2698,7 @@ export class SyrupBombTag extends BattlerTag {
*/
override onAdd(pokemon: Pokemon) {
super.onAdd(pokemon);
gScene.queueMessage(i18next.t("battlerTags:syrupBombOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:syrupBombOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
/**
@ -2708,12 +2708,12 @@ export class SyrupBombTag extends BattlerTag {
* @returns `true` if the `turnCount` is still greater than `0`; `false` if the `turnCount` is `0` or the target or source Pokemon has been removed from the field
*/
override lapse(pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean {
if (this.sourceId && !gScene.getPokemonById(this.sourceId)?.isActive(true)) {
if (this.sourceId && !globalScene.getPokemonById(this.sourceId)?.isActive(true)) {
return false;
}
// Custom message in lieu of an animation in mainline
gScene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
gScene.unshiftPhase(new StatStageChangePhase(
globalScene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.unshiftPhase(new StatStageChangePhase(
pokemon.getBattlerIndex(), true,
[ Stat.SPD ], -1, true, false, true
));
@ -2733,7 +2733,7 @@ export class TelekinesisTag extends BattlerTag {
}
override onAdd(pokemon: Pokemon) {
gScene.queueMessage(i18next.t("battlerTags:telekinesisOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:telekinesisOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
}
@ -2748,12 +2748,12 @@ export class PowerTrickTag extends BattlerTag {
onAdd(pokemon: Pokemon): void {
this.swapStat(pokemon);
gScene.queueMessage(i18next.t("battlerTags:powerTrickActive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:powerTrickActive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
onRemove(pokemon: Pokemon): void {
this.swapStat(pokemon);
gScene.queueMessage(i18next.t("battlerTags:powerTrickActive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("battlerTags:powerTrickActive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
}
/**
@ -2977,7 +2977,7 @@ export function loadBattlerTag(source: BattlerTag | any): BattlerTag {
* corresponding {@linkcode Move} and user {@linkcode Pokemon}
*/
function getMoveEffectPhaseData(pokemon: Pokemon): {phase: MoveEffectPhase, attacker: Pokemon, move: Move} | null {
const phase = gScene.getCurrentPhase();
const phase = globalScene.getCurrentPhase();
if (phase instanceof MoveEffectPhase) {
return {
phase : phase,

View File

@ -9,7 +9,7 @@ import { BerryType } from "#enums/berry-type";
import { Stat, type BattleStat } from "#app/enums/stat";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export function getBerryName(berryType: BerryType): string {
return i18next.t(`berry:${BerryType[berryType]}.name`);
@ -74,7 +74,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
}
const hpHealed = new Utils.NumberHolder(Utils.toDmgValue(pokemon.getMaxHp() / 4));
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, hpHealed);
gScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
hpHealed.value, i18next.t("battle:hpHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: getBerryName(berryType) }), true));
};
case BerryType.LUM:
@ -83,7 +83,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
pokemon.battleData.berriesEaten.push(berryType);
}
if (pokemon.status) {
gScene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
globalScene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)));
}
pokemon.resetStatus(true, true);
pokemon.updateInfo();
@ -101,7 +101,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
const stat: BattleStat = berryType - BerryType.ENIGMA;
const statStages = new Utils.NumberHolder(1);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statStages);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], statStages.value));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ stat ], statStages.value));
};
case BerryType.LANSAT:
return (pokemon: Pokemon) => {
@ -118,7 +118,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
const randStat = Utils.randSeedInt(Stat.SPD, Stat.ATK);
const stages = new Utils.NumberHolder(2);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ randStat ], stages.value));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ randStat ], stages.value));
};
case BerryType.LEPPA:
return (pokemon: Pokemon) => {
@ -128,7 +128,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
const ppRestoreMove = pokemon.getMoveset().find(m => !m?.getPpRatio()) ? pokemon.getMoveset().find(m => !m?.getPpRatio()) : pokemon.getMoveset().find(m => m!.getPpRatio() < 1); // TODO: is this bang correct?
if (ppRestoreMove !== undefined) {
ppRestoreMove!.ppUsed = Math.max(ppRestoreMove!.ppUsed - 10, 0);
gScene.queueMessage(i18next.t("battle:ppHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: ppRestoreMove!.getName(), berryName: getBerryName(berryType) }));
globalScene.queueMessage(i18next.t("battle:ppHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: ppRestoreMove!.getName(), berryName: getBerryName(berryType) }));
}
};
}

View File

@ -1,6 +1,6 @@
import { PartyMemberStrength } from "#enums/party-member-strength";
import { Species } from "#enums/species";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { PlayerPokemon } from "#app/field/pokemon";
import { Starter } from "#app/ui/starter-select-ui-handler";
import * as Utils from "#app/utils";
@ -28,8 +28,8 @@ export function fetchDailyRunSeed(): Promise<string | null> {
export function getDailyRunStarters(seed: string): Starter[] {
const starters: Starter[] = [];
gScene.executeWithSeedOffset(() => {
const startingLevel = gScene.gameMode.getStartingLevel();
globalScene.executeWithSeedOffset(() => {
const startingLevel = globalScene.gameMode.getStartingLevel();
if (/\d{18}$/.test(seed)) {
for (let s = 0; s < 3; s++) {

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { PlayerPokemon } from "#app/field/pokemon";
import { DexEntry, StarterDataEntry } from "#app/system/game-data";
@ -36,8 +36,8 @@ export class EggHatchData {
* Used before updating the dex, so comparing the pokemon to these entries will show the new attributes
*/
setDex() {
const currDexEntry = gScene.gameData.dexData[this.pokemon.species.speciesId];
const currStarterDataEntry = gScene.gameData.starterData[this.pokemon.species.getRootSpeciesId()];
const currDexEntry = globalScene.gameData.dexData[this.pokemon.species.speciesId];
const currStarterDataEntry = globalScene.gameData.starterData[this.pokemon.species.getRootSpeciesId()];
this.dexEntryBeforeUpdate = {
seenAttr: currDexEntry.seenAttr,
caughtAttr: currDexEntry.caughtAttr,
@ -83,9 +83,9 @@ export class EggHatchData {
*/
updatePokemon(showMessage : boolean = false) {
return new Promise<void>(resolve => {
gScene.gameData.setPokemonCaught(this.pokemon, true, true, showMessage).then(() => {
gScene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
gScene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex, showMessage).then((value) => {
globalScene.gameData.setPokemonCaught(this.pokemon, true, true, showMessage).then(() => {
globalScene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
globalScene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex, showMessage).then((value) => {
this.setEggMoveUnlocked(value);
resolve();
});

View File

@ -1,4 +1,4 @@
import BattleScene, { gScene } from "#app/battle-scene";
import BattleScene, { globalScene } from "#app/battle-scene";
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { VariantTier } from "#enums/variant-tier";
@ -233,7 +233,7 @@ export class Egg {
}
// This function has way to many optional parameters
ret = gScene.addPlayerPokemon(pokemonSpecies, 1, abilityIndex, undefined, undefined, false);
ret = globalScene.addPlayerPokemon(pokemonSpecies, 1, abilityIndex, undefined, undefined, false);
ret.shiny = this._isShiny;
ret.variant = this._variantTier;
@ -245,7 +245,7 @@ export class Egg {
};
ret = ret!; // Tell TS compiler it's defined now
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
generatePlayerPokemonHelper();
}, this._id, EGG_SEED.toString());
@ -254,7 +254,7 @@ export class Egg {
// Doesn't need to be called if the egg got pulled by a gacha machiene
public addEggToGameData(): void {
gScene.gameData.eggs.push(this);
globalScene.gameData.eggs.push(this);
}
public getEggDescriptor(): string {
@ -352,7 +352,7 @@ export class Egg {
}
private rollSpecies(): Species | null {
if (!gScene) {
if (!globalScene) {
return null;
}
/**
@ -405,8 +405,8 @@ export class Egg {
.filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
// If this is the 10th egg without unlocking something new, attempt to force it.
if (gScene.gameData.unlockPity[this.tier] >= 9) {
const lockedPool = speciesPool.filter(s => !gScene.gameData.dexData[s].caughtAttr && !gScene.gameData.eggs.some(e => e.species === s));
if (globalScene.gameData.unlockPity[this.tier] >= 9) {
const lockedPool = speciesPool.filter(s => !globalScene.gameData.dexData[s].caughtAttr && !globalScene.gameData.eggs.some(e => e.species === s));
if (lockedPool.length) { // Skip this if everything is unlocked
speciesPool = lockedPool;
}
@ -453,10 +453,10 @@ export class Egg {
}
species = species!; // tell TS compiled it's defined now!
if (gScene.gameData.dexData[species].caughtAttr || gScene.gameData.eggs.some(e => e.species === species)) {
gScene.gameData.unlockPity[this.tier] = Math.min(gScene.gameData.unlockPity[this.tier] + 1, 10);
if (globalScene.gameData.dexData[species].caughtAttr || globalScene.gameData.eggs.some(e => e.species === species)) {
globalScene.gameData.unlockPity[this.tier] = Math.min(globalScene.gameData.unlockPity[this.tier] + 1, 10);
} else {
gScene.gameData.unlockPity[this.tier] = 0;
globalScene.gameData.unlockPity[this.tier] = 0;
}
return species;
@ -502,36 +502,36 @@ export class Egg {
private checkForPityTierOverrides(): void {
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
gScene.gameData.eggPity[EggTier.RARE] += 1;
gScene.gameData.eggPity[EggTier.EPIC] += 1;
gScene.gameData.eggPity[EggTier.LEGENDARY] += 1 + tierValueOffset;
globalScene.gameData.eggPity[EggTier.RARE] += 1;
globalScene.gameData.eggPity[EggTier.EPIC] += 1;
globalScene.gameData.eggPity[EggTier.LEGENDARY] += 1 + tierValueOffset;
// These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered.
if (gScene.gameData.eggPity[EggTier.LEGENDARY] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) {
if (globalScene.gameData.eggPity[EggTier.LEGENDARY] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) {
this._tier = EggTier.LEGENDARY;
} else if (gScene.gameData.eggPity[EggTier.EPIC] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) {
} else if (globalScene.gameData.eggPity[EggTier.EPIC] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) {
this._tier = EggTier.EPIC;
} else if (gScene.gameData.eggPity[EggTier.RARE] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) {
} else if (globalScene.gameData.eggPity[EggTier.RARE] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) {
this._tier = EggTier.RARE;
}
gScene.gameData.eggPity[this._tier] = 0;
globalScene.gameData.eggPity[this._tier] = 0;
}
private increasePullStatistic(): void {
gScene.gameData.gameStats.eggsPulled++;
globalScene.gameData.gameStats.eggsPulled++;
if (this.isManaphyEgg()) {
gScene.gameData.gameStats.manaphyEggsPulled++;
globalScene.gameData.gameStats.manaphyEggsPulled++;
this._hatchWaves = this.getEggTierDefaultHatchWaves(EggTier.EPIC);
return;
}
switch (this.tier) {
case EggTier.RARE:
gScene.gameData.gameStats.rareEggsPulled++;
globalScene.gameData.gameStats.rareEggsPulled++;
break;
case EggTier.EPIC:
gScene.gameData.gameStats.epicEggsPulled++;
globalScene.gameData.gameStats.epicEggsPulled++;
break;
case EggTier.LEGENDARY:
gScene.gameData.gameStats.legendaryEggsPulled++;
globalScene.gameData.gameStats.legendaryEggsPulled++;
break;
}
}
@ -563,7 +563,7 @@ export function getLegendaryGachaSpeciesForTimestamp(timestamp: number): Species
const offset = Math.floor(Math.floor(dayTimestamp / 86400000) / legendarySpecies.length); // Cycle number
const index = Math.floor(dayTimestamp / 86400000) % legendarySpecies.length; // Index within cycle
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
ret = Phaser.Math.RND.shuffle(legendarySpecies)[index];
}, offset, EGG_SEED.toString());
ret = ret!; // tell TS compiler it's

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { trainerConfigs, } from "#app/data/trainer-config";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
@ -37,7 +37,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
])
.withAutoHideIntroVisuals(false)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Randomly pick from 1 of the 5 stat trainers to spawn
let trainerType: TrainerType;
@ -139,7 +139,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
buttonTooltip: `${namespace}:option.1.tooltip`
},
async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Battle the stat trainer for an Egg and great rewards
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
@ -162,9 +162,9 @@ export const ATrainersTestEncounter: MysteryEncounter =
buttonTooltip: `${namespace}:option.2.tooltip`
},
async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Full heal party
gScene.unshiftPhase(new PartyHealPhase(true));
globalScene.unshiftPhase(new PartyHealPhase(true));
const eggOptions: IEggOptions = {
pulled: false,

View File

@ -3,7 +3,7 @@ import Pokemon, { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
import { BerryModifierType, modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Species } from "#enums/species";
import { gScene } from "#app/battle-scene";
import { globalScene } 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";
@ -171,17 +171,17 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
gScene.loadSe("PRSFX- Bug Bite", "battle_anims", "PRSFX- Bug Bite.wav");
gScene.loadSe("Follow Me", "battle_anims", "Follow Me.mp3");
globalScene.loadSe("PRSFX- Bug Bite", "battle_anims", "PRSFX- Bug Bite.wav");
globalScene.loadSe("Follow Me", "battle_anims", "Follow Me.mp3");
// Get all player berry items, remove from party, and store reference
const berryItems = gScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
const berryItems = globalScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
// Sort berries by party member ID to more easily re-add later if necessary
const berryItemsMap = new Map<number, BerryModifier[]>();
gScene.getParty().forEach(pokemon => {
globalScene.getParty().forEach(pokemon => {
const pokemonBerries = berryItems.filter(b => b.pokemonId === pokemon.id);
if (pokemonBerries?.length > 0) {
berryItemsMap.set(pokemon.id, pokemonBerries);
@ -204,7 +204,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
// Do NOT remove the real berries yet or else it will be persisted in the session data
// SpDef buff below wave 50, +1 to all stats otherwise
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = gScene.currentBattle.waveIndex < 50 ?
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = globalScene.currentBattle.waveIndex < 50 ?
[ Stat.SPDEF ] :
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
@ -221,7 +221,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(`${namespace}:option.1.boss_enraged`);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
}
}
],
@ -238,12 +238,12 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
// Remove the berries from the party
// Session has been safely saved at this point, so data won't be lost
const berryItems = gScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
const berryItems = globalScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
berryItems.forEach(berryMod => {
gScene.removeModifier(berryMod);
globalScene.removeModifier(berryMod);
});
gScene.updateModifiers(true);
globalScene.updateModifiers(true);
return true;
})
@ -261,18 +261,18 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Pick battle
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Provides 1x Reviver Seed to each party member at end of battle
const revSeed = generateModifierType(modifierTypes.REVIVER_SEED);
encounter.setDialogueToken("foodReward", revSeed?.name ?? i18next.t("modifierType:ModifierType.REVIVER_SEED.name"));
const givePartyPokemonReviverSeeds = () => {
const party = gScene.getParty();
const party = globalScene.getParty();
party.forEach(p => {
const heldItems = p.getHeldItems();
if (revSeed && !heldItems.some(item => item instanceof PokemonInstantReviveModifier)) {
const seedModifier = revSeed.newModifier(p);
gScene.addModifier(seedModifier, false, false, false, true);
globalScene.addModifier(seedModifier, false, false, false, true);
}
});
queueEncounterMessage(`${namespace}:option.1.food_stash`);
@ -304,11 +304,11 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
],
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const berryMap = encounter.misc.berryItemsMap;
// Returns 2/5 of the berries stolen to each Pokemon
const party = gScene.getParty();
const party = globalScene.getParty();
party.forEach(pokemon => {
const stolenBerries: BerryModifier[] = berryMap.get(pokemon.id);
const berryTypesAsArray: BerryType[] = [];
@ -326,7 +326,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
}
}
});
await gScene.updateModifiers(true);
await globalScene.updateModifiers(true);
await transitionMysteryEncounterIntroVisuals(true, true, 500);
leaveEncounterWithoutBattle(true);
@ -371,10 +371,10 @@ function doGreedentSpriteSteal() {
const shakeDelay = 50;
const slideDelay = 500;
const greedentSprites = gScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(1);
const greedentSprites = globalScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(1);
gScene.playSound("battle_anims/Follow Me");
gScene.tweens.chain({
globalScene.playSound("battle_anims/Follow Me");
globalScene.tweens.chain({
targets: greedentSprites,
tweens: [
{ // Slide Greedent diagonally
@ -445,9 +445,9 @@ function doGreedentSpriteSteal() {
}
function doGreedentEatBerries() {
const greedentSprites = gScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(1);
const greedentSprites = globalScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(1);
let index = 1;
gScene.tweens.add({
globalScene.tweens.add({
targets: greedentSprites,
duration: 150,
ease: "Cubic.easeOut",
@ -455,11 +455,11 @@ function doGreedentEatBerries() {
y: "-=8",
loop: 5,
onStart: () => {
gScene.playSound("battle_anims/PRSFX- Bug Bite");
globalScene.playSound("battle_anims/PRSFX- Bug Bite");
},
onLoop: () => {
if (index % 2 === 0) {
gScene.playSound("battle_anims/PRSFX- Bug Bite");
globalScene.playSound("battle_anims/PRSFX- Bug Bite");
}
index++;
}
@ -477,7 +477,7 @@ function doBerrySpritePile(isEat: boolean = false) {
if (isEat) {
animationOrder = animationOrder.reverse();
}
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
animationOrder.forEach((berry, i) => {
const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey?.includes(berry));
let sprite: Phaser.GameObjects.Sprite, tintSprite: Phaser.GameObjects.Sprite;
@ -486,7 +486,7 @@ function doBerrySpritePile(isEat: boolean = false) {
sprite = sprites[0];
tintSprite = sprites[1];
}
gScene.time.delayedCall(berryAddDelay * i + 400, () => {
globalScene.time.delayedCall(berryAddDelay * i + 400, () => {
if (sprite) {
sprite.setVisible(!isEat);
}
@ -496,7 +496,7 @@ function doBerrySpritePile(isEat: boolean = false) {
// Animate Petaya berry falling off the pile
if (berry === "petaya" && sprite && tintSprite && !isEat) {
gScene.time.delayedCall(200, () => {
globalScene.time.delayedCall(200, () => {
doBerryBounce([ sprite, tintSprite ], 30, 500);
});
}
@ -509,7 +509,7 @@ function doBerryBounce(berrySprites: Phaser.GameObjects.Sprite[], yd: number, ba
let bounceYOffset = yd;
const doBounce = () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: berrySprites,
y: "+=" + bounceYOffset,
x: { value: "+=" + (bouncePower * bouncePower * 10), ease: "Linear" },
@ -521,7 +521,7 @@ function doBerryBounce(berrySprites: Phaser.GameObjects.Sprite[], yd: number, ba
if (bouncePower) {
bounceYOffset = bounceYOffset * bouncePower;
gScene.tweens.add({
globalScene.tweens.add({
targets: berrySprites,
y: "-=" + bounceYOffset,
x: { value: "+=" + (bouncePower * bouncePower * 10), ease: "Linear" },

View File

@ -2,7 +2,7 @@ import { generateModifierType, leaveEncounterWithoutBattle, setEncounterExp, upd
import { modifierTypes } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Species } from "#enums/species";
import { gScene } from "#app/battle-scene";
import { globalScene } 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";
@ -70,13 +70,13 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const pokemon = getHighestStatTotalPlayerPokemon(true, true);
const baseSpecies = pokemon.getSpeciesForm().getRootSpeciesId();
const starterValue: number = speciesStarterCosts[baseSpecies] ?? 1;
const multiplier = Math.max(MONEY_MAXIMUM_MULTIPLIER / 10 * starterValue, MONEY_MINIMUM_MULTIPLIER);
const price = gScene.getWaveMoneyAmount(multiplier);
const price = globalScene.getWaveMoneyAmount(multiplier);
encounter.setDialogueToken("strongestPokemon", pokemon.getNameToRender());
encounter.setDialogueToken("price", price.toString());
@ -119,15 +119,15 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
],
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Update money and remove pokemon from party
updatePlayerMoney(encounter.misc.price);
gScene.removePokemonFromPlayerParty(encounter.misc.pokemon);
globalScene.removePokemonFromPlayerParty(encounter.misc.pokemon);
return true;
})
.withOptionPhase(async () => {
// Give the player a Shiny Charm
gScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.SHINY_CHARM));
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.SHINY_CHARM));
leaveEncounterWithoutBattle(true);
})
.build()
@ -154,7 +154,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Extort the rich kid for money
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Update money and remove pokemon from party
updatePlayerMoney(encounter.misc.price);

View File

@ -20,7 +20,7 @@ import {
import { randSeedInt } from "#app/utils";
import { BattlerTagType } from "#enums/battler-tag-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import { getPokemonNameWithAffix } from "#app/messages";
@ -58,11 +58,11 @@ export const BerriesAboundEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculate boss mon
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
const bossSpecies = gScene.arena.randomSpecies(gScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(gScene.getParty()), true);
const bossSpecies = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getParty()), true);
const bossPokemon = new EnemyPokemon(bossSpecies, level, TrainerSlot.NONE, true);
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
const config: EnemyPartyConfig = {
@ -78,10 +78,10 @@ export const BerriesAboundEncounter: MysteryEncounter =
// Calculate the number of extra berries that player receives
// 10-40: 2, 40-120: 4, 120-160: 5, 160-180: 7
const numBerries =
gScene.currentBattle.waveIndex > 160 ? 7
: gScene.currentBattle.waveIndex > 120 ? 5
: gScene.currentBattle.waveIndex > 40 ? 4 : 2;
regenerateModifierPoolThresholds(gScene.getParty(), ModifierPoolType.PLAYER, 0);
globalScene.currentBattle.waveIndex > 160 ? 7
: globalScene.currentBattle.waveIndex > 120 ? 5
: globalScene.currentBattle.waveIndex > 40 ? 4 : 2;
regenerateModifierPoolThresholds(globalScene.getParty(), ModifierPoolType.PLAYER, 0);
encounter.misc = { numBerries };
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(bossPokemon);
@ -130,13 +130,13 @@ export const BerriesAboundEncounter: MysteryEncounter =
},
async () => {
// Pick battle
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const numBerries = encounter.misc.numBerries;
const doBerryRewards = () => {
const berryText = i18next.t(`${namespace}:berries`);
gScene.playSound("item_fanfare");
globalScene.playSound("item_fanfare");
queueEncounterMessage(i18next.t("battle:rewardGainCount", { modifierName: berryText, count: numBerries }));
// Generate a random berry and give it to the first Pokemon with room for it
@ -155,7 +155,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
}
setEncounterRewards({ guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
await initBattleWithEnemyConfig(gScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
await initBattleWithEnemyConfig(globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
}
)
.withOption(
@ -167,7 +167,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Pick race for berries
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const fastestPokemon: PlayerPokemon = encounter.misc.fastestPokemon;
const enemySpeed: number = encounter.misc.enemySpeed;
const speedDiff = fastestPokemon.getStat(Stat.SPD) / (enemySpeed * 1.1);
@ -187,7 +187,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
const doBerryRewards = () => {
const berryText = i18next.t(`${namespace}:berries`);
gScene.playSound("item_fanfare");
globalScene.playSound("item_fanfare");
queueEncounterMessage(i18next.t("battle:rewardGainCount", { modifierName: berryText, count: numBerries }));
// Generate a random berry and give it to the first Pokemon with room for it
@ -197,15 +197,15 @@ export const BerriesAboundEncounter: MysteryEncounter =
};
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = gScene.currentBattle.waveIndex < 50 ?
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = globalScene.currentBattle.waveIndex < 50 ?
[ Stat.DEF, Stat.SPDEF, Stat.SPD ] :
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
const config = gScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
const config = globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
config.pokemonConfigs![0].tags = [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ];
config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
queueEncounterMessage(`${namespace}:option.2.boss_enraged`);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
};
setEncounterRewards({ guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
await showEncounterText(`${namespace}:option.2.selected_bad`);
@ -218,7 +218,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
const doFasterBerryRewards = () => {
const berryText = i18next.t(`${namespace}:berries`);
gScene.playSound("item_fanfare");
globalScene.playSound("item_fanfare");
queueEncounterMessage(i18next.t("battle:rewardGainCount", { modifierName: berryText, count: numBerriesGrabbed }));
// Generate a random berry and give it to the first Pokemon with room for it (trying to give to fastest first)
@ -257,11 +257,11 @@ function tryGiveBerry(prioritizedPokemon?: PlayerPokemon) {
const berryType = randSeedInt(Object.keys(BerryType).filter(s => !isNaN(Number(s))).length) as BerryType;
const berry = generateModifierType(modifierTypes.BERRY, [ berryType ]) as BerryModifierType;
const party = gScene.getParty();
const party = globalScene.getParty();
// Will try to apply to prioritized pokemon first, then do normal application method if it fails
if (prioritizedPokemon) {
const heldBerriesOfType = gScene.findModifier(m => m instanceof BerryModifier
const heldBerriesOfType = globalScene.findModifier(m => m instanceof BerryModifier
&& m.pokemonId === prioritizedPokemon.id && (m as BerryModifier).berryType === berryType, true) as BerryModifier;
if (!heldBerriesOfType || heldBerriesOfType.getStackCount() < heldBerriesOfType.getMaxStackCount()) {
@ -272,7 +272,7 @@ function tryGiveBerry(prioritizedPokemon?: PlayerPokemon) {
// Iterate over the party until berry was successfully given
for (const pokemon of party) {
const heldBerriesOfType = gScene.findModifier(m => m instanceof BerryModifier
const heldBerriesOfType = globalScene.findModifier(m => m instanceof BerryModifier
&& m.pokemonId === pokemon.id && (m as BerryModifier).berryType === berryType, true) as BerryModifier;
if (!heldBerriesOfType || heldBerriesOfType.getStackCount() < heldBerriesOfType.getMaxStackCount()) {

View File

@ -18,7 +18,7 @@ import {
} from "#app/data/trainer-config";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { PartyMemberStrength } from "#enums/party-member-strength";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#app/utils";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -216,11 +216,11 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculates what trainers are available for battle in the encounter
// Bug type superfan trainer config
const config = getTrainerConfigForWave(gScene.currentBattle.waveIndex);
const config = getTrainerConfigForWave(globalScene.currentBattle.waveIndex);
const spriteKey = config.getSpriteKey();
encounter.enemyPartyConfigs.push({
trainerConfig: config,
@ -228,7 +228,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
});
let beedrillKeys: { spriteKey: string, fileRoot: string }, butterfreeKeys: { spriteKey: string, fileRoot: string };
if (gScene.currentBattle.waveIndex < WAVE_LEVEL_BREAKPOINTS[3]) {
if (globalScene.currentBattle.waveIndex < WAVE_LEVEL_BREAKPOINTS[3]) {
beedrillKeys = getSpriteKeysFromSpecies(Species.BEEDRILL, false);
butterfreeKeys = getSpriteKeysFromSpecies(Species.BUTTERFREE, false);
} else {
@ -298,7 +298,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
},
async () => {
// Select battle the bug trainer
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
// Init the moves available for tutor
@ -329,10 +329,10 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
})
.withPreOptionPhase(async () => {
// Player shows off their bug types
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Player gets different rewards depending on the number of bug types they have
const numBugTypes = gScene.getParty().filter(p => p.isOfType(Type.BUG, true)).length;
const numBugTypes = globalScene.getParty().filter(p => p.isOfType(Type.BUG, true)).length;
const numBugTypesText = i18next.t(`${namespace}:numBugTypes`, { count: numBugTypes });
encounter.setDialogueToken("numBugTypes", numBugTypesText);
@ -366,10 +366,10 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
const modifierOptions: ModifierTypeOption[] = [ generateModifierTypeOption(modifierTypes.MASTER_BALL)! ];
const specialOptions: ModifierTypeOption[] = [];
if (!gScene.findModifier(m => m instanceof MegaEvolutionAccessModifier)) {
if (!globalScene.findModifier(m => m instanceof MegaEvolutionAccessModifier)) {
modifierOptions.push(generateModifierTypeOption(modifierTypes.MEGA_BRACELET)!);
}
if (!gScene.findModifier(m => m instanceof GigantamaxAccessModifier)) {
if (!globalScene.findModifier(m => m instanceof GigantamaxAccessModifier)) {
modifierOptions.push(generateModifierTypeOption(modifierTypes.DYNAMAX_BAND)!);
}
const nonRareEvolutionModifier = generateModifierTypeOption(modifierTypes.EVOLUTION_ITEM);
@ -431,7 +431,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
secondOptionPrompt: `${namespace}:option.3.select_prompt`,
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Get Pokemon held items and filter for valid ones
@ -476,15 +476,15 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const modifier = encounter.misc.chosenModifier;
// Remove the modifier if its stacks go to 0
modifier.stackCount -= 1;
if (modifier.stackCount === 0) {
gScene.removeModifier(modifier);
globalScene.removeModifier(modifier);
}
gScene.updateModifiers(true, true);
globalScene.updateModifiers(true, true);
const bugNet = generateModifierTypeOption(modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!;
bugNet.type.tier = ModifierTier.ROGUE;
@ -648,7 +648,7 @@ function getTrainerConfigForWave(waveIndex: number) {
function doBugTypeMoveTutor(): Promise<void> {
return new Promise<void>(async resolve => {
const moveOptions = gScene.currentBattle.mysteryEncounter!.misc.moveTutorOptions;
const moveOptions = globalScene.currentBattle.mysteryEncounter!.misc.moveTutorOptions;
await showEncounterDialogue(`${namespace}:battle_won`, `${namespace}:speaker`);
const overlayScale = 1;
@ -659,9 +659,9 @@ function doBugTypeMoveTutor(): Promise<void> {
right: true,
x: 1,
y: -MoveInfoOverlay.getHeight(overlayScale, true) - 1,
width: (gScene.game.canvas.width / 6) - 2,
width: (globalScene.game.canvas.width / 6) - 2,
});
gScene.ui.add(moveInfoOverlay);
globalScene.ui.add(moveInfoOverlay);
const optionSelectItems = moveOptions.map((move: PokemonMove) => {
const option: OptionSelectItem = {
@ -695,7 +695,7 @@ function doBugTypeMoveTutor(): Promise<void> {
// Option select complete, handle if they are learning a move
if (result && result.selectedOptionIndex < moveOptions.length) {
gScene.unshiftPhase(new LearnMovePhase(result.selectedPokemonIndex, moveOptions[result.selectedOptionIndex].moveId));
globalScene.unshiftPhase(new LearnMovePhase(result.selectedPokemonIndex, moveOptions[result.selectedOptionIndex].moveId));
}
// Complete battle and go to rewards

View File

@ -4,7 +4,7 @@ import { ModifierTier } from "#app/modifier/modifier-tier";
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { PartyMemberStrength } from "#enums/party-member-strength";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { Species } from "#enums/species";
@ -106,7 +106,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const clownTrainerType = TrainerType.HARLEQUIN;
const clownConfig = trainerConfigs[clownTrainerType].clone();
@ -166,7 +166,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
],
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Spawn battle
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
@ -205,15 +205,15 @@ export const ClowningAroundEncounter: MysteryEncounter =
// Play animations once ability swap is complete
// Trainer sprite that is shown at end of battle is not the same as mystery encounter intro visuals
gScene.tweens.add({
targets: gScene.currentBattle.trainer,
globalScene.tweens.add({
targets: globalScene.currentBattle.trainer,
x: "+=16",
y: "-=16",
alpha: 0,
ease: "Sine.easeInOut",
duration: 250
});
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, gScene.getPlayerPokemon()!, gScene.getPlayerPokemon());
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, globalScene.getPlayerPokemon()!, globalScene.getPlayerPokemon());
background.playWithoutTargets(230, 40, 2);
return true;
})
@ -243,9 +243,9 @@ export const ClowningAroundEncounter: MysteryEncounter =
// Swap player's items on pokemon with the most items
// Item comparisons look at whichever Pokemon has the greatest number of TRANSFERABLE, non-berry items
// So Vitamins, form change items, etc. are not included
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const party = gScene.getParty();
const party = globalScene.getParty();
let mostHeldItemsPokemon = party[0];
let count = mostHeldItemsPokemon.getHeldItems()
.filter(m => m.isTransferable && !(m instanceof BerryModifier))
@ -270,7 +270,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
items.filter(m => m instanceof BerryModifier)
.forEach(m => {
numBerries += m.stackCount;
gScene.removeModifier(m);
globalScene.removeModifier(m);
});
generateItemsOfTier(mostHeldItemsPokemon, numBerries, "Berries");
@ -284,10 +284,10 @@ export const ClowningAroundEncounter: MysteryEncounter =
const tier = type.tier ?? ModifierTier.ULTRA;
if (type.id === "GOLDEN_EGG" || tier === ModifierTier.ROGUE) {
numRogue += m.stackCount;
gScene.removeModifier(m);
globalScene.removeModifier(m);
} else if (type.id === "LUCKY_EGG" || tier === ModifierTier.ULTRA) {
numUltra += m.stackCount;
gScene.removeModifier(m);
globalScene.removeModifier(m);
}
});
@ -299,7 +299,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
})
.withPostOptionPhase(async () => {
// Play animations
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, gScene.getPlayerPokemon()!, gScene.getPlayerPokemon());
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, globalScene.getPlayerPokemon()!, globalScene.getPlayerPokemon());
background.playWithoutTargets(230, 40, 2);
await transitionMysteryEncounterIntroVisuals(true, true, 200);
})
@ -328,7 +328,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
.withPreOptionPhase(async () => {
// Randomize the second type of all player's pokemon
// If the pokemon does not normally have a second type, it will gain 1
for (const pokemon of gScene.getParty()) {
for (const pokemon of globalScene.getParty()) {
const originalTypes = pokemon.getTypes(false, false, true);
// If the Pokemon has non-status moves that don't match the Pokemon's type, prioritizes those as the new type
@ -370,7 +370,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
})
.withPostOptionPhase(async () => {
// Play animations
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, gScene.getPlayerPokemon()!, gScene.getPlayerPokemon());
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, globalScene.getPlayerPokemon()!, globalScene.getPlayerPokemon());
background.playWithoutTargets(230, 40, 2);
await transitionMysteryEncounterIntroVisuals(true, true, 200);
})
@ -388,7 +388,7 @@ async function handleSwapAbility() {
await showEncounterDialogue(`${namespace}:option.1.apply_ability_dialogue`, `${namespace}:speaker`);
await showEncounterText(`${namespace}:option.1.apply_ability_message`);
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
displayYesNoOptions(resolve);
});
});
@ -418,21 +418,21 @@ function displayYesNoOptions(resolve) {
maxOptions: 7,
yOffset: 0
};
gScene.ui.setModeWithoutClear(Mode.OPTION_SELECT, config, null, true);
globalScene.ui.setModeWithoutClear(Mode.OPTION_SELECT, config, null, true);
}
function onYesAbilitySwap(resolve) {
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Do ability swap
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
applyAbilityOverrideToPokemon(pokemon, encounter.misc.ability);
encounter.setDialogueToken("chosenPokemon", pokemon.getNameToRender());
gScene.ui.setMode(Mode.MESSAGE).then(() => resolve(true));
globalScene.ui.setMode(Mode.MESSAGE).then(() => resolve(true));
};
const onPokemonNotSelected = () => {
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
displayYesNoOptions(resolve);
});
};

View File

@ -2,7 +2,7 @@ import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattl
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Species } from "#enums/species";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -92,7 +92,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
.withCatchAllowed(true)
.withFleeAllowed(false)
.withOnVisualsStart(() => {
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, gScene.getEnemyPokemon()!, gScene.getParty()[0]);
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, globalScene.getEnemyPokemon()!, globalScene.getParty()[0]);
danceAnim.play();
return true;
@ -107,7 +107,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const species = getPokemonSpecies(Species.ORICORIO);
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
@ -122,7 +122,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
// Set the form index based on the biome
// Defaults to Baile style if somehow nothing matches
const currentBiome = gScene.arena.biomeType;
const currentBiome = globalScene.arena.biomeType;
if (BAILE_STYLE_BIOMES.includes(currentBiome)) {
enemyPokemon.formIndex = 0;
} else if (POM_POM_STYLE_BIOMES.includes(currentBiome)) {
@ -136,14 +136,14 @@ export const DancingLessonsEncounter: MysteryEncounter =
}
const oricorioData = new PokemonData(enemyPokemon);
const oricorio = gScene.addEnemyPokemon(species, level, TrainerSlot.NONE, false, oricorioData);
const oricorio = globalScene.addEnemyPokemon(species, level, TrainerSlot.NONE, false, oricorioData);
// Adds a real Pokemon sprite to the field (required for the animation)
gScene.getEnemyParty().forEach(enemyPokemon => {
gScene.field.remove(enemyPokemon, true);
globalScene.getEnemyParty().forEach(enemyPokemon => {
globalScene.field.remove(enemyPokemon, true);
});
gScene.currentBattle.enemyParty = [ oricorio ];
gScene.field.add(oricorio);
globalScene.currentBattle.enemyParty = [ oricorio ];
globalScene.field.add(oricorio);
// Spawns on offscreen field
oricorio.x -= 300;
encounter.loadAssets.push(oricorio.loadAssets());
@ -157,7 +157,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(`${namespace}:option.1.boss_enraged`);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF ], 1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF ], 1));
}
}],
};
@ -184,7 +184,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Pick battle
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
encounter.startOfBattleEffects.push({
sourceBattlerIndex: BattlerIndex.ENEMY,
@ -213,14 +213,14 @@ export const DancingLessonsEncounter: MysteryEncounter =
})
.withPreOptionPhase(async () => {
// Learn its Dance
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
encounter.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
gScene.unshiftPhase(new LearnMovePhase(gScene.getParty().indexOf(pokemon), Moves.REVELATION_DANCE));
globalScene.unshiftPhase(new LearnMovePhase(globalScene.getParty().indexOf(pokemon), Moves.REVELATION_DANCE));
// Play animation again to "learn" the dance
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, gScene.getEnemyPokemon()!, gScene.getPlayerPokemon());
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, globalScene.getEnemyPokemon()!, globalScene.getPlayerPokemon());
danceAnim.play();
};
@ -250,7 +250,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
})
.withPreOptionPhase(async () => {
// Open menu for selecting pokemon with a Dancing move
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Return the options for nature selection
return pokemon.moveset
@ -289,7 +289,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Show the Oricorio a dance, and recruit it
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const oricorio = encounter.misc.oricorioData.toPokemon();
oricorio.passive = true;
@ -313,8 +313,8 @@ export const DancingLessonsEncounter: MysteryEncounter =
function hideOricorioPokemon() {
return new Promise<void>(resolve => {
const oricorioSprite = gScene.getEnemyParty()[0];
gScene.tweens.add({
const oricorioSprite = globalScene.getEnemyParty()[0];
globalScene.tweens.add({
targets: oricorioSprite,
x: "+=16",
y: "-=16",
@ -322,7 +322,7 @@ function hideOricorioPokemon() {
ease: "Sine.easeInOut",
duration: 750,
onComplete: () => {
gScene.field.remove(oricorioSprite, true);
globalScene.field.remove(oricorioSprite, true);
resolve();
}
});

View File

@ -2,7 +2,7 @@ import { Type } from "#app/data/type";
import { isNullOrUndefined, randSeedInt } from "#app/utils";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Species } from "#enums/species";
import { gScene } from "#app/battle-scene";
import { globalScene } 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";
@ -145,9 +145,9 @@ export const DarkDealEncounter: MysteryEncounter =
// Get all the pokemon's held items
const modifiers = removedPokemon.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier));
gScene.removePokemonFromPlayerParty(removedPokemon);
globalScene.removePokemonFromPlayerParty(removedPokemon);
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
encounter.setDialogueToken("pokeName", removedPokemon.getNameToRender());
// Store removed pokemon types
@ -158,14 +158,14 @@ export const DarkDealEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Give the player 5 Rogue Balls
const encounter = gScene.currentBattle.mysteryEncounter!;
gScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.ROGUE_BALL));
const encounter = globalScene.currentBattle.mysteryEncounter!;
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.ROGUE_BALL));
// Start encounter with random legendary (7-10 starter strength) that has level additive
// If this is a mono-type challenge, always ensure the required type is filtered for
let bossTypes: Type[] = encounter.misc.removedTypes;
const singleTypeChallenges = gScene.gameMode.challenges.filter(c => c.value && c.id === Challenges.SINGLE_TYPE);
if (gScene.gameMode.isChallenge && singleTypeChallenges.length > 0) {
const singleTypeChallenges = globalScene.gameMode.challenges.filter(c => c.value && c.id === Challenges.SINGLE_TYPE);
if (globalScene.gameMode.isChallenge && singleTypeChallenges.length > 0) {
bossTypes = singleTypeChallenges.map(c => (c.value - 1) as Type);
}

View File

@ -3,7 +3,7 @@ import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Species } from "#enums/species";
import { gScene } from "#app/battle-scene";
import { globalScene } 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";
@ -97,14 +97,14 @@ export const DelibirdyEncounter: MysteryEncounter =
}
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
encounter.setDialogueToken("delibirdName", getPokemonSpecies(Species.DELIBIRD).getName());
gScene.loadBgm("mystery_encounter_delibirdy", "mystery_encounter_delibirdy.mp3");
globalScene.loadBgm("mystery_encounter_delibirdy", "mystery_encounter_delibirdy.mp3");
return true;
})
.withOnVisualsStart(() => {
gScene.fadeAndSwitchBgm("mystery_encounter_delibirdy");
globalScene.fadeAndSwitchBgm("mystery_encounter_delibirdy");
return true;
})
.withOption(
@ -121,23 +121,23 @@ export const DelibirdyEncounter: MysteryEncounter =
],
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
updatePlayerMoney(-(encounter.options[0].requirements[0] as MoneyRequirement).requiredMoney, true, false);
return true;
})
.withOptionPhase(async () => {
// Give the player an Amulet Coin
// Check if the player has max stacks of that item already
const existing = gScene.findModifier(m => m instanceof MoneyMultiplierModifier) as MoneyMultiplierModifier;
const existing = globalScene.findModifier(m => m instanceof MoneyMultiplierModifier) as MoneyMultiplierModifier;
if (existing && existing.getStackCount() >= existing.getMaxStackCount()) {
// At max stacks, give the first party pokemon a Shell Bell instead
const shellBell = generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
await applyModifierTypeToPlayerPokemon(gScene.getParty()[0], shellBell);
gScene.playSound("item_fanfare");
await applyModifierTypeToPlayerPokemon(globalScene.getParty()[0], shellBell);
globalScene.playSound("item_fanfare");
await showEncounterText(i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true);
} else {
gScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.AMULET_COIN));
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.AMULET_COIN));
}
leaveEncounterWithoutBattle(true);
@ -159,7 +159,7 @@ export const DelibirdyEncounter: MysteryEncounter =
],
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Get Pokemon held items and filter for valid ones
const validItems = pokemon.getHeldItems().filter((it) => {
@ -196,42 +196,42 @@ export const DelibirdyEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const modifier: BerryModifier | HealingBoosterModifier = encounter.misc.chosenModifier;
// Give the player a Candy Jar if they gave a Berry, and a Berry Pouch for Reviver Seed
if (modifier instanceof BerryModifier) {
// Check if the player has max stacks of that Candy Jar already
const existing = gScene.findModifier(m => m instanceof LevelIncrementBoosterModifier) as LevelIncrementBoosterModifier;
const existing = globalScene.findModifier(m => m instanceof LevelIncrementBoosterModifier) as LevelIncrementBoosterModifier;
if (existing && existing.getStackCount() >= existing.getMaxStackCount()) {
// At max stacks, give the first party pokemon a Shell Bell instead
const shellBell = generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
await applyModifierTypeToPlayerPokemon(gScene.getParty()[0], shellBell);
gScene.playSound("item_fanfare");
await applyModifierTypeToPlayerPokemon(globalScene.getParty()[0], shellBell);
globalScene.playSound("item_fanfare");
await showEncounterText(i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true);
} else {
gScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.CANDY_JAR));
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.CANDY_JAR));
}
} else {
// Check if the player has max stacks of that Berry Pouch already
const existing = gScene.findModifier(m => m instanceof PreserveBerryModifier) as PreserveBerryModifier;
const existing = globalScene.findModifier(m => m instanceof PreserveBerryModifier) as PreserveBerryModifier;
if (existing && existing.getStackCount() >= existing.getMaxStackCount()) {
// At max stacks, give the first party pokemon a Shell Bell instead
const shellBell = generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
await applyModifierTypeToPlayerPokemon(gScene.getParty()[0], shellBell);
gScene.playSound("item_fanfare");
await applyModifierTypeToPlayerPokemon(globalScene.getParty()[0], shellBell);
globalScene.playSound("item_fanfare");
await showEncounterText(i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true);
} else {
gScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.BERRY_POUCH));
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.BERRY_POUCH));
}
}
// Remove the modifier if its stacks go to 0
modifier.stackCount -= 1;
if (modifier.stackCount === 0) {
gScene.removeModifier(modifier);
globalScene.removeModifier(modifier);
}
leaveEncounterWithoutBattle(true);
@ -253,7 +253,7 @@ export const DelibirdyEncounter: MysteryEncounter =
],
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Get Pokemon held items and filter for valid ones
const validItems = pokemon.getHeldItems().filter((it) => {
@ -290,26 +290,26 @@ export const DelibirdyEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const modifier = encounter.misc.chosenModifier;
// Check if the player has max stacks of Healing Charm already
const existing = gScene.findModifier(m => m instanceof HealingBoosterModifier) as HealingBoosterModifier;
const existing = globalScene.findModifier(m => m instanceof HealingBoosterModifier) as HealingBoosterModifier;
if (existing && existing.getStackCount() >= existing.getMaxStackCount()) {
// At max stacks, give the first party pokemon a Shell Bell instead
const shellBell = generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
await applyModifierTypeToPlayerPokemon(gScene.getParty()[0], shellBell);
gScene.playSound("item_fanfare");
await applyModifierTypeToPlayerPokemon(globalScene.getParty()[0], shellBell);
globalScene.playSound("item_fanfare");
await showEncounterText(i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true);
} else {
gScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.HEALING_CHARM));
globalScene.unshiftPhase(new ModifierRewardPhase(modifierTypes.HEALING_CHARM));
}
// Remove the modifier if its stacks go to 0
modifier.stackCount -= 1;
if (modifier.stackCount === 0) {
gScene.removeModifier(modifier);
globalScene.removeModifier(modifier);
}
leaveEncounterWithoutBattle(true);

View File

@ -5,7 +5,7 @@ import { PlayerPokemon, PokemonMove } from "#app/field/pokemon";
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 { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
@ -65,7 +65,7 @@ export const FieldTripEncounter: MysteryEncounter =
secondOptionPrompt: `${namespace}:second_option_prompt`,
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Return the options for Pokemon move valid for this option
return pokemon.moveset.map((move: PokemonMove) => {
@ -85,7 +85,7 @@ export const FieldTripEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
if (encounter.misc.correctMove) {
const modifiers = [
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.ATK ])!,
@ -111,7 +111,7 @@ export const FieldTripEncounter: MysteryEncounter =
secondOptionPrompt: `${namespace}:second_option_prompt`,
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Return the options for Pokemon move valid for this option
return pokemon.moveset.map((move: PokemonMove) => {
@ -131,7 +131,7 @@ export const FieldTripEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
if (encounter.misc.correctMove) {
const modifiers = [
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPATK ])!,
@ -157,7 +157,7 @@ export const FieldTripEncounter: MysteryEncounter =
secondOptionPrompt: `${namespace}:second_option_prompt`,
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Return the options for Pokemon move valid for this option
return pokemon.moveset.map((move: PokemonMove) => {
@ -177,7 +177,7 @@ export const FieldTripEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
if (encounter.misc.correctMove) {
const modifiers = [
generateModifierTypeOption(modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.ACC ])!,
@ -197,7 +197,7 @@ export const FieldTripEncounter: MysteryEncounter =
.build();
function pokemonAndMoveChosen(pokemon: PlayerPokemon, move: PokemonMove, correctMoveCategory: MoveCategory) {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const correctMove = move.getMove().category === correctMoveCategory;
encounter.setDialogueToken("pokeName", pokemon.getNameToRender());
encounter.setDialogueToken("move", move.getName());
@ -214,7 +214,7 @@ function pokemonAndMoveChosen(pokemon: PlayerPokemon, move: PokemonMove, correct
text: `${namespace}:incorrect_exp`,
},
];
setEncounterExp(gScene.getParty().map((p) => p.id), 50);
setEncounterExp(globalScene.getParty().map((p) => p.id), 50);
} else {
encounter.selectedOption!.dialogue!.selected = [
{

View File

@ -2,7 +2,7 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/myst
import { EnemyPartyConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals, generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { AttackTypeBoosterModifierType, modifierTypes, } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { AbilityRequirement, CombinationPokemonRequirement, TypeRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
import { Species } from "#enums/species";
@ -59,7 +59,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculate boss mons
const volcaronaSpecies = getPokemonSpecies(Species.VOLCARONA);
@ -71,7 +71,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
gender: Gender.MALE,
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPDEF, Stat.SPD ], 1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPDEF, Stat.SPD ], 1));
}
},
{
@ -80,7 +80,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
gender: Gender.FEMALE,
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPDEF, Stat.SPD ], 1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.SPDEF, Stat.SPD ], 1));
}
}
],
@ -115,7 +115,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
// Load animations/sfx for Volcarona moves
loadCustomMovesForEncounter([ Moves.FIRE_SPIN, Moves.QUIVER_DANCE ]);
gScene.arena.trySetWeather(WeatherType.SUNNY, true);
globalScene.arena.trySetWeather(WeatherType.SUNNY, true);
encounter.setDialogueToken("volcaronaName", getPokemonSpecies(Species.VOLCARONA).getName());
@ -123,14 +123,14 @@ export const FieryFalloutEncounter: MysteryEncounter =
})
.withOnVisualsStart(() => {
// Play animations
const background = new EncounterBattleAnim(EncounterAnim.MAGMA_BG, gScene.getPlayerPokemon()!, gScene.getPlayerPokemon());
const background = new EncounterBattleAnim(EncounterAnim.MAGMA_BG, globalScene.getPlayerPokemon()!, globalScene.getPlayerPokemon());
background.playWithoutTargets(200, 70, 2, 3);
const animation = new EncounterBattleAnim(EncounterAnim.MAGMA_SPOUT, gScene.getPlayerPokemon()!, gScene.getPlayerPokemon());
const animation = new EncounterBattleAnim(EncounterAnim.MAGMA_SPOUT, globalScene.getPlayerPokemon()!, globalScene.getPlayerPokemon());
animation.playWithoutTargets(80, 100, 2);
gScene.time.delayedCall(600, () => {
globalScene.time.delayedCall(600, () => {
animation.playWithoutTargets(-20, 100, 2);
});
gScene.time.delayedCall(1200, () => {
globalScene.time.delayedCall(1200, () => {
animation.playWithoutTargets(140, 150, 2);
});
@ -152,7 +152,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
},
async () => {
// Pick battle
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
setEncounterRewards({ fillRemaining: true }, undefined, () => giveLeadPokemonAttackTypeBoostItem());
encounter.startOfBattleEffects.push(
@ -168,7 +168,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
move: new PokemonMove(Moves.FIRE_SPIN),
ignorePp: true
});
await initBattleWithEnemyConfig(gScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
await initBattleWithEnemyConfig(globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
}
)
.withSimpleOption(
@ -183,8 +183,8 @@ export const FieryFalloutEncounter: MysteryEncounter =
},
async () => {
// Damage non-fire types and burn 1 random non-fire type member + give it Heatproof
const encounter = gScene.currentBattle.mysteryEncounter!;
const nonFireTypes = gScene.getParty().filter((p) => p.isAllowedInBattle() && !p.getTypes().includes(Type.FIRE));
const encounter = globalScene.currentBattle.mysteryEncounter!;
const nonFireTypes = globalScene.getParty().filter((p) => p.isAllowedInBattle() && !p.getTypes().includes(Type.FIRE));
for (const pkm of nonFireTypes) {
const percentage = DAMAGE_PERCENTAGE / 100;
@ -237,7 +237,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Fire types help calm the Volcarona
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
await transitionMysteryEncounterIntroVisuals();
setEncounterRewards(
{ fillRemaining: true },
@ -257,7 +257,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
function giveLeadPokemonAttackTypeBoostItem() {
// Give first party pokemon attack type boost item for free at end of battle
const leadPokemon = gScene.getParty()?.[0];
const leadPokemon = globalScene.getParty()?.[0];
if (leadPokemon) {
// Generate type booster held item, default to Charcoal if item fails to generate
let boosterModifierType = generateModifierType(modifierTypes.ATTACK_TYPE_BOOSTER) as AttackTypeBoosterModifierType;
@ -266,7 +266,7 @@ function giveLeadPokemonAttackTypeBoostItem() {
}
applyModifierTypeToPlayerPokemon(leadPokemon, boosterModifierType);
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
encounter.setDialogueToken("itemName", boosterModifierType.name);
encounter.setDialogueToken("leadPokemon", leadPokemon.getNameToRender());
queueEncounterMessage(`${namespace}:found_item`);

View File

@ -17,7 +17,7 @@ import {
regenerateModifierPoolThresholds,
} from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -53,11 +53,11 @@ export const FightOrFlightEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculate boss mon
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
const bossSpecies = gScene.arena.randomSpecies(gScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(gScene.getParty()), true);
const bossSpecies = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getParty()), true);
const bossPokemon = new EnemyPokemon(bossSpecies, level, TrainerSlot.NONE, true);
encounter.setDialogueToken("enemyPokemon", bossPokemon.getNameToRender());
const config: EnemyPartyConfig = {
@ -71,7 +71,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
queueEncounterMessage(`${namespace}:option.1.stat_boost`);
// Randomly boost 1 stat 2 stages
// Cannot boost Spd, Acc, or Evasion
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ randSeedInt(4, 1) ], 2));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ randSeedInt(4, 1) ], 2));
}
}],
};
@ -80,18 +80,18 @@ export const FightOrFlightEncounter: MysteryEncounter =
// Calculate item
// Waves 10-40 GREAT, 60-120 ULTRA, 120-160 ROGUE, 160-180 MASTER
const tier =
gScene.currentBattle.waveIndex > 160
globalScene.currentBattle.waveIndex > 160
? ModifierTier.MASTER
: gScene.currentBattle.waveIndex > 120
: globalScene.currentBattle.waveIndex > 120
? ModifierTier.ROGUE
: gScene.currentBattle.waveIndex > 40
: globalScene.currentBattle.waveIndex > 40
? ModifierTier.ULTRA
: ModifierTier.GREAT;
regenerateModifierPoolThresholds(gScene.getParty(), ModifierPoolType.PLAYER, 0);
regenerateModifierPoolThresholds(globalScene.getParty(), ModifierPoolType.PLAYER, 0);
let item: ModifierTypeOption | null = null;
// TMs and Candy Jar excluded from possible rewards as they're too swingy in value for a singular item reward
while (!item || item.type.id.includes("TM_") || item.type.id === "CANDY_JAR") {
item = getPlayerModifierTypeOptions(1, gScene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0];
item = getPlayerModifierTypeOptions(1, globalScene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0];
}
encounter.setDialogueToken("itemName", item.type.name);
encounter.misc = item;
@ -138,9 +138,9 @@ export const FightOrFlightEncounter: MysteryEncounter =
async () => {
// Pick battle
// Pokemon will randomly boost 1 stat by 2 stages
const item = gScene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
const item = globalScene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
setEncounterRewards({ guaranteedModifierTypeOptions: [ item ], fillRemaining: false });
await initBattleWithEnemyConfig(gScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
await initBattleWithEnemyConfig(globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
}
)
.withOption(
@ -159,8 +159,8 @@ export const FightOrFlightEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Pick steal
const encounter = gScene.currentBattle.mysteryEncounter!;
const item = gScene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const item = globalScene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
setEncounterRewards({ guaranteedModifierTypeOptions: [ item ], fillRemaining: false });
// Use primaryPokemon to execute the thievery

View File

@ -1,6 +1,6 @@
import { leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterRewards, transitionMysteryEncounterIntroVisuals, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { TrainerSlot } from "#app/data/trainer-config";
@ -81,13 +81,13 @@ export const FunAndGamesEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
gScene.loadBgm("mystery_encounter_fun_and_games", "mystery_encounter_fun_and_games.mp3");
const encounter = globalScene.currentBattle.mysteryEncounter!;
globalScene.loadBgm("mystery_encounter_fun_and_games", "mystery_encounter_fun_and_games.mp3");
encounter.setDialogueToken("wobbuffetName", getPokemonSpecies(Species.WOBBUFFET).getName());
return true;
})
.withOnVisualsStart(() => {
gScene.fadeAndSwitchBgm("mystery_encounter_fun_and_games");
globalScene.fadeAndSwitchBgm("mystery_encounter_fun_and_games");
return true;
})
.withOption(MysteryEncounterOptionBuilder
@ -104,7 +104,7 @@ export const FunAndGamesEncounter: MysteryEncounter =
})
.withPreOptionPhase(async () => {
// Select Pokemon for minigame
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
encounter.misc = {
playerPokemon: pokemon,
@ -120,7 +120,7 @@ export const FunAndGamesEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Start minigame
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
encounter.misc.turnsRemaining = 3;
// Update money
@ -161,11 +161,11 @@ export const FunAndGamesEncounter: MysteryEncounter =
async function summonPlayerPokemon() {
return new Promise<void>(async resolve => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const playerPokemon = encounter.misc.playerPokemon;
// Swaps the chosen Pokemon and the first player's lead Pokemon in the party
const party = gScene.getParty();
const party = globalScene.getParty();
const chosenIndex = party.indexOf(playerPokemon);
if (chosenIndex !== 0) {
const leadPokemon = party[0];
@ -175,36 +175,36 @@ async function summonPlayerPokemon() {
// Do trainer summon animation
let playerAnimationPromise: Promise<void> | undefined;
gScene.ui.showText(i18next.t("battle:playerGo", { pokemonName: getPokemonNameWithAffix(playerPokemon) }));
gScene.pbTray.hide();
gScene.trainer.setTexture(`trainer_${gScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
gScene.time.delayedCall(562, () => {
gScene.trainer.setFrame("2");
gScene.time.delayedCall(64, () => {
gScene.trainer.setFrame("3");
globalScene.ui.showText(i18next.t("battle:playerGo", { pokemonName: getPokemonNameWithAffix(playerPokemon) }));
globalScene.pbTray.hide();
globalScene.trainer.setTexture(`trainer_${globalScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
globalScene.time.delayedCall(562, () => {
globalScene.trainer.setFrame("2");
globalScene.time.delayedCall(64, () => {
globalScene.trainer.setFrame("3");
});
});
gScene.tweens.add({
targets: gScene.trainer,
globalScene.tweens.add({
targets: globalScene.trainer,
x: -36,
duration: 1000,
onComplete: () => gScene.trainer.setVisible(false)
onComplete: () => globalScene.trainer.setVisible(false)
});
gScene.time.delayedCall(750, () => {
globalScene.time.delayedCall(750, () => {
playerAnimationPromise = summonPlayerPokemonAnimation(playerPokemon);
});
// Also loads Wobbuffet data
const enemySpecies = getPokemonSpecies(Species.WOBBUFFET);
gScene.currentBattle.enemyParty = [];
const wobbuffet = gScene.addEnemyPokemon(enemySpecies, encounter.misc.playerPokemon.level, TrainerSlot.NONE, false);
globalScene.currentBattle.enemyParty = [];
const wobbuffet = globalScene.addEnemyPokemon(enemySpecies, encounter.misc.playerPokemon.level, TrainerSlot.NONE, false);
wobbuffet.ivs = [ 0, 0, 0, 0, 0, 0 ];
wobbuffet.setNature(Nature.MILD);
wobbuffet.setAlpha(0);
wobbuffet.setVisible(false);
wobbuffet.calculateStats();
gScene.currentBattle.enemyParty[0] = wobbuffet;
gScene.gameData.setPokemonSeen(wobbuffet, true);
globalScene.currentBattle.enemyParty[0] = wobbuffet;
globalScene.gameData.setPokemonSeen(wobbuffet, true);
await wobbuffet.loadAssets();
const id = setInterval(checkPlayerAnimationPromise, 500);
async function checkPlayerAnimationPromise() {
@ -220,20 +220,20 @@ async function summonPlayerPokemon() {
function handleLoseMinigame() {
return new Promise<void>(async resolve => {
// Check Wobbuffet is still alive
const wobbuffet = gScene.getEnemyPokemon();
const wobbuffet = globalScene.getEnemyPokemon();
if (!wobbuffet || wobbuffet.isFainted(true) || wobbuffet.hp === 0) {
// Player loses
// End the battle
if (wobbuffet) {
wobbuffet.hideInfo();
gScene.field.remove(wobbuffet);
globalScene.field.remove(wobbuffet);
}
transitionMysteryEncounterIntroVisuals(true, true);
gScene.currentBattle.enemyParty = [];
gScene.currentBattle.mysteryEncounter!.doContinueEncounter = undefined;
globalScene.currentBattle.enemyParty = [];
globalScene.currentBattle.mysteryEncounter!.doContinueEncounter = undefined;
leaveEncounterWithoutBattle(true);
await showEncounterText(`${namespace}:ko`);
const reviveCost = gScene.getWaveMoneyAmount(1.5);
const reviveCost = globalScene.getWaveMoneyAmount(1.5);
updatePlayerMoney(-reviveCost, true, false);
}
@ -242,9 +242,9 @@ function handleLoseMinigame() {
}
function handleNextTurn() {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const wobbuffet = gScene.getEnemyPokemon();
const wobbuffet = globalScene.getEnemyPokemon();
if (!wobbuffet) {
// Should never be triggered, just handling the edge case
handleLoseMinigame();
@ -275,9 +275,9 @@ function handleNextTurn() {
// End the battle
wobbuffet.hideInfo();
gScene.field.remove(wobbuffet);
gScene.currentBattle.enemyParty = [];
gScene.currentBattle.mysteryEncounter!.doContinueEncounter = undefined;
globalScene.field.remove(wobbuffet);
globalScene.currentBattle.enemyParty = [];
globalScene.currentBattle.mysteryEncounter!.doContinueEncounter = undefined;
leaveEncounterWithoutBattle(isHealPhase);
// Must end the TurnInit phase prematurely so battle phases aren't added to queue
queueEncounterMessage(`${namespace}:end_game`);
@ -299,32 +299,32 @@ function handleNextTurn() {
}
async function showWobbuffetHealthBar() {
const wobbuffet = gScene.getEnemyPokemon()!;
const wobbuffet = globalScene.getEnemyPokemon()!;
gScene.add.existing(wobbuffet);
gScene.field.add(wobbuffet);
globalScene.add.existing(wobbuffet);
globalScene.field.add(wobbuffet);
const playerPokemon = gScene.getPlayerPokemon() as Pokemon;
const playerPokemon = globalScene.getPlayerPokemon() as Pokemon;
if (playerPokemon?.visible) {
gScene.field.moveBelow(wobbuffet, playerPokemon);
globalScene.field.moveBelow(wobbuffet, playerPokemon);
}
// Show health bar and trigger cry
wobbuffet.showInfo();
gScene.time.delayedCall(1000, () => {
globalScene.time.delayedCall(1000, () => {
wobbuffet.cry();
});
wobbuffet.resetSummonData();
// Track the HP change across turns
gScene.currentBattle.mysteryEncounter!.misc.wobbuffetHealth = wobbuffet.hp;
globalScene.currentBattle.mysteryEncounter!.misc.wobbuffetHealth = wobbuffet.hp;
}
function summonPlayerPokemonAnimation(pokemon: PlayerPokemon): Promise<void> {
return new Promise<void>(resolve => {
const pokeball = gScene.addFieldSprite(36, 80, "pb", getPokeballAtlasKey(pokemon.pokeball));
const pokeball = globalScene.addFieldSprite(36, 80, "pb", getPokeballAtlasKey(pokemon.pokeball));
pokeball.setVisible(false);
pokeball.setOrigin(0.5, 0.625);
gScene.field.add(pokeball);
globalScene.field.add(pokeball);
pokemon.setFieldPosition(FieldPosition.CENTER, 0);
@ -332,32 +332,32 @@ function summonPlayerPokemonAnimation(pokemon: PlayerPokemon): Promise<void> {
pokeball.setVisible(true);
gScene.tweens.add({
globalScene.tweens.add({
targets: pokeball,
duration: 650,
x: 100 + fpOffset[0]
});
gScene.tweens.add({
globalScene.tweens.add({
targets: pokeball,
duration: 150,
ease: "Cubic.easeOut",
y: 70 + fpOffset[1],
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: pokeball,
duration: 500,
ease: "Cubic.easeIn",
angle: 1440,
y: 132 + fpOffset[1],
onComplete: () => {
gScene.playSound("se/pb_rel");
globalScene.playSound("se/pb_rel");
pokeball.destroy();
gScene.add.existing(pokemon);
gScene.field.add(pokemon);
globalScene.add.existing(pokemon);
globalScene.field.add(pokemon);
addPokeballOpenParticles(pokemon.x, pokemon.y - 16, pokemon.pokeball);
gScene.updateModifiers(true);
gScene.updateFieldScale();
globalScene.updateModifiers(true);
globalScene.updateFieldScale();
pokemon.showInfo();
pokemon.playAnim();
pokemon.setVisible(true);
@ -365,8 +365,8 @@ function summonPlayerPokemonAnimation(pokemon: PlayerPokemon): Promise<void> {
pokemon.setScale(0.5);
pokemon.tint(getPokeballTintColor(pokemon.pokeball));
pokemon.untint(250, "Sine.easeIn");
gScene.updateFieldScale();
gScene.tweens.add({
globalScene.updateFieldScale();
globalScene.tweens.add({
targets: pokemon,
duration: 250,
ease: "Sine.easeIn",
@ -375,15 +375,15 @@ function summonPlayerPokemonAnimation(pokemon: PlayerPokemon): Promise<void> {
pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 });
pokemon.getSprite().clearTint();
pokemon.resetSummonData();
gScene.time.delayedCall(1000, () => {
globalScene.time.delayedCall(1000, () => {
if (pokemon.isShiny()) {
gScene.unshiftPhase(new ShinySparklePhase(pokemon.getBattlerIndex()));
globalScene.unshiftPhase(new ShinySparklePhase(pokemon.getBattlerIndex()));
}
pokemon.resetTurnData();
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
gScene.pushPhase(new PostSummonPhase(pokemon.getBattlerIndex()));
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
globalScene.pushPhase(new PostSummonPhase(pokemon.getBattlerIndex()));
resolve();
});
}
@ -396,12 +396,12 @@ function summonPlayerPokemonAnimation(pokemon: PlayerPokemon): Promise<void> {
}
function hideShowmanIntroSprite() {
const carnivalGame = gScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(0)[0];
const wobbuffet = gScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(1)[0];
const showMan = gScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(2)[0];
const carnivalGame = globalScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(0)[0];
const wobbuffet = globalScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(1)[0];
const showMan = globalScene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(2)[0];
// Hide the showman
gScene.tweens.add({
globalScene.tweens.add({
targets: showMan,
x: "+=16",
y: "-=16",
@ -411,7 +411,7 @@ function hideShowmanIntroSprite() {
});
// Slide the Wobbuffet and Game over slightly
gScene.tweens.add({
globalScene.tweens.add({
targets: [ wobbuffet, carnivalGame ],
x: "+=16",
ease: "Sine.easeInOut",

View File

@ -3,7 +3,7 @@ import { TrainerSlot, } from "#app/data/trainer-config";
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 { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { Species } from "#enums/species";
@ -101,17 +101,17 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Load bgm
let bgmKey: string;
if (gScene.musicPreference === 0) {
if (globalScene.musicPreference === 0) {
bgmKey = "mystery_encounter_gen_5_gts";
gScene.loadBgm(bgmKey, `${bgmKey}.mp3`);
globalScene.loadBgm(bgmKey, `${bgmKey}.mp3`);
} else {
// Mixed option
bgmKey = "mystery_encounter_gen_6_gts";
gScene.loadBgm(bgmKey, `${bgmKey}.mp3`);
globalScene.loadBgm(bgmKey, `${bgmKey}.mp3`);
}
// Load possible trade options
@ -126,7 +126,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
return true;
})
.withOnVisualsStart(() => {
gScene.fadeAndSwitchBgm(gScene.currentBattle.mysteryEncounter!.misc.bgmKey);
globalScene.fadeAndSwitchBgm(globalScene.currentBattle.mysteryEncounter!.misc.bgmKey);
return true;
})
.withOption(
@ -139,7 +139,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
secondOptionPrompt: `${namespace}:option.1.trade_options_prompt`,
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Get the trade species options for the selected pokemon
const tradeOptionsMap: Map<number, EnemyPokemon[]> = encounter.misc.tradeOptionsMap;
@ -173,7 +173,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const tradedPokemon: PlayerPokemon = encounter.misc.tradedPokemon;
const receivedPokemonData: EnemyPokemon = encounter.misc.receivedPokemon;
const modifiers = tradedPokemon.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier) && !(m instanceof SpeciesStatBoosterModifier));
@ -183,27 +183,27 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
encounter.setDialogueToken("tradeTrainerName", traderName.trim());
// Remove the original party member from party
gScene.removePokemonFromPlayerParty(tradedPokemon, false);
globalScene.removePokemonFromPlayerParty(tradedPokemon, false);
// Set data properly, then generate the new Pokemon's assets
receivedPokemonData.passive = tradedPokemon.passive;
// Pokeball to Ultra ball, randomly
receivedPokemonData.pokeball = randInt(4) as PokeballType;
const dataSource = new PokemonData(receivedPokemonData);
const newPlayerPokemon = gScene.addPlayerPokemon(receivedPokemonData.species, receivedPokemonData.level, dataSource.abilityIndex, dataSource.formIndex, dataSource.gender, dataSource.shiny, dataSource.variant, dataSource.ivs, dataSource.nature, dataSource);
gScene.getParty().push(newPlayerPokemon);
const newPlayerPokemon = globalScene.addPlayerPokemon(receivedPokemonData.species, receivedPokemonData.level, dataSource.abilityIndex, dataSource.formIndex, dataSource.gender, dataSource.shiny, dataSource.variant, dataSource.ivs, dataSource.nature, dataSource);
globalScene.getParty().push(newPlayerPokemon);
await newPlayerPokemon.loadAssets();
for (const mod of modifiers) {
mod.pokemonId = newPlayerPokemon.id;
gScene.addModifier(mod, true, false, false, true);
globalScene.addModifier(mod, true, false, false, true);
}
// Show the trade animation
await showTradeBackground();
await doPokemonTradeSequence(tradedPokemon, newPlayerPokemon);
await showEncounterText(`${namespace}:trade_received`, null, 0, true, 4000);
gScene.playBgm(encounter.misc.bgmKey);
globalScene.playBgm(encounter.misc.bgmKey);
await addPokemonDataToDexAndValidateAchievements(newPlayerPokemon);
await hideTradeBackground();
tradedPokemon.destroy();
@ -221,18 +221,18 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
buttonTooltip: `${namespace}:option.2.tooltip`,
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Randomly generate a Wonder Trade pokemon
const randomTradeOption = generateTradeOption(gScene.getParty().map(p => p.species));
const randomTradeOption = generateTradeOption(globalScene.getParty().map(p => p.species));
const tradePokemon = new EnemyPokemon(randomTradeOption, pokemon.level, TrainerSlot.NONE, false);
// Extra shiny roll at 1/128 odds (boosted by events and charms)
if (!tradePokemon.shiny) {
const shinyThreshold = new Utils.IntegerHolder(WONDER_TRADE_SHINY_CHANCE);
if (gScene.eventManager.isEventActive()) {
shinyThreshold.value *= gScene.eventManager.getShinyMultiplier();
if (globalScene.eventManager.isEventActive()) {
shinyThreshold.value *= globalScene.eventManager.getShinyMultiplier();
}
gScene.applyModifiers(ShinyRateBoosterModifier, true, shinyThreshold);
globalScene.applyModifiers(ShinyRateBoosterModifier, true, shinyThreshold);
// Base shiny chance of 512/65536 -> 1/128, affected by events and Shiny Charms
// Maximum shiny chance of 4096/65536 -> 1/16, cannot improve further after that
@ -246,7 +246,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
if (tradePokemon.species.abilityHidden) {
if (tradePokemon.abilityIndex < hiddenIndex) {
const hiddenAbilityChance = new IntegerHolder(64);
gScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value);
@ -282,7 +282,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const tradedPokemon: PlayerPokemon = encounter.misc.tradedPokemon;
const receivedPokemonData: EnemyPokemon = encounter.misc.receivedPokemon;
const modifiers = tradedPokemon.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier) && !(m instanceof SpeciesStatBoosterModifier));
@ -292,26 +292,26 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
encounter.setDialogueToken("tradeTrainerName", traderName.trim());
// Remove the original party member from party
gScene.removePokemonFromPlayerParty(tradedPokemon, false);
globalScene.removePokemonFromPlayerParty(tradedPokemon, false);
// Set data properly, then generate the new Pokemon's assets
receivedPokemonData.passive = tradedPokemon.passive;
receivedPokemonData.pokeball = randInt(4) as PokeballType;
const dataSource = new PokemonData(receivedPokemonData);
const newPlayerPokemon = gScene.addPlayerPokemon(receivedPokemonData.species, receivedPokemonData.level, dataSource.abilityIndex, dataSource.formIndex, dataSource.gender, dataSource.shiny, dataSource.variant, dataSource.ivs, dataSource.nature, dataSource);
gScene.getParty().push(newPlayerPokemon);
const newPlayerPokemon = globalScene.addPlayerPokemon(receivedPokemonData.species, receivedPokemonData.level, dataSource.abilityIndex, dataSource.formIndex, dataSource.gender, dataSource.shiny, dataSource.variant, dataSource.ivs, dataSource.nature, dataSource);
globalScene.getParty().push(newPlayerPokemon);
await newPlayerPokemon.loadAssets();
for (const mod of modifiers) {
mod.pokemonId = newPlayerPokemon.id;
gScene.addModifier(mod, true, false, false, true);
globalScene.addModifier(mod, true, false, false, true);
}
// Show the trade animation
await showTradeBackground();
await doPokemonTradeSequence(tradedPokemon, newPlayerPokemon);
await showEncounterText(`${namespace}:trade_received`, null, 0, true, 4000);
gScene.playBgm(encounter.misc.bgmKey);
globalScene.playBgm(encounter.misc.bgmKey);
await addPokemonDataToDexAndValidateAchievements(newPlayerPokemon);
await hideTradeBackground();
tradedPokemon.destroy();
@ -329,7 +329,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
secondOptionPrompt: `${namespace}:option.3.trade_options_prompt`,
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Get Pokemon held items and filter for valid ones
const validItems = pokemon.getHeldItems().filter((it) => {
@ -365,7 +365,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const modifier = encounter.misc.chosenModifier;
// Check tier of the traded item, the received item will be one tier up
@ -384,11 +384,11 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
tier++;
}
regenerateModifierPoolThresholds(gScene.getParty(), ModifierPoolType.PLAYER, 0);
regenerateModifierPoolThresholds(globalScene.getParty(), ModifierPoolType.PLAYER, 0);
let item: ModifierTypeOption | null = null;
// TMs excluded from possible rewards
while (!item || item.type.id.includes("TM_")) {
item = getPlayerModifierTypeOptions(1, gScene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0];
item = getPlayerModifierTypeOptions(1, globalScene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0];
}
encounter.setDialogueToken("itemName", item.type.name);
@ -397,9 +397,9 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
// Remove the chosen modifier if its stacks go to 0
modifier.stackCount -= 1;
if (modifier.stackCount === 0) {
gScene.removeModifier(modifier);
globalScene.removeModifier(modifier);
}
await gScene.updateModifiers(true, true);
await globalScene.updateModifiers(true, true);
// Generate a trainer name
const traderName = generateRandomTraderName();
@ -430,9 +430,9 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
function getPokemonTradeOptions(): Map<number, EnemyPokemon[]> {
const tradeOptionsMap: Map<number, EnemyPokemon[]> = new Map<number, EnemyPokemon[]>();
// Starts by filtering out any current party members as valid resulting species
const alreadyUsedSpecies: PokemonSpecies[] = gScene.getParty().map(p => p.species);
const alreadyUsedSpecies: PokemonSpecies[] = globalScene.getParty().map(p => p.species);
gScene.getParty().forEach(pokemon => {
globalScene.getParty().forEach(pokemon => {
// If the party member is legendary/mythical, the only trade options available are always pulled from generation-specific legendary trade pools
if (pokemon.species.legendary || pokemon.species.subLegendary || pokemon.species.mythical) {
const generation = pokemon.species.generation;
@ -498,26 +498,26 @@ function generateTradeOption(alreadyUsedSpecies: PokemonSpecies[], originalBst?:
function showTradeBackground() {
return new Promise<void>(resolve => {
const tradeContainer = gScene.add.container(0, -gScene.game.canvas.height / 6);
const tradeContainer = globalScene.add.container(0, -globalScene.game.canvas.height / 6);
tradeContainer.setName("Trade Background");
const flyByStaticBg = gScene.add.rectangle(0, 0, gScene.game.canvas.width / 6, gScene.game.canvas.height / 6, 0);
const flyByStaticBg = globalScene.add.rectangle(0, 0, globalScene.game.canvas.width / 6, globalScene.game.canvas.height / 6, 0);
flyByStaticBg.setName("Black Background");
flyByStaticBg.setOrigin(0, 0);
flyByStaticBg.setVisible(false);
tradeContainer.add(flyByStaticBg);
const tradeBaseBg = gScene.add.image(0, 0, "default_bg");
const tradeBaseBg = globalScene.add.image(0, 0, "default_bg");
tradeBaseBg.setName("Trade Background Image");
tradeBaseBg.setOrigin(0, 0);
tradeContainer.add(tradeBaseBg);
gScene.fieldUI.add(tradeContainer);
gScene.fieldUI.bringToTop(tradeContainer);
globalScene.fieldUI.add(tradeContainer);
globalScene.fieldUI.bringToTop(tradeContainer);
tradeContainer.setVisible(true);
tradeContainer.alpha = 0;
gScene.tweens.add({
globalScene.tweens.add({
targets: tradeContainer,
alpha: 1,
duration: 500,
@ -531,15 +531,15 @@ function showTradeBackground() {
function hideTradeBackground() {
return new Promise<void>(resolve => {
const transformationContainer = gScene.fieldUI.getByName("Trade Background");
const transformationContainer = globalScene.fieldUI.getByName("Trade Background");
gScene.tweens.add({
globalScene.tweens.add({
targets: transformationContainer,
alpha: 0,
duration: 1000,
ease: "Sine.easeInOut",
onComplete: () => {
gScene.fieldUI.remove(transformationContainer, true);
globalScene.fieldUI.remove(transformationContainer, true);
resolve();
}
});
@ -554,7 +554,7 @@ function hideTradeBackground() {
*/
function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: PlayerPokemon) {
return new Promise<void>(resolve => {
const tradeContainer = gScene.fieldUI.getByName("Trade Background") as Phaser.GameObjects.Container;
const tradeContainer = globalScene.fieldUI.getByName("Trade Background") as Phaser.GameObjects.Container;
const tradeBaseBg = tradeContainer.getByName("Trade Background Image") as Phaser.GameObjects.Image;
let tradedPokemonSprite: Phaser.GameObjects.Sprite;
@ -563,8 +563,8 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P
let receivedPokemonTintSprite: Phaser.GameObjects.Sprite;
const getPokemonSprite = () => {
const ret = gScene.addPokemonSprite(tradedPokemon, tradeBaseBg.displayWidth / 2, tradeBaseBg.displayHeight / 2, "pkmn__sub");
ret.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
const ret = globalScene.addPokemonSprite(tradedPokemon, tradeBaseBg.displayWidth / 2, tradeBaseBg.displayHeight / 2, "pkmn__sub");
ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
return ret;
};
@ -582,7 +582,7 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P
[ tradedPokemonSprite, tradedPokemonTintSprite ].map(sprite => {
sprite.play(tradedPokemon.getSpriteKey(true));
sprite.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()) });
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()) });
sprite.setPipelineData("ignoreTimeTint", true);
sprite.setPipelineData("spriteKey", tradedPokemon.getSpriteKey());
sprite.setPipelineData("shiny", tradedPokemon.shiny);
@ -597,7 +597,7 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P
[ receivedPokemonSprite, receivedPokemonTintSprite ].map(sprite => {
sprite.play(receivedPokemon.getSpriteKey(true));
sprite.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()) });
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(tradedPokemon.getTeraType()) });
sprite.setPipelineData("ignoreTimeTint", true);
sprite.setPipelineData("spriteKey", receivedPokemon.getSpriteKey());
sprite.setPipelineData("shiny", receivedPokemon.shiny);
@ -612,45 +612,45 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P
// Traded pokemon pokeball
const tradedPbAtlasKey = getPokeballAtlasKey(tradedPokemon.pokeball);
const tradedPokeball: Phaser.GameObjects.Sprite = gScene.add.sprite(tradeBaseBg.displayWidth / 2, tradeBaseBg.displayHeight / 2, "pb", tradedPbAtlasKey);
const tradedPokeball: Phaser.GameObjects.Sprite = globalScene.add.sprite(tradeBaseBg.displayWidth / 2, tradeBaseBg.displayHeight / 2, "pb", tradedPbAtlasKey);
tradedPokeball.setVisible(false);
tradeContainer.add(tradedPokeball);
// Received pokemon pokeball
const receivedPbAtlasKey = getPokeballAtlasKey(receivedPokemon.pokeball);
const receivedPokeball: Phaser.GameObjects.Sprite = gScene.add.sprite(tradeBaseBg.displayWidth / 2, tradeBaseBg.displayHeight / 2, "pb", receivedPbAtlasKey);
const receivedPokeball: Phaser.GameObjects.Sprite = globalScene.add.sprite(tradeBaseBg.displayWidth / 2, tradeBaseBg.displayHeight / 2, "pb", receivedPbAtlasKey);
receivedPokeball.setVisible(false);
tradeContainer.add(receivedPokeball);
gScene.tweens.add({
globalScene.tweens.add({
targets: tradedPokemonSprite,
alpha: 1,
ease: "Cubic.easeInOut",
duration: 500,
onComplete: async () => {
gScene.fadeOutBgm(1000, false);
globalScene.fadeOutBgm(1000, false);
await showEncounterText(`${namespace}:pokemon_trade_selected`);
tradedPokemon.cry();
gScene.playBgm("evolution");
globalScene.playBgm("evolution");
await showEncounterText(`${namespace}:pokemon_trade_goodbye`);
tradedPokeball.setAlpha(0);
tradedPokeball.setVisible(true);
gScene.tweens.add({
globalScene.tweens.add({
targets: tradedPokeball,
alpha: 1,
ease: "Cubic.easeInOut",
duration: 250,
onComplete: () => {
tradedPokeball.setTexture("pb", `${tradedPbAtlasKey}_opening`);
gScene.time.delayedCall(17, () => tradedPokeball.setTexture("pb", `${tradedPbAtlasKey}_open`));
gScene.playSound("se/pb_rel");
globalScene.time.delayedCall(17, () => tradedPokeball.setTexture("pb", `${tradedPbAtlasKey}_open`));
globalScene.playSound("se/pb_rel");
tradedPokemonTintSprite.setVisible(true);
// TODO: need to add particles to fieldUI instead of field
// addPokeballOpenParticles(tradedPokemon.x, tradedPokemon.y, tradedPokemon.pokeball);
gScene.tweens.add({
globalScene.tweens.add({
targets: [ tradedPokemonTintSprite, tradedPokemonSprite ],
duration: 500,
ease: "Sine.easeIn",
@ -659,26 +659,26 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P
tradedPokemonSprite.setVisible(false);
tradedPokeball.setTexture("pb", `${tradedPbAtlasKey}_opening`);
tradedPokemonTintSprite.setVisible(false);
gScene.playSound("se/pb_catch");
gScene.time.delayedCall(17, () => tradedPokeball.setTexture("pb", `${tradedPbAtlasKey}`));
globalScene.playSound("se/pb_catch");
globalScene.time.delayedCall(17, () => tradedPokeball.setTexture("pb", `${tradedPbAtlasKey}`));
gScene.tweens.add({
globalScene.tweens.add({
targets: tradedPokeball,
y: "+=10",
duration: 200,
delay: 250,
ease: "Cubic.easeIn",
onComplete: () => {
gScene.playSound("se/pb_bounce_1");
globalScene.playSound("se/pb_bounce_1");
gScene.tweens.add({
globalScene.tweens.add({
targets: tradedPokeball,
y: "-=100",
duration: 200,
delay: 1000,
ease: "Cubic.easeInOut",
onStart: () => {
gScene.playSound("se/pb_throw");
globalScene.playSound("se/pb_throw");
},
onComplete: async () => {
await doPokemonTradeFlyBySequence(tradedPokemonSprite, receivedPokemonSprite);
@ -699,7 +699,7 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P
function doPokemonTradeFlyBySequence(tradedPokemonSprite: Phaser.GameObjects.Sprite, receivedPokemonSprite: Phaser.GameObjects.Sprite) {
return new Promise<void>(resolve => {
const tradeContainer = gScene.fieldUI.getByName("Trade Background") as Phaser.GameObjects.Container;
const tradeContainer = globalScene.fieldUI.getByName("Trade Background") as Phaser.GameObjects.Container;
const tradeBaseBg = tradeContainer.getByName("Trade Background Image") as Phaser.GameObjects.Image;
const flyByStaticBg = tradeContainer.getByName("Black Background") as Phaser.GameObjects.Rectangle;
flyByStaticBg.setVisible(true);
@ -720,47 +720,47 @@ function doPokemonTradeFlyBySequence(tradedPokemonSprite: Phaser.GameObjects.Spr
const BASE_ANIM_DURATION = 1000;
// Fade out trade background
gScene.tweens.add({
globalScene.tweens.add({
targets: tradeBaseBg,
alpha: 0,
ease: "Cubic.easeInOut",
duration: FADE_DELAY,
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: [ receivedPokemonSprite, tradedPokemonSprite ],
y: tradeBaseBg.displayWidth / 2 - 100,
ease: "Cubic.easeInOut",
duration: BASE_ANIM_DURATION * 3,
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: receivedPokemonSprite,
x: tradeBaseBg.displayWidth / 4,
ease: "Cubic.easeInOut",
duration: BASE_ANIM_DURATION / 2,
delay: ANIM_DELAY
});
gScene.tweens.add({
globalScene.tweens.add({
targets: tradedPokemonSprite,
x: tradeBaseBg.displayWidth * 3 / 4,
ease: "Cubic.easeInOut",
duration: BASE_ANIM_DURATION / 2,
delay: ANIM_DELAY,
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: receivedPokemonSprite,
y: "+=200",
ease: "Cubic.easeInOut",
duration: BASE_ANIM_DURATION * 2,
delay: ANIM_DELAY,
});
gScene.tweens.add({
globalScene.tweens.add({
targets: tradedPokemonSprite,
y: "-=200",
ease: "Cubic.easeInOut",
duration: BASE_ANIM_DURATION * 2,
delay: ANIM_DELAY,
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: tradeBaseBg,
alpha: 1,
ease: "Cubic.easeInOut",
@ -782,7 +782,7 @@ function doPokemonTradeFlyBySequence(tradedPokemonSprite: Phaser.GameObjects.Spr
function doTradeReceivedSequence(receivedPokemon: PlayerPokemon, receivedPokemonSprite: Phaser.GameObjects.Sprite, receivedPokemonTintSprite: Phaser.GameObjects.Sprite, receivedPokeballSprite: Phaser.GameObjects.Sprite, receivedPbAtlasKey: string) {
return new Promise<void>(resolve => {
const tradeContainer = gScene.fieldUI.getByName("Trade Background") as Phaser.GameObjects.Container;
const tradeContainer = globalScene.fieldUI.getByName("Trade Background") as Phaser.GameObjects.Container;
const tradeBaseBg = tradeContainer.getByName("Trade Background Image") as Phaser.GameObjects.Image;
receivedPokemonSprite.setVisible(false);
@ -799,19 +799,19 @@ function doTradeReceivedSequence(receivedPokemon: PlayerPokemon, receivedPokemon
const BASE_ANIM_DURATION = 1000;
// Pokeball falls to the screen
gScene.playSound("se/pb_throw");
gScene.tweens.add({
globalScene.playSound("se/pb_throw");
globalScene.tweens.add({
targets: receivedPokeballSprite,
y: "+=100",
ease: "Cubic.easeInOut",
duration: BASE_ANIM_DURATION,
onComplete: () => {
gScene.playSound("se/pb_bounce_1");
gScene.time.delayedCall(100, () => gScene.playSound("se/pb_bounce_1"));
globalScene.playSound("se/pb_bounce_1");
globalScene.time.delayedCall(100, () => globalScene.playSound("se/pb_bounce_1"));
gScene.time.delayedCall(2000, () => {
gScene.playSound("se/pb_rel");
gScene.fadeOutBgm(500, false);
globalScene.time.delayedCall(2000, () => {
globalScene.playSound("se/pb_rel");
globalScene.fadeOutBgm(500, false);
receivedPokemon.cry();
receivedPokemonTintSprite.scale = 0.25;
receivedPokemonTintSprite.alpha = 1;
@ -820,14 +820,14 @@ function doTradeReceivedSequence(receivedPokemon: PlayerPokemon, receivedPokemon
receivedPokemonTintSprite.alpha = 1;
receivedPokemonTintSprite.setVisible(true);
receivedPokeballSprite.setTexture("pb", `${receivedPbAtlasKey}_opening`);
gScene.time.delayedCall(17, () => receivedPokeballSprite.setTexture("pb", `${receivedPbAtlasKey}_open`));
gScene.tweens.add({
globalScene.time.delayedCall(17, () => receivedPokeballSprite.setTexture("pb", `${receivedPbAtlasKey}_open`));
globalScene.tweens.add({
targets: receivedPokemonSprite,
duration: 250,
ease: "Sine.easeOut",
scale: 1
});
gScene.tweens.add({
globalScene.tweens.add({
targets: receivedPokemonTintSprite,
duration: 250,
ease: "Sine.easeOut",
@ -835,7 +835,7 @@ function doTradeReceivedSequence(receivedPokemon: PlayerPokemon, receivedPokemon
alpha: 0,
onComplete: () => {
receivedPokeballSprite.destroy();
gScene.time.delayedCall(2000, () => resolve());
globalScene.time.delayedCall(2000, () => resolve());
}
});
});

View File

@ -2,7 +2,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Moves } from "#app/enums/moves";
import { Species } from "#app/enums/species";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { leaveEncounterWithoutBattle, setEncounterExp } from "../utils/encounter-phase-utils";
@ -42,7 +42,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
])
.withIntroDialogue([{ text: `${namespace}:intro` }])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
encounter.setDialogueToken("damagePercentage", String(DAMAGE_PERCENTAGE));
encounter.setDialogueToken("option1RequiredMove", new PokemonMove(OPTION_1_REQUIRED_MOVE).getName());
@ -104,7 +104,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
],
},
async () => {
const allowedPokemon = gScene.getParty().filter((p) => p.isAllowedInBattle());
const allowedPokemon = globalScene.getParty().filter((p) => p.isAllowedInBattle());
for (const pkm of allowedPokemon) {
const percentage = DAMAGE_PERCENTAGE / 100;
@ -131,7 +131,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
*/
function handlePokemonGuidingYouPhase() {
const laprasSpecies = getPokemonSpecies(Species.LAPRAS);
const { mysteryEncounter } = gScene.currentBattle;
const { mysteryEncounter } = globalScene.currentBattle;
if (mysteryEncounter?.selectedOption?.primaryPokemon?.id) {
setEncounterExp(mysteryEncounter.selectedOption.primaryPokemon.id, laprasSpecies.baseExp, true);

View File

@ -13,7 +13,7 @@ import { ModifierTier } from "#app/modifier/modifier-tier";
import { modifierTypes } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { PartyMemberStrength } from "#enums/party-member-strength";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import * as Utils from "#app/utils";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -38,11 +38,11 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculates what trainers are available for battle in the encounter
// Normal difficulty trainer is randomly pulled from biome
const normalTrainerType = gScene.arena.randomTrainerType(gScene.currentBattle.waveIndex);
const normalTrainerType = globalScene.arena.randomTrainerType(globalScene.currentBattle.waveIndex);
const normalConfig = trainerConfigs[normalTrainerType].clone();
let female = false;
if (normalConfig.hasGenders) {
@ -57,16 +57,16 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
// Hard difficulty trainer is another random trainer, but with AVERAGE_BALANCED config
// Number of mons is based off wave: 1-20 is 2, 20-40 is 3, etc. capping at 6 after wave 100
let retries = 0;
let hardTrainerType = gScene.arena.randomTrainerType(gScene.currentBattle.waveIndex);
let hardTrainerType = globalScene.arena.randomTrainerType(globalScene.currentBattle.waveIndex);
while (retries < 5 && hardTrainerType === normalTrainerType) {
// Will try to use a different trainer from the normal trainer type
hardTrainerType = gScene.arena.randomTrainerType(gScene.currentBattle.waveIndex);
hardTrainerType = globalScene.arena.randomTrainerType(globalScene.currentBattle.waveIndex);
retries++;
}
const hardTemplate = new TrainerPartyCompoundTemplate(
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER, false, true),
new TrainerPartyTemplate(
Math.min(Math.ceil(gScene.currentBattle.waveIndex / 20), 5),
Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 20), 5),
PartyMemberStrength.AVERAGE,
false,
true
@ -87,8 +87,8 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
// Brutal trainer is pulled from pool of boss trainers (gym leaders) for the biome
// They are given an E4 template team, so will be stronger than usual boss encounter and always have 6 mons
const brutalTrainerType = gScene.arena.randomTrainerType(
gScene.currentBattle.waveIndex,
const brutalTrainerType = globalScene.arena.randomTrainerType(
globalScene.currentBattle.waveIndex,
true
);
const e4Template = trainerPartyTemplates.ELITE_FOUR;
@ -146,7 +146,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
],
},
async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Spawn standard trainer battle with memory mushroom reward
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
@ -154,9 +154,9 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
// Seed offsets to remove possibility of different trainers having exact same teams
let initBattlePromise: Promise<void>;
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
initBattlePromise = initBattleWithEnemyConfig(config);
}, gScene.currentBattle.waveIndex * 10);
}, globalScene.currentBattle.waveIndex * 10);
await initBattlePromise!;
}
)
@ -171,7 +171,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
],
},
async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Spawn hard fight
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
@ -179,9 +179,9 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
// Seed offsets to remove possibility of different trainers having exact same teams
let initBattlePromise: Promise<void>;
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
initBattlePromise = initBattleWithEnemyConfig(config);
}, gScene.currentBattle.waveIndex * 100);
}, globalScene.currentBattle.waveIndex * 100);
await initBattlePromise!;
}
)
@ -196,7 +196,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
],
},
async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Spawn brutal fight
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[2];
@ -207,9 +207,9 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
// Seed offsets to remove possibility of different trainers having exact same teams
let initBattlePromise: Promise<void>;
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
initBattlePromise = initBattleWithEnemyConfig(config);
}, gScene.currentBattle.waveIndex * 1000);
}, globalScene.currentBattle.waveIndex * 1000);
await initBattlePromise!;
}
)

View File

@ -4,7 +4,7 @@ import { getHighestLevelPlayerPokemon, koPlayerPokemon } from "#app/data/mystery
import { ModifierTier } from "#app/modifier/modifier-tier";
import { randSeedInt } from "#app/utils";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -66,7 +66,7 @@ export const MysteriousChestEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculate boss mon
const config: EnemyPartyConfig = {
@ -107,7 +107,7 @@ export const MysteriousChestEncounter: MysteryEncounter =
})
.withPreOptionPhase(async () => {
// Play animation
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const introVisuals = encounter.introVisuals!;
// Determine roll first
@ -129,7 +129,7 @@ export const MysteriousChestEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Open the chest
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const roll = encounter.misc.roll;
if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT) {
// Choose between 2 COMMON / 2 GREAT tier items (20%)
@ -177,11 +177,11 @@ export const MysteriousChestEncounter: MysteryEncounter =
await showEncounterText(`${namespace}:option.1.bad`);
// Handle game over edge case
const allowedPokemon = gScene.getParty().filter(p => p.isAllowedInBattle());
const allowedPokemon = globalScene.getParty().filter(p => p.isAllowedInBattle());
if (allowedPokemon.length === 0) {
// If there are no longer any legal pokemon in the party, game over.
gScene.clearPhaseQueue();
gScene.unshiftPhase(new GameOverPhase());
globalScene.clearPhaseQueue();
globalScene.unshiftPhase(new GameOverPhase());
} else {
// Show which Pokemon was KOed, then start battle against Gimmighoul
await transitionMysteryEncounterIntroVisuals(true, true, 500);

View File

@ -1,7 +1,7 @@
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
import { leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals, updatePlayerMoney } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -54,18 +54,18 @@ export const PartTimerEncounter: MysteryEncounter =
])
.withOnInit(() => {
// Load sfx
gScene.loadSe("PRSFX- Horn Drill1", "battle_anims", "PRSFX- Horn Drill1.wav");
gScene.loadSe("PRSFX- Horn Drill3", "battle_anims", "PRSFX- Horn Drill3.wav");
gScene.loadSe("PRSFX- Guillotine2", "battle_anims", "PRSFX- Guillotine2.wav");
gScene.loadSe("PRSFX- Heavy Slam2", "battle_anims", "PRSFX- Heavy Slam2.wav");
globalScene.loadSe("PRSFX- Horn Drill1", "battle_anims", "PRSFX- Horn Drill1.wav");
globalScene.loadSe("PRSFX- Horn Drill3", "battle_anims", "PRSFX- Horn Drill3.wav");
globalScene.loadSe("PRSFX- Guillotine2", "battle_anims", "PRSFX- Guillotine2.wav");
globalScene.loadSe("PRSFX- Heavy Slam2", "battle_anims", "PRSFX- Heavy Slam2.wav");
gScene.loadSe("PRSFX- Agility", "battle_anims", "PRSFX- Agility.wav");
gScene.loadSe("PRSFX- Extremespeed1", "battle_anims", "PRSFX- Extremespeed1.wav");
gScene.loadSe("PRSFX- Accelerock1", "battle_anims", "PRSFX- Accelerock1.wav");
globalScene.loadSe("PRSFX- Agility", "battle_anims", "PRSFX- Agility.wav");
globalScene.loadSe("PRSFX- Extremespeed1", "battle_anims", "PRSFX- Extremespeed1.wav");
globalScene.loadSe("PRSFX- Accelerock1", "battle_anims", "PRSFX- Accelerock1.wav");
gScene.loadSe("PRSFX- Captivate", "battle_anims", "PRSFX- Captivate.wav");
gScene.loadSe("PRSFX- Attract2", "battle_anims", "PRSFX- Attract2.wav");
gScene.loadSe("PRSFX- Aurora Veil2", "battle_anims", "PRSFX- Aurora Veil2.wav");
globalScene.loadSe("PRSFX- Captivate", "battle_anims", "PRSFX- Captivate.wav");
globalScene.loadSe("PRSFX- Attract2", "battle_anims", "PRSFX- Attract2.wav");
globalScene.loadSe("PRSFX- Aurora Veil2", "battle_anims", "PRSFX- Aurora Veil2.wav");
return true;
})
@ -85,7 +85,7 @@ export const PartTimerEncounter: MysteryEncounter =
]
})
.withPreOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
encounter.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
@ -129,7 +129,7 @@ export const PartTimerEncounter: MysteryEncounter =
// Bring visuals back in
await transitionMysteryEncounterIntroVisuals(false, false);
const moneyMultiplier = gScene.currentBattle.mysteryEncounter!.misc.moneyMultiplier;
const moneyMultiplier = globalScene.currentBattle.mysteryEncounter!.misc.moneyMultiplier;
// Give money and do dialogue
if (moneyMultiplier > 2.5) {
@ -137,7 +137,7 @@ export const PartTimerEncounter: MysteryEncounter =
} else {
await showEncounterDialogue(`${namespace}:job_complete_bad`, `${namespace}:speaker`);
}
const moneyChange = gScene.getWaveMoneyAmount(moneyMultiplier);
const moneyChange = globalScene.getWaveMoneyAmount(moneyMultiplier);
updatePlayerMoney(moneyChange, true, false);
await showEncounterText(i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
await showEncounterText(`${namespace}:pokemon_tired`);
@ -159,7 +159,7 @@ export const PartTimerEncounter: MysteryEncounter =
]
})
.withPreOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
encounter.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
@ -206,7 +206,7 @@ export const PartTimerEncounter: MysteryEncounter =
// Bring visuals back in
await transitionMysteryEncounterIntroVisuals(false, false);
const moneyMultiplier = gScene.currentBattle.mysteryEncounter!.misc.moneyMultiplier;
const moneyMultiplier = globalScene.currentBattle.mysteryEncounter!.misc.moneyMultiplier;
// Give money and do dialogue
if (moneyMultiplier > 2.5) {
@ -214,7 +214,7 @@ export const PartTimerEncounter: MysteryEncounter =
} else {
await showEncounterDialogue(`${namespace}:job_complete_bad`, `${namespace}:speaker`);
}
const moneyChange = gScene.getWaveMoneyAmount(moneyMultiplier);
const moneyChange = globalScene.getWaveMoneyAmount(moneyMultiplier);
updatePlayerMoney(moneyChange, true, false);
await showEncounterText(i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
await showEncounterText(`${namespace}:pokemon_tired`);
@ -239,7 +239,7 @@ export const PartTimerEncounter: MysteryEncounter =
],
})
.withPreOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const selectedPokemon = encounter.selectedOption?.primaryPokemon!;
encounter.setDialogueToken("selectedPokemon", selectedPokemon.getNameToRender());
@ -266,7 +266,7 @@ export const PartTimerEncounter: MysteryEncounter =
// Give money and do dialogue
await showEncounterDialogue(`${namespace}:job_complete_good`, `${namespace}:speaker`);
const moneyChange = gScene.getWaveMoneyAmount(2.5);
const moneyChange = globalScene.getWaveMoneyAmount(2.5);
updatePlayerMoney(moneyChange, true, false);
await showEncounterText(i18next.t("mysteryEncounterMessages:receive_money", { amount: moneyChange }));
await showEncounterText(`${namespace}:pokemon_tired`);
@ -285,50 +285,50 @@ export const PartTimerEncounter: MysteryEncounter =
.build();
function doStrongWorkSfx() {
gScene.playSound("battle_anims/PRSFX- Horn Drill1");
gScene.playSound("battle_anims/PRSFX- Horn Drill1");
globalScene.playSound("battle_anims/PRSFX- Horn Drill1");
globalScene.playSound("battle_anims/PRSFX- Horn Drill1");
gScene.time.delayedCall(1000, () => {
gScene.playSound("battle_anims/PRSFX- Guillotine2");
globalScene.time.delayedCall(1000, () => {
globalScene.playSound("battle_anims/PRSFX- Guillotine2");
});
gScene.time.delayedCall(2000, () => {
gScene.playSound("battle_anims/PRSFX- Heavy Slam2");
globalScene.time.delayedCall(2000, () => {
globalScene.playSound("battle_anims/PRSFX- Heavy Slam2");
});
gScene.time.delayedCall(2500, () => {
gScene.playSound("battle_anims/PRSFX- Guillotine2");
globalScene.time.delayedCall(2500, () => {
globalScene.playSound("battle_anims/PRSFX- Guillotine2");
});
}
function doDeliverySfx() {
gScene.playSound("battle_anims/PRSFX- Accelerock1");
globalScene.playSound("battle_anims/PRSFX- Accelerock1");
gScene.time.delayedCall(1500, () => {
gScene.playSound("battle_anims/PRSFX- Extremespeed1");
globalScene.time.delayedCall(1500, () => {
globalScene.playSound("battle_anims/PRSFX- Extremespeed1");
});
gScene.time.delayedCall(2000, () => {
gScene.playSound("battle_anims/PRSFX- Extremespeed1");
globalScene.time.delayedCall(2000, () => {
globalScene.playSound("battle_anims/PRSFX- Extremespeed1");
});
gScene.time.delayedCall(2250, () => {
gScene.playSound("battle_anims/PRSFX- Agility");
globalScene.time.delayedCall(2250, () => {
globalScene.playSound("battle_anims/PRSFX- Agility");
});
}
function doSalesSfx() {
gScene.playSound("battle_anims/PRSFX- Captivate");
globalScene.playSound("battle_anims/PRSFX- Captivate");
gScene.time.delayedCall(1500, () => {
gScene.playSound("battle_anims/PRSFX- Attract2");
globalScene.time.delayedCall(1500, () => {
globalScene.playSound("battle_anims/PRSFX- Attract2");
});
gScene.time.delayedCall(2000, () => {
gScene.playSound("battle_anims/PRSFX- Aurora Veil2");
globalScene.time.delayedCall(2000, () => {
globalScene.playSound("battle_anims/PRSFX- Aurora Veil2");
});
gScene.time.delayedCall(3000, () => {
gScene.playSound("battle_anims/PRSFX- Attract2");
globalScene.time.delayedCall(3000, () => {
globalScene.playSound("battle_anims/PRSFX- Attract2");
});
}

View File

@ -1,6 +1,6 @@
import { initSubsequentOptionSelect, leaveEncounterWithoutBattle, transitionMysteryEncounterIntroVisuals, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import MysteryEncounterOption, { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
import { TrainerSlot } from "#app/data/trainer-config";
@ -59,7 +59,7 @@ export const SafariZoneEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
gScene.currentBattle.mysteryEncounter?.setDialogueToken("numEncounters", NUM_SAFARI_ENCOUNTERS.toString());
globalScene.currentBattle.mysteryEncounter?.setDialogueToken("numEncounters", NUM_SAFARI_ENCOUNTERS.toString());
return true;
})
.withOption(MysteryEncounterOptionBuilder
@ -76,20 +76,20 @@ export const SafariZoneEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Start safari encounter
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
encounter.continuousEncounter = true;
encounter.misc = {
safariPokemonRemaining: NUM_SAFARI_ENCOUNTERS
};
updatePlayerMoney(-(encounter.options[0].requirements[0] as MoneyRequirement).requiredMoney);
// Load bait/mud assets
gScene.loadSe("PRSFX- Bug Bite", "battle_anims", "PRSFX- Bug Bite.wav");
gScene.loadSe("PRSFX- Sludge Bomb2", "battle_anims", "PRSFX- Sludge Bomb2.wav");
gScene.loadSe("PRSFX- Taunt2", "battle_anims", "PRSFX- Taunt2.wav");
gScene.loadAtlas("safari_zone_bait", "mystery-encounters");
gScene.loadAtlas("safari_zone_mud", "mystery-encounters");
globalScene.loadSe("PRSFX- Bug Bite", "battle_anims", "PRSFX- Bug Bite.wav");
globalScene.loadSe("PRSFX- Sludge Bomb2", "battle_anims", "PRSFX- Sludge Bomb2.wav");
globalScene.loadSe("PRSFX- Taunt2", "battle_anims", "PRSFX- Taunt2.wav");
globalScene.loadAtlas("safari_zone_bait", "mystery-encounters");
globalScene.loadAtlas("safari_zone_mud", "mystery-encounters");
// Clear enemy party
gScene.currentBattle.enemyParty = [];
globalScene.currentBattle.enemyParty = [];
await transitionMysteryEncounterIntroVisuals();
await summonSafariPokemon();
initSubsequentOptionSelect({ overrideOptions: safariZoneGameOptions, hideDescription: true });
@ -144,7 +144,7 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
})
.withOptionPhase(async () => {
// Throw a ball option
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const pokemon = encounter.misc.pokemon;
const catchResult = await throwPokeball(pokemon);
@ -179,7 +179,7 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
})
.withOptionPhase(async () => {
// Throw bait option
const pokemon = gScene.currentBattle.mysteryEncounter!.misc.pokemon;
const pokemon = globalScene.currentBattle.mysteryEncounter!.misc.pokemon;
await throwBait(pokemon);
// 100% chance to increase catch stage +2
@ -209,7 +209,7 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
})
.withOptionPhase(async () => {
// Throw mud option
const pokemon = gScene.currentBattle.mysteryEncounter!.misc.pokemon;
const pokemon = globalScene.currentBattle.mysteryEncounter!.misc.pokemon;
await throwMud(pokemon);
// 100% chance to decrease flee stage -2
tryChangeFleeStage(-2);
@ -233,7 +233,7 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
})
.withOptionPhase(async () => {
// Flee option
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const pokemon = encounter.misc.pokemon;
await doPlayerFlee(pokemon);
// Check how many safari pokemon left
@ -251,20 +251,20 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
];
async function summonSafariPokemon() {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Message pokemon remaining
encounter.setDialogueToken("remainingCount", encounter.misc.safariPokemonRemaining);
gScene.queueMessage(getEncounterText(`${namespace}:safari.remaining_count`) ?? "", null, true);
globalScene.queueMessage(getEncounterText(`${namespace}:safari.remaining_count`) ?? "", null, true);
// Generate pokemon using safariPokemonRemaining so they are always the same pokemon no matter how many turns are taken
// Safari pokemon roll twice on shiny and HA chances, but are otherwise normal
let enemySpecies;
let pokemon;
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
enemySpecies = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false));
const level = gScene.currentBattle.getLevelForWave();
enemySpecies = getPokemonSpecies(enemySpecies.getWildSpeciesForLevel(level, true, false, gScene.gameMode));
pokemon = gScene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, false);
const level = globalScene.currentBattle.getLevelForWave();
enemySpecies = getPokemonSpecies(enemySpecies.getWildSpeciesForLevel(level, true, false, globalScene.gameMode));
pokemon = globalScene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, false);
// Roll shiny twice
if (!pokemon.shiny) {
@ -276,7 +276,7 @@ async function summonSafariPokemon() {
const hiddenIndex = pokemon.species.ability2 ? 2 : 1;
if (pokemon.abilityIndex < hiddenIndex) {
const hiddenAbilityChance = new IntegerHolder(256);
gScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value);
@ -288,10 +288,10 @@ async function summonSafariPokemon() {
pokemon.calculateStats();
gScene.currentBattle.enemyParty.unshift(pokemon);
}, gScene.currentBattle.waveIndex * 1000 * encounter.misc.safariPokemonRemaining);
globalScene.currentBattle.enemyParty.unshift(pokemon);
}, globalScene.currentBattle.waveIndex * 1000 * encounter.misc.safariPokemonRemaining);
gScene.gameData.setPokemonSeen(pokemon, true);
globalScene.gameData.setPokemonSeen(pokemon, true);
await pokemon.loadAssets();
// Reset safari catch and flee rates
@ -300,7 +300,7 @@ async function summonSafariPokemon() {
encounter.misc.pokemon = pokemon;
encounter.misc.safariPokemonRemaining -= 1;
gScene.unshiftPhase(new SummonPhase(0, false));
globalScene.unshiftPhase(new SummonPhase(0, false));
encounter.setDialogueToken("pokemonName", getPokemonNameWithAffix(pokemon));
@ -309,16 +309,16 @@ async function summonSafariPokemon() {
// shows up and the IV scanner breaks. For now, we place the IV scanner code
// separately so that at least the IV scanner works.
const ivScannerModifier = gScene.findModifier(m => m instanceof IvScannerModifier);
const ivScannerModifier = globalScene.findModifier(m => m instanceof IvScannerModifier);
if (ivScannerModifier) {
gScene.pushPhase(new ScanIvsPhase(pokemon.getBattlerIndex(), Math.min(ivScannerModifier.getStackCount() * 2, 6)));
globalScene.pushPhase(new ScanIvsPhase(pokemon.getBattlerIndex(), Math.min(ivScannerModifier.getStackCount() * 2, 6)));
}
}
function throwPokeball(pokemon: EnemyPokemon): Promise<boolean> {
const baseCatchRate = pokemon.species.catchRate;
// Catch stage ranges from -6 to +6 (like stat boost stages)
const safariCatchStage = gScene.currentBattle.mysteryEncounter!.misc.catchStage;
const safariCatchStage = globalScene.currentBattle.mysteryEncounter!.misc.catchStage;
// Catch modifier ranges from 2/8 (-6 stage) to 8/2 (+6)
const safariModifier = (2 + Math.min(Math.max(safariCatchStage, 0), 6)) / (2 - Math.max(Math.min(safariCatchStage, 0), -6));
// Catch rate same as safari ball
@ -332,26 +332,26 @@ async function throwBait(pokemon: EnemyPokemon): Promise<boolean> {
const originalY: number = pokemon.y;
const fpOffset = pokemon.getFieldPositionOffset();
const bait: Phaser.GameObjects.Sprite = gScene.addFieldSprite(16 + 75, 80 + 25, "safari_zone_bait", "0001.png");
const bait: Phaser.GameObjects.Sprite = globalScene.addFieldSprite(16 + 75, 80 + 25, "safari_zone_bait", "0001.png");
bait.setOrigin(0.5, 0.625);
gScene.field.add(bait);
globalScene.field.add(bait);
return new Promise(resolve => {
gScene.trainer.setTexture(`trainer_${gScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
gScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[0], () => {
gScene.playSound("se/pb_throw");
globalScene.trainer.setTexture(`trainer_${globalScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
globalScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[0], () => {
globalScene.playSound("se/pb_throw");
// Trainer throw frames
gScene.trainer.setFrame("2");
gScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[1], () => {
gScene.trainer.setFrame("3");
gScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[2], () => {
gScene.trainer.setTexture(`trainer_${gScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back`);
globalScene.trainer.setFrame("2");
globalScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[1], () => {
globalScene.trainer.setFrame("3");
globalScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[2], () => {
globalScene.trainer.setTexture(`trainer_${globalScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back`);
});
});
// Pokeball move and catch logic
gScene.tweens.add({
globalScene.tweens.add({
targets: bait,
x: { value: 210 + fpOffset[0], ease: "Linear" },
y: { value: 55 + fpOffset[1], ease: "Cubic.easeOut" },
@ -359,8 +359,8 @@ async function throwBait(pokemon: EnemyPokemon): Promise<boolean> {
onComplete: () => {
let index = 1;
gScene.time.delayedCall(768, () => {
gScene.tweens.add({
globalScene.time.delayedCall(768, () => {
globalScene.tweens.add({
targets: pokemon,
duration: 150,
ease: "Cubic.easeOut",
@ -368,12 +368,12 @@ async function throwBait(pokemon: EnemyPokemon): Promise<boolean> {
y: originalY - 5,
loop: 6,
onStart: () => {
gScene.playSound("battle_anims/PRSFX- Bug Bite");
globalScene.playSound("battle_anims/PRSFX- Bug Bite");
bait.setFrame("0002.png");
},
onLoop: () => {
if (index % 2 === 0) {
gScene.playSound("battle_anims/PRSFX- Bug Bite");
globalScene.playSound("battle_anims/PRSFX- Bug Bite");
}
if (index === 4) {
bait.setFrame("0003.png");
@ -381,7 +381,7 @@ async function throwBait(pokemon: EnemyPokemon): Promise<boolean> {
index++;
},
onComplete: () => {
gScene.time.delayedCall(256, () => {
globalScene.time.delayedCall(256, () => {
bait.destroy();
resolve(true);
});
@ -398,51 +398,51 @@ async function throwMud(pokemon: EnemyPokemon): Promise<boolean> {
const originalY: number = pokemon.y;
const fpOffset = pokemon.getFieldPositionOffset();
const mud: Phaser.GameObjects.Sprite = gScene.addFieldSprite(16 + 75, 80 + 35, "safari_zone_mud", "0001.png");
const mud: Phaser.GameObjects.Sprite = globalScene.addFieldSprite(16 + 75, 80 + 35, "safari_zone_mud", "0001.png");
mud.setOrigin(0.5, 0.625);
gScene.field.add(mud);
globalScene.field.add(mud);
return new Promise(resolve => {
gScene.trainer.setTexture(`trainer_${gScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
gScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[0], () => {
gScene.playSound("se/pb_throw");
globalScene.trainer.setTexture(`trainer_${globalScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
globalScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[0], () => {
globalScene.playSound("se/pb_throw");
// Trainer throw frames
gScene.trainer.setFrame("2");
gScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[1], () => {
gScene.trainer.setFrame("3");
gScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[2], () => {
gScene.trainer.setTexture(`trainer_${gScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back`);
globalScene.trainer.setFrame("2");
globalScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[1], () => {
globalScene.trainer.setFrame("3");
globalScene.time.delayedCall(TRAINER_THROW_ANIMATION_TIMES[2], () => {
globalScene.trainer.setTexture(`trainer_${globalScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back`);
});
});
// Mud throw and splat
gScene.tweens.add({
globalScene.tweens.add({
targets: mud,
x: { value: 230 + fpOffset[0], ease: "Linear" },
y: { value: 55 + fpOffset[1], ease: "Cubic.easeOut" },
duration: 500,
onComplete: () => {
// Mud frame 2
gScene.playSound("battle_anims/PRSFX- Sludge Bomb2");
globalScene.playSound("battle_anims/PRSFX- Sludge Bomb2");
mud.setFrame("0002.png");
// Mud splat
gScene.time.delayedCall(200, () => {
globalScene.time.delayedCall(200, () => {
mud.setFrame("0003.png");
gScene.time.delayedCall(400, () => {
globalScene.time.delayedCall(400, () => {
mud.setFrame("0004.png");
});
});
// Fade mud then angry animation
gScene.tweens.add({
globalScene.tweens.add({
targets: mud,
alpha: 0,
ease: "Cubic.easeIn",
duration: 1000,
onComplete: () => {
mud.destroy();
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemon,
duration: 300,
ease: "Cubic.easeOut",
@ -450,10 +450,10 @@ async function throwMud(pokemon: EnemyPokemon): Promise<boolean> {
y: originalY - 20,
loop: 1,
onStart: () => {
gScene.playSound("battle_anims/PRSFX- Taunt2");
globalScene.playSound("battle_anims/PRSFX- Taunt2");
},
onLoop: () => {
gScene.playSound("battle_anims/PRSFX- Taunt2");
globalScene.playSound("battle_anims/PRSFX- Taunt2");
},
onComplete: () => {
resolve(true);
@ -481,8 +481,8 @@ function tryChangeFleeStage(change: number, chance?: number): boolean {
if (chance && randSeedInt(10) >= chance) {
return false;
}
const currentFleeStage = gScene.currentBattle.mysteryEncounter!.misc.fleeStage ?? 0;
gScene.currentBattle.mysteryEncounter!.misc.fleeStage = Math.min(Math.max(currentFleeStage + change, -6), 6);
const currentFleeStage = globalScene.currentBattle.mysteryEncounter!.misc.fleeStage ?? 0;
globalScene.currentBattle.mysteryEncounter!.misc.fleeStage = Math.min(Math.max(currentFleeStage + change, -6), 6);
return true;
}
@ -490,23 +490,23 @@ function tryChangeCatchStage(change: number, chance?: number): boolean {
if (chance && randSeedInt(10) >= chance) {
return false;
}
const currentCatchStage = gScene.currentBattle.mysteryEncounter!.misc.catchStage ?? 0;
gScene.currentBattle.mysteryEncounter!.misc.catchStage = Math.min(Math.max(currentCatchStage + change, -6), 6);
const currentCatchStage = globalScene.currentBattle.mysteryEncounter!.misc.catchStage ?? 0;
globalScene.currentBattle.mysteryEncounter!.misc.catchStage = Math.min(Math.max(currentCatchStage + change, -6), 6);
return true;
}
async function doEndTurn(cursorIndex: number) {
// First cleanup and destroy old Pokemon objects that were left in the enemyParty
// They are left in enemyParty temporarily so that VictoryPhase properly handles EXP
const party = gScene.getEnemyParty();
const party = globalScene.getEnemyParty();
if (party.length > 1) {
for (let i = 1; i < party.length; i++) {
party[i].destroy();
}
gScene.currentBattle.enemyParty = party.slice(0, 1);
globalScene.currentBattle.enemyParty = party.slice(0, 1);
}
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const pokemon = encounter.misc.pokemon;
const isFlee = isPokemonFlee(pokemon, encounter.misc.fleeStage);
if (isFlee) {
@ -522,7 +522,7 @@ async function doEndTurn(cursorIndex: number) {
leaveEncounterWithoutBattle(true);
}
} else {
gScene.queueMessage(getEncounterText(`${namespace}:safari.watching`) ?? "", 0, null, 1000);
globalScene.queueMessage(getEncounterText(`${namespace}:safari.watching`) ?? "", 0, null, 1000);
initSubsequentOptionSelect({ overrideOptions: safariZoneGameOptions, startingCursorIndex: cursorIndex, hideDescription: true });
}
}

View File

@ -4,7 +4,7 @@ import { modifierTypes } from "#app/modifier/modifier-type";
import { randSeedInt } from "#app/utils";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Species } from "#enums/species";
import { gScene } from "#app/battle-scene";
import { globalScene } 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";
@ -80,7 +80,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
],
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Update money
updatePlayerMoney(-(encounter.options[0].requirements[0] as MoneyRequirement).requiredMoney);
@ -114,7 +114,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Choose Cheap Option
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const chosenPokemon = encounter.misc.chosenPokemon;
const modifiers = encounter.misc.modifiers;
@ -126,7 +126,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
})
.withPostOptionPhase(async () => {
// Damage and status applied after dealer leaves (to make thematic sense)
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const chosenPokemon = encounter.misc.chosenPokemon as PlayerPokemon;
// Pokemon takes half max HP damage and nature is randomized (does not update dex)
@ -160,7 +160,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
],
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Update money
updatePlayerMoney(-(encounter.options[1].requirements[0] as MoneyRequirement).requiredMoney);
@ -186,7 +186,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Choose Expensive Option
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const chosenPokemon = encounter.misc.chosenPokemon;
const modifiers = encounter.misc.modifiers;
@ -198,7 +198,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
})
.withPostOptionPhase(async () => {
// Status applied after dealer leaves (to make thematic sense)
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const chosenPokemon = encounter.misc.chosenPokemon;
queueEncounterMessage(`${namespace}:no_bad_effects`);

View File

@ -2,7 +2,7 @@ import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requir
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Species } from "#enums/species";
import { gScene } from "#app/battle-scene";
import { globalScene } 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";
@ -52,7 +52,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
console.log(encounter);
// Calculate boss mon
@ -104,7 +104,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
},
async () => {
// Pick battle
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
setEncounterRewards({ guaranteedModifierTypeFuncs: [ modifierTypes.LEFTOVERS ], fillRemaining: true });
encounter.startOfBattleEffects.push(
{
@ -135,7 +135,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
async () => {
// Fall asleep waiting for Snorlax
// Full heal party
gScene.unshiftPhase(new PartyHealPhase(true));
globalScene.unshiftPhase(new PartyHealPhase(true));
queueEncounterMessage(`${namespace}:option.2.rest_result`);
leaveEncounterWithoutBattle();
}
@ -156,7 +156,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Steal the Snorlax's Leftovers
const instance = gScene.currentBattle.mysteryEncounter!;
const instance = globalScene.currentBattle.mysteryEncounter!;
setEncounterRewards({ guaranteedModifierTypeFuncs: [ modifierTypes.LEFTOVERS ], fillRemaining: false });
// Snorlax exp to Pokemon that did the stealing
setEncounterExp(instance.primaryPokemon!.id, getPokemonSpecies(Species.SNORLAX).baseExp);

View File

@ -1,7 +1,7 @@
import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { randSeedInt } from "#app/utils";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 Pokemon, { EnemyPokemon } from "#app/field/pokemon";
@ -63,8 +63,8 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const price = gScene.getWaveMoneyAmount(MONEY_COST_MULTIPLIER);
const encounter = globalScene.currentBattle.mysteryEncounter!;
const price = globalScene.getWaveMoneyAmount(MONEY_COST_MULTIPLIER);
encounter.setDialogueToken("price", price.toString());
encounter.misc = {
price
@ -87,7 +87,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
})
.withPreOptionPhase(async () => {
// Update money
updatePlayerMoney(-gScene.currentBattle.mysteryEncounter!.misc.price, true, false);
updatePlayerMoney(-globalScene.currentBattle.mysteryEncounter!.misc.price, true, false);
})
.withOptionPhase(async () => {
const config: EnemyPartyConfig = await doBiomeTransitionDialogueAndBattleInit();
@ -113,7 +113,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
.withOptionPhase(async () => {
const config: EnemyPartyConfig = await doBiomeTransitionDialogueAndBattleInit();
setEncounterRewards({ fillRemaining: true });
setEncounterExp(gScene.currentBattle.mysteryEncounter!.selectedOption!.primaryPokemon!.id, 100);
setEncounterExp(globalScene.currentBattle.mysteryEncounter!.selectedOption!.primaryPokemon!.id, 100);
await initBattleWithEnemyConfig(config);
})
.build()
@ -130,11 +130,11 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
},
async () => {
// Inspect the Machine
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Init enemy
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
const bossSpecies = gScene.arena.randomSpecies(gScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(gScene.getParty()), true);
const bossSpecies = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getParty()), true);
const bossPokemon = new EnemyPokemon(bossSpecies, level, TrainerSlot.NONE, true);
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
const config: EnemyPartyConfig = {
@ -156,26 +156,26 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
.build();
async function doBiomeTransitionDialogueAndBattleInit() {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculate new biome (cannot be current biome)
const filteredBiomes = BIOME_CANDIDATES.filter(b => gScene.arena.biomeType !== b);
const filteredBiomes = BIOME_CANDIDATES.filter(b => globalScene.arena.biomeType !== b);
const newBiome = filteredBiomes[randSeedInt(filteredBiomes.length)];
// Show dialogue and transition biome
await showEncounterText(`${namespace}:transport`);
await Promise.all([ animateBiomeChange(newBiome), transitionMysteryEncounterIntroVisuals() ]);
gScene.playBgm();
globalScene.playBgm();
await showEncounterText(`${namespace}:attacked`);
// Init enemy
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
const bossSpecies = gScene.arena.randomSpecies(gScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(gScene.getParty()), true);
const bossSpecies = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getParty()), true);
const bossPokemon = new EnemyPokemon(bossSpecies, level, TrainerSlot.NONE, true);
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = gScene.currentBattle.waveIndex < 50 ?
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = globalScene.currentBattle.waveIndex < 50 ?
[ Stat.DEF, Stat.SPDEF, Stat.SPD ] :
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
@ -188,7 +188,7 @@ async function doBiomeTransitionDialogueAndBattleInit() {
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(`${namespace}:boss_enraged`);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
}
}],
};
@ -198,44 +198,44 @@ async function doBiomeTransitionDialogueAndBattleInit() {
async function animateBiomeChange(nextBiome: Biome) {
return new Promise<void>(resolve => {
gScene.tweens.add({
targets: [ gScene.arenaEnemy, gScene.lastEnemyTrainer ],
globalScene.tweens.add({
targets: [ globalScene.arenaEnemy, globalScene.lastEnemyTrainer ],
x: "+=300",
duration: 2000,
onComplete: () => {
gScene.newArena(nextBiome);
globalScene.newArena(nextBiome);
const biomeKey = getBiomeKey(nextBiome);
const bgTexture = `${biomeKey}_bg`;
gScene.arenaBgTransition.setTexture(bgTexture);
gScene.arenaBgTransition.setAlpha(0);
gScene.arenaBgTransition.setVisible(true);
gScene.arenaPlayerTransition.setBiome(nextBiome);
gScene.arenaPlayerTransition.setAlpha(0);
gScene.arenaPlayerTransition.setVisible(true);
globalScene.arenaBgTransition.setTexture(bgTexture);
globalScene.arenaBgTransition.setAlpha(0);
globalScene.arenaBgTransition.setVisible(true);
globalScene.arenaPlayerTransition.setBiome(nextBiome);
globalScene.arenaPlayerTransition.setAlpha(0);
globalScene.arenaPlayerTransition.setVisible(true);
gScene.tweens.add({
targets: [ gScene.arenaPlayer, gScene.arenaBgTransition, gScene.arenaPlayerTransition ],
globalScene.tweens.add({
targets: [ globalScene.arenaPlayer, globalScene.arenaBgTransition, globalScene.arenaPlayerTransition ],
duration: 1000,
ease: "Sine.easeInOut",
alpha: (target: any) => target === gScene.arenaPlayer ? 0 : 1,
alpha: (target: any) => target === globalScene.arenaPlayer ? 0 : 1,
onComplete: () => {
gScene.arenaBg.setTexture(bgTexture);
gScene.arenaPlayer.setBiome(nextBiome);
gScene.arenaPlayer.setAlpha(1);
gScene.arenaEnemy.setBiome(nextBiome);
gScene.arenaEnemy.setAlpha(1);
gScene.arenaNextEnemy.setBiome(nextBiome);
gScene.arenaBgTransition.setVisible(false);
gScene.arenaPlayerTransition.setVisible(false);
if (gScene.lastEnemyTrainer) {
gScene.lastEnemyTrainer.destroy();
globalScene.arenaBg.setTexture(bgTexture);
globalScene.arenaPlayer.setBiome(nextBiome);
globalScene.arenaPlayer.setAlpha(1);
globalScene.arenaEnemy.setBiome(nextBiome);
globalScene.arenaEnemy.setAlpha(1);
globalScene.arenaNextEnemy.setBiome(nextBiome);
globalScene.arenaBgTransition.setVisible(false);
globalScene.arenaPlayerTransition.setVisible(false);
if (globalScene.lastEnemyTrainer) {
globalScene.lastEnemyTrainer.destroy();
}
resolve();
gScene.tweens.add({
targets: gScene.arenaEnemy,
globalScene.tweens.add({
targets: globalScene.arenaEnemy,
x: "-=300",
});
}

View File

@ -1,7 +1,7 @@
import { EnemyPartyConfig, generateModifierType, handleMysteryEncounterBattleFailed, initBattleWithEnemyConfig, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { trainerConfigs } from "#app/data/trainer-config";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { randSeedShuffle } from "#app/utils";
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -95,8 +95,8 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const waveIndex = gScene.currentBattle.waveIndex;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const waveIndex = globalScene.currentBattle.waveIndex;
// Calculates what trainers are available for battle in the encounter
// If player is in space biome, uses special "Space" version of the trainer
@ -126,7 +126,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
];
// Determine the 3 pokemon the player can battle with
let partyCopy = gScene.getParty().slice(0);
let partyCopy = globalScene.getParty().slice(0);
partyCopy = partyCopy
.filter(p => p.isAllowedInBattle())
.sort((a, b) => a.friendship - b.friendship);
@ -214,7 +214,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
],
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Spawn battle with first pokemon
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
@ -266,7 +266,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
],
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Spawn battle with second pokemon
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
@ -318,7 +318,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
],
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Spawn battle with third pokemon
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
@ -367,7 +367,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
function getPartyConfig(): EnemyPartyConfig {
// Bug type superfan trainer config
const waveIndex = gScene.currentBattle.waveIndex;
const waveIndex = globalScene.currentBattle.waveIndex;
const breederConfig = trainerConfigs[TrainerType.EXPERT_POKEMON_BREEDER].clone();
breederConfig.name = i18next.t(trainerNameKey);
@ -394,7 +394,7 @@ function getPartyConfig(): EnemyPartyConfig {
]
};
if (gScene.arena.biomeType === Biome.SPACE) {
if (globalScene.arena.biomeType === Biome.SPACE) {
// All 3 members always Cleffa line, but different configs
baseConfig.pokemonConfigs!.push({
nickname: i18next.t(`${namespace}:cleffa_2_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
@ -506,41 +506,41 @@ function getEggOptions(commonEggs: number, rareEggs: number) {
}
function removePokemonFromPartyAndStoreHeldItems(encounter: MysteryEncounter, chosenPokemon: PlayerPokemon) {
const party = gScene.getParty();
const party = globalScene.getParty();
const chosenIndex = party.indexOf(chosenPokemon);
party[chosenIndex] = party[0];
party[0] = chosenPokemon;
encounter.misc.originalParty = gScene.getParty().slice(1);
encounter.misc.originalParty = globalScene.getParty().slice(1);
encounter.misc.originalPartyHeldItems = encounter.misc.originalParty
.map(p => p.getHeldItems());
gScene["party"] = [
globalScene["party"] = [
chosenPokemon
];
}
function checkAchievement() {
if (gScene.arena.biomeType === Biome.SPACE) {
gScene.validateAchv(achvs.BREEDERS_IN_SPACE);
if (globalScene.arena.biomeType === Biome.SPACE) {
globalScene.validateAchv(achvs.BREEDERS_IN_SPACE);
}
}
function restorePartyAndHeldItems() {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Restore original party
gScene.getParty().push(...encounter.misc.originalParty);
globalScene.getParty().push(...encounter.misc.originalParty);
// Restore held items
const originalHeldItems = encounter.misc.originalPartyHeldItems;
originalHeldItems.forEach((pokemonHeldItemsList: PokemonHeldItemModifier[]) => {
pokemonHeldItemsList.forEach(heldItem => {
gScene.addModifier(heldItem, true, false, false, true);
globalScene.addModifier(heldItem, true, false, false, true);
});
});
gScene.updateModifiers(true);
globalScene.updateModifiers(true);
}
function onGameOver() {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
encounter.dialogue.outro = [
{
@ -561,33 +561,33 @@ function onGameOver() {
encounter.misc.encounterFailed = true;
// Revert BGM
gScene.playBgm(gScene.arena.bgm);
globalScene.playBgm(globalScene.arena.bgm);
// Clear any leftover battle phases
gScene.clearPhaseQueue();
gScene.clearPhaseQueueSplice();
globalScene.clearPhaseQueue();
globalScene.clearPhaseQueueSplice();
// Return enemy Pokemon
const pokemon = gScene.getEnemyPokemon();
const pokemon = globalScene.getEnemyPokemon();
if (pokemon) {
gScene.playSound("se/pb_rel");
globalScene.playSound("se/pb_rel");
pokemon.hideInfo();
pokemon.tint(getPokeballTintColor(pokemon.pokeball), 1, 250, "Sine.easeIn");
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemon,
duration: 250,
ease: "Sine.easeIn",
scale: 0.5,
onComplete: () => {
gScene.field.remove(pokemon, true);
globalScene.field.remove(pokemon, true);
}
});
}
// Show the enemy trainer
gScene.time.delayedCall(250, () => {
const sprites = gScene.currentBattle.trainer?.getSprites();
const tintSprites = gScene.currentBattle.trainer?.getTintSprites();
globalScene.time.delayedCall(250, () => {
const sprites = globalScene.currentBattle.trainer?.getSprites();
const tintSprites = globalScene.currentBattle.trainer?.getTintSprites();
if (sprites && tintSprites) {
for (let i = 0; i < sprites.length; i++) {
sprites[i].setVisible(true);
@ -596,8 +596,8 @@ function onGameOver() {
tintSprites[i].clearTint();
}
}
gScene.tweens.add({
targets: gScene.currentBattle.trainer,
globalScene.tweens.add({
targets: globalScene.currentBattle.trainer,
x: "-=16",
y: "+=16",
alpha: 1,
@ -613,7 +613,7 @@ function onGameOver() {
}
function doPostEncounterCleanup() {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
if (!encounter.misc.encounterFailed) {
// Give achievement if in Space biome
checkAchievement();

View File

@ -1,7 +1,7 @@
import { leaveEncounterWithoutBattle, transitionMysteryEncounterIntroVisuals, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { isNullOrUndefined, randSeedInt } from "#app/utils";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { catchPokemon, getRandomSpeciesByStarterTier, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
@ -58,7 +58,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
let species = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false));
let tries = 0;
@ -100,7 +100,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
encounter.dialogue.encounterOptionsDialogue!.description = `${namespace}:description_shiny`;
encounter.options[0].dialogue!.buttonTooltip = `${namespace}:option.1.tooltip_shiny`;
}
const price = gScene.getWaveMoneyAmount(priceMultiplier);
const price = globalScene.getWaveMoneyAmount(priceMultiplier);
encounter.setDialogueToken("purchasePokemon", pokemon.getNameToRender());
encounter.setDialogueToken("price", price.toString());
encounter.misc = {
@ -127,7 +127,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
],
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const price = encounter.misc.price;
const purchasedPokemon = encounter.misc.pokemon as PlayerPokemon;

View File

@ -1,7 +1,7 @@
import { EnemyPartyConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { modifierTypes, PokemonHeldItemModifierType, } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Species } from "#enums/species";
@ -68,7 +68,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculate boss mon
const config: EnemyPartyConfig = {
@ -103,7 +103,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(`${namespace}:option.2.stat_boost`);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.DEF, Stat.SPDEF ], 2));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ Stat.DEF, Stat.SPDEF ], 2));
}
}
],
@ -132,15 +132,15 @@ export const TheStrongStuffEncounter: MysteryEncounter =
]
},
async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Do blackout and hide intro visuals during blackout
gScene.time.delayedCall(750, () => {
globalScene.time.delayedCall(750, () => {
transitionMysteryEncounterIntroVisuals(true, true, 50);
});
// -15 to all base stats of highest BST (halved for HP), +10 to all base stats of rest of party (halved for HP)
// Sort party by bst
const sortedParty = gScene.getParty().slice(0)
const sortedParty = globalScene.getParty().slice(0)
.sort((pokemon1, pokemon2) => {
const pokemon1Bst = pokemon1.calculateBaseStats().reduce((a, b) => a + b, 0);
const pokemon2Bst = pokemon2.calculateBaseStats().reduce((a, b) => a + b, 0);
@ -184,7 +184,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
},
async () => {
// Pick battle
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
setEncounterRewards({ guaranteedModifierTypeFuncs: [ modifierTypes.SOUL_DEW ], fillRemaining: true });
encounter.startOfBattleEffects.push(
{

View File

@ -1,7 +1,7 @@
import { EnemyPartyConfig, generateModifierType, generateModifierTypeOption, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { TrainerType } from "#enums/trainer-type";
@ -83,7 +83,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
])
.withAutoHideIntroVisuals(false)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Loaded back to front for pop() operations
encounter.enemyPartyConfigs.push(getVitoTrainerConfig());
@ -111,7 +111,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
},
async () => {
// Spawn 5 trainer battles back to back with Macho Brace in rewards
gScene.currentBattle.mysteryEncounter!.doContinueEncounter = async () => {
globalScene.currentBattle.mysteryEncounter!.doContinueEncounter = async () => {
await endTrainerBattleAndShowDialogue();
};
await transitionMysteryEncounterIntroVisuals(true, false);
@ -131,7 +131,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
},
async () => {
// Refuse the challenge, they full heal the party and give the player a Rarer Candy
gScene.unshiftPhase(new PartyHealPhase(true));
globalScene.unshiftPhase(new PartyHealPhase(true));
setEncounterRewards({ guaranteedModifierTypeFuncs: [ modifierTypes.RARER_CANDY ], fillRemaining: false });
leaveEncounterWithoutBattle();
}
@ -139,7 +139,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
.build();
async function spawnNextTrainerOrEndEncounter() {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const nextConfig = encounter.enemyPartyConfigs.pop();
if (!nextConfig) {
await transitionMysteryEncounterIntroVisuals(false, false);
@ -147,12 +147,12 @@ async function spawnNextTrainerOrEndEncounter() {
// Give 10x Voucher
const newModifier = modifierTypes.VOUCHER_PREMIUM().newModifier();
await gScene.addModifier(newModifier);
gScene.playSound("item_fanfare");
await globalScene.addModifier(newModifier);
globalScene.playSound("item_fanfare");
await showEncounterText(i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }));
await showEncounterDialogue(`${namespace}:victory_2`, `${namespace}:speaker`);
gScene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in
globalScene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in
const machoBrace = generateModifierTypeOption(modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!;
machoBrace.type.tier = ModifierTier.MASTER;
setEncounterRewards({ guaranteedModifierTypeOptions: [ machoBrace ], fillRemaining: false });
@ -165,11 +165,11 @@ async function spawnNextTrainerOrEndEncounter() {
function endTrainerBattleAndShowDialogue(): Promise<void> {
return new Promise(async resolve => {
if (gScene.currentBattle.mysteryEncounter!.enemyPartyConfigs.length === 0) {
if (globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs.length === 0) {
// Battle is over
const trainer = gScene.currentBattle.trainer;
const trainer = globalScene.currentBattle.trainer;
if (trainer) {
gScene.tweens.add({
globalScene.tweens.add({
targets: trainer,
x: "+=16",
y: "-=16",
@ -177,7 +177,7 @@ function endTrainerBattleAndShowDialogue(): Promise<void> {
ease: "Sine.easeInOut",
duration: 750,
onComplete: () => {
gScene.field.remove(trainer, true);
globalScene.field.remove(trainer, true);
}
});
}
@ -185,29 +185,29 @@ function endTrainerBattleAndShowDialogue(): Promise<void> {
await spawnNextTrainerOrEndEncounter();
resolve(); // Wait for all dialogue/post battle stuff to complete before resolving
} else {
gScene.arena.resetArenaEffects();
const playerField = gScene.getPlayerField();
playerField.forEach((_, p) => gScene.unshiftPhase(new ReturnPhase(p)));
globalScene.arena.resetArenaEffects();
const playerField = globalScene.getPlayerField();
playerField.forEach((_, p) => globalScene.unshiftPhase(new ReturnPhase(p)));
for (const pokemon of gScene.getParty()) {
for (const pokemon of globalScene.getParty()) {
// Only trigger form change when Eiscue is in Noice form
// Hardcoded Eiscue for now in case it is fused with another pokemon
if (pokemon.species.speciesId === Species.EISCUE && pokemon.hasAbility(Abilities.ICE_FACE) && pokemon.formIndex === 1) {
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
}
pokemon.resetBattleData();
applyPostBattleInitAbAttrs(PostBattleInitAbAttr, pokemon);
}
gScene.unshiftPhase(new ShowTrainerPhase());
globalScene.unshiftPhase(new ShowTrainerPhase());
// Hide the trainer and init next battle
const trainer = gScene.currentBattle.trainer;
const trainer = globalScene.currentBattle.trainer;
// Unassign previous trainer from battle so it isn't destroyed before animation completes
gScene.currentBattle.trainer = null;
globalScene.currentBattle.trainer = null;
await spawnNextTrainerOrEndEncounter();
if (trainer) {
gScene.tweens.add({
globalScene.tweens.add({
targets: trainer,
x: "+=16",
y: "-=16",
@ -215,7 +215,7 @@ function endTrainerBattleAndShowDialogue(): Promise<void> {
ease: "Sine.easeInOut",
duration: 750,
onComplete: () => {
gScene.field.remove(trainer, true);
globalScene.field.remove(trainer, true);
resolve();
}
});

View File

@ -10,7 +10,7 @@ import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
import { isNullOrUndefined, randSeedShuffle } from "#app/utils";
import { BattlerTagType } from "#enums/battler-tag-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
@ -71,7 +71,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
],
})
.withPreOptionPhase(async (): Promise<boolean> => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
encounter.misc = {
playerPokemon: pokemon,
@ -86,18 +86,18 @@ export const TrainingSessionEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const playerPokemon: PlayerPokemon = encounter.misc.playerPokemon;
// Spawn light training session with chosen pokemon
// Every 50 waves, add +1 boss segment, capping at 5
const segments = Math.min(
2 + Math.floor(gScene.currentBattle.waveIndex / 50),
2 + Math.floor(globalScene.currentBattle.waveIndex / 50),
5
);
const modifiers = new ModifiersHolder();
const config = getEnemyConfig(playerPokemon, segments, modifiers);
gScene.removePokemonFromPlayerParty(playerPokemon, false);
globalScene.removePokemonFromPlayerParty(playerPokemon, false);
const onBeforeRewardsPhase = () => {
encounter.setDialogueToken("stat1", "-");
@ -147,17 +147,17 @@ export const TrainingSessionEncounter: MysteryEncounter =
if (improvedCount > 0) {
playerPokemon.calculateStats();
gScene.gameData.updateSpeciesDexIvs(playerPokemon.species.getRootSpeciesId(true), playerPokemon.ivs);
gScene.gameData.setPokemonCaught(playerPokemon, false);
globalScene.gameData.updateSpeciesDexIvs(playerPokemon.species.getRootSpeciesId(true), playerPokemon.ivs);
globalScene.gameData.setPokemonCaught(playerPokemon, false);
}
// Add pokemon and mods back
gScene.getParty().push(playerPokemon);
globalScene.getParty().push(playerPokemon);
for (const mod of modifiers.value) {
mod.pokemonId = playerPokemon.id;
gScene.addModifier(mod, true, false, false, true);
globalScene.addModifier(mod, true, false, false, true);
}
gScene.updateModifiers(true);
globalScene.updateModifiers(true);
queueEncounterMessage(`${namespace}:option.1.finished`);
};
@ -183,13 +183,13 @@ export const TrainingSessionEncounter: MysteryEncounter =
})
.withPreOptionPhase(async (): Promise<boolean> => {
// Open menu for selecting pokemon and Nature
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const natures = new Array(25).fill(null).map((val, i) => i as Nature);
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Return the options for nature selection
return natures.map((nature: Nature) => {
const option: OptionSelectItem = {
label: getNatureName(nature, true, true, true, gScene.uiTheme),
label: getNatureName(nature, true, true, true, globalScene.uiTheme),
handler: () => {
// Pokemon and second option selected
encounter.setDialogueToken("nature", getNatureName(nature));
@ -212,29 +212,29 @@ export const TrainingSessionEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const playerPokemon: PlayerPokemon = encounter.misc.playerPokemon;
// Spawn medium training session with chosen pokemon
// Every 40 waves, add +1 boss segment, capping at 6
const segments = Math.min(2 + Math.floor(gScene.currentBattle.waveIndex / 40), 6);
const segments = Math.min(2 + Math.floor(globalScene.currentBattle.waveIndex / 40), 6);
const modifiers = new ModifiersHolder();
const config = getEnemyConfig(playerPokemon, segments, modifiers);
gScene.removePokemonFromPlayerParty(playerPokemon, false);
globalScene.removePokemonFromPlayerParty(playerPokemon, false);
const onBeforeRewardsPhase = () => {
queueEncounterMessage(`${namespace}:option.2.finished`);
// Add the pokemon back to party with Nature change
playerPokemon.setNature(encounter.misc.chosenNature);
gScene.gameData.setPokemonCaught(playerPokemon, false);
globalScene.gameData.setPokemonCaught(playerPokemon, false);
// Add pokemon and modifiers back
gScene.getParty().push(playerPokemon);
globalScene.getParty().push(playerPokemon);
for (const mod of modifiers.value) {
mod.pokemonId = playerPokemon.id;
gScene.addModifier(mod, true, false, false, true);
globalScene.addModifier(mod, true, false, false, true);
}
gScene.updateModifiers(true);
globalScene.updateModifiers(true);
};
setEncounterRewards({ fillRemaining: true }, undefined, onBeforeRewardsPhase);
@ -259,7 +259,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
})
.withPreOptionPhase(async (): Promise<boolean> => {
// Open menu for selecting pokemon and ability to learn
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const onPokemonSelected = (pokemon: PlayerPokemon) => {
// Return the options for ability selection
const speciesForm = !!pokemon.getFusionSpeciesForm()
@ -303,19 +303,19 @@ export const TrainingSessionEncounter: MysteryEncounter =
return selectPokemonForOption(onPokemonSelected, undefined, selectableFilter);
})
.withOptionPhase(async () => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const playerPokemon: PlayerPokemon = encounter.misc.playerPokemon;
// Spawn hard training session with chosen pokemon
// Every 30 waves, add +1 boss segment, capping at 6
// Also starts with +1 to all stats
const segments = Math.min(2 + Math.floor(gScene.currentBattle.waveIndex / 30), 6);
const segments = Math.min(2 + Math.floor(globalScene.currentBattle.waveIndex / 30), 6);
const modifiers = new ModifiersHolder();
const config = getEnemyConfig(playerPokemon, segments, modifiers);
config.pokemonConfigs![0].tags = [
BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON,
];
gScene.removePokemonFromPlayerParty(playerPokemon, false);
globalScene.removePokemonFromPlayerParty(playerPokemon, false);
const onBeforeRewardsPhase = () => {
queueEncounterMessage(`${namespace}:option.3.finished`);
@ -329,8 +329,8 @@ export const TrainingSessionEncounter: MysteryEncounter =
const rootFusionSpecies = playerPokemon.fusionSpecies?.getRootSpeciesId();
if (!isNullOrUndefined(rootFusionSpecies)
&& speciesStarterCosts.hasOwnProperty(rootFusionSpecies)
&& !!gScene.gameData.dexData[rootFusionSpecies].caughtAttr) {
gScene.gameData.starterData[rootFusionSpecies].abilityAttr |= playerPokemon.fusionAbilityIndex !== 1 || playerPokemon.fusionSpecies?.ability2
&& !!globalScene.gameData.dexData[rootFusionSpecies].caughtAttr) {
globalScene.gameData.starterData[rootFusionSpecies].abilityAttr |= playerPokemon.fusionAbilityIndex !== 1 || playerPokemon.fusionSpecies?.ability2
? 1 << playerPokemon.fusionAbilityIndex
: AbilityAttr.ABILITY_HIDDEN;
}
@ -339,15 +339,15 @@ export const TrainingSessionEncounter: MysteryEncounter =
}
playerPokemon.calculateStats();
gScene.gameData.setPokemonCaught(playerPokemon, false);
globalScene.gameData.setPokemonCaught(playerPokemon, false);
// Add pokemon and mods back
gScene.getParty().push(playerPokemon);
globalScene.getParty().push(playerPokemon);
for (const mod of modifiers.value) {
mod.pokemonId = playerPokemon.id;
gScene.addModifier(mod, true, false, false, true);
globalScene.addModifier(mod, true, false, false, true);
}
gScene.updateModifiers(true);
globalScene.updateModifiers(true);
};
setEncounterRewards({ fillRemaining: true }, undefined, onBeforeRewardsPhase);

View File

@ -1,7 +1,7 @@
import { EnemyPartyConfig, EnemyPokemonConfig, generateModifierType, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, loadCustomMovesForEncounter, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -59,7 +59,7 @@ export const TrashToTreasureEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculate boss mon
const bossSpecies = getPokemonSpecies(Species.GARBODOR);
@ -80,8 +80,8 @@ export const TrashToTreasureEncounter: MysteryEncounter =
// Load animations/sfx for Garbodor fight start moves
loadCustomMovesForEncounter([ Moves.TOXIC, Moves.AMNESIA ]);
gScene.loadSe("PRSFX- Dig2", "battle_anims", "PRSFX- Dig2.wav");
gScene.loadSe("PRSFX- Venom Drench", "battle_anims", "PRSFX- Venom Drench.wav");
globalScene.loadSe("PRSFX- Dig2", "battle_anims", "PRSFX- Dig2.wav");
globalScene.loadSe("PRSFX- Venom Drench", "battle_anims", "PRSFX- Venom Drench.wav");
encounter.setDialogueToken("costMultiplier", SHOP_ITEM_COST_MULTIPLIER.toString());
@ -111,8 +111,8 @@ export const TrashToTreasureEncounter: MysteryEncounter =
const blackSludge = generateModifierType(modifierTypes.MYSTERY_ENCOUNTER_BLACK_SLUDGE, [ SHOP_ITEM_COST_MULTIPLIER ]);
const modifier = blackSludge?.newModifier();
if (modifier) {
await gScene.addModifier(modifier, false, false, false, true);
gScene.playSound("battle_anims/PRSFX- Venom Drench", { volume: 2 });
await globalScene.addModifier(modifier, false, false, false, true);
globalScene.playSound("battle_anims/PRSFX- Venom Drench", { volume: 2 });
await showEncounterText(i18next.t("battle:rewardGain", { modifierName: modifier.type.name }), null, undefined, true);
}
@ -134,11 +134,11 @@ export const TrashToTreasureEncounter: MysteryEncounter =
})
.withOptionPhase(async () => {
// Investigate garbage, battle Gmax Garbodor
gScene.setFieldScale(0.75);
globalScene.setFieldScale(0.75);
await showEncounterText(`${namespace}:option.2.selected_2`);
await transitionMysteryEncounterIntroVisuals();
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
setEncounterRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT ], fillRemaining: true });
encounter.startOfBattleEffects.push(
@ -164,12 +164,12 @@ async function tryApplyDigRewardItems() {
const shellBell = generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
const leftovers = generateModifierType(modifierTypes.LEFTOVERS) as PokemonHeldItemModifierType;
const party = gScene.getParty();
const party = globalScene.getParty();
// Iterate over the party until an item was successfully given
// First leftovers
for (const pokemon of party) {
const heldItems = gScene.findModifiers(m => m instanceof PokemonHeldItemModifier
const heldItems = globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& m.pokemonId === pokemon.id, true) as PokemonHeldItemModifier[];
const existingLeftovers = heldItems.find(m => m instanceof TurnHealModifier) as TurnHealModifier;
@ -181,7 +181,7 @@ async function tryApplyDigRewardItems() {
// Second leftovers
for (const pokemon of party) {
const heldItems = gScene.findModifiers(m => m instanceof PokemonHeldItemModifier
const heldItems = globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& m.pokemonId === pokemon.id, true) as PokemonHeldItemModifier[];
const existingLeftovers = heldItems.find(m => m instanceof TurnHealModifier) as TurnHealModifier;
@ -191,12 +191,12 @@ async function tryApplyDigRewardItems() {
}
}
gScene.playSound("item_fanfare");
globalScene.playSound("item_fanfare");
await showEncounterText(i18next.t("battle:rewardGainCount", { modifierName: leftovers.name, count: 2 }), null, undefined, true);
// First Shell bell
for (const pokemon of party) {
const heldItems = gScene.findModifiers(m => m instanceof PokemonHeldItemModifier
const heldItems = globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& m.pokemonId === pokemon.id, true) as PokemonHeldItemModifier[];
const existingShellBell = heldItems.find(m => m instanceof HitHealModifier) as HitHealModifier;
@ -208,7 +208,7 @@ async function tryApplyDigRewardItems() {
// Second Shell bell
for (const pokemon of party) {
const heldItems = gScene.findModifiers(m => m instanceof PokemonHeldItemModifier
const heldItems = globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& m.pokemonId === pokemon.id, true) as PokemonHeldItemModifier[];
const existingShellBell = heldItems.find(m => m instanceof HitHealModifier) as HitHealModifier;
@ -218,17 +218,17 @@ async function tryApplyDigRewardItems() {
}
}
gScene.playSound("item_fanfare");
globalScene.playSound("item_fanfare");
await showEncounterText(i18next.t("battle:rewardGainCount", { modifierName: shellBell.name, count: 2 }), null, undefined, true);
}
function doGarbageDig() {
gScene.playSound("battle_anims/PRSFX- Dig2");
gScene.time.delayedCall(SOUND_EFFECT_WAIT_TIME, () => {
gScene.playSound("battle_anims/PRSFX- Dig2");
gScene.playSound("battle_anims/PRSFX- Venom Drench", { volume: 2 });
globalScene.playSound("battle_anims/PRSFX- Dig2");
globalScene.time.delayedCall(SOUND_EFFECT_WAIT_TIME, () => {
globalScene.playSound("battle_anims/PRSFX- Dig2");
globalScene.playSound("battle_anims/PRSFX- Venom Drench", { volume: 2 });
});
gScene.time.delayedCall(SOUND_EFFECT_WAIT_TIME * 2, () => {
gScene.playSound("battle_anims/PRSFX- Dig2");
globalScene.time.delayedCall(SOUND_EFFECT_WAIT_TIME * 2, () => {
globalScene.playSound("battle_anims/PRSFX- Dig2");
});
}

View File

@ -4,7 +4,7 @@ import { CHARMING_MOVES } from "#app/data/mystery-encounters/requirements/requir
import Pokemon, { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
import { getPartyLuckValue } from "#app/modifier/modifier-type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
@ -46,12 +46,12 @@ export const UncommonBreedEncounter: MysteryEncounter =
},
])
.withOnInit(() => {
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
// Calculate boss mon
// Level equal to 2 below highest party member
const level = getHighestLevelPlayerPokemon(false, true).level - 2;
const species = gScene.arena.randomSpecies(gScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(gScene.getParty()), true);
const species = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getParty()), true);
const pokemon = new EnemyPokemon(species, level, TrainerSlot.NONE, true);
// Pokemon will always have one of its egg moves in its moveset
@ -73,7 +73,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
}
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = gScene.currentBattle.waveIndex < 50 ?
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = globalScene.currentBattle.waveIndex < 50 ?
[ Stat.DEF, Stat.SPDEF, Stat.SPD ] :
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
@ -86,7 +86,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(`${namespace}:option.1.stat_boost`);
gScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
}
}],
};
@ -105,15 +105,15 @@ export const UncommonBreedEncounter: MysteryEncounter =
];
encounter.setDialogueToken("enemyPokemon", pokemon.getNameToRender());
gScene.loadSe("PRSFX- Spotlight2", "battle_anims", "PRSFX- Spotlight2.wav");
globalScene.loadSe("PRSFX- Spotlight2", "battle_anims", "PRSFX- Spotlight2.wav");
return true;
})
.withOnVisualsStart(() => {
// Animate the pokemon
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const pokemonSprite = encounter.introVisuals!.getSprites();
gScene.tweens.add({ // Bounce at the end
globalScene.tweens.add({ // Bounce at the end
targets: pokemonSprite,
duration: 300,
ease: "Cubic.easeOut",
@ -122,7 +122,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
loop: 1,
});
gScene.time.delayedCall(500, () => gScene.playSound("battle_anims/PRSFX- Spotlight2"));
globalScene.time.delayedCall(500, () => globalScene.playSound("battle_anims/PRSFX- Spotlight2"));
return true;
})
.setLocalizationKey(`${namespace}`)
@ -141,7 +141,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
},
async () => {
// Pick battle
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const eggMove = encounter.misc.eggMove;
if (!isNullOrUndefined(eggMove)) {
@ -182,20 +182,20 @@ export const UncommonBreedEncounter: MysteryEncounter =
// Remove 4 random berries from player's party
// Get all player berry items, remove from party, and store reference
const berryItems: BerryModifier[] = gScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
const berryItems: BerryModifier[] = globalScene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
for (let i = 0; i < 4; i++) {
const index = randSeedInt(berryItems.length);
const randBerry = berryItems[index];
randBerry.stackCount--;
if (randBerry.stackCount === 0) {
gScene.removeModifier(randBerry);
globalScene.removeModifier(randBerry);
berryItems.splice(index, 1);
}
}
await gScene.updateModifiers(true, true);
await globalScene.updateModifiers(true, true);
// Pokemon joins the team, with 2 egg moves
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const pokemon = encounter.misc.pokemon;
// Give 1 additional egg move
@ -224,7 +224,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
.withOptionPhase(async () => {
// Attract the pokemon with a move
// Pokemon joins the team, with 2 egg moves and IVs rolled an additional time
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
const pokemon = encounter.misc.pokemon;
// Give 1 additional egg move

View File

@ -1,7 +1,7 @@
import { Type } from "#app/data/type";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Species } from "#enums/species";
import { gScene } from "#app/battle-scene";
import { globalScene } 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 { EnemyPartyConfig, EnemyPokemonConfig, generateModifierType, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, } from "../utils/encounter-phase-utils";
@ -139,12 +139,12 @@ export const WeirdDreamEncounter: MysteryEncounter =
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withOnInit(() => {
gScene.loadBgm("mystery_encounter_weird_dream", "mystery_encounter_weird_dream.mp3");
globalScene.loadBgm("mystery_encounter_weird_dream", "mystery_encounter_weird_dream.mp3");
// Calculate all the newly transformed Pokemon and begin asset load
const teamTransformations = getTeamTransformations();
const loadAssets = teamTransformations.map(t => (t.newPokemon as PlayerPokemon).loadAssets());
gScene.currentBattle.mysteryEncounter!.misc = {
globalScene.currentBattle.mysteryEncounter!.misc = {
teamTransformations,
loadAssets
};
@ -152,7 +152,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
return true;
})
.withOnVisualsStart(() => {
gScene.fadeAndSwitchBgm("mystery_encounter_weird_dream");
globalScene.fadeAndSwitchBgm("mystery_encounter_weird_dream");
return true;
})
.withOption(
@ -170,13 +170,13 @@ export const WeirdDreamEncounter: MysteryEncounter =
})
.withPreOptionPhase(async () => {
// Play the animation as the player goes through the dialogue
gScene.time.delayedCall(1000, () => {
globalScene.time.delayedCall(1000, () => {
doShowDreamBackground();
});
for (const transformation of gScene.currentBattle.mysteryEncounter!.misc.teamTransformations) {
gScene.removePokemonFromPlayerParty(transformation.previousPokemon, false);
gScene.getParty().push(transformation.newPokemon);
for (const transformation of globalScene.currentBattle.mysteryEncounter!.misc.teamTransformations) {
globalScene.removePokemonFromPlayerParty(transformation.previousPokemon, false);
globalScene.getParty().push(transformation.newPokemon);
}
})
.withOptionPhase(async () => {
@ -185,8 +185,8 @@ export const WeirdDreamEncounter: MysteryEncounter =
// Change the entire player's party
// Wait for all new Pokemon assets to be loaded before showing transformation animations
await Promise.all(gScene.currentBattle.mysteryEncounter!.misc.loadAssets);
const transformations = gScene.currentBattle.mysteryEncounter!.misc.teamTransformations;
await Promise.all(globalScene.currentBattle.mysteryEncounter!.misc.loadAssets);
const transformations = globalScene.currentBattle.mysteryEncounter!.misc.teamTransformations;
// If there are 1-3 transformations, do them centered back to back
// Otherwise, the first 3 transformations are executed side-by-side, then any remaining 1-3 transformations occur in those same respective positions
@ -225,7 +225,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
},
async () => {
// Battle your "future" team for some item rewards
const transformations: PokemonTransformation[] = gScene.currentBattle.mysteryEncounter!.misc.teamTransformations;
const transformations: PokemonTransformation[] = globalScene.currentBattle.mysteryEncounter!.misc.teamTransformations;
// Uses the pokemon that player's party would have transformed into
const enemyPokemonConfigs: EnemyPokemonConfig[] = [];
@ -268,7 +268,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
enemyPokemonConfigs.push(enemyConfig);
}
const genderIndex = gScene.gameData.gender ?? PlayerGender.UNSET;
const genderIndex = globalScene.gameData.gender ?? PlayerGender.UNSET;
const trainerConfig = trainerConfigs[genderIndex === PlayerGender.FEMALE ? TrainerType.FUTURE_SELF_F : TrainerType.FUTURE_SELF_M].clone();
trainerConfig.setPartyTemplates(new TrainerPartyTemplate(transformations.length, PartyMemberStrength.STRONG));
const enemyPartyConfig: EnemyPartyConfig = {
@ -280,7 +280,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
const onBeforeRewards = () => {
// Before battle rewards, unlock the passive on a pokemon in the player's team for the rest of the run (not permanently)
// One random pokemon will get its passive unlocked
const passiveDisabledPokemon = gScene.getParty().filter(p => !p.passive);
const passiveDisabledPokemon = globalScene.getParty().filter(p => !p.passive);
if (passiveDisabledPokemon?.length > 0) {
const enablePassiveMon = passiveDisabledPokemon[randSeedInt(passiveDisabledPokemon.length)];
enablePassiveMon.passive = true;
@ -306,7 +306,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
},
async () => {
// Leave, reduce party levels by 10%
for (const pokemon of gScene.getParty()) {
for (const pokemon of globalScene.getParty()) {
pokemon.level = Math.max(Math.ceil((100 - PERCENT_LEVEL_LOSS_ON_REFUSE) / 100 * pokemon.level), 1);
pokemon.exp = getLevelTotalExp(pokemon.level, pokemon.species.growthRate);
pokemon.levelExp = 0;
@ -329,7 +329,7 @@ interface PokemonTransformation {
}
function getTeamTransformations(): PokemonTransformation[] {
const party = gScene.getParty();
const party = globalScene.getParty();
// Removes all pokemon from the party
const alreadyUsedSpecies: PokemonSpecies[] = party.map(p => p.species);
const pokemonTransformations: PokemonTransformation[] = party.map(p => {
@ -378,7 +378,7 @@ function getTeamTransformations(): PokemonTransformation[] {
for (const transformation of pokemonTransformations) {
const newAbilityIndex = randSeedInt(transformation.newSpecies.getAbilityCount());
transformation.newPokemon = gScene.addPlayerPokemon(transformation.newSpecies, transformation.previousPokemon.level, newAbilityIndex, undefined);
transformation.newPokemon = globalScene.addPlayerPokemon(transformation.newSpecies, transformation.previousPokemon.level, newAbilityIndex, undefined);
}
return pokemonTransformations;
@ -398,17 +398,17 @@ async function doNewTeamPostProcess(transformations: PokemonTransformation[]) {
// Copy old items to new pokemon
for (const item of transformation.heldItems) {
item.pokemonId = newPokemon.id;
await gScene.addModifier(item, false, false, false, true);
await globalScene.addModifier(item, false, false, false, true);
}
// Any pokemon that is below 570 BST gets +20 permanent BST to 3 stats
if (shouldGetOldGateau(newPokemon)) {
const stats = getOldGateauBoostedStats(newPokemon);
const modType = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU()
.generateType(gScene.getParty(), [ OLD_GATEAU_STATS_UP, stats ])
.generateType(globalScene.getParty(), [ OLD_GATEAU_STATS_UP, stats ])
?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU);
const modifier = modType?.newModifier(newPokemon);
if (modifier) {
await gScene.addModifier(modifier, false, false, false, true);
await globalScene.addModifier(modifier, false, false, false, true);
}
}
@ -417,7 +417,7 @@ async function doNewTeamPostProcess(transformations: PokemonTransformation[]) {
}
// One random pokemon will get its passive unlocked
const passiveDisabledPokemon = gScene.getParty().filter(p => !p.passive);
const passiveDisabledPokemon = globalScene.getParty().filter(p => !p.passive);
if (passiveDisabledPokemon?.length > 0) {
const enablePassiveMon = passiveDisabledPokemon[randSeedInt(passiveDisabledPokemon.length)];
enablePassiveMon.passive = true;
@ -426,7 +426,7 @@ async function doNewTeamPostProcess(transformations: PokemonTransformation[]) {
// If at least one new starter was unlocked, play 1 fanfare
if (atLeastOneNewStarter) {
gScene.playSound("level_up_fanfare");
globalScene.playSound("level_up_fanfare");
}
}
@ -446,7 +446,7 @@ async function postProcessTransformedPokemon(previousPokemon: PlayerPokemon, new
const hiddenIndex = newPokemon.species.ability2 ? 2 : 1;
if (newPokemon.abilityIndex < hiddenIndex) {
const hiddenAbilityChance = new IntegerHolder(256);
gScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value);
@ -468,23 +468,23 @@ async function postProcessTransformedPokemon(previousPokemon: PlayerPokemon, new
// For pokemon at/below 570 BST or any shiny pokemon, unlock it permanently as if you had caught it
if (!forBattle && (newPokemon.getSpeciesForm().getBaseStatTotal() <= NON_LEGENDARY_BST_THRESHOLD || newPokemon.isShiny())) {
if (newPokemon.getSpeciesForm().abilityHidden && newPokemon.abilityIndex === newPokemon.getSpeciesForm().getAbilityCount() - 1) {
gScene.validateAchv(achvs.HIDDEN_ABILITY);
globalScene.validateAchv(achvs.HIDDEN_ABILITY);
}
if (newPokemon.species.subLegendary) {
gScene.validateAchv(achvs.CATCH_SUB_LEGENDARY);
globalScene.validateAchv(achvs.CATCH_SUB_LEGENDARY);
}
if (newPokemon.species.legendary) {
gScene.validateAchv(achvs.CATCH_LEGENDARY);
globalScene.validateAchv(achvs.CATCH_LEGENDARY);
}
if (newPokemon.species.mythical) {
gScene.validateAchv(achvs.CATCH_MYTHICAL);
globalScene.validateAchv(achvs.CATCH_MYTHICAL);
}
gScene.gameData.updateSpeciesDexIvs(newPokemon.species.getRootSpeciesId(true), newPokemon.ivs);
const newStarterUnlocked = await gScene.gameData.setPokemonCaught(newPokemon, true, false, false);
globalScene.gameData.updateSpeciesDexIvs(newPokemon.species.getRootSpeciesId(true), newPokemon.ivs);
const newStarterUnlocked = await globalScene.gameData.setPokemonCaught(newPokemon, true, false, false);
if (newStarterUnlocked) {
isNewStarter = true;
await showEncounterText(i18next.t("battle:addedAsAStarter", { pokemonName: getPokemonSpecies(speciesRootForm).getName() }));
@ -503,8 +503,8 @@ async function postProcessTransformedPokemon(previousPokemon: PlayerPokemon, new
});
// For pokemon that the player owns (including ones just caught), gain a candy
if (!forBattle && !!gScene.gameData.dexData[speciesRootForm].caughtAttr) {
gScene.gameData.addStarterCandy(getPokemonSpecies(speciesRootForm), 1);
if (!forBattle && !!globalScene.gameData.dexData[speciesRootForm].caughtAttr) {
globalScene.gameData.addStarterCandy(getPokemonSpecies(speciesRootForm), 1);
}
// Set the moveset of the new pokemon to be the same as previous, but with 1 egg move and 1 (attempted) STAB move of the new species
@ -597,30 +597,30 @@ function getTransformedSpecies(originalBst: number, bstSearchRange: [number, num
}
function doShowDreamBackground() {
const transformationContainer = gScene.add.container(0, -gScene.game.canvas.height / 6);
const transformationContainer = globalScene.add.container(0, -globalScene.game.canvas.height / 6);
transformationContainer.name = "Dream Background";
// In case it takes a bit for video to load
const transformationStaticBg = gScene.add.rectangle(0, 0, gScene.game.canvas.width / 6, gScene.game.canvas.height / 6, 0);
const transformationStaticBg = globalScene.add.rectangle(0, 0, globalScene.game.canvas.width / 6, globalScene.game.canvas.height / 6, 0);
transformationStaticBg.setName("Black Background");
transformationStaticBg.setOrigin(0, 0);
transformationContainer.add(transformationStaticBg);
transformationStaticBg.setVisible(true);
const transformationVideoBg: Phaser.GameObjects.Video = gScene.add.video(0, 0, "evo_bg").stop();
const transformationVideoBg: Phaser.GameObjects.Video = globalScene.add.video(0, 0, "evo_bg").stop();
transformationVideoBg.setLoop(true);
transformationVideoBg.setOrigin(0, 0);
transformationVideoBg.setScale(0.4359673025);
transformationContainer.add(transformationVideoBg);
gScene.fieldUI.add(transformationContainer);
gScene.fieldUI.bringToTop(transformationContainer);
globalScene.fieldUI.add(transformationContainer);
globalScene.fieldUI.bringToTop(transformationContainer);
transformationVideoBg.play();
transformationContainer.setVisible(true);
transformationContainer.alpha = 0;
gScene.tweens.add({
globalScene.tweens.add({
targets: transformationContainer,
alpha: 1,
duration: 3000,
@ -629,15 +629,15 @@ function doShowDreamBackground() {
}
function doHideDreamBackground() {
const transformationContainer = gScene.fieldUI.getByName("Dream Background");
const transformationContainer = globalScene.fieldUI.getByName("Dream Background");
gScene.tweens.add({
globalScene.tweens.add({
targets: transformationContainer,
alpha: 0,
duration: 3000,
ease: "Sine.easeInOut",
onComplete: () => {
gScene.fieldUI.remove(transformationContainer, true);
globalScene.fieldUI.remove(transformationContainer, true);
}
});
}
@ -647,7 +647,7 @@ function doSideBySideTransformations(transformations: PokemonTransformation[]) {
const allTransformationPromises: Promise<void>[] = [];
for (let i = 0; i < 3; i++) {
const delay = i * 4000;
gScene.time.delayedCall(delay, () => {
globalScene.time.delayedCall(delay, () => {
const transformation = transformations[i];
const pokemon1 = transformation.previousPokemon;
const pokemon2 = transformation.newPokemon;
@ -711,8 +711,8 @@ async function addEggMoveToNewPokemonMoveset(newPokemon: PlayerPokemon, speciesR
}
// For pokemon that the player owns (including ones just caught), unlock the egg move
if (!forBattle && !isNullOrUndefined(randomEggMoveIndex) && !!gScene.gameData.dexData[speciesRootForm].caughtAttr) {
await gScene.gameData.setEggMoveUnlocked(getPokemonSpecies(speciesRootForm), randomEggMoveIndex, true);
if (!forBattle && !isNullOrUndefined(randomEggMoveIndex) && !!globalScene.gameData.dexData[speciesRootForm].caughtAttr) {
await globalScene.gameData.setEggMoveUnlocked(getPokemonSpecies(speciesRootForm), randomEggMoveIndex, true);
}
}
}

View File

@ -1,7 +1,7 @@
import { OptionTextDisplay } from "#app/data/mystery-encounters/mystery-encounter-dialogue";
import { Moves } from "#app/enums/moves";
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { Type } from "../type";
import { EncounterPokemonRequirement, EncounterSceneRequirement, MoneyRequirement, TypeRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
import { CanLearnMoveRequirement, CanLearnMoveRequirementOptions } from "./requirements/can-learn-move-requirement";
@ -88,7 +88,7 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption {
* @param pokemon
*/
pokemonMeetsPrimaryRequirements(pokemon: Pokemon): boolean {
return !this.primaryPokemonRequirements.some(req => !req.queryParty(gScene.getParty()).map(p => p.id).includes(pokemon.id));
return !this.primaryPokemonRequirements.some(req => !req.queryParty(globalScene.getParty()).map(p => p.id).includes(pokemon.id));
}
/**
@ -102,10 +102,10 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption {
if (!this.primaryPokemonRequirements || this.primaryPokemonRequirements.length === 0) {
return true;
}
let qualified: PlayerPokemon[] = gScene.getParty();
let qualified: PlayerPokemon[] = globalScene.getParty();
for (const req of this.primaryPokemonRequirements) {
if (req.meetsRequirement()) {
const queryParty = req.queryParty(gScene.getParty());
const queryParty = req.queryParty(globalScene.getParty());
qualified = qualified.filter(pkmn => queryParty.includes(pkmn));
} else {
this.primaryPokemon = undefined;
@ -162,10 +162,10 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption {
return true;
}
let qualified: PlayerPokemon[] = gScene.getParty();
let qualified: PlayerPokemon[] = globalScene.getParty();
for (const req of this.secondaryPokemonRequirements) {
if (req.meetsRequirement()) {
const queryParty = req.queryParty(gScene.getParty());
const queryParty = req.queryParty(globalScene.getParty());
qualified = qualified.filter(pkmn => queryParty.includes(pkmn));
} else {
this.secondaryPokemon = [];

View File

@ -1,5 +1,5 @@
import { PlayerPokemon } from "#app/field/pokemon";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { isNullOrUndefined } from "#app/utils";
import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
@ -201,11 +201,11 @@ export class PreviousEncounterRequirement extends EncounterSceneRequirement {
}
override meetsRequirement(): boolean {
return gScene.mysteryEncounterSaveData.encounteredEvents.some(e => e.type === this.previousEncounterRequirement);
return globalScene.mysteryEncounterSaveData.encounteredEvents.some(e => e.type === this.previousEncounterRequirement);
}
override getDialogueToken(pokemon?: PlayerPokemon): [string, string] {
return [ "previousEncounter", gScene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? "" ];
return [ "previousEncounter", globalScene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? "" ];
}
}
@ -224,7 +224,7 @@ export class WaveRangeRequirement extends EncounterSceneRequirement {
override meetsRequirement(): boolean {
if (!isNullOrUndefined(this.waveRange) && this.waveRange[0] <= this.waveRange[1]) {
const waveIndex = gScene.currentBattle.waveIndex;
const waveIndex = globalScene.currentBattle.waveIndex;
if (waveIndex >= 0 && (this.waveRange[0] >= 0 && this.waveRange[0] > waveIndex) || (this.waveRange[1] >= 0 && this.waveRange[1] < waveIndex)) {
return false;
}
@ -233,7 +233,7 @@ export class WaveRangeRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(pokemon?: PlayerPokemon): [string, string] {
return [ "waveIndex", gScene.currentBattle.waveIndex.toString() ];
return [ "waveIndex", globalScene.currentBattle.waveIndex.toString() ];
}
}
@ -258,11 +258,11 @@ export class WaveModulusRequirement extends EncounterSceneRequirement {
}
override meetsRequirement(): boolean {
return this.waveModuli.includes(gScene.currentBattle.waveIndex % this.modulusValue);
return this.waveModuli.includes(globalScene.currentBattle.waveIndex % this.modulusValue);
}
override getDialogueToken(pokemon?: PlayerPokemon): [string, string] {
return [ "waveIndex", gScene.currentBattle.waveIndex.toString() ];
return [ "waveIndex", globalScene.currentBattle.waveIndex.toString() ];
}
}
@ -275,7 +275,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
}
override meetsRequirement(): boolean {
const timeOfDay = gScene.arena?.getTimeOfDay();
const timeOfDay = globalScene.arena?.getTimeOfDay();
if (!isNullOrUndefined(timeOfDay) && this.requiredTimeOfDay?.length > 0 && !this.requiredTimeOfDay.includes(timeOfDay)) {
return false;
}
@ -284,7 +284,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(pokemon?: PlayerPokemon): [string, string] {
return [ "timeOfDay", TimeOfDay[gScene.arena.getTimeOfDay()].toLocaleLowerCase() ];
return [ "timeOfDay", TimeOfDay[globalScene.arena.getTimeOfDay()].toLocaleLowerCase() ];
}
}
@ -297,7 +297,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
}
override meetsRequirement(): boolean {
const currentWeather = gScene.arena.weather?.weatherType;
const currentWeather = globalScene.arena.weather?.weatherType;
if (!isNullOrUndefined(currentWeather) && this.requiredWeather?.length > 0 && !this.requiredWeather.includes(currentWeather!)) {
return false;
}
@ -306,7 +306,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(pokemon?: PlayerPokemon): [string, string] {
const currentWeather = gScene.arena.weather?.weatherType;
const currentWeather = globalScene.arena.weather?.weatherType;
let token = "";
if (!isNullOrUndefined(currentWeather)) {
token = WeatherType[currentWeather].replace("_", " ").toLocaleLowerCase();
@ -333,7 +333,7 @@ export class PartySizeRequirement extends EncounterSceneRequirement {
override meetsRequirement(): boolean {
if (!isNullOrUndefined(this.partySizeRange) && this.partySizeRange[0] <= this.partySizeRange[1]) {
const partySize = this.excludeDisallowedPokemon ? gScene.getParty().filter(p => p.isAllowedInBattle()).length : gScene.getParty().length;
const partySize = this.excludeDisallowedPokemon ? globalScene.getParty().filter(p => p.isAllowedInBattle()).length : globalScene.getParty().length;
if (partySize >= 0 && (this.partySizeRange[0] >= 0 && this.partySizeRange[0] > partySize) || (this.partySizeRange[1] >= 0 && this.partySizeRange[1] < partySize)) {
return false;
}
@ -343,7 +343,7 @@ export class PartySizeRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(pokemon?: PlayerPokemon): [string, string] {
return [ "partySize", gScene.getParty().length.toString() ];
return [ "partySize", globalScene.getParty().length.toString() ];
}
}
@ -358,13 +358,13 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon) || this.requiredHeldItemModifiers?.length < 0) {
return false;
}
let modifierCount = 0;
this.requiredHeldItemModifiers.forEach(modifier => {
const matchingMods = gScene.findModifiers(m => m.constructor.name === modifier);
const matchingMods = globalScene.findModifiers(m => m.constructor.name === modifier);
if (matchingMods?.length > 0) {
matchingMods.forEach(matchingMod => {
modifierCount += matchingMod.stackCount;
@ -391,19 +391,19 @@ export class MoneyRequirement extends EncounterSceneRequirement {
}
override meetsRequirement(): boolean {
const money = gScene.money;
const money = globalScene.money;
if (isNullOrUndefined(money)) {
return false;
}
if (this.scalingMultiplier > 0) {
this.requiredMoney = gScene.getWaveMoneyAmount(this.scalingMultiplier);
this.requiredMoney = globalScene.getWaveMoneyAmount(this.scalingMultiplier);
}
return !(this.requiredMoney > 0 && this.requiredMoney > money);
}
override getDialogueToken(pokemon?: PlayerPokemon): [string, string] {
const value = this.scalingMultiplier > 0 ? gScene.getWaveMoneyAmount(this.scalingMultiplier).toString() : this.requiredMoney.toString();
const value = this.scalingMultiplier > 0 ? globalScene.getWaveMoneyAmount(this.scalingMultiplier).toString() : this.requiredMoney.toString();
return [ "money", value ];
}
}
@ -421,7 +421,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon) || this.requiredSpecies?.length < 0) {
return false;
}
@ -459,7 +459,7 @@ export class NatureRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon) || this.requiredNature?.length < 0) {
return false;
}
@ -498,7 +498,7 @@ export class TypeRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
let partyPokemon = gScene.getParty();
let partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon)) {
return false;
@ -545,7 +545,7 @@ export class MoveRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) {
return false;
}
@ -594,7 +594,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) {
return false;
}
@ -635,7 +635,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon) || this.requiredAbilities?.length < 0) {
return false;
}
@ -677,7 +677,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon) || this.requiredStatusEffect?.length < 0) {
return false;
}
@ -746,7 +746,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon) || this.requiredFormChangeItem?.length < 0) {
return false;
}
@ -798,7 +798,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon) || this.requiredEvolutionItem?.length < 0) {
return false;
}
@ -849,7 +849,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon)) {
return false;
}
@ -900,7 +900,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
if (isNullOrUndefined(partyPokemon)) {
return false;
}
@ -957,7 +957,7 @@ export class LevelRequirement extends EncounterPokemonRequirement {
override meetsRequirement(): boolean {
// Party Pokemon inside required level range
if (!isNullOrUndefined(this.requiredLevelRange) && this.requiredLevelRange[0] <= this.requiredLevelRange[1]) {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
const pokemonInRange = this.queryParty(partyPokemon);
if (pokemonInRange.length < this.minNumberOfPokemon) {
return false;
@ -995,7 +995,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
override meetsRequirement(): boolean {
// Party Pokemon inside required friendship range
if (!isNullOrUndefined(this.requiredFriendshipRange) && this.requiredFriendshipRange[0] <= this.requiredFriendshipRange[1]) {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
const pokemonInRange = this.queryParty(partyPokemon);
if (pokemonInRange.length < this.minNumberOfPokemon) {
return false;
@ -1038,7 +1038,7 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
override meetsRequirement(): boolean {
// Party Pokemon's health inside required health range
if (!isNullOrUndefined(this.requiredHealthRange) && this.requiredHealthRange[0] <= this.requiredHealthRange[1]) {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
const pokemonInRange = this.queryParty(partyPokemon);
if (pokemonInRange.length < this.minNumberOfPokemon) {
return false;
@ -1082,7 +1082,7 @@ export class WeightRequirement extends EncounterPokemonRequirement {
override meetsRequirement(): boolean {
// Party Pokemon's weight inside required weight range
if (!isNullOrUndefined(this.requiredWeightRange) && this.requiredWeightRange[0] <= this.requiredWeightRange[1]) {
const partyPokemon = gScene.getParty();
const partyPokemon = globalScene.getParty();
const pokemonInRange = this.queryParty(partyPokemon);
if (pokemonInRange.length < this.minNumberOfPokemon) {
return false;

View File

@ -15,7 +15,7 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode
import { GameModes } from "#app/game-mode";
import { EncounterAnim } from "#enums/encounter-anims";
import { Challenges } from "#enums/challenges";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export interface EncounterStartOfBattleEffect {
sourcePokemon?: Pokemon;
@ -314,7 +314,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
* @param pokemon
*/
pokemonMeetsPrimaryRequirements(pokemon: Pokemon): boolean {
return !this.primaryPokemonRequirements.some(req => !req.queryParty(gScene.getParty()).map(p => p.id).includes(pokemon.id));
return !this.primaryPokemonRequirements.some(req => !req.queryParty(globalScene.getParty()).map(p => p.id).includes(pokemon.id));
}
/**
@ -326,18 +326,18 @@ export default class MysteryEncounter implements IMysteryEncounter {
*/
private meetsPrimaryRequirementAndPrimaryPokemonSelected(): boolean {
if (!this.primaryPokemonRequirements || this.primaryPokemonRequirements.length === 0) {
const activeMon = gScene.getParty().filter(p => p.isActive(true));
const activeMon = globalScene.getParty().filter(p => p.isActive(true));
if (activeMon.length > 0) {
this.primaryPokemon = activeMon[0];
} else {
this.primaryPokemon = gScene.getParty().filter(p => p.isAllowedInBattle())[0];
this.primaryPokemon = globalScene.getParty().filter(p => p.isAllowedInBattle())[0];
}
return true;
}
let qualified: PlayerPokemon[] = gScene.getParty();
let qualified: PlayerPokemon[] = globalScene.getParty();
for (const req of this.primaryPokemonRequirements) {
if (req.meetsRequirement()) {
qualified = qualified.filter(pkmn => req.queryParty(gScene.getParty()).includes(pkmn));
qualified = qualified.filter(pkmn => req.queryParty(globalScene.getParty()).includes(pkmn));
} else {
this.primaryPokemon = undefined;
return false;
@ -394,10 +394,10 @@ export default class MysteryEncounter implements IMysteryEncounter {
return true;
}
let qualified: PlayerPokemon[] = gScene.getParty();
let qualified: PlayerPokemon[] = globalScene.getParty();
for (const req of this.secondaryPokemonRequirements) {
if (req.meetsRequirement()) {
qualified = qualified.filter(pkmn => req.queryParty(gScene.getParty()).includes(pkmn));
qualified = qualified.filter(pkmn => req.queryParty(globalScene.getParty()).includes(pkmn));
} else {
this.secondaryPokemon = [];
return false;
@ -521,7 +521,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
* @param scene
*/
updateSeedOffset() {
const currentOffset = this.seedOffset ?? gScene.currentBattle.waveIndex * 1000;
const currentOffset = this.seedOffset ?? globalScene.currentBattle.waveIndex * 1000;
this.seedOffset = currentOffset + 512;
}
}

View File

@ -2,7 +2,7 @@ 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 { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
/**
* {@linkcode CanLearnMoveRequirement} options
@ -39,7 +39,7 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
}
override meetsRequirement(): boolean {
const partyPokemon = gScene.getParty().filter((pkm) => (this.includeFainted ? pkm.isAllowed() : pkm.isAllowedInBattle()));
const partyPokemon = globalScene.getParty().filter((pkm) => (this.includeFainted ? pkm.isAllowed() : pkm.isAllowedInBattle()));
if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) {
return false;

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { getTextWithColors, TextStyle } from "#app/ui/text";
import { UiTheme } from "#enums/ui-theme";
import { isNullOrUndefined } from "#app/utils";
@ -29,12 +29,12 @@ export function getEncounterText(keyOrString?: string, primaryStyle?: TextStyle,
}
/**
* Helper function to inject {@linkcode gScene.currentBattle.mysteryEncounter.dialogueTokens} into a given content string
* Helper function to inject {@linkcode globalScene.currentBattle.mysteryEncounter.dialogueTokens} into a given content string
* @param scene
* @param keyOrString
*/
function getTextWithDialogueTokens(keyOrString: string): string | null {
const tokens = gScene.currentBattle?.mysteryEncounter?.dialogueTokens;
const tokens = globalScene.currentBattle?.mysteryEncounter?.dialogueTokens;
if (i18next.exists(keyOrString, tokens)) {
return i18next.t(keyOrString, tokens) as string;
@ -50,7 +50,7 @@ function getTextWithDialogueTokens(keyOrString: string): string | null {
*/
export function queueEncounterMessage(contentKey: string): void {
const text: string | null = getEncounterText(contentKey);
gScene.queueMessage(text ?? "", null, true);
globalScene.queueMessage(text ?? "", null, true);
}
/**
@ -65,7 +65,7 @@ export function queueEncounterMessage(contentKey: string): void {
export function showEncounterText(contentKey: string, delay: number | null = null, callbackDelay: number = 0, prompt: boolean = true, promptDelay: number | null = null): Promise<void> {
return new Promise<void>(resolve => {
const text: string | null = getEncounterText(contentKey);
gScene.ui.showText(text ?? "", delay, () => resolve(), callbackDelay, prompt, promptDelay);
globalScene.ui.showText(text ?? "", delay, () => resolve(), callbackDelay, prompt, promptDelay);
});
}
@ -81,6 +81,6 @@ export function showEncounterDialogue(textContentKey: string, speakerContentKey:
return new Promise<void>(resolve => {
const text: string | null = getEncounterText(textContentKey);
const speaker: string | null = getEncounterText(speakerContentKey);
gScene.ui.showDialogue(text ?? "", speaker ?? "", delay, () => resolve(), callbackDelay);
globalScene.ui.showDialogue(text ?? "", speaker ?? "", delay, () => resolve(), callbackDelay);
});
}

View File

@ -36,33 +36,33 @@ import { GameOverPhase } from "#app/phases/game-over-phase";
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
import { PartyExpPhase } from "#app/phases/party-exp-phase";
import { Variant } from "#app/data/variant";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
/**
* Animates exclamation sprite over trainer's head at start of encounter
* @param scene
*/
export function doTrainerExclamation() {
const exclamationSprite = gScene.add.sprite(0, 0, "encounter_exclaim");
const exclamationSprite = globalScene.add.sprite(0, 0, "encounter_exclaim");
exclamationSprite.setName("exclamation");
gScene.field.add(exclamationSprite);
gScene.field.moveTo(exclamationSprite, gScene.field.getAll().length - 1);
globalScene.field.add(exclamationSprite);
globalScene.field.moveTo(exclamationSprite, globalScene.field.getAll().length - 1);
exclamationSprite.setVisible(true);
exclamationSprite.setPosition(110, 68);
gScene.tweens.add({
globalScene.tweens.add({
targets: exclamationSprite,
y: "-=25",
ease: "Cubic.easeOut",
duration: 300,
yoyo: true,
onComplete: () => {
gScene.time.delayedCall(800, () => {
gScene.field.remove(exclamationSprite, true);
globalScene.time.delayedCall(800, () => {
globalScene.field.remove(exclamationSprite, true);
});
}
});
gScene.playSound("battle_anims/GEN8- Exclaim", { volume: 0.7 });
globalScene.playSound("battle_anims/GEN8- Exclaim", { volume: 0.7 });
}
export interface EnemyPokemonConfig {
@ -120,7 +120,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
const loaded: boolean = false;
const loadEnemyAssets: Promise<void>[] = [];
const battle: Battle = gScene.currentBattle;
const battle: Battle = globalScene.currentBattle;
let doubleBattle: boolean = partyConfig?.doubleBattle ?? false;
@ -129,10 +129,10 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
const partyTrainerConfig = partyConfig?.trainerConfig;
let trainerConfig: TrainerConfig;
if (!isNullOrUndefined(trainerType) || partyTrainerConfig) {
gScene.currentBattle.mysteryEncounter!.encounterMode = MysteryEncounterMode.TRAINER_BATTLE;
if (gScene.currentBattle.trainer) {
gScene.currentBattle.trainer.setVisible(false);
gScene.currentBattle.trainer.destroy();
globalScene.currentBattle.mysteryEncounter!.encounterMode = MysteryEncounterMode.TRAINER_BATTLE;
if (globalScene.currentBattle.trainer) {
globalScene.currentBattle.trainer.setVisible(false);
globalScene.currentBattle.trainer.destroy();
}
trainerConfig = partyTrainerConfig ? partyTrainerConfig : trainerConfigs[trainerType!];
@ -143,20 +143,20 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
const newTrainer = new Trainer(trainerConfig.trainerType, doubleTrainer ? TrainerVariant.DOUBLE : trainerFemale ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT, undefined, undefined, undefined, trainerConfig);
newTrainer.x += 300;
newTrainer.setVisible(false);
gScene.field.add(newTrainer);
gScene.currentBattle.trainer = newTrainer;
globalScene.field.add(newTrainer);
globalScene.currentBattle.trainer = newTrainer;
loadEnemyAssets.push(newTrainer.loadAssets().then(() => newTrainer.initSprite()));
battle.enemyLevels = gScene.currentBattle.trainer.getPartyLevels(gScene.currentBattle.waveIndex);
battle.enemyLevels = globalScene.currentBattle.trainer.getPartyLevels(globalScene.currentBattle.waveIndex);
} else {
// Wild
gScene.currentBattle.mysteryEncounter!.encounterMode = MysteryEncounterMode.WILD_BATTLE;
globalScene.currentBattle.mysteryEncounter!.encounterMode = MysteryEncounterMode.WILD_BATTLE;
const numEnemies = partyConfig?.pokemonConfigs && partyConfig.pokemonConfigs.length > 0 ? partyConfig?.pokemonConfigs?.length : doubleBattle ? 2 : 1;
battle.enemyLevels = new Array(numEnemies).fill(null).map(() => gScene.currentBattle.getLevelForWave());
battle.enemyLevels = new Array(numEnemies).fill(null).map(() => globalScene.currentBattle.getLevelForWave());
}
gScene.getEnemyParty().forEach(enemyPokemon => {
gScene.field.remove(enemyPokemon, true);
globalScene.getEnemyParty().forEach(enemyPokemon => {
globalScene.field.remove(enemyPokemon, true);
});
battle.enemyParty = [];
battle.double = doubleBattle;
@ -167,7 +167,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
// levelAdditiveModifier 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 additive = Math.max(Math.round((gScene.currentBattle.waveIndex / 10) * mult), 0);
const additive = Math.max(Math.round((globalScene.currentBattle.waveIndex / 10) * mult), 0);
battle.enemyLevels = battle.enemyLevels.map(level => level + additive);
battle.enemyLevels.forEach((level, e) => {
@ -183,7 +183,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
dataSource = config.dataSource;
enemySpecies = config.species;
isBoss = config.isBoss;
battle.enemyParty[e] = gScene.addEnemyPokemon(enemySpecies, level, TrainerSlot.TRAINER, isBoss, dataSource);
battle.enemyParty[e] = globalScene.addEnemyPokemon(enemySpecies, level, TrainerSlot.TRAINER, isBoss, dataSource);
} else {
battle.enemyParty[e] = battle.trainer.genPartyMember(e);
}
@ -195,17 +195,17 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
enemySpecies = config.species;
isBoss = config.isBoss;
if (isBoss) {
gScene.currentBattle.mysteryEncounter!.encounterMode = MysteryEncounterMode.BOSS_BATTLE;
globalScene.currentBattle.mysteryEncounter!.encounterMode = MysteryEncounterMode.BOSS_BATTLE;
}
} else {
enemySpecies = gScene.randomSpecies(battle.waveIndex, level, true);
enemySpecies = globalScene.randomSpecies(battle.waveIndex, level, true);
}
battle.enemyParty[e] = gScene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, isBoss, dataSource);
battle.enemyParty[e] = globalScene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, isBoss, dataSource);
}
}
const enemyPokemon = gScene.getEnemyParty()[e];
const enemyPokemon = globalScene.getEnemyParty()[e];
// Make sure basic data is clean
enemyPokemon.hp = enemyPokemon.getMaxHp();
@ -218,7 +218,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
}
if (!loaded && isNullOrUndefined(partyConfig.countAsSeen) || partyConfig.countAsSeen) {
gScene.gameData.setPokemonSeen(enemyPokemon, true, !!(trainerType || trainerConfig));
globalScene.gameData.setPokemonSeen(enemyPokemon, true, !!(trainerType || trainerConfig));
}
if (partyConfig?.pokemonConfigs && e < partyConfig.pokemonConfigs.length) {
@ -256,7 +256,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
// Set Boss
if (config.isBoss) {
let segments = !isNullOrUndefined(config.bossSegments) ? config.bossSegments! : gScene.getEncounterBossSegments(gScene.currentBattle.waveIndex, level, enemySpecies, true);
let segments = !isNullOrUndefined(config.bossSegments) ? config.bossSegments! : globalScene.getEncounterBossSegments(globalScene.currentBattle.waveIndex, level, enemySpecies, true);
if (!isNullOrUndefined(config.bossSegmentModifier)) {
segments += config.bossSegmentModifier;
}
@ -342,7 +342,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
console.log(`Pokemon: ${enemyPokemon.name}`, `Species ID: ${enemyPokemon.species.speciesId}`, `Stats: ${enemyPokemon.stats}`, `Ability: ${enemyPokemon.getAbility().name}`, `Passive Ability: ${enemyPokemon.getPassiveAbility().name}`);
});
gScene.pushPhase(new MysteryEncounterBattlePhase(partyConfig.disableSwitch));
globalScene.pushPhase(new MysteryEncounterBattlePhase(partyConfig.disableSwitch));
await Promise.all(loadEnemyAssets);
battle.enemyParty.forEach((enemyPokemon_2, e_1) => {
@ -356,11 +356,11 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
}
});
if (!loaded) {
regenerateModifierPoolThresholds(gScene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD);
regenerateModifierPoolThresholds(globalScene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD);
const customModifierTypes = partyConfig?.pokemonConfigs
?.filter(config => config?.modifierConfigs)
.map(config => config.modifierConfigs!);
gScene.generateEnemyModifiers(customModifierTypes);
globalScene.generateEnemyModifiers(customModifierTypes);
}
}
@ -386,17 +386,17 @@ export function loadCustomMovesForEncounter(moves: Moves | Moves[]) {
* @param showMessage
*/
export function updatePlayerMoney(changeValue: number, playSound: boolean = true, showMessage: boolean = true) {
gScene.money = Math.min(Math.max(gScene.money + changeValue, 0), Number.MAX_SAFE_INTEGER);
gScene.updateMoneyText();
gScene.animateMoneyChanged(false);
globalScene.money = Math.min(Math.max(globalScene.money + changeValue, 0), Number.MAX_SAFE_INTEGER);
globalScene.updateMoneyText();
globalScene.animateMoneyChanged(false);
if (playSound) {
gScene.playSound("se/buy");
globalScene.playSound("se/buy");
}
if (showMessage) {
if (changeValue < 0) {
gScene.queueMessage(i18next.t("mysteryEncounterMessages:paid_money", { amount: -changeValue }), null, true);
globalScene.queueMessage(i18next.t("mysteryEncounterMessages:paid_money", { amount: -changeValue }), null, true);
} else {
gScene.queueMessage(i18next.t("mysteryEncounterMessages:receive_money", { amount: changeValue }), null, true);
globalScene.queueMessage(i18next.t("mysteryEncounterMessages:receive_money", { amount: changeValue }), null, true);
}
}
}
@ -420,7 +420,7 @@ export function generateModifierType(modifier: () => ModifierType, pregenArgs?:
.withIdFromFunc(modifierTypes[modifierId])
.withTierFromPool();
return result instanceof ModifierTypeGenerator ? result.generateType(gScene.getParty(), pregenArgs) : result;
return result instanceof ModifierTypeGenerator ? result.generateType(globalScene.getParty(), pregenArgs) : result;
}
/**
@ -447,22 +447,22 @@ export function generateModifierTypeOption(modifier: () => ModifierType, pregenA
*/
export function selectPokemonForOption(onPokemonSelected: (pokemon: PlayerPokemon) => void | OptionSelectItem[], onPokemonNotSelected?: () => void, selectablePokemonFilter?: PokemonSelectFilter): Promise<boolean> {
return new Promise(resolve => {
const modeToSetOnExit = gScene.ui.getMode();
const modeToSetOnExit = globalScene.ui.getMode();
// Open party screen to choose pokemon
gScene.ui.setMode(Mode.PARTY, PartyUiMode.SELECT, -1, (slotIndex: number, option: PartyOption) => {
if (slotIndex < gScene.getParty().length) {
gScene.ui.setMode(modeToSetOnExit).then(() => {
const pokemon = gScene.getParty()[slotIndex];
globalScene.ui.setMode(Mode.PARTY, PartyUiMode.SELECT, -1, (slotIndex: number, option: PartyOption) => {
if (slotIndex < globalScene.getParty().length) {
globalScene.ui.setMode(modeToSetOnExit).then(() => {
const pokemon = globalScene.getParty()[slotIndex];
const secondaryOptions = onPokemonSelected(pokemon);
if (!secondaryOptions) {
gScene.currentBattle.mysteryEncounter!.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
globalScene.currentBattle.mysteryEncounter!.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
resolve(true);
return;
}
// There is a second option to choose after selecting the Pokemon
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
const displayOptions = () => {
// Always appends a cancel option to bottom of options
const fullOptions = secondaryOptions.map(option => {
@ -470,7 +470,7 @@ export function selectPokemonForOption(onPokemonSelected: (pokemon: PlayerPokemo
const onSelect = option.handler;
option.handler = () => {
onSelect();
gScene.currentBattle.mysteryEncounter!.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
globalScene.currentBattle.mysteryEncounter!.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
resolve(true);
return true;
};
@ -478,8 +478,8 @@ export function selectPokemonForOption(onPokemonSelected: (pokemon: PlayerPokemo
}).concat({
label: i18next.t("menu:cancel"),
handler: () => {
gScene.ui.clearText();
gScene.ui.setMode(modeToSetOnExit);
globalScene.ui.clearText();
globalScene.ui.setMode(modeToSetOnExit);
resolve(false);
return true;
},
@ -499,10 +499,10 @@ export function selectPokemonForOption(onPokemonSelected: (pokemon: PlayerPokemo
if (fullOptions[0].onHover) {
fullOptions[0].onHover();
}
gScene.ui.setModeWithoutClear(Mode.OPTION_SELECT, config, null, true);
globalScene.ui.setModeWithoutClear(Mode.OPTION_SELECT, config, null, true);
};
const textPromptKey = gScene.currentBattle.mysteryEncounter?.selectedOption?.dialogue?.secondOptionPrompt;
const textPromptKey = globalScene.currentBattle.mysteryEncounter?.selectedOption?.dialogue?.secondOptionPrompt;
if (!textPromptKey) {
displayOptions();
} else {
@ -511,7 +511,7 @@ export function selectPokemonForOption(onPokemonSelected: (pokemon: PlayerPokemo
});
});
} else {
gScene.ui.setMode(modeToSetOnExit).then(() => {
globalScene.ui.setMode(modeToSetOnExit).then(() => {
if (onPokemonNotSelected) {
onPokemonNotSelected();
}
@ -538,23 +538,23 @@ interface PokemonAndOptionSelected {
*/
export function selectOptionThenPokemon(options: OptionSelectItem[], optionSelectPromptKey: string, selectablePokemonFilter?: PokemonSelectFilter, onHoverOverCancelOption?: () => void): Promise<PokemonAndOptionSelected | null> {
return new Promise<PokemonAndOptionSelected | null>(resolve => {
const modeToSetOnExit = gScene.ui.getMode();
const modeToSetOnExit = globalScene.ui.getMode();
const displayOptions = (config: OptionSelectConfig) => {
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
if (!optionSelectPromptKey) {
// Do hover over the starting selection option
if (fullOptions[0].onHover) {
fullOptions[0].onHover();
}
gScene.ui.setMode(Mode.OPTION_SELECT, config);
globalScene.ui.setMode(Mode.OPTION_SELECT, config);
} else {
showEncounterText(optionSelectPromptKey).then(() => {
// Do hover over the starting selection option
if (fullOptions[0].onHover) {
fullOptions[0].onHover();
}
gScene.ui.setMode(Mode.OPTION_SELECT, config);
globalScene.ui.setMode(Mode.OPTION_SELECT, config);
});
}
});
@ -562,10 +562,10 @@ export function selectOptionThenPokemon(options: OptionSelectItem[], optionSelec
const selectPokemonAfterOption = (selectedOptionIndex: number) => {
// Open party screen to choose a Pokemon
gScene.ui.setMode(Mode.PARTY, PartyUiMode.SELECT, -1, (slotIndex: number, option: PartyOption) => {
if (slotIndex < gScene.getParty().length) {
globalScene.ui.setMode(Mode.PARTY, PartyUiMode.SELECT, -1, (slotIndex: number, option: PartyOption) => {
if (slotIndex < globalScene.getParty().length) {
// Pokemon and option selected
gScene.ui.setMode(modeToSetOnExit).then(() => {
globalScene.ui.setMode(modeToSetOnExit).then(() => {
const result: PokemonAndOptionSelected = { selectedPokemonIndex: slotIndex, selectedOptionIndex: selectedOptionIndex };
resolve(result);
});
@ -589,8 +589,8 @@ export function selectOptionThenPokemon(options: OptionSelectItem[], optionSelec
}).concat({
label: i18next.t("menu:cancel"),
handler: () => {
gScene.ui.clearText();
gScene.ui.setMode(modeToSetOnExit);
globalScene.ui.clearText();
globalScene.ui.setMode(modeToSetOnExit);
resolve(null);
return true;
},
@ -622,15 +622,15 @@ export function selectOptionThenPokemon(options: OptionSelectItem[], optionSelec
* @param preRewardsCallback - can execute an arbitrary callback before the new phases if necessary (useful for updating items/party/injecting new phases before {@linkcode MysteryEncounterRewardsPhase})
*/
export function setEncounterRewards(customShopRewards?: CustomModifierSettings, eggRewards?: IEggOptions[], preRewardsCallback?: Function) {
gScene.currentBattle.mysteryEncounter!.doEncounterRewards = () => {
globalScene.currentBattle.mysteryEncounter!.doEncounterRewards = () => {
if (preRewardsCallback) {
preRewardsCallback();
}
if (customShopRewards) {
gScene.unshiftPhase(new SelectModifierPhase(0, undefined, customShopRewards));
globalScene.unshiftPhase(new SelectModifierPhase(0, undefined, customShopRewards));
} else {
gScene.tryRemovePhase(p => p instanceof SelectModifierPhase);
globalScene.tryRemovePhase(p => p instanceof SelectModifierPhase);
}
if (eggRewards) {
@ -665,8 +665,8 @@ export function setEncounterRewards(customShopRewards?: CustomModifierSettings,
export function setEncounterExp(participantId: number | number[], baseExpValue: number, useWaveIndex: boolean = true) {
const participantIds = Array.isArray(participantId) ? participantId : [ participantId ];
gScene.currentBattle.mysteryEncounter!.doEncounterExp = () => {
gScene.unshiftPhase(new PartyExpPhase(baseExpValue, useWaveIndex, new Set(participantIds)));
globalScene.currentBattle.mysteryEncounter!.doEncounterExp = () => {
globalScene.unshiftPhase(new PartyExpPhase(baseExpValue, useWaveIndex, new Set(participantIds)));
return true;
};
@ -689,7 +689,7 @@ export class OptionSelectSettings {
* @param optionSelectSettings
*/
export function initSubsequentOptionSelect(optionSelectSettings: OptionSelectSettings) {
gScene.pushPhase(new MysteryEncounterPhase(optionSelectSettings));
globalScene.pushPhase(new MysteryEncounterPhase(optionSelectSettings));
}
/**
@ -700,9 +700,9 @@ export function initSubsequentOptionSelect(optionSelectSettings: OptionSelectSet
* @param encounterMode - Can set custom encounter mode if necessary (may be required for forcing Pokemon to return before next phase)
*/
export function leaveEncounterWithoutBattle(addHealPhase: boolean = false, encounterMode: MysteryEncounterMode = MysteryEncounterMode.NO_BATTLE) {
gScene.currentBattle.mysteryEncounter!.encounterMode = encounterMode;
gScene.clearPhaseQueue();
gScene.clearPhaseQueueSplice();
globalScene.currentBattle.mysteryEncounter!.encounterMode = encounterMode;
globalScene.clearPhaseQueue();
globalScene.clearPhaseQueueSplice();
handleMysteryEncounterVictory(addHealPhase);
}
@ -713,32 +713,32 @@ export function leaveEncounterWithoutBattle(addHealPhase: boolean = false, encou
* @param doNotContinue - default `false`. If set to true, will not end the battle and continue to next wave
*/
export function handleMysteryEncounterVictory(addHealPhase: boolean = false, doNotContinue: boolean = false) {
const allowedPkm = gScene.getParty().filter((pkm) => pkm.isAllowedInBattle());
const allowedPkm = globalScene.getParty().filter((pkm) => pkm.isAllowedInBattle());
if (allowedPkm.length === 0) {
gScene.clearPhaseQueue();
gScene.unshiftPhase(new GameOverPhase());
globalScene.clearPhaseQueue();
globalScene.unshiftPhase(new GameOverPhase());
return;
}
// If in repeated encounter variant, do nothing
// Variant must eventually be swapped in order to handle "true" end of the encounter
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
if (encounter.continuousEncounter || doNotContinue) {
return;
} else if (encounter.encounterMode === MysteryEncounterMode.NO_BATTLE) {
gScene.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
gScene.pushPhase(new EggLapsePhase());
} else if (!gScene.getEnemyParty().find(p => encounter.encounterMode !== MysteryEncounterMode.TRAINER_BATTLE ? p.isOnField() : !p?.isFainted(true))) {
gScene.pushPhase(new BattleEndPhase());
globalScene.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
globalScene.pushPhase(new EggLapsePhase());
} else if (!globalScene.getEnemyParty().find(p => encounter.encounterMode !== MysteryEncounterMode.TRAINER_BATTLE ? p.isOnField() : !p?.isFainted(true))) {
globalScene.pushPhase(new BattleEndPhase());
if (encounter.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
gScene.pushPhase(new TrainerVictoryPhase());
globalScene.pushPhase(new TrainerVictoryPhase());
}
if (gScene.gameMode.isEndless || !gScene.gameMode.isWaveFinal(gScene.currentBattle.waveIndex)) {
gScene.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
if (globalScene.gameMode.isEndless || !globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex)) {
globalScene.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
if (!encounter.doContinueEncounter) {
// Only lapse eggs once for multi-battle encounters
gScene.pushPhase(new EggLapsePhase());
globalScene.pushPhase(new EggLapsePhase());
}
}
}
@ -750,28 +750,28 @@ export function handleMysteryEncounterVictory(addHealPhase: boolean = false, doN
* @param addHealPhase
*/
export function handleMysteryEncounterBattleFailed(addHealPhase: boolean = false, doNotContinue: boolean = false) {
const allowedPkm = gScene.getParty().filter((pkm) => pkm.isAllowedInBattle());
const allowedPkm = globalScene.getParty().filter((pkm) => pkm.isAllowedInBattle());
if (allowedPkm.length === 0) {
gScene.clearPhaseQueue();
gScene.unshiftPhase(new GameOverPhase());
globalScene.clearPhaseQueue();
globalScene.unshiftPhase(new GameOverPhase());
return;
}
// If in repeated encounter variant, do nothing
// Variant must eventually be swapped in order to handle "true" end of the encounter
const encounter = gScene.currentBattle.mysteryEncounter!;
const encounter = globalScene.currentBattle.mysteryEncounter!;
if (encounter.continuousEncounter || doNotContinue) {
return;
} else if (encounter.encounterMode !== MysteryEncounterMode.NO_BATTLE) {
gScene.pushPhase(new BattleEndPhase(false));
globalScene.pushPhase(new BattleEndPhase(false));
}
gScene.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
globalScene.pushPhase(new MysteryEncounterRewardsPhase(addHealPhase));
if (!encounter.doContinueEncounter) {
// Only lapse eggs once for multi-battle encounters
gScene.pushPhase(new EggLapsePhase());
globalScene.pushPhase(new EggLapsePhase());
}
}
@ -784,10 +784,10 @@ export function handleMysteryEncounterBattleFailed(addHealPhase: boolean = false
*/
export function transitionMysteryEncounterIntroVisuals(hide: boolean = true, destroy: boolean = true, duration: number = 750): Promise<boolean> {
return new Promise(resolve => {
const introVisuals = gScene.currentBattle.mysteryEncounter!.introVisuals;
const enemyPokemon = gScene.getEnemyField();
const introVisuals = globalScene.currentBattle.mysteryEncounter!.introVisuals;
const enemyPokemon = globalScene.getEnemyField();
if (enemyPokemon) {
gScene.currentBattle.enemyParty = [];
globalScene.currentBattle.enemyParty = [];
}
if (introVisuals) {
if (!hide) {
@ -799,7 +799,7 @@ export function transitionMysteryEncounterIntroVisuals(hide: boolean = true, des
}
// Transition
gScene.tweens.add({
globalScene.tweens.add({
targets: [ introVisuals, enemyPokemon ],
x: `${hide ? "+" : "-"}=16`,
y: `${hide ? "-" : "+"}=16`,
@ -808,13 +808,13 @@ export function transitionMysteryEncounterIntroVisuals(hide: boolean = true, des
duration,
onComplete: () => {
if (hide && destroy) {
gScene.field.remove(introVisuals, true);
globalScene.field.remove(introVisuals, true);
enemyPokemon.forEach(pokemon => {
gScene.field.remove(pokemon, true);
globalScene.field.remove(pokemon, true);
});
gScene.currentBattle.mysteryEncounter!.introVisuals = undefined;
globalScene.currentBattle.mysteryEncounter!.introVisuals = undefined;
}
resolve(true);
}
@ -831,8 +831,8 @@ export function transitionMysteryEncounterIntroVisuals(hide: boolean = true, des
* @param scene
*/
export function handleMysteryEncounterBattleStartEffects() {
const encounter = gScene.currentBattle.mysteryEncounter;
if (gScene.currentBattle.isBattleMysteryEncounter() && encounter && encounter.encounterMode !== MysteryEncounterMode.NO_BATTLE && !encounter.startOfBattleEffectsComplete) {
const encounter = globalScene.currentBattle.mysteryEncounter;
if (globalScene.currentBattle.isBattleMysteryEncounter() && encounter && encounter.encounterMode !== MysteryEncounterMode.NO_BATTLE && !encounter.startOfBattleEffectsComplete) {
const effects = encounter.startOfBattleEffects;
effects.forEach(effect => {
let source;
@ -840,24 +840,24 @@ export function handleMysteryEncounterBattleStartEffects() {
source = effect.sourcePokemon;
} else if (!isNullOrUndefined(effect.sourceBattlerIndex)) {
if (effect.sourceBattlerIndex === BattlerIndex.ATTACKER) {
source = gScene.getEnemyField()[0];
source = globalScene.getEnemyField()[0];
} else if (effect.sourceBattlerIndex === BattlerIndex.ENEMY) {
source = gScene.getEnemyField()[0];
source = globalScene.getEnemyField()[0];
} else if (effect.sourceBattlerIndex === BattlerIndex.ENEMY_2) {
source = gScene.getEnemyField()[1];
source = globalScene.getEnemyField()[1];
} else if (effect.sourceBattlerIndex === BattlerIndex.PLAYER) {
source = gScene.getPlayerField()[0];
source = globalScene.getPlayerField()[0];
} else if (effect.sourceBattlerIndex === BattlerIndex.PLAYER_2) {
source = gScene.getPlayerField()[1];
source = globalScene.getPlayerField()[1];
}
} else {
source = gScene.getEnemyField()[0];
source = globalScene.getEnemyField()[0];
}
gScene.pushPhase(new MovePhase(source, effect.targets, effect.move, effect.followUp, effect.ignorePp));
globalScene.pushPhase(new MovePhase(source, effect.targets, effect.move, effect.followUp, effect.ignorePp));
});
// Pseudo turn end phase to reset flinch states, Endure, etc.
gScene.pushPhase(new MysteryEncounterBattleStartCleanupPhase());
globalScene.pushPhase(new MysteryEncounterBattleStartCleanupPhase());
encounter.startOfBattleEffectsComplete = true;
}
@ -870,8 +870,8 @@ export function handleMysteryEncounterBattleStartEffects() {
* @return boolean - if true, will skip the remainder of the {@linkcode TurnInitPhase}
*/
export function handleMysteryEncounterTurnStartEffects(): boolean {
const encounter = gScene.currentBattle.mysteryEncounter;
if (gScene.currentBattle.isBattleMysteryEncounter() && encounter && encounter.onTurnStart) {
const encounter = globalScene.currentBattle.mysteryEncounter;
if (globalScene.currentBattle.isBattleMysteryEncounter() && encounter && encounter.onTurnStart) {
return encounter.onTurnStart();
}
@ -897,9 +897,9 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
const encountersByBiome = new Map<string, number>(biomes.map(b => [ b, 0 ]));
const validMEfloorsByBiome = new Map<string, number>(biomes.map(b => [ b, 0 ]));
let currentBiome = Biome.TOWN;
let currentArena = gScene.newArena(currentBiome);
gScene.setSeed(Utils.randomString(24));
gScene.resetSeed();
let currentArena = globalScene.newArena(currentBiome);
globalScene.setSeed(Utils.randomString(24));
globalScene.resetSeed();
for (let i = 10; i < 180; i++) {
// Boss
if (i % 10 === 0) {
@ -910,7 +910,7 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
if (i % 10 === 1) {
if (Array.isArray(biomeLinks[currentBiome])) {
let biomes: Biome[];
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
biomes = (biomeLinks[currentBiome] as (Biome | [Biome, number])[])
.filter(b => {
return !Array.isArray(b) || !Utils.randSeedInt(b[1]);
@ -931,20 +931,20 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
if (!(i % 50)) {
currentBiome = Biome.END;
} else {
currentBiome = gScene.generateRandomBiome(i);
currentBiome = globalScene.generateRandomBiome(i);
}
}
currentArena = gScene.newArena(currentBiome);
currentArena = globalScene.newArena(currentBiome);
}
// Fixed battle
if (gScene.gameMode.isFixedBattle(i)) {
if (globalScene.gameMode.isFixedBattle(i)) {
continue;
}
// Trainer
if (gScene.gameMode.isWaveTrainer(i, currentArena)) {
if (globalScene.gameMode.isWaveTrainer(i, currentArena)) {
continue;
}
@ -994,7 +994,7 @@ export function calculateMEAggregateStats(baseSpawnWeight: number) {
const encountersByBiomeRuns: Map<string, number>[] = [];
const validFloorsByBiome: Map<string, number>[] = [];
while (run < numRuns) {
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
const [ numEncounters, encountersByBiome, validMEfloorsByBiome ] = calculateNumEncounters();
encounterRuns.push(numEncounters);
encountersByBiomeRuns.push(encountersByBiome);
@ -1055,8 +1055,8 @@ export function calculateRareSpawnAggregateStats(luckValue: number) {
const calculateNumRareEncounters = (): any[] => {
const bossEncountersByRarity = [ 0, 0, 0, 0 ];
gScene.setSeed(Utils.randomString(24));
gScene.resetSeed();
globalScene.setSeed(Utils.randomString(24));
globalScene.resetSeed();
// There are 12 wild boss floors
for (let i = 0; i < 12; i++) {
// Roll boss tier
@ -1090,7 +1090,7 @@ export function calculateRareSpawnAggregateStats(luckValue: number) {
const encounterRuns: number[][] = [];
while (run < numRuns) {
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
const bossEncountersByRarity = calculateNumRareEncounters();
encounterRuns.push(bossEncountersByRarity);
}, 1000 * run);

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import i18next from "i18next";
import { isNullOrUndefined, randSeedInt } from "#app/utils";
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
@ -60,7 +60,7 @@ export function getSpriteKeysFromPokemon(pokemon: Pokemon): { spriteKey: string,
* @returns
*/
export function getRandomPlayerPokemon(isAllowed: boolean = false, isFainted: boolean = false, doNotReturnLastAllowedMon: boolean = false): PlayerPokemon {
const party = gScene.getParty();
const party = globalScene.getParty();
let chosenIndex: number;
let chosenPokemon: PlayerPokemon | null = null;
const fullyLegalMons = party.filter(p => (!isAllowed || p.isAllowed()) && (isFainted || !p.isFainted()));
@ -99,7 +99,7 @@ export function getRandomPlayerPokemon(isAllowed: boolean = false, isFainted: bo
* @returns
*/
export function getHighestLevelPlayerPokemon(isAllowed: boolean = false, isFainted: boolean = false): PlayerPokemon {
const party = gScene.getParty();
const party = globalScene.getParty();
let pokemon: PlayerPokemon | null = null;
for (const p of party) {
@ -125,7 +125,7 @@ export function getHighestLevelPlayerPokemon(isAllowed: boolean = false, isFaint
* @returns
*/
export function getHighestStatPlayerPokemon(stat: PermanentStat, isAllowed: boolean = false, isFainted: boolean = false): PlayerPokemon {
const party = gScene.getParty();
const party = globalScene.getParty();
let pokemon: PlayerPokemon | null = null;
for (const p of party) {
@ -150,7 +150,7 @@ export function getHighestStatPlayerPokemon(stat: PermanentStat, isAllowed: bool
* @returns
*/
export function getLowestLevelPlayerPokemon(isAllowed: boolean = false, isFainted: boolean = false): PlayerPokemon {
const party = gScene.getParty();
const party = globalScene.getParty();
let pokemon: PlayerPokemon | null = null;
for (const p of party) {
@ -175,7 +175,7 @@ export function getLowestLevelPlayerPokemon(isAllowed: boolean = false, isFainte
* @returns
*/
export function getHighestStatTotalPlayerPokemon(isAllowed: boolean = false, isFainted: boolean = false): PlayerPokemon {
const party = gScene.getParty();
const party = globalScene.getParty();
let pokemon: PlayerPokemon | null = null;
for (const p of party) {
@ -313,11 +313,11 @@ export function applyHealToPokemon(pokemon: PlayerPokemon, heal: number) {
*/
export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: number) {
const modType = modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE()
.generateType(gScene.getParty(), [ value ])
.generateType(globalScene.getParty(), [ value ])
?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE);
const modifier = modType?.newModifier(pokemon);
if (modifier) {
await gScene.addModifier(modifier, false, false, false, true);
await globalScene.addModifier(modifier, false, false, false, true);
pokemon.calculateStats();
}
}
@ -333,7 +333,7 @@ export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: numb
export async function applyModifierTypeToPlayerPokemon(pokemon: PlayerPokemon, modType: PokemonHeldItemModifierType, fallbackModifierType?: PokemonHeldItemModifierType) {
// Check if the Pokemon has max stacks of that item already
const modifier = modType.newModifier(pokemon);
const existing = gScene.findModifier(m => (
const existing = globalScene.findModifier(m => (
m instanceof PokemonHeldItemModifier &&
m.type.id === modType.id &&
m.pokemonId === pokemon.id &&
@ -350,7 +350,7 @@ export async function applyModifierTypeToPlayerPokemon(pokemon: PlayerPokemon, m
return applyModifierTypeToPlayerPokemon(pokemon, fallbackModifierType);
}
await gScene.addModifier(modifier, false, false, false, true);
await globalScene.addModifier(modifier, false, false, false, true);
}
/**
@ -379,43 +379,43 @@ export function trainerThrowPokeball(pokemon: EnemyPokemon, pokeballType: Pokeba
const fpOffset = pokemon.getFieldPositionOffset();
const pokeballAtlasKey = getPokeballAtlasKey(pokeballType);
const pokeball: Phaser.GameObjects.Sprite = gScene.addFieldSprite(16 + 75, 80 + 25, "pb", pokeballAtlasKey);
const pokeball: Phaser.GameObjects.Sprite = globalScene.addFieldSprite(16 + 75, 80 + 25, "pb", pokeballAtlasKey);
pokeball.setOrigin(0.5, 0.625);
gScene.field.add(pokeball);
globalScene.field.add(pokeball);
gScene.time.delayedCall(300, () => {
gScene.field.moveBelow(pokeball as Phaser.GameObjects.GameObject, pokemon);
globalScene.time.delayedCall(300, () => {
globalScene.field.moveBelow(pokeball as Phaser.GameObjects.GameObject, pokemon);
});
return new Promise(resolve => {
gScene.trainer.setTexture(`trainer_${gScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
gScene.time.delayedCall(512, () => {
gScene.playSound("se/pb_throw");
globalScene.trainer.setTexture(`trainer_${globalScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back_pb`);
globalScene.time.delayedCall(512, () => {
globalScene.playSound("se/pb_throw");
// Trainer throw frames
gScene.trainer.setFrame("2");
gScene.time.delayedCall(256, () => {
gScene.trainer.setFrame("3");
gScene.time.delayedCall(768, () => {
gScene.trainer.setTexture(`trainer_${gScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back`);
globalScene.trainer.setFrame("2");
globalScene.time.delayedCall(256, () => {
globalScene.trainer.setFrame("3");
globalScene.time.delayedCall(768, () => {
globalScene.trainer.setTexture(`trainer_${globalScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}_back`);
});
});
// Pokeball move and catch logic
gScene.tweens.add({
globalScene.tweens.add({
targets: pokeball,
x: { value: 236 + fpOffset[0], ease: "Linear" },
y: { value: 16 + fpOffset[1], ease: "Cubic.easeOut" },
duration: 500,
onComplete: () => {
pokeball.setTexture("pb", `${pokeballAtlasKey}_opening`);
gScene.time.delayedCall(17, () => pokeball.setTexture("pb", `${pokeballAtlasKey}_open`));
gScene.playSound("se/pb_rel");
globalScene.time.delayedCall(17, () => pokeball.setTexture("pb", `${pokeballAtlasKey}_open`));
globalScene.playSound("se/pb_rel");
pokemon.tint(getPokeballTintColor(pokeballType));
addPokeballOpenParticles(pokeball.x, pokeball.y, pokeballType);
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemon,
duration: 500,
ease: "Sine.easeIn",
@ -424,13 +424,13 @@ export function trainerThrowPokeball(pokemon: EnemyPokemon, pokeballType: Pokeba
onComplete: () => {
pokeball.setTexture("pb", `${pokeballAtlasKey}_opening`);
pokemon.setVisible(false);
gScene.playSound("se/pb_catch");
gScene.time.delayedCall(17, () => pokeball.setTexture("pb", `${pokeballAtlasKey}`));
globalScene.playSound("se/pb_catch");
globalScene.time.delayedCall(17, () => pokeball.setTexture("pb", `${pokeballAtlasKey}`));
const doShake = () => {
let shakeCount = 0;
const pbX = pokeball.x;
const shakeCounter = gScene.tweens.addCounter({
const shakeCounter = globalScene.tweens.addCounter({
from: 0,
to: 1,
repeat: 4,
@ -452,27 +452,27 @@ export function trainerThrowPokeball(pokemon: EnemyPokemon, pokeballType: Pokeba
failCatch(pokemon, originalY, pokeball, pokeballType).then(() => resolve(false));
} else if (shakeCount++ < 3) {
if (randSeedInt(65536) < ballTwitchRate) {
gScene.playSound("se/pb_move");
globalScene.playSound("se/pb_move");
} else {
shakeCounter.stop();
failCatch(pokemon, originalY, pokeball, pokeballType).then(() => resolve(false));
}
} else {
gScene.playSound("se/pb_lock");
globalScene.playSound("se/pb_lock");
addPokeballCaptureStars(pokeball);
const pbTint = gScene.add.sprite(pokeball.x, pokeball.y, "pb", "pb");
const pbTint = globalScene.add.sprite(pokeball.x, pokeball.y, "pb", "pb");
pbTint.setOrigin(pokeball.originX, pokeball.originY);
pbTint.setTintFill(0);
pbTint.setAlpha(0);
gScene.field.add(pbTint);
gScene.tweens.add({
globalScene.field.add(pbTint);
globalScene.tweens.add({
targets: pbTint,
alpha: 0.375,
duration: 200,
easing: "Sine.easeOut",
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: pbTint,
alpha: 0,
duration: 200,
@ -489,7 +489,7 @@ export function trainerThrowPokeball(pokemon: EnemyPokemon, pokeballType: Pokeba
});
};
gScene.time.delayedCall(250, () => doPokeballBounceAnim(pokeball, 16, 72, 350, doShake));
globalScene.time.delayedCall(250, () => doPokeballBounceAnim(pokeball, 16, 72, 350, doShake));
}
});
}
@ -508,7 +508,7 @@ export function trainerThrowPokeball(pokemon: EnemyPokemon, pokeballType: Pokeba
*/
function failCatch(pokemon: EnemyPokemon, originalY: number, pokeball: Phaser.GameObjects.Sprite, pokeballType: PokeballType) {
return new Promise<void>(resolve => {
gScene.playSound("se/pb_rel");
globalScene.playSound("se/pb_rel");
pokemon.setY(originalY);
if (pokemon.status?.effect !== StatusEffect.SLEEP) {
pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 });
@ -519,19 +519,19 @@ function failCatch(pokemon: EnemyPokemon, originalY: number, pokeball: Phaser.Ga
const pokeballAtlasKey = getPokeballAtlasKey(pokeballType);
pokeball.setTexture("pb", `${pokeballAtlasKey}_opening`);
gScene.time.delayedCall(17, () => pokeball.setTexture("pb", `${pokeballAtlasKey}_open`));
globalScene.time.delayedCall(17, () => pokeball.setTexture("pb", `${pokeballAtlasKey}_open`));
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemon,
duration: 250,
ease: "Sine.easeOut",
scale: 1
});
gScene.currentBattle.lastUsedPokeball = pokeballType;
globalScene.currentBattle.lastUsedPokeball = pokeballType;
removePb(pokeball);
gScene.ui.showText(i18next.t("battle:pokemonBrokeFree", { pokemonName: pokemon.getNameToRender() }), null, () => resolve(), null, true);
globalScene.ui.showText(i18next.t("battle:pokemonBrokeFree", { pokemonName: pokemon.getNameToRender() }), null, () => resolve(), null, true);
});
}
@ -548,34 +548,34 @@ export async function catchPokemon(pokemon: EnemyPokemon, pokeball: Phaser.GameO
const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm();
if (speciesForm.abilityHidden && (pokemon.fusionSpecies ? pokemon.fusionAbilityIndex : pokemon.abilityIndex) === speciesForm.getAbilityCount() - 1) {
gScene.validateAchv(achvs.HIDDEN_ABILITY);
globalScene.validateAchv(achvs.HIDDEN_ABILITY);
}
if (pokemon.species.subLegendary) {
gScene.validateAchv(achvs.CATCH_SUB_LEGENDARY);
globalScene.validateAchv(achvs.CATCH_SUB_LEGENDARY);
}
if (pokemon.species.legendary) {
gScene.validateAchv(achvs.CATCH_LEGENDARY);
globalScene.validateAchv(achvs.CATCH_LEGENDARY);
}
if (pokemon.species.mythical) {
gScene.validateAchv(achvs.CATCH_MYTHICAL);
globalScene.validateAchv(achvs.CATCH_MYTHICAL);
}
gScene.pokemonInfoContainer.show(pokemon, true);
globalScene.pokemonInfoContainer.show(pokemon, true);
gScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
globalScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
return new Promise(resolve => {
const doPokemonCatchMenu = () => {
const end = () => {
// Ensure the pokemon is in the enemy party in all situations
if (!gScene.getEnemyParty().some(p => p.id === pokemon.id)) {
gScene.getEnemyParty().push(pokemon);
if (!globalScene.getEnemyParty().some(p => p.id === pokemon.id)) {
globalScene.getEnemyParty().push(pokemon);
}
gScene.unshiftPhase(new VictoryPhase(pokemon.id, true));
gScene.pokemonInfoContainer.hide();
globalScene.unshiftPhase(new VictoryPhase(pokemon.id, true));
globalScene.pokemonInfoContainer.hide();
if (pokeball) {
removePb(pokeball);
}
@ -583,17 +583,17 @@ export async function catchPokemon(pokemon: EnemyPokemon, pokeball: Phaser.GameO
};
const removePokemon = () => {
if (pokemon) {
gScene.field.remove(pokemon, true);
globalScene.field.remove(pokemon, true);
}
};
const addToParty = (slotIndex?: number) => {
const newPokemon = pokemon.addToParty(pokeballType, slotIndex);
const modifiers = gScene.findModifiers(m => m instanceof PokemonHeldItemModifier, false);
if (gScene.getParty().filter(p => p.isShiny()).length === 6) {
gScene.validateAchv(achvs.SHINY_PARTY);
const modifiers = globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier, false);
if (globalScene.getParty().filter(p => p.isShiny()).length === 6) {
globalScene.validateAchv(achvs.SHINY_PARTY);
}
Promise.all(modifiers.map(m => gScene.addModifier(m, true))).then(() => {
gScene.updateModifiers(true);
Promise.all(modifiers.map(m => globalScene.addModifier(m, true))).then(() => {
globalScene.updateModifiers(true);
removePokemon();
if (newPokemon) {
newPokemon.loadAssets().then(end);
@ -602,21 +602,21 @@ export async function catchPokemon(pokemon: EnemyPokemon, pokeball: Phaser.GameO
}
});
};
Promise.all([ pokemon.hideInfo(), gScene.gameData.setPokemonCaught(pokemon) ]).then(() => {
if (gScene.getParty().length === 6) {
Promise.all([ pokemon.hideInfo(), globalScene.gameData.setPokemonCaught(pokemon) ]).then(() => {
if (globalScene.getParty().length === 6) {
const promptRelease = () => {
gScene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
gScene.pokemonInfoContainer.makeRoomForConfirmUi(1, true);
gScene.ui.setMode(Mode.CONFIRM, () => {
const newPokemon = gScene.addPlayerPokemon(pokemon.species, pokemon.level, pokemon.abilityIndex, pokemon.formIndex, pokemon.gender, pokemon.shiny, pokemon.variant, pokemon.ivs, pokemon.nature, pokemon);
gScene.ui.setMode(Mode.SUMMARY, newPokemon, 0, SummaryUiMode.DEFAULT, () => {
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
globalScene.pokemonInfoContainer.makeRoomForConfirmUi(1, true);
globalScene.ui.setMode(Mode.CONFIRM, () => {
const newPokemon = globalScene.addPlayerPokemon(pokemon.species, pokemon.level, pokemon.abilityIndex, pokemon.formIndex, pokemon.gender, pokemon.shiny, pokemon.variant, pokemon.ivs, pokemon.nature, pokemon);
globalScene.ui.setMode(Mode.SUMMARY, newPokemon, 0, SummaryUiMode.DEFAULT, () => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
promptRelease();
});
}, false);
}, () => {
gScene.ui.setMode(Mode.PARTY, PartyUiMode.RELEASE, 0, (slotIndex: integer, _option: PartyOption) => {
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.PARTY, PartyUiMode.RELEASE, 0, (slotIndex: integer, _option: PartyOption) => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
if (slotIndex < 6) {
addToParty(slotIndex);
} else {
@ -625,7 +625,7 @@ export async function catchPokemon(pokemon: EnemyPokemon, pokeball: Phaser.GameO
});
});
}, () => {
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
removePokemon();
end();
});
@ -640,7 +640,7 @@ export async function catchPokemon(pokemon: EnemyPokemon, pokeball: Phaser.GameO
};
if (showCatchObtainMessage) {
gScene.ui.showText(i18next.t(isObtain ? "battle:pokemonObtained" : "battle:pokemonCaught", { pokemonName: pokemon.getNameToRender() }), null, doPokemonCatchMenu, 0, true);
globalScene.ui.showText(i18next.t(isObtain ? "battle:pokemonObtained" : "battle:pokemonCaught", { pokemonName: pokemon.getNameToRender() }), null, doPokemonCatchMenu, 0, true);
} else {
doPokemonCatchMenu();
}
@ -654,7 +654,7 @@ export async function catchPokemon(pokemon: EnemyPokemon, pokeball: Phaser.GameO
*/
function removePb(pokeball: Phaser.GameObjects.Sprite) {
if (pokeball) {
gScene.tweens.add({
globalScene.tweens.add({
targets: pokeball,
duration: 250,
delay: 250,
@ -674,9 +674,9 @@ function removePb(pokeball: Phaser.GameObjects.Sprite) {
*/
export async function doPokemonFlee(pokemon: EnemyPokemon): Promise<void> {
await new Promise<void>(resolve => {
gScene.playSound("se/flee");
globalScene.playSound("se/flee");
// Ease pokemon out
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemon,
x: "+=16",
y: "-=16",
@ -686,7 +686,7 @@ export async function doPokemonFlee(pokemon: EnemyPokemon): Promise<void> {
scale: pokemon.getSpriteScale(),
onComplete: () => {
pokemon.setVisible(false);
gScene.field.remove(pokemon, true);
globalScene.field.remove(pokemon, true);
showEncounterText(i18next.t("battle:pokemonFled", { pokemonName: pokemon.getNameToRender() }), null, 600, false)
.then(() => {
resolve();
@ -704,7 +704,7 @@ export async function doPokemonFlee(pokemon: EnemyPokemon): Promise<void> {
export function doPlayerFlee(pokemon: EnemyPokemon): Promise<void> {
return new Promise<void>(resolve => {
// Ease pokemon out
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemon,
x: "+=16",
y: "-=16",
@ -714,7 +714,7 @@ export function doPlayerFlee(pokemon: EnemyPokemon): Promise<void> {
scale: pokemon.getSpriteScale(),
onComplete: () => {
pokemon.setVisible(false);
gScene.field.remove(pokemon, true);
globalScene.field.remove(pokemon, true);
showEncounterText(i18next.t("battle:playerFled", { pokemonName: pokemon.getNameToRender() }), null, 600, false)
.then(() => {
resolve();
@ -784,7 +784,7 @@ export function getGoldenBugNetSpecies(level: number): PokemonSpecies {
* @param levelAdditiveModifier Default 0. will add +(1 level / 10 waves * levelAdditiveModifier) to the level calculation
*/
export function getEncounterPokemonLevelForWave(levelAdditiveModifier: number = 0) {
const currentBattle = gScene.currentBattle;
const currentBattle = globalScene.currentBattle;
const baseLevel = currentBattle.getLevelForWave();
// Add a level scaling modifier that is (+1 level per 10 waves) * levelAdditiveModifier
@ -795,23 +795,23 @@ export async function addPokemonDataToDexAndValidateAchievements(pokemon: Player
const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm();
if (speciesForm.abilityHidden && (pokemon.fusionSpecies ? pokemon.fusionAbilityIndex : pokemon.abilityIndex) === speciesForm.getAbilityCount() - 1) {
gScene.validateAchv(achvs.HIDDEN_ABILITY);
globalScene.validateAchv(achvs.HIDDEN_ABILITY);
}
if (pokemon.species.subLegendary) {
gScene.validateAchv(achvs.CATCH_SUB_LEGENDARY);
globalScene.validateAchv(achvs.CATCH_SUB_LEGENDARY);
}
if (pokemon.species.legendary) {
gScene.validateAchv(achvs.CATCH_LEGENDARY);
globalScene.validateAchv(achvs.CATCH_LEGENDARY);
}
if (pokemon.species.mythical) {
gScene.validateAchv(achvs.CATCH_MYTHICAL);
globalScene.validateAchv(achvs.CATCH_MYTHICAL);
}
gScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
return gScene.gameData.setPokemonCaught(pokemon, true, false, false);
globalScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
return globalScene.gameData.setPokemonCaught(pokemon, true, false, false);
}
/**

View File

@ -2,7 +2,7 @@ import { PlayerPokemon } from "#app/field/pokemon";
import { getFrameMs } from "#app/utils";
import { cos, sin } from "#app/field/anims";
import { getTypeRgb } from "#app/data/type";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export enum TransformationScreenPosition {
CENTER,
@ -19,8 +19,8 @@ export enum TransformationScreenPosition {
*/
export function doPokemonTransformationSequence(previousPokemon: PlayerPokemon, transformPokemon: PlayerPokemon, screenPosition: TransformationScreenPosition) {
return new Promise<void>(resolve => {
const transformationContainer = gScene.fieldUI.getByName("Dream Background") as Phaser.GameObjects.Container;
const transformationBaseBg = gScene.add.image(0, 0, "default_bg");
const transformationContainer = globalScene.fieldUI.getByName("Dream Background") as Phaser.GameObjects.Container;
const transformationBaseBg = globalScene.add.image(0, 0, "default_bg");
transformationBaseBg.setOrigin(0, 0);
transformationBaseBg.setVisible(false);
transformationContainer.add(transformationBaseBg);
@ -36,8 +36,8 @@ export function doPokemonTransformationSequence(previousPokemon: PlayerPokemon,
const yOffset = screenPosition !== TransformationScreenPosition.CENTER ? -15 : 0;
const getPokemonSprite = () => {
const ret = gScene.addPokemonSprite(previousPokemon, transformationBaseBg.displayWidth / 2 + xOffset, transformationBaseBg.displayHeight / 2 + yOffset, "pkmn__sub");
ret.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
const ret = globalScene.addPokemonSprite(previousPokemon, transformationBaseBg.displayWidth / 2 + xOffset, transformationBaseBg.displayHeight / 2 + yOffset, "pkmn__sub");
ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
return ret;
};
@ -55,7 +55,7 @@ export function doPokemonTransformationSequence(previousPokemon: PlayerPokemon,
[ pokemonSprite, pokemonTintSprite, pokemonEvoSprite, pokemonEvoTintSprite ].map(sprite => {
sprite.play(previousPokemon.getSpriteKey(true));
sprite.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(previousPokemon.getTeraType()) });
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(previousPokemon.getTeraType()) });
sprite.setPipelineData("ignoreTimeTint", true);
sprite.setPipelineData("spriteKey", previousPokemon.getSpriteKey());
sprite.setPipelineData("shiny", previousPokemon.shiny);
@ -82,14 +82,14 @@ export function doPokemonTransformationSequence(previousPokemon: PlayerPokemon,
});
});
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemonSprite,
alpha: 1,
ease: "Cubic.easeInOut",
duration: 2000,
onComplete: () => {
doSpiralUpward(transformationBaseBg, transformationContainer, xOffset, yOffset);
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
from: 0,
to: 1,
duration: 1000,
@ -98,26 +98,26 @@ export function doPokemonTransformationSequence(previousPokemon: PlayerPokemon,
},
onComplete: () => {
pokemonSprite.setVisible(false);
gScene.time.delayedCall(700, () => {
globalScene.time.delayedCall(700, () => {
doArcDownward(transformationBaseBg, transformationContainer, xOffset, yOffset);
gScene.time.delayedCall(1000, () => {
globalScene.time.delayedCall(1000, () => {
pokemonEvoTintSprite.setScale(0.25);
pokemonEvoTintSprite.setVisible(true);
doCycle(1.5, 6, pokemonTintSprite, pokemonEvoTintSprite).then(() => {
pokemonEvoSprite.setVisible(true);
doCircleInward(transformationBaseBg, transformationContainer, xOffset, yOffset);
gScene.time.delayedCall(900, () => {
gScene.tweens.add({
globalScene.time.delayedCall(900, () => {
globalScene.tweens.add({
targets: pokemonEvoTintSprite,
alpha: 0,
duration: 1500,
delay: 150,
easing: "Sine.easeIn",
onComplete: () => {
gScene.time.delayedCall(3000, () => {
globalScene.time.delayedCall(3000, () => {
resolve();
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemonEvoSprite,
alpha: 0,
duration: 2000,
@ -154,7 +154,7 @@ export function doPokemonTransformationSequence(previousPokemon: PlayerPokemon,
function doSpiralUpward(transformationBaseBg: Phaser.GameObjects.Image, transformationContainer: Phaser.GameObjects.Container, xOffset: number, yOffset: number) {
let f = 0;
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
repeat: 64,
duration: getFrameMs(1),
onRepeat: () => {
@ -181,7 +181,7 @@ function doSpiralUpward(transformationBaseBg: Phaser.GameObjects.Image, transfor
function doArcDownward(transformationBaseBg: Phaser.GameObjects.Image, transformationContainer: Phaser.GameObjects.Container, xOffset: number, yOffset: number) {
let f = 0;
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
repeat: 96,
duration: getFrameMs(1),
onRepeat: () => {
@ -208,14 +208,14 @@ function doArcDownward(transformationBaseBg: Phaser.GameObjects.Image, transform
function doCycle(l: number, lastCycle: number, pokemonTintSprite: Phaser.GameObjects.Sprite, pokemonEvoTintSprite: Phaser.GameObjects.Sprite): Promise<boolean> {
return new Promise(resolve => {
const isLastCycle = l === lastCycle;
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemonTintSprite,
scale: 0.25,
ease: "Cubic.easeInOut",
duration: 500 / l,
yoyo: !isLastCycle
});
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemonEvoTintSprite,
scale: 1,
ease: "Cubic.easeInOut",
@ -244,7 +244,7 @@ function doCycle(l: number, lastCycle: number, pokemonTintSprite: Phaser.GameObj
function doCircleInward(transformationBaseBg: Phaser.GameObjects.Image, transformationContainer: Phaser.GameObjects.Container, xOffset: number, yOffset: number) {
let f = 0;
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
repeat: 48,
duration: getFrameMs(1),
onRepeat: () => {
@ -273,13 +273,13 @@ function doCircleInward(transformationBaseBg: Phaser.GameObjects.Image, transfor
*/
function doSpiralUpwardParticle(trigIndex: number, transformationBaseBg: Phaser.GameObjects.Image, transformationContainer: Phaser.GameObjects.Container, xOffset: number, yOffset: number) {
const initialX = transformationBaseBg.displayWidth / 2 + xOffset;
const particle = gScene.add.image(initialX, 0, "evo_sparkle");
const particle = globalScene.add.image(initialX, 0, "evo_sparkle");
transformationContainer.add(particle);
let f = 0;
let amp = 48;
const particleTimer = gScene.tweens.addCounter({
const particleTimer = globalScene.tweens.addCounter({
repeat: -1,
duration: getFrameMs(1),
onRepeat: () => {
@ -318,14 +318,14 @@ function doSpiralUpwardParticle(trigIndex: number, transformationBaseBg: Phaser.
*/
function doArcDownParticle(trigIndex: number, transformationBaseBg: Phaser.GameObjects.Image, transformationContainer: Phaser.GameObjects.Container, xOffset: number, yOffset: number) {
const initialX = transformationBaseBg.displayWidth / 2 + xOffset;
const particle = gScene.add.image(initialX, 0, "evo_sparkle");
const particle = globalScene.add.image(initialX, 0, "evo_sparkle");
particle.setScale(0.5);
transformationContainer.add(particle);
let f = 0;
let amp = 8;
const particleTimer = gScene.tweens.addCounter({
const particleTimer = globalScene.tweens.addCounter({
repeat: -1,
duration: getFrameMs(1),
onRepeat: () => {
@ -362,12 +362,12 @@ function doArcDownParticle(trigIndex: number, transformationBaseBg: Phaser.GameO
function doCircleInwardParticle(trigIndex: number, speed: number, transformationBaseBg: Phaser.GameObjects.Image, transformationContainer: Phaser.GameObjects.Container, xOffset: number, yOffset: number) {
const initialX = transformationBaseBg.displayWidth / 2 + xOffset;
const initialY = transformationBaseBg.displayHeight / 2 + yOffset;
const particle = gScene.add.image(initialX, initialY, "evo_sparkle");
const particle = globalScene.add.image(initialX, initialY, "evo_sparkle");
transformationContainer.add(particle);
let amp = 120;
const particleTimer = gScene.tweens.addCounter({
const particleTimer = globalScene.tweens.addCounter({
repeat: -1,
duration: getFrameMs(1),
onRepeat: () => {

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { PokeballType } from "#enums/pokeball";
import i18next from "i18next";
@ -89,13 +89,13 @@ export function doPokeballBounceAnim(pokeball: Phaser.GameObjects.Sprite, y1: nu
const yd = y2 - y1;
const doBounce = () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: pokeball,
y: y2,
duration: bouncePower * baseBounceDuration,
ease: "Cubic.easeIn",
onComplete: () => {
gScene.playSound("se/pb_bounce_1", { volume: bouncePower });
globalScene.playSound("se/pb_bounce_1", { volume: bouncePower });
bouncePower = bouncePower > 0.01 ? bouncePower * 0.5 : 0;
@ -103,7 +103,7 @@ export function doPokeballBounceAnim(pokeball: Phaser.GameObjects.Sprite, y1: nu
bounceYOffset = yd * bouncePower;
bounceY = y2 - bounceYOffset;
gScene.tweens.add({
globalScene.tweens.add({
targets: pokeball,
y: bounceY,
duration: bouncePower * baseBounceDuration,

View File

@ -13,7 +13,7 @@ import i18next from "i18next";
import { WeatherType } from "./weather";
import { Challenges } from "#app/enums/challenges";
import { SpeciesFormKey } from "#enums/species-form-key";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export enum FormChangeItem {
NONE,
@ -260,7 +260,7 @@ export class SpeciesFormChangeItemTrigger extends SpeciesFormChangeTrigger {
}
canChange(pokemon: Pokemon): boolean {
return !!gScene.findModifier(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id && m.formChangeItem === this.item && m.active === this.active);
return !!globalScene.findModifier(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id && m.formChangeItem === this.item && m.active === this.active);
}
}
@ -273,7 +273,7 @@ export class SpeciesFormChangeTimeOfDayTrigger extends SpeciesFormChangeTrigger
}
canChange(pokemon: Pokemon): boolean {
return this.timesOfDay.indexOf(gScene.arena.getTimeOfDay()) > -1;
return this.timesOfDay.indexOf(globalScene.arena.getTimeOfDay()) > -1;
}
}
@ -336,7 +336,7 @@ export abstract class SpeciesFormChangeMoveTrigger extends SpeciesFormChangeTrig
export class SpeciesFormChangePreMoveTrigger extends SpeciesFormChangeMoveTrigger {
canChange(pokemon: Pokemon): boolean {
const command = gScene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
const command = globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
return !!command?.move && this.movePredicate(command.move.move) === this.used;
}
}
@ -349,7 +349,7 @@ export class SpeciesFormChangePostMoveTrigger extends SpeciesFormChangeMoveTrigg
export class MeloettaFormChangePostMoveTrigger extends SpeciesFormChangePostMoveTrigger {
override canChange(pokemon: Pokemon): boolean {
if (gScene.gameMode.hasChallenge(Challenges.SINGLE_TYPE)) {
if (globalScene.gameMode.hasChallenge(Challenges.SINGLE_TYPE)) {
return false;
} else {
return super.canChange(pokemon);
@ -366,7 +366,7 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger {
}
canChange(pokemon: Pokemon): boolean {
return this.formKey === pokemon.species.forms[gScene.getSpeciesFormIndex(pokemon.species, pokemon.gender, pokemon.getNature(), true)].formKey;
return this.formKey === pokemon.species.forms[globalScene.getSpeciesFormIndex(pokemon.species, pokemon.gender, pokemon.getNature(), true)].formKey;
}
}
@ -390,7 +390,7 @@ export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger {
* @returns `true` if the Pokémon can change forms, `false` otherwise
*/
canChange(pokemon: Pokemon): boolean {
return !!gScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id && m.teraType === this.teraType);
return !!globalScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id && m.teraType === this.teraType);
}
}
@ -401,7 +401,7 @@ export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger {
*/
export class SpeciesFormChangeLapseTeraTrigger extends SpeciesFormChangeTrigger {
canChange(pokemon: Pokemon): boolean {
return !!gScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id);
return !!globalScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id);
}
}
@ -429,8 +429,8 @@ export class SpeciesFormChangeWeatherTrigger extends SpeciesFormChangeTrigger {
* @returns `true` if the Pokemon can change forms, `false` otherwise
*/
canChange(pokemon: Pokemon): boolean {
const currentWeather = gScene.arena.weather?.weatherType ?? WeatherType.NONE;
const isWeatherSuppressed = gScene.arena.weather?.isEffectSuppressed();
const currentWeather = globalScene.arena.weather?.weatherType ?? WeatherType.NONE;
const isWeatherSuppressed = globalScene.arena.weather?.isEffectSuppressed();
const isAbilitySuppressed = pokemon.summonData.abilitySuppressed;
return !isAbilitySuppressed && !isWeatherSuppressed && (pokemon.hasAbility(this.ability) && this.weathers.includes(currentWeather));
@ -463,8 +463,8 @@ export class SpeciesFormChangeRevertWeatherFormTrigger extends SpeciesFormChange
*/
canChange(pokemon: Pokemon): boolean {
if (pokemon.hasAbility(this.ability, false, true)) {
const currentWeather = gScene.arena.weather?.weatherType ?? WeatherType.NONE;
const isWeatherSuppressed = gScene.arena.weather?.isEffectSuppressed();
const currentWeather = globalScene.arena.weather?.weatherType ?? WeatherType.NONE;
const isWeatherSuppressed = globalScene.arena.weather?.isEffectSuppressed();
const isAbilitySuppressed = pokemon.summonData.abilitySuppressed;
const summonDataAbility = pokemon.summonData.ability;
const isAbilityChanged = summonDataAbility !== this.ability && summonDataAbility !== Abilities.NONE;
@ -507,7 +507,7 @@ export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: Specie
* @returns A {@linkcode SpeciesFormChangeCondition} checking if that species is registered as caught
*/
function getSpeciesDependentFormChangeCondition(species: Species): SpeciesFormChangeCondition {
return new SpeciesFormChangeCondition(p => !!gScene.gameData.dexData[species].caughtAttr);
return new SpeciesFormChangeCondition(p => !!globalScene.gameData.dexData[species].caughtAttr);
}
interface PokemonFormChanges {

View File

@ -4,7 +4,7 @@ import { PartyMemberStrength } from "#enums/party-member-strength";
import { Species } from "#enums/species";
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
import i18next from "i18next";
import { AnySound, gScene } from "#app/battle-scene";
import { AnySound, globalScene } from "#app/battle-scene";
import { GameMode } from "#app/game-mode";
import { StarterMoveset } from "#app/system/game-data";
import * as Utils from "#app/utils";
@ -470,26 +470,26 @@ export abstract class PokemonSpeciesForm {
loadAssets(female: boolean, formIndex?: integer, shiny?: boolean, variant?: Variant, startLoad?: boolean): Promise<void> {
return new Promise(resolve => {
const spriteKey = this.getSpriteKey(female, formIndex, shiny, variant);
gScene.loadPokemonAtlas(spriteKey, this.getSpriteAtlasPath(female, formIndex, shiny, variant));
gScene.load.audio(`cry/${this.getCryKey(formIndex)}`, `audio/cry/${this.getCryKey(formIndex)}.m4a`);
gScene.load.once(Phaser.Loader.Events.COMPLETE, () => {
globalScene.loadPokemonAtlas(spriteKey, this.getSpriteAtlasPath(female, formIndex, shiny, variant));
globalScene.load.audio(`cry/${this.getCryKey(formIndex)}`, `audio/cry/${this.getCryKey(formIndex)}.m4a`);
globalScene.load.once(Phaser.Loader.Events.COMPLETE, () => {
const originalWarn = console.warn;
// Ignore warnings for missing frames, because there will be a lot
console.warn = () => {};
const frameNames = gScene.anims.generateFrameNames(spriteKey, { zeroPad: 4, suffix: ".png", start: 1, end: 400 });
const frameNames = globalScene.anims.generateFrameNames(spriteKey, { zeroPad: 4, suffix: ".png", start: 1, end: 400 });
console.warn = originalWarn;
if (!(gScene.anims.exists(spriteKey))) {
gScene.anims.create({
if (!(globalScene.anims.exists(spriteKey))) {
globalScene.anims.create({
key: this.getSpriteKey(female, formIndex, shiny, variant),
frames: frameNames,
frameRate: 12,
repeat: -1
});
} else {
gScene.anims.get(spriteKey).frameRate = 12;
globalScene.anims.get(spriteKey).frameRate = 12;
}
let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace("variant/", "").replace(/_[1-3]$/, "");
const useExpSprite = gScene.experimentalSprites && gScene.hasExpSprite(spriteKey);
const useExpSprite = globalScene.experimentalSprites && globalScene.hasExpSprite(spriteKey);
if (useExpSprite) {
spritePath = `exp/${spritePath}`;
}
@ -502,7 +502,7 @@ export abstract class PokemonSpeciesForm {
if (variantColorCache.hasOwnProperty(key)) {
return resolve();
}
gScene.cachedFetch(`./images/pokemon/variant/${spritePath}.json`).then(res => res.json()).then(c => {
globalScene.cachedFetch(`./images/pokemon/variant/${spritePath}.json`).then(res => res.json()).then(c => {
variantColorCache[key] = c;
resolve();
});
@ -514,8 +514,8 @@ export abstract class PokemonSpeciesForm {
resolve();
});
if (startLoad) {
if (!gScene.load.isLoading()) {
gScene.load.start();
if (!globalScene.load.isLoading()) {
globalScene.load.start();
}
} else {
resolve();
@ -525,11 +525,11 @@ export abstract class PokemonSpeciesForm {
cry(soundConfig?: Phaser.Types.Sound.SoundConfig, ignorePlay?: boolean): AnySound {
const cryKey = this.getCryKey(this.formIndex);
let cry: AnySound | null = gScene.sound.get(cryKey) as AnySound;
let cry: AnySound | null = globalScene.sound.get(cryKey) as AnySound;
if (cry?.pendingRemove) {
cry = null;
}
cry = gScene.playSound(`cry/${(cry ?? cryKey)}`, soundConfig);
cry = globalScene.playSound(`cry/${(cry ?? cryKey)}`, soundConfig);
if (ignorePlay) {
cry.stop();
}
@ -537,7 +537,7 @@ export abstract class PokemonSpeciesForm {
}
generateCandyColors(): integer[][] {
const sourceTexture = gScene.textures.get(this.getSpriteKey(false));
const sourceTexture = globalScene.textures.get(this.getSpriteKey(false));
const sourceFrame = sourceTexture.frames[sourceTexture.firstFrame];
const sourceImage = sourceTexture.getSourceImage() as HTMLImageElement;
@ -580,7 +580,7 @@ export abstract class PokemonSpeciesForm {
const originalRandom = Math.random;
Math.random = () => Phaser.Math.RND.realInRange(0, 1);
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
paletteColors = QuantizerCelebi.quantize(pixelColors, 2);
}, 0, "This result should not vary");
@ -955,7 +955,7 @@ export function getPokerusStarters(): PokemonSpecies[] {
const pokerusStarters: PokemonSpecies[] = [];
const date = new Date();
date.setUTCHours(0, 0, 0, 0);
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
while (pokerusStarters.length < POKERUS_STARTER_COUNT) {
const randomSpeciesId = parseInt(Utils.randSeedItem(Object.keys(speciesStarterCosts)), 10);
const species = getPokemonSpecies(randomSpeciesId);

View File

@ -1,4 +1,4 @@
import { gScene, startingWave } from "#app/battle-scene";
import { globalScene, startingWave } from "#app/battle-scene";
import { ModifierTypeFunc, modifierTypes } from "#app/modifier/modifier-type";
import { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
import * as Utils from "#app/utils";
@ -842,7 +842,7 @@ export class TrainerConfig {
this.setBattleBgm("battle_unova_gym");
this.setVictoryBgm("victory_gym");
this.setGenModifiersFunc(party => {
const waveIndex = gScene.currentBattle.waveIndex;
const waveIndex = globalScene.currentBattle.waveIndex;
return getRandomTeraModifiers(party, waveIndex >= 100 ? 1 : 0, specialtyTypes.length ? specialtyTypes : undefined);
});
@ -1016,23 +1016,23 @@ export class TrainerConfig {
const isDouble = variant === TrainerVariant.DOUBLE;
const trainerKey = this.getSpriteKey(variant === TrainerVariant.FEMALE, false);
const partnerTrainerKey = this.getSpriteKey(true, true);
gScene.loadAtlas(trainerKey, "trainer");
globalScene.loadAtlas(trainerKey, "trainer");
if (isDouble) {
gScene.loadAtlas(partnerTrainerKey, "trainer");
globalScene.loadAtlas(partnerTrainerKey, "trainer");
}
gScene.load.once(Phaser.Loader.Events.COMPLETE, () => {
globalScene.load.once(Phaser.Loader.Events.COMPLETE, () => {
const originalWarn = console.warn;
// Ignore warnings for missing frames, because there will be a lot
console.warn = () => {
};
const frameNames = gScene.anims.generateFrameNames(trainerKey, {
const frameNames = globalScene.anims.generateFrameNames(trainerKey, {
zeroPad: 4,
suffix: ".png",
start: 1,
end: 128
});
const partnerFrameNames = isDouble
? gScene.anims.generateFrameNames(partnerTrainerKey, {
? globalScene.anims.generateFrameNames(partnerTrainerKey, {
zeroPad: 4,
suffix: ".png",
start: 1,
@ -1040,16 +1040,16 @@ export class TrainerConfig {
})
: "";
console.warn = originalWarn;
if (!(gScene.anims.exists(trainerKey))) {
gScene.anims.create({
if (!(globalScene.anims.exists(trainerKey))) {
globalScene.anims.create({
key: trainerKey,
frames: frameNames,
frameRate: 24,
repeat: -1
});
}
if (isDouble && !(gScene.anims.exists(partnerTrainerKey))) {
gScene.anims.create({
if (isDouble && !(globalScene.anims.exists(partnerTrainerKey))) {
globalScene.anims.create({
key: partnerTrainerKey,
frames: partnerFrameNames,
frameRate: 24,
@ -1058,8 +1058,8 @@ export class TrainerConfig {
}
resolve();
});
if (!gScene.load.isLoading()) {
gScene.load.start();
if (!globalScene.load.isLoading()) {
globalScene.load.start();
}
});
}
@ -1137,7 +1137,7 @@ interface TrainerConfigs {
* @returns the correct TrainerPartyTemplate
*/
function getEvilGruntPartyTemplate(): TrainerPartyTemplate {
const waveIndex = gScene.currentBattle?.waveIndex;
const waveIndex = globalScene.currentBattle?.waveIndex;
if (waveIndex < 40) {
return trainerPartyTemplates.TWO_AVG;
} else if (waveIndex < 63) {
@ -1152,7 +1152,7 @@ function getEvilGruntPartyTemplate(): TrainerPartyTemplate {
}
function getWavePartyTemplate(...templates: TrainerPartyTemplate[]) {
return templates[Math.min(Math.max(Math.ceil((gScene.gameMode.getWaveForDifficulty(gScene.currentBattle?.waveIndex || startingWave, true) - 20) / 30), 0), templates.length - 1)];
return templates[Math.min(Math.max(Math.ceil((globalScene.gameMode.getWaveForDifficulty(globalScene.currentBattle?.waveIndex || startingWave, true) - 20) / 30), 0), templates.length - 1)];
}
function getGymLeaderPartyTemplate() {
@ -1161,7 +1161,7 @@ function getGymLeaderPartyTemplate() {
/**
* Randomly selects one of the `Species` from `speciesPool`, determines its evolution, level, and strength.
* Then adds Pokemon to gScene.
* Then adds Pokemon to globalScene.
* @param speciesPool
* @param trainerSlot
* @param ignoreEvolution
@ -1171,9 +1171,9 @@ export function getRandomPartyMemberFunc(speciesPool: Species[], trainerSlot: Tr
return (level: number, strength: PartyMemberStrength) => {
let species = Utils.randSeedItem(speciesPool);
if (!ignoreEvolution) {
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength, gScene.currentBattle.waveIndex);
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength, globalScene.currentBattle.waveIndex);
}
return gScene.addEnemyPokemon(getPokemonSpecies(species), level, trainerSlot, undefined, undefined, postProcess);
return globalScene.addEnemyPokemon(getPokemonSpecies(species), level, trainerSlot, undefined, undefined, postProcess);
};
}
@ -1181,7 +1181,7 @@ function getSpeciesFilterRandomPartyMemberFunc(speciesFilter: PokemonSpeciesFilt
const originalSpeciesFilter = speciesFilter;
speciesFilter = (species: PokemonSpecies) => (allowLegendaries || (!species.legendary && !species.subLegendary && !species.mythical)) && !species.isTrainerForbidden() && originalSpeciesFilter(species);
return (level: integer, strength: PartyMemberStrength) => {
const ret = gScene.addEnemyPokemon(getPokemonSpecies(gScene.randomSpecies(gScene.currentBattle.waveIndex, level, false, speciesFilter).getTrainerSpeciesForLevel(level, true, strength, gScene.currentBattle.waveIndex)), level, trainerSlot, undefined, undefined, postProcess);
const ret = globalScene.addEnemyPokemon(getPokemonSpecies(globalScene.randomSpecies(globalScene.currentBattle.waveIndex, level, false, speciesFilter).getTrainerSpeciesForLevel(level, true, strength, globalScene.currentBattle.waveIndex)), level, trainerSlot, undefined, undefined, postProcess);
return ret;
};
}

View File

@ -8,7 +8,7 @@ import * as Utils from "../utils";
import { SuppressWeatherEffectAbAttr } from "./ability";
import { TerrainType, getTerrainName } from "./terrain";
import i18next from "i18next";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export { WeatherType };
export class Weather {
@ -102,7 +102,7 @@ export class Weather {
}
isEffectSuppressed(): boolean {
const field = gScene.getField(true);
const field = globalScene.getField(true);
for (const pokemon of field) {
let suppressWeatherEffectAbAttr: SuppressWeatherEffectAbAttr | null = pokemon.getAbility().getAttrs(SuppressWeatherEffectAbAttr)[0];

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { PokeballType } from "../data/pokeball";
import * as Utils from "../utils";
@ -23,9 +23,9 @@ export function addPokeballOpenParticles(x: number, y: number, pokeballType: Pok
}
function doDefaultPbOpenParticles(x: number, y: number, radius: number) {
const pbOpenParticlesFrameNames = gScene.anims.generateFrameNames("pb_particles", { start: 0, end: 3, suffix: ".png" });
if (!(gScene.anims.exists("pb_open_particle"))) {
gScene.anims.create({
const pbOpenParticlesFrameNames = globalScene.anims.generateFrameNames("pb_particles", { start: 0, end: 3, suffix: ".png" });
if (!(globalScene.anims.exists("pb_open_particle"))) {
globalScene.anims.create({
key: "pb_open_particle",
frames: pbOpenParticlesFrameNames,
frameRate: 16,
@ -34,11 +34,11 @@ function doDefaultPbOpenParticles(x: number, y: number, radius: number) {
}
const addParticle = (index: integer) => {
const particle = gScene.add.sprite(x, y, "pb_open_particle");
gScene.field.add(particle);
const particle = globalScene.add.sprite(x, y, "pb_open_particle");
globalScene.field.add(particle);
const angle = index * 45;
const [ xCoord, yCoord ] = [ radius * Math.cos(angle * Math.PI / 180), radius * Math.sin(angle * Math.PI / 180) ];
gScene.tweens.add({
globalScene.tweens.add({
targets: particle,
x: x + xCoord,
y: y + yCoord,
@ -47,9 +47,9 @@ function doDefaultPbOpenParticles(x: number, y: number, radius: number) {
particle.play({
key: "pb_open_particle",
startFrame: (index + 3) % 4,
frameRate: Math.floor(16 * gScene.gameSpeed)
frameRate: Math.floor(16 * globalScene.gameSpeed)
});
gScene.tweens.add({
globalScene.tweens.add({
targets: particle,
delay: 500,
duration: 75,
@ -60,7 +60,7 @@ function doDefaultPbOpenParticles(x: number, y: number, radius: number) {
};
let particleCount = 0;
gScene.time.addEvent({
globalScene.time.addEvent({
delay: 20,
repeat: 16,
callback: () => addParticle(++particleCount)
@ -73,7 +73,7 @@ function doUbOpenParticles(x: number, y: number, frameIndex: integer) {
particles.push(doFanOutParticle(i * 25, x, y, 1, 1, 5, frameIndex));
}
gScene.tweens.add({
globalScene.tweens.add({
targets: particles,
delay: 750,
duration: 250,
@ -94,7 +94,7 @@ function doMbOpenParticles(x: number, y: number) {
particles.push(doFanOutParticle(i * 32, x, y, j ? 1 : 2, j ? 2 : 1, 8, 4));
}
gScene.tweens.add({
globalScene.tweens.add({
targets: particles,
delay: 750,
duration: 250,
@ -112,8 +112,8 @@ function doMbOpenParticles(x: number, y: number) {
function doFanOutParticle(trigIndex: integer, x: integer, y: integer, xSpeed: integer, ySpeed: integer, angle: integer, frameIndex: integer): Phaser.GameObjects.Image {
let f = 0;
const particle = gScene.add.image(x, y, "pb_particles", `${frameIndex}.png`);
gScene.field.add(particle);
const particle = globalScene.add.image(x, y, "pb_particles", `${frameIndex}.png`);
globalScene.field.add(particle);
const updateParticle = () => {
if (!particle.scene) {
@ -125,7 +125,7 @@ function doFanOutParticle(trigIndex: integer, x: integer, y: integer, xSpeed: in
f++;
};
const particleTimer = gScene.tweens.addCounter({
const particleTimer = globalScene.tweens.addCounter({
repeat: -1,
duration: Utils.getFrameMs(1),
onRepeat: () => {
@ -138,18 +138,18 @@ function doFanOutParticle(trigIndex: integer, x: integer, y: integer, xSpeed: in
export function addPokeballCaptureStars(pokeball: Phaser.GameObjects.Sprite): void {
const addParticle = () => {
const particle = gScene.add.sprite(pokeball.x, pokeball.y, "pb_particles", "4.png");
const particle = globalScene.add.sprite(pokeball.x, pokeball.y, "pb_particles", "4.png");
particle.setOrigin(pokeball.originX, pokeball.originY);
particle.setAlpha(0.5);
gScene.field.add(particle);
globalScene.field.add(particle);
gScene.tweens.add({
globalScene.tweens.add({
targets: particle,
y: pokeball.y - 10,
ease: "Sine.easeOut",
duration: 250,
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: particle,
y: pokeball.y,
alpha: 0,
@ -160,13 +160,13 @@ export function addPokeballCaptureStars(pokeball: Phaser.GameObjects.Sprite): vo
});
const dist = Utils.randGauss(25);
gScene.tweens.add({
globalScene.tweens.add({
targets: particle,
x: pokeball.x + dist,
duration: 500
});
gScene.tweens.add({
globalScene.tweens.add({
targets: particle,
alpha: 0,
delay: 425,

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene"; // ?
import { globalScene } from "#app/battle-scene";
import { biomePokemonPools, BiomePoolTier, BiomeTierTrainerPools, biomeTrainerPools, PokemonPools } from "#app/data/balance/biomes";
import { Constructor } from "#app/utils";
import * as Utils from "#app/utils";
@ -59,12 +59,12 @@ export class Arena {
init() {
const biomeKey = getBiomeKey(this.biomeType);
gScene.arenaPlayer.setBiome(this.biomeType);
gScene.arenaPlayerTransition.setBiome(this.biomeType);
gScene.arenaEnemy.setBiome(this.biomeType);
gScene.arenaNextEnemy.setBiome(this.biomeType);
gScene.arenaBg.setTexture(`${biomeKey}_bg`);
gScene.arenaBgTransition.setTexture(`${biomeKey}_bg`);
globalScene.arenaPlayer.setBiome(this.biomeType);
globalScene.arenaPlayerTransition.setBiome(this.biomeType);
globalScene.arenaEnemy.setBiome(this.biomeType);
globalScene.arenaNextEnemy.setBiome(this.biomeType);
globalScene.arenaBg.setTexture(`${biomeKey}_bg`);
globalScene.arenaBgTransition.setTexture(`${biomeKey}_bg`);
// Redo this on initialize because during save/load the current wave isn't always
// set correctly during construction
@ -83,12 +83,12 @@ export class Arena {
}
randomSpecies(waveIndex: integer, level: integer, attempt?: integer, luckValue?: integer, isBoss?: boolean): PokemonSpecies {
const overrideSpecies = gScene.gameMode.getOverrideSpecies(waveIndex);
const overrideSpecies = globalScene.gameMode.getOverrideSpecies(waveIndex);
if (overrideSpecies) {
return overrideSpecies;
}
const isBossSpecies = !!gScene.getEncounterBossSegments(waveIndex, level) && !!this.pokemonPool[BiomePoolTier.BOSS].length
&& (this.biomeType !== Biome.END || gScene.gameMode.isClassic || gScene.gameMode.isWaveFinal(waveIndex));
const isBossSpecies = !!globalScene.getEncounterBossSegments(waveIndex, level) && !!this.pokemonPool[BiomePoolTier.BOSS].length
&& (this.biomeType !== Biome.END || globalScene.gameMode.isClassic || globalScene.gameMode.isWaveFinal(waveIndex));
const randVal = isBossSpecies ? 64 : 512;
// luck influences encounter rarity
let luckModifier = 0;
@ -108,7 +108,7 @@ export class Arena {
let ret: PokemonSpecies;
let regen = false;
if (!tierPool.length) {
ret = gScene.randomSpecies(waveIndex, level);
ret = globalScene.randomSpecies(waveIndex, level);
} else {
const entry = tierPool[Utils.randSeedInt(tierPool.length)];
let species: Species;
@ -155,7 +155,7 @@ export class Arena {
return this.randomSpecies(waveIndex, level, (attempt || 0) + 1);
}
const newSpeciesId = ret.getWildSpeciesForLevel(level, true, isBoss ?? isBossSpecies, gScene.gameMode);
const newSpeciesId = ret.getWildSpeciesForLevel(level, true, isBoss ?? isBossSpecies, globalScene.gameMode);
if (newSpeciesId !== ret.speciesId) {
console.log("Replaced", Species[ret.speciesId], "with", Species[newSpeciesId]);
ret = getPokemonSpecies(newSpeciesId);
@ -165,7 +165,7 @@ export class Arena {
randomTrainerType(waveIndex: integer, isBoss: boolean = false): TrainerType {
const isTrainerBoss = !!this.trainerPool[BiomePoolTier.BOSS].length
&& (gScene.gameMode.isTrainerBoss(waveIndex, this.biomeType, gScene.offsetGym) || isBoss);
&& (globalScene.gameMode.isTrainerBoss(waveIndex, this.biomeType, globalScene.offsetGym) || isBoss);
console.log(isBoss, this.trainerPool);
const tierValue = Utils.randSeedInt(!isTrainerBoss ? 512 : 64);
let tier = !isTrainerBoss
@ -300,8 +300,8 @@ export class Arena {
*/
trySetWeatherOverride(weather: WeatherType): boolean {
this.weather = new Weather(weather, 0);
gScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
gScene.queueMessage(getWeatherStartMessage(weather)!); // TODO: is this bang correct?
globalScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
globalScene.queueMessage(getWeatherStartMessage(weather)!); // TODO: is this bang correct?
return true;
}
@ -326,13 +326,13 @@ export class Arena {
this.eventTarget.dispatchEvent(new WeatherChangedEvent(oldWeatherType, this.weather?.weatherType!, this.weather?.turnsLeft!)); // TODO: is this bang correct?
if (this.weather) {
gScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (weather - 1), true));
gScene.queueMessage(getWeatherStartMessage(weather)!); // TODO: is this bang correct?
globalScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (weather - 1), true));
globalScene.queueMessage(getWeatherStartMessage(weather)!); // TODO: is this bang correct?
} else {
gScene.queueMessage(getWeatherClearMessage(oldWeatherType)!); // TODO: is this bang correct?
globalScene.queueMessage(getWeatherClearMessage(oldWeatherType)!); // TODO: is this bang correct?
}
gScene.getField(true).filter(p => p.isOnField()).map(pokemon => {
globalScene.getField(true).filter(p => p.isOnField()).map(pokemon => {
pokemon.findAndRemoveTags(t => "weatherTypes" in t && !(t.weatherTypes as WeatherType[]).find(t => t === weather));
applyPostWeatherChangeAbAttrs(PostWeatherChangeAbAttr, pokemon, weather);
});
@ -344,13 +344,13 @@ export class Arena {
* Function to trigger all weather based form changes
*/
triggerWeatherBasedFormChanges(): void {
gScene.getField(true).forEach( p => {
globalScene.getField(true).forEach( p => {
const isCastformWithForecast = (p.hasAbility(Abilities.FORECAST) && p.species.speciesId === Species.CASTFORM);
const isCherrimWithFlowerGift = (p.hasAbility(Abilities.FLOWER_GIFT) && p.species.speciesId === Species.CHERRIM);
if (isCastformWithForecast || isCherrimWithFlowerGift) {
new ShowAbilityPhase(p.getBattlerIndex());
gScene.triggerPokemonFormChange(p, SpeciesFormChangeWeatherTrigger);
globalScene.triggerPokemonFormChange(p, SpeciesFormChangeWeatherTrigger);
}
});
}
@ -359,13 +359,13 @@ export class Arena {
* Function to trigger all weather based form changes back into their normal forms
*/
triggerWeatherBasedFormChangesToNormal(): void {
gScene.getField(true).forEach( p => {
globalScene.getField(true).forEach( p => {
const isCastformWithForecast = (p.hasAbility(Abilities.FORECAST, false, true) && p.species.speciesId === Species.CASTFORM);
const isCherrimWithFlowerGift = (p.hasAbility(Abilities.FLOWER_GIFT, false, true) && p.species.speciesId === Species.CHERRIM);
if (isCastformWithForecast || isCherrimWithFlowerGift) {
new ShowAbilityPhase(p.getBattlerIndex());
return gScene.triggerPokemonFormChange(p, SpeciesFormChangeRevertWeatherFormTrigger);
return globalScene.triggerPokemonFormChange(p, SpeciesFormChangeRevertWeatherFormTrigger);
}
});
}
@ -382,14 +382,14 @@ export class Arena {
if (this.terrain) {
if (!ignoreAnim) {
gScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.MISTY_TERRAIN + (terrain - 1)));
globalScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.MISTY_TERRAIN + (terrain - 1)));
}
gScene.queueMessage(getTerrainStartMessage(terrain)!); // TODO: is this bang correct?
globalScene.queueMessage(getTerrainStartMessage(terrain)!); // TODO: is this bang correct?
} else {
gScene.queueMessage(getTerrainClearMessage(oldTerrainType)!); // TODO: is this bang correct?
globalScene.queueMessage(getTerrainClearMessage(oldTerrainType)!); // TODO: is this bang correct?
}
gScene.getField(true).filter(p => p.isOnField()).map(pokemon => {
globalScene.getField(true).filter(p => p.isOnField()).map(pokemon => {
pokemon.findAndRemoveTags(t => "terrainTypes" in t && !(t.terrainTypes as TerrainType[]).find(t => t === terrain));
applyPostTerrainChangeAbAttrs(PostTerrainChangeAbAttr, pokemon, terrain);
applyAbAttrs(TerrainEventTypeChangeAbAttr, pokemon, null, false);
@ -478,7 +478,7 @@ export class Arena {
return TimeOfDay.NIGHT;
}
const waveCycle = ((gScene.currentBattle?.waveIndex || 0) + gScene.waveCycleOffset) % 40;
const waveCycle = ((globalScene.currentBattle?.waveIndex || 0) + globalScene.waveCycleOffset) % 40;
if (waveCycle < 15) {
return TimeOfDay.DAY;
@ -748,7 +748,7 @@ export class Arena {
}
preloadBgm(): void {
gScene.loadBgm(this.bgm);
globalScene.loadBgm(this.bgm);
}
getBgmLoopPoint(): number {
@ -873,16 +873,16 @@ export class ArenaBase extends Phaser.GameObjects.Container {
public props: Phaser.GameObjects.Sprite[];
constructor(player: boolean) {
super(gScene, 0, 0);
super(globalScene, 0, 0);
this.player = player;
this.base = gScene.addFieldSprite(0, 0, "plains_a", undefined, 1);
this.base = globalScene.addFieldSprite(0, 0, "plains_a", undefined, 1);
this.base.setOrigin(0, 0);
this.props = !player ?
new Array(3).fill(null).map(() => {
const ret = gScene.addFieldSprite(0, 0, "plains_b", undefined, 1);
const ret = globalScene.addFieldSprite(0, 0, "plains_b", undefined, 1);
ret.setOrigin(0, 0);
ret.setVisible(false);
return ret;
@ -898,9 +898,9 @@ export class ArenaBase extends Phaser.GameObjects.Container {
this.base.setTexture(baseKey);
if (this.base.texture.frameTotal > 1) {
const baseFrameNames = gScene.anims.generateFrameNames(baseKey, { zeroPad: 4, suffix: ".png", start: 1, end: this.base.texture.frameTotal - 1 });
if (!(gScene.anims.exists(baseKey))) {
gScene.anims.create({
const baseFrameNames = globalScene.anims.generateFrameNames(baseKey, { zeroPad: 4, suffix: ".png", start: 1, end: this.base.texture.frameTotal - 1 });
if (!(globalScene.anims.exists(baseKey))) {
globalScene.anims.create({
key: baseKey,
frames: baseFrameNames,
frameRate: 12,
@ -916,7 +916,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
}
if (!this.player) {
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
this.propValue = propValue === undefined
? hasProps ? Utils.randSeedInt(8) : 0
: propValue;
@ -925,9 +925,9 @@ export class ArenaBase extends Phaser.GameObjects.Container {
prop.setTexture(propKey);
if (hasProps && prop.texture.frameTotal > 1) {
const propFrameNames = gScene.anims.generateFrameNames(propKey, { zeroPad: 4, suffix: ".png", start: 1, end: prop.texture.frameTotal - 1 });
if (!(gScene.anims.exists(propKey))) {
gScene.anims.create({
const propFrameNames = globalScene.anims.generateFrameNames(propKey, { zeroPad: 4, suffix: ".png", start: 1, end: prop.texture.frameTotal - 1 });
if (!(globalScene.anims.exists(propKey))) {
globalScene.anims.create({
key: propKey,
frames: propFrameNames,
frameRate: 12,
@ -942,7 +942,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
prop.setVisible(hasProps && !!(this.propValue & (1 << p)));
this.add(prop);
});
}, gScene.currentBattle?.waveIndex || 0, gScene.waveSeed);
}, globalScene.currentBattle?.waveIndex || 0, globalScene.waveSeed);
}
}
}

View File

@ -2,7 +2,7 @@ import { TextStyle, addTextObject } from "../ui/text";
import Pokemon, { DamageResult, HitResult } from "./pokemon";
import * as Utils from "../utils";
import { BattlerIndex } from "../battle";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
type TextAndShadowArr = [ string | null, string | null ];
@ -14,13 +14,13 @@ export default class DamageNumberHandler {
}
add(target: Pokemon, amount: integer, result: DamageResult | HitResult.HEAL = HitResult.EFFECTIVE, critical: boolean = false): void {
if (!gScene?.damageNumbersMode) {
if (!globalScene?.damageNumbersMode) {
return;
}
const battlerIndex = target.getBattlerIndex();
const baseScale = target.getSpriteScale() / 6;
const damageNumber = addTextObject(target.x, -(gScene.game.canvas.height / 6) + target.y - target.getSprite().height / 2, Utils.formatStat(amount, true), TextStyle.SUMMARY);
const damageNumber = addTextObject(target.x, -(globalScene.game.canvas.height / 6) + target.y - target.getSprite().height / 2, Utils.formatStat(amount, true), TextStyle.SUMMARY);
damageNumber.setName("text-damage-number");
damageNumber.setOrigin(0.5, 1);
damageNumber.setScale(baseScale);
@ -57,7 +57,7 @@ export default class DamageNumberHandler {
}
}
gScene.fieldUI.add(damageNumber);
globalScene.fieldUI.add(damageNumber);
if (!this.damageNumbers.has(battlerIndex)) {
this.damageNumbers.set(battlerIndex, []);
@ -70,14 +70,14 @@ export default class DamageNumberHandler {
this.damageNumbers.get(battlerIndex)!.push(damageNumber);
if (gScene.damageNumbersMode === 1) {
gScene.tweens.add({
if (globalScene.damageNumbersMode === 1) {
globalScene.tweens.add({
targets: damageNumber,
duration: Utils.fixedInt(750),
alpha: 1,
y: "-=32"
});
gScene.tweens.add({
globalScene.tweens.add({
delay: 375,
targets: damageNumber,
duration: Utils.fixedInt(625),
@ -93,7 +93,7 @@ export default class DamageNumberHandler {
damageNumber.setAlpha(0);
gScene.tweens.chain({
globalScene.tweens.chain({
targets: damageNumber,
tweens: [
{

View File

@ -1,5 +1,5 @@
import { GameObjects } from "phaser";
import BattleScene, { gScene } from "#app/battle-scene";
import BattleScene, { globalScene } from "#app/battle-scene";
import MysteryEncounter from "../data/mystery-encounters/mystery-encounter";
import { Species } from "#enums/species";
import { isNullOrUndefined } from "#app/utils";
@ -76,7 +76,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
public enterFromRight: boolean;
constructor(encounter: MysteryEncounter) {
super(gScene, -72, 76);
super(globalScene, -72, 76);
this.encounter = encounter;
this.enterFromRight = encounter.enterIntroVisualsFromRight ?? false;
// Shallow copy configs to allow visual config updates at runtime without dirtying master copy of Encounter
@ -99,16 +99,16 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
}
const getSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => {
const ret = gScene.addFieldSprite(0, 0, spriteKey);
const ret = globalScene.addFieldSprite(0, 0, spriteKey);
ret.setOrigin(0.5, 1);
ret.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
return ret;
};
const getItemSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => {
const icon = gScene.add.sprite(-19, 2, "items", spriteKey);
const icon = globalScene.add.sprite(-19, 2, "items", spriteKey);
icon.setOrigin(0.5, 1);
icon.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
icon.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
return icon;
};
@ -186,15 +186,15 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
this.spriteConfigs.forEach((config) => {
if (config.isPokemon) {
gScene.loadPokemonAtlas(config.spriteKey, config.fileRoot);
globalScene.loadPokemonAtlas(config.spriteKey, config.fileRoot);
} else if (config.isItem) {
gScene.loadAtlas("items", "");
globalScene.loadAtlas("items", "");
} else {
gScene.loadAtlas(config.spriteKey, config.fileRoot);
globalScene.loadAtlas(config.spriteKey, config.fileRoot);
}
});
gScene.load.once(Phaser.Loader.Events.COMPLETE, () => {
globalScene.load.once(Phaser.Loader.Events.COMPLETE, () => {
this.spriteConfigs.every((config) => {
if (config.isItem) {
return true;
@ -205,11 +205,11 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
// Ignore warnings for missing frames, because there will be a lot
console.warn = () => {
};
const frameNames = gScene.anims.generateFrameNames(config.spriteKey, { zeroPad: 4, suffix: ".png", start: 1, end: 128 });
const frameNames = globalScene.anims.generateFrameNames(config.spriteKey, { zeroPad: 4, suffix: ".png", start: 1, end: 128 });
console.warn = originalWarn;
if (!(gScene.anims.exists(config.spriteKey))) {
gScene.anims.create({
if (!(globalScene.anims.exists(config.spriteKey))) {
globalScene.anims.create({
key: config.spriteKey,
frames: frameNames,
frameRate: 12,
@ -223,8 +223,8 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
resolve();
});
if (!gScene.load.isLoading()) {
gScene.load.start();
if (!globalScene.load.isLoading()) {
globalScene.load.start();
}
});
}
@ -374,7 +374,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
if (duration) {
sprite.setAlpha(0);
gScene.tweens.add({
globalScene.tweens.add({
targets: sprite,
alpha: alpha || 1,
duration: duration,
@ -407,7 +407,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
*/
private untint(sprite, duration: integer, ease?: string): void {
if (duration) {
gScene.tweens.add({
globalScene.tweens.add({
targets: sprite,
alpha: 0,
duration: duration,

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import Pokemon from "./pokemon";
import * as Utils from "../utils";
@ -8,7 +8,7 @@ export default class PokemonSpriteSparkleHandler {
setup(): void {
this.sprites = new Set();
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
duration: Utils.fixedInt(200),
from: 0,
to: 1,
@ -37,7 +37,7 @@ export default class PokemonSpriteSparkleHandler {
const pixel = texture.manager.getPixel(pixelX, pixelY, texture.key, "__BASE");
if (pixel?.alpha) {
const [ xOffset, yOffset ] = [ -s.originX * s.width, -s.originY * s.height ];
const sparkle = gScene.addFieldSprite(((pokemon?.x || 0) + s.x + pixelX * ratioX + xOffset), ((pokemon?.y || 0) + s.y + pixelY * ratioY + yOffset), "tera_sparkle");
const sparkle = globalScene.addFieldSprite(((pokemon?.x || 0) + s.x + pixelX * ratioX + xOffset), ((pokemon?.y || 0) + s.y + pixelY * ratioY + yOffset), "tera_sparkle");
sparkle.pipelineData["ignoreTimeTint"] = s.pipelineData["ignoreTimeTint"];
sparkle.setName("sprite-tera-sparkle");
sparkle.play("tera_sparkle");

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import BattleScene, { gScene } from "#app/battle-scene";
import BattleScene, { globalScene } from "#app/battle-scene";
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
import {
@ -36,7 +36,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
public partnerName: string;
constructor(trainerType: TrainerType, variant: TrainerVariant, partyTemplateIndex?: integer, name?: string, partnerName?: string, trainerConfigOverride?: TrainerConfig) {
super(gScene, -72, 80);
super(globalScene, -72, 80);
this.config = trainerConfigs.hasOwnProperty(trainerType)
? trainerConfigs[trainerType]
: trainerConfigs[TrainerType.ACE_TRAINER];
@ -80,9 +80,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
console.log(Object.keys(trainerPartyTemplates)[Object.values(trainerPartyTemplates).indexOf(this.getPartyTemplate())]);
const getSprite = (hasShadow?: boolean, forceFemale?: boolean) => {
const ret = gScene.addFieldSprite(0, 0, this.config.getSpriteKey(variant === TrainerVariant.FEMALE || forceFemale, this.isDouble()));
const ret = globalScene.addFieldSprite(0, 0, this.config.getSpriteKey(variant === TrainerVariant.FEMALE || forceFemale, this.isDouble()));
ret.setOrigin(0.5, 1);
ret.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow });
ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow });
return ret;
};
@ -216,7 +216,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
const ret: number[] = [];
const partyTemplate = this.getPartyTemplate();
const difficultyWaveIndex = gScene.gameMode.getWaveForDifficulty(waveIndex);
const difficultyWaveIndex = globalScene.gameMode.getWaveForDifficulty(waveIndex);
const baseLevel = 1 + difficultyWaveIndex / 2 + Math.pow(difficultyWaveIndex / 25, 2);
if (this.isDouble() && partyTemplate.size < 2) {
@ -261,12 +261,12 @@ export default class Trainer extends Phaser.GameObjects.Container {
}
genPartyMember(index: integer): EnemyPokemon {
const battle = gScene.currentBattle;
const battle = globalScene.currentBattle;
const level = battle.enemyLevels?.[index]!; // TODO: is this bang correct?
let ret: EnemyPokemon;
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
const template = this.getPartyTemplate();
const strength: PartyMemberStrength = template.getStrength(index);
@ -364,23 +364,23 @@ export default class Trainer extends Phaser.GameObjects.Container {
let species = useNewSpeciesPool
? getPokemonSpecies(newSpeciesPool[Math.floor(Utils.randSeedInt(newSpeciesPool.length))])
: template.isSameSpecies(index) && index > offset
? getPokemonSpecies(battle.enemyParty[offset].species.getTrainerSpeciesForLevel(level, false, template.getStrength(offset), gScene.currentBattle.waveIndex))
? getPokemonSpecies(battle.enemyParty[offset].species.getTrainerSpeciesForLevel(level, false, template.getStrength(offset), globalScene.currentBattle.waveIndex))
: this.genNewPartyMemberSpecies(level, strength);
// If the species is from newSpeciesPool, we need to adjust it based on the level and strength
if (newSpeciesPool) {
species = getPokemonSpecies(species.getSpeciesForLevel(level, true, true, strength, gScene.currentBattle.waveIndex));
species = getPokemonSpecies(species.getSpeciesForLevel(level, true, true, strength, globalScene.currentBattle.waveIndex));
}
ret = gScene.addEnemyPokemon(species, level, !this.isDouble() || !(index % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER);
}, this.config.hasStaticParty ? this.config.getDerivedType() + ((index + 1) << 8) : gScene.currentBattle.waveIndex + (this.config.getDerivedType() << 10) + (((!this.config.useSameSeedForAllMembers ? index : 0) + 1) << 8));
ret = globalScene.addEnemyPokemon(species, level, !this.isDouble() || !(index % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER);
}, this.config.hasStaticParty ? this.config.getDerivedType() + ((index + 1) << 8) : globalScene.currentBattle.waveIndex + (this.config.getDerivedType() << 10) + (((!this.config.useSameSeedForAllMembers ? index : 0) + 1) << 8));
return ret!; // TODO: is this bang correct?
}
genNewPartyMemberSpecies(level: integer, strength: PartyMemberStrength, attempt?: integer): PokemonSpecies {
const battle = gScene.currentBattle;
const battle = globalScene.currentBattle;
const template = this.getPartyTemplate();
let baseSpecies: PokemonSpecies;
@ -395,10 +395,10 @@ export default class Trainer extends Phaser.GameObjects.Container {
const tierPool = this.config.speciesPools[tier];
baseSpecies = getPokemonSpecies(Utils.randSeedItem(tierPool));
} else {
baseSpecies = gScene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
baseSpecies = globalScene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
}
let ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, gScene.currentBattle.waveIndex));
let ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, globalScene.currentBattle.waveIndex));
let retry = false;
console.log(ret.getName());
@ -417,7 +417,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
console.log("Attempting reroll of species evolution to fit specialty type...");
let evoAttempt = 0;
while (retry && evoAttempt++ < 10) {
ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, gScene.currentBattle.waveIndex));
ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, globalScene.currentBattle.waveIndex));
console.log(ret.name);
if (this.config.specialtyTypes.find(t => ret.isOfType(t))) {
retry = false;
@ -448,7 +448,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
checkDuplicateSpecies(species: PokemonSpecies, baseSpecies: PokemonSpecies): boolean {
const staticPartyPokemon = (signatureSpecies[TrainerType[this.config.trainerType]] ?? []).flat(1);
const currentPartySpecies = gScene.getEnemyParty().map(p => {
const currentPartySpecies = globalScene.getEnemyParty().map(p => {
return p.species.speciesId;
});
return currentPartySpecies.includes(species.speciesId) || staticPartyPokemon.includes(baseSpecies.speciesId);
@ -459,10 +459,10 @@ export default class Trainer extends Phaser.GameObjects.Container {
trainerSlot = TrainerSlot.NONE;
}
const party = gScene.getEnemyParty();
const nonFaintedLegalPartyMembers = party.slice(gScene.currentBattle.getBattlerCount()).filter(p => p.isAllowedInBattle()).filter(p => !trainerSlot || p.trainerSlot === trainerSlot);
const party = globalScene.getEnemyParty();
const nonFaintedLegalPartyMembers = party.slice(globalScene.currentBattle.getBattlerCount()).filter(p => p.isAllowedInBattle()).filter(p => !trainerSlot || p.trainerSlot === trainerSlot);
const partyMemberScores = nonFaintedLegalPartyMembers.map(p => {
const playerField = gScene.getPlayerField().filter(p => p.isAllowedInBattle());
const playerField = globalScene.getPlayerField().filter(p => p.isAllowedInBattle());
let score = 0;
if (playerField.length > 0) {
@ -474,7 +474,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
}
score /= playerField.length;
if (forSwitch && !p.isOnField()) {
gScene.arena.findTagsOnSide(t => t instanceof ArenaTrapTag, ArenaTagSide.ENEMY).map(t => score *= (t as ArenaTrapTag).getMatchupScoreMultiplier(p));
globalScene.arena.findTagsOnSide(t => t instanceof ArenaTrapTag, ArenaTagSide.ENEMY).map(t => score *= (t as ArenaTrapTag).getMatchupScoreMultiplier(p));
}
}
@ -506,7 +506,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
if (maxScorePartyMemberIndexes.length > 1) {
let rand: integer;
gScene.executeWithSeedOffset(() => rand = Utils.randSeedInt(maxScorePartyMemberIndexes.length), gScene.currentBattle.turn << 2);
globalScene.executeWithSeedOffset(() => rand = Utils.randSeedInt(maxScorePartyMemberIndexes.length), globalScene.currentBattle.turn << 2);
return maxScorePartyMemberIndexes[rand!];
}
@ -627,7 +627,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
if (duration) {
tintSprite.setAlpha(0);
gScene.tweens.add({
globalScene.tweens.add({
targets: tintSprite,
alpha: alpha || 1,
duration: duration,
@ -643,7 +643,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
const tintSprites = this.getTintSprites();
tintSprites.map(tintSprite => {
if (duration) {
gScene.tweens.add({
globalScene.tweens.add({
targets: tintSprite,
alpha: 0,
duration: duration,

View File

@ -8,7 +8,7 @@ import * as Utils from "./utils";
import { Biome } from "#enums/biome";
import { Species } from "#enums/species";
import { Challenges } from "./enums/challenges";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export enum GameModes {
CLASSIC,
@ -118,7 +118,7 @@ export class GameMode implements GameModeConfig {
getStartingBiome(): Biome {
switch (this.modeId) {
case GameModes.DAILY:
return gScene.generateRandomBiome(this.getWaveForDifficulty(1));
return globalScene.generateRandomBiome(this.getWaveForDifficulty(1));
default:
return Overrides.STARTING_BIOME_OVERRIDE || Biome.TOWN;
}
@ -146,7 +146,7 @@ export class GameMode implements GameModeConfig {
if (this.isDaily) {
return waveIndex % 10 === 5 || (!(waveIndex % 10) && waveIndex > 10 && !this.isWaveFinal(waveIndex));
}
if ((waveIndex % 30) === (gScene.offsetGym ? 0 : 20) && !this.isWaveFinal(waveIndex)) {
if ((waveIndex % 30) === (globalScene.offsetGym ? 0 : 20) && !this.isWaveFinal(waveIndex)) {
return true;
} else if (waveIndex % 10 !== 1 && waveIndex % 10) {
/**
@ -163,11 +163,11 @@ export class GameMode implements GameModeConfig {
if (w === waveIndex) {
continue;
}
if ((w % 30) === (gScene.offsetGym ? 0 : 20) || this.isFixedBattle(w)) {
if ((w % 30) === (globalScene.offsetGym ? 0 : 20) || this.isFixedBattle(w)) {
allowTrainerBattle = false;
break;
} else if (w < waveIndex) {
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
const waveTrainerChance = arena.getTrainerChance();
if (!Utils.randSeedInt(waveTrainerChance)) {
allowTrainerBattle = false;

View File

@ -15,7 +15,7 @@ import {
getButtonWithKeycode,
getIconForLatestInput, swap,
} from "#app/configs/inputs/configHandler";
import { gScene } from "./battle-scene";
import { globalScene } from "./battle-scene";
import { SettingGamepad } from "#app/system/settings/settings-gamepad";
import { SettingKeyboard } from "#app/system/settings/settings-keyboard";
import TouchControl from "#app/touch-controls";
@ -132,14 +132,14 @@ export class InputsController {
* Additionally, it manages the game's behavior when it loses focus to prevent unwanted game actions during this state.
*/
init(): void {
this.events = gScene.game.events;
this.events = globalScene.game.events;
gScene.game.events.on(Phaser.Core.Events.BLUR, () => {
globalScene.game.events.on(Phaser.Core.Events.BLUR, () => {
this.loseFocus();
});
if (typeof gScene.input.gamepad !== "undefined") {
gScene.input.gamepad?.on("connected", function (thisGamepad) {
if (typeof globalScene.input.gamepad !== "undefined") {
globalScene.input.gamepad?.on("connected", function (thisGamepad) {
if (!thisGamepad) {
return;
}
@ -148,23 +148,23 @@ export class InputsController {
this.onReconnect(thisGamepad);
}, this);
gScene.input.gamepad?.on("disconnected", function (thisGamepad) {
globalScene.input.gamepad?.on("disconnected", function (thisGamepad) {
this.onDisconnect(thisGamepad); // when a gamepad is disconnected
}, this);
// Check to see if the gamepad has already been setup by the browser
gScene.input.gamepad?.refreshPads();
if (gScene.input.gamepad?.total) {
globalScene.input.gamepad?.refreshPads();
if (globalScene.input.gamepad?.total) {
this.refreshGamepads();
for (const thisGamepad of this.gamepads) {
gScene.input.gamepad.emit("connected", thisGamepad);
globalScene.input.gamepad.emit("connected", thisGamepad);
}
}
gScene.input.gamepad?.on("down", this.gamepadButtonDown, this);
gScene.input.gamepad?.on("up", this.gamepadButtonUp, this);
gScene.input.keyboard?.on("keydown", this.keyboardKeyDown, this);
gScene.input.keyboard?.on("keyup", this.keyboardKeyUp, this);
globalScene.input.gamepad?.on("down", this.gamepadButtonDown, this);
globalScene.input.gamepad?.on("up", this.gamepadButtonUp, this);
globalScene.input.keyboard?.on("keydown", this.keyboardKeyDown, this);
globalScene.input.keyboard?.on("keyup", this.keyboardKeyUp, this);
}
this.touchControls = new TouchControl();
this.moveTouchControlsHandler = new MoveTouchControlsHandler(this.touchControls);
@ -236,7 +236,7 @@ export class InputsController {
if (gamepadName) {
this.selectedDevice[Device.GAMEPAD] = gamepadName.toLowerCase();
}
const handler = gScene.ui?.handlers[Mode.SETTINGS_GAMEPAD] as SettingsGamepadUiHandler;
const handler = globalScene.ui?.handlers[Mode.SETTINGS_GAMEPAD] as SettingsGamepadUiHandler;
handler && handler.updateChosenGamepadDisplay();
}
@ -249,7 +249,7 @@ export class InputsController {
if (layoutKeyboard) {
this.selectedDevice[Device.KEYBOARD] = layoutKeyboard.toLowerCase();
}
const handler = gScene.ui?.handlers[Mode.SETTINGS_KEYBOARD] as SettingsKeyboardUiHandler;
const handler = globalScene.ui?.handlers[Mode.SETTINGS_KEYBOARD] as SettingsKeyboardUiHandler;
handler && handler.updateChosenKeyboardDisplay();
}
@ -294,10 +294,10 @@ export class InputsController {
const config = deepCopy(this.getConfig(gamepadID)) as InterfaceConfig;
config.custom = this.configs[gamepadID]?.custom || { ...config.default };
this.configs[gamepadID] = config;
gScene.gameData?.saveMappingConfigs(gamepadID, this.configs[gamepadID]);
globalScene.gameData?.saveMappingConfigs(gamepadID, this.configs[gamepadID]);
}
this.lastSource = "gamepad";
const handler = gScene.ui?.handlers[Mode.SETTINGS_GAMEPAD] as SettingsGamepadUiHandler;
const handler = globalScene.ui?.handlers[Mode.SETTINGS_GAMEPAD] as SettingsGamepadUiHandler;
handler && handler.updateChosenGamepadDisplay();
}
@ -309,7 +309,7 @@ export class InputsController {
const config = deepCopy(this.getConfigKeyboard(layout)) as InterfaceConfig;
config.custom = this.configs[layout]?.custom || { ...config.default };
this.configs[layout] = config;
gScene.gameData?.saveMappingConfigs(this.selectedDevice[Device.KEYBOARD], this.configs[layout]);
globalScene.gameData?.saveMappingConfigs(this.selectedDevice[Device.KEYBOARD], this.configs[layout]);
}
this.initChosenLayoutKeyboard(this.selectedDevice[Device.KEYBOARD]);
}
@ -324,7 +324,7 @@ export class InputsController {
*/
refreshGamepads(): void {
// Sometimes, gamepads are undefined. For some reason.
this.gamepads = gScene.input.gamepad?.gamepads.filter(function (el) {
this.gamepads = globalScene.input.gamepad?.gamepads.filter(function (el) {
return el !== null;
}) ?? [];
@ -407,7 +407,7 @@ export class InputsController {
return;
}
this.lastSource = "gamepad";
if (!this.selectedDevice[Device.GAMEPAD] || (gScene.ui.getMode() !== Mode.GAMEPAD_BINDING && this.selectedDevice[Device.GAMEPAD] !== pad.id.toLowerCase())) {
if (!this.selectedDevice[Device.GAMEPAD] || (globalScene.ui.getMode() !== Mode.GAMEPAD_BINDING && this.selectedDevice[Device.GAMEPAD] !== pad.id.toLowerCase())) {
this.setChosenGamepad(pad.id);
}
if (!this.gamepadSupport || pad.id.toLowerCase() !== this.selectedDevice[Device.GAMEPAD].toLowerCase()) {

View File

@ -20,7 +20,7 @@ import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
import { initVouchers } from "#app/system/voucher";
import { Biome } from "#enums/biome";
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export class LoadingScene extends SceneBase {
public static readonly KEY = "loading";
@ -511,7 +511,7 @@ export class LoadingScene extends SceneBase {
async create() {
this.events.once(Phaser.Scenes.Events.DESTROY, () => this.handleDestroy());
gScene.scene.start("battle");
globalScene.scene.start("battle");
}
handleDestroy() {

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { BattleSpec } from "#enums/battle-spec";
import Pokemon from "./field/pokemon";
import i18next from "i18next";
@ -13,7 +13,7 @@ export function getPokemonNameWithAffix(pokemon: Pokemon | undefined): string {
return "Missigno";
}
switch (gScene.currentBattle.battleSpec) {
switch (globalScene.currentBattle.battleSpec) {
case BattleSpec.DEFAULT:
return !pokemon.isPlayer()
? pokemon.hasTrainer()

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { EvolutionItem, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
import { tmPoolTiers, tmSpecies } from "#app/data/balance/tms";
import { getBerryEffectDescription, getBerryName } from "#app/data/berry";
@ -187,7 +187,7 @@ class AddPokeballModifierType extends ModifierType {
"modifierCount": this.count,
"pokeballName": getPokeballName(this.pokeballType),
"catchRate": getPokeballCatchMultiplier(this.pokeballType) > -1 ? `${getPokeballCatchMultiplier(this.pokeballType)}x` : "100%",
"pokeballAmount": `${gScene.pokeballCounts[this.pokeballType]}`,
"pokeballAmount": `${globalScene.pokeballCounts[this.pokeballType]}`,
});
}
}
@ -231,7 +231,7 @@ export class PokemonHeldItemModifierType extends PokemonModifierType {
constructor(localeKey: string, iconImage: string, newModifierFunc: NewModifierFunc, group?: string, soundName?: string) {
super(localeKey, iconImage, newModifierFunc, (pokemon: PlayerPokemon) => {
const dummyModifier = this.newModifier(pokemon);
const matchingModifier = gScene.findModifier(m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(dummyModifier)) as PokemonHeldItemModifier;
const matchingModifier = globalScene.findModifier(m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(dummyModifier)) as PokemonHeldItemModifier;
const maxStackCount = dummyModifier.getMaxStackCount();
if (!maxStackCount) {
return i18next.t("modifierType:ModifierType.PokemonHeldItemModifierType.extra.inoperable", { "pokemonName": getPokemonNameWithAffix(pokemon) });
@ -578,7 +578,7 @@ export class PokemonLevelIncrementModifierType extends PokemonModifierType {
getDescription(): string {
let levels = 1;
const hasCandyJar = gScene.modifiers.find(modifier => modifier instanceof LevelIncrementBoosterModifier);
const hasCandyJar = globalScene.modifiers.find(modifier => modifier instanceof LevelIncrementBoosterModifier);
if (hasCandyJar) {
levels += hasCandyJar.stackCount;
}
@ -593,7 +593,7 @@ export class AllPokemonLevelIncrementModifierType extends ModifierType {
getDescription(): string {
let levels = 1;
const hasCandyJar = gScene.modifiers.find(modifier => modifier instanceof LevelIncrementBoosterModifier);
const hasCandyJar = globalScene.modifiers.find(modifier => modifier instanceof LevelIncrementBoosterModifier);
if (hasCandyJar) {
levels += hasCandyJar.stackCount;
}
@ -707,9 +707,9 @@ export class MoneyRewardModifierType extends ModifierType {
}
getDescription(): string {
const moneyAmount = new IntegerHolder(gScene.getWaveMoneyAmount(this.moneyMultiplier));
gScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
const formattedMoney = formatMoney(gScene.moneyFormat, moneyAmount.value);
const moneyAmount = new IntegerHolder(globalScene.getWaveMoneyAmount(this.moneyMultiplier));
globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
const formattedMoney = formatMoney(globalScene.moneyFormat, moneyAmount.value);
return i18next.t("modifierType:ModifierType.MoneyRewardModifierType.description", {
moneyMultiplier: i18next.t(this.moneyMultiplierDescriptorKey as any),
@ -803,7 +803,7 @@ export class TmModifierType extends PokemonModifierType {
}
getDescription(): string {
return i18next.t(gScene.enableMoveInfo ? "modifierType:ModifierType.TmModifierTypeWithInfo.description" : "modifierType:ModifierType.TmModifierType.description", { moveName: allMoves[this.moveId].name });
return i18next.t(globalScene.enableMoveInfo ? "modifierType:ModifierType.TmModifierTypeWithInfo.description" : "modifierType:ModifierType.TmModifierType.description", { moveName: allMoves[this.moveId].name });
}
}
@ -1116,12 +1116,12 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
const formChangeItemPool = [ ...new Set(party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => {
const formChanges = pokemonFormChanges[p.species.speciesId];
let formChangeItemTriggers = formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || gScene.getModifiers(MegaEvolutionAccessModifier).length)
&& ((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 && fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) || gScene.getModifiers(GigantamaxAccessModifier).length)
let formChangeItemTriggers = formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || globalScene.getModifiers(MegaEvolutionAccessModifier).length)
&& ((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 && fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) || globalScene.getModifiers(GigantamaxAccessModifier).length)
&& (!fc.conditions.length || fc.conditions.filter(cond => cond instanceof SpeciesFormChangeCondition && cond.predicate(p)).length)
&& (fc.preFormKey === p.getFormKey()))
.map(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger)
.filter(t => t && t.active && !gScene.findModifier(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === p.id && m.formChangeItem === t.item));
.filter(t => t && t.active && !globalScene.findModifier(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === p.id && m.formChangeItem === t.item));
if (p.species.speciesId === Species.NECROZMA) {
// technically we could use a simplified version and check for formChanges.length > 3, but in case any code changes later, this might break...
@ -1252,8 +1252,8 @@ type WeightedModifierTypeWeightFunc = (party: Pokemon[], rerollCount?: integer)
*/
function skipInClassicAfterWave(wave: integer, defaultWeight: integer): WeightedModifierTypeWeightFunc {
return (party: Pokemon[]) => {
const gameMode = gScene.gameMode;
const currentWave = gScene.currentBattle.waveIndex;
const gameMode = globalScene.gameMode;
const currentWave = globalScene.currentBattle.waveIndex;
return gameMode.isClassic && currentWave >= wave ? 0 : defaultWeight;
};
}
@ -1277,8 +1277,8 @@ function skipInLastClassicWaveOrDefault(defaultWeight: integer) : WeightedModifi
*/
function lureWeightFunc(maxBattles: number, weight: number): WeightedModifierTypeWeightFunc {
return (party: Pokemon[]) => {
const lures = gScene.getModifiers(DoubleBattleChanceBoosterModifier);
return !(gScene.gameMode.isClassic && gScene.currentBattle.waveIndex === 199) && (lures.length === 0 || lures.filter(m => m.getMaxBattles() === maxBattles && m.getBattleCount() >= maxBattles * 0.6).length === 0) ? weight : 0;
const lures = globalScene.getModifiers(DoubleBattleChanceBoosterModifier);
return !(globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex === 199) && (lures.length === 0 || lures.filter(m => m.getMaxBattles() === maxBattles && m.getBattleCount() >= maxBattles * 0.6).length === 0) ? weight : 0;
};
}
class WeightedModifierType {
@ -1435,7 +1435,7 @@ export const modifierTypes = {
if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in Type)) {
return new TerastallizeModifierType(pregenArgs[0] as Type);
}
if (!gScene.getModifiers(TerastallizeAccessModifier).length) {
if (!globalScene.getModifiers(TerastallizeAccessModifier).length) {
return null;
}
let type: Type;
@ -1588,7 +1588,7 @@ interface ModifierPool {
* @returns boolean: true if the player has the maximum of a given ball type
*/
function hasMaximumBalls(party: Pokemon[], ballType: PokeballType): boolean {
return (gScene.gameMode.isClassic && gScene.pokeballCounts[ballType] >= MAX_PER_TYPE_POKEBALLS);
return (globalScene.gameMode.isClassic && globalScene.pokeballCounts[ballType] >= MAX_PER_TYPE_POKEBALLS);
}
const modifierPool: ModifierPool = {
@ -1671,12 +1671,12 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.SUPER_LURE, lureWeightFunc(15, 4)),
new WeightedModifierType(modifierTypes.NUGGET, skipInLastClassicWaveOrDefault(5)),
new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, (party: Pokemon[]) => {
return Math.min(Math.ceil(gScene.currentBattle.waveIndex / 15), 8);
return Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 15), 8);
}, 8),
new WeightedModifierType(modifierTypes.MAP,
(party: Pokemon[]) => gScene.gameMode.isClassic && gScene.currentBattle.waveIndex < 180 ? gScene.eventManager.isEventActive() ? 2 : 1 : 0,
(party: Pokemon[]) => gScene.eventManager.isEventActive() ? 2 : 1),
new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => gScene.eventManager.isEventActive() ? 3 : 0),
(party: Pokemon[]) => globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex < 180 ? globalScene.eventManager.isEventActive() ? 2 : 1 : 0,
(party: Pokemon[]) => globalScene.eventManager.isEventActive() ? 2 : 1),
new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => globalScene.eventManager.isEventActive() ? 3 : 0),
new WeightedModifierType(modifierTypes.TM_GREAT, 3),
new WeightedModifierType(modifierTypes.MEMORY_MUSHROOM, (party: Pokemon[]) => {
if (!party.find(p => p.getLearnableLevelMoves().length)) {
@ -1687,8 +1687,8 @@ const modifierPool: ModifierPool = {
}, 4),
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3),
new WeightedModifierType(modifierTypes.TERA_SHARD, 1),
new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => gScene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 4 : 0),
new WeightedModifierType(modifierTypes.VOUCHER, (party: Pokemon[], rerollCount: integer) => !gScene.gameMode.isDaily ? Math.max(1 - rerollCount, 0) : 0, 1),
new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => globalScene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 4 : 0),
new WeightedModifierType(modifierTypes.VOUCHER, (party: Pokemon[], rerollCount: integer) => !globalScene.gameMode.isDaily ? Math.max(1 - rerollCount, 0) : 0, 1),
].map(m => {
m.setTier(ModifierTier.GREAT); return m;
}),
@ -1698,11 +1698,11 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.BIG_NUGGET, skipInLastClassicWaveOrDefault(12)),
new WeightedModifierType(modifierTypes.PP_MAX, 3),
new WeightedModifierType(modifierTypes.MINT, 4),
new WeightedModifierType(modifierTypes.RARE_EVOLUTION_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(gScene.currentBattle.waveIndex / 15) * 4, 32), 32),
new WeightedModifierType(modifierTypes.FORM_CHANGE_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(gScene.currentBattle.waveIndex / 50), 4) * 6, 24),
new WeightedModifierType(modifierTypes.RARE_EVOLUTION_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 15) * 4, 32), 32),
new WeightedModifierType(modifierTypes.FORM_CHANGE_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6, 24),
new WeightedModifierType(modifierTypes.AMULET_COIN, skipInLastClassicWaveOrDefault(3)),
new WeightedModifierType(modifierTypes.EVIOLITE, (party: Pokemon[]) => {
const { gameMode, gameData } = gScene;
const { gameMode, gameData } = globalScene;
if (gameMode.isDaily || (!gameMode.isFreshStartChallenge() && gameData.isUnlocked(Unlockables.EVIOLITE))) {
return party.some(p => ((p.getSpeciesForm(true).speciesId in pokemonEvolutions) || (p.isFusion() && (p.getFusionSpeciesForm(true).speciesId in pokemonEvolutions)))
&& !p.getHeldItems().some(i => i instanceof EvolutionStatBoosterModifier) && !p.isMax()) ? 10 : 0;
@ -1744,13 +1744,13 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)),
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9),
new WeightedModifierType(modifierTypes.TM_ULTRA, 11),
new WeightedModifierType(modifierTypes.RARER_CANDY, (party: Pokemon[]) => gScene.eventManager.isEventActive() ? 6 : 4),
new WeightedModifierType(modifierTypes.RARER_CANDY, (party: Pokemon[]) => globalScene.eventManager.isEventActive() ? 6 : 4),
new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, skipInLastClassicWaveOrDefault(2)),
new WeightedModifierType(modifierTypes.IV_SCANNER, skipInLastClassicWaveOrDefault(4)),
new WeightedModifierType(modifierTypes.EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
new WeightedModifierType(modifierTypes.EXP_SHARE, skipInLastClassicWaveOrDefault(10)),
new WeightedModifierType(modifierTypes.EXP_BALANCE, skipInLastClassicWaveOrDefault(3)),
new WeightedModifierType(modifierTypes.TERA_ORB, (party: Pokemon[]) => Math.min(Math.max(Math.floor(gScene.currentBattle.waveIndex / 50) * 2, 1), 4), 4),
new WeightedModifierType(modifierTypes.TERA_ORB, (party: Pokemon[]) => Math.min(Math.max(Math.floor(globalScene.currentBattle.waveIndex / 50) * 2, 1), 4), 4),
new WeightedModifierType(modifierTypes.QUICK_CLAW, 3),
new WeightedModifierType(modifierTypes.WIDE_LENS, 4),
].map(m => {
@ -1767,16 +1767,16 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.BATON, 2),
new WeightedModifierType(modifierTypes.SOUL_DEW, 7),
//new WeightedModifierType(modifierTypes.OVAL_CHARM, 6),
new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => gScene.eventManager.isEventActive() ? 0 : 4),
new WeightedModifierType(modifierTypes.SOOTHE_BELL, (party: Pokemon[]) => globalScene.eventManager.isEventActive() ? 0 : 4),
new WeightedModifierType(modifierTypes.ABILITY_CHARM, skipInClassicAfterWave(189, 6)),
new WeightedModifierType(modifierTypes.FOCUS_BAND, 5),
new WeightedModifierType(modifierTypes.KINGS_ROCK, 3),
new WeightedModifierType(modifierTypes.LOCK_CAPSULE, (party: Pokemon[]) => gScene.gameMode.isClassic ? 0 : 3),
new WeightedModifierType(modifierTypes.LOCK_CAPSULE, (party: Pokemon[]) => globalScene.gameMode.isClassic ? 0 : 3),
new WeightedModifierType(modifierTypes.SUPER_EXP_CHARM, skipInLastClassicWaveOrDefault(8)),
new WeightedModifierType(modifierTypes.RARE_FORM_CHANGE_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(gScene.currentBattle.waveIndex / 50), 4) * 6, 24),
new WeightedModifierType(modifierTypes.MEGA_BRACELET, (party: Pokemon[]) => Math.min(Math.ceil(gScene.currentBattle.waveIndex / 50), 4) * 9, 36),
new WeightedModifierType(modifierTypes.DYNAMAX_BAND, (party: Pokemon[]) => Math.min(Math.ceil(gScene.currentBattle.waveIndex / 50), 4) * 9, 36),
new WeightedModifierType(modifierTypes.VOUCHER_PLUS, (party: Pokemon[], rerollCount: integer) => !gScene.gameMode.isDaily ? Math.max(3 - rerollCount * 1, 0) : 0, 3),
new WeightedModifierType(modifierTypes.RARE_FORM_CHANGE_ITEM, (party: Pokemon[]) => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 6, 24),
new WeightedModifierType(modifierTypes.MEGA_BRACELET, (party: Pokemon[]) => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9, 36),
new WeightedModifierType(modifierTypes.DYNAMAX_BAND, (party: Pokemon[]) => Math.min(Math.ceil(globalScene.currentBattle.waveIndex / 50), 4) * 9, 36),
new WeightedModifierType(modifierTypes.VOUCHER_PLUS, (party: Pokemon[], rerollCount: integer) => !globalScene.gameMode.isDaily ? Math.max(3 - rerollCount * 1, 0) : 0, 3),
].map(m => {
m.setTier(ModifierTier.ROGUE); return m;
}),
@ -1786,9 +1786,9 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.HEALING_CHARM, 18),
new WeightedModifierType(modifierTypes.MULTI_LENS, 18),
new WeightedModifierType(modifierTypes.VOUCHER_PREMIUM, (party: Pokemon[], rerollCount: integer) =>
!gScene.gameMode.isDaily && !gScene.gameMode.isEndless && !gScene.gameMode.isSplicedOnly ? Math.max(5 - rerollCount * 2, 0) : 0, 5),
new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => !gScene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 24 : 0, 24),
new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, (party: Pokemon[]) => (gScene.gameMode.isDaily || (!gScene.gameMode.isFreshStartChallenge() && gScene.gameData.isUnlocked(Unlockables.MINI_BLACK_HOLE))) ? 1 : 0, 1),
!globalScene.gameMode.isDaily && !globalScene.gameMode.isEndless && !globalScene.gameMode.isSplicedOnly ? Math.max(5 - rerollCount * 2, 0) : 0, 5),
new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => !globalScene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 24 : 0, 24),
new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, (party: Pokemon[]) => (globalScene.gameMode.isDaily || (!globalScene.gameMode.isFreshStartChallenge() && globalScene.gameData.isUnlocked(Unlockables.MINI_BLACK_HOLE))) ? 1 : 0, 1),
].map(m => {
m.setTier(ModifierTier.MASTER); return m;
})
@ -2001,7 +2001,7 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod
let i = 0;
pool[t].reduce((total: integer, modifierType: WeightedModifierType) => {
const weightedModifierType = modifierType as WeightedModifierType;
const existingModifiers = gScene.findModifiers(m => m.type.id === weightedModifierType.modifierType.id, poolType === ModifierPoolType.PLAYER);
const existingModifiers = globalScene.findModifiers(m => m.type.id === weightedModifierType.modifierType.id, poolType === ModifierPoolType.PLAYER);
const itemModifierType = weightedModifierType.modifierType instanceof ModifierTypeGenerator
? weightedModifierType.modifierType.generateType(party)
: weightedModifierType.modifierType;
@ -2438,11 +2438,11 @@ export class ModifierTypeOption {
* @returns A number between 0 and 14 based on the party's total luck value, or a random number between 0 and 14 if the player is in Daily Run mode.
*/
export function getPartyLuckValue(party: Pokemon[]): integer {
if (gScene.gameMode.isDaily) {
if (globalScene.gameMode.isDaily) {
const DailyLuck = new NumberHolder(0);
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
DailyLuck.value = randSeedInt(15); // Random number between 0 and 14
}, 0, gScene.seed);
}, 0, globalScene.seed);
return DailyLuck.value;
}
const luck = Phaser.Math.Clamp(party.map(p => p.isAllowedInBattle() ? p.getLuck() : 0)

View File

@ -30,7 +30,7 @@ import i18next from "i18next";
import { type DoubleBattleChanceBoosterModifierType, type EvolutionItemModifierType, type FormChangeItemModifierType, type ModifierOverride, type ModifierType, type PokemonBaseStatTotalModifierType, type PokemonExpBoosterModifierType, type PokemonFriendshipBoosterModifierType, type PokemonMoveAccuracyBoosterModifierType, type PokemonMultiHitModifierType, type TerastallizeModifierType, type TmModifierType, getModifierType, ModifierPoolType, ModifierTypeGenerator, modifierTypes, PokemonHeldItemModifierType } from "./modifier-type";
import { Color, ShadowColor } from "#enums/color";
import { FRIENDSHIP_GAIN_FROM_RARE_CANDY } from "#app/data/balance/starters";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export type ModifierPredicate = (modifier: Modifier) => boolean;
@ -65,7 +65,7 @@ export class ModifierBar extends Phaser.GameObjects.Container {
private modifierCache: PersistentModifier[];
constructor(enemy?: boolean) {
super(gScene, 1 + (enemy ? 302 : 0), 2);
super(globalScene, 1 + (enemy ? 302 : 0), 2);
this.player = !enemy;
this.setScale(0.5);
@ -96,13 +96,13 @@ export class ModifierBar extends Phaser.GameObjects.Container {
this.setModifierIconPosition(icon, sortedVisibleIconModifiers.length);
icon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 32, 24), Phaser.Geom.Rectangle.Contains);
icon.on("pointerover", () => {
gScene.ui.showTooltip(modifier.type.name, modifier.type.getDescription());
globalScene.ui.showTooltip(modifier.type.name, modifier.type.getDescription());
if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) {
thisArg.updateModifierOverflowVisibility(true);
}
});
icon.on("pointerout", () => {
gScene.ui.hideTooltip();
globalScene.ui.hideTooltip();
if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) {
thisArg.updateModifierOverflowVisibility(false);
}
@ -215,9 +215,9 @@ export abstract class PersistentModifier extends Modifier {
}
getIcon(forSummary?: boolean): Phaser.GameObjects.Container {
const container = gScene.add.container(0, 0);
const container = globalScene.add.container(0, 0);
const item = gScene.add.sprite(0, 12, "items");
const item = globalScene.add.sprite(0, 12, "items");
item.setFrame(this.type.iconImage);
item.setOrigin(0, 0.5);
container.add(item);
@ -240,7 +240,7 @@ export abstract class PersistentModifier extends Modifier {
return null;
}
const text = gScene.add.bitmapText(10, 15, "item-count", this.stackCount.toString(), 11);
const text = globalScene.add.bitmapText(10, 15, "item-count", this.stackCount.toString(), 11);
text.letterSpacing = -0.5;
if (this.getStackCount() >= this.getMaxStackCount()) {
text.setTint(0xf89890);
@ -278,7 +278,7 @@ export class AddPokeballModifier extends ConsumableModifier {
* @returns always `true`
*/
override apply(): boolean {
const pokeballCounts = gScene.pokeballCounts;
const pokeballCounts = globalScene.pokeballCounts;
pokeballCounts[this.pokeballType] = Math.min(pokeballCounts[this.pokeballType] + this.count, MAX_PER_TYPE_POKEBALLS);
return true;
@ -302,7 +302,7 @@ export class AddVoucherModifier extends ConsumableModifier {
* @returns always `true`
*/
override apply(): boolean {
const voucherCounts = gScene.gameData.voucherCounts;
const voucherCounts = globalScene.gameData.voucherCounts;
voucherCounts[this.voucherType] += this.count;
return true;
@ -348,7 +348,7 @@ export abstract class LapsingPersistentModifier extends PersistentModifier {
const modifierInstance = modifier as LapsingPersistentModifier;
if (modifierInstance.getBattleCount() < modifierInstance.getMaxBattles()) {
modifierInstance.resetBattleCount();
gScene.playSound("se/restore");
globalScene.playSound("se/restore");
return true;
}
// should never get here
@ -684,17 +684,17 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
}
getIcon(forSummary?: boolean): Phaser.GameObjects.Container {
const container = !forSummary ? gScene.add.container(0, 0) : super.getIcon();
const container = !forSummary ? globalScene.add.container(0, 0) : super.getIcon();
if (!forSummary) {
const pokemon = this.getPokemon();
if (pokemon) {
const pokemonIcon = gScene.addPokemonIcon(pokemon, -2, 10, 0, 0.5);
const pokemonIcon = globalScene.addPokemonIcon(pokemon, -2, 10, 0, 0.5);
container.add(pokemonIcon);
container.setName(pokemon.id.toString());
}
const item = gScene.add.sprite(16, this.virtualStackCount ? 8 : 16, "items");
const item = globalScene.add.sprite(16, this.virtualStackCount ? 8 : 16, "items");
item.setScale(0.5);
item.setOrigin(0, 0.5);
item.setTexture("items", this.type.iconImage);
@ -717,7 +717,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
}
getPokemon(): Pokemon | undefined {
return this.pokemonId ? gScene.getPokemonById(this.pokemonId) ?? undefined : undefined;
return this.pokemonId ? globalScene.getPokemonById(this.pokemonId) ?? undefined : undefined;
}
getScoreMultiplier(): number {
@ -746,7 +746,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
return 0;
}
if (pokemon.isPlayer() && forThreshold) {
return gScene.getParty().map(p => this.getMaxHeldItemCount(p)).reduce((stackCount: number, maxStackCount: number) => Math.max(stackCount, maxStackCount), 0);
return globalScene.getParty().map(p => this.getMaxHeldItemCount(p)).reduce((stackCount: number, maxStackCount: number) => Math.max(stackCount, maxStackCount), 0);
}
return this.getMaxHeldItemCount(pokemon);
}
@ -835,10 +835,10 @@ export class TerastallizeModifier extends LapsingPokemonHeldItemModifier {
*/
override apply(pokemon: Pokemon): boolean {
if (pokemon.isPlayer()) {
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeTeraTrigger);
gScene.validateAchv(achvs.TERASTALLIZE);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeTeraTrigger);
globalScene.validateAchv(achvs.TERASTALLIZE);
if (this.teraType === Type.STELLAR) {
gScene.validateAchv(achvs.STELLAR_TERASTALLIZE);
globalScene.validateAchv(achvs.STELLAR_TERASTALLIZE);
}
}
pokemon.updateSpritePipelineData();
@ -853,7 +853,7 @@ export class TerastallizeModifier extends LapsingPokemonHeldItemModifier {
public override lapse(pokemon: Pokemon): boolean {
const ret = super.lapse(pokemon);
if (!ret) {
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeLapseTeraTrigger);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeLapseTeraTrigger);
pokemon.updateSpritePipelineData();
}
return ret;
@ -964,14 +964,14 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier {
return null;
}
const pokemon = gScene.getPokemonById(this.pokemonId);
const pokemon = globalScene.getPokemonById(this.pokemonId);
this.stackCount = pokemon
? pokemon.evoCounter + pokemon.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
+ gScene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length
+ globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length
: this.stackCount;
const text = gScene.add.bitmapText(10, 15, "item-count", this.stackCount.toString(), 11);
const text = globalScene.add.bitmapText(10, 15, "item-count", this.stackCount.toString(), 11);
text.letterSpacing = -0.5;
if (this.getStackCount() >= this.required) {
text.setTint(0xf89890);
@ -983,7 +983,7 @@ export class EvoTrackerModifier extends PokemonHeldItemModifier {
getMaxHeldItemCount(pokemon: Pokemon): number {
this.stackCount = pokemon.evoCounter + pokemon.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
+ gScene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length;
+ globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier || m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length;
return 999;
}
}
@ -1551,7 +1551,7 @@ export class SurviveDamageModifier extends PokemonHeldItemModifier {
if (!surviveDamage.value && pokemon.randSeedInt(10) < this.getStackCount()) {
surviveDamage.value = true;
gScene.queueMessage(i18next.t("modifier:surviveDamageApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }));
globalScene.queueMessage(i18next.t("modifier:surviveDamageApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }));
return true;
}
@ -1595,11 +1595,11 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier {
override apply(pokemon: Pokemon, doBypassSpeed: BooleanHolder): boolean {
if (!doBypassSpeed.value && pokemon.randSeedInt(10) < this.getStackCount()) {
doBypassSpeed.value = true;
const isCommandFight = gScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT;
const isCommandFight = globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT;
const hasQuickClaw = this.type instanceof PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW";
if (isCommandFight && hasQuickClaw) {
gScene.queueMessage(i18next.t("modifier:bypassSpeedChanceApply", { pokemonName: getPokemonNameWithAffix(pokemon), itemName: i18next.t("modifierType:ModifierType.QUICK_CLAW.name") }));
globalScene.queueMessage(i18next.t("modifier:bypassSpeedChanceApply", { pokemonName: getPokemonNameWithAffix(pokemon), itemName: i18next.t("modifierType:ModifierType.QUICK_CLAW.name") }));
}
return true;
}
@ -1675,7 +1675,7 @@ export class TurnHealModifier extends PokemonHeldItemModifier {
*/
override apply(pokemon: Pokemon): boolean {
if (!pokemon.isFullHp()) {
gScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
toDmgValue(pokemon.getMaxHp() / 16) * this.stackCount, i18next.t("modifier:turnHealApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }), true));
return true;
}
@ -1767,7 +1767,7 @@ export class HitHealModifier extends PokemonHeldItemModifier {
*/
override apply(pokemon: Pokemon): boolean {
if (pokemon.turnData.damageDealt && !pokemon.isFullHp()) {
gScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
toDmgValue(pokemon.turnData.damageDealt / 8) * this.stackCount, i18next.t("modifier:hitHealApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }), true));
}
@ -1856,7 +1856,7 @@ export class BerryModifier extends PokemonHeldItemModifier {
*/
override apply(pokemon: Pokemon): boolean {
const preserve = new BooleanHolder(false);
gScene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve);
globalScene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve);
getBerryEffectFunc(this.berryType)(pokemon);
if (!preserve.value) {
@ -1935,7 +1935,7 @@ export class PokemonInstantReviveModifier extends PokemonHeldItemModifier {
* @returns always `true`
*/
override apply(pokemon: Pokemon): boolean {
gScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(pokemon.getBattlerIndex(),
toDmgValue(pokemon.getMaxHp() / 2), i18next.t("modifier:pokemonInstantReviveApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }), false, false, true));
pokemon.resetStatus(true, false, true);
@ -1983,7 +1983,7 @@ export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier {
}
if (statRestored) {
gScene.queueMessage(i18next.t("modifier:resetNegativeStatStageApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }));
globalScene.queueMessage(i18next.t("modifier:resetNegativeStatStageApply", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), typeName: this.type.name }));
}
return statRestored;
}
@ -2020,7 +2020,7 @@ export abstract class ConsumablePokemonModifier extends ConsumableModifier {
abstract override apply(playerPokemon: PlayerPokemon, ...args: unknown[]): boolean | Promise<boolean>;
getPokemon() {
return gScene.getParty().find(p => p.id === this.pokemonId);
return globalScene.getParty().find(p => p.id === this.pokemonId);
}
}
@ -2189,11 +2189,11 @@ export class PokemonNatureChangeModifier extends ConsumablePokemonModifier {
override apply(playerPokemon: PlayerPokemon): boolean {
playerPokemon.customPokemonData.nature = this.nature;
let speciesId = playerPokemon.species.speciesId;
gScene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1);
globalScene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1);
while (pokemonPrevolutions.hasOwnProperty(speciesId)) {
speciesId = pokemonPrevolutions[speciesId];
gScene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1);
globalScene.gameData.dexData[speciesId].natureAttr |= 1 << (this.nature + 1);
}
return true;
@ -2212,17 +2212,17 @@ export class PokemonLevelIncrementModifier extends ConsumablePokemonModifier {
* @returns always `true`
*/
override apply(playerPokemon: PlayerPokemon, levelCount: NumberHolder = new NumberHolder(1)): boolean {
gScene.applyModifiers(LevelIncrementBoosterModifier, true, levelCount);
globalScene.applyModifiers(LevelIncrementBoosterModifier, true, levelCount);
playerPokemon.level += levelCount.value;
if (playerPokemon.level <= gScene.getMaxExpLevel(true)) {
if (playerPokemon.level <= globalScene.getMaxExpLevel(true)) {
playerPokemon.exp = getLevelTotalExp(playerPokemon.level, playerPokemon.species.growthRate);
playerPokemon.levelExp = 0;
}
playerPokemon.addFriendship(FRIENDSHIP_GAIN_FROM_RARE_CANDY);
gScene.unshiftPhase(new LevelUpPhase(gScene.getParty().indexOf(playerPokemon), playerPokemon.level - levelCount.value, playerPokemon.level));
globalScene.unshiftPhase(new LevelUpPhase(globalScene.getParty().indexOf(playerPokemon), playerPokemon.level - levelCount.value, playerPokemon.level));
return true;
}
@ -2242,7 +2242,7 @@ export class TmModifier extends ConsumablePokemonModifier {
*/
override apply(playerPokemon: PlayerPokemon): boolean {
gScene.unshiftPhase(new LearnMovePhase(gScene.getParty().indexOf(playerPokemon), this.type.moveId, LearnMoveType.TM));
globalScene.unshiftPhase(new LearnMovePhase(globalScene.getParty().indexOf(playerPokemon), this.type.moveId, LearnMoveType.TM));
return true;
}
@ -2264,7 +2264,7 @@ export class RememberMoveModifier extends ConsumablePokemonModifier {
*/
override apply(playerPokemon: PlayerPokemon, cost?: number): boolean {
gScene.unshiftPhase(new LearnMovePhase(gScene.getParty().indexOf(playerPokemon), playerPokemon.getLearnableLevelMoves()[this.levelMoveIndex], LearnMoveType.MEMORY, cost));
globalScene.unshiftPhase(new LearnMovePhase(globalScene.getParty().indexOf(playerPokemon), playerPokemon.getLearnableLevelMoves()[this.levelMoveIndex], LearnMoveType.MEMORY, cost));
return true;
}
@ -2299,7 +2299,7 @@ export class EvolutionItemModifier extends ConsumablePokemonModifier {
}
if (matchingEvolution) {
gScene.unshiftPhase(new EvolutionPhase(playerPokemon, matchingEvolution, playerPokemon.level - 1));
globalScene.unshiftPhase(new EvolutionPhase(playerPokemon, matchingEvolution, playerPokemon.level - 1));
return true;
}
@ -2746,7 +2746,7 @@ export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier {
this.active = false;
}
const ret = gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger);
const ret = globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger);
if (switchActive) {
this.active = true;
@ -2774,17 +2774,17 @@ export class MoneyRewardModifier extends ConsumableModifier {
* @returns always `true`
*/
override apply(): boolean {
const moneyAmount = new NumberHolder(gScene.getWaveMoneyAmount(this.moneyMultiplier));
const moneyAmount = new NumberHolder(globalScene.getWaveMoneyAmount(this.moneyMultiplier));
gScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
gScene.addMoney(moneyAmount.value);
globalScene.addMoney(moneyAmount.value);
gScene.getParty().map(p => {
globalScene.getParty().map(p => {
if (p.species?.speciesId === Species.GIMMIGHOUL || p.fusionSpecies?.speciesId === Species.GIMMIGHOUL) {
p.evoCounter ? p.evoCounter++ : p.evoCounter = 1;
const modifier = getModifierType(modifierTypes.EVOLUTION_TRACKER_GIMMIGHOUL).newModifier(p) as EvoTrackerModifier;
gScene.addModifier(modifier);
globalScene.addModifier(modifier);
}
});
@ -2842,8 +2842,8 @@ export class DamageMoneyRewardModifier extends PokemonHeldItemModifier {
*/
override apply(pokemon: Pokemon, multiplier: NumberHolder): boolean {
const moneyAmount = new NumberHolder(Math.floor(multiplier.value * (0.5 * this.getStackCount())));
gScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
gScene.addMoney(moneyAmount.value);
globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
globalScene.addMoney(moneyAmount.value);
return true;
}
@ -2867,13 +2867,13 @@ export class MoneyInterestModifier extends PersistentModifier {
* @returns always `true`
*/
override apply(): boolean {
const interestAmount = Math.floor(gScene.money * 0.1 * this.getStackCount());
gScene.addMoney(interestAmount);
const interestAmount = Math.floor(globalScene.money * 0.1 * this.getStackCount());
globalScene.addMoney(interestAmount);
const userLocale = navigator.language || "en-US";
const formattedMoneyAmount = interestAmount.toLocaleString(userLocale);
const message = i18next.t("modifier:moneyInterestApply", { moneyAmount: formattedMoneyAmount, typeName: this.type.name });
gScene.queueMessage(message, undefined, true);
globalScene.queueMessage(message, undefined, true);
return true;
}
@ -3110,7 +3110,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
const poolType = pokemon.isPlayer() ? ModifierPoolType.PLAYER : pokemon.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD;
const transferredModifierTypes: ModifierType[] = [];
const itemModifiers = gScene.findModifiers(m => m instanceof PokemonHeldItemModifier
const itemModifiers = globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& m.pokemonId === targetPokemon.id && m.isTransferable, 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);
@ -3128,7 +3128,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
}
const randItemIndex = pokemon.randSeedInt(itemModifiers.length);
const randItem = itemModifiers[randItemIndex];
heldItemTransferPromises.push(gScene.tryTransferHeldItemModifier(randItem, pokemon, false).then(success => {
heldItemTransferPromises.push(globalScene.tryTransferHeldItemModifier(randItem, pokemon, false).then(success => {
if (success) {
transferredModifierTypes.push(randItem.type);
itemModifiers.splice(randItemIndex, 1);
@ -3138,7 +3138,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
Promise.all(heldItemTransferPromises).then(() => {
for (const mt of transferredModifierTypes) {
gScene.queueMessage(this.getTransferMessage(pokemon, targetPokemon, mt));
globalScene.queueMessage(this.getTransferMessage(pokemon, targetPokemon, mt));
}
});
@ -3317,7 +3317,7 @@ export class TempExtraModifierModifier extends LapsingPersistentModifier {
const newBattleCount = this.getMaxBattles() + modifierInstance.getBattleCount();
modifierInstance.setNewBattleCount(newBattleCount);
gScene.playSound("se/restore");
globalScene.playSound("se/restore");
return true;
}
}
@ -3422,7 +3422,7 @@ export class EnemyDamageReducerModifier extends EnemyDamageMultiplierModifier {
}
getMaxStackCount(): number {
return gScene.currentBattle.waveIndex < 2000 ? super.getMaxStackCount() : 999;
return globalScene.currentBattle.waveIndex < 2000 ? super.getMaxStackCount() : 999;
}
}
@ -3455,7 +3455,7 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier {
*/
override apply(enemyPokemon: Pokemon): boolean {
if (!enemyPokemon.isFullHp()) {
gScene.unshiftPhase(new PokemonHealPhase(enemyPokemon.getBattlerIndex(),
globalScene.unshiftPhase(new PokemonHealPhase(enemyPokemon.getBattlerIndex(),
Math.max(Math.floor(enemyPokemon.getMaxHp() / (100 / this.healPercent)) * this.stackCount, 1), i18next.t("modifier:enemyTurnHealApply", { pokemonNameWithAffix: getPokemonNameWithAffix(enemyPokemon) }), true, false, false, false, true));
return true;
}
@ -3539,7 +3539,7 @@ export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier
*/
override apply(enemyPokemon: Pokemon): boolean {
if (enemyPokemon.status && Phaser.Math.RND.realInRange(0, 1) < (this.chance * this.getStackCount())) {
gScene.queueMessage(getStatusEffectHealText(enemyPokemon.status.effect, getPokemonNameWithAffix(enemyPokemon)));
globalScene.queueMessage(getStatusEffectHealText(enemyPokemon.status.effect, getPokemonNameWithAffix(enemyPokemon)));
enemyPokemon.resetStatus();
enemyPokemon.updateInfo();
return true;
@ -3647,13 +3647,13 @@ export class EnemyFusionChanceModifier extends EnemyPersistentModifier {
*/
export function overrideModifiers(isPlayer: boolean = true): void {
const modifiersOverride: ModifierOverride[] = isPlayer ? Overrides.STARTING_MODIFIER_OVERRIDE : Overrides.OPP_MODIFIER_OVERRIDE;
if (!modifiersOverride || modifiersOverride.length === 0 || !gScene) {
if (!modifiersOverride || modifiersOverride.length === 0 || !globalScene) {
return;
}
// If it's the opponent, clear all of their current modifiers to avoid stacking
if (!isPlayer) {
gScene.clearEnemyModifiers();
globalScene.clearEnemyModifiers();
}
modifiersOverride.forEach(item => {
@ -3670,9 +3670,9 @@ export function overrideModifiers(isPlayer: boolean = true): void {
modifier.stackCount = item.count || 1;
if (isPlayer) {
gScene.addModifier(modifier, true, false, false, true);
globalScene.addModifier(modifier, true, false, false, true);
} else {
gScene.addEnemyModifier(modifier, true, true);
globalScene.addEnemyModifier(modifier, true, true);
}
}
});
@ -3688,12 +3688,12 @@ export function overrideModifiers(isPlayer: boolean = true): void {
*/
export function overrideHeldItems(pokemon: Pokemon, isPlayer: boolean = true): void {
const heldItemsOverride: ModifierOverride[] = isPlayer ? Overrides.STARTING_HELD_ITEMS_OVERRIDE : Overrides.OPP_HELD_ITEMS_OVERRIDE;
if (!heldItemsOverride || heldItemsOverride.length === 0 || !gScene) {
if (!heldItemsOverride || heldItemsOverride.length === 0 || !globalScene) {
return;
}
if (!isPlayer) {
gScene.clearEnemyHeldItemModifiers(pokemon);
globalScene.clearEnemyHeldItemModifiers(pokemon);
}
heldItemsOverride.forEach(item => {
@ -3711,9 +3711,9 @@ export function overrideHeldItems(pokemon: Pokemon, isPlayer: boolean = true): v
heldItemModifier.pokemonId = pokemon.id;
heldItemModifier.stackCount = qty;
if (isPlayer) {
gScene.addModifier(heldItemModifier, true, false, false, true);
globalScene.addModifier(heldItemModifier, true, false, false, true);
} else {
gScene.addEnemyModifier(heldItemModifier, true, true);
globalScene.addEnemyModifier(heldItemModifier, true, true);
}
}
});

View File

@ -1,13 +1,13 @@
import { gScene } from "./battle-scene";
import { globalScene } from "./battle-scene";
export class Phase {
start() {
if (gScene.abilityBar.shown) {
gScene.abilityBar.resetAutoHideTimer();
if (globalScene.abilityBar.shown) {
globalScene.abilityBar.resetAutoHideTimer();
}
}
end() {
gScene.shiftPhase();
globalScene.shiftPhase();
}
}

View File

@ -2,7 +2,7 @@ import { ModifierTier } from "#app/modifier/modifier-tier";
import { regenerateModifierPoolThresholds, ModifierPoolType, getEnemyBuffModifierForWave } from "#app/modifier/modifier-type";
import { EnemyPersistentModifier } from "#app/modifier/modifier";
import { Phase } from "#app/phase";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export class AddEnemyBuffModifierPhase extends Phase {
constructor() {
@ -12,15 +12,15 @@ export class AddEnemyBuffModifierPhase extends Phase {
start() {
super.start();
const waveIndex = gScene.currentBattle.waveIndex;
const waveIndex = globalScene.currentBattle.waveIndex;
const tier = !(waveIndex % 1000) ? ModifierTier.ULTRA : !(waveIndex % 250) ? ModifierTier.GREAT : ModifierTier.COMMON;
regenerateModifierPoolThresholds(gScene.getEnemyParty(), ModifierPoolType.ENEMY_BUFF);
regenerateModifierPoolThresholds(globalScene.getEnemyParty(), ModifierPoolType.ENEMY_BUFF);
const count = Math.ceil(waveIndex / 250);
for (let i = 0; i < count; i++) {
gScene.addEnemyModifier(getEnemyBuffModifierForWave(tier, gScene.findModifiers(m => m instanceof EnemyPersistentModifier, false)), true, true);
globalScene.addEnemyModifier(getEnemyBuffModifierForWave(tier, globalScene.findModifiers(m => m instanceof EnemyPersistentModifier, false)), true, true);
}
gScene.updateModifiers(false, true).then(() => this.end());
globalScene.updateModifiers(false, true).then(() => this.end());
}
}

View File

@ -15,7 +15,7 @@ import i18next from "i18next";
import { PokemonPhase } from "./pokemon-phase";
import { VictoryPhase } from "./victory-phase";
import { SubstituteTag } from "#app/data/battler-tags";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export class AttemptCapturePhase extends PokemonPhase {
private pokeballType: PokeballType;
@ -42,7 +42,7 @@ export class AttemptCapturePhase extends PokemonPhase {
substitute.sprite.setVisible(false);
}
gScene.pokeballCounts[this.pokeballType]--;
globalScene.pokeballCounts[this.pokeballType]--;
this.originalY = pokemon.y;
@ -56,29 +56,29 @@ export class AttemptCapturePhase extends PokemonPhase {
const fpOffset = pokemon.getFieldPositionOffset();
const pokeballAtlasKey = getPokeballAtlasKey(this.pokeballType);
this.pokeball = gScene.addFieldSprite(16, 80, "pb", pokeballAtlasKey);
this.pokeball = globalScene.addFieldSprite(16, 80, "pb", pokeballAtlasKey);
this.pokeball.setOrigin(0.5, 0.625);
gScene.field.add(this.pokeball);
globalScene.field.add(this.pokeball);
gScene.playSound("se/pb_throw");
gScene.time.delayedCall(300, () => {
gScene.field.moveBelow(this.pokeball as Phaser.GameObjects.GameObject, pokemon);
globalScene.playSound("se/pb_throw");
globalScene.time.delayedCall(300, () => {
globalScene.field.moveBelow(this.pokeball as Phaser.GameObjects.GameObject, pokemon);
});
gScene.tweens.add({
globalScene.tweens.add({
targets: this.pokeball,
x: { value: 236 + fpOffset[0], ease: "Linear" },
y: { value: 16 + fpOffset[1], ease: "Cubic.easeOut" },
duration: 500,
onComplete: () => {
this.pokeball.setTexture("pb", `${pokeballAtlasKey}_opening`);
gScene.time.delayedCall(17, () => this.pokeball.setTexture("pb", `${pokeballAtlasKey}_open`));
gScene.playSound("se/pb_rel");
globalScene.time.delayedCall(17, () => this.pokeball.setTexture("pb", `${pokeballAtlasKey}_open`));
globalScene.playSound("se/pb_rel");
pokemon.tint(getPokeballTintColor(this.pokeballType));
addPokeballOpenParticles(this.pokeball.x, this.pokeball.y, this.pokeballType);
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemon,
duration: 500,
ease: "Sine.easeIn",
@ -87,13 +87,13 @@ export class AttemptCapturePhase extends PokemonPhase {
onComplete: () => {
this.pokeball.setTexture("pb", `${pokeballAtlasKey}_opening`);
pokemon.setVisible(false);
gScene.playSound("se/pb_catch");
gScene.time.delayedCall(17, () => this.pokeball.setTexture("pb", `${pokeballAtlasKey}`));
globalScene.playSound("se/pb_catch");
globalScene.time.delayedCall(17, () => this.pokeball.setTexture("pb", `${pokeballAtlasKey}`));
const doShake = () => {
let shakeCount = 0;
const pbX = this.pokeball.x;
const shakeCounter = gScene.tweens.addCounter({
const shakeCounter = globalScene.tweens.addCounter({
from: 0,
to: 1,
repeat: 4,
@ -115,27 +115,27 @@ export class AttemptCapturePhase extends PokemonPhase {
this.failCatch(shakeCount);
} else if (shakeCount++ < 3) {
if (pokeballMultiplier === -1 || pokemon.randSeedInt(65536) < y) {
gScene.playSound("se/pb_move");
globalScene.playSound("se/pb_move");
} else {
shakeCounter.stop();
this.failCatch(shakeCount);
}
} else {
gScene.playSound("se/pb_lock");
globalScene.playSound("se/pb_lock");
addPokeballCaptureStars(this.pokeball);
const pbTint = gScene.add.sprite(this.pokeball.x, this.pokeball.y, "pb", "pb");
const pbTint = globalScene.add.sprite(this.pokeball.x, this.pokeball.y, "pb", "pb");
pbTint.setOrigin(this.pokeball.originX, this.pokeball.originY);
pbTint.setTintFill(0);
pbTint.setAlpha(0);
gScene.field.add(pbTint);
gScene.tweens.add({
globalScene.field.add(pbTint);
globalScene.tweens.add({
targets: pbTint,
alpha: 0.375,
duration: 200,
easing: "Sine.easeOut",
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: pbTint,
alpha: 0,
duration: 200,
@ -152,7 +152,7 @@ export class AttemptCapturePhase extends PokemonPhase {
});
};
gScene.time.delayedCall(250, () => doPokeballBounceAnim(this.pokeball, 16, 72, 350, doShake));
globalScene.time.delayedCall(250, () => doPokeballBounceAnim(this.pokeball, 16, 72, 350, doShake));
}
});
}
@ -162,7 +162,7 @@ export class AttemptCapturePhase extends PokemonPhase {
failCatch(shakeCount: integer) {
const pokemon = this.getPokemon();
gScene.playSound("se/pb_rel");
globalScene.playSound("se/pb_rel");
pokemon.setY(this.originalY);
if (pokemon.status?.effect !== StatusEffect.SLEEP) {
pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 });
@ -178,16 +178,16 @@ export class AttemptCapturePhase extends PokemonPhase {
const pokeballAtlasKey = getPokeballAtlasKey(this.pokeballType);
this.pokeball.setTexture("pb", `${pokeballAtlasKey}_opening`);
gScene.time.delayedCall(17, () => this.pokeball.setTexture("pb", `${pokeballAtlasKey}_open`));
globalScene.time.delayedCall(17, () => this.pokeball.setTexture("pb", `${pokeballAtlasKey}_open`));
gScene.tweens.add({
globalScene.tweens.add({
targets: pokemon,
duration: 250,
ease: "Sine.easeOut",
scale: 1
});
gScene.currentBattle.lastUsedPokeball = this.pokeballType;
globalScene.currentBattle.lastUsedPokeball = this.pokeballType;
this.removePb();
this.end();
}
@ -198,48 +198,48 @@ export class AttemptCapturePhase extends PokemonPhase {
const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm();
if (speciesForm.abilityHidden && (pokemon.fusionSpecies ? pokemon.fusionAbilityIndex : pokemon.abilityIndex) === speciesForm.getAbilityCount() - 1) {
gScene.validateAchv(achvs.HIDDEN_ABILITY);
globalScene.validateAchv(achvs.HIDDEN_ABILITY);
}
if (pokemon.species.subLegendary) {
gScene.validateAchv(achvs.CATCH_SUB_LEGENDARY);
globalScene.validateAchv(achvs.CATCH_SUB_LEGENDARY);
}
if (pokemon.species.legendary) {
gScene.validateAchv(achvs.CATCH_LEGENDARY);
globalScene.validateAchv(achvs.CATCH_LEGENDARY);
}
if (pokemon.species.mythical) {
gScene.validateAchv(achvs.CATCH_MYTHICAL);
globalScene.validateAchv(achvs.CATCH_MYTHICAL);
}
gScene.pokemonInfoContainer.show(pokemon, true);
globalScene.pokemonInfoContainer.show(pokemon, true);
gScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
globalScene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs);
gScene.ui.showText(i18next.t("battle:pokemonCaught", { pokemonName: getPokemonNameWithAffix(pokemon) }), null, () => {
globalScene.ui.showText(i18next.t("battle:pokemonCaught", { pokemonName: getPokemonNameWithAffix(pokemon) }), null, () => {
const end = () => {
gScene.unshiftPhase(new VictoryPhase(this.battlerIndex));
gScene.pokemonInfoContainer.hide();
globalScene.unshiftPhase(new VictoryPhase(this.battlerIndex));
globalScene.pokemonInfoContainer.hide();
this.removePb();
this.end();
};
const removePokemon = () => {
gScene.addFaintedEnemyScore(pokemon);
gScene.getPlayerField().filter(p => p.isActive(true)).forEach(playerPokemon => playerPokemon.removeTagsBySourceId(pokemon.id));
globalScene.addFaintedEnemyScore(pokemon);
globalScene.getPlayerField().filter(p => p.isActive(true)).forEach(playerPokemon => playerPokemon.removeTagsBySourceId(pokemon.id));
pokemon.hp = 0;
pokemon.trySetStatus(StatusEffect.FAINT);
gScene.clearEnemyHeldItemModifiers();
gScene.field.remove(pokemon, true);
globalScene.clearEnemyHeldItemModifiers();
globalScene.field.remove(pokemon, true);
};
const addToParty = (slotIndex?: number) => {
const newPokemon = pokemon.addToParty(this.pokeballType, slotIndex);
const modifiers = gScene.findModifiers(m => m instanceof PokemonHeldItemModifier, false);
if (gScene.getParty().filter(p => p.isShiny()).length === 6) {
gScene.validateAchv(achvs.SHINY_PARTY);
const modifiers = globalScene.findModifiers(m => m instanceof PokemonHeldItemModifier, false);
if (globalScene.getParty().filter(p => p.isShiny()).length === 6) {
globalScene.validateAchv(achvs.SHINY_PARTY);
}
Promise.all(modifiers.map(m => gScene.addModifier(m, true))).then(() => {
gScene.updateModifiers(true);
Promise.all(modifiers.map(m => globalScene.addModifier(m, true))).then(() => {
globalScene.updateModifiers(true);
removePokemon();
if (newPokemon) {
newPokemon.loadAssets().then(end);
@ -248,21 +248,21 @@ export class AttemptCapturePhase extends PokemonPhase {
}
});
};
Promise.all([ pokemon.hideInfo(), gScene.gameData.setPokemonCaught(pokemon) ]).then(() => {
if (gScene.getParty().length === 6) {
Promise.all([ pokemon.hideInfo(), globalScene.gameData.setPokemonCaught(pokemon) ]).then(() => {
if (globalScene.getParty().length === 6) {
const promptRelease = () => {
gScene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
gScene.pokemonInfoContainer.makeRoomForConfirmUi(1, true);
gScene.ui.setMode(Mode.CONFIRM, () => {
const newPokemon = gScene.addPlayerPokemon(pokemon.species, pokemon.level, pokemon.abilityIndex, pokemon.formIndex, pokemon.gender, pokemon.shiny, pokemon.variant, pokemon.ivs, pokemon.nature, pokemon);
gScene.ui.setMode(Mode.SUMMARY, newPokemon, 0, SummaryUiMode.DEFAULT, () => {
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
globalScene.pokemonInfoContainer.makeRoomForConfirmUi(1, true);
globalScene.ui.setMode(Mode.CONFIRM, () => {
const newPokemon = globalScene.addPlayerPokemon(pokemon.species, pokemon.level, pokemon.abilityIndex, pokemon.formIndex, pokemon.gender, pokemon.shiny, pokemon.variant, pokemon.ivs, pokemon.nature, pokemon);
globalScene.ui.setMode(Mode.SUMMARY, newPokemon, 0, SummaryUiMode.DEFAULT, () => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
promptRelease();
});
}, false);
}, () => {
gScene.ui.setMode(Mode.PARTY, PartyUiMode.RELEASE, this.fieldIndex, (slotIndex: integer, _option: PartyOption) => {
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.PARTY, PartyUiMode.RELEASE, this.fieldIndex, (slotIndex: integer, _option: PartyOption) => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
if (slotIndex < 6) {
addToParty(slotIndex);
} else {
@ -271,7 +271,7 @@ export class AttemptCapturePhase extends PokemonPhase {
});
});
}, () => {
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
removePokemon();
end();
});
@ -287,7 +287,7 @@ export class AttemptCapturePhase extends PokemonPhase {
}
removePb() {
gScene.tweens.add({
globalScene.tweens.add({
targets: this.pokeball,
duration: 250,
delay: 250,

View File

@ -7,7 +7,7 @@ import * as Utils from "#app/utils";
import { BattleEndPhase } from "./battle-end-phase";
import { NewBattlePhase } from "./new-battle-phase";
import { PokemonPhase } from "./pokemon-phase";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export class AttemptRunPhase extends PokemonPhase {
@ -21,8 +21,8 @@ export class AttemptRunPhase extends PokemonPhase {
start() {
super.start();
const playerField = gScene.getPlayerField();
const enemyField = gScene.getEnemyField();
const playerField = globalScene.getPlayerField();
const enemyField = globalScene.getEnemyField();
const playerPokemon = this.getPokemon();
@ -33,18 +33,18 @@ export class AttemptRunPhase extends PokemonPhase {
applyAbAttrs(RunSuccessAbAttr, playerPokemon, null, false, escapeChance);
if (playerPokemon.randSeedInt(100) < escapeChance.value && !this.forceFailEscape) {
gScene.playSound("se/flee");
gScene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);
globalScene.playSound("se/flee");
globalScene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);
gScene.tweens.add({
targets: [ gScene.arenaEnemy, enemyField ].flat(),
globalScene.tweens.add({
targets: [ globalScene.arenaEnemy, enemyField ].flat(),
alpha: 0,
duration: 250,
ease: "Sine.easeIn",
onComplete: () => enemyField.forEach(enemyPokemon => enemyPokemon.destroy())
});
gScene.clearEnemyHeldItemModifiers();
globalScene.clearEnemyHeldItemModifiers();
enemyField.forEach(enemyPokemon => {
enemyPokemon.hideInfo().then(() => enemyPokemon.destroy());
@ -52,11 +52,11 @@ export class AttemptRunPhase extends PokemonPhase {
enemyPokemon.trySetStatus(StatusEffect.FAINT);
});
gScene.pushPhase(new BattleEndPhase());
gScene.pushPhase(new NewBattlePhase());
globalScene.pushPhase(new BattleEndPhase());
globalScene.pushPhase(new NewBattlePhase());
} else {
playerPokemon.turnData.failedRunAway = true;
gScene.queueMessage(i18next.t("battle:runAwayCannotEscape"), null, true, 500);
globalScene.queueMessage(i18next.t("battle:runAwayCannotEscape"), null, true, 500);
}
this.end();
@ -103,6 +103,6 @@ export class AttemptRunPhase extends PokemonPhase {
const escapeSlope = (maxChance - minChance) / speedCap;
// This will calculate the escape chance given all of the above and clamp it to the range of [`minChance`, `maxChance`]
escapeChance.value = Phaser.Math.Clamp(Math.round((escapeSlope * speedRatio) + minChance + (escapeBonus * gScene.currentBattle.escapeAttempts++)), minChance, maxChance);
escapeChance.value = Phaser.Math.Clamp(Math.round((escapeSlope * speedRatio) + minChance + (escapeBonus * globalScene.currentBattle.escapeAttempts++)), minChance, maxChance);
}
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { applyPostBattleAbAttrs, PostBattleAbAttr } from "#app/data/ability";
import { LapsingPersistentModifier, LapsingPokemonHeldItemModifier } from "#app/modifier/modifier";
import { BattlePhase } from "./battle-phase";
@ -18,50 +18,50 @@ export class BattleEndPhase extends BattlePhase {
super.start();
if (this.isVictory) {
gScene.currentBattle.addBattleScore();
globalScene.currentBattle.addBattleScore();
gScene.gameData.gameStats.battles++;
if (gScene.currentBattle.trainer) {
gScene.gameData.gameStats.trainersDefeated++;
globalScene.gameData.gameStats.battles++;
if (globalScene.currentBattle.trainer) {
globalScene.gameData.gameStats.trainersDefeated++;
}
if (gScene.gameMode.isEndless && gScene.currentBattle.waveIndex + 1 > gScene.gameData.gameStats.highestEndlessWave) {
gScene.gameData.gameStats.highestEndlessWave = gScene.currentBattle.waveIndex + 1;
if (globalScene.gameMode.isEndless && globalScene.currentBattle.waveIndex + 1 > globalScene.gameData.gameStats.highestEndlessWave) {
globalScene.gameData.gameStats.highestEndlessWave = globalScene.currentBattle.waveIndex + 1;
}
}
// Endless graceful end
if (gScene.gameMode.isEndless && gScene.currentBattle.waveIndex >= 5850) {
gScene.clearPhaseQueue();
gScene.unshiftPhase(new GameOverPhase(true));
if (globalScene.gameMode.isEndless && globalScene.currentBattle.waveIndex >= 5850) {
globalScene.clearPhaseQueue();
globalScene.unshiftPhase(new GameOverPhase(true));
}
for (const pokemon of gScene.getField()) {
for (const pokemon of globalScene.getField()) {
if (pokemon && pokemon.battleSummonData) {
pokemon.battleSummonData.waveTurnCount = 1;
}
}
for (const pokemon of gScene.getParty().filter(p => p.isAllowedInBattle())) {
for (const pokemon of globalScene.getParty().filter(p => p.isAllowedInBattle())) {
applyPostBattleAbAttrs(PostBattleAbAttr, pokemon);
}
if (gScene.currentBattle.moneyScattered) {
gScene.currentBattle.pickUpScatteredMoney();
if (globalScene.currentBattle.moneyScattered) {
globalScene.currentBattle.pickUpScatteredMoney();
}
gScene.clearEnemyHeldItemModifiers();
globalScene.clearEnemyHeldItemModifiers();
const lapsingModifiers = gScene.findModifiers(m => m instanceof LapsingPersistentModifier || m instanceof LapsingPokemonHeldItemModifier) as (LapsingPersistentModifier | LapsingPokemonHeldItemModifier)[];
const lapsingModifiers = globalScene.findModifiers(m => m instanceof LapsingPersistentModifier || m instanceof LapsingPokemonHeldItemModifier) as (LapsingPersistentModifier | LapsingPokemonHeldItemModifier)[];
for (const m of lapsingModifiers) {
const args: any[] = [];
if (m instanceof LapsingPokemonHeldItemModifier) {
args.push(gScene.getPokemonById(m.pokemonId));
args.push(globalScene.getPokemonById(m.pokemonId));
}
if (!m.lapse(...args)) {
gScene.removeModifier(m);
globalScene.removeModifier(m);
}
}
gScene.updateModifiers().then(() => this.end());
globalScene.updateModifiers().then(() => this.end());
}
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { TrainerSlot } from "#app/data/trainer-config";
import { Phase } from "#app/phase";
@ -8,8 +8,8 @@ export class BattlePhase extends Phase {
}
showEnemyTrainer(trainerSlot: TrainerSlot = TrainerSlot.NONE): void {
const sprites = gScene.currentBattle.trainer?.getSprites()!; // TODO: is this bang correct?
const tintSprites = gScene.currentBattle.trainer?.getTintSprites()!; // TODO: is this bang correct?
const sprites = globalScene.currentBattle.trainer?.getSprites()!; // TODO: is this bang correct?
const tintSprites = globalScene.currentBattle.trainer?.getTintSprites()!; // TODO: is this bang correct?
for (let i = 0; i < sprites.length; i++) {
const visible = !trainerSlot || !i === (trainerSlot === TrainerSlot.TRAINER) || sprites.length < 2;
[ sprites[i], tintSprites[i] ].map(sprite => {
@ -24,8 +24,8 @@ export class BattlePhase extends Phase {
sprites[i].clearTint();
tintSprites[i].clearTint();
}
gScene.tweens.add({
targets: gScene.currentBattle.trainer,
globalScene.tweens.add({
targets: globalScene.currentBattle.trainer,
x: "-=16",
y: "+=16",
alpha: 1,
@ -35,8 +35,8 @@ export class BattlePhase extends Phase {
}
hideEnemyTrainer(): void {
gScene.tweens.add({
targets: gScene.currentBattle.trainer,
globalScene.tweens.add({
targets: globalScene.currentBattle.trainer,
x: "+=16",
y: "-=16",
alpha: 0,

View File

@ -7,7 +7,7 @@ import i18next from "i18next";
import * as Utils from "#app/utils";
import { FieldPhase } from "./field-phase";
import { CommonAnimPhase } from "./common-anim-phase";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
/** The phase after attacks where the pokemon eat berries */
export class BerryPhase extends FieldPhase {
@ -15,7 +15,7 @@ export class BerryPhase extends FieldPhase {
super.start();
this.executeForAll((pokemon) => {
const hasUsableBerry = !!gScene.findModifier((m) => {
const hasUsableBerry = !!globalScene.findModifier((m) => {
return m instanceof BerryModifier && m.shouldApply(pokemon);
}, pokemon.isPlayer());
@ -24,24 +24,24 @@ export class BerryPhase extends FieldPhase {
pokemon.getOpponents().map((opp) => applyAbAttrs(PreventBerryUseAbAttr, opp, cancelled));
if (cancelled.value) {
gScene.queueMessage(i18next.t("abilityTriggers:preventBerryUse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
globalScene.queueMessage(i18next.t("abilityTriggers:preventBerryUse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
} else {
gScene.unshiftPhase(
globalScene.unshiftPhase(
new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM)
);
for (const berryModifier of gScene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) {
for (const berryModifier of globalScene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) {
if (berryModifier.consumed) {
if (!--berryModifier.stackCount) {
gScene.removeModifier(berryModifier);
globalScene.removeModifier(berryModifier);
} else {
berryModifier.consumed = false;
}
}
gScene.eventTarget.dispatchEvent(new BerryUsedEvent(berryModifier)); // Announce a berry was used
globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(berryModifier)); // Announce a berry was used
}
gScene.updateModifiers(pokemon.isPlayer());
globalScene.updateModifiers(pokemon.isPlayer());
applyAbAttrs(HealFromBerryUseAbAttr, pokemon, new Utils.BooleanHolder(false));
}

View File

@ -1,7 +1,7 @@
import { PostTurnStatusEffectPhase } from "#app/phases/post-turn-status-effect-phase";
import { Phase } from "#app/phase";
import { BattlerIndex } from "#app/battle";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
export class CheckStatusEffectPhase extends Phase {
private order : BattlerIndex[];
@ -11,10 +11,10 @@ export class CheckStatusEffectPhase extends Phase {
}
start() {
const field = gScene.getField();
const field = globalScene.getField();
for (const o of this.order) {
if (field[o].status && field[o].status.isPostTurn()) {
gScene.unshiftPhase(new PostTurnStatusEffectPhase(o));
globalScene.unshiftPhase(new PostTurnStatusEffectPhase(o));
}
}
this.end();

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { BattleStyle } from "#app/enums/battle-style";
import { BattlerTagType } from "#app/enums/battler-tag-type";
import { getPokemonNameWithAffix } from "#app/messages";
@ -24,20 +24,20 @@ export class CheckSwitchPhase extends BattlePhase {
start() {
super.start();
const pokemon = gScene.getPlayerField()[this.fieldIndex];
const pokemon = globalScene.getPlayerField()[this.fieldIndex];
if (gScene.battleStyle === BattleStyle.SET) {
if (globalScene.battleStyle === BattleStyle.SET) {
super.end();
return;
}
if (gScene.field.getAll().indexOf(pokemon) === -1) {
gScene.unshiftPhase(new SummonMissingPhase(this.fieldIndex));
if (globalScene.field.getAll().indexOf(pokemon) === -1) {
globalScene.unshiftPhase(new SummonMissingPhase(this.fieldIndex));
super.end();
return;
}
if (!gScene.getParty().slice(1).filter(p => p.isActive()).length) {
if (!globalScene.getParty().slice(1).filter(p => p.isActive()).length) {
super.end();
return;
}
@ -47,14 +47,14 @@ export class CheckSwitchPhase extends BattlePhase {
return;
}
gScene.ui.showText(i18next.t("battle:switchQuestion", { pokemonName: this.useName ? getPokemonNameWithAffix(pokemon) : i18next.t("battle:pokemon") }), null, () => {
gScene.ui.setMode(Mode.CONFIRM, () => {
gScene.ui.setMode(Mode.MESSAGE);
gScene.tryRemovePhase(p => p instanceof PostSummonPhase && p.player && p.fieldIndex === this.fieldIndex);
gScene.unshiftPhase(new SwitchPhase(SwitchType.INITIAL_SWITCH, this.fieldIndex, false, true));
globalScene.ui.showText(i18next.t("battle:switchQuestion", { pokemonName: this.useName ? getPokemonNameWithAffix(pokemon) : i18next.t("battle:pokemon") }), null, () => {
globalScene.ui.setMode(Mode.CONFIRM, () => {
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.tryRemovePhase(p => p instanceof PostSummonPhase && p.player && p.fieldIndex === this.fieldIndex);
globalScene.unshiftPhase(new SwitchPhase(SwitchType.INITIAL_SWITCH, this.fieldIndex, false, true));
this.end();
}, () => {
gScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.setMode(Mode.MESSAGE);
this.end();
});
});

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { TurnCommand, BattleType } from "#app/battle";
import { TrappedTag, EncoreTag } from "#app/data/battler-tags";
import { MoveTargetSet, getMoveTargets } from "#app/data/move";
@ -30,9 +30,9 @@ export class CommandPhase extends FieldPhase {
start() {
super.start();
const commandUiHandler = gScene.ui.handlers[Mode.COMMAND];
const commandUiHandler = globalScene.ui.handlers[Mode.COMMAND];
if (commandUiHandler) {
if (gScene.currentBattle.turn === 1 || commandUiHandler.getCursor() === Command.POKEMON) {
if (globalScene.currentBattle.turn === 1 || commandUiHandler.getCursor() === Command.POKEMON) {
commandUiHandler.setCursor(Command.FIGHT);
} else {
commandUiHandler.setCursor(commandUiHandler.getCursor());
@ -42,21 +42,21 @@ export class CommandPhase extends FieldPhase {
if (this.fieldIndex) {
// If we somehow are attempting to check the right pokemon but there's only one pokemon out
// Switch back to the center pokemon. This can happen rarely in double battles with mid turn switching
if (gScene.getPlayerField().filter(p => p.isActive()).length === 1) {
if (globalScene.getPlayerField().filter(p => p.isActive()).length === 1) {
this.fieldIndex = FieldPosition.CENTER;
} else {
const allyCommand = gScene.currentBattle.turnCommands[this.fieldIndex - 1];
const allyCommand = globalScene.currentBattle.turnCommands[this.fieldIndex - 1];
if (allyCommand?.command === Command.BALL || allyCommand?.command === Command.RUN) {
gScene.currentBattle.turnCommands[this.fieldIndex] = { command: allyCommand?.command, skip: true };
globalScene.currentBattle.turnCommands[this.fieldIndex] = { command: allyCommand?.command, skip: true };
}
}
}
if (gScene.currentBattle.turnCommands[this.fieldIndex]?.skip) {
if (globalScene.currentBattle.turnCommands[this.fieldIndex]?.skip) {
return this.end();
}
const playerPokemon = gScene.getPlayerField()[this.fieldIndex];
const playerPokemon = globalScene.getPlayerField()[this.fieldIndex];
const moveQueue = playerPokemon.getMoveQueue();
@ -75,21 +75,21 @@ export class CommandPhase extends FieldPhase {
if (moveIndex > -1 && playerPokemon.getMoveset()[moveIndex]!.isUsable(playerPokemon, queuedMove.ignorePP)) { // TODO: is the bang correct?
this.handleCommand(Command.FIGHT, moveIndex, queuedMove.ignorePP, { targets: queuedMove.targets, multiple: queuedMove.targets.length > 1 });
} else {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}
}
} else {
if (gScene.currentBattle.isBattleMysteryEncounter() && gScene.currentBattle.mysteryEncounter?.skipToFightInput) {
gScene.ui.clearText();
gScene.ui.setMode(Mode.FIGHT, this.fieldIndex);
if (globalScene.currentBattle.isBattleMysteryEncounter() && globalScene.currentBattle.mysteryEncounter?.skipToFightInput) {
globalScene.ui.clearText();
globalScene.ui.setMode(Mode.FIGHT, this.fieldIndex);
} else {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}
}
}
handleCommand(command: Command, cursor: integer, ...args: any[]): boolean {
const playerPokemon = gScene.getPlayerField()[this.fieldIndex];
const playerPokemon = globalScene.getPlayerField()[this.fieldIndex];
let success: boolean;
switch (command) {
@ -106,20 +106,20 @@ export class CommandPhase extends FieldPhase {
}
console.log(moveTargets, getPokemonNameWithAffix(playerPokemon));
if (moveTargets.targets.length > 1 && moveTargets.multiple) {
gScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
globalScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
}
if (moveTargets.targets.length <= 1 || moveTargets.multiple) {
turnCommand.move!.targets = moveTargets.targets; //TODO: is the bang correct here?
} else if (playerPokemon.getTag(BattlerTagType.CHARGING) && playerPokemon.getMoveQueue().length >= 1) {
turnCommand.move!.targets = playerPokemon.getMoveQueue()[0].targets; //TODO: is the bang correct here?
} else {
gScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
globalScene.unshiftPhase(new SelectTargetPhase(this.fieldIndex));
}
gScene.currentBattle.turnCommands[this.fieldIndex] = turnCommand;
globalScene.currentBattle.turnCommands[this.fieldIndex] = turnCommand;
success = true;
} else if (cursor < playerPokemon.getMoveset().length) {
const move = playerPokemon.getMoveset()[cursor]!; //TODO: is this bang correct?
gScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.setMode(Mode.MESSAGE);
// Decides between a Disabled, Not Implemented, or No PP translation message
const errorMessage =
@ -128,58 +128,58 @@ export class CommandPhase extends FieldPhase {
: move.getName().endsWith(" (N)") ? "battle:moveNotImplemented" : "battle:moveNoPP";
const moveName = move.getName().replace(" (N)", ""); // Trims off the indicator
gScene.ui.showText(i18next.t(errorMessage, { moveName: moveName }), null, () => {
gScene.ui.clearText();
gScene.ui.setMode(Mode.FIGHT, this.fieldIndex);
globalScene.ui.showText(i18next.t(errorMessage, { moveName: moveName }), null, () => {
globalScene.ui.clearText();
globalScene.ui.setMode(Mode.FIGHT, this.fieldIndex);
}, null, true);
}
break;
case Command.BALL:
const notInDex = (gScene.getEnemyField().filter(p => p.isActive(true)).some(p => !gScene.gameData.dexData[p.species.speciesId].caughtAttr) && gScene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1);
if (gScene.arena.biomeType === Biome.END && (!gScene.gameMode.isClassic || gScene.gameMode.isFreshStartChallenge() || notInDex )) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
gScene.ui.setMode(Mode.MESSAGE);
gScene.ui.showText(i18next.t("battle:noPokeballForce"), null, () => {
gScene.ui.showText("", 0);
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
const notInDex = (globalScene.getEnemyField().filter(p => p.isActive(true)).some(p => !globalScene.gameData.dexData[p.species.speciesId].caughtAttr) && globalScene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1);
if (globalScene.arena.biomeType === Biome.END && (!globalScene.gameMode.isClassic || globalScene.gameMode.isFreshStartChallenge() || notInDex )) {
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.showText(i18next.t("battle:noPokeballForce"), null, () => {
globalScene.ui.showText("", 0);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
} else if (gScene.currentBattle.battleType === BattleType.TRAINER) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
gScene.ui.setMode(Mode.MESSAGE);
gScene.ui.showText(i18next.t("battle:noPokeballTrainer"), null, () => {
gScene.ui.showText("", 0);
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
} else if (globalScene.currentBattle.battleType === BattleType.TRAINER) {
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.showText(i18next.t("battle:noPokeballTrainer"), null, () => {
globalScene.ui.showText("", 0);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
} else if (gScene.currentBattle.isBattleMysteryEncounter() && !gScene.currentBattle.mysteryEncounter!.catchAllowed) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
gScene.ui.setMode(Mode.MESSAGE);
gScene.ui.showText(i18next.t("battle:noPokeballMysteryEncounter"), null, () => {
gScene.ui.showText("", 0);
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
} else if (globalScene.currentBattle.isBattleMysteryEncounter() && !globalScene.currentBattle.mysteryEncounter!.catchAllowed) {
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.showText(i18next.t("battle:noPokeballMysteryEncounter"), null, () => {
globalScene.ui.showText("", 0);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
} else {
const targets = gScene.getEnemyField().filter(p => p.isActive(true)).map(p => p.getBattlerIndex());
const targets = globalScene.getEnemyField().filter(p => p.isActive(true)).map(p => p.getBattlerIndex());
if (targets.length > 1) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
gScene.ui.setMode(Mode.MESSAGE);
gScene.ui.showText(i18next.t("battle:noPokeballMulti"), null, () => {
gScene.ui.showText("", 0);
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.showText(i18next.t("battle:noPokeballMulti"), null, () => {
globalScene.ui.showText("", 0);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
} else if (cursor < 5) {
const targetPokemon = gScene.getEnemyField().find(p => p.isActive(true));
const targetPokemon = globalScene.getEnemyField().find(p => p.isActive(true));
if (targetPokemon?.isBoss() && targetPokemon?.bossSegmentIndex >= 1 && !targetPokemon?.hasAbility(Abilities.WONDER_GUARD, false, true) && cursor < PokeballType.MASTER_BALL) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
gScene.ui.setMode(Mode.MESSAGE);
gScene.ui.showText(i18next.t("battle:noPokeballStrong"), null, () => {
gScene.ui.showText("", 0);
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.showText(i18next.t("battle:noPokeballStrong"), null, () => {
globalScene.ui.showText("", 0);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
} else {
gScene.currentBattle.turnCommands[this.fieldIndex] = { command: Command.BALL, cursor: cursor };
gScene.currentBattle.turnCommands[this.fieldIndex]!.targets = targets;
globalScene.currentBattle.turnCommands[this.fieldIndex] = { command: Command.BALL, cursor: cursor };
globalScene.currentBattle.turnCommands[this.fieldIndex]!.targets = targets;
if (this.fieldIndex) {
gScene.currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true;
globalScene.currentBattle.turnCommands[this.fieldIndex - 1]!.skip = true;
}
success = true;
}
@ -189,21 +189,21 @@ export class CommandPhase extends FieldPhase {
case Command.POKEMON:
case Command.RUN:
const isSwitch = command === Command.POKEMON;
const { currentBattle, arena } = gScene;
const { currentBattle, arena } = globalScene;
const mysteryEncounterFleeAllowed = currentBattle.mysteryEncounter?.fleeAllowed;
if (!isSwitch && (arena.biomeType === Biome.END || (!isNullOrUndefined(mysteryEncounterFleeAllowed) && !mysteryEncounterFleeAllowed))) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
gScene.ui.setMode(Mode.MESSAGE);
gScene.ui.showText(i18next.t("battle:noEscapeForce"), null, () => {
gScene.ui.showText("", 0);
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.showText(i18next.t("battle:noEscapeForce"), null, () => {
globalScene.ui.showText("", 0);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
} else if (!isSwitch && (currentBattle.battleType === BattleType.TRAINER || currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE)) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
gScene.ui.setMode(Mode.MESSAGE);
gScene.ui.showText(i18next.t("battle:noEscapeTrainer"), null, () => {
gScene.ui.showText("", 0);
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.showText(i18next.t("battle:noEscapeTrainer"), null, () => {
globalScene.ui.showText("", 0);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}, null, true);
} else {
const batonPass = isSwitch && args[0] as boolean;
@ -218,12 +218,12 @@ export class CommandPhase extends FieldPhase {
}
} else if (trappedAbMessages.length > 0) {
if (!isSwitch) {
gScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.setMode(Mode.MESSAGE);
}
gScene.ui.showText(trappedAbMessages[0], null, () => {
gScene.ui.showText("", 0);
globalScene.ui.showText(trappedAbMessages[0], null, () => {
globalScene.ui.showText("", 0);
if (!isSwitch) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}
}, null, true);
} else {
@ -238,20 +238,20 @@ export class CommandPhase extends FieldPhase {
}
if (!isSwitch) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
gScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.MESSAGE);
}
gScene.ui.showText(
globalScene.ui.showText(
i18next.t("battle:noEscapePokemon", {
pokemonName: trapTag.sourceId && gScene.getPokemonById(trapTag.sourceId) ? getPokemonNameWithAffix(gScene.getPokemonById(trapTag.sourceId)!) : "",
pokemonName: trapTag.sourceId && globalScene.getPokemonById(trapTag.sourceId) ? getPokemonNameWithAffix(globalScene.getPokemonById(trapTag.sourceId)!) : "",
moveName: trapTag.getMoveName(),
escapeVerb: isSwitch ? i18next.t("battle:escapeVerbSwitch") : i18next.t("battle:escapeVerbFlee")
}),
null,
() => {
gScene.ui.showText("", 0);
globalScene.ui.showText("", 0);
if (!isSwitch) {
gScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
globalScene.ui.setMode(Mode.COMMAND, this.fieldIndex);
}
}, null, true);
}
@ -268,8 +268,8 @@ export class CommandPhase extends FieldPhase {
cancel() {
if (this.fieldIndex) {
gScene.unshiftPhase(new CommandPhase(0));
gScene.unshiftPhase(new CommandPhase(1));
globalScene.unshiftPhase(new CommandPhase(0));
globalScene.unshiftPhase(new CommandPhase(1));
this.end();
}
}
@ -299,10 +299,10 @@ export class CommandPhase extends FieldPhase {
}
getPokemon(): PlayerPokemon {
return gScene.getPlayerField()[this.fieldIndex];
return globalScene.getPlayerField()[this.fieldIndex];
}
end() {
gScene.ui.setMode(Mode.MESSAGE).then(() => super.end());
globalScene.ui.setMode(Mode.MESSAGE).then(() => super.end());
}
}

View File

@ -1,5 +1,5 @@
import { BattlerIndex } from "#app/battle";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { CommonAnim, CommonBattleAnim } from "#app/data/battle-anims";
import { PokemonPhase } from "./pokemon-phase";
@ -21,7 +21,7 @@ export class CommonAnimPhase extends PokemonPhase {
}
start() {
const target = this.targetIndex !== undefined ? (this.player ? gScene.getEnemyField() : gScene.getPlayerField())[this.targetIndex] : this.getPokemon();
const target = this.targetIndex !== undefined ? (this.player ? globalScene.getEnemyField() : globalScene.getPlayerField())[this.targetIndex] : this.getPokemon();
new CommonBattleAnim(this.anim, this.getPokemon(), target).play(false, () => {
this.end();
});

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { BattlerIndex } from "#app/battle";
import { BattleSpec } from "#app/enums/battle-spec";
import { DamageResult, HitResult } from "#app/field/pokemon";
@ -22,11 +22,11 @@ export class DamagePhase extends PokemonPhase {
super.start();
if (this.damageResult === HitResult.ONE_HIT_KO) {
if (gScene.moveAnimations) {
gScene.toggleInvert(true);
if (globalScene.moveAnimations) {
globalScene.toggleInvert(true);
}
gScene.time.delayedCall(Utils.fixedInt(1000), () => {
gScene.toggleInvert(false);
globalScene.time.delayedCall(Utils.fixedInt(1000), () => {
globalScene.toggleInvert(false);
this.applyDamage();
});
return;
@ -42,23 +42,23 @@ export class DamagePhase extends PokemonPhase {
applyDamage() {
switch (this.damageResult) {
case HitResult.EFFECTIVE:
gScene.playSound("se/hit");
globalScene.playSound("se/hit");
break;
case HitResult.SUPER_EFFECTIVE:
case HitResult.ONE_HIT_KO:
gScene.playSound("se/hit_strong");
globalScene.playSound("se/hit_strong");
break;
case HitResult.NOT_VERY_EFFECTIVE:
gScene.playSound("se/hit_weak");
globalScene.playSound("se/hit_weak");
break;
}
if (this.amount) {
gScene.damageNumberHandler.add(this.getPokemon(), this.amount, this.damageResult, this.critical);
globalScene.damageNumberHandler.add(this.getPokemon(), this.amount, this.damageResult, this.critical);
}
if (this.damageResult !== HitResult.OTHER && this.amount > 0) {
const flashTimer = gScene.time.addEvent({
const flashTimer = globalScene.time.addEvent({
delay: 100,
repeat: 5,
startAt: 200,
@ -75,8 +75,8 @@ export class DamagePhase extends PokemonPhase {
}
override end() {
if (gScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
gScene.initFinalBossPhaseTwo(this.getPokemon());
if (globalScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
globalScene.initFinalBossPhaseTwo(this.getPokemon());
} else {
super.end();
}

View File

@ -1,4 +1,4 @@
import { AnySound, gScene } from "#app/battle-scene";
import { AnySound, globalScene } from "#app/battle-scene";
import { Egg } from "#app/data/egg";
import { EggCountChangedEvent } from "#app/events/egg";
import { PlayerPokemon } from "#app/field/pokemon";
@ -76,37 +76,37 @@ export class EggHatchPhase extends Phase {
start() {
super.start();
gScene.ui.setModeForceTransition(Mode.EGG_HATCH_SCENE).then(() => {
globalScene.ui.setModeForceTransition(Mode.EGG_HATCH_SCENE).then(() => {
if (!this.egg) {
return this.end();
}
const eggIndex = gScene.gameData.eggs.findIndex(e => e.id === this.egg.id);
const eggIndex = globalScene.gameData.eggs.findIndex(e => e.id === this.egg.id);
if (eggIndex === -1) {
return this.end();
}
gScene.gameData.eggs.splice(eggIndex, 1);
globalScene.gameData.eggs.splice(eggIndex, 1);
gScene.fadeOutBgm(undefined, false);
globalScene.fadeOutBgm(undefined, false);
this.eggHatchHandler = gScene.ui.getHandler() as EggHatchSceneHandler;
this.eggHatchHandler = globalScene.ui.getHandler() as EggHatchSceneHandler;
this.eggHatchContainer = this.eggHatchHandler.eggHatchContainer;
this.eggHatchBg = gScene.add.image(0, 0, "default_bg");
this.eggHatchBg = globalScene.add.image(0, 0, "default_bg");
this.eggHatchBg.setOrigin(0, 0);
this.eggHatchContainer.add(this.eggHatchBg);
this.eggContainer = gScene.add.container(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2);
this.eggContainer = globalScene.add.container(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2);
this.eggSprite = gScene.add.sprite(0, 0, "egg", `egg_${this.egg.getKey()}`);
this.eggCrackSprite = gScene.add.sprite(0, 0, "egg_crack", "0");
this.eggSprite = globalScene.add.sprite(0, 0, "egg", `egg_${this.egg.getKey()}`);
this.eggCrackSprite = globalScene.add.sprite(0, 0, "egg_crack", "0");
this.eggCrackSprite.setVisible(false);
this.eggLightraysOverlay = gScene.add.sprite((-this.eggHatchBg.displayWidth / 2) + 4, -this.eggHatchBg.displayHeight / 2, "egg_lightrays", "3");
this.eggLightraysOverlay = globalScene.add.sprite((-this.eggHatchBg.displayWidth / 2) + 4, -this.eggHatchBg.displayHeight / 2, "egg_lightrays", "3");
this.eggLightraysOverlay.setOrigin(0, 0);
this.eggLightraysOverlay.setVisible(false);
@ -119,22 +119,22 @@ export class EggHatchPhase extends Phase {
this.eggHatchContainer.add(this.eggCounterContainer);
const getPokemonSprite = () => {
const ret = gScene.add.sprite(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2, "pkmn__sub");
ret.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
const ret = globalScene.add.sprite(this.eggHatchBg.displayWidth / 2, this.eggHatchBg.displayHeight / 2, "pkmn__sub");
ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
return ret;
};
this.eggHatchContainer.add((this.pokemonSprite = getPokemonSprite()));
this.pokemonShinySparkle = gScene.add.sprite(this.pokemonSprite.x, this.pokemonSprite.y, "shiny");
this.pokemonShinySparkle = globalScene.add.sprite(this.pokemonSprite.x, this.pokemonSprite.y, "shiny");
this.pokemonShinySparkle.setVisible(false);
this.eggHatchContainer.add(this.pokemonShinySparkle);
this.eggHatchOverlay = gScene.add.rectangle(0, -gScene.game.canvas.height / 6, gScene.game.canvas.width / 6, gScene.game.canvas.height / 6, 0xFFFFFF);
this.eggHatchOverlay = globalScene.add.rectangle(0, -globalScene.game.canvas.height / 6, globalScene.game.canvas.width / 6, globalScene.game.canvas.height / 6, 0xFFFFFF);
this.eggHatchOverlay.setOrigin(0, 0);
this.eggHatchOverlay.setAlpha(0);
gScene.fieldUI.add(this.eggHatchOverlay);
globalScene.fieldUI.add(this.eggHatchOverlay);
this.infoContainer = new PokemonInfoContainer();
this.infoContainer.setup();
@ -154,13 +154,13 @@ export class EggHatchPhase extends Phase {
pokemon.loadAssets().then(() => {
this.canSkip = true;
gScene.time.delayedCall(1000, () => {
globalScene.time.delayedCall(1000, () => {
if (!this.hatched) {
this.evolutionBgm = gScene.playSoundWithoutBgm("evolution");
this.evolutionBgm = globalScene.playSoundWithoutBgm("evolution");
}
});
gScene.time.delayedCall(2000, () => {
globalScene.time.delayedCall(2000, () => {
if (this.hatched) {
return;
}
@ -170,25 +170,25 @@ export class EggHatchPhase extends Phase {
if (this.hatched) {
return;
}
gScene.time.delayedCall(1000, () => {
globalScene.time.delayedCall(1000, () => {
if (this.hatched) {
return;
}
this.doSpray(2, this.eggSprite.displayHeight / -4);
this.eggCrackSprite.setFrame("1");
gScene.time.delayedCall(125, () => this.eggCrackSprite.setFrame("2"));
globalScene.time.delayedCall(125, () => this.eggCrackSprite.setFrame("2"));
this.doEggShake(4).then(() => {
if (this.hatched) {
return;
}
gScene.time.delayedCall(1000, () => {
globalScene.time.delayedCall(1000, () => {
if (this.hatched) {
return;
}
gScene.playSound("se/egg_crack");
globalScene.playSound("se/egg_crack");
this.doSpray(4);
this.eggCrackSprite.setFrame("3");
gScene.time.delayedCall(125, () => this.eggCrackSprite.setFrame("4"));
globalScene.time.delayedCall(125, () => this.eggCrackSprite.setFrame("4"));
this.doEggShake(8, 2).then(() => {
if (!this.hatched) {
this.doHatch();
@ -204,10 +204,10 @@ export class EggHatchPhase extends Phase {
}
end() {
if (gScene.findPhase((p) => p instanceof EggHatchPhase)) {
if (globalScene.findPhase((p) => p instanceof EggHatchPhase)) {
this.eggHatchHandler.clear();
} else {
gScene.time.delayedCall(250, () => gScene.setModifiersVisible(true));
globalScene.time.delayedCall(250, () => globalScene.setModifiersVisible(true));
}
super.end();
}
@ -227,14 +227,14 @@ export class EggHatchPhase extends Phase {
if (count === undefined) {
count = 0;
}
gScene.playSound("se/pb_move");
gScene.tweens.add({
globalScene.playSound("se/pb_move");
globalScene.tweens.add({
targets: this.eggContainer,
x: `-=${intensity / (count ? 1 : 2)}`,
ease: "Sine.easeInOut",
duration: 125,
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: this.eggContainer,
x: `+=${intensity}`,
ease: "Sine.easeInOut",
@ -244,7 +244,7 @@ export class EggHatchPhase extends Phase {
if (count! < repeatCount!) { // we know they are defined
return this.doEggShake(intensity, repeatCount, count).then(() => resolve());
}
gScene.tweens.add({
globalScene.tweens.add({
targets: this.eggContainer,
x: `-=${intensity / 2}`,
ease: "Sine.easeInOut",
@ -285,14 +285,14 @@ export class EggHatchPhase extends Phase {
this.canSkip = false;
this.hatched = true;
if (this.evolutionBgm) {
SoundFade.fadeOut(gScene, this.evolutionBgm, Utils.fixedInt(100));
SoundFade.fadeOut(globalScene, this.evolutionBgm, Utils.fixedInt(100));
}
for (let e = 0; e < 5; e++) {
gScene.time.delayedCall(Utils.fixedInt(375 * e), () => gScene.playSound("se/egg_hatch", { volume: 1 - (e * 0.2) }));
globalScene.time.delayedCall(Utils.fixedInt(375 * e), () => globalScene.playSound("se/egg_hatch", { volume: 1 - (e * 0.2) }));
}
this.eggLightraysOverlay.setVisible(true);
this.eggLightraysOverlay.play("egg_lightrays");
gScene.tweens.add({
globalScene.tweens.add({
duration: Utils.fixedInt(125),
targets: this.eggHatchOverlay,
alpha: 1,
@ -302,7 +302,7 @@ export class EggHatchPhase extends Phase {
this.canSkip = true;
}
});
gScene.time.delayedCall(Utils.fixedInt(1500), () => {
globalScene.time.delayedCall(Utils.fixedInt(1500), () => {
this.canSkip = false;
if (!this.skipped) {
this.doReveal();
@ -317,16 +317,16 @@ export class EggHatchPhase extends Phase {
// set the previous dex data so info container can show new unlocks in egg summary
const isShiny = this.pokemon.isShiny();
if (this.pokemon.species.subLegendary) {
gScene.validateAchv(achvs.HATCH_SUB_LEGENDARY);
globalScene.validateAchv(achvs.HATCH_SUB_LEGENDARY);
}
if (this.pokemon.species.legendary) {
gScene.validateAchv(achvs.HATCH_LEGENDARY);
globalScene.validateAchv(achvs.HATCH_LEGENDARY);
}
if (this.pokemon.species.mythical) {
gScene.validateAchv(achvs.HATCH_MYTHICAL);
globalScene.validateAchv(achvs.HATCH_MYTHICAL);
}
if (isShiny) {
gScene.validateAchv(achvs.HATCH_SHINY);
globalScene.validateAchv(achvs.HATCH_SHINY);
}
this.eggContainer.setVisible(false);
this.pokemonSprite.play(this.pokemon.getSpriteKey(true));
@ -335,34 +335,34 @@ export class EggHatchPhase extends Phase {
this.pokemonSprite.setPipelineData("shiny", this.pokemon.shiny);
this.pokemonSprite.setPipelineData("variant", this.pokemon.variant);
this.pokemonSprite.setVisible(true);
gScene.time.delayedCall(Utils.fixedInt(250), () => {
globalScene.time.delayedCall(Utils.fixedInt(250), () => {
this.eggsToHatchCount--;
this.eggHatchHandler.eventTarget.dispatchEvent(new EggCountChangedEvent(this.eggsToHatchCount));
this.pokemon.cry();
if (isShiny) {
gScene.time.delayedCall(Utils.fixedInt(500), () => {
globalScene.time.delayedCall(Utils.fixedInt(500), () => {
this.pokemonShinySparkle.play(`sparkle${this.pokemon.variant ? `_${this.pokemon.variant + 1}` : ""}`);
gScene.playSound("se/sparkle");
globalScene.playSound("se/sparkle");
});
}
gScene.time.delayedCall(Utils.fixedInt(!this.skipped ? !isShiny ? 1250 : 1750 : !isShiny ? 250 : 750), () => {
globalScene.time.delayedCall(Utils.fixedInt(!this.skipped ? !isShiny ? 1250 : 1750 : !isShiny ? 250 : 750), () => {
this.infoContainer.show(this.pokemon, false, this.skipped ? 2 : 1);
gScene.playSoundWithoutBgm("evolution_fanfare");
globalScene.playSoundWithoutBgm("evolution_fanfare");
gScene.ui.showText(i18next.t("egg:hatchFromTheEgg", { pokemonName: getPokemonNameWithAffix(this.pokemon) }), null, () => {
gScene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
gScene.gameData.setPokemonCaught(this.pokemon, true, true).then(() => {
gScene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex).then((value) => {
globalScene.ui.showText(i18next.t("egg:hatchFromTheEgg", { pokemonName: getPokemonNameWithAffix(this.pokemon) }), null, () => {
globalScene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
globalScene.gameData.setPokemonCaught(this.pokemon, true, true).then(() => {
globalScene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex).then((value) => {
this.eggHatchData.setEggMoveUnlocked(value);
gScene.ui.showText("", 0);
globalScene.ui.showText("", 0);
this.end();
});
});
}, null, true, 3000);
});
});
gScene.tweens.add({
globalScene.tweens.add({
duration: Utils.fixedInt(this.skipped ? 500 : 3000),
targets: this.eggHatchOverlay,
alpha: 0,
@ -386,7 +386,7 @@ export class EggHatchPhase extends Phase {
* @param offsetY how much to offset the Y coordinates
*/
doSpray(intensity: integer, offsetY?: number) {
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
repeat: intensity,
duration: Utils.getFrameMs(1),
onRepeat: () => {
@ -404,7 +404,7 @@ export class EggHatchPhase extends Phase {
const initialX = this.eggHatchBg.displayWidth / 2;
const initialY = this.eggHatchBg.displayHeight / 2 + offsetY;
const shardKey = !this.egg.isManaphyEgg() ? this.egg.tier.toString() : "1";
const particle = gScene.add.image(initialX, initialY, "egg_shard", `${shardKey}_${Math.floor(trigIndex / 2)}`);
const particle = globalScene.add.image(initialX, initialY, "egg_shard", `${shardKey}_${Math.floor(trigIndex / 2)}`);
this.eggHatchContainer.add(particle);
let f = 0;
@ -412,7 +412,7 @@ export class EggHatchPhase extends Phase {
const speed = 3 - Utils.randInt(8);
const amp = 24 + Utils.randInt(32);
const particleTimer = gScene.tweens.addCounter({
const particleTimer = globalScene.tweens.addCounter({
repeat: -1,
duration: Utils.getFrameMs(1),
onRepeat: () => {

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { Egg, EGG_SEED } from "#app/data/egg";
import { Phase } from "#app/phase";
import i18next from "i18next";
@ -24,18 +24,18 @@ export class EggLapsePhase extends Phase {
start() {
super.start();
const eggsToHatch: Egg[] = gScene.gameData.eggs.filter((egg: Egg) => {
const eggsToHatch: Egg[] = globalScene.gameData.eggs.filter((egg: Egg) => {
return Overrides.EGG_IMMEDIATE_HATCH_OVERRIDE ? true : --egg.hatchWaves < 1;
});
const eggsToHatchCount: number = eggsToHatch.length;
this.eggHatchData = [];
if (eggsToHatchCount > 0) {
if (eggsToHatchCount >= this.minEggsToSkip && gScene.eggSkipPreference === 1) {
gScene.ui.showText(i18next.t("battle:eggHatching"), 0, () => {
if (eggsToHatchCount >= this.minEggsToSkip && globalScene.eggSkipPreference === 1) {
globalScene.ui.showText(i18next.t("battle:eggHatching"), 0, () => {
// show prompt for skip, blocking inputs for 1 second
gScene.ui.showText(i18next.t("battle:eggSkipPrompt"), 0);
gScene.ui.setModeWithoutClear(Mode.CONFIRM, () => {
globalScene.ui.showText(i18next.t("battle:eggSkipPrompt"), 0);
globalScene.ui.setModeWithoutClear(Mode.CONFIRM, () => {
this.hatchEggsSkipped(eggsToHatch);
this.showSummary();
}, () => {
@ -45,13 +45,13 @@ export class EggLapsePhase extends Phase {
null, null, null, 1000, true
);
}, 100, true);
} else if (eggsToHatchCount >= this.minEggsToSkip && gScene.eggSkipPreference === 2) {
gScene.queueMessage(i18next.t("battle:eggHatching"));
} else if (eggsToHatchCount >= this.minEggsToSkip && globalScene.eggSkipPreference === 2) {
globalScene.queueMessage(i18next.t("battle:eggHatching"));
this.hatchEggsSkipped(eggsToHatch);
this.showSummary();
} else {
// regular hatches, no summary
gScene.queueMessage(i18next.t("battle:eggHatching"));
globalScene.queueMessage(i18next.t("battle:eggHatching"));
this.hatchEggsRegular(eggsToHatch);
this.end();
}
@ -67,7 +67,7 @@ export class EggLapsePhase extends Phase {
hatchEggsRegular(eggsToHatch: Egg[]) {
let eggsToHatchCount: number = eggsToHatch.length;
for (const egg of eggsToHatch) {
gScene.unshiftPhase(new EggHatchPhase(this, egg, eggsToHatchCount));
globalScene.unshiftPhase(new EggHatchPhase(this, egg, eggsToHatchCount));
eggsToHatchCount--;
}
}
@ -83,7 +83,7 @@ export class EggLapsePhase extends Phase {
}
showSummary() {
gScene.unshiftPhase(new EggSummaryPhase(this.eggHatchData));
globalScene.unshiftPhase(new EggSummaryPhase(this.eggHatchData));
this.end();
}
@ -93,11 +93,11 @@ export class EggLapsePhase extends Phase {
* @param egg egg to hatch
*/
hatchEggSilently(egg: Egg) {
const eggIndex = gScene.gameData.eggs.findIndex(e => e.id === egg.id);
const eggIndex = globalScene.gameData.eggs.findIndex(e => e.id === egg.id);
if (eggIndex === -1) {
return this.end();
}
gScene.gameData.eggs.splice(eggIndex, 1);
globalScene.gameData.eggs.splice(eggIndex, 1);
const data = this.generatePokemon(egg);
const pokemon = data.pokemon;
@ -106,16 +106,16 @@ export class EggLapsePhase extends Phase {
}
if (pokemon.species.subLegendary) {
gScene.validateAchv(achvs.HATCH_SUB_LEGENDARY);
globalScene.validateAchv(achvs.HATCH_SUB_LEGENDARY);
}
if (pokemon.species.legendary) {
gScene.validateAchv(achvs.HATCH_LEGENDARY);
globalScene.validateAchv(achvs.HATCH_LEGENDARY);
}
if (pokemon.species.mythical) {
gScene.validateAchv(achvs.HATCH_MYTHICAL);
globalScene.validateAchv(achvs.HATCH_MYTHICAL);
}
if (pokemon.isShiny()) {
gScene.validateAchv(achvs.HATCH_SHINY);
globalScene.validateAchv(achvs.HATCH_SHINY);
}
}
@ -128,7 +128,7 @@ export class EggLapsePhase extends Phase {
generatePokemon(egg: Egg): EggHatchData {
let ret: PlayerPokemon;
let newHatchData: EggHatchData;
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
ret = egg.generatePlayerPokemon();
newHatchData = new EggHatchData(ret, egg.eggMoveIndex);
newHatchData.setDex();

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { Phase } from "#app/phase";
import { Mode } from "#app/ui/ui";
import { EggHatchData } from "#app/data/egg-hatch-data";
@ -22,8 +22,8 @@ export class EggSummaryPhase extends Phase {
// updates next pokemon once the current update has been completed
const updateNextPokemon = (i: number) => {
if (i >= this.eggHatchData.length) {
gScene.ui.setModeForceTransition(Mode.EGG_HATCH_SUMMARY, this.eggHatchData).then(() => {
gScene.fadeOutBgm(undefined, false);
globalScene.ui.setModeForceTransition(Mode.EGG_HATCH_SUMMARY, this.eggHatchData).then(() => {
globalScene.fadeOutBgm(undefined, false);
});
} else {
@ -40,8 +40,8 @@ export class EggSummaryPhase extends Phase {
}
end() {
gScene.time.delayedCall(250, () => gScene.setModifiersVisible(true));
gScene.ui.setModeForceTransition(Mode.MESSAGE).then(() => {
globalScene.time.delayedCall(250, () => globalScene.setModifiersVisible(true));
globalScene.ui.setModeForceTransition(Mode.MESSAGE).then(() => {
super.end();
});
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { BattlerIndex, BattleType } from "#app/battle";
import { applyAbAttrs, SyncEncounterNatureAbAttr } from "#app/data/ability";
import { getCharVariantFromDialogue } from "#app/data/dialogue";
@ -49,26 +49,26 @@ export class EncounterPhase extends BattlePhase {
start() {
super.start();
gScene.updateGameInfo();
globalScene.updateGameInfo();
gScene.initSession();
globalScene.initSession();
gScene.eventTarget.dispatchEvent(new EncounterPhaseEvent());
globalScene.eventTarget.dispatchEvent(new EncounterPhaseEvent());
// Failsafe if players somehow skip floor 200 in classic mode
if (gScene.gameMode.isClassic && gScene.currentBattle.waveIndex > 200) {
gScene.unshiftPhase(new GameOverPhase());
if (globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex > 200) {
globalScene.unshiftPhase(new GameOverPhase());
}
const loadEnemyAssets: Promise<void>[] = [];
const battle = gScene.currentBattle;
const battle = globalScene.currentBattle;
// Generate and Init Mystery Encounter
if (battle.isBattleMysteryEncounter() && !battle.mysteryEncounter) {
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
const currentSessionEncounterType = battle.mysteryEncounterType;
battle.mysteryEncounter = gScene.getMysteryEncounter(currentSessionEncounterType);
battle.mysteryEncounter = globalScene.getMysteryEncounter(currentSessionEncounterType);
}, battle.waveIndex * 16);
}
const mysteryEncounter = battle.mysteryEncounter;
@ -76,7 +76,7 @@ export class EncounterPhase extends BattlePhase {
// If ME has an onInit() function, call it
// Usually used for calculating rand data before initializing anything visual
// Also prepopulates any dialogue tokens from encounter/option requirements
gScene.executeWithSeedOffset(() => {
globalScene.executeWithSeedOffset(() => {
if (mysteryEncounter.onInit) {
mysteryEncounter.onInit();
}
@ -90,7 +90,7 @@ export class EncounterPhase extends BattlePhase {
// Add intro visuals for mystery encounter
mysteryEncounter.initIntroVisuals();
gScene.field.add(mysteryEncounter.introVisuals!);
globalScene.field.add(mysteryEncounter.introVisuals!);
}
let totalBst = 0;
@ -104,35 +104,35 @@ export class EncounterPhase extends BattlePhase {
if (battle.battleType === BattleType.TRAINER) {
battle.enemyParty[e] = battle.trainer?.genPartyMember(e)!; // TODO:: is the bang correct here?
} else {
let enemySpecies = gScene.randomSpecies(battle.waveIndex, level, true);
let enemySpecies = globalScene.randomSpecies(battle.waveIndex, level, true);
// If player has golden bug net, rolls 10% chance to replace non-boss wave wild species from the golden bug net bug pool
if (gScene.findModifier(m => m instanceof BoostBugSpawnModifier)
&& !gScene.gameMode.isBoss(battle.waveIndex)
&& gScene.arena.biomeType !== Biome.END
if (globalScene.findModifier(m => m instanceof BoostBugSpawnModifier)
&& !globalScene.gameMode.isBoss(battle.waveIndex)
&& globalScene.arena.biomeType !== Biome.END
&& randSeedInt(10) === 0) {
enemySpecies = getGoldenBugNetSpecies(level);
}
battle.enemyParty[e] = gScene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, !!gScene.getEncounterBossSegments(battle.waveIndex, level, enemySpecies));
if (gScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
battle.enemyParty[e] = globalScene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, !!globalScene.getEncounterBossSegments(battle.waveIndex, level, enemySpecies));
if (globalScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
battle.enemyParty[e].ivs = new Array(6).fill(31);
}
gScene.getParty().slice(0, !battle.double ? 1 : 2).reverse().forEach(playerPokemon => {
globalScene.getParty().slice(0, !battle.double ? 1 : 2).reverse().forEach(playerPokemon => {
applyAbAttrs(SyncEncounterNatureAbAttr, playerPokemon, null, false, battle.enemyParty[e]);
});
}
}
const enemyPokemon = gScene.getEnemyParty()[e];
const enemyPokemon = globalScene.getEnemyParty()[e];
if (e < (battle.double ? 2 : 1)) {
enemyPokemon.setX(-66 + enemyPokemon.getFieldPositionOffset()[0]);
enemyPokemon.resetSummonData();
}
if (!this.loaded) {
gScene.gameData.setPokemonSeen(enemyPokemon, true, battle.battleType === BattleType.TRAINER || battle?.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE);
globalScene.gameData.setPokemonSeen(enemyPokemon, true, battle.battleType === BattleType.TRAINER || battle?.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE);
}
if (enemyPokemon.species.speciesId === Species.ETERNATUS) {
if (gScene.gameMode.isClassic && (battle.battleSpec === BattleSpec.FINAL_BOSS || gScene.gameMode.isWaveFinal(battle.waveIndex))) {
if (globalScene.gameMode.isClassic && (battle.battleSpec === BattleSpec.FINAL_BOSS || globalScene.gameMode.isWaveFinal(battle.waveIndex))) {
if (battle.battleSpec !== BattleSpec.FINAL_BOSS) {
enemyPokemon.formIndex = 1;
enemyPokemon.updateScale();
@ -141,10 +141,10 @@ export class EncounterPhase extends BattlePhase {
} else if (!(battle.waveIndex % 1000)) {
enemyPokemon.formIndex = 1;
enemyPokemon.updateScale();
const bossMBH = gScene.findModifier(m => m instanceof TurnHeldItemTransferModifier && m.pokemonId === enemyPokemon.id, false) as TurnHeldItemTransferModifier;
gScene.removeModifier(bossMBH!);
const bossMBH = globalScene.findModifier(m => m instanceof TurnHeldItemTransferModifier && m.pokemonId === enemyPokemon.id, false) as TurnHeldItemTransferModifier;
globalScene.removeModifier(bossMBH!);
bossMBH?.setTransferrableFalse();
gScene.addEnemyModifier(bossMBH!);
globalScene.addEnemyModifier(bossMBH!);
}
}
@ -156,8 +156,8 @@ export class EncounterPhase extends BattlePhase {
return true;
});
if (gScene.getParty().filter(p => p.isShiny()).length === 6) {
gScene.validateAchv(achvs.SHINY_PARTY);
if (globalScene.getParty().filter(p => p.isShiny()).length === 6) {
globalScene.validateAchv(achvs.SHINY_PARTY);
}
if (battle.battleType === BattleType.TRAINER) {
@ -171,11 +171,11 @@ export class EncounterPhase extends BattlePhase {
}
// Load Mystery Encounter Exclamation bubble and sfx
loadEnemyAssets.push(new Promise<void>(resolve => {
gScene.loadSe("GEN8- Exclaim", "battle_anims", "GEN8- Exclaim.wav");
gScene.loadImage("encounter_exclaim", "mystery-encounters");
gScene.load.once(Phaser.Loader.Events.COMPLETE, () => resolve());
if (!gScene.load.isLoading()) {
gScene.load.start();
globalScene.loadSe("GEN8- Exclaim", "battle_anims", "GEN8- Exclaim.wav");
globalScene.loadImage("encounter_exclaim", "mystery-encounters");
globalScene.load.once(Phaser.Loader.Events.COMPLETE, () => resolve());
if (!globalScene.load.isLoading()) {
globalScene.load.start();
}
}));
} else {
@ -199,16 +199,16 @@ export class EncounterPhase extends BattlePhase {
}
if (e < (battle.double ? 2 : 1)) {
if (battle.battleType === BattleType.WILD) {
gScene.field.add(enemyPokemon);
globalScene.field.add(enemyPokemon);
battle.seenEnemyPartyMemberIds.add(enemyPokemon.id);
const playerPokemon = gScene.getPlayerPokemon();
const playerPokemon = globalScene.getPlayerPokemon();
if (playerPokemon?.visible) {
gScene.field.moveBelow(enemyPokemon as Pokemon, playerPokemon);
globalScene.field.moveBelow(enemyPokemon as Pokemon, playerPokemon);
}
enemyPokemon.tint(0, 0.5);
} else if (battle.battleType === BattleType.TRAINER) {
enemyPokemon.setVisible(false);
gScene.currentBattle.trainer?.tint(0, 0.5);
globalScene.currentBattle.trainer?.tint(0, 0.5);
}
if (battle.double) {
enemyPokemon.setFieldPosition(e ? FieldPosition.RIGHT : FieldPosition.LEFT);
@ -218,56 +218,50 @@ export class EncounterPhase extends BattlePhase {
});
if (!this.loaded && battle.battleType !== BattleType.MYSTERY_ENCOUNTER) {
regenerateModifierPoolThresholds(gScene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD);
gScene.generateEnemyModifiers();
regenerateModifierPoolThresholds(globalScene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD);
globalScene.generateEnemyModifiers();
}
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
if (!this.loaded) {
this.trySetWeatherIfNewBiome(); // Set weather before session gets saved
gScene.gameData.saveAll(true, battle.waveIndex % 10 === 1 || (gScene.lastSavePlayTime ?? 0) >= 300).then(success => {
gScene.disableMenu = false;
globalScene.gameData.saveAll(true, battle.waveIndex % 10 === 1 || (globalScene.lastSavePlayTime ?? 0) >= 300).then(success => {
globalScene.disableMenu = false;
if (!success) {
return gScene.reset(true);
return globalScene.reset(true);
}
this.doEncounter();
gScene.resetSeed();
globalScene.resetSeed();
});
} else {
this.doEncounter();
gScene.resetSeed();
globalScene.resetSeed();
}
});
});
}
doEncounter() {
gScene.playBgm(undefined, true);
gScene.updateModifiers(false);
gScene.setFieldScale(1);
globalScene.playBgm(undefined, true);
globalScene.updateModifiers(false);
globalScene.setFieldScale(1);
/*if (startingWave > 10) {
for (let m = 0; m < Math.min(Math.floor(startingWave / 10), 99); m++)
gScene.addModifier(getPlayerModifierTypeOptionsForWave((m + 1) * 10, 1, gScene.getParty())[0].type.newModifier(), true);
gScene.updateModifiers(true);
}*/
const { battleType, waveIndex } = gScene.currentBattle;
if (gScene.isMysteryEncounterValidForWave(battleType, waveIndex) && !gScene.currentBattle.isBattleMysteryEncounter()) {
const { battleType, waveIndex } = globalScene.currentBattle;
if (globalScene.isMysteryEncounterValidForWave(battleType, waveIndex) && !globalScene.currentBattle.isBattleMysteryEncounter()) {
// Increment ME spawn chance if an ME could have spawned but did not
// Only do this AFTER session has been saved to avoid duplicating increments
gScene.mysteryEncounterSaveData.encounterSpawnChance += WEIGHT_INCREMENT_ON_SPAWN_MISS;
globalScene.mysteryEncounterSaveData.encounterSpawnChance += WEIGHT_INCREMENT_ON_SPAWN_MISS;
}
for (const pokemon of gScene.getParty()) {
for (const pokemon of globalScene.getParty()) {
if (pokemon) {
pokemon.resetBattleData();
}
}
const enemyField = gScene.getEnemyField();
gScene.tweens.add({
targets: [ gScene.arenaEnemy, gScene.currentBattle.trainer, enemyField, gScene.arenaPlayer, gScene.trainer ].flat(),
const enemyField = globalScene.getEnemyField();
globalScene.tweens.add({
targets: [ globalScene.arenaEnemy, globalScene.currentBattle.trainer, enemyField, globalScene.arenaPlayer, globalScene.trainer ].flat(),
x: (_target, _key, value, fieldIndex: integer) => fieldIndex < 2 + (enemyField.length) ? value + 300 : value - 300,
duration: 2000,
onComplete: () => {
@ -277,13 +271,13 @@ export class EncounterPhase extends BattlePhase {
}
});
const encounterIntroVisuals = gScene.currentBattle?.mysteryEncounter?.introVisuals;
const encounterIntroVisuals = globalScene.currentBattle?.mysteryEncounter?.introVisuals;
if (encounterIntroVisuals) {
const enterFromRight = encounterIntroVisuals.enterFromRight;
if (enterFromRight) {
encounterIntroVisuals.x += 500;
}
gScene.tweens.add({
globalScene.tweens.add({
targets: encounterIntroVisuals,
x: enterFromRight ? "-=200" : "+=300",
duration: 2000
@ -292,18 +286,18 @@ export class EncounterPhase extends BattlePhase {
}
getEncounterMessage(): string {
const enemyField = gScene.getEnemyField();
const enemyField = globalScene.getEnemyField();
if (gScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
if (globalScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
return i18next.t("battle:bossAppeared", { bossName: getPokemonNameWithAffix(enemyField[0]) });
}
if (gScene.currentBattle.battleType === BattleType.TRAINER) {
if (gScene.currentBattle.double) {
return i18next.t("battle:trainerAppearedDouble", { trainerName: gScene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) });
if (globalScene.currentBattle.battleType === BattleType.TRAINER) {
if (globalScene.currentBattle.double) {
return i18next.t("battle:trainerAppearedDouble", { trainerName: globalScene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) });
} else {
return i18next.t("battle:trainerAppeared", { trainerName: gScene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) });
return i18next.t("battle:trainerAppeared", { trainerName: globalScene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) });
}
}
@ -313,70 +307,70 @@ export class EncounterPhase extends BattlePhase {
}
doEncounterCommon(showEncounterMessage: boolean = true) {
const enemyField = gScene.getEnemyField();
const enemyField = globalScene.getEnemyField();
if (gScene.currentBattle.battleType === BattleType.WILD) {
if (globalScene.currentBattle.battleType === BattleType.WILD) {
enemyField.forEach(enemyPokemon => {
enemyPokemon.untint(100, "Sine.easeOut");
enemyPokemon.cry();
enemyPokemon.showInfo();
if (enemyPokemon.isShiny()) {
gScene.validateAchv(achvs.SEE_SHINY);
globalScene.validateAchv(achvs.SEE_SHINY);
}
});
gScene.updateFieldScale();
globalScene.updateFieldScale();
if (showEncounterMessage) {
gScene.ui.showText(this.getEncounterMessage(), null, () => this.end(), 1500);
globalScene.ui.showText(this.getEncounterMessage(), null, () => this.end(), 1500);
} else {
this.end();
}
} else if (gScene.currentBattle.battleType === BattleType.TRAINER) {
const trainer = gScene.currentBattle.trainer;
} else if (globalScene.currentBattle.battleType === BattleType.TRAINER) {
const trainer = globalScene.currentBattle.trainer;
trainer?.untint(100, "Sine.easeOut");
trainer?.playAnim();
const doSummon = () => {
gScene.currentBattle.started = true;
gScene.playBgm(undefined);
gScene.pbTray.showPbTray(gScene.getParty());
gScene.pbTrayEnemy.showPbTray(gScene.getEnemyParty());
globalScene.currentBattle.started = true;
globalScene.playBgm(undefined);
globalScene.pbTray.showPbTray(globalScene.getParty());
globalScene.pbTrayEnemy.showPbTray(globalScene.getEnemyParty());
const doTrainerSummon = () => {
this.hideEnemyTrainer();
const availablePartyMembers = gScene.getEnemyParty().filter(p => !p.isFainted()).length;
gScene.unshiftPhase(new SummonPhase(0, false));
if (gScene.currentBattle.double && availablePartyMembers > 1) {
gScene.unshiftPhase(new SummonPhase(1, false));
const availablePartyMembers = globalScene.getEnemyParty().filter(p => !p.isFainted()).length;
globalScene.unshiftPhase(new SummonPhase(0, false));
if (globalScene.currentBattle.double && availablePartyMembers > 1) {
globalScene.unshiftPhase(new SummonPhase(1, false));
}
this.end();
};
if (showEncounterMessage) {
gScene.ui.showText(this.getEncounterMessage(), null, doTrainerSummon, 1500, true);
globalScene.ui.showText(this.getEncounterMessage(), null, doTrainerSummon, 1500, true);
} else {
doTrainerSummon();
}
};
const encounterMessages = gScene.currentBattle.trainer?.getEncounterMessages();
const encounterMessages = globalScene.currentBattle.trainer?.getEncounterMessages();
if (!encounterMessages?.length) {
doSummon();
} else {
let message: string;
gScene.executeWithSeedOffset(() => message = Utils.randSeedItem(encounterMessages), gScene.currentBattle.waveIndex);
globalScene.executeWithSeedOffset(() => message = Utils.randSeedItem(encounterMessages), globalScene.currentBattle.waveIndex);
message = message!; // tell TS compiler it's defined now
const showDialogueAndSummon = () => {
gScene.ui.showDialogue(message, trainer?.getName(TrainerSlot.NONE, true), null, () => {
gScene.charSprite.hide().then(() => gScene.hideFieldOverlay(250).then(() => doSummon()));
globalScene.ui.showDialogue(message, trainer?.getName(TrainerSlot.NONE, true), null, () => {
globalScene.charSprite.hide().then(() => globalScene.hideFieldOverlay(250).then(() => doSummon()));
});
};
if (gScene.currentBattle.trainer?.config.hasCharSprite && !gScene.ui.shouldSkipDialogue(message)) {
gScene.showFieldOverlay(500).then(() => gScene.charSprite.showCharacter(trainer?.getKey()!, getCharVariantFromDialogue(encounterMessages[0])).then(() => showDialogueAndSummon())); // TODO: is this bang correct?
if (globalScene.currentBattle.trainer?.config.hasCharSprite && !globalScene.ui.shouldSkipDialogue(message)) {
globalScene.showFieldOverlay(500).then(() => globalScene.charSprite.showCharacter(trainer?.getKey()!, getCharVariantFromDialogue(encounterMessages[0])).then(() => showDialogueAndSummon())); // TODO: is this bang correct?
} else {
showDialogueAndSummon();
}
}
} else if (gScene.currentBattle.isBattleMysteryEncounter() && gScene.currentBattle.mysteryEncounter) {
const encounter = gScene.currentBattle.mysteryEncounter;
} else if (globalScene.currentBattle.isBattleMysteryEncounter() && globalScene.currentBattle.mysteryEncounter) {
const encounter = globalScene.currentBattle.mysteryEncounter;
const introVisuals = encounter.introVisuals;
introVisuals?.playAnim();
@ -386,10 +380,10 @@ export class EncounterPhase extends BattlePhase {
const doEncounter = () => {
const doShowEncounterOptions = () => {
gScene.ui.clearText();
gScene.ui.getMessageHandler().hideNameText();
globalScene.ui.clearText();
globalScene.ui.getMessageHandler().hideNameText();
gScene.unshiftPhase(new MysteryEncounterPhase());
globalScene.unshiftPhase(new MysteryEncounterPhase());
this.end();
};
@ -407,9 +401,9 @@ export class EncounterPhase extends BattlePhase {
const text = getEncounterText(dialogue.text)!;
i++;
if (title) {
gScene.ui.showDialogue(text, title, null, nextAction, 0, i === 1 ? FIRST_DIALOGUE_PROMPT_DELAY : 0);
globalScene.ui.showDialogue(text, title, null, nextAction, 0, i === 1 ? FIRST_DIALOGUE_PROMPT_DELAY : 0);
} else {
gScene.ui.showText(text, null, nextAction, i === 1 ? FIRST_DIALOGUE_PROMPT_DELAY : 0, true);
globalScene.ui.showText(text, null, nextAction, i === 1 ? FIRST_DIALOGUE_PROMPT_DELAY : 0, true);
}
};
@ -428,71 +422,71 @@ export class EncounterPhase extends BattlePhase {
doEncounter();
} else {
doTrainerExclamation();
gScene.ui.showDialogue(encounterMessage, "???", null, () => {
gScene.charSprite.hide().then(() => gScene.hideFieldOverlay(250).then(() => doEncounter()));
globalScene.ui.showDialogue(encounterMessage, "???", null, () => {
globalScene.charSprite.hide().then(() => globalScene.hideFieldOverlay(250).then(() => doEncounter()));
});
}
}
}
end() {
const enemyField = gScene.getEnemyField();
const enemyField = globalScene.getEnemyField();
enemyField.forEach((enemyPokemon, e) => {
if (enemyPokemon.isShiny()) {
gScene.unshiftPhase(new ShinySparklePhase(BattlerIndex.ENEMY + e));
globalScene.unshiftPhase(new ShinySparklePhase(BattlerIndex.ENEMY + e));
}
});
if (![ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(gScene.currentBattle.battleType)) {
enemyField.map(p => gScene.pushConditionalPhase(new PostSummonPhase(p.getBattlerIndex()), () => {
if (![ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(globalScene.currentBattle.battleType)) {
enemyField.map(p => globalScene.pushConditionalPhase(new PostSummonPhase(p.getBattlerIndex()), () => {
// if there is not a player party, we can't continue
if (!gScene.getParty()?.length) {
if (!globalScene.getParty()?.length) {
return false;
}
// how many player pokemon are on the field ?
const pokemonsOnFieldCount = gScene.getParty().filter(p => p.isOnField()).length;
const pokemonsOnFieldCount = globalScene.getParty().filter(p => p.isOnField()).length;
// if it's a 2vs1, there will never be a 2nd pokemon on our field even
const requiredPokemonsOnField = Math.min(gScene.getParty().filter((p) => !p.isFainted()).length, 2);
const requiredPokemonsOnField = Math.min(globalScene.getParty().filter((p) => !p.isFainted()).length, 2);
// if it's a double, there should be 2, otherwise 1
if (gScene.currentBattle.double) {
if (globalScene.currentBattle.double) {
return pokemonsOnFieldCount === requiredPokemonsOnField;
}
return pokemonsOnFieldCount === 1;
}));
const ivScannerModifier = gScene.findModifier(m => m instanceof IvScannerModifier);
const ivScannerModifier = globalScene.findModifier(m => m instanceof IvScannerModifier);
if (ivScannerModifier) {
enemyField.map(p => gScene.pushPhase(new ScanIvsPhase(p.getBattlerIndex(), Math.min(ivScannerModifier.getStackCount() * 2, 6))));
enemyField.map(p => globalScene.pushPhase(new ScanIvsPhase(p.getBattlerIndex(), Math.min(ivScannerModifier.getStackCount() * 2, 6))));
}
}
if (!this.loaded) {
const availablePartyMembers = gScene.getParty().filter(p => p.isAllowedInBattle());
const availablePartyMembers = globalScene.getParty().filter(p => p.isAllowedInBattle());
if (!availablePartyMembers[0].isOnField()) {
gScene.pushPhase(new SummonPhase(0));
globalScene.pushPhase(new SummonPhase(0));
}
if (gScene.currentBattle.double) {
if (globalScene.currentBattle.double) {
if (availablePartyMembers.length > 1) {
gScene.pushPhase(new ToggleDoublePositionPhase(true));
globalScene.pushPhase(new ToggleDoublePositionPhase(true));
if (!availablePartyMembers[1].isOnField()) {
gScene.pushPhase(new SummonPhase(1));
globalScene.pushPhase(new SummonPhase(1));
}
}
} else {
if (availablePartyMembers.length > 1 && availablePartyMembers[1].isOnField()) {
gScene.pushPhase(new ReturnPhase(1));
globalScene.pushPhase(new ReturnPhase(1));
}
gScene.pushPhase(new ToggleDoublePositionPhase(false));
globalScene.pushPhase(new ToggleDoublePositionPhase(false));
}
if (gScene.currentBattle.battleType !== BattleType.TRAINER && (gScene.currentBattle.waveIndex > 1 || !gScene.gameMode.isDaily)) {
const minPartySize = gScene.currentBattle.double ? 2 : 1;
if (globalScene.currentBattle.battleType !== BattleType.TRAINER && (globalScene.currentBattle.waveIndex > 1 || !globalScene.gameMode.isDaily)) {
const minPartySize = globalScene.currentBattle.double ? 2 : 1;
if (availablePartyMembers.length > minPartySize) {
gScene.pushPhase(new CheckSwitchPhase(0, gScene.currentBattle.double));
if (gScene.currentBattle.double) {
gScene.pushPhase(new CheckSwitchPhase(1, gScene.currentBattle.double));
globalScene.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
if (globalScene.currentBattle.double) {
globalScene.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
}
}
}
@ -501,27 +495,27 @@ export class EncounterPhase extends BattlePhase {
}
tryOverrideForBattleSpec(): boolean {
switch (gScene.currentBattle.battleSpec) {
switch (globalScene.currentBattle.battleSpec) {
case BattleSpec.FINAL_BOSS:
const enemy = gScene.getEnemyPokemon();
gScene.ui.showText(this.getEncounterMessage(), null, () => {
const enemy = globalScene.getEnemyPokemon();
globalScene.ui.showText(this.getEncounterMessage(), null, () => {
const localizationKey = "battleSpecDialogue:encounter";
if (gScene.ui.shouldSkipDialogue(localizationKey)) {
if (globalScene.ui.shouldSkipDialogue(localizationKey)) {
// Logging mirrors logging found in dialogue-ui-handler
console.log(`Dialogue ${localizationKey} skipped`);
this.doEncounterCommon(false);
} else {
const count = 5643853 + gScene.gameData.gameStats.classicSessionsPlayed;
const count = 5643853 + globalScene.gameData.gameStats.classicSessionsPlayed;
// The line below checks if an English ordinal is necessary or not based on whether an entry for encounterLocalizationKey exists in the language or not.
const ordinalUsed = !i18next.exists(localizationKey, { fallbackLng: []}) || i18next.resolvedLanguage === "en" ? i18next.t("battleSpecDialogue:key", { count: count, ordinal: true }) : "";
const cycleCount = count.toLocaleString() + ordinalUsed;
const genderIndex = gScene.gameData.gender ?? PlayerGender.UNSET;
const genderIndex = globalScene.gameData.gender ?? PlayerGender.UNSET;
const genderStr = PlayerGender[genderIndex].toLowerCase();
const encounterDialogue = i18next.t(localizationKey, { context: genderStr, cycleCount: cycleCount });
if (!gScene.gameData.getSeenDialogues()[localizationKey]) {
gScene.gameData.saveSeenDialogue(localizationKey);
if (!globalScene.gameData.getSeenDialogues()[localizationKey]) {
globalScene.gameData.saveSeenDialogue(localizationKey);
}
gScene.ui.showDialogue(encounterDialogue, enemy?.species.name, null, () => {
globalScene.ui.showDialogue(encounterDialogue, enemy?.species.name, null, () => {
this.doEncounterCommon(false);
});
}
@ -541,7 +535,7 @@ export class EncounterPhase extends BattlePhase {
*/
trySetWeatherIfNewBiome(): void {
if (!this.loaded) {
gScene.arena.trySetWeather(getRandomWeatherType(gScene.arena), false);
globalScene.arena.trySetWeather(getRandomWeatherType(globalScene.arena), false);
}
}
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { PlayerGender } from "#app/enums/player-gender";
import { Phase } from "#app/phase";
import { addTextObject, TextStyle } from "#app/ui/text";
@ -15,24 +15,24 @@ export class EndCardPhase extends Phase {
start(): void {
super.start();
gScene.ui.getMessageHandler().bg.setVisible(false);
gScene.ui.getMessageHandler().nameBoxContainer.setVisible(false);
globalScene.ui.getMessageHandler().bg.setVisible(false);
globalScene.ui.getMessageHandler().nameBoxContainer.setVisible(false);
this.endCard = gScene.add.image(0, 0, `end_${gScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}`);
this.endCard = globalScene.add.image(0, 0, `end_${globalScene.gameData.gender === PlayerGender.FEMALE ? "f" : "m"}`);
this.endCard.setOrigin(0);
this.endCard.setScale(0.5);
gScene.field.add(this.endCard);
globalScene.field.add(this.endCard);
this.text = addTextObject(gScene.game.canvas.width / 12, (gScene.game.canvas.height / 6) - 16, i18next.t("battle:congratulations"), TextStyle.SUMMARY, { fontSize: "128px" });
this.text = addTextObject(globalScene.game.canvas.width / 12, (globalScene.game.canvas.height / 6) - 16, i18next.t("battle:congratulations"), TextStyle.SUMMARY, { fontSize: "128px" });
this.text.setOrigin(0.5);
gScene.field.add(this.text);
globalScene.field.add(this.text);
gScene.ui.clearText();
globalScene.ui.clearText();
gScene.ui.fadeIn(1000).then(() => {
globalScene.ui.fadeIn(1000).then(() => {
gScene.ui.showText("", null, () => {
gScene.ui.getMessageHandler().bg.setVisible(true);
globalScene.ui.showText("", null, () => {
globalScene.ui.getMessageHandler().bg.setVisible(true);
this.end();
}, null, true);
});

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { Phase } from "#app/phase";
import { Mode } from "#app/ui/ui";
@ -11,6 +11,6 @@ export class EndEvolutionPhase extends Phase {
start() {
super.start();
gScene.ui.setModeForceTransition(Mode.MESSAGE).then(() => this.end());
globalScene.ui.setModeForceTransition(Mode.MESSAGE).then(() => this.end());
}
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { BattlerIndex } from "#app/battle";
import { Command } from "#app/ui/command-ui-handler";
import { FieldPhase } from "./field-phase";
@ -20,7 +20,7 @@ export class EnemyCommandPhase extends FieldPhase {
super();
this.fieldIndex = fieldIndex;
if (gScene.currentBattle.mysteryEncounter?.skipEnemyBattleTurns) {
if (globalScene.currentBattle.mysteryEncounter?.skipEnemyBattleTurns) {
this.skipTurn = true;
}
}
@ -28,9 +28,9 @@ export class EnemyCommandPhase extends FieldPhase {
start() {
super.start();
const enemyPokemon = gScene.getEnemyField()[this.fieldIndex];
const enemyPokemon = globalScene.getEnemyField()[this.fieldIndex];
const battle = gScene.currentBattle;
const battle = globalScene.currentBattle;
const trainer = battle.trainer;
@ -74,10 +74,10 @@ export class EnemyCommandPhase extends FieldPhase {
/** Select a move to use (and a target to use it against, if applicable) */
const nextMove = enemyPokemon.getNextMove();
gScene.currentBattle.turnCommands[this.fieldIndex + BattlerIndex.ENEMY] =
globalScene.currentBattle.turnCommands[this.fieldIndex + BattlerIndex.ENEMY] =
{ command: Command.FIGHT, move: nextMove, skip: this.skipTurn };
gScene.currentBattle.enemySwitchCounter = Math.max(gScene.currentBattle.enemySwitchCounter - 1, 0);
globalScene.currentBattle.enemySwitchCounter = Math.max(globalScene.currentBattle.enemySwitchCounter - 1, 0);
this.end();
}

View File

@ -1,6 +1,6 @@
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { Phase } from "#app/phase";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { SpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions";
import EvolutionSceneHandler from "#app/ui/evolution-scene-handler";
import * as Utils from "#app/utils";
@ -42,7 +42,7 @@ export class EvolutionPhase extends Phase {
}
setMode(): Promise<void> {
return gScene.ui.setModeForceTransition(Mode.EVOLUTION_SCENE);
return globalScene.ui.setModeForceTransition(Mode.EVOLUTION_SCENE);
}
start() {
@ -54,30 +54,30 @@ export class EvolutionPhase extends Phase {
return this.end();
}
gScene.fadeOutBgm(undefined, false);
globalScene.fadeOutBgm(undefined, false);
const evolutionHandler = gScene.ui.getHandler() as EvolutionSceneHandler;
const evolutionHandler = globalScene.ui.getHandler() as EvolutionSceneHandler;
this.evolutionContainer = evolutionHandler.evolutionContainer;
this.evolutionBaseBg = gScene.add.image(0, 0, "default_bg");
this.evolutionBaseBg = globalScene.add.image(0, 0, "default_bg");
this.evolutionBaseBg.setOrigin(0, 0);
this.evolutionContainer.add(this.evolutionBaseBg);
this.evolutionBg = gScene.add.video(0, 0, "evo_bg").stop();
this.evolutionBg = globalScene.add.video(0, 0, "evo_bg").stop();
this.evolutionBg.setOrigin(0, 0);
this.evolutionBg.setScale(0.4359673025);
this.evolutionBg.setVisible(false);
this.evolutionContainer.add(this.evolutionBg);
this.evolutionBgOverlay = gScene.add.rectangle(0, 0, gScene.game.canvas.width / 6, gScene.game.canvas.height / 6, 0x262626);
this.evolutionBgOverlay = globalScene.add.rectangle(0, 0, globalScene.game.canvas.width / 6, globalScene.game.canvas.height / 6, 0x262626);
this.evolutionBgOverlay.setOrigin(0, 0);
this.evolutionBgOverlay.setAlpha(0);
this.evolutionContainer.add(this.evolutionBgOverlay);
const getPokemonSprite = () => {
const ret = gScene.addPokemonSprite(this.pokemon, this.evolutionBaseBg.displayWidth / 2, this.evolutionBaseBg.displayHeight / 2, "pkmn__sub");
ret.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
const ret = globalScene.addPokemonSprite(this.pokemon, this.evolutionBaseBg.displayWidth / 2, this.evolutionBaseBg.displayHeight / 2, "pkmn__sub");
ret.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
return ret;
};
@ -92,14 +92,14 @@ export class EvolutionPhase extends Phase {
this.pokemonEvoTintSprite.setVisible(false);
this.pokemonEvoTintSprite.setTintFill(0xFFFFFF);
this.evolutionOverlay = gScene.add.rectangle(0, -gScene.game.canvas.height / 6, gScene.game.canvas.width / 6, (gScene.game.canvas.height / 6) - 48, 0xFFFFFF);
this.evolutionOverlay = globalScene.add.rectangle(0, -globalScene.game.canvas.height / 6, globalScene.game.canvas.width / 6, (globalScene.game.canvas.height / 6) - 48, 0xFFFFFF);
this.evolutionOverlay.setOrigin(0, 0);
this.evolutionOverlay.setAlpha(0);
gScene.ui.add(this.evolutionOverlay);
globalScene.ui.add(this.evolutionOverlay);
[ this.pokemonSprite, this.pokemonTintSprite, this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => {
sprite.play(this.pokemon.getSpriteKey(true));
sprite.setPipeline(gScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) });
sprite.setPipeline(globalScene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) });
sprite.setPipelineData("ignoreTimeTint", true);
sprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey());
sprite.setPipelineData("shiny", this.pokemon.shiny);
@ -117,10 +117,10 @@ export class EvolutionPhase extends Phase {
}
doEvolution(): void {
const evolutionHandler = gScene.ui.getHandler() as EvolutionSceneHandler;
const evolutionHandler = globalScene.ui.getHandler() as EvolutionSceneHandler;
const preName = getPokemonNameWithAffix(this.pokemon);
gScene.ui.showText(i18next.t("menu:evolving", { pokemonName: preName }), null, () => {
globalScene.ui.showText(i18next.t("menu:evolving", { pokemonName: preName }), null, () => {
this.pokemon.cry();
this.pokemon.getPossibleEvolution(this.evolution).then(evolvedPokemon => {
@ -139,17 +139,17 @@ export class EvolutionPhase extends Phase {
});
});
gScene.time.delayedCall(1000, () => {
const evolutionBgm = gScene.playSoundWithoutBgm("evolution");
gScene.tweens.add({
globalScene.time.delayedCall(1000, () => {
const evolutionBgm = globalScene.playSoundWithoutBgm("evolution");
globalScene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 1,
delay: 500,
duration: 1500,
ease: "Sine.easeOut",
onComplete: () => {
gScene.time.delayedCall(1000, () => {
gScene.tweens.add({
globalScene.time.delayedCall(1000, () => {
globalScene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 0,
duration: 250
@ -157,9 +157,9 @@ export class EvolutionPhase extends Phase {
this.evolutionBg.setVisible(true);
this.evolutionBg.play();
});
gScene.playSound("se/charge");
globalScene.playSound("se/charge");
this.doSpiralUpward();
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
from: 0,
to: 1,
duration: 2000,
@ -168,10 +168,10 @@ export class EvolutionPhase extends Phase {
},
onComplete: () => {
this.pokemonSprite.setVisible(false);
gScene.time.delayedCall(1100, () => {
gScene.playSound("se/beam");
globalScene.time.delayedCall(1100, () => {
globalScene.playSound("se/beam");
this.doArcDownward();
gScene.time.delayedCall(1500, () => {
globalScene.time.delayedCall(1500, () => {
this.pokemonEvoTintSprite.setScale(0.25);
this.pokemonEvoTintSprite.setVisible(true);
evolutionHandler.canCancel = true;
@ -180,7 +180,7 @@ export class EvolutionPhase extends Phase {
this.pokemonSprite.setVisible(true);
this.pokemonTintSprite.setScale(1);
gScene.tweens.add({
globalScene.tweens.add({
targets: [ this.evolutionBg, this.pokemonTintSprite, this.pokemonEvoSprite, this.pokemonEvoTintSprite ],
alpha: 0,
duration: 250,
@ -189,47 +189,47 @@ export class EvolutionPhase extends Phase {
}
});
SoundFade.fadeOut(gScene, evolutionBgm, 100);
SoundFade.fadeOut(globalScene, evolutionBgm, 100);
gScene.unshiftPhase(new EndEvolutionPhase());
globalScene.unshiftPhase(new EndEvolutionPhase());
gScene.ui.showText(i18next.t("menu:stoppedEvolving", { pokemonName: preName }), null, () => {
gScene.ui.showText(i18next.t("menu:pauseEvolutionsQuestion", { pokemonName: preName }), null, () => {
globalScene.ui.showText(i18next.t("menu:stoppedEvolving", { pokemonName: preName }), null, () => {
globalScene.ui.showText(i18next.t("menu:pauseEvolutionsQuestion", { pokemonName: preName }), null, () => {
const end = () => {
gScene.ui.showText("", 0);
gScene.playBgm();
globalScene.ui.showText("", 0);
globalScene.playBgm();
evolvedPokemon.destroy();
this.end();
};
gScene.ui.setOverlayMode(Mode.CONFIRM, () => {
gScene.ui.revertMode();
globalScene.ui.setOverlayMode(Mode.CONFIRM, () => {
globalScene.ui.revertMode();
this.pokemon.pauseEvolutions = true;
gScene.ui.showText(i18next.t("menu:evolutionsPaused", { pokemonName: preName }), null, end, 3000);
globalScene.ui.showText(i18next.t("menu:evolutionsPaused", { pokemonName: preName }), null, end, 3000);
}, () => {
gScene.ui.revertMode();
gScene.time.delayedCall(3000, end);
globalScene.ui.revertMode();
globalScene.time.delayedCall(3000, end);
});
});
}, null, true);
return;
}
gScene.playSound("se/sparkle");
globalScene.playSound("se/sparkle");
this.pokemonEvoSprite.setVisible(true);
this.doCircleInward();
gScene.time.delayedCall(900, () => {
globalScene.time.delayedCall(900, () => {
evolutionHandler.canCancel = false;
this.pokemon.evolve(this.evolution, this.pokemon.species).then(() => {
const levelMoves = this.pokemon.getLevelMoves(this.lastLevel + 1, true);
for (const lm of levelMoves) {
gScene.unshiftPhase(new LearnMovePhase(gScene.getParty().indexOf(this.pokemon), lm[1]));
globalScene.unshiftPhase(new LearnMovePhase(globalScene.getParty().indexOf(this.pokemon), lm[1]));
}
gScene.unshiftPhase(new EndEvolutionPhase());
globalScene.unshiftPhase(new EndEvolutionPhase());
gScene.playSound("se/shine");
globalScene.playSound("se/shine");
this.doSpray();
gScene.tweens.add({
globalScene.tweens.add({
targets: this.evolutionOverlay,
alpha: 1,
duration: 250,
@ -237,27 +237,27 @@ export class EvolutionPhase extends Phase {
onComplete: () => {
this.evolutionBgOverlay.setAlpha(1);
this.evolutionBg.setVisible(false);
gScene.tweens.add({
globalScene.tweens.add({
targets: [ this.evolutionOverlay, this.pokemonEvoTintSprite ],
alpha: 0,
duration: 2000,
delay: 150,
easing: "Sine.easeIn",
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 0,
duration: 250,
onComplete: () => {
SoundFade.fadeOut(gScene, evolutionBgm, 100);
gScene.time.delayedCall(250, () => {
SoundFade.fadeOut(globalScene, evolutionBgm, 100);
globalScene.time.delayedCall(250, () => {
this.pokemon.cry();
gScene.time.delayedCall(1250, () => {
gScene.playSoundWithoutBgm("evolution_fanfare");
globalScene.time.delayedCall(1250, () => {
globalScene.playSoundWithoutBgm("evolution_fanfare");
evolvedPokemon.destroy();
gScene.ui.showText(i18next.t("menu:evolutionDone", { pokemonName: preName, evolvedPokemonName: this.pokemon.name }), null, () => this.end(), null, true, Utils.fixedInt(4000));
gScene.time.delayedCall(Utils.fixedInt(4250), () => gScene.playBgm());
globalScene.ui.showText(i18next.t("menu:evolutionDone", { pokemonName: preName, evolvedPokemonName: this.pokemon.name }), null, () => this.end(), null, true, Utils.fixedInt(4000));
globalScene.time.delayedCall(Utils.fixedInt(4250), () => globalScene.playBgm());
});
});
}
@ -283,7 +283,7 @@ export class EvolutionPhase extends Phase {
doSpiralUpward() {
let f = 0;
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
repeat: 64,
duration: Utils.getFrameMs(1),
onRepeat: () => {
@ -302,7 +302,7 @@ export class EvolutionPhase extends Phase {
doArcDownward() {
let f = 0;
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
repeat: 96,
duration: Utils.getFrameMs(1),
onRepeat: () => {
@ -320,16 +320,16 @@ export class EvolutionPhase extends Phase {
doCycle(l: number, lastCycle: integer = 15): Promise<boolean> {
return new Promise(resolve => {
const evolutionHandler = gScene.ui.getHandler() as EvolutionSceneHandler;
const evolutionHandler = globalScene.ui.getHandler() as EvolutionSceneHandler;
const isLastCycle = l === lastCycle;
gScene.tweens.add({
globalScene.tweens.add({
targets: this.pokemonTintSprite,
scale: 0.25,
ease: "Cubic.easeInOut",
duration: 500 / l,
yoyo: !isLastCycle
});
gScene.tweens.add({
globalScene.tweens.add({
targets: this.pokemonEvoTintSprite,
scale: 1,
ease: "Cubic.easeInOut",
@ -353,7 +353,7 @@ export class EvolutionPhase extends Phase {
doCircleInward() {
let f = 0;
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
repeat: 48,
duration: Utils.getFrameMs(1),
onRepeat: () => {
@ -374,7 +374,7 @@ export class EvolutionPhase extends Phase {
doSpray() {
let f = 0;
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
repeat: 48,
duration: Utils.getFrameMs(1),
onRepeat: () => {
@ -392,13 +392,13 @@ export class EvolutionPhase extends Phase {
doSpiralUpwardParticle(trigIndex: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 2;
const particle = gScene.add.image(initialX, 0, "evo_sparkle");
const particle = globalScene.add.image(initialX, 0, "evo_sparkle");
this.evolutionContainer.add(particle);
let f = 0;
let amp = 48;
const particleTimer = gScene.tweens.addCounter({
const particleTimer = globalScene.tweens.addCounter({
repeat: -1,
duration: Utils.getFrameMs(1),
onRepeat: () => {
@ -428,14 +428,14 @@ export class EvolutionPhase extends Phase {
doArcDownParticle(trigIndex: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 2;
const particle = gScene.add.image(initialX, 0, "evo_sparkle");
const particle = globalScene.add.image(initialX, 0, "evo_sparkle");
particle.setScale(0.5);
this.evolutionContainer.add(particle);
let f = 0;
let amp = 8;
const particleTimer = gScene.tweens.addCounter({
const particleTimer = globalScene.tweens.addCounter({
repeat: -1,
duration: Utils.getFrameMs(1),
onRepeat: () => {
@ -462,12 +462,12 @@ export class EvolutionPhase extends Phase {
doCircleInwardParticle(trigIndex: integer, speed: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 2;
const initialY = this.evolutionBaseBg.displayHeight / 2;
const particle = gScene.add.image(initialX, initialY, "evo_sparkle");
const particle = globalScene.add.image(initialX, initialY, "evo_sparkle");
this.evolutionContainer.add(particle);
let amp = 120;
const particleTimer = gScene.tweens.addCounter({
const particleTimer = globalScene.tweens.addCounter({
repeat: -1,
duration: Utils.getFrameMs(1),
onRepeat: () => {
@ -494,7 +494,7 @@ export class EvolutionPhase extends Phase {
doSprayParticle(trigIndex: integer) {
const initialX = this.evolutionBaseBg.displayWidth / 2;
const initialY = this.evolutionBaseBg.displayHeight / 2;
const particle = gScene.add.image(initialX, initialY, "evo_sparkle");
const particle = globalScene.add.image(initialX, initialY, "evo_sparkle");
this.evolutionContainer.add(particle);
let f = 0;
@ -502,7 +502,7 @@ export class EvolutionPhase extends Phase {
const speed = 3 - Utils.randInt(8);
const amp = 48 + Utils.randInt(64);
const particleTimer = gScene.tweens.addCounter({
const particleTimer = globalScene.tweens.addCounter({
repeat: -1,
duration: Utils.getFrameMs(1),
onRepeat: () => {

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { getPokemonNameWithAffix } from "#app/messages";
import { ExpBoosterModifier } from "#app/modifier/modifier";
import i18next from "i18next";
@ -20,14 +20,14 @@ export class ExpPhase extends PlayerPartyMemberPokemonPhase {
const pokemon = this.getPokemon();
const exp = new Utils.NumberHolder(this.expValue);
gScene.applyModifiers(ExpBoosterModifier, true, exp);
globalScene.applyModifiers(ExpBoosterModifier, true, exp);
exp.value = Math.floor(exp.value);
gScene.ui.showText(i18next.t("battle:expGain", { pokemonName: getPokemonNameWithAffix(pokemon), exp: exp.value }), null, () => {
globalScene.ui.showText(i18next.t("battle:expGain", { pokemonName: getPokemonNameWithAffix(pokemon), exp: exp.value }), null, () => {
const lastLevel = pokemon.level;
pokemon.addExp(exp.value);
const newLevel = pokemon.level;
if (newLevel > lastLevel) {
gScene.unshiftPhase(new LevelUpPhase(this.partyMemberIndex, lastLevel, newLevel));
globalScene.unshiftPhase(new LevelUpPhase(this.partyMemberIndex, lastLevel, newLevel));
}
pokemon.updateInfo().then(() => this.end());
}, null, true);

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { BattlerIndex, BattleType } from "#app/battle";
import { applyPostFaintAbAttrs, PostFaintAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr } from "#app/data/ability";
import { BattlerTagLapseType, DestinyBondTag } from "#app/data/battler-tags";
@ -54,22 +54,22 @@ export class FaintPhase extends PokemonPhase {
}
if (!this.preventEndure) {
const instantReviveModifier = gScene.applyModifier(PokemonInstantReviveModifier, this.player, this.getPokemon()) as PokemonInstantReviveModifier;
const instantReviveModifier = globalScene.applyModifier(PokemonInstantReviveModifier, this.player, this.getPokemon()) as PokemonInstantReviveModifier;
if (instantReviveModifier) {
if (!--instantReviveModifier.stackCount) {
gScene.removeModifier(instantReviveModifier);
globalScene.removeModifier(instantReviveModifier);
}
gScene.updateModifiers(this.player);
globalScene.updateModifiers(this.player);
return this.end();
}
}
/** In case the current pokemon was just switched in, make sure it is counted as participating in the combat */
gScene.getPlayerField().forEach((pokemon, i) => {
globalScene.getPlayerField().forEach((pokemon, i) => {
if (pokemon?.isActive(true)) {
if (pokemon.isPlayer()) {
gScene.currentBattle.addParticipant(pokemon as PlayerPokemon);
globalScene.currentBattle.addParticipant(pokemon as PlayerPokemon);
}
}
});
@ -85,27 +85,27 @@ export class FaintPhase extends PokemonPhase {
// Track total times pokemon have been KO'd for supreme overlord/last respects
if (pokemon.isPlayer()) {
gScene.currentBattle.playerFaints += 1;
gScene.currentBattle.playerFaintsHistory.push({ pokemon: pokemon, turn: gScene.currentBattle.turn });
globalScene.currentBattle.playerFaints += 1;
globalScene.currentBattle.playerFaintsHistory.push({ pokemon: pokemon, turn: globalScene.currentBattle.turn });
} else {
gScene.currentBattle.enemyFaints += 1;
gScene.currentBattle.enemyFaintsHistory.push({ pokemon: pokemon, turn: gScene.currentBattle.turn });
globalScene.currentBattle.enemyFaints += 1;
globalScene.currentBattle.enemyFaintsHistory.push({ pokemon: pokemon, turn: globalScene.currentBattle.turn });
}
gScene.queueMessage(i18next.t("battle:fainted", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, true);
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
globalScene.queueMessage(i18next.t("battle:fainted", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, true);
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
if (pokemon.turnData?.attacksReceived?.length) {
const lastAttack = pokemon.turnData.attacksReceived[0];
applyPostFaintAbAttrs(PostFaintAbAttr, pokemon, gScene.getPokemonById(lastAttack.sourceId)!, new PokemonMove(lastAttack.move).getMove(), lastAttack.result); // TODO: is this bang correct?
applyPostFaintAbAttrs(PostFaintAbAttr, pokemon, globalScene.getPokemonById(lastAttack.sourceId)!, new PokemonMove(lastAttack.move).getMove(), lastAttack.result); // TODO: is this bang correct?
} else { //If killed by indirect damage, apply post-faint abilities without providing a last move
applyPostFaintAbAttrs(PostFaintAbAttr, pokemon);
}
const alivePlayField = gScene.getField(true);
const alivePlayField = globalScene.getField(true);
alivePlayField.forEach(p => applyPostKnockOutAbAttrs(PostKnockOutAbAttr, p, pokemon));
if (pokemon.turnData?.attacksReceived?.length) {
const defeatSource = gScene.getPokemonById(pokemon.turnData.attacksReceived[0].sourceId);
const defeatSource = globalScene.getPokemonById(pokemon.turnData.attacksReceived[0].sourceId);
if (defeatSource?.isOnField()) {
applyPostVictoryAbAttrs(PostVictoryAbAttr, defeatSource);
const pvmove = allMoves[pokemon.turnData.attacksReceived[0].move];
@ -120,39 +120,39 @@ export class FaintPhase extends PokemonPhase {
if (this.player) {
/** The total number of Pokemon in the player's party that can legally fight */
const legalPlayerPokemon = gScene.getParty().filter(p => p.isAllowedInBattle());
const legalPlayerPokemon = globalScene.getParty().filter(p => p.isAllowedInBattle());
/** The total number of legal player Pokemon that aren't currently on the field */
const legalPlayerPartyPokemon = legalPlayerPokemon.filter(p => !p.isActive(true));
if (!legalPlayerPokemon.length) {
/** If the player doesn't have any legal Pokemon, end the game */
gScene.unshiftPhase(new GameOverPhase());
} else if (gScene.currentBattle.double && legalPlayerPokemon.length === 1 && legalPlayerPartyPokemon.length === 0) {
globalScene.unshiftPhase(new GameOverPhase());
} else if (globalScene.currentBattle.double && legalPlayerPokemon.length === 1 && legalPlayerPartyPokemon.length === 0) {
/**
* If the player has exactly one Pokemon in total at this point in a double battle, and that Pokemon
* is already on the field, unshift a phase that moves that Pokemon to center position.
*/
gScene.unshiftPhase(new ToggleDoublePositionPhase(true));
globalScene.unshiftPhase(new ToggleDoublePositionPhase(true));
} else if (legalPlayerPartyPokemon.length > 0) {
/**
* If previous conditions weren't met, and the player has at least 1 legal Pokemon off the field,
* push a phase that prompts the player to summon a Pokemon from their party.
*/
gScene.pushPhase(new SwitchPhase(SwitchType.SWITCH, this.fieldIndex, true, false));
globalScene.pushPhase(new SwitchPhase(SwitchType.SWITCH, this.fieldIndex, true, false));
}
} else {
gScene.unshiftPhase(new VictoryPhase(this.battlerIndex));
if ([ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(gScene.currentBattle.battleType)) {
const hasReservePartyMember = !!gScene.getEnemyParty().filter(p => p.isActive() && !p.isOnField() && p.trainerSlot === (pokemon as EnemyPokemon).trainerSlot).length;
globalScene.unshiftPhase(new VictoryPhase(this.battlerIndex));
if ([ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(globalScene.currentBattle.battleType)) {
const hasReservePartyMember = !!globalScene.getEnemyParty().filter(p => p.isActive() && !p.isOnField() && p.trainerSlot === (pokemon as EnemyPokemon).trainerSlot).length;
if (hasReservePartyMember) {
gScene.pushPhase(new SwitchSummonPhase(SwitchType.SWITCH, this.fieldIndex, -1, false, false));
globalScene.pushPhase(new SwitchSummonPhase(SwitchType.SWITCH, this.fieldIndex, -1, false, false));
}
}
}
// in double battles redirect potential moves off fainted pokemon
if (gScene.currentBattle.double) {
if (globalScene.currentBattle.double) {
const allyPokemon = pokemon.getAlly();
gScene.redirectPokemonMoves(pokemon, allyPokemon);
globalScene.redirectPokemonMoves(pokemon, allyPokemon);
}
pokemon.faintCry(() => {
@ -160,8 +160,8 @@ export class FaintPhase extends PokemonPhase {
pokemon.addFriendship(-FRIENDSHIP_LOSS_FROM_FAINT);
}
pokemon.hideInfo();
gScene.playSound("se/faint");
gScene.tweens.add({
globalScene.playSound("se/faint");
globalScene.tweens.add({
targets: pokemon,
duration: 500,
y: pokemon.y + 150,
@ -169,17 +169,17 @@ export class FaintPhase extends PokemonPhase {
onComplete: () => {
pokemon.resetSprite();
pokemon.lapseTags(BattlerTagLapseType.FAINT);
gScene.getField(true).filter(p => p !== pokemon).forEach(p => p.removeTagsBySourceId(pokemon.id));
globalScene.getField(true).filter(p => p !== pokemon).forEach(p => p.removeTagsBySourceId(pokemon.id));
pokemon.y -= 150;
pokemon.trySetStatus(StatusEffect.FAINT);
if (pokemon.isPlayer()) {
gScene.currentBattle.removeFaintedParticipant(pokemon as PlayerPokemon);
globalScene.currentBattle.removeFaintedParticipant(pokemon as PlayerPokemon);
} else {
gScene.addFaintedEnemyScore(pokemon as EnemyPokemon);
gScene.currentBattle.addPostBattleLoot(pokemon as EnemyPokemon);
globalScene.addFaintedEnemyScore(pokemon as EnemyPokemon);
globalScene.currentBattle.addPostBattleLoot(pokemon as EnemyPokemon);
}
gScene.field.remove(pokemon);
globalScene.field.remove(pokemon);
this.end();
}
});
@ -187,16 +187,16 @@ export class FaintPhase extends PokemonPhase {
}
tryOverrideForBattleSpec(): boolean {
switch (gScene.currentBattle.battleSpec) {
switch (globalScene.currentBattle.battleSpec) {
case BattleSpec.FINAL_BOSS:
if (!this.player) {
const enemy = this.getPokemon();
if (enemy.formIndex) {
gScene.ui.showDialogue(battleSpecDialogue[BattleSpec.FINAL_BOSS].secondStageWin, enemy.species.name, null, () => this.doFaint());
globalScene.ui.showDialogue(battleSpecDialogue[BattleSpec.FINAL_BOSS].secondStageWin, enemy.species.name, null, () => this.doFaint());
} else {
// Final boss' HP threshold has been bypassed; cancel faint and force check for 2nd phase
enemy.hp++;
gScene.unshiftPhase(new DamagePhase(enemy.getBattlerIndex(), 0, HitResult.OTHER));
globalScene.unshiftPhase(new DamagePhase(enemy.getBattlerIndex(), 0, HitResult.OTHER));
this.end();
}
return true;

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import Pokemon from "#app/field/pokemon";
import { BattlePhase } from "./battle-phase";
@ -6,7 +6,7 @@ type PokemonFunc = (pokemon: Pokemon) => void;
export abstract class FieldPhase extends BattlePhase {
executeForAll(func: PokemonFunc): void {
const field = gScene.getField(true).filter(p => p.summonData);
const field = globalScene.getField(true).filter(p => p.summonData);
field.forEach(pokemon => func(pokemon));
}
}

View File

@ -1,4 +1,4 @@
import { gScene } from "../battle-scene";
import { globalScene } from "../battle-scene";
import * as Utils from "../utils";
import { achvs } from "../system/achv";
import { SpeciesFormChange, getSpeciesFormChangeMessage } from "../data/pokemon-forms";
@ -30,7 +30,7 @@ export class FormChangePhase extends EvolutionPhase {
if (!this.modal) {
return super.setMode();
}
return gScene.ui.setOverlayMode(Mode.EVOLUTION_SCENE);
return globalScene.ui.setOverlayMode(Mode.EVOLUTION_SCENE);
}
doEvolution(): void {
@ -52,16 +52,16 @@ export class FormChangePhase extends EvolutionPhase {
});
});
gScene.time.delayedCall(250, () => {
gScene.tweens.add({
globalScene.time.delayedCall(250, () => {
globalScene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 1,
delay: 500,
duration: 1500,
ease: "Sine.easeOut",
onComplete: () => {
gScene.time.delayedCall(1000, () => {
gScene.tweens.add({
globalScene.time.delayedCall(1000, () => {
globalScene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 0,
duration: 250
@ -69,9 +69,9 @@ export class FormChangePhase extends EvolutionPhase {
this.evolutionBg.setVisible(true);
this.evolutionBg.play();
});
gScene.playSound("se/charge");
globalScene.playSound("se/charge");
this.doSpiralUpward();
gScene.tweens.addCounter({
globalScene.tweens.addCounter({
from: 0,
to: 1,
duration: 2000,
@ -80,25 +80,25 @@ export class FormChangePhase extends EvolutionPhase {
},
onComplete: () => {
this.pokemonSprite.setVisible(false);
gScene.time.delayedCall(1100, () => {
gScene.playSound("se/beam");
globalScene.time.delayedCall(1100, () => {
globalScene.playSound("se/beam");
this.doArcDownward();
gScene.time.delayedCall(1000, () => {
globalScene.time.delayedCall(1000, () => {
this.pokemonEvoTintSprite.setScale(0.25);
this.pokemonEvoTintSprite.setVisible(true);
this.doCycle(1, 1).then(_success => {
gScene.playSound("se/sparkle");
globalScene.playSound("se/sparkle");
this.pokemonEvoSprite.setVisible(true);
this.doCircleInward();
gScene.time.delayedCall(900, () => {
globalScene.time.delayedCall(900, () => {
this.pokemon.changeForm(this.formChange).then(() => {
if (!this.modal) {
gScene.unshiftPhase(new EndEvolutionPhase());
globalScene.unshiftPhase(new EndEvolutionPhase());
}
gScene.playSound("se/shine");
globalScene.playSound("se/shine");
this.doSpray();
gScene.tweens.add({
globalScene.tweens.add({
targets: this.evolutionOverlay,
alpha: 1,
duration: 250,
@ -106,36 +106,36 @@ export class FormChangePhase extends EvolutionPhase {
onComplete: () => {
this.evolutionBgOverlay.setAlpha(1);
this.evolutionBg.setVisible(false);
gScene.tweens.add({
globalScene.tweens.add({
targets: [ this.evolutionOverlay, this.pokemonEvoTintSprite ],
alpha: 0,
duration: 2000,
delay: 150,
easing: "Sine.easeIn",
onComplete: () => {
gScene.tweens.add({
globalScene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 0,
duration: 250,
onComplete: () => {
gScene.time.delayedCall(250, () => {
globalScene.time.delayedCall(250, () => {
this.pokemon.cry();
gScene.time.delayedCall(1250, () => {
globalScene.time.delayedCall(1250, () => {
let playEvolutionFanfare = false;
if (this.formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1) {
gScene.validateAchv(achvs.MEGA_EVOLVE);
globalScene.validateAchv(achvs.MEGA_EVOLVE);
playEvolutionFanfare = true;
} else if (this.formChange.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1 || this.formChange.formKey.indexOf(SpeciesFormKey.ETERNAMAX) > -1) {
gScene.validateAchv(achvs.GIGANTAMAX);
globalScene.validateAchv(achvs.GIGANTAMAX);
playEvolutionFanfare = true;
}
const delay = playEvolutionFanfare ? 4000 : 1750;
gScene.playSoundWithoutBgm(playEvolutionFanfare ? "evolution_fanfare" : "minor_fanfare");
globalScene.playSoundWithoutBgm(playEvolutionFanfare ? "evolution_fanfare" : "minor_fanfare");
transformedPokemon.destroy();
gScene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), null, true, Utils.fixedInt(delay));
gScene.time.delayedCall(Utils.fixedInt(delay + 250), () => gScene.playBgm());
globalScene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), null, true, Utils.fixedInt(delay));
globalScene.time.delayedCall(Utils.fixedInt(delay + 250), () => globalScene.playBgm());
});
});
}
@ -160,9 +160,9 @@ export class FormChangePhase extends EvolutionPhase {
end(): void {
this.pokemon.findAndRemoveTags(t => t.tagType === BattlerTagType.AUTOTOMIZED);
if (this.modal) {
gScene.ui.revertMode().then(() => {
if (gScene.ui.getMode() === Mode.PARTY) {
const partyUiHandler = gScene.ui.getHandler() as PartyUiHandler;
globalScene.ui.revertMode().then(() => {
if (globalScene.ui.getMode() === Mode.PARTY) {
const partyUiHandler = globalScene.ui.getHandler() as PartyUiHandler;
partyUiHandler.clearPartySlots();
partyUiHandler.populatePartySlots();
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { ModifierTypeFunc } from "#app/modifier/modifier-type";
import { Mode } from "#app/ui/ui";
import i18next from "i18next";
@ -12,13 +12,13 @@ export class GameOverModifierRewardPhase extends ModifierRewardPhase {
doReward(): Promise<void> {
return new Promise<void>(resolve => {
const newModifier = this.modifierType.newModifier();
gScene.addModifier(newModifier).then(() => {
globalScene.addModifier(newModifier).then(() => {
// Sound loaded into game as is
gScene.playSound("level_up_fanfare");
gScene.ui.setMode(Mode.MESSAGE);
gScene.ui.fadeIn(250).then(() => {
gScene.ui.showText(i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }), null, () => {
gScene.time.delayedCall(1500, () => gScene.arenaBg.setVisible(true));
globalScene.playSound("level_up_fanfare");
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.fadeIn(250).then(() => {
globalScene.ui.showText(i18next.t("battle:rewardGain", { modifierName: newModifier?.type.name }), null, () => {
globalScene.time.delayedCall(1500, () => globalScene.arenaBg.setVisible(true));
resolve();
}, null, true, 1500);
});

View File

@ -1,6 +1,6 @@
import { clientSessionId } from "#app/account";
import { BattleType } from "#app/battle";
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { getCharVariantFromDialogue } from "#app/data/dialogue";
import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
@ -38,47 +38,47 @@ export class GameOverPhase extends BattlePhase {
super.start();
// Failsafe if players somehow skip floor 200 in classic mode
if (gScene.gameMode.isClassic && gScene.currentBattle.waveIndex > 200) {
if (globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex > 200) {
this.victory = true;
}
// Handle Mystery Encounter special Game Over cases
// Situations such as when player lost a battle, but it isn't treated as full Game Over
if (!this.victory && gScene.currentBattle.mysteryEncounter?.onGameOver && !gScene.currentBattle.mysteryEncounter.onGameOver()) {
if (!this.victory && globalScene.currentBattle.mysteryEncounter?.onGameOver && !globalScene.currentBattle.mysteryEncounter.onGameOver()) {
// Do not end the game
return this.end();
}
// Otherwise, continue standard Game Over logic
if (this.victory && gScene.gameMode.isEndless) {
const genderIndex = gScene.gameData.gender ?? PlayerGender.UNSET;
if (this.victory && globalScene.gameMode.isEndless) {
const genderIndex = globalScene.gameData.gender ?? PlayerGender.UNSET;
const genderStr = PlayerGender[genderIndex].toLowerCase();
gScene.ui.showDialogue(i18next.t("miscDialogue:ending_endless", { context: genderStr }), i18next.t("miscDialogue:ending_name"), 0, () => this.handleGameOver());
} else if (this.victory || !gScene.enableRetries) {
globalScene.ui.showDialogue(i18next.t("miscDialogue:ending_endless", { context: genderStr }), i18next.t("miscDialogue:ending_name"), 0, () => this.handleGameOver());
} else if (this.victory || !globalScene.enableRetries) {
this.handleGameOver();
} else {
gScene.ui.showText(i18next.t("battle:retryBattle"), null, () => {
gScene.ui.setMode(Mode.CONFIRM, () => {
gScene.ui.fadeOut(1250).then(() => {
gScene.reset();
gScene.clearPhaseQueue();
gScene.gameData.loadSession(gScene.sessionSlotId).then(() => {
gScene.pushPhase(new EncounterPhase(true));
globalScene.ui.showText(i18next.t("battle:retryBattle"), null, () => {
globalScene.ui.setMode(Mode.CONFIRM, () => {
globalScene.ui.fadeOut(1250).then(() => {
globalScene.reset();
globalScene.clearPhaseQueue();
globalScene.gameData.loadSession(globalScene.sessionSlotId).then(() => {
globalScene.pushPhase(new EncounterPhase(true));
const availablePartyMembers = gScene.getParty().filter(p => p.isAllowedInBattle()).length;
const availablePartyMembers = globalScene.getParty().filter(p => p.isAllowedInBattle()).length;
gScene.pushPhase(new SummonPhase(0));
if (gScene.currentBattle.double && availablePartyMembers > 1) {
gScene.pushPhase(new SummonPhase(1));
globalScene.pushPhase(new SummonPhase(0));
if (globalScene.currentBattle.double && availablePartyMembers > 1) {
globalScene.pushPhase(new SummonPhase(1));
}
if (gScene.currentBattle.waveIndex > 1 && gScene.currentBattle.battleType !== BattleType.TRAINER) {
gScene.pushPhase(new CheckSwitchPhase(0, gScene.currentBattle.double));
if (gScene.currentBattle.double && availablePartyMembers > 1) {
gScene.pushPhase(new CheckSwitchPhase(1, gScene.currentBattle.double));
if (globalScene.currentBattle.waveIndex > 1 && globalScene.currentBattle.battleType !== BattleType.TRAINER) {
globalScene.pushPhase(new CheckSwitchPhase(0, globalScene.currentBattle.double));
if (globalScene.currentBattle.double && availablePartyMembers > 1) {
globalScene.pushPhase(new CheckSwitchPhase(1, globalScene.currentBattle.double));
}
}
gScene.ui.fadeIn(1250);
globalScene.ui.fadeIn(1250);
this.end();
});
});
@ -89,38 +89,38 @@ export class GameOverPhase extends BattlePhase {
handleGameOver(): void {
const doGameOver = (newClear: boolean) => {
gScene.disableMenu = true;
gScene.time.delayedCall(1000, () => {
globalScene.disableMenu = true;
globalScene.time.delayedCall(1000, () => {
let firstClear = false;
if (this.victory && newClear) {
if (gScene.gameMode.isClassic) {
firstClear = gScene.validateAchv(achvs.CLASSIC_VICTORY);
gScene.validateAchv(achvs.UNEVOLVED_CLASSIC_VICTORY);
gScene.gameData.gameStats.sessionsWon++;
for (const pokemon of gScene.getParty()) {
if (globalScene.gameMode.isClassic) {
firstClear = globalScene.validateAchv(achvs.CLASSIC_VICTORY);
globalScene.validateAchv(achvs.UNEVOLVED_CLASSIC_VICTORY);
globalScene.gameData.gameStats.sessionsWon++;
for (const pokemon of globalScene.getParty()) {
this.awardRibbon(pokemon);
if (pokemon.species.getRootSpeciesId() !== pokemon.species.getRootSpeciesId(true)) {
this.awardRibbon(pokemon, true);
}
}
} else if (gScene.gameMode.isDaily && newClear) {
gScene.gameData.gameStats.dailyRunSessionsWon++;
} else if (globalScene.gameMode.isDaily && newClear) {
globalScene.gameData.gameStats.dailyRunSessionsWon++;
}
}
gScene.gameData.saveRunHistory(gScene.gameData.getSessionSaveData(), this.victory);
globalScene.gameData.saveRunHistory(globalScene.gameData.getSessionSaveData(), this.victory);
const fadeDuration = this.victory ? 10000 : 5000;
gScene.fadeOutBgm(fadeDuration, true);
const activeBattlers = gScene.getField().filter(p => p?.isActive(true));
globalScene.fadeOutBgm(fadeDuration, true);
const activeBattlers = globalScene.getField().filter(p => p?.isActive(true));
activeBattlers.map(p => p.hideInfo());
gScene.ui.fadeOut(fadeDuration).then(() => {
globalScene.ui.fadeOut(fadeDuration).then(() => {
activeBattlers.map(a => a.setVisible(false));
gScene.setFieldScale(1, true);
gScene.clearPhaseQueue();
gScene.ui.clearText();
globalScene.setFieldScale(1, true);
globalScene.clearPhaseQueue();
globalScene.ui.clearText();
if (this.victory && gScene.gameMode.isChallenge) {
gScene.gameMode.challenges.forEach(c => gScene.validateAchvs(ChallengeAchv, c));
if (this.victory && globalScene.gameMode.isChallenge) {
globalScene.gameMode.challenges.forEach(c => globalScene.validateAchvs(ChallengeAchv, c));
}
const clear = (endCardPhase?: EndCardPhase) => {
@ -129,31 +129,31 @@ export class GameOverPhase extends BattlePhase {
}
if (this.victory && newClear) {
for (const species of this.firstRibbons) {
gScene.unshiftPhase(new RibbonModifierRewardPhase(modifierTypes.VOUCHER_PLUS, species));
globalScene.unshiftPhase(new RibbonModifierRewardPhase(modifierTypes.VOUCHER_PLUS, species));
}
if (!firstClear) {
gScene.unshiftPhase(new GameOverModifierRewardPhase(modifierTypes.VOUCHER_PREMIUM));
globalScene.unshiftPhase(new GameOverModifierRewardPhase(modifierTypes.VOUCHER_PREMIUM));
}
}
gScene.pushPhase(new PostGameOverPhase(endCardPhase));
globalScene.pushPhase(new PostGameOverPhase(endCardPhase));
this.end();
};
if (this.victory && gScene.gameMode.isClassic) {
if (this.victory && globalScene.gameMode.isClassic) {
const dialogueKey = "miscDialogue:ending";
if (!gScene.ui.shouldSkipDialogue(dialogueKey)) {
gScene.ui.fadeIn(500).then(() => {
const genderIndex = gScene.gameData.gender ?? PlayerGender.UNSET;
if (!globalScene.ui.shouldSkipDialogue(dialogueKey)) {
globalScene.ui.fadeIn(500).then(() => {
const genderIndex = globalScene.gameData.gender ?? PlayerGender.UNSET;
const genderStr = PlayerGender[genderIndex].toLowerCase();
// Dialogue has to be retrieved so that the rival's expressions can be loaded and shown via getCharVariantFromDialogue
const dialogue = i18next.t(dialogueKey, { context: genderStr });
gScene.charSprite.showCharacter(`rival_${gScene.gameData.gender === PlayerGender.FEMALE ? "m" : "f"}`, getCharVariantFromDialogue(dialogue)).then(() => {
gScene.ui.showDialogue(dialogueKey, gScene.gameData.gender === PlayerGender.FEMALE ? trainerConfigs[TrainerType.RIVAL].name : trainerConfigs[TrainerType.RIVAL].nameFemale, null, () => {
gScene.ui.fadeOut(500).then(() => {
gScene.charSprite.hide().then(() => {
globalScene.charSprite.showCharacter(`rival_${globalScene.gameData.gender === PlayerGender.FEMALE ? "m" : "f"}`, getCharVariantFromDialogue(dialogue)).then(() => {
globalScene.ui.showDialogue(dialogueKey, globalScene.gameData.gender === PlayerGender.FEMALE ? trainerConfigs[TrainerType.RIVAL].name : trainerConfigs[TrainerType.RIVAL].nameFemale, null, () => {
globalScene.ui.fadeOut(500).then(() => {
globalScene.charSprite.hide().then(() => {
const endCardPhase = new EndCardPhase();
gScene.unshiftPhase(endCardPhase);
globalScene.unshiftPhase(endCardPhase);
clear(endCardPhase);
});
});
@ -162,7 +162,7 @@ export class GameOverPhase extends BattlePhase {
});
} else {
const endCardPhase = new EndCardPhase();
gScene.unshiftPhase(endCardPhase);
globalScene.unshiftPhase(endCardPhase);
clear(endCardPhase);
}
} else {
@ -177,11 +177,11 @@ export class GameOverPhase extends BattlePhase {
If Offline, execute offlineNewClear(), a localStorage implementation of newClear daily run checks */
if (this.victory) {
if (!Utils.isLocal) {
Utils.apiFetch(`savedata/session/newclear?slot=${gScene.sessionSlotId}&clientSessionId=${clientSessionId}`, true)
Utils.apiFetch(`savedata/session/newclear?slot=${globalScene.sessionSlotId}&clientSessionId=${clientSessionId}`, true)
.then(response => response.json())
.then(newClear => doGameOver(newClear));
} else {
gScene.gameData.offlineNewClear().then(result => {
globalScene.gameData.offlineNewClear().then(result => {
doGameOver(result);
});
}
@ -191,25 +191,25 @@ export class GameOverPhase extends BattlePhase {
}
handleUnlocks(): void {
if (this.victory && gScene.gameMode.isClassic) {
if (!gScene.gameData.unlocks[Unlockables.ENDLESS_MODE]) {
gScene.unshiftPhase(new UnlockPhase(Unlockables.ENDLESS_MODE));
if (this.victory && globalScene.gameMode.isClassic) {
if (!globalScene.gameData.unlocks[Unlockables.ENDLESS_MODE]) {
globalScene.unshiftPhase(new UnlockPhase(Unlockables.ENDLESS_MODE));
}
if (gScene.getParty().filter(p => p.fusionSpecies).length && !gScene.gameData.unlocks[Unlockables.SPLICED_ENDLESS_MODE]) {
gScene.unshiftPhase(new UnlockPhase(Unlockables.SPLICED_ENDLESS_MODE));
if (globalScene.getParty().filter(p => p.fusionSpecies).length && !globalScene.gameData.unlocks[Unlockables.SPLICED_ENDLESS_MODE]) {
globalScene.unshiftPhase(new UnlockPhase(Unlockables.SPLICED_ENDLESS_MODE));
}
if (!gScene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE]) {
gScene.unshiftPhase(new UnlockPhase(Unlockables.MINI_BLACK_HOLE));
if (!globalScene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE]) {
globalScene.unshiftPhase(new UnlockPhase(Unlockables.MINI_BLACK_HOLE));
}
if (!gScene.gameData.unlocks[Unlockables.EVIOLITE] && gScene.getParty().some(p => p.getSpeciesForm(true).speciesId in pokemonEvolutions)) {
gScene.unshiftPhase(new UnlockPhase(Unlockables.EVIOLITE));
if (!globalScene.gameData.unlocks[Unlockables.EVIOLITE] && globalScene.getParty().some(p => p.getSpeciesForm(true).speciesId in pokemonEvolutions)) {
globalScene.unshiftPhase(new UnlockPhase(Unlockables.EVIOLITE));
}
}
}
awardRibbon(pokemon: Pokemon, forStarter: boolean = false): void {
const speciesId = getPokemonSpecies(pokemon.species.speciesId);
const speciesRibbonCount = gScene.gameData.incrementRibbonCount(speciesId, forStarter);
const speciesRibbonCount = globalScene.gameData.incrementRibbonCount(speciesId, forStarter);
// first time classic win, award voucher
if (speciesRibbonCount === 1) {
this.firstRibbons.push(getPokemonSpecies(pokemon.species.getRootSpeciesId(forStarter)));

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { BattlePhase } from "./battle-phase";
export class HidePartyExpBarPhase extends BattlePhase {
@ -9,6 +9,6 @@ export class HidePartyExpBarPhase extends BattlePhase {
start() {
super.start();
gScene.partyExpBar.hide().then(() => this.end());
globalScene.partyExpBar.hide().then(() => this.end());
}
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
import Move, { allMoves } from "#app/data/move";
import { SpeciesFormChangeMoveLearnedTrigger } from "#app/data/pokemon-forms";
@ -48,8 +48,8 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
return this.end();
}
this.messageMode = gScene.ui.getHandler() instanceof EvolutionSceneHandler ? Mode.EVOLUTION_SCENE : Mode.MESSAGE;
gScene.ui.setMode(this.messageMode);
this.messageMode = globalScene.ui.getHandler() instanceof EvolutionSceneHandler ? Mode.EVOLUTION_SCENE : Mode.MESSAGE;
globalScene.ui.setMode(this.messageMode);
// If the Pokemon has less than 4 moves, the new move is added to the largest empty moveset index
// If it has 4 moves, the phase then checks if the player wants to replace the move itself.
if (currentMoveset.length < 4) {
@ -73,12 +73,12 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
const moveLimitReached = i18next.t("battle:learnMoveLimitReached", { pokemonName: getPokemonNameWithAffix(pokemon) });
const shouldReplaceQ = i18next.t("battle:learnMoveReplaceQuestion", { moveName: move.name });
const preQText = [ learnMovePrompt, moveLimitReached ].join("$");
await gScene.ui.showTextPromise(preQText);
await gScene.ui.showTextPromise(shouldReplaceQ, undefined, false);
await gScene.ui.setModeWithoutClear(Mode.CONFIRM,
await globalScene.ui.showTextPromise(preQText);
await globalScene.ui.showTextPromise(shouldReplaceQ, undefined, false);
await globalScene.ui.setModeWithoutClear(Mode.CONFIRM,
() => this.forgetMoveProcess(move, pokemon), // Yes
() => { // No
gScene.ui.setMode(this.messageMode);
globalScene.ui.setMode(this.messageMode);
this.rejectMoveAndEnd(move, pokemon);
}
);
@ -96,16 +96,16 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
* @param Pokemon The Pokemon learning the move
*/
async forgetMoveProcess(move: Move, pokemon: Pokemon) {
gScene.ui.setMode(this.messageMode);
await gScene.ui.showTextPromise(i18next.t("battle:learnMoveForgetQuestion"), undefined, true);
await gScene.ui.setModeWithoutClear(Mode.SUMMARY, pokemon, SummaryUiMode.LEARN_MOVE, move, (moveIndex: integer) => {
globalScene.ui.setMode(this.messageMode);
await globalScene.ui.showTextPromise(i18next.t("battle:learnMoveForgetQuestion"), undefined, true);
await globalScene.ui.setModeWithoutClear(Mode.SUMMARY, pokemon, SummaryUiMode.LEARN_MOVE, move, (moveIndex: integer) => {
if (moveIndex === 4) {
gScene.ui.setMode(this.messageMode).then(() => this.rejectMoveAndEnd(move, pokemon));
globalScene.ui.setMode(this.messageMode).then(() => this.rejectMoveAndEnd(move, pokemon));
return;
}
const forgetSuccessText = i18next.t("battle:learnMoveForgetSuccess", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: pokemon.moveset[moveIndex]!.getName() });
const fullText = [ i18next.t("battle:countdownPoof"), forgetSuccessText, i18next.t("battle:learnMoveAnd") ].join("$");
gScene.ui.setMode(this.messageMode).then(() => this.learnMove(moveIndex, move, pokemon, fullText));
globalScene.ui.setMode(this.messageMode).then(() => this.learnMove(moveIndex, move, pokemon, fullText));
});
}
@ -120,14 +120,14 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
* @param Pokemon The Pokemon learning the move
*/
async rejectMoveAndEnd(move: Move, pokemon: Pokemon) {
await gScene.ui.showTextPromise(i18next.t("battle:learnMoveStopTeaching", { moveName: move.name }), undefined, false);
gScene.ui.setModeWithoutClear(Mode.CONFIRM,
await globalScene.ui.showTextPromise(i18next.t("battle:learnMoveStopTeaching", { moveName: move.name }), undefined, false);
globalScene.ui.setModeWithoutClear(Mode.CONFIRM,
() => {
gScene.ui.setMode(this.messageMode);
gScene.ui.showTextPromise(i18next.t("battle:learnMoveNotLearned", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }), undefined, true).then(() => this.end());
globalScene.ui.setMode(this.messageMode);
globalScene.ui.showTextPromise(i18next.t("battle:learnMoveNotLearned", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }), undefined, true).then(() => this.end());
},
() => {
gScene.ui.setMode(this.messageMode);
globalScene.ui.setMode(this.messageMode);
this.replaceMoveCheck(move, pokemon);
}
);
@ -154,31 +154,31 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
pokemon.usedTMs = [];
}
pokemon.usedTMs.push(this.moveId);
gScene.tryRemovePhase((phase) => phase instanceof SelectModifierPhase);
globalScene.tryRemovePhase((phase) => phase instanceof SelectModifierPhase);
} else if (this.learnMoveType === LearnMoveType.MEMORY) {
if (this.cost !== -1) {
if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) {
gScene.money -= this.cost;
gScene.updateMoneyText();
gScene.animateMoneyChanged(false);
globalScene.money -= this.cost;
globalScene.updateMoneyText();
globalScene.animateMoneyChanged(false);
}
gScene.playSound("se/buy");
globalScene.playSound("se/buy");
} else {
gScene.tryRemovePhase((phase) => phase instanceof SelectModifierPhase);
globalScene.tryRemovePhase((phase) => phase instanceof SelectModifierPhase);
}
}
pokemon.setMove(index, this.moveId);
initMoveAnim(this.moveId).then(() => {
loadMoveAnimAssets([ this.moveId ], true);
});
gScene.ui.setMode(this.messageMode);
globalScene.ui.setMode(this.messageMode);
const learnMoveText = i18next.t("battle:learnMove", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name });
if (textMessage) {
await gScene.ui.showTextPromise(textMessage);
await globalScene.ui.showTextPromise(textMessage);
}
gScene.playSound("level_up_fanfare"); // Sound loaded into game as is
gScene.ui.showText(learnMoveText, null, () => {
gScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeMoveLearnedTrigger, true);
globalScene.playSound("level_up_fanfare"); // Sound loaded into game as is
globalScene.ui.showText(learnMoveText, null, () => {
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeMoveLearnedTrigger, true);
this.end();
}, this.messageMode === Mode.EVOLUTION_SCENE ? 1000 : undefined, true);
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { Mode } from "#app/ui/ui";
import i18next from "i18next";
import { FieldPhase } from "./field-phase";
@ -11,10 +11,10 @@ export class LevelCapPhase extends FieldPhase {
start(): void {
super.start();
gScene.ui.setMode(Mode.MESSAGE).then(() => {
globalScene.ui.setMode(Mode.MESSAGE).then(() => {
// Sound loaded into game as is
gScene.playSound("level_up_fanfare");
gScene.ui.showText(i18next.t("battle:levelCapUp", { levelCap: gScene.getMaxExpLevel() }), null, () => this.end(), null, true);
globalScene.playSound("level_up_fanfare");
globalScene.ui.showText(i18next.t("battle:levelCapUp", { levelCap: globalScene.getMaxExpLevel() }), null, () => this.end(), null, true);
this.executeForAll(pokemon => pokemon.updateInfo(true));
});
}

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { ExpNotification } from "#app/enums/exp-notification";
import { EvolutionPhase } from "#app/phases/evolution-phase";
import { PlayerPokemon } from "#app/field/pokemon";
@ -23,35 +23,35 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
start() {
super.start();
if (this.level > gScene.gameData.gameStats.highestLevel) {
gScene.gameData.gameStats.highestLevel = this.level;
if (this.level > globalScene.gameData.gameStats.highestLevel) {
globalScene.gameData.gameStats.highestLevel = this.level;
}
gScene.validateAchvs(LevelAchv, new Utils.NumberHolder(this.level));
globalScene.validateAchvs(LevelAchv, new Utils.NumberHolder(this.level));
const pokemon = this.getPokemon();
const prevStats = pokemon.stats.slice(0);
pokemon.calculateStats();
pokemon.updateInfo();
if (gScene.expParty === ExpNotification.DEFAULT) {
gScene.playSound("level_up_fanfare");
gScene.ui.showText(i18next.t("battle:levelUp", { pokemonName: getPokemonNameWithAffix(this.getPokemon()), level: this.level }), null, () => gScene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end()), null, true);
} else if (gScene.expParty === ExpNotification.SKIP) {
if (globalScene.expParty === ExpNotification.DEFAULT) {
globalScene.playSound("level_up_fanfare");
globalScene.ui.showText(i18next.t("battle:levelUp", { pokemonName: getPokemonNameWithAffix(this.getPokemon()), level: this.level }), null, () => globalScene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end()), null, true);
} else if (globalScene.expParty === ExpNotification.SKIP) {
this.end();
} else {
// we still want to display the stats if activated
gScene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end());
globalScene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end());
}
if (this.lastLevel < 100) { // this feels like an unnecessary optimization
const levelMoves = this.getPokemon().getLevelMoves(this.lastLevel + 1);
for (const lm of levelMoves) {
gScene.unshiftPhase(new LearnMovePhase(this.partyMemberIndex, lm[1]));
globalScene.unshiftPhase(new LearnMovePhase(this.partyMemberIndex, lm[1]));
}
}
if (!pokemon.pauseEvolutions) {
const evolution = pokemon.getEvolution();
if (evolution) {
gScene.unshiftPhase(new EvolutionPhase(pokemon as PlayerPokemon, evolution, this.lastLevel));
globalScene.unshiftPhase(new EvolutionPhase(pokemon as PlayerPokemon, evolution, this.lastLevel));
}
}
}

View File

@ -1,5 +1,5 @@
import { updateUserInfo } from "#app/account";
import { bypassLogin, gScene } from "#app/battle-scene";
import { bypassLogin, globalScene } from "#app/battle-scene";
import { Phase } from "#app/phase";
import { handleTutorial, Tutorial } from "#app/tutorial";
import { Mode } from "#app/ui/ui";
@ -22,50 +22,50 @@ export class LoginPhase extends Phase {
const hasSession = !!Utils.getCookie(Utils.sessionIdKey);
gScene.ui.setMode(Mode.LOADING, { buttonActions: []});
globalScene.ui.setMode(Mode.LOADING, { buttonActions: []});
Utils.executeIf(bypassLogin || hasSession, updateUserInfo).then(response => {
const success = response ? response[0] : false;
const statusCode = response ? response[1] : null;
if (!success) {
if (!statusCode || statusCode === 400) {
if (this.showText) {
gScene.ui.showText(i18next.t("menu:logInOrCreateAccount"));
globalScene.ui.showText(i18next.t("menu:logInOrCreateAccount"));
}
gScene.playSound("menu_open");
globalScene.playSound("menu_open");
const loadData = () => {
updateUserInfo().then(success => {
if (!success[0]) {
Utils.removeCookie(Utils.sessionIdKey);
gScene.reset(true, true);
globalScene.reset(true, true);
return;
}
gScene.gameData.loadSystem().then(() => this.end());
globalScene.gameData.loadSystem().then(() => this.end());
});
};
gScene.ui.setMode(Mode.LOGIN_FORM, {
globalScene.ui.setMode(Mode.LOGIN_FORM, {
buttonActions: [
() => {
gScene.ui.playSelect();
globalScene.ui.playSelect();
loadData();
}, () => {
gScene.playSound("menu_open");
gScene.ui.setMode(Mode.REGISTRATION_FORM, {
globalScene.playSound("menu_open");
globalScene.ui.setMode(Mode.REGISTRATION_FORM, {
buttonActions: [
() => {
gScene.ui.playSelect();
globalScene.ui.playSelect();
updateUserInfo().then(success => {
if (!success[0]) {
Utils.removeCookie(Utils.sessionIdKey);
gScene.reset(true, true);
globalScene.reset(true, true);
return;
}
this.end();
} );
}, () => {
gScene.unshiftPhase(new LoginPhase(false));
globalScene.unshiftPhase(new LoginPhase(false));
this.end();
}
]
@ -85,19 +85,19 @@ export class LoginPhase extends Phase {
});
} else if (statusCode === 401) {
Utils.removeCookie(Utils.sessionIdKey);
gScene.reset(true, true);
globalScene.reset(true, true);
} else {
gScene.unshiftPhase(new UnavailablePhase());
globalScene.unshiftPhase(new UnavailablePhase());
super.end();
}
return null;
} else {
gScene.gameData.loadSystem().then(success => {
globalScene.gameData.loadSystem().then(success => {
if (success || bypassLogin) {
this.end();
} else {
gScene.ui.setMode(Mode.MESSAGE);
gScene.ui.showText(t("menu:failedToLoadSaveData"));
globalScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.showText(t("menu:failedToLoadSaveData"));
}
});
}
@ -105,10 +105,10 @@ export class LoginPhase extends Phase {
}
end(): void {
gScene.ui.setMode(Mode.MESSAGE);
globalScene.ui.setMode(Mode.MESSAGE);
if (!gScene.gameData.gender) {
gScene.unshiftPhase(new SelectGenderPhase());
if (!globalScene.gameData.gender) {
globalScene.unshiftPhase(new SelectGenderPhase());
}
handleTutorial(Tutorial.Intro).then(() => super.end());

View File

@ -1,4 +1,4 @@
import { gScene } from "#app/battle-scene";
import { globalScene } from "#app/battle-scene";
import { Phase } from "#app/phase";
export class MessagePhase extends Phase {
@ -23,20 +23,20 @@ export class MessagePhase extends Phase {
if (this.text.indexOf("$") > -1) {
const pageIndex = this.text.indexOf("$");
gScene.unshiftPhase(new MessagePhase(this.text.slice(pageIndex + 1), this.callbackDelay, this.prompt, this.promptDelay, this.speaker));
globalScene.unshiftPhase(new MessagePhase(this.text.slice(pageIndex + 1), this.callbackDelay, this.prompt, this.promptDelay, this.speaker));
this.text = this.text.slice(0, pageIndex).trim();
}
if (this.speaker) {
gScene.ui.showDialogue(this.text, this.speaker, null, () => this.end(), this.callbackDelay || (this.prompt ? 0 : 1500), this.promptDelay ?? 0);
globalScene.ui.showDialogue(this.text, this.speaker, null, () => this.end(), this.callbackDelay || (this.prompt ? 0 : 1500), this.promptDelay ?? 0);
} else {
gScene.ui.showText(this.text, null, () => this.end(), this.callbackDelay || (this.prompt ? 0 : 1500), this.prompt, this.promptDelay);
globalScene.ui.showText(this.text, null, () => this.end(), this.callbackDelay || (this.prompt ? 0 : 1500), this.prompt, this.promptDelay);
}
}
end() {
if (gScene.abilityBar.shown) {
gScene.abilityBar.hide();
if (globalScene.abilityBar.shown) {
globalScene.abilityBar.hide();
}
super.end();

Some files were not shown because too many files have changed in this diff Show More