Merge branch 'beta' into implement-new-release-process
BIN
public/images/events/spr25event-de.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
public/images/events/spr25event-en.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
public/images/events/spr25event-es-ES.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
public/images/events/spr25event-es-MX.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
public/images/events/spr25event-fr.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
public/images/events/spr25event-it.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
public/images/events/spr25event-ja.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
public/images/events/spr25event-ko.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
public/images/events/spr25event-pt-BR.png
Normal file
After Width: | Height: | Size: 30 KiB |
@ -6145,7 +6145,7 @@ export class RevivalBlessingAttr extends MoveEffectAttr {
|
||||
const faintedPokemon = globalScene.getEnemyParty().filter((p) => p.isFainted() && !p.isBoss());
|
||||
const pokemon = faintedPokemon[user.randSeedInt(faintedPokemon.length)];
|
||||
const slotIndex = globalScene.getEnemyParty().findIndex((p) => pokemon.id === p.id);
|
||||
pokemon.resetStatus();
|
||||
pokemon.resetStatus(true, false, false, true);
|
||||
pokemon.heal(Math.min(toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: getPokemonNameWithAffix(pokemon) }), 0, true);
|
||||
const allyPokemon = user.getAlly();
|
||||
|
@ -106,7 +106,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
* If an event with more than 1 valid event encounter species is active, you have 20% chance to get one of those
|
||||
* If the rolled species has no HA, and there are valid event encounters, you will get one of those
|
||||
* If the rolled species has no HA and there are no valid event encounters, you will get Shiny Magikarp
|
||||
* Mons rolled from the event encounter pool get 2 extra shiny rolls
|
||||
* Mons rolled from the event encounter pool get 3 extra shiny rolls
|
||||
*/
|
||||
if (
|
||||
r === 0 ||
|
||||
@ -120,12 +120,13 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
(validEventEncounters.length > 0 && (r <= EVENT_THRESHOLD ||
|
||||
(isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE)))
|
||||
) {
|
||||
// If you roll 20%, give event encounter with 2 extra shiny rolls and its HA, if it has one
|
||||
// If you roll 20%, give event encounter with 3 extra shiny rolls and its HA, if it has one
|
||||
const enc = randSeedItem(validEventEncounters);
|
||||
species = getPokemonSpecies(enc.species);
|
||||
pokemon = new PlayerPokemon(species, 5, species.abilityHidden === Abilities.NONE ? undefined : 2, enc.formIndex);
|
||||
pokemon.trySetShinySeed();
|
||||
pokemon.trySetShinySeed();
|
||||
pokemon.trySetShinySeed();
|
||||
} else {
|
||||
pokemon = new PlayerPokemon(species, 5, 2, species.formIndex);
|
||||
}
|
||||
|
@ -5608,13 +5608,44 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* @param revive Whether revive should be cured; defaults to true.
|
||||
* @param confusion Whether resetStatus should include confusion or not; defaults to false.
|
||||
* @param reloadAssets Whether to reload the assets or not; defaults to false.
|
||||
* @param asPhase Whether to reset the status in a phase or immediately
|
||||
*/
|
||||
resetStatus(revive = true, confusion = false, reloadAssets = false): void {
|
||||
resetStatus(revive = true, confusion = false, reloadAssets = false, asPhase = true): void {
|
||||
const lastStatus = this.status?.effect;
|
||||
if (!revive && lastStatus === StatusEffect.FAINT) {
|
||||
return;
|
||||
}
|
||||
globalScene.unshiftPhase(new ResetStatusPhase(this, confusion, reloadAssets));
|
||||
|
||||
if (asPhase) {
|
||||
globalScene.unshiftPhase(new ResetStatusPhase(this, confusion, reloadAssets));
|
||||
} else {
|
||||
this.clearStatus(confusion, reloadAssets);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the action of clearing a Pokemon's status
|
||||
*
|
||||
* This is a helper to {@linkcode resetStatus}, which should be called directly instead of this method
|
||||
*/
|
||||
public clearStatus(confusion: boolean, reloadAssets: boolean) {
|
||||
const lastStatus = this.status?.effect;
|
||||
this.status = null;
|
||||
if (lastStatus === StatusEffect.SLEEP) {
|
||||
this.setFrameRate(10);
|
||||
if (this.getTag(BattlerTagType.NIGHTMARE)) {
|
||||
this.lapseTag(BattlerTagType.NIGHTMARE);
|
||||
}
|
||||
}
|
||||
if (confusion) {
|
||||
if (this.getTag(BattlerTagType.CONFUSED)) {
|
||||
this.lapseTag(BattlerTagType.CONFUSED);
|
||||
}
|
||||
}
|
||||
if (reloadAssets) {
|
||||
this.loadAssets(false).then(() => this.playAnim());
|
||||
}
|
||||
this.updateInfo(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1953,7 +1953,7 @@ export class PokemonInstantReviveModifier extends PokemonHeldItemModifier {
|
||||
);
|
||||
|
||||
// Remove the Pokemon's FAINT status
|
||||
pokemon.resetStatus(true, false, true);
|
||||
pokemon.resetStatus(true, false, true, false);
|
||||
|
||||
// Reapply Commander on the Pokemon's side of the field, if applicable
|
||||
const field = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
@ -2161,7 +2161,7 @@ export class PokemonHpRestoreModifier extends ConsumablePokemonModifier {
|
||||
restorePoints = Math.floor(restorePoints * multiplier);
|
||||
}
|
||||
if (this.fainted || this.healStatus) {
|
||||
pokemon.resetStatus(true, true);
|
||||
pokemon.resetStatus(true, true, false, false);
|
||||
}
|
||||
pokemon.hp = Math.min(
|
||||
pokemon.hp +
|
||||
@ -2181,7 +2181,7 @@ export class PokemonStatusHealModifier extends ConsumablePokemonModifier {
|
||||
* @returns always `true`
|
||||
*/
|
||||
override apply(playerPokemon: PlayerPokemon): boolean {
|
||||
playerPokemon.resetStatus(true, true);
|
||||
playerPokemon.resetStatus(true, true, false, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ export class PartyHealPhase extends BattlePhase {
|
||||
globalScene.ui.fadeOut(1000).then(() => {
|
||||
for (const pokemon of globalScene.getPlayerParty()) {
|
||||
pokemon.hp = pokemon.getMaxHp();
|
||||
pokemon.resetStatus();
|
||||
pokemon.resetStatus(true, false, false, true);
|
||||
for (const move of pokemon.moveset) {
|
||||
move.ppUsed = 0;
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
import type Pokemon from "#app/field/pokemon";
|
||||
import { BattlePhase } from "#app/phases/battle-phase";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
|
||||
/**
|
||||
* Phase which handles resetting a Pokemon's status to none
|
||||
@ -22,23 +20,7 @@ export class ResetStatusPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
public override start() {
|
||||
const lastStatus = this.pokemon.status?.effect;
|
||||
this.pokemon.status = null;
|
||||
if (lastStatus === StatusEffect.SLEEP) {
|
||||
this.pokemon.setFrameRate(10);
|
||||
if (this.pokemon.getTag(BattlerTagType.NIGHTMARE)) {
|
||||
this.pokemon.lapseTag(BattlerTagType.NIGHTMARE);
|
||||
}
|
||||
}
|
||||
if (this.affectConfusion) {
|
||||
if (this.pokemon.getTag(BattlerTagType.CONFUSED)) {
|
||||
this.pokemon.lapseTag(BattlerTagType.CONFUSED);
|
||||
}
|
||||
}
|
||||
if (this.reloadAssets) {
|
||||
this.pokemon.loadAssets(false).then(() => this.pokemon.playAnim());
|
||||
}
|
||||
this.pokemon.updateInfo(true);
|
||||
this.pokemon.clearStatus(this.affectConfusion, this.reloadAssets);
|
||||
this.end();
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ export class RevivalBlessingPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
pokemon.resetTurnData();
|
||||
pokemon.resetStatus();
|
||||
pokemon.resetStatus(true, false, false, false);
|
||||
pokemon.heal(Math.min(toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
|
||||
globalScene.queueMessage(
|
||||
i18next.t("moveTriggers:revivalBlessing", {
|
||||
|
@ -310,6 +310,48 @@ const timedEvents: TimedEvent[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Shining Spring",
|
||||
eventType: EventType.SHINY,
|
||||
startDate: new Date(Date.UTC(2025, 4, 2)),
|
||||
endDate: new Date(Date.UTC(2025, 4, 12)),
|
||||
bannerKey: "spr25event",
|
||||
scale: 0.21,
|
||||
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "es-MX", "pt-BR", "zh-CN"],
|
||||
shinyMultiplier: 2,
|
||||
upgradeUnlockedVouchers: true,
|
||||
eventEncounters: [
|
||||
{ species: Species.HOPPIP },
|
||||
{ species: Species.CELEBI },
|
||||
{ species: Species.VOLBEAT },
|
||||
{ species: Species.ILLUMISE },
|
||||
{ species: Species.SPOINK },
|
||||
{ species: Species.LILEEP },
|
||||
{ species: Species.SHINX },
|
||||
{ species: Species.PACHIRISU },
|
||||
{ species: Species.CHERUBI },
|
||||
{ species: Species.MUNCHLAX },
|
||||
{ species: Species.TEPIG },
|
||||
{ species: Species.PANSAGE },
|
||||
{ species: Species.PANSEAR },
|
||||
{ species: Species.PANPOUR },
|
||||
{ species: Species.DARUMAKA },
|
||||
{ species: Species.ARCHEN },
|
||||
{ species: Species.DEERLING, formIndex: 0 }, // Spring Deerling
|
||||
{ species: Species.CLAUNCHER },
|
||||
{ species: Species.WISHIWASHI },
|
||||
{ species: Species.MUDBRAY },
|
||||
{ species: Species.DRAMPA },
|
||||
{ species: Species.JANGMO_O },
|
||||
{ species: Species.APPLIN },
|
||||
],
|
||||
classicWaveRewards: [
|
||||
{ wave: 8, type: "SHINY_CHARM" },
|
||||
{ wave: 8, type: "ABILITY_CHARM" },
|
||||
{ wave: 8, type: "CATCHING_CHARM" },
|
||||
{ wave: 25, type: "SHINY_CHARM" },
|
||||
],
|
||||
}
|
||||
];
|
||||
|
||||
export class TimedEventManager {
|
||||
|