diff --git a/public/images/pokemon/281.json b/public/images/pokemon/281.json index 8e865cdc935..cb1a43f256f 100644 --- a/public/images/pokemon/281.json +++ b/public/images/pokemon/281.json @@ -399,13 +399,13 @@ "x": 0, "y": 6, "w": 36, - "h": 55 + "h": 54 }, "frame": { "x": 72, "y": 55, "w": 36, - "h": 55 + "h": 54 } }, { @@ -420,13 +420,13 @@ "x": 0, "y": 6, "w": 36, - "h": 55 + "h": 54 }, "frame": { "x": 72, "y": 55, "w": 36, - "h": 55 + "h": 54 } }, { diff --git a/public/images/pokemon/shiny/281.json b/public/images/pokemon/shiny/281.json index 684be77edf9..64e10c7f9a6 100644 --- a/public/images/pokemon/shiny/281.json +++ b/public/images/pokemon/shiny/281.json @@ -399,13 +399,13 @@ "x": 0, "y": 6, "w": 36, - "h": 55 + "h": 54 }, "frame": { "x": 72, "y": 55, "w": 36, - "h": 55 + "h": 54 } }, { @@ -420,13 +420,13 @@ "x": 0, "y": 6, "w": 36, - "h": 55 + "h": 54 }, "frame": { "x": 72, "y": 55, "w": 36, - "h": 55 + "h": 54 } }, { diff --git a/public/locales b/public/locales index b44ee217378..fc4a1effd51 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit b44ee2173788018ffd5dc6b7b7fa159be5b9d514 +Subproject commit fc4a1effd5170def3c8314208a52cd0d8e6913ef diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index a0ad4e8a52f..241524df1b9 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -2758,7 +2758,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (damage > 0) { if (source.isPlayer()) { - this.scene.validateAchvs(DamageAchv, damage); + this.scene.validateAchvs(DamageAchv, new Utils.NumberHolder(damage)); if (damage > this.scene.gameData.gameStats.highestDamage) { this.scene.gameData.gameStats.highestDamage = damage; } diff --git a/src/overrides.ts b/src/overrides.ts index 27886ded2f2..211d430a835 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -156,6 +156,7 @@ class DefaultOverrides { readonly EGG_VARIANT_OVERRIDE: VariantTier | null = null; readonly EGG_FREE_GACHA_PULLS_OVERRIDE: boolean = false; readonly EGG_GACHA_PULL_COUNT_OVERRIDE: number = 0; + readonly UNLIMITED_EGG_COUNT_OVERRIDE: boolean = false; // ------------------------- // MYSTERY ENCOUNTER OVERRIDES diff --git a/src/phases/level-up-phase.ts b/src/phases/level-up-phase.ts index a99e038acba..a2fa8a16533 100644 --- a/src/phases/level-up-phase.ts +++ b/src/phases/level-up-phase.ts @@ -28,7 +28,7 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase { this.scene.gameData.gameStats.highestLevel = this.level; } - this.scene.validateAchvs(LevelAchv, new Utils.IntegerHolder(this.level)); + this.scene.validateAchvs(LevelAchv, new Utils.NumberHolder(this.level)); const pokemon = this.getPokemon(); const prevStats = pokemon.stats.slice(0); diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index be4c6983c0a..d24484bbf9d 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -81,6 +81,8 @@ const namespaceMap = { miscDialogue: "dialogue-misc", battleSpecDialogue: "dialogue-final-boss", doubleBattleDialogue: "dialogue-double-battle", + splashMessages: "splash-texts", + mysteryEncounterMessages: "mystery-encounter-texts", }; //#region Functions diff --git a/src/system/achv.ts b/src/system/achv.ts index 7bac631d7aa..7329dd41fd5 100644 --- a/src/system/achv.ts +++ b/src/system/achv.ts @@ -109,7 +109,7 @@ export class DamageAchv extends Achv { damageAmount: integer; constructor(localizationKey: string, name: string, damageAmount: integer, iconImage: string, score: integer) { - super(localizationKey, name, "", iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] as Utils.NumberHolder).value >= this.damageAmount); + super(localizationKey, name, "", iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] instanceof Utils.NumberHolder ? args[0].value : args[0]) >= this.damageAmount); this.damageAmount = damageAmount; } } @@ -118,7 +118,7 @@ export class HealAchv extends Achv { healAmount: integer; constructor(localizationKey: string, name: string, healAmount: integer, iconImage: string, score: integer) { - super(localizationKey, name, "", iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] as Utils.NumberHolder).value >= this.healAmount); + super(localizationKey, name, "", iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] instanceof Utils.NumberHolder ? args[0].value : args[0]) >= this.healAmount); this.healAmount = healAmount; } } @@ -127,7 +127,7 @@ export class LevelAchv extends Achv { level: integer; constructor(localizationKey: string, name: string, level: integer, iconImage: string, score: integer) { - super(localizationKey, name, "", iconImage, score, (scene: BattleScene, args: any[]) => (args[0] as Utils.IntegerHolder).value >= this.level); + super(localizationKey, name, "", iconImage, score, (scene: BattleScene, args: any[]) => (args[0] instanceof Utils.NumberHolder ? args[0].value : args[0]) >= this.level); this.level = level; } } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 3131d468ee1..ea0857ab0c2 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1123,10 +1123,16 @@ export class GameData { }); } + /** + * Delete the session data at the given slot when overwriting a save file + * For deleting the session of a finished run, use {@linkcode tryClearSession} + * @param slotId the slot to clear + * @returns Promise with result `true` if the session was deleted successfully, `false` otherwise + */ deleteSession(slotId: integer): Promise { return new Promise(resolve => { if (bypassLogin) { - localStorage.removeItem(`sessionData${this.scene.sessionSlotId ? this.scene.sessionSlotId : ""}_${loggedInUser?.username}`); + localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); return resolve(true); } @@ -1147,7 +1153,7 @@ export class GameData { loggedInUser.lastSessionSlot = -1; } - localStorage.removeItem(`sessionData${slotId > 0 ? slotId : ""}_${loggedInUser?.username}`); + localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); resolve(true); } @@ -1188,7 +1194,9 @@ export class GameData { /** - * Attempt to clear session data. After session data is removed, attempt to update user info so the menu updates + * Attempt to clear session data after the end of a run + * After session data is removed, attempt to update user info so the menu updates + * To delete an unfinished run instead, use {@linkcode deleteSession} */ async tryClearSession(scene: BattleScene, slotId: integer): Promise<[success: boolean, newClear: boolean]> { let result: [boolean, boolean] = [ false, false ]; @@ -1206,7 +1214,7 @@ export class GameData { if (loggedInUser) { loggedInUser!.lastSessionSlot = -1; } - localStorage.removeItem(`sessionData${slotId > 0 ? slotId : ""}_${loggedInUser?.username}`); + localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`); } else { if (jsonResponse && jsonResponse.error?.startsWith("session out of date")) { this.scene.clearPhaseQueue(); diff --git a/src/ui/egg-gacha-ui-handler.ts b/src/ui/egg-gacha-ui-handler.ts index 56cd5299949..366f1604740 100644 --- a/src/ui/egg-gacha-ui-handler.ts +++ b/src/ui/egg-gacha-ui-handler.ts @@ -34,6 +34,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { private cursorObj: Phaser.GameObjects.Image; private transitioning: boolean; private transitionCancelled: boolean; + private summaryFinished: boolean; private defaultText: string; private scale: number = 0.1666666667; @@ -479,7 +480,12 @@ export default class EggGachaUiHandler extends MessageUiHandler { } showSummary(eggs: Egg[]): void { - this.transitioning = false; + // the overlay will appear faster if the egg pulling animation was skipped + const overlayEaseInDuration = this.getDelayValue(750); + + this.summaryFinished = false; + this.transitionCancelled = false; + this.setTransitioning(true); this.eggGachaSummaryContainer.setVisible(true); const eggScale = eggs.length < 20 ? 1 : 0.5; @@ -488,12 +494,14 @@ export default class EggGachaUiHandler extends MessageUiHandler { targets: this.eggGachaOverlay, alpha: 0.5, ease: "Sine.easeOut", - duration: 750, + duration: overlayEaseInDuration, onComplete: () => { const rowItems = 5; const rows = Math.ceil(eggs.length / rowItems); const cols = Math.min(eggs.length, rowItems); const height = this.eggGachaOverlay.displayHeight - this.eggGachaMessageBox.displayHeight; + + // Create sprites for each egg const eggContainers = eggs.map((egg, t) => { const col = t % rowItems; const row = Math.floor(t / rowItems); @@ -515,14 +523,24 @@ export default class EggGachaUiHandler extends MessageUiHandler { return ret; }); - eggContainers.forEach((eggContainer, e) => { - this.scene.tweens.add({ - targets: eggContainer, - delay: this.getDelayValue(e * 100), - duration: this.getDelayValue(350), - scale: eggScale, - ease: "Sine.easeOut" - }); + // If action/cancel was pressed when the overlay was easing in, show all eggs at once + // Otherwise show the eggs one by one with a small delay between each + eggContainers.forEach((eggContainer, index) => { + const delay = !this.transitionCancelled ? this.getDelayValue(index * 100) : 0; + this.scene.time.delayedCall(delay, () => + this.scene.tweens.add({ + targets: eggContainer, + duration: this.getDelayValue(350), + scale: eggScale, + ease: "Sine.easeOut", + onComplete: () => { + if (index === eggs.length - 1) { + this.setTransitioning(false); + this.summaryFinished = true; + } + } + })); + }); } }); @@ -540,6 +558,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { this.eggGachaSummaryContainer.setAlpha(1); this.eggGachaSummaryContainer.removeAll(true); this.setTransitioning(false); + this.summaryFinished = false; this.eggGachaOptionsContainer.setVisible(true); } }); @@ -613,7 +632,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { } else { if (this.eggGachaSummaryContainer.visible) { - if (button === Button.ACTION || button === Button.CANCEL) { + if (this.summaryFinished && (button === Button.ACTION || button === Button.CANCEL)) { this.hideSummary(); success = true; } @@ -625,7 +644,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { if (!this.scene.gameData.voucherCounts[VoucherType.REGULAR] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { error = true; this.showError(i18next.t("egg:notEnoughVouchers")); - } else if (this.scene.gameData.eggs.length < 99) { + } else if (this.scene.gameData.eggs.length < 99 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) { if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { this.consumeVouchers(VoucherType.REGULAR, 1); } @@ -640,7 +659,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { if (!this.scene.gameData.voucherCounts[VoucherType.PLUS] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { error = true; this.showError(i18next.t("egg:notEnoughVouchers")); - } else if (this.scene.gameData.eggs.length < 95) { + } else if (this.scene.gameData.eggs.length < 95 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) { if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { this.consumeVouchers(VoucherType.PLUS, 1); } @@ -657,7 +676,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { || (this.cursor === 3 && !this.scene.gameData.voucherCounts[VoucherType.PREMIUM] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE)) { error = true; this.showError(i18next.t("egg:notEnoughVouchers")); - } else if (this.scene.gameData.eggs.length < 90) { + } else if (this.scene.gameData.eggs.length < 90 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) { if (this.cursor === 3) { if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { this.consumeVouchers(VoucherType.PREMIUM, 1); @@ -678,7 +697,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { if (!this.scene.gameData.voucherCounts[VoucherType.GOLDEN] && !Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { error = true; this.showError(i18next.t("egg:notEnoughVouchers")); - } else if (this.scene.gameData.eggs.length < 75) { + } else if (this.scene.gameData.eggs.length < 75 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) { if (!Overrides.EGG_FREE_GACHA_PULLS_OVERRIDE) { this.consumeVouchers(VoucherType.GOLDEN, 1); } diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 9623d78c51e..5bbe765947e 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -1789,7 +1789,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { options.push({ label: `x${sameSpeciesEggCost} ${i18next.t("starterSelectUiHandler:sameSpeciesEgg")}`, handler: () => { - if (this.scene.gameData.eggs.length < 99 && (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= sameSpeciesEggCost)) { + if ((this.scene.gameData.eggs.length < 99 || Overrides.UNLIMITED_EGG_COUNT_OVERRIDE) + && (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= sameSpeciesEggCost)) { if (!Overrides.FREE_CANDY_UPGRADE_OVERRIDE) { starterData.candyCount -= sameSpeciesEggCost; }