mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-19 14:52:19 +02:00
commit
db8f630ec3
@ -167,9 +167,10 @@ import { ExpGainsSpeed } from "#enums/exp-gains-speed";
|
|||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { FRIENDSHIP_GAIN_FROM_BATTLE } from "#app/data/balance/starters";
|
import { FRIENDSHIP_GAIN_FROM_BATTLE } from "#app/data/balance/starters";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import { initGlobalScene } from "#app/global-scene";
|
import { globalScene, initGlobalScene } from "#app/global-scene";
|
||||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||||
import { HideAbilityPhase } from "#app/phases/hide-ability-phase";
|
import { HideAbilityPhase } from "#app/phases/hide-ability-phase";
|
||||||
|
import { timedEventManager } from "./global-event-manager";
|
||||||
|
|
||||||
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
||||||
|
|
||||||
@ -2265,6 +2266,9 @@ export default class BattleScene extends SceneBase {
|
|||||||
if (bgmName === undefined) {
|
if (bgmName === undefined) {
|
||||||
bgmName = this.currentBattle?.getBgmOverride() || this.arena?.bgm;
|
bgmName = this.currentBattle?.getBgmOverride() || this.arena?.bgm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bgmName = timedEventManager.getEventBgmReplacement(bgmName);
|
||||||
|
|
||||||
if (this.bgm && bgmName === this.bgm.key) {
|
if (this.bgm && bgmName === this.bgm.key) {
|
||||||
if (!this.bgm.isPlaying) {
|
if (!this.bgm.isPlaying) {
|
||||||
this.bgm.play({
|
this.bgm.play({
|
||||||
|
@ -37,6 +37,7 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode
|
|||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounters/delibirdy";
|
const namespace = "mysteryEncounters/delibirdy";
|
||||||
@ -56,7 +57,7 @@ const OPTION_3_DISALLOWED_MODIFIERS = [
|
|||||||
const DELIBIRDY_MONEY_PRICE_MULTIPLIER = 2;
|
const DELIBIRDY_MONEY_PRICE_MULTIPLIER = 2;
|
||||||
|
|
||||||
const doEventReward = () => {
|
const doEventReward = () => {
|
||||||
const event_buff = globalScene.eventManager.getDelibirdyBuff();
|
const event_buff = timedEventManager.getDelibirdyBuff();
|
||||||
if (event_buff.length > 0) {
|
if (event_buff.length > 0) {
|
||||||
const candidates = event_buff.filter(c => {
|
const candidates = event_buff.filter(c => {
|
||||||
const mtype = generateModifierType(modifierTypes[c]);
|
const mtype = generateModifierType(modifierTypes[c]);
|
||||||
|
@ -46,6 +46,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
|||||||
import { addPokemonDataToDexAndValidateAchievements } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { addPokemonDataToDexAndValidateAchievements } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import type { PokeballType } from "#enums/pokeball";
|
import type { PokeballType } from "#enums/pokeball";
|
||||||
import { doShinySparkleAnim } from "#app/field/anims";
|
import { doShinySparkleAnim } from "#app/field/anims";
|
||||||
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/globalTradeSystem";
|
const namespace = "mysteryEncounters/globalTradeSystem";
|
||||||
@ -273,8 +274,8 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
|||||||
// Extra shiny roll at 1/128 odds (boosted by events and charms)
|
// Extra shiny roll at 1/128 odds (boosted by events and charms)
|
||||||
if (!tradePokemon.shiny) {
|
if (!tradePokemon.shiny) {
|
||||||
const shinyThreshold = new NumberHolder(WONDER_TRADE_SHINY_CHANCE);
|
const shinyThreshold = new NumberHolder(WONDER_TRADE_SHINY_CHANCE);
|
||||||
if (globalScene.eventManager.isEventActive()) {
|
if (timedEventManager.isEventActive()) {
|
||||||
shinyThreshold.value *= globalScene.eventManager.getShinyMultiplier();
|
shinyThreshold.value *= timedEventManager.getShinyMultiplier();
|
||||||
}
|
}
|
||||||
globalScene.applyModifiers(ShinyRateBoosterModifier, true, shinyThreshold);
|
globalScene.applyModifiers(ShinyRateBoosterModifier, true, shinyThreshold);
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { getNatureName } from "#app/data/nature";
|
import { getNatureName } from "#app/data/nature";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animates exclamation sprite over trainer's head at start of encounter
|
* Animates exclamation sprite over trainer's head at start of encounter
|
||||||
@ -1045,7 +1046,7 @@ export function handleMysteryEncounterTurnStartEffects(): boolean {
|
|||||||
export function getRandomEncounterSpecies(level: number, isBoss = false, rerollHidden = false): EnemyPokemon {
|
export function getRandomEncounterSpecies(level: number, isBoss = false, rerollHidden = false): EnemyPokemon {
|
||||||
let bossSpecies: PokemonSpecies;
|
let bossSpecies: PokemonSpecies;
|
||||||
let isEventEncounter = false;
|
let isEventEncounter = false;
|
||||||
const eventEncounters = globalScene.eventManager.getEventEncounters();
|
const eventEncounters = timedEventManager.getEventEncounters();
|
||||||
let formIndex: number | undefined;
|
let formIndex: number | undefined;
|
||||||
|
|
||||||
if (eventEncounters.length > 0 && randSeedInt(2) === 1) {
|
if (eventEncounters.length > 0 && randSeedInt(2) === 1) {
|
||||||
|
@ -24,6 +24,7 @@ import { TrainerType } from "#enums/trainer-type";
|
|||||||
import { Gender } from "#app/data/gender";
|
import { Gender } from "#app/data/gender";
|
||||||
import { signatureSpecies } from "./balance/signature-species";
|
import { signatureSpecies } from "./balance/signature-species";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
|
|
||||||
/** Minimum BST for Pokemon generated onto the Elite Four's teams */
|
/** Minimum BST for Pokemon generated onto the Elite Four's teams */
|
||||||
const ELITE_FOUR_MINIMUM_BST = 460;
|
const ELITE_FOUR_MINIMUM_BST = 460;
|
||||||
@ -739,13 +740,13 @@ export class TrainerConfig {
|
|||||||
// return ret;
|
// return ret;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
setEventModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig {
|
/**
|
||||||
this.eventRewardFuncs = modifierTypeFuncs.map(func => () => {
|
* Sets eventRewardFuncs to the active event rewards for the specified wave
|
||||||
const modifierTypeFunc = func();
|
* @param wave Associated with {@linkcode getFixedBattleEventRewards}
|
||||||
const modifierType = modifierTypeFunc();
|
* @returns this
|
||||||
modifierType.withIdFromFunc(modifierTypeFunc);
|
*/
|
||||||
return modifierType;
|
setEventModifierRewardFuncs(wave: number): TrainerConfig {
|
||||||
});
|
this.eventRewardFuncs = timedEventManager.getFixedBattleEventRewards(wave).map(r => modifierTypes[r]);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4382,11 +4383,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
() => modifierTypes.SUPER_EXP_CHARM,
|
() => modifierTypes.SUPER_EXP_CHARM,
|
||||||
() => modifierTypes.EXP_SHARE,
|
() => modifierTypes.EXP_SHARE,
|
||||||
)
|
)
|
||||||
.setEventModifierRewardFuncs(
|
.setEventModifierRewardFuncs(8)
|
||||||
() => modifierTypes.SHINY_CHARM,
|
|
||||||
() => modifierTypes.ABILITY_CHARM,
|
|
||||||
() => modifierTypes.CATCHING_CHARM,
|
|
||||||
)
|
|
||||||
.setPartyMemberFunc(
|
.setPartyMemberFunc(
|
||||||
0,
|
0,
|
||||||
getRandomPartyMemberFunc(
|
getRandomPartyMemberFunc(
|
||||||
@ -4454,7 +4451,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
.setMixedBattleBgm("battle_rival")
|
.setMixedBattleBgm("battle_rival")
|
||||||
.setPartyTemplates(trainerPartyTemplates.RIVAL_2)
|
.setPartyTemplates(trainerPartyTemplates.RIVAL_2)
|
||||||
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
|
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
|
||||||
.setEventModifierRewardFuncs(() => modifierTypes.SHINY_CHARM)
|
.setEventModifierRewardFuncs(25)
|
||||||
.setPartyMemberFunc(
|
.setPartyMemberFunc(
|
||||||
0,
|
0,
|
||||||
getRandomPartyMemberFunc(
|
getRandomPartyMemberFunc(
|
||||||
@ -4763,7 +4760,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
getRandomPartyMemberFunc([Species.RAYQUAZA], TrainerSlot.TRAINER, true, p => {
|
getRandomPartyMemberFunc([Species.RAYQUAZA], TrainerSlot.TRAINER, true, p => {
|
||||||
p.setBoss(true, 3);
|
p.setBoss(true, 3);
|
||||||
p.pokeball = PokeballType.MASTER_BALL;
|
p.pokeball = PokeballType.MASTER_BALL;
|
||||||
p.shiny = true;
|
p.shiny = timedEventManager.getClassicTrainerShinyChance() === 0;
|
||||||
p.variant = 1;
|
p.variant = 1;
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -4860,7 +4857,7 @@ export const trainerConfigs: TrainerConfigs = {
|
|||||||
p.setBoss();
|
p.setBoss();
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
p.pokeball = PokeballType.MASTER_BALL;
|
p.pokeball = PokeballType.MASTER_BALL;
|
||||||
p.shiny = true;
|
p.shiny = timedEventManager.getClassicTrainerShinyChance() === 0;
|
||||||
p.variant = 1;
|
p.variant = 1;
|
||||||
p.formIndex = 1; // Mega Rayquaza
|
p.formIndex = 1; // Mega Rayquaza
|
||||||
p.generateName();
|
p.generateName();
|
||||||
|
@ -11,6 +11,7 @@ import { TerrainType, getTerrainName } from "./terrain";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type { Arena } from "#app/field/arena";
|
import type { Arena } from "#app/field/arena";
|
||||||
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
|
|
||||||
export class Weather {
|
export class Weather {
|
||||||
public weatherType: WeatherType;
|
public weatherType: WeatherType;
|
||||||
@ -405,8 +406,8 @@ export function getRandomWeatherType(arena: Arena): WeatherType {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arena.biomeType === Biome.TOWN && globalScene.eventManager.isEventActive()) {
|
if (arena.biomeType === Biome.TOWN && timedEventManager.isEventActive()) {
|
||||||
globalScene.eventManager.getWeather()?.map(w => weatherPool.push(w));
|
timedEventManager.getWeather()?.map(w => weatherPool.push(w));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weatherPool.length > 1) {
|
if (weatherPool.length > 1) {
|
||||||
|
@ -260,6 +260,7 @@ import {
|
|||||||
import { Nature } from "#enums/nature";
|
import { Nature } from "#enums/nature";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import { doShinySparkleAnim } from "#app/field/anims";
|
import { doShinySparkleAnim } from "#app/field/anims";
|
||||||
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
|
|
||||||
export enum LearnMoveSituation {
|
export enum LearnMoveSituation {
|
||||||
MISC,
|
MISC,
|
||||||
@ -2978,8 +2979,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
const shinyThreshold = new Utils.NumberHolder(BASE_SHINY_CHANCE);
|
const shinyThreshold = new Utils.NumberHolder(BASE_SHINY_CHANCE);
|
||||||
if (thresholdOverride === undefined) {
|
if (thresholdOverride === undefined) {
|
||||||
if (globalScene.eventManager.isEventActive()) {
|
if (timedEventManager.isEventActive()) {
|
||||||
shinyThreshold.value *= globalScene.eventManager.getShinyMultiplier();
|
const tchance = timedEventManager.getClassicTrainerShinyChance();
|
||||||
|
shinyThreshold.value *= timedEventManager.getShinyMultiplier();
|
||||||
|
if (this.hasTrainer() && tchance > 0) {
|
||||||
|
shinyThreshold.value = Math.max(tchance, shinyThreshold.value); // Choose the higher boost
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!this.hasTrainer()) {
|
if (!this.hasTrainer()) {
|
||||||
globalScene.applyModifiers(
|
globalScene.applyModifiers(
|
||||||
@ -3020,8 +3025,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
if (thresholdOverride !== undefined && applyModifiersToOverride) {
|
if (thresholdOverride !== undefined && applyModifiersToOverride) {
|
||||||
shinyThreshold.value = thresholdOverride;
|
shinyThreshold.value = thresholdOverride;
|
||||||
}
|
}
|
||||||
if (globalScene.eventManager.isEventActive()) {
|
if (timedEventManager.isEventActive()) {
|
||||||
shinyThreshold.value *= globalScene.eventManager.getShinyMultiplier();
|
shinyThreshold.value *= timedEventManager.getShinyMultiplier();
|
||||||
}
|
}
|
||||||
if (!this.hasTrainer()) {
|
if (!this.hasTrainer()) {
|
||||||
globalScene.applyModifiers(
|
globalScene.applyModifiers(
|
||||||
@ -6432,10 +6437,10 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
amount,
|
amount,
|
||||||
);
|
);
|
||||||
const candyFriendshipMultiplier = globalScene.gameMode.isClassic
|
const candyFriendshipMultiplier = globalScene.gameMode.isClassic
|
||||||
? globalScene.eventManager.getClassicFriendshipMultiplier()
|
? timedEventManager.getClassicFriendshipMultiplier()
|
||||||
: 1;
|
: 1;
|
||||||
const fusionReduction = fusionStarterSpeciesId
|
const fusionReduction = fusionStarterSpeciesId
|
||||||
? globalScene.eventManager.areFusionsBoosted()
|
? timedEventManager.areFusionsBoosted()
|
||||||
? 1.5 // Divide candy gain for fusions by 1.5 during events
|
? 1.5 // Divide candy gain for fusions by 1.5 during events
|
||||||
: 2 // 2 for fusions outside events
|
: 2 // 2 for fusions outside events
|
||||||
: 1; // 1 for non-fused mons
|
: 1; // 1 for non-fused mons
|
||||||
|
3
src/global-event-manager.ts
Normal file
3
src/global-event-manager.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { TimedEventManager } from "./timed-event-manager";
|
||||||
|
|
||||||
|
export const timedEventManager = new TimedEventManager();
|
@ -20,6 +20,7 @@ import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
|
|||||||
import { initVouchers } from "#app/system/voucher";
|
import { initVouchers } from "#app/system/voucher";
|
||||||
import { Biome } from "#enums/biome";
|
import { Biome } from "#enums/biome";
|
||||||
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
|
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
|
||||||
|
import { timedEventManager } from "./global-event-manager";
|
||||||
|
|
||||||
export class LoadingScene extends SceneBase {
|
export class LoadingScene extends SceneBase {
|
||||||
public static readonly KEY = "loading";
|
public static readonly KEY = "loading";
|
||||||
@ -250,11 +251,13 @@ export class LoadingScene extends SceneBase {
|
|||||||
this.loadAtlas("statuses", "");
|
this.loadAtlas("statuses", "");
|
||||||
this.loadAtlas("types", "");
|
this.loadAtlas("types", "");
|
||||||
}
|
}
|
||||||
const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN", "zh-TW", "ca-ES"];
|
if (timedEventManager.activeEventHasBanner()) {
|
||||||
|
const availableLangs = timedEventManager.getEventBannerLangs();
|
||||||
if (lang && availableLangs.includes(lang)) {
|
if (lang && availableLangs.includes(lang)) {
|
||||||
this.loadImage(`pkmnday2025event-${lang}`, "events");
|
this.loadImage(`${timedEventManager.getEventBannerFilename()}-${lang}`, "events");
|
||||||
} else {
|
} else {
|
||||||
this.loadImage("pkmnday2025event-en", "events");
|
this.loadImage(`${timedEventManager.getEventBannerFilename()}-en`, "events");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadAtlas("statuses", "");
|
this.loadAtlas("statuses", "");
|
||||||
|
@ -127,6 +127,7 @@ import type { PermanentStat, TempBattleStat } from "#enums/stat";
|
|||||||
import { getStatKey, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
import { getStatKey, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
|
|
||||||
const outputModifierData = false;
|
const outputModifierData = false;
|
||||||
const useMaxWeightForOutput = false;
|
const useMaxWeightForOutput = false;
|
||||||
@ -2655,7 +2656,7 @@ const modifierPool: ModifierPool = {
|
|||||||
if (globalScene.gameMode.isSplicedOnly) {
|
if (globalScene.gameMode.isSplicedOnly) {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
if (globalScene.gameMode.isClassic && globalScene.eventManager.areFusionsBoosted()) {
|
if (globalScene.gameMode.isClassic && timedEventManager.areFusionsBoosted()) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2939,7 +2940,7 @@ const modifierPool: ModifierPool = {
|
|||||||
new WeightedModifierType(
|
new WeightedModifierType(
|
||||||
modifierTypes.DNA_SPLICERS,
|
modifierTypes.DNA_SPLICERS,
|
||||||
(party: Pokemon[]) =>
|
(party: Pokemon[]) =>
|
||||||
!(globalScene.gameMode.isClassic && globalScene.eventManager.areFusionsBoosted()) &&
|
!(globalScene.gameMode.isClassic && timedEventManager.areFusionsBoosted()) &&
|
||||||
!globalScene.gameMode.isSplicedOnly &&
|
!globalScene.gameMode.isSplicedOnly &&
|
||||||
party.filter(p => !p.fusionSpecies).length > 1
|
party.filter(p => !p.fusionSpecies).length > 1
|
||||||
? 24
|
? 24
|
||||||
@ -3703,7 +3704,7 @@ export function getPartyLuckValue(party: Pokemon[]): number {
|
|||||||
);
|
);
|
||||||
return DailyLuck.value;
|
return DailyLuck.value;
|
||||||
}
|
}
|
||||||
const eventSpecies = globalScene.eventManager.getEventLuckBoostedSpecies();
|
const eventSpecies = timedEventManager.getEventLuckBoostedSpecies();
|
||||||
const luck = Phaser.Math.Clamp(
|
const luck = Phaser.Math.Clamp(
|
||||||
party
|
party
|
||||||
.map(p => (p.isAllowedInBattle() ? p.getLuck() + (eventSpecies.includes(p.species.speciesId) ? 1 : 0) : 0))
|
.map(p => (p.isAllowedInBattle() ? p.getLuck() + (eventSpecies.includes(p.species.speciesId) ? 1 : 0) : 0))
|
||||||
@ -3711,7 +3712,7 @@ export function getPartyLuckValue(party: Pokemon[]): number {
|
|||||||
0,
|
0,
|
||||||
14,
|
14,
|
||||||
);
|
);
|
||||||
return Math.min(globalScene.eventManager.getEventLuckBoost() + (luck ?? 0), 14);
|
return Math.min(timedEventManager.getEventLuckBoost() + (luck ?? 0), 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLuckString(luckValue: number): string {
|
export function getLuckString(luckValue: number): string {
|
||||||
|
@ -11,6 +11,7 @@ import { TrainerSlot } from "#app/data/trainer-config";
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { Biome } from "#app/enums/biome";
|
import { Biome } from "#app/enums/biome";
|
||||||
import { achvs } from "#app/system/achv";
|
import { achvs } from "#app/system/achv";
|
||||||
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
|
|
||||||
export class TrainerVictoryPhase extends BattlePhase {
|
export class TrainerVictoryPhase extends BattlePhase {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -29,7 +30,7 @@ export class TrainerVictoryPhase extends BattlePhase {
|
|||||||
globalScene.unshiftPhase(new ModifierRewardPhase(modifierRewardFunc));
|
globalScene.unshiftPhase(new ModifierRewardPhase(modifierRewardFunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalScene.eventManager.isEventActive()) {
|
if (timedEventManager.isEventActive()) {
|
||||||
for (const rewardFunc of globalScene.currentBattle.trainer?.config.eventRewardFuncs!) {
|
for (const rewardFunc of globalScene.currentBattle.trainer?.config.eventRewardFuncs!) {
|
||||||
globalScene.unshiftPhase(new ModifierRewardPhase(rewardFunc));
|
globalScene.unshiftPhase(new ModifierRewardPhase(rewardFunc));
|
||||||
}
|
}
|
||||||
@ -42,7 +43,7 @@ export class TrainerVictoryPhase extends BattlePhase {
|
|||||||
!globalScene.validateVoucher(vouchers[TrainerType[trainerType]]) &&
|
!globalScene.validateVoucher(vouchers[TrainerType[trainerType]]) &&
|
||||||
globalScene.currentBattle.trainer?.config.isBoss
|
globalScene.currentBattle.trainer?.config.isBoss
|
||||||
) {
|
) {
|
||||||
if (globalScene.eventManager.getUpgradeUnlockedVouchers()) {
|
if (timedEventManager.getUpgradeUnlockedVouchers()) {
|
||||||
globalScene.unshiftPhase(
|
globalScene.unshiftPhase(
|
||||||
new ModifierRewardPhase(
|
new ModifierRewardPhase(
|
||||||
[
|
[
|
||||||
|
@ -36,6 +36,13 @@ interface EventMysteryEncounterTier {
|
|||||||
disable?: boolean;
|
disable?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface EventWaveReward {
|
||||||
|
wave: number;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventMusicReplacement = [string, string];
|
||||||
|
|
||||||
interface TimedEvent extends EventBanner {
|
interface TimedEvent extends EventBanner {
|
||||||
name: string;
|
name: string;
|
||||||
eventType: EventType;
|
eventType: EventType;
|
||||||
@ -51,6 +58,9 @@ interface TimedEvent extends EventBanner {
|
|||||||
mysteryEncounterTierChanges?: EventMysteryEncounterTier[];
|
mysteryEncounterTierChanges?: EventMysteryEncounterTier[];
|
||||||
luckBoostedSpecies?: Species[];
|
luckBoostedSpecies?: Species[];
|
||||||
boostFusions?: boolean; //MODIFIER REWORK PLEASE
|
boostFusions?: boolean; //MODIFIER REWORK PLEASE
|
||||||
|
classicWaveRewards?: EventWaveReward[]; // Rival battle rewards
|
||||||
|
trainerShinyChance?: number; // Odds over 65536 of trainer mon generating as shiny
|
||||||
|
music?: EventMusicReplacement[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const timedEvents: TimedEvent[] = [
|
const timedEvents: TimedEvent[] = [
|
||||||
@ -61,7 +71,7 @@ const timedEvents: TimedEvent[] = [
|
|||||||
upgradeUnlockedVouchers: true,
|
upgradeUnlockedVouchers: true,
|
||||||
startDate: new Date(Date.UTC(2024, 11, 21, 0)),
|
startDate: new Date(Date.UTC(2024, 11, 21, 0)),
|
||||||
endDate: new Date(Date.UTC(2025, 0, 4, 0)),
|
endDate: new Date(Date.UTC(2025, 0, 4, 0)),
|
||||||
bannerKey: "winter_holidays2024-event-",
|
bannerKey: "winter_holidays2024-event",
|
||||||
scale: 0.21,
|
scale: 0.21,
|
||||||
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"],
|
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"],
|
||||||
eventEncounters: [
|
eventEncounters: [
|
||||||
@ -104,6 +114,12 @@ const timedEvents: TimedEvent[] = [
|
|||||||
disable: true,
|
disable: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
classicWaveRewards: [
|
||||||
|
{ wave: 8, type: "SHINY_CHARM" },
|
||||||
|
{ wave: 8, type: "ABILITY_CHARM" },
|
||||||
|
{ wave: 8, type: "CATCHING_CHARM" },
|
||||||
|
{ wave: 25, type: "SHINY_CHARM" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Year of the Snake",
|
name: "Year of the Snake",
|
||||||
@ -111,7 +127,7 @@ const timedEvents: TimedEvent[] = [
|
|||||||
luckBoost: 1,
|
luckBoost: 1,
|
||||||
startDate: new Date(Date.UTC(2025, 0, 29, 0)),
|
startDate: new Date(Date.UTC(2025, 0, 29, 0)),
|
||||||
endDate: new Date(Date.UTC(2025, 1, 3, 0)),
|
endDate: new Date(Date.UTC(2025, 1, 3, 0)),
|
||||||
bannerKey: "yearofthesnakeevent-",
|
bannerKey: "yearofthesnakeevent",
|
||||||
scale: 0.21,
|
scale: 0.21,
|
||||||
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"],
|
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"],
|
||||||
eventEncounters: [
|
eventEncounters: [
|
||||||
@ -169,6 +185,12 @@ const timedEvents: TimedEvent[] = [
|
|||||||
Species.ROARING_MOON,
|
Species.ROARING_MOON,
|
||||||
Species.BLOODMOON_URSALUNA,
|
Species.BLOODMOON_URSALUNA,
|
||||||
],
|
],
|
||||||
|
classicWaveRewards: [
|
||||||
|
{ wave: 8, type: "SHINY_CHARM" },
|
||||||
|
{ wave: 8, type: "ABILITY_CHARM" },
|
||||||
|
{ wave: 8, type: "CATCHING_CHARM" },
|
||||||
|
{ wave: 25, type: "SHINY_CHARM" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Valentine",
|
name: "Valentine",
|
||||||
@ -177,7 +199,7 @@ const timedEvents: TimedEvent[] = [
|
|||||||
endDate: new Date(Date.UTC(2025, 1, 21)),
|
endDate: new Date(Date.UTC(2025, 1, 21)),
|
||||||
boostFusions: true,
|
boostFusions: true,
|
||||||
shinyMultiplier: 2,
|
shinyMultiplier: 2,
|
||||||
bannerKey: "valentines2025event-",
|
bannerKey: "valentines2025event",
|
||||||
scale: 0.21,
|
scale: 0.21,
|
||||||
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"],
|
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"],
|
||||||
eventEncounters: [
|
eventEncounters: [
|
||||||
@ -203,6 +225,12 @@ const timedEvents: TimedEvent[] = [
|
|||||||
{ species: Species.ENAMORUS },
|
{ species: Species.ENAMORUS },
|
||||||
],
|
],
|
||||||
luckBoostedSpecies: [Species.LUVDISC],
|
luckBoostedSpecies: [Species.LUVDISC],
|
||||||
|
classicWaveRewards: [
|
||||||
|
{ wave: 8, type: "SHINY_CHARM" },
|
||||||
|
{ wave: 8, type: "ABILITY_CHARM" },
|
||||||
|
{ wave: 8, type: "CATCHING_CHARM" },
|
||||||
|
{ wave: 25, type: "SHINY_CHARM" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "PKMNDAY2025",
|
name: "PKMNDAY2025",
|
||||||
@ -210,7 +238,7 @@ const timedEvents: TimedEvent[] = [
|
|||||||
startDate: new Date(Date.UTC(2025, 1, 27)),
|
startDate: new Date(Date.UTC(2025, 1, 27)),
|
||||||
endDate: new Date(Date.UTC(2025, 2, 4)),
|
endDate: new Date(Date.UTC(2025, 2, 4)),
|
||||||
classicFriendshipMultiplier: 4,
|
classicFriendshipMultiplier: 4,
|
||||||
bannerKey: "pkmnday2025event-",
|
bannerKey: "pkmnday2025event",
|
||||||
scale: 0.21,
|
scale: 0.21,
|
||||||
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"],
|
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"],
|
||||||
eventEncounters: [
|
eventEncounters: [
|
||||||
@ -248,6 +276,26 @@ const timedEvents: TimedEvent[] = [
|
|||||||
Species.ZYGARDE,
|
Species.ZYGARDE,
|
||||||
Species.ETERNAL_FLOETTE,
|
Species.ETERNAL_FLOETTE,
|
||||||
],
|
],
|
||||||
|
classicWaveRewards: [
|
||||||
|
{ wave: 8, type: "SHINY_CHARM" },
|
||||||
|
{ wave: 8, type: "ABILITY_CHARM" },
|
||||||
|
{ wave: 8, type: "CATCHING_CHARM" },
|
||||||
|
{ wave: 25, type: "SHINY_CHARM" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "April Fools 2025",
|
||||||
|
eventType: EventType.NO_TIMER_DISPLAY,
|
||||||
|
startDate: new Date(Date.UTC(2025, 2, 1)),
|
||||||
|
endDate: new Date(Date.UTC(2025, 3, 3)),
|
||||||
|
// bannerKey: "aprf25-",
|
||||||
|
// scale: 0.21,
|
||||||
|
// availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN"],
|
||||||
|
trainerShinyChance: 16384, // 16384/65536 = 1/4
|
||||||
|
music: [
|
||||||
|
["title", "mystery_encounter_fun_and_games"],
|
||||||
|
["battle_rival_3", "mystery_encounter_fun_and_games"],
|
||||||
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -283,6 +331,12 @@ export class TimedEventManager {
|
|||||||
return timedEvents.find((te: TimedEvent) => this.isActive(te))?.bannerKey ?? "";
|
return timedEvents.find((te: TimedEvent) => this.isActive(te))?.bannerKey ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEventBannerLangs(): string[] {
|
||||||
|
const ret: string[] = [];
|
||||||
|
ret.push(...timedEvents.find(te => this.isActive(te) && !isNullOrUndefined(te.availableLangs))?.availableLangs!);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
getEventEncounters(): EventEncounter[] {
|
getEventEncounters(): EventEncounter[] {
|
||||||
const ret: EventEncounter[] = [];
|
const ret: EventEncounter[] = [];
|
||||||
timedEvents
|
timedEvents
|
||||||
@ -417,6 +471,45 @@ export class TimedEventManager {
|
|||||||
areFusionsBoosted(): boolean {
|
areFusionsBoosted(): boolean {
|
||||||
return timedEvents.some(te => this.isActive(te) && te.boostFusions);
|
return timedEvents.some(te => this.isActive(te) && te.boostFusions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the modifier types associated with a certain wave during an event
|
||||||
|
* @see EventWaveReward
|
||||||
|
* @param wave the wave to check for associated rewards
|
||||||
|
* @returns array of strings of the event modifier reward types
|
||||||
|
*/
|
||||||
|
getFixedBattleEventRewards(wave: number): string[] {
|
||||||
|
const ret: string[] = [];
|
||||||
|
timedEvents
|
||||||
|
.filter(te => this.isActive(te) && !isNullOrUndefined(te.classicWaveRewards))
|
||||||
|
.map(te => {
|
||||||
|
ret.push(...te.classicWaveRewards!.filter(cwr => cwr.wave === wave).map(cwr => cwr.type));
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the extra shiny chance for trainers due to event (odds/65536)
|
||||||
|
getClassicTrainerShinyChance(): number {
|
||||||
|
let ret = 0;
|
||||||
|
const tsEvents = timedEvents.filter(te => this.isActive(te) && !isNullOrUndefined(te.trainerShinyChance));
|
||||||
|
tsEvents.map(t => (ret += t.trainerShinyChance!));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEventBgmReplacement(bgm: string): string {
|
||||||
|
let ret = bgm;
|
||||||
|
timedEvents.map(te => {
|
||||||
|
if (this.isActive(te) && !isNullOrUndefined(te.music)) {
|
||||||
|
te.music.map(mr => {
|
||||||
|
if (mr[0] === bgm) {
|
||||||
|
console.log(`it is ${te.name} so instead of ${mr[0]} we play ${mr[1]}`);
|
||||||
|
ret = mr[1];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TimedEventDisplay extends Phaser.GameObjects.Container {
|
export class TimedEventDisplay extends Phaser.GameObjects.Container {
|
||||||
|
@ -8,6 +8,7 @@ import { TimedEventDisplay } from "#app/timed-event-manager";
|
|||||||
import { version } from "../../package.json";
|
import { version } from "../../package.json";
|
||||||
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
|
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { timedEventManager } from "#app/global-event-manager";
|
||||||
|
|
||||||
export default class TitleUiHandler extends OptionSelectUiHandler {
|
export default class TitleUiHandler extends OptionSelectUiHandler {
|
||||||
/** If the stats can not be retrieved, use this fallback value */
|
/** If the stats can not be retrieved, use this fallback value */
|
||||||
@ -40,8 +41,8 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
|
|||||||
logo.setOrigin(0.5, 0);
|
logo.setOrigin(0.5, 0);
|
||||||
this.titleContainer.add(logo);
|
this.titleContainer.add(logo);
|
||||||
|
|
||||||
if (globalScene.eventManager.isEventActive()) {
|
if (timedEventManager.isEventActive()) {
|
||||||
this.eventDisplay = new TimedEventDisplay(0, 0, globalScene.eventManager.activeEvent());
|
this.eventDisplay = new TimedEventDisplay(0, 0, timedEventManager.activeEvent());
|
||||||
this.eventDisplay.setup();
|
this.eventDisplay.setup();
|
||||||
this.titleContainer.add(this.eventDisplay);
|
this.titleContainer.add(this.eventDisplay);
|
||||||
}
|
}
|
||||||
@ -116,7 +117,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
|
|||||||
|
|
||||||
const ui = this.getUi();
|
const ui = this.getUi();
|
||||||
|
|
||||||
if (globalScene.eventManager.isEventActive()) {
|
if (timedEventManager.isEventActive()) {
|
||||||
this.eventDisplay.setWidth(globalScene.scaledCanvas.width - this.optionSelectBg.width - this.optionSelectBg.x);
|
this.eventDisplay.setWidth(globalScene.scaledCanvas.width - this.optionSelectBg.width - this.optionSelectBg.x);
|
||||||
this.eventDisplay.show();
|
this.eventDisplay.show();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user