From 5cdf1489653c587411dbcba698e59e8c25321acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Ricardo=20Fleury=20Oliveira?= Date: Sun, 16 Jun 2024 17:23:18 -0300 Subject: [PATCH 01/16] [Localization] Localized Daily Run Scoreboard (#2053) * localized daily run scoreboard * Update src/locales/de/menu.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * localized positionIcon * Update src/locales/ko/menu.ts Co-authored-by: Enoch --------- Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> Co-authored-by: Enoch --- src/locales/de/menu.ts | 4 ++++ src/locales/en/menu.ts | 4 ++++ src/locales/es/menu.ts | 4 ++++ src/locales/fr/menu.ts | 4 ++++ src/locales/it/menu.ts | 4 ++++ src/locales/ko/menu.ts | 4 ++++ src/locales/pt_BR/menu.ts | 4 ++++ src/locales/zh_CN/menu.ts | 4 ++++ src/locales/zh_TW/menu.ts | 4 ++++ src/ui/daily-run-scoreboard.ts | 6 +++--- 10 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/locales/de/menu.ts b/src/locales/de/menu.ts index d8987fcf77b..d8a3c8f14e8 100644 --- a/src/locales/de/menu.ts +++ b/src/locales/de/menu.ts @@ -44,6 +44,10 @@ export const menu: SimpleTranslationEntries = { "dailyRankings": "Tägliche Rangliste", "weeklyRankings": "Wöchentliche Rangliste", "noRankings": "Keine Rangliste", + "positionIcon": "#", + "usernameScoreboard": "Benutzername", + "score": "Punkte", + "wave": "Welle", "loading": "Lade…", "loadingAsset": "Loading asset: {{assetName}}", "playersOnline": "Spieler Online", diff --git a/src/locales/en/menu.ts b/src/locales/en/menu.ts index 03b8f22332d..0b9e45aa6d9 100644 --- a/src/locales/en/menu.ts +++ b/src/locales/en/menu.ts @@ -44,6 +44,10 @@ export const menu: SimpleTranslationEntries = { "dailyRankings": "Daily Rankings", "weeklyRankings": "Weekly Rankings", "noRankings": "No Rankings", + "positionIcon": "#", + "usernameScoreboard": "Username", + "score": "Score", + "wave": "Wave", "loading": "Loading…", "loadingAsset": "Loading asset: {{assetName}}", "playersOnline": "Players Online", diff --git a/src/locales/es/menu.ts b/src/locales/es/menu.ts index 4bd6d750d69..a201bc91e77 100644 --- a/src/locales/es/menu.ts +++ b/src/locales/es/menu.ts @@ -44,6 +44,10 @@ export const menu: SimpleTranslationEntries = { "dailyRankings": "Rankings Diarios", "weeklyRankings": "Rankings Semanales", "noRankings": "Sin Rankings", + "positionIcon": "#", + "usernameScoreboard": "Username", + "score": "Score", + "wave": "Wave", "loading": "Cargando…", "loadingAsset": "Cargando recurso: {{assetName}}", "playersOnline": "Jugadores en Línea", diff --git a/src/locales/fr/menu.ts b/src/locales/fr/menu.ts index f9538e9d26c..4d37bde35d8 100644 --- a/src/locales/fr/menu.ts +++ b/src/locales/fr/menu.ts @@ -39,6 +39,10 @@ export const menu: SimpleTranslationEntries = { "dailyRankings": "Classement du Jour", "weeklyRankings": "Classement de la Semaine", "noRankings": "Pas de Classement", + "positionIcon": "#", + "usernameScoreboard": "Username", + "score": "Score", + "wave": "Wave", "loading": "Chargement…", "loadingAsset": "Loading asset: {{assetName}}", "playersOnline": "Joueurs Connectés", diff --git a/src/locales/it/menu.ts b/src/locales/it/menu.ts index 07af8ee70e9..acfe68403ec 100644 --- a/src/locales/it/menu.ts +++ b/src/locales/it/menu.ts @@ -39,6 +39,10 @@ export const menu: SimpleTranslationEntries = { "dailyRankings": "Classifica giornaliera", "weeklyRankings": "Classifica settimanale", "noRankings": "Nessuna classifica", + "positionIcon": "#", + "usernameScoreboard": "Username", + "score": "Score", + "wave": "Wave", "loading": "Caricamento…", "loadingAsset": "Caricamento asset: {{assetName}}", "playersOnline": "Giocatori online", diff --git a/src/locales/ko/menu.ts b/src/locales/ko/menu.ts index 9245d67533a..2ad8b0c9e14 100644 --- a/src/locales/ko/menu.ts +++ b/src/locales/ko/menu.ts @@ -44,6 +44,10 @@ export const menu: SimpleTranslationEntries = { "dailyRankings": "일간 랭킹", "weeklyRankings": "주간 랭킹", "noRankings": "랭킹 정보 없음", + "positionIcon": "#", + "usernameScoreboard": "이름", + "score": "점수", + "wave": "웨이브", "loading": "로딩 중…", "loadingAsset": "Loading asset: {{assetName}}", "playersOnline": "플레이어 온라인", diff --git a/src/locales/pt_BR/menu.ts b/src/locales/pt_BR/menu.ts index f4fc8cc3a72..1743154c0d0 100644 --- a/src/locales/pt_BR/menu.ts +++ b/src/locales/pt_BR/menu.ts @@ -44,6 +44,10 @@ export const menu: SimpleTranslationEntries = { "dailyRankings": "Classificação Diária", "weeklyRankings": "Classificação Semanal", "noRankings": "Sem Classificação", + "positionIcon": "#", + "usernameScoreboard": "Usuário", + "score": "Pontuação", + "wave": "Onda", "loading": "Carregando…", "loadingAsset": "Carregando recurso: {{assetName}}", "playersOnline": "Jogadores Ativos", diff --git a/src/locales/zh_CN/menu.ts b/src/locales/zh_CN/menu.ts index 39d8e5e3a04..4dd2a4cbe33 100644 --- a/src/locales/zh_CN/menu.ts +++ b/src/locales/zh_CN/menu.ts @@ -44,6 +44,10 @@ export const menu: SimpleTranslationEntries = { "dailyRankings": "每日排名", "weeklyRankings": "每周排名", "noRankings": "无排名", + "positionIcon": "#", + "usernameScoreboard": "Username", + "score": "Score", + "wave": "Wave", "loading": "加载中...", "loadingAsset": "Loading asset: {{assetName}}", "playersOnline": "在线玩家", diff --git a/src/locales/zh_TW/menu.ts b/src/locales/zh_TW/menu.ts index d16052f2ac7..a967c0d8c16 100644 --- a/src/locales/zh_TW/menu.ts +++ b/src/locales/zh_TW/menu.ts @@ -44,6 +44,10 @@ export const menu: SimpleTranslationEntries = { "dailyRankings": "每日排名", "weeklyRankings": "每週排名", "noRankings": "無排名", + "positionIcon": "#", + "usernameScoreboard": "Username", + "score": "Score", + "wave": "Wave", "loading": "加載中…", "loadingAsset": "Loading asset: {{assetName}}", "playersOnline": "在線玩家", diff --git a/src/ui/daily-run-scoreboard.ts b/src/ui/daily-run-scoreboard.ts index aa0cce62525..212d7b2a66c 100644 --- a/src/ui/daily-run-scoreboard.ts +++ b/src/ui/daily-run-scoreboard.ts @@ -1,8 +1,8 @@ +import i18next from "i18next"; import BattleScene from "../battle-scene"; +import * as Utils from "../utils"; import { TextStyle, addTextObject } from "./text"; import { WindowVariant, addWindow } from "./ui-theme"; -import * as Utils from "../utils"; -import i18next from "i18next"; interface RankingEntry { rank: integer, @@ -154,7 +154,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container { return entryContainer; }; - this.rankingsContainer.add(getEntry("#", "Username", "Score", "Wave")); + this.rankingsContainer.add(getEntry(i18next.t("menu:positionIcon"), i18next.t("menu:usernameScoreboard"), i18next.t("menu:score"), i18next.t("menu:wave"))); rankings.forEach((r: RankingEntry, i: integer) => { const entryContainer = getEntry(r.rank.toString(), r.username, r.score.toString(), r.wave.toString()); From cc1b37c0970847171c038e2881b421870c1c2699 Mon Sep 17 00:00:00 2001 From: Madmadness65 Date: Sun, 16 Jun 2024 17:38:32 -0500 Subject: [PATCH 02/16] Correct Iron Jugulis' passive ability --- src/data/pokemon-species.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 58050c99d78..28e39755139 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -3795,7 +3795,7 @@ export const starterPassiveAbilities = { [Species.IRON_TREADS]: Abilities.STEELY_SPIRIT, [Species.IRON_BUNDLE]: Abilities.SNOW_WARNING, [Species.IRON_HANDS]: Abilities.IRON_FIST, - [Species.IRON_JUGULIS]: Abilities.AERILATE, + [Species.IRON_JUGULIS]: Abilities.LIGHTNING_ROD, [Species.IRON_MOTH]: Abilities.LEVITATE, [Species.IRON_THORNS]: Abilities.SAND_STREAM, [Species.FRIGIBAX]: Abilities.SNOW_WARNING, From 90f6ae7e6d4adc00062ec398419d8863ececc120 Mon Sep 17 00:00:00 2001 From: chaosgrimmon <31082757+chaosgrimmon@users.noreply.github.com> Date: Sun, 16 Jun 2024 18:40:47 -0400 Subject: [PATCH 03/16] [Bug] Friendship-based moves have Base Power -1 when Pokemon is wild (#2291) Affects RETURN, FRUSTRATION, PIKA_POW, and VEEVEE_VOLLEY. --- src/data/move.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 3116bf58f56..31ddd7b14ff 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -3034,10 +3034,8 @@ export class FriendshipPowerAttr extends VariablePowerAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const power = args[0] as Utils.NumberHolder; - if (user instanceof PlayerPokemon) { - const friendshipPower = Math.floor(Math.min(user.friendship, 255) / 2.5); - power.value = Math.max(!this.invert ? friendshipPower : 102 - friendshipPower, 1); - } + const friendshipPower = Math.floor(Math.min(user instanceof PlayerPokemon ? user.friendship : user.species.baseFriendship, 255) / 2.5); + power.value = Math.max(!this.invert ? friendshipPower : 102 - friendshipPower, 1); return true; } From f26a21c74bed9a562d424a813dc4e2c4b024d598 Mon Sep 17 00:00:00 2001 From: Yonmaru40 <47717431+40chyan@users.noreply.github.com> Date: Mon, 17 Jun 2024 06:42:17 +0800 Subject: [PATCH 04/16] [Localization(zh)] Update fight-ui-handler.ts (#2302) --- src/locales/zh_CN/fight-ui-handler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/zh_CN/fight-ui-handler.ts b/src/locales/zh_CN/fight-ui-handler.ts index 7ccab7561da..43b59d09170 100644 --- a/src/locales/zh_CN/fight-ui-handler.ts +++ b/src/locales/zh_CN/fight-ui-handler.ts @@ -4,6 +4,6 @@ export const fightUiHandler: SimpleTranslationEntries = { "pp": "PP", "power": "威力", "accuracy": "命中", - "abilityFlyInText": " {{pokemonName}}'s {{passive}}{{abilityName}}", - "passive": "Passive ", // The space at the end is important + "abilityFlyInText": " {{pokemonName}} 的 {{passive}}{{abilityName}}", + "passive": "被动 ", // The space at the end is important } as const; From 0ed8c32e8a810b0566e517da441c82d4780b3e87 Mon Sep 17 00:00:00 2001 From: Yonmaru40 <47717431+40chyan@users.noreply.github.com> Date: Mon, 17 Jun 2024 06:43:52 +0800 Subject: [PATCH 05/16] [Localization(zh)] Update growth.ts (#2305) --- src/locales/zh_CN/growth.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/locales/zh_CN/growth.ts b/src/locales/zh_CN/growth.ts index 33a1dec8bb8..7297554bd98 100644 --- a/src/locales/zh_CN/growth.ts +++ b/src/locales/zh_CN/growth.ts @@ -1,10 +1,10 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n"; export const growth: SimpleTranslationEntries = { - "Erratic": "最快", - "Fast": "较快", - "Medium_Fast": "快", - "Medium_Slow": "慢", - "Slow": "较慢", - "Fluctuating": "最慢" -} as const; + "Erratic": "非常快", + "Fast": "快", + "Medium_Fast": "较快", + "Medium_Slow": "较慢", + "Slow": "慢", + "Fluctuating": "非常慢" +} as const; From 29f95ef3941646dad6e37c531511394c003e9c68 Mon Sep 17 00:00:00 2001 From: Yonmaru40 <47717431+40chyan@users.noreply.github.com> Date: Mon, 17 Jun 2024 06:44:49 +0800 Subject: [PATCH 06/16] [Localization] zh_cn various translation fix and update (#2306) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update pokemon-info.ts * Update trainers.ts * Update ability-trigger.ts * Update battle.ts * Update ability-trigger.ts * Update save-slot-select-ui-handler.ts * 用→因为 --- src/locales/zh_CN/ability-trigger.ts | 4 +-- src/locales/zh_CN/battle.ts | 28 +++++++++---------- src/locales/zh_CN/pokemon-info.ts | 4 +-- .../zh_CN/save-slot-select-ui-handler.ts | 4 +-- src/locales/zh_CN/trainers.ts | 12 ++++---- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/locales/zh_CN/ability-trigger.ts b/src/locales/zh_CN/ability-trigger.ts index 07fedd8ac3e..4efc3cdb0b5 100644 --- a/src/locales/zh_CN/ability-trigger.ts +++ b/src/locales/zh_CN/ability-trigger.ts @@ -2,7 +2,7 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n"; export const abilityTriggers: SimpleTranslationEntries = { "blockRecoilDamage" : "{{pokemonName}} 的 {{abilityName}}\n抵消了反作用力!", - "badDreams": "{{pokemonName}} 被折磨着!", + "badDreams": "{{pokemonName}} 被折磨着!", "windPowerCharged": "受 {{moveName}} 的影响, {{pokemonName}} 提升了能力!", - "iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!" + "iceFaceAvoidedDamage": "{{pokemonName}} 因为 {{abilityName}}\n避免了伤害!" } as const; diff --git a/src/locales/zh_CN/battle.ts b/src/locales/zh_CN/battle.ts index 6d911b7b502..8c607a6ade6 100644 --- a/src/locales/zh_CN/battle.ts +++ b/src/locales/zh_CN/battle.ts @@ -56,18 +56,18 @@ export const battle: SimpleTranslationEntries = { "skipItemQuestion": "你确定要跳过拾取道具吗?", "eggHatching": "咦?", "ivScannerUseQuestion": "对 {{pokemonName}} 使用个体值扫描仪?", - "wildPokemonWithAffix": "Wild {{pokemonName}}", - "foePokemonWithAffix": "Foe {{pokemonName}}", - "useMove": "{{pokemonNameWithAffix}} used {{moveName}}!", - "drainMessage": "{{pokemonName}} had its\nenergy drained!", - "regainHealth": "{{pokemonName}} regained\nhealth!", - "fainted": "{{pokemonNameWithAffix}} fainted!", - "statRose": "rose", - "statSharplyRose": "sharply rose", - "statRoseDrastically": "rose drastically", - "statWontGoAnyHigher": "won't go any higher", - "statFell": "fell", - "statHarshlyFell": "harshly fell", - "statSeverelyFell": "severely fell", - "statWontGoAnyLower": "won't go any lower", + "wildPokemonWithAffix": "野生的 {{pokemonName}}", + "foePokemonWithAffix": "对手 {{pokemonName}}", + "useMove": "{{pokemonNameWithAffix}} 使用了 {{moveName}}!", + "drainMessage": "{{pokemonName}} 吸取了体力!", + "regainHealth": "{{pokemonName}} 回复了体力!", + "fainted": "{{pokemonNameWithAffix}} 倒下了!", + "statRose": "提高了!", + "statSharplyRose": "大幅提高了!", + "statRoseDrastically": "极大幅提高了!", + "statWontGoAnyHigher": "已经无法再提高了!", + "statFell": "降低了!", + "statHarshlyFell": "大幅降低了!", + "statSeverelyFell": "极大幅降低了!", + "statWontGoAnyLower": "已经无法再降低了!", } as const; diff --git a/src/locales/zh_CN/pokemon-info.ts b/src/locales/zh_CN/pokemon-info.ts index 7c72acb1b2a..7f3394219fb 100644 --- a/src/locales/zh_CN/pokemon-info.ts +++ b/src/locales/zh_CN/pokemon-info.ts @@ -14,8 +14,8 @@ export const pokemonInfo: PokemonInfoTranslationEntries = { "SPDEFshortened": "特防", "SPD": "速度", "SPDshortened": "速度", - "ACC": "Accuracy", - "EVA": "Evasiveness" + "ACC": "命中率", + "EVA": "回避率" }, Type: { diff --git a/src/locales/zh_CN/save-slot-select-ui-handler.ts b/src/locales/zh_CN/save-slot-select-ui-handler.ts index 0d657235e49..657c2dccb3a 100644 --- a/src/locales/zh_CN/save-slot-select-ui-handler.ts +++ b/src/locales/zh_CN/save-slot-select-ui-handler.ts @@ -1,9 +1,9 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n"; export const saveSlotSelectUiHandler: SimpleTranslationEntries = { - "overwriteData": "Overwrite the data in the selected slot?", + "overwriteData": "要覆盖该槽位的存档吗?", "loading": "正在加载中...", - "wave": "Wave", + "wave": "层数", "lv": "Lv", "empty": "空", } as const; diff --git a/src/locales/zh_CN/trainers.ts b/src/locales/zh_CN/trainers.ts index 28b0760cc9b..8238978781e 100644 --- a/src/locales/zh_CN/trainers.ts +++ b/src/locales/zh_CN/trainers.ts @@ -48,7 +48,7 @@ export const trainerClasses: SimpleTranslationEntries = { "depot_agent": "铁路员工", "doctor": "医生", "doctor_female": "医生", - "firebreather": "Firebreather", + "firebreather": "吹火人", "fisherman": "垂钓者", "fisherman_female": "垂钓者", "gentleman": "绅士", @@ -87,13 +87,13 @@ export const trainerClasses: SimpleTranslationEntries = { "pokémon_rangers": "宝可梦巡护员组合", "ranger": "巡护员", "restaurant_staff": "服务生组合", - "rich": "Rich", - "rich_female": "Rich", + "rich": "富豪", + "rich_female": "富豪太太", "rich_boy": "富家少爷", "rich_couple": "富豪夫妇", - "rich_kid": "Rich Kid", - "rich_kid_female": "Rich Kid", - "rich_kids": "富二代组合", + "rich_kid": "富家小孩", + "rich_kid_female": "富家小孩", + "rich_kids": "富家小孩组合", "roughneck": "光头男", "sailor": "水手", "scientist": "研究员", From 1396aaaa5729173898a633970a6ab9212a155d41 Mon Sep 17 00:00:00 2001 From: chaosgrimmon <31082757+chaosgrimmon@users.noreply.github.com> Date: Sun, 16 Jun 2024 18:48:42 -0400 Subject: [PATCH 07/16] [Move] Sappy Seed shouldn't be Making Contact (#2303) https://bulbapedia.bulbagarden.net/wiki/Sappy_Seed_(move) --- src/data/move.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/data/move.ts b/src/data/move.ts index 31ddd7b14ff..83909c7f3c5 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -7576,6 +7576,7 @@ export function initMoves() { new AttackMove(Moves.BADDY_BAD, Type.DARK, MoveCategory.SPECIAL, 80, 95, 15, -1, 0, 7) .attr(AddArenaTagAttr, ArenaTagType.REFLECT, 5, false, true), new AttackMove(Moves.SAPPY_SEED, Type.GRASS, MoveCategory.PHYSICAL, 100, 90, 10, 100, 0, 7) + .makesContact(false) .attr(AddBattlerTagAttr, BattlerTagType.SEEDED), new AttackMove(Moves.FREEZY_FROST, Type.ICE, MoveCategory.SPECIAL, 100, 90, 10, -1, 0, 7) .attr(ResetStatsAttr), From a44ab950badaf3f979cf7f36f64df0b303f5f58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2?= <123510358+NicusPulcis@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:49:11 +0200 Subject: [PATCH 08/16] [Localization(it)] Update tutorial.ts (#2294) --- src/locales/it/tutorial.ts | 50 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/locales/it/tutorial.ts b/src/locales/it/tutorial.ts index 8488fc3151f..e5bee8ae2be 100644 --- a/src/locales/it/tutorial.ts +++ b/src/locales/it/tutorial.ts @@ -2,41 +2,41 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n"; export const tutorial: SimpleTranslationEntries = { "intro": `Benvenuto in PokéRogue! Questo gioco si concentra sulle battaglie, con elementi roguelite. - $Questo gioco non è monetizzato e non siamo proprietari di Pokemon e Assets presenti nel gioco. - $Il gioco è work-in-progress ma giocabile al 100%.\nPer reportare eventuali bugs è possibile discuterne sul nostro Discord. - $Se il game risulta 'lento', assicurati di aver abilitato l'Accelerazione Hardware nelle impostazioni del tuo Browser`, + $Questo gioco non è monetizzato e non siamo proprietari di Pokémon ed assets presenti nel gioco. + $Il progetto è work-in-progress, ma giocabile al 100%.\nPer segnalare eventuali bug è possibile contattarci al nostro apposito Discord. + $Se il gioco risulta 'lento', assicurati di aver abilitato l'accelerazione hardware nelle impostazioni del tuo browser`, - "accessMenu": "Per accedere al menù, press M o Esc.\nDal menù puoi cambiare impostazioni, controllare la wiki e accedere a varie features.", + "accessMenu": "Per accedere al menu, premi M o esc.\nDal menu puoi modificare le impostazioni, controllare la wiki ed accedere a varie features.", - "menu": `Da questo menù puoi accedere alle impostazioni. - $Dalle impostazioni puoi cambiare velocità di gioco, stile di finestra e altre opzioni. - $Ci sono varie funzionalità, controlla bene e non perderti nulla!`, + "menu": `Da questo menu puoi accedere alle impostazioni. + $Esse ti permettono di cambiare velocità di gioco, stile delle finestre ed altre opzioni. + $Ci sono varie funzionalità: controlla bene e non perderti nulla!`, - "starterSelect": `Da questa schermata puoi selezionare il tuo starter.\nQuesti sono i membri iniziali del tuo parti. + "starterSelect": `Da questa schermata puoi selezionare il tuo starter.\nQuesti sono i membri iniziali della tua squadra. $Ogni starter ha un valore. Puoi avere fino a \n6 Pokèmon, avendo a disposizione un massimo di 10 punti. - $Puoi anche selezionare Sesso, Abilità, e Forma a seconda delle\nvarianti che hai catturato o schiuso. + $Puoi anche selezionare genere, abilità, e forma a seconda delle\nvarianti che hai catturato o schiuso. $Le IVs di una specie sono le migliori rispetto a tutte quelle che hai\ncatturato o schiuso, quindi prova a catturarne il piu possibile!`, - "pokerus": `Giornalmente 3 Starter casuali disponibili avranno il bordo viola. - $Se possiedi uno di questi starter,\nprova ad aggiungerlo al party. Ricorda di controllare le info!`, + "pokerus": `Giornalmente 3 starter casuali disponibili avranno il bordo viola. + $Se possiedi uno di questi starter,\nprova ad aggiungerlo alla squadra. Ricorda di controllarne le info!`, - "statChange": `I cambiamenti alle statistiche persistono fintanto che i tuoi pokèmon resteranno in campo. + "statChange": `I cambiamenti alle statistiche persistono fintanto che i tuoi pokèmon restano in campo. $I tuoi pokemon verranno richiamati quando incontrerai un allenatore o al cambiamento di bioma. $Puoi anche vedere i cambiamenti alle statistiche in corso tenendo premuto C o Shift`, - "selectItem": `Dopo ogni battaglia avrai disponibili tre item.\nPotrai prenderne solo uno. - $Questi spaziano tra consumabili, item tenuti da Pokèmon o con un effetto passivo permanente. - $La maggior parte degli Item non Consumabili possono stackare in diversi modi. - $Alcuni Item risulteranno disponibili solo se possono essere usati, come Item Evolutivi. - $Puoi anche passare un Item tenuto da un Pokèmon ad un altro attraverso l'opzione 'trasferisci strumento'. - $L'opzione 'trasferisci strumento' sarà disponibile solo dopo aver assegnato uno strumento ad un Pokèmon. - $Puoi acquistare consumabili con le monete, progredendo saranno poi disponibili ulteriori oggetti. - $Assicurati di fare un acquisto prima di selezionare un item casuale, poichè passerai subito alla lotta successiva.`, + "selectItem": `Dopo ogni battaglia potrai scegliere tra 3 oggetti.\nPotrai prenderne solo uno. + $Questi spaziano tra consumabili, oggetti tenuti da Pokèmon o con un effetto passivo permanente. + $La maggior parte degli oggetti non consumabili possono accumulare i loro effetti in diversi modi. + $Alcuni risulteranno inoltre disponibili solo se possono essere usati, come ad esempio gli oggetti evolutivi. + $Puoi anche passare un oggetto tenuto da un Pokèmon a un altro attraverso l'opzione 'trasferisci strumento'. + $Quest'ultima sarà disponibile solo dopo aver assegnato uno strumento ad un Pokèmon. + $Puoi acquistare consumabili con le monete; progredendo saranno poi disponibili ulteriori oggetti. + $Assicurati di fare un acquisto prima di selezionare un item casuale, poichè dopo aver fatto ciò passerai subito alla lotta successiva.`, - "eggGacha": `Da questa schermata, puoi riscattare i tuoi vouchers in cambio di\nuova Pokèmon. - $Le uova vanno schiuse e saranno sempre più vicine alla schiusura dopo\nogni battaglia. Le uova più rare impiegheranno più battaglie per la schiusura. - $I Pokémon schiusi non verranno aggiunti alla tua squadra, saranno\naggiunti ai tuoi starters. - $I Pokémon schiusi generalmente hanno IVs migliori rispetto ai\n Pokémon selvatici. - $Alcuni Pokémon possono essere ottenuti solo tramite uova. + "eggGacha": `Da questa schermata puoi riscattare i tuoi vouchers in cambio di\nuova Pokèmon. + $Le uova vanno schiuse, e saranno sempre più vicine alla schiusura dopo\nogni battaglia. Le uova più rare impiegheranno più battaglie per la schiusura. + $I Pokémon schiusi non verranno aggiunti alla tua squadra, ma saranno\ninvece aggiunti ai tuoi starters. + $I Pokémon schiusi hanno (generalmente) IVs migliori rispetto ai\n Pokémon selvatici. + $Inoltre, alcuni Pokémon possono essere ottenuti solo tramite uova. $Ci sono 3 diversi macchinari con differenti\nbonus, scegli quello che preferisci!`, } as const; From bcd622bd946377eca83e451315bc6882ee0c8d23 Mon Sep 17 00:00:00 2001 From: ReneGV Date: Sun, 16 Jun 2024 16:51:25 -0600 Subject: [PATCH 09/16] [QoL] Skip money rewards on last classic wave (#2121) * Skip money rewards on last classic round * Fix big nugget --- src/modifier/modifier-type.ts | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index ac7452ae4c9..4d2d2765eac 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1017,6 +1017,30 @@ export class EnemyEndureChanceModifierType extends ModifierType { export type ModifierTypeFunc = () => ModifierType; type WeightedModifierTypeWeightFunc = (party: Pokemon[], rerollCount?: integer) => integer; +/** + * High order function that returns a WeightedModifierTypeWeightFunc that will only be applied on + * classic and skip an ModifierType if current wave is greater or equal to the one passed down + * @param wave - Wave where we should stop showing the modifier + * @param defaultWeight - ModifierType default weight + * @returns A WeightedModifierTypeWeightFunc + */ +function skipInClassicAfterWave(wave: integer, defaultWeight: integer): WeightedModifierTypeWeightFunc { + return (party: Pokemon[]) => { + const gameMode = party[0].scene.gameMode; + const currentWave = party[0].scene.currentBattle.waveIndex; + return gameMode.isClassic && currentWave >= wave ? 0 : defaultWeight; + }; +} + +/** + * High order function that returns a WeightedModifierTypeWeightFunc that will only be applied on + * classic and it will skip a ModifierType if it is the last wave pull. + * @param defaultWeight ModifierType default weight + * @returns A WeightedModifierTypeWeightFunc + */ +function skipInLastClassicWaveOrDefault(defaultWeight: integer) : WeightedModifierTypeWeightFunc { + return skipInClassicAfterWave(199, defaultWeight); +} class WeightedModifierType { public modifierType: ModifierType; public weight: integer | WeightedModifierTypeWeightFunc; @@ -1313,7 +1337,7 @@ const modifierPool: ModifierPool = { }, 3), new WeightedModifierType(modifierTypes.DIRE_HIT, 4), new WeightedModifierType(modifierTypes.SUPER_LURE, 4), - new WeightedModifierType(modifierTypes.NUGGET, 5), + new WeightedModifierType(modifierTypes.NUGGET, skipInLastClassicWaveOrDefault(5)), new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, (party: Pokemon[]) => { return Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15), 8); }, 8), @@ -1336,7 +1360,7 @@ const modifierPool: ModifierPool = { [ModifierTier.ULTRA]: [ new WeightedModifierType(modifierTypes.ULTRA_BALL, 24), new WeightedModifierType(modifierTypes.MAX_LURE, 4), - new WeightedModifierType(modifierTypes.BIG_NUGGET, 12), + new WeightedModifierType(modifierTypes.BIG_NUGGET, skipInLastClassicWaveOrDefault(12)), new WeightedModifierType(modifierTypes.PP_UP, 9), new WeightedModifierType(modifierTypes.PP_MAX, 3), new WeightedModifierType(modifierTypes.MINT, 4), @@ -1371,7 +1395,7 @@ const modifierPool: ModifierPool = { }), [ModifierTier.ROGUE]: [ new WeightedModifierType(modifierTypes.ROGUE_BALL, 24), - new WeightedModifierType(modifierTypes.RELIC_GOLD, 2), + new WeightedModifierType(modifierTypes.RELIC_GOLD, skipInLastClassicWaveOrDefault(2)), new WeightedModifierType(modifierTypes.LEFTOVERS, 3), new WeightedModifierType(modifierTypes.SHELL_BELL, 3), new WeightedModifierType(modifierTypes.BERRY_POUCH, 4), From 0138a480f999d57bd15d0b9787247a6f8512dfa6 Mon Sep 17 00:00:00 2001 From: Yonmaru40 <47717431+40chyan@users.noreply.github.com> Date: Mon, 17 Jun 2024 06:53:22 +0800 Subject: [PATCH 10/16] [Localization(zh)] Update game-mode.ts (#2304) --- src/locales/zh_CN/game-mode.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/locales/zh_CN/game-mode.ts b/src/locales/zh_CN/game-mode.ts index be342b4c390..3a9ad92fc84 100644 --- a/src/locales/zh_CN/game-mode.ts +++ b/src/locales/zh_CN/game-mode.ts @@ -1,10 +1,10 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n"; export const gameMode: SimpleTranslationEntries = { - "classic": "Classic", - "endless": "Endless", - "endlessSpliced": "Endless (Spliced)", - "dailyRun": "Daily Run", - "unknown": "Unknown", - "challenge": "Challenge", + "classic": "经典模式", + "endless": "无尽模式", + "endlessSpliced": "融合无尽模式", + "dailyRun": "每日挑战", + "unknown": "未知", + "challenge": "挑战模式", } as const; From 40ade2da1d7c845cac8228cfac17d5128d454aaa Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:54:31 +0200 Subject: [PATCH 11/16] [Localization(ko)] Fixed Korean Battle Stat Change Text (#2292) --- src/locales/ko/battle.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/locales/ko/battle.ts b/src/locales/ko/battle.ts index d9774bf1c06..ddfcf99aed6 100644 --- a/src/locales/ko/battle.ts +++ b/src/locales/ko/battle.ts @@ -63,11 +63,11 @@ export const battle: SimpleTranslationEntries = { "regainHealth": "{{pokemonName}}[[는]]\n기력을 회복했다!", "fainted": "{{pokemonNameWithAffix}}[[는]] 쓰러졌다!", "statRose": "상승했다", - "statSharplyRose": "약간 상승했다", - "statRoseDrastically": "대폭 상승했다", - "statWontGoAnyHigher": "더 이상 상승할 수 없다", + "statSharplyRose": "크게 상승했다", + "statRoseDrastically": "매우 크게 상승했다", + "statWontGoAnyHigher": "더 이상 올라갈 수 없다", "statFell": "떨어졌다", - "statHarshlyFell": "약간 떨어졌다", - "statSeverelyFell": "대폭 떨어졌다", + "statHarshlyFell": "크게 떨어졌다", + "statSeverelyFell": "매우 크게 떨어졌다", "statWontGoAnyLower": "더 이상 떨어질 수 없다", } as const; From de51c5b7a5d149526f2ea574e4e49b523dfa444a Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Mon, 17 Jun 2024 01:43:14 +0200 Subject: [PATCH 12/16] [Localization] Translated missing german entries (#2289) --- src/locales/de/ability-trigger.ts | 2 +- src/locales/de/battle.ts | 16 ++++++++-------- src/locales/de/pokemon-info.ts | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/locales/de/ability-trigger.ts b/src/locales/de/ability-trigger.ts index 652c16eb662..042b70acf8c 100644 --- a/src/locales/de/ability-trigger.ts +++ b/src/locales/de/ability-trigger.ts @@ -4,5 +4,5 @@ export const abilityTriggers: SimpleTranslationEntries = { "blockRecoilDamage" : "{{pokemonName}} wurde durch {{abilityName}}\nvor Rückstoß geschützt!", "badDreams": "{{pokemonName}} ist in einem Alptraum gefangen!", "windPowerCharged": "Der Treffer durch {{moveName}} läd die Stärke von {{pokemonName}} auf!", - "iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!", + "iceFaceAvoidedDamage": "{{pokemonName}} wehrt Schaden\nmit {{abilityName}} ab!", } as const; diff --git a/src/locales/de/battle.ts b/src/locales/de/battle.ts index 86336b0e233..48f355e7ea1 100644 --- a/src/locales/de/battle.ts +++ b/src/locales/de/battle.ts @@ -62,12 +62,12 @@ export const battle: SimpleTranslationEntries = { "drainMessage": "{{pokemonName}} wurde Energie abgesaugt", "regainHealth": "KP von {{pokemonName}} wurden wieder aufgefrischt!", "fainted": "{{pokemonNameWithAffix}} wurde besiegt!", - "statRose": "rose", - "statSharplyRose": "sharply rose", - "statRoseDrastically": "rose drastically", - "statWontGoAnyHigher": "won't go any higher", - "statFell": "fell", - "statHarshlyFell": "harshly fell", - "statSeverelyFell": "severely fell", - "statWontGoAnyLower": "won't go any lower", + "statRose": "steigt", + "statSharplyRose": "steigt stark", + "statRoseDrastically": "steigt drastisch", + "statWontGoAnyHigher": "kann nicht weiter erhöht werden", + "statFell": "sinkt", + "statHarshlyFell": "sinkt stark", + "statSeverelyFell": "sinkt drastisch", + "statWontGoAnyLower": "kann nicht weiter sinken", } as const; diff --git a/src/locales/de/pokemon-info.ts b/src/locales/de/pokemon-info.ts index 0d350a75c36..730a4cc4c5f 100644 --- a/src/locales/de/pokemon-info.ts +++ b/src/locales/de/pokemon-info.ts @@ -14,8 +14,8 @@ export const pokemonInfo: PokemonInfoTranslationEntries = { "SPDEFshortened": "SpVert", "SPD": "Initiative", "SPDshortened": "Init", - "ACC": "Accuracy", - "EVA": "Evasiveness" + "ACC": "Genauigkeit", + "EVA": "Fluchtwert", }, Type: { From 1efb7c58470746300506c1157efc67dc1ca4e117 Mon Sep 17 00:00:00 2001 From: Frederico Santos Date: Mon, 17 Jun 2024 02:44:07 +0100 Subject: [PATCH 13/16] [Bug] Unauthorized 401 error fix (#2315) * reset scene on 401 * fix: Reset scene and clear session ID on 401 error * Added explanation to clientSessionId --- src/account.ts | 1 + src/phases.ts | 24 +++++++++++++++++++++--- src/system/game-data.ts | 2 +- src/ui/unavailable-modal-ui-handler.ts | 4 ++++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/account.ts b/src/account.ts index e5bde56bfe3..4d19513908f 100644 --- a/src/account.ts +++ b/src/account.ts @@ -7,6 +7,7 @@ export interface UserInfo { } export let loggedInUser: UserInfo = null; +// This is a random string that is used to identify the client session - unique per session (tab or window) so that the game will only save on the one that the server is expecting export const clientSessionId = Utils.randomString(32); export function initLoggedInUser(): void { diff --git a/src/phases.ts b/src/phases.ts index ad5819edf30..f4c32284f8c 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -94,7 +94,14 @@ export class LoginPhase extends Phase { this.scene.playSound("menu_open"); const loadData = () => { - updateUserInfo().then(() => this.scene.gameData.loadSystem().then(() => this.end())); + updateUserInfo().then(success => { + if (!success[0]) { + Utils.setCookie(Utils.sessionIdKey, ""); + this.scene.reset(true, true); + return; + } + this.scene.gameData.loadSystem().then(() => this.end()); + }); }; this.scene.ui.setMode(Mode.LOGIN_FORM, { @@ -108,7 +115,14 @@ export class LoginPhase extends Phase { buttonActions: [ () => { this.scene.ui.playSelect(); - updateUserInfo().then(() => this.end()); + updateUserInfo().then(success => { + if (!success[0]) { + Utils.setCookie(Utils.sessionIdKey, ""); + this.scene.reset(true, true); + return; + } + this.end(); + } ); }, () => { this.scene.unshiftPhase(new LoginPhase(this.scene, false)); this.end(); @@ -118,6 +132,9 @@ export class LoginPhase extends Phase { } ] }); + } else if (statusCode === 401) { + Utils.setCookie(Utils.sessionIdKey, ""); + this.scene.reset(true, true); } else { this.scene.unshiftPhase(new UnavailablePhase(this.scene)); super.end(); @@ -4198,7 +4215,8 @@ 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=${this.scene.sessionSlotId}&clientSessionId=${clientSessionId}`, true) .then(response => response.json()) + Utils.apiFetch(`savedata/session/newclear?slot=${this.scene.sessionSlotId}&clientSessionId=${clientSessionId}`, true) + .then(response => response.json()) .then(newClear => doGameOver(newClear)); } else { this.scene.gameData.offlineNewClear(this.scene).then(result => { diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 9fb253df092..0e26eab436d 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1261,7 +1261,7 @@ export class GameData { if (!bypassLogin && dataType < GameDataType.SETTINGS) { updateUserInfo().then(success => { - if (!success) { + if (!success[0]) { return displayError(`Could not contact the server. Your ${dataName} data could not be imported.`); } let url: string; diff --git a/src/ui/unavailable-modal-ui-handler.ts b/src/ui/unavailable-modal-ui-handler.ts index 60d01a93c82..cddcde2a1b3 100644 --- a/src/ui/unavailable-modal-ui-handler.ts +++ b/src/ui/unavailable-modal-ui-handler.ts @@ -3,6 +3,7 @@ import { ModalConfig, ModalUiHandler } from "./modal-ui-handler"; import { addTextObject, TextStyle } from "./text"; import { Mode } from "./ui"; import { updateUserInfo } from "#app/account"; +import * as Utils from "#app/utils"; export default class UnavailableModalUiHandler extends ModalUiHandler { private reconnectTimer: NodeJS.Timeout; @@ -55,6 +56,9 @@ export default class UnavailableModalUiHandler extends ModalUiHandler { this.reconnectDuration = this.minTime; this.scene.playSound("pb_bounce_1"); this.reconnectCallback(); + } else if (response[1] === 401) { + Utils.setCookie(Utils.sessionIdKey, ""); + this.scene.reset(true, true); } else { this.reconnectDuration = Math.min(this.reconnectDuration * 2, this.maxTime); // Set a max delay so it isn't infinite this.reconnectTimer = From 942cbb21817b510b98b19af8ee1908860cd8203e Mon Sep 17 00:00:00 2001 From: layharu0 <37300617+layharu0@users.noreply.github.com> Date: Mon, 17 Jun 2024 11:01:08 +0900 Subject: [PATCH 14/16] [Localization][ko] StatRose, StatFell Message Fix (#2285) --- src/locales/ko/battle.ts | 16 ++++++++-------- src/test/lokalisation/battle-stat.test.ts | 5 ++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/locales/ko/battle.ts b/src/locales/ko/battle.ts index ddfcf99aed6..e9be8a7fa43 100644 --- a/src/locales/ko/battle.ts +++ b/src/locales/ko/battle.ts @@ -62,12 +62,12 @@ export const battle: SimpleTranslationEntries = { "drainMessage": "{{pokemonName}}[[로]]부터\n체력을 흡수했다!", "regainHealth": "{{pokemonName}}[[는]]\n기력을 회복했다!", "fainted": "{{pokemonNameWithAffix}}[[는]] 쓰러졌다!", - "statRose": "상승했다", - "statSharplyRose": "크게 상승했다", - "statRoseDrastically": "매우 크게 상승했다", - "statWontGoAnyHigher": "더 이상 올라갈 수 없다", - "statFell": "떨어졌다", - "statHarshlyFell": "크게 떨어졌다", - "statSeverelyFell": "매우 크게 떨어졌다", - "statWontGoAnyLower": "더 이상 떨어질 수 없다", + "statRose": "[[가]] 올라갔다!", + "statSharplyRose": "[[가]] 크게 올라갔다!", + "statRoseDrastically": "[[가]] 매우 크게 올라갔다!", + "statWontGoAnyHigher": "[[는]] 더 올라가지 않는다!", + "statFell": "[[가]] 떨어졌다!", + "statHarshlyFell": "[[가]] 크게 떨어졌다!", + "statSeverelyFell": "[[가]] 매우 크게 떨어졌다!", + "statWontGoAnyLower": "[[는]] 더 떨어지지 않는다!", } as const; diff --git a/src/test/lokalisation/battle-stat.test.ts b/src/test/lokalisation/battle-stat.test.ts index 99269c6ec4c..cd21f638258 100644 --- a/src/test/lokalisation/battle-stat.test.ts +++ b/src/test/lokalisation/battle-stat.test.ts @@ -21,6 +21,7 @@ import { pokemonInfo as zhTwPokemonInfo } from "#app/locales/zh_TW/pokemon-info. import { battle as zhTwBattleStat } from "#app/locales/zh_TW/battle.js"; import i18next, {initI18n} from "#app/plugins/i18n"; +import { KoreanPostpositionProcessor } from "i18next-korean-postposition-processor"; interface BattleStatTestUnit { stat: BattleStat, @@ -198,7 +199,9 @@ describe("Test for BattleStat Localization", () => { it("Test getBattleStatLevelChangeDescription() in 한국어", async () => { i18next.changeLanguage("ko", () => { battleStatLevelUnits.forEach(unit => { - testBattleStatLevelChangeDescription(unit.levels, unit.up, koBattleStat[unit.key]); + const processor = new KoreanPostpositionProcessor(); + const message = processor.process(koBattleStat[unit.key]); + testBattleStatLevelChangeDescription(unit.levels, unit.up, message); }); }); }); From 9e1da3d5489446764b631e5fa22a538f47ef6c7f Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 16 Jun 2024 22:03:40 -0400 Subject: [PATCH 15/16] clean loading scene and let mobile see intro (#2316) --- src/loading-scene.ts | 86 +++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 50 deletions(-) diff --git a/src/loading-scene.ts b/src/loading-scene.ts index fbe1d23f049..f6ca88192da 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -24,6 +24,8 @@ import { Biome } from "#enums/biome"; import { TrainerType } from "#enums/trainer-type"; export class LoadingScene extends SceneBase { + readonly LOAD_EVENTS = Phaser.Loader.Events; + constructor() { super("loading"); @@ -35,10 +37,6 @@ export class LoadingScene extends SceneBase { Utils.localPing(); this.load["manifest"] = this.game["manifest"]; - if (!isMobile()) { - this.load.video("intro_dark", "images/intro_dark.mp4", true); - } - this.loadImage("loading_bg", "arenas"); this.loadImage("logo", ""); this.loadImage("pride-update", "events"); @@ -421,58 +419,46 @@ export class LoadingScene extends SceneBase { }); disclaimerDescriptionText.setOrigin(0.5, 0.5); - disclaimerText.setVisible(false); - disclaimerDescriptionText.setVisible(false); - - const intro = this.add.video(0, 0); - intro.setOrigin(0, 0); - intro.setScale(3); - - this.load.on("progress", (value: string) => { - const parsedValue = parseFloat(value); - percentText.setText(`${Math.floor(parsedValue * 100)}%`); - progressBar.clear(); - progressBar.fillStyle(0xffffff, 0.8); - progressBar.fillRect(midWidth - 320, 360, 640 * parsedValue, 64); - }); - - this.load.on("fileprogress", file => { - assetText.setText(i18next.t("menu:loadingAsset", { assetName: file.key })); - }); - - loadingGraphics.push(bg, graphics, progressBar, progressBox, logo, percentText, assetText); + loadingGraphics.push(bg, graphics, progressBar, progressBox, logo, percentText, assetText, disclaimerText, disclaimerDescriptionText); if (!mobile) { loadingGraphics.map(g => g.setVisible(false)); } - const destroyLoadingAssets = () => { - intro.destroy(); - bg.destroy(); - logo.destroy(); - progressBar.destroy(); - progressBox.destroy(); - percentText.destroy(); - assetText.destroy(); - }; + const intro = this.add.video(0, 0); + intro.on(Phaser.GameObjects.Events.VIDEO_COMPLETE, (video: Phaser.GameObjects.Video) => { + this.tweens.add({ + targets: intro, + duration: 500, + alpha: 0, + ease: "Sine.easeIn", + onComplete: () => video.destroy(), + }); + loadingGraphics.forEach(g => g.setVisible(true)); + }); + intro.setOrigin(0, 0); + intro.setScale(3); - this.load.on("filecomplete", key => { + this.load.once(this.LOAD_EVENTS.START, () => { + // videos do not need to be preloaded + intro.loadURL("images/intro_dark.mp4", true); + if (mobile) { + intro.video.setAttribute("webkit-playsinline", "webkit-playsinline"); + intro.video.setAttribute("playsinline", "playsinline"); + } + intro.play(); + }); + + this.load.on(this.LOAD_EVENTS.PROGRESS , (progress: number) => { + percentText.setText(`${Math.floor(progress * 100)}%`); + progressBar.clear(); + progressBar.fillStyle(0xffffff, 0.8); + progressBar.fillRect(midWidth - 320, 360, 640 * progress, 64); + }); + + this.load.on(this.LOAD_EVENTS.FILE_COMPLETE, (key: string) => { + assetText.setText(i18next.t("menu:loadingAsset", { assetName: key })); switch (key) { - case "intro_dark": - intro.load("intro_dark"); - intro.on("complete", () => { - this.tweens.add({ - targets: intro, - duration: 500, - alpha: 0, - ease: "Sine.easeIn" - }); - loadingGraphics.map(g => g.setVisible(true)); - disclaimerText.setVisible(true); - disclaimerDescriptionText.setVisible(true); - }); - intro.play(); - break; case "loading_bg": bg.setTexture("loading_bg"); if (mobile) { @@ -488,7 +474,7 @@ export class LoadingScene extends SceneBase { } }); - this.load.on("complete", () => destroyLoadingAssets()); + this.load.on(this.LOAD_EVENTS.COMPLETE, () => loadingGraphics.forEach(go => go.destroy())); } get gameHeight() { From 111f4362fcc1f88f640923368297a0379257e11c Mon Sep 17 00:00:00 2001 From: prime <10091050+prime-dialga@users.noreply.github.com> Date: Mon, 17 Jun 2024 06:49:29 +0200 Subject: [PATCH 16/16] [QoL] Improved Nature selection + Persistent selection of various values (#1401) * Added nature selection menu Added a nature selection menu to the starter selection, as you can way too easily skip over the nature you want when cycling. All nature selections are furthermore persistent and stored in the starterData. Those changes are compatible with the current save format, but will increase the size, so, in case the size of the save file can't be increased, further changes will be needed. * Sorted nature selection into sub-menus The nature-selection menu is now, instead of one large list, multiple smaller menus. Those menus will appear once at least one nature of the appropriate kind has been collected. Translations partially required. * Update French starter-select-ui-handler.ts * Added support for updated save structure Adds compatibility with updated save-data structure which supports more persistent starter attributes * more persistent start data Abilities, Variants and Forms are now also saved. * added gender to stored information * fixed typedoc issues * Starter Preferences now stored locally * removed deprecated import (due last merge) * Sub menus removed --------- Co-authored-by: Lugiad --- src/locales/de/starter-select-ui-handler.ts | 2 + src/locales/en/starter-select-ui-handler.ts | 2 + src/locales/es/starter-select-ui-handler.ts | 2 + src/locales/fr/starter-select-ui-handler.ts | 8 +- src/locales/it/starter-select-ui-handler.ts | 2 + .../pt_BR/starter-select-ui-handler.ts | 2 + .../zh_CN/starter-select-ui-handler.ts | 2 + .../zh_TW/starter-select-ui-handler.ts | 2 + src/system/game-data.ts | 42 +++++- src/ui/starter-select-ui-handler.ts | 137 +++++++++++++++++- 10 files changed, 194 insertions(+), 7 deletions(-) diff --git a/src/locales/de/starter-select-ui-handler.ts b/src/locales/de/starter-select-ui-handler.ts index a448dcedad8..c31f4725806 100644 --- a/src/locales/de/starter-select-ui-handler.ts +++ b/src/locales/de/starter-select-ui-handler.ts @@ -25,7 +25,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "addToParty": "Zum Team hinzufügen", "toggleIVs": "DVs anzeigen/verbergen", "manageMoves": "Attacken ändern", + "manageNature": "Wesen ändern", "useCandies": "Bonbons verwenden", + "selectNature": "Wähle das neue Wesen.", "selectMoveSwapOut": "Wähle die zu ersetzende Attacke.", "selectMoveSwapWith": "Wähle die gewünschte Attacke.", "unlockPassive": "Passiv-Skill freischalten", diff --git a/src/locales/en/starter-select-ui-handler.ts b/src/locales/en/starter-select-ui-handler.ts index fd2eb6c40df..d17f681b53c 100644 --- a/src/locales/en/starter-select-ui-handler.ts +++ b/src/locales/en/starter-select-ui-handler.ts @@ -25,7 +25,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "addToParty": "Add to Party", "toggleIVs": "Toggle IVs", "manageMoves": "Manage Moves", + "manageNature": "Manage Nature", "useCandies": "Use Candies", + "selectNature": "Select nature.", "selectMoveSwapOut": "Select a move to swap out.", "selectMoveSwapWith": "Select a move to swap with", "unlockPassive": "Unlock Passive", diff --git a/src/locales/es/starter-select-ui-handler.ts b/src/locales/es/starter-select-ui-handler.ts index 4d025820260..9b6e03b26c0 100644 --- a/src/locales/es/starter-select-ui-handler.ts +++ b/src/locales/es/starter-select-ui-handler.ts @@ -25,7 +25,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "addToParty": "Añadir a Equipo", "toggleIVs": "Mostrar IVs", "manageMoves": "Gestionar Movs.", + "manageNature": "Gestionar Natur", "useCandies": "Usar Caramelos", + "selectNature": "Elige Natur.", "selectMoveSwapOut": "Elige el movimiento que sustituir.", "selectMoveSwapWith": "Elige el movimiento que sustituirá a", "unlockPassive": "Añadir Pasiva", diff --git a/src/locales/fr/starter-select-ui-handler.ts b/src/locales/fr/starter-select-ui-handler.ts index 9f504cab11e..02e5c2742ac 100644 --- a/src/locales/fr/starter-select-ui-handler.ts +++ b/src/locales/fr/starter-select-ui-handler.ts @@ -23,9 +23,11 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "eggMoves": "Capacités Œuf", "start": "Lancer", "addToParty": "Ajouter à l’équipe", - "toggleIVs": "Voir IVs", - "manageMoves": "Gérer Capacités", - "useCandies": "Utiliser Bonbons", + "toggleIVs": "Voir les IV", + "manageMoves": "Modifier les Capacités", + "manageNature": "Modifier la Nature", + "useCandies": "Utiliser des Bonbons", + "selectNature": "Sélectionnez une nature.", "selectMoveSwapOut": "Sélectionnez la capacité à échanger.", "selectMoveSwapWith": "Sélectionnez laquelle échanger avec", "unlockPassive": "Débloquer Passif", diff --git a/src/locales/it/starter-select-ui-handler.ts b/src/locales/it/starter-select-ui-handler.ts index 48a0badaefc..fea0d2d8352 100644 --- a/src/locales/it/starter-select-ui-handler.ts +++ b/src/locales/it/starter-select-ui-handler.ts @@ -25,7 +25,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "addToParty": "Aggiungi al gruppo", "toggleIVs": "Vedi/Nascondi IV", "manageMoves": "Gestisci mosse", + "manageNature": "Gestisci natura", "useCandies": "Usa caramelle", + "selectNature": "Seleziona natura.", "selectMoveSwapOut": "Seleziona una mossa da scambiare.", "selectMoveSwapWith": "Seleziona una mossa da scambiare con", "unlockPassive": "Sblocca passiva", diff --git a/src/locales/pt_BR/starter-select-ui-handler.ts b/src/locales/pt_BR/starter-select-ui-handler.ts index fc98e72c614..7ee8789f860 100644 --- a/src/locales/pt_BR/starter-select-ui-handler.ts +++ b/src/locales/pt_BR/starter-select-ui-handler.ts @@ -25,7 +25,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "addToParty": "Adicionar à equipe", "toggleIVs": "Mostrar IVs", "manageMoves": "Mudar Movimentos", + "manageNature": "Mudar Natureza", "useCandies": "Usar Doces", + "selectNature": "Escolha Natureza.", "selectMoveSwapOut": "Escolha um movimento para substituir.", "selectMoveSwapWith": "Escolha o movimento que substituirá", "unlockPassive": "Aprender Passiva", diff --git a/src/locales/zh_CN/starter-select-ui-handler.ts b/src/locales/zh_CN/starter-select-ui-handler.ts index 803e64e0439..742e3c815f0 100644 --- a/src/locales/zh_CN/starter-select-ui-handler.ts +++ b/src/locales/zh_CN/starter-select-ui-handler.ts @@ -25,7 +25,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "addToParty": "加入队伍", "toggleIVs": "切换个体值", "manageMoves": "管理招式", + "manageNature": "管理性格", "useCandies": "使用糖果", + "selectNature": "选择性格", "selectMoveSwapOut": "选择要替换的招式。", "selectMoveSwapWith": "选择要替换成的招式", "unlockPassive": "解锁被动", diff --git a/src/locales/zh_TW/starter-select-ui-handler.ts b/src/locales/zh_TW/starter-select-ui-handler.ts index c28cb39b94b..748cb05af40 100644 --- a/src/locales/zh_TW/starter-select-ui-handler.ts +++ b/src/locales/zh_TW/starter-select-ui-handler.ts @@ -25,7 +25,9 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "addToParty": "加入隊伍", "toggleIVs": "查看個體值", "manageMoves": "管理技能", + "manageNature": "管理性格", "useCandies": "使用糖果", + "selectNature": "選擇性格", "selectMoveSwapOut": "選擇想要替換走的招式", "selectMoveSwapWith": "選擇想要替換成的招式", "unlockPassive": "解鎖被動", diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 0e26eab436d..f36bf1af229 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -136,7 +136,7 @@ interface VoucherUnlocks { } export interface VoucherCounts { - [type: string]: integer; + [type: string]: integer; } export interface DexData { @@ -187,6 +187,46 @@ export interface StarterMoveData { [key: integer]: StarterMoveset | StarterFormMoveData } +export interface StarterAttributes { + nature?: integer; + ability?: integer; + variant?: integer; + form?: integer; + female?: boolean; +} + +export interface StarterPreferences { + [key: integer]: StarterAttributes; +} + +// the latest data saved/loaded for the Starter Preferences. Required to reduce read/writes. Initialize as "{}", since this is the default value and no data needs to be stored if present. +// if they ever add private static variables, move this into StarterPrefs +const StarterPrefers_DEFAULT : string = "{}"; +let StarterPrefers_private_latest : string = StarterPrefers_DEFAULT; + +// This is its own class as StarterPreferences... +// - don't need to be loaded on startup +// - isn't stored with other data +// - don't require to be encrypted +// - shouldn't require calls outside of the starter selection +export class StarterPrefs { + // called on starter selection show once + static load(): StarterPreferences { + return JSON.parse( + StarterPrefers_private_latest = (localStorage.getItem(`starterPrefs_${loggedInUser?.username}`) || StarterPrefers_DEFAULT) + ); + } + + // called on starter selection clear, always + static save(prefs: StarterPreferences): void { + const pStr : string = JSON.stringify(prefs); + if (pStr !== StarterPrefers_private_latest) { + // something changed, store the update + localStorage.setItem(`starterPrefs_${loggedInUser?.username}`, pStr); + } + } +} + export interface StarterDataEntry { moveset: StarterMoveset | StarterFormMoveData; eggMoves: integer; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 0aa71de7e90..b9fd5c5c27e 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -17,7 +17,7 @@ import PokemonSpecies, { allSpecies, getPokemonSpecies, getPokemonSpeciesForm, g import { Type } from "../data/type"; import { GameModes } from "../game-mode"; import { SelectChallengePhase, TitlePhase } from "../phases"; -import { AbilityAttr, DexAttr, DexAttrProps, DexEntry, StarterFormMoveData, StarterMoveset } from "../system/game-data"; +import { AbilityAttr, DexAttr, DexAttrProps, DexEntry, StarterFormMoveData, StarterMoveset, StarterAttributes, StarterPreferences, StarterPrefs } from "../system/game-data"; import { Tutorial, handleTutorial } from "../tutorial"; import * as Utils from "../utils"; import { OptionSelectItem } from "./abstact-option-select-ui-handler"; @@ -270,6 +270,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { private starterSelectCallback: StarterSelectCallback; + private starterPreferences: StarterPreferences; + protected blockInput: boolean = false; constructor(scene: BattleScene) { @@ -780,6 +782,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } show(args: any[]): boolean { + if (!this.starterPreferences) { + // starterPreferences haven't been loaded yet + this.starterPreferences = StarterPrefs.load(); + } this.moveInfoOverlay.clear(); // clear this when removing a menu; the cancel button doesn't seem to trigger this automatically on controllers if (args.length >= 1 && args[0] instanceof Function) { super.show(args); @@ -1223,6 +1229,54 @@ export default class StarterSelectUiHandler extends MessageUiHandler { }); } const starterData = this.scene.gameData.starterData[this.lastSpecies.speciesId]; + let starterAttributes = this.starterPreferences[this.lastSpecies.speciesId]; + if (this.canCycleNature) { + // if we could cycle natures, enable the improved nature menu + const showNatureOptions = () => { + ui.setMode(Mode.STARTER_SELECT).then(() => { + ui.showText(i18next.t("starterSelectUiHandler:selectNature"), null, () => { + const natures = this.scene.gameData.getNaturesForAttr(this.speciesStarterDexEntry.natureAttr); + ui.setModeWithoutClear(Mode.OPTION_SELECT, { + options: natures.map((n: Nature, i: number) => { + const option: OptionSelectItem = { + label: getNatureName(n, true, true, true, this.scene.uiTheme), + handler: () => { + // update default nature in starter save data + if (!starterAttributes) { + starterAttributes= + this.starterPreferences[this.lastSpecies.speciesId] = {}; + } + starterAttributes.nature = n as unknown as integer; + this.clearText(); + ui.setMode(Mode.STARTER_SELECT); + // set nature for starter + this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, undefined, n, undefined); + return true; + } + }; + return option; + }).concat({ + label: i18next.t("menu:cancel"), + handler: () => { + this.clearText(); + ui.setMode(Mode.STARTER_SELECT); + return true; + } + }), + maxOptions: 8, + yOffset: 19 + }); + }); + }); + }; + options.push({ + label: i18next.t("starterSelectUiHandler:manageNature"), + handler: () => { + showNatureOptions(); + return true; + } + }); + } const candyCount = starterData.candyCount; const passiveAttr = starterData.passiveAttr; if (passiveAttr & PassiveAttr.UNLOCKED) { @@ -1362,9 +1416,16 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const rows = Math.ceil(genStarters / 9); const row = Math.floor(this.cursor / 9); const props = this.scene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.dexAttrCursor); + // prepare persistent starter data to store changes + let starterAttributes = this.starterPreferences[this.lastSpecies.speciesId]; + if (!starterAttributes) { + starterAttributes = + this.starterPreferences[this.lastSpecies.speciesId] = {}; + } switch (button) { case Button.CYCLE_SHINY: if (this.canCycleShiny) { + starterAttributes.variant = !props.shiny ? props.variant : -1; // update shiny setting this.setSpeciesDetails(this.lastSpecies, !props.shiny, undefined, undefined, props.shiny ? 0 : undefined, undefined, undefined); if (this.dexAttrCursor & DexAttr.SHINY) { this.scene.playSound("sparkle"); @@ -1383,12 +1444,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { break; } } while (newFormIndex !== props.formIndex); + starterAttributes.form = newFormIndex; // store the selected form this.setSpeciesDetails(this.lastSpecies, undefined, newFormIndex, undefined, undefined, undefined, undefined); success = true; } break; case Button.CYCLE_GENDER: if (this.canCycleGender) { + starterAttributes.female = !props.female; this.setSpeciesDetails(this.lastSpecies, undefined, undefined, !props.female, undefined, undefined, undefined); success = true; } @@ -1414,6 +1477,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } } } while (newAbilityIndex !== this.abilityCursor); + starterAttributes.ability = newAbilityIndex; // store the selected ability this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, newAbilityIndex, undefined); success = true; } @@ -1423,6 +1487,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const natures = this.scene.gameData.getNaturesForAttr(this.speciesStarterDexEntry.natureAttr); const natureIndex = natures.indexOf(this.natureCursor); const newNature = natures[natureIndex < natures.length - 1 ? natureIndex + 1 : 0]; + // store cycled nature as default + starterAttributes.nature = newNature as unknown as integer; this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, undefined, undefined, newNature, undefined); success = true; } @@ -1446,6 +1512,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } } } while (newVariant !== props.variant); + starterAttributes.variant = newVariant; // store the selected variant this.setSpeciesDetails(this.lastSpecies, undefined, undefined, undefined, newVariant, undefined, undefined); // Cycle tint based on current sprite tint @@ -1782,6 +1849,60 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.abilityCursor = species ? this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species) : 0; this.natureCursor = species ? this.scene.gameData.getSpeciesDefaultNature(species) : 0; + const starterAttributes : StarterAttributes = species ? {...this.starterPreferences[species.speciesId]} : null; + // validate starterAttributes + if (starterAttributes) { + // this may cause changes so we created a copy of the attributes before + if (!isNaN(starterAttributes.variant)) { + if (![ + this.speciesStarterDexEntry.caughtAttr & DexAttr.NON_SHINY, + this.speciesStarterDexEntry.caughtAttr & DexAttr.DEFAULT_VARIANT, + this.speciesStarterDexEntry.caughtAttr & DexAttr.VARIANT_2, + this.speciesStarterDexEntry.caughtAttr & DexAttr.VARIANT_3 + ][starterAttributes.variant+1]) { // add 1 as -1 = non-shiny + // requested variant wasn't unlocked, purging setting + delete starterAttributes.variant; + } + } + + if (typeof starterAttributes.female !== "boolean" || !(starterAttributes.female ? + this.speciesStarterDexEntry.caughtAttr & DexAttr.FEMALE : + this.speciesStarterDexEntry.caughtAttr & DexAttr.MALE + )) { + // requested gender wasn't unlocked, purging setting + delete starterAttributes.female; + } + + const abilityAttr = this.scene.gameData.starterData[species.speciesId].abilityAttr; + if (![ + abilityAttr & AbilityAttr.ABILITY_1, + species.ability2 ? (abilityAttr & AbilityAttr.ABILITY_2) : abilityAttr & AbilityAttr.ABILITY_HIDDEN, + species.ability2 && abilityAttr & AbilityAttr.ABILITY_HIDDEN + ][starterAttributes.ability]) { + // requested ability wasn't unlocked, purging setting + delete starterAttributes.ability; + } + + if (!(species.forms[starterAttributes.form]?.isStarterSelectable && this.speciesStarterDexEntry.caughtAttr & this.scene.gameData.getFormAttr(starterAttributes.form))) { + // requested form wasn't unlocked/isn't a starter form, purging setting + delete starterAttributes.form; + } + + if (this.scene.gameData.getNaturesForAttr(this.speciesStarterDexEntry.natureAttr).indexOf(starterAttributes.nature as unknown as Nature) < 0) { + // requested nature wasn't unlocked, purging setting + delete starterAttributes.nature; + } + } + + if (starterAttributes?.nature) { + // load default nature from stater save data, if set + this.natureCursor = starterAttributes.nature; + } + if (!isNaN(starterAttributes?.ability)) { + // load default nature from stater save data, if set + this.abilityCursor = starterAttributes.ability; + } + if (this.statsMode) { if (this.speciesStarterDexEntry?.caughtAttr) { this.statsContainer.setVisible(true); @@ -1920,9 +2041,17 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.setSpeciesDetails(species, props.shiny, props.formIndex, props.female, props.variant, this.starterAbilityIndexes[starterIndex], this.starterNatures[starterIndex]); } else { const defaultDexAttr = this.scene.gameData.getSpeciesDefaultDexAttr(species, false, true); - const defaultAbilityIndex = this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species); - const defaultNature = this.scene.gameData.getSpeciesDefaultNature(species); + const defaultAbilityIndex = starterAttributes?.ability ?? this.scene.gameData.getStarterSpeciesDefaultAbilityIndex(species); + // load default nature from stater save data, if set + const defaultNature = starterAttributes?.nature || this.scene.gameData.getSpeciesDefaultNature(species); props = this.scene.gameData.getSpeciesDexAttrProps(species, defaultDexAttr); + if (!isNaN(starterAttributes?.variant)) { + if (props.shiny = (starterAttributes.variant >= 0)) { + props.variant = starterAttributes.variant as Variant; + } + } + props.formIndex = starterAttributes?.form ?? props.formIndex; + props.female = starterAttributes?.female ?? props.female; this.setSpeciesDetails(species, props.shiny, props.formIndex, props.female, props.variant, defaultAbilityIndex, defaultNature); } @@ -2417,6 +2546,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { clear(): void { super.clear(); + + StarterPrefs.save(this.starterPreferences); this.cursor = -1; this.hideInstructions(); this.starterSelectContainer.setVisible(false);