diff --git a/public/images/events/valentines2025event-de.png b/public/images/events/valentines2025event-de.png new file mode 100644 index 00000000000..0ec3bfe704b Binary files /dev/null and b/public/images/events/valentines2025event-de.png differ diff --git a/public/images/events/valentines2025event-en.png b/public/images/events/valentines2025event-en.png new file mode 100644 index 00000000000..0ec3bfe704b Binary files /dev/null and b/public/images/events/valentines2025event-en.png differ diff --git a/public/images/events/valentines2025event-es-ES.png b/public/images/events/valentines2025event-es-ES.png new file mode 100644 index 00000000000..0ec3bfe704b Binary files /dev/null and b/public/images/events/valentines2025event-es-ES.png differ diff --git a/public/images/events/valentines2025event-fr.png b/public/images/events/valentines2025event-fr.png new file mode 100644 index 00000000000..0ec3bfe704b Binary files /dev/null and b/public/images/events/valentines2025event-fr.png differ diff --git a/public/images/events/valentines2025event-it.png b/public/images/events/valentines2025event-it.png new file mode 100644 index 00000000000..0ec3bfe704b Binary files /dev/null and b/public/images/events/valentines2025event-it.png differ diff --git a/public/images/events/valentines2025event-ja.png b/public/images/events/valentines2025event-ja.png new file mode 100644 index 00000000000..0ec3bfe704b Binary files /dev/null and b/public/images/events/valentines2025event-ja.png differ diff --git a/public/images/events/valentines2025event-ko.png b/public/images/events/valentines2025event-ko.png new file mode 100644 index 00000000000..0ec3bfe704b Binary files /dev/null and b/public/images/events/valentines2025event-ko.png differ diff --git a/public/images/events/valentines2025event-pt-BR.png b/public/images/events/valentines2025event-pt-BR.png new file mode 100644 index 00000000000..0ec3bfe704b Binary files /dev/null and b/public/images/events/valentines2025event-pt-BR.png differ diff --git a/public/images/events/valentines2025event-zh-CN.png b/public/images/events/valentines2025event-zh-CN.png new file mode 100644 index 00000000000..0ec3bfe704b Binary files /dev/null and b/public/images/events/valentines2025event-zh-CN.png differ diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index ead0443908b..351b969b1a8 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -887,16 +887,21 @@ export function getRandomEncounterSpecies(level: number, isBoss: boolean = false let bossSpecies: PokemonSpecies; let isEventEncounter = false; const eventEncounters = globalScene.eventManager.getEventEncounters(); + let formIndex; if (eventEncounters.length > 0 && randSeedInt(2) === 1) { const eventEncounter = randSeedItem(eventEncounters); const levelSpecies = getPokemonSpecies(eventEncounter.species).getWildSpeciesForLevel(level, !eventEncounter.blockEvolution, isBoss, globalScene.gameMode); isEventEncounter = true; bossSpecies = getPokemonSpecies(levelSpecies); + formIndex = eventEncounter.formIndex; } else { bossSpecies = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getPlayerParty()), isBoss); } const ret = new EnemyPokemon(bossSpecies, level, TrainerSlot.NONE, isBoss); + if (formIndex) { + ret.formIndex = formIndex; + } //Reroll shiny for event encounters if (isEventEncounter && !ret.shiny) { diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 16af8364502..daab808918c 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4356,8 +4356,12 @@ export class PlayerPokemon extends Pokemon { ].filter(d => !!d); const amount = new Utils.NumberHolder(friendship); globalScene.applyModifier(PokemonFriendshipBoosterModifier, true, this, amount); - const candyFriendshipMultiplier = globalScene.eventManager.getClassicFriendshipMultiplier(); - const starterAmount = new Utils.NumberHolder(Math.floor(amount.value * (globalScene.gameMode.isClassic ? candyFriendshipMultiplier : 1) / (fusionStarterSpeciesId ? 2 : 1))); + const candyFriendshipMultiplier = globalScene.gameMode.isClassic ? globalScene.eventManager.getClassicFriendshipMultiplier() : 1; + const fusionReduction = fusionStarterSpeciesId + ? globalScene.eventManager.areFusionsBoosted() ? 1.5 // Divide candy gain for fusions by 1.5 during events + : 2 // 2 for fusions outside events + : 1; // 1 for non-fused mons + const starterAmount = new Utils.NumberHolder(Math.floor(amount.value * candyFriendshipMultiplier / fusionReduction)); // Add friendship to this PlayerPokemon this.friendship = Math.min(this.friendship + amount.value, 255); diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 60a0513f608..e8f817c1c39 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -249,9 +249,9 @@ export class LoadingScene extends SceneBase { } const availableLangs = [ "en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN" ]; if (lang && availableLangs.includes(lang)) { - this.loadImage("yearofthesnakeevent-" + lang, "events"); + this.loadImage("valentines2025event-" + lang, "events"); } else { - this.loadImage("yearofthesnakeevent-en", "events"); + this.loadImage("valentines2025event-en", "events"); } this.loadAtlas("statuses", ""); diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index b65f1b53441..b1e8b69df36 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1720,7 +1720,16 @@ const modifierPool: ModifierPool = { }, 4), new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3), new WeightedModifierType(modifierTypes.TERA_SHARD, 1), - new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => globalScene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 4 : 0), + new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => { + if (party.filter(p => !p.fusionSpecies).length > 1) { + if (globalScene.gameMode.isSplicedOnly) { + return 4; + } else if (globalScene.gameMode.isClassic && globalScene.eventManager.areFusionsBoosted()) { + return 1; + } + } + return 0; + }, 4), new WeightedModifierType(modifierTypes.VOUCHER, (_party: Pokemon[], rerollCount: number) => !globalScene.gameMode.isDaily ? Math.max(1 - rerollCount, 0) : 0, 1), ].map(m => { m.setTier(ModifierTier.GREAT); return m; @@ -1879,7 +1888,7 @@ const modifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.MULTI_LENS, 18), new WeightedModifierType(modifierTypes.VOUCHER_PREMIUM, (_party: Pokemon[], rerollCount: number) => !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.DNA_SPLICERS, (party: Pokemon[]) => !(globalScene.gameMode.isClassic && globalScene.eventManager.areFusionsBoosted()) && !globalScene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 24 : 0, 24), new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, () => (globalScene.gameMode.isDaily || (!globalScene.gameMode.isFreshStartChallenge() && globalScene.gameData.isUnlocked(Unlockables.MINI_BLACK_HOLE))) ? 1 : 0, 1), ].map(m => { m.setTier(ModifierTier.MASTER); return m; @@ -2538,7 +2547,7 @@ export function getPartyLuckValue(party: Pokemon[]): number { return DailyLuck.value; } const eventSpecies = globalScene.eventManager.getEventLuckBoostedSpecies(); - const luck = Phaser.Math.Clamp(party.map(p => p.isAllowedInBattle() ? p.getLuck() + (eventSpecies.includes(p.species.speciesId) ? 1 : 0) : 0) + const luck = Phaser.Math.Clamp(party.map(p => p.isAllowedInBattle() ? p.getLuck() + (eventSpecies.includes(p.species.speciesId) ? 3 : 0) : 0) .reduce((total: number, value: number) => total += value, 0), 0, 14); return Math.min(globalScene.eventManager.getEventLuckBoost() + (luck ?? 0), 14); } diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index 7a9f0e59993..bebacf87ebc 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -27,6 +27,7 @@ interface EventBanner { interface EventEncounter { species: Species; blockEvolution?: boolean; + formIndex?: number; } interface EventMysteryEncounterTier { @@ -49,6 +50,7 @@ interface TimedEvent extends EventBanner { weather?: WeatherPoolEntry[]; mysteryEncounterTierChanges?: EventMysteryEncounterTier[]; luckBoostedSpecies?: Species[]; + boostFusions?: boolean; //MODIFIER REWORK PLEASE } const timedEvents: TimedEvent[] = [ @@ -144,6 +146,40 @@ const timedEvents: TimedEvent[] = [ Species.ROARING_MOON, Species.BLOODMOON_URSALUNA ] + }, + { + name: "Valentine", + eventType: EventType.SHINY, + startDate: new Date(Date.UTC(2025, 1, 10)), + endDate: new Date(Date.UTC(2025, 1, 21)), + boostFusions: true, + shinyMultiplier: 2, + bannerKey: "valentines2025event-", + scale: 0.21, + availableLangs: [ "en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN" ], + eventEncounters: [ + { species: Species.NIDORAN_F }, + { species: Species.NIDORAN_M }, + { species: Species.IGGLYBUFF }, + { species: Species.SMOOCHUM }, + { species: Species.VOLBEAT }, + { species: Species.ILLUMISE }, + { species: Species.ROSELIA }, + { species: Species.LUVDISC }, + { species: Species.WOOBAT }, + { species: Species.FRILLISH }, + { species: Species.ALOMOMOLA }, + { species: Species.FURFROU, formIndex: 1 }, // Heart trim + { species: Species.ESPURR }, + { species: Species.SPRITZEE }, + { species: Species.SWIRLIX }, + { species: Species.APPLIN }, + { species: Species.MILCERY }, + { species: Species.INDEEDEE }, + { species: Species.TANDEMAUS }, + { species: Species.ENAMORUS } + ], + luckBoostedSpecies: [ Species.LUVDISC ] } ]; @@ -297,6 +333,10 @@ export class TimedEventManager { }); return ret; } + + areFusionsBoosted(): boolean { + return timedEvents.some((te) => this.isActive(te) && te.boostFusions); + } } export class TimedEventDisplay extends Phaser.GameObjects.Container {