diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index 9068f1ae9a2..2850418bc59 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -11,6 +11,8 @@ on: branches: - main # Trigger on pull request events targeting the main branch - beta # Trigger on pull request events targeting the beta branch + merge_group: + types: [checks_requested] jobs: run-linters: # Define a job named "run-linters" diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index 3b7617c45f4..a092ccb425a 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -8,6 +8,8 @@ on: branches: - main - beta + merge_group: + types: [checks_requested] jobs: pages: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9ce1d1c5038..adac45519ab 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,6 +11,8 @@ on: branches: - main # Trigger on pull request events targeting the main branch - beta # Trigger on pull request events targeting the beta branch + merge_group: + types: [checks_requested] jobs: run-tests: # Define a job named "run-tests" diff --git a/src/battle-scene.ts b/src/battle-scene.ts index c9f7362728a..4cc3f69ebee 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -130,7 +130,7 @@ export default class BattleScene extends SceneBase { public gameSpeed: integer = 1; public damageNumbersMode: integer = 0; public reroll: boolean = false; - public shopCursorTarget: number = ShopCursorTarget.CHECK_TEAM; + public shopCursorTarget: number = ShopCursorTarget.REWARDS; public showMovesetFlyout: boolean = true; public showArenaFlyout: boolean = true; public showTimeOfDayWidget: boolean = true; diff --git a/src/data/ability.ts b/src/data/ability.ts index 04dd15f9239..16ae7a2b2d2 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -3475,12 +3475,12 @@ export class MoodyAbAttr extends PostTurnAbAttr { if (!simulated) { if (canRaise.length > 0) { - const raisedStat = Utils.randSeedItem(canRaise); + const raisedStat = canRaise[pokemon.randSeedInt(canRaise.length)]; canLower = canRaise.filter(s => s !== raisedStat); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ raisedStat ], 2)); } if (canLower.length > 0) { - const loweredStat = Utils.randSeedItem(canLower); + const loweredStat = canLower[pokemon.randSeedInt(canLower.length)]; pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ loweredStat ], -1)); } } diff --git a/src/data/move.ts b/src/data/move.ts index bcdb16cdfbc..14d7addead0 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2675,7 +2675,7 @@ export class AcupressureStatStageChangeAttr extends MoveEffectAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { const randStats = BATTLE_STATS.filter(s => target.getStatStage(s) < 6); if (randStats.length > 0) { - const boostStat = [randStats[Utils.randInt(randStats.length)]]; + const boostStat = [randStats[user.randSeedInt(randStats.length)]]; user.scene.unshiftPhase(new StatStageChangePhase(user.scene, target.getBattlerIndex(), this.selfTarget, boostStat, 2)); return true; } diff --git a/src/enums/shop-cursor-target.ts b/src/enums/shop-cursor-target.ts index d2f72fed0d6..11f524399b2 100644 --- a/src/enums/shop-cursor-target.ts +++ b/src/enums/shop-cursor-target.ts @@ -1,13 +1,13 @@ /** - * Determines the cursor target when entering the shop phase. + * Determines the row cursor target when entering the shop phase. */ export enum ShopCursorTarget { - /** Cursor points to Reroll */ + /** Cursor points to Reroll row */ REROLL, - /** Cursor points to Items */ - ITEMS, - /** Cursor points to Shop */ + /** Cursor points to Rewards row */ + REWARDS, + /** Cursor points to Shop row */ SHOP, - /** Cursor points to Check Team */ + /** Cursor points to Check Team row */ CHECK_TEAM } diff --git a/src/locales/de/battle.json b/src/locales/de/battle.json index 762b5848439..05205b001b6 100644 --- a/src/locales/de/battle.json +++ b/src/locales/de/battle.json @@ -94,5 +94,6 @@ "retryBattle": "Möchtest du vom Beginn des Kampfes neustarten?", "unlockedSomething": "{{unlockedThing}} wurde freigeschaltet.", "congratulations": "Glückwunsch!", - "beatModeFirstTime": "{{speciesName}} hat den {{gameMode}} Modus zum ersten Mal beendet! Du erhältst {{newModifier}}!" + "beatModeFirstTime": "{{speciesName}} hat den {{gameMode}} Modus zum ersten Mal beendet! Du erhältst {{newModifier}}!", + "eggSkipPrompt": "Zur Ei-Zusammenfassung springen?" } \ No newline at end of file diff --git a/src/locales/de/challenges.json b/src/locales/de/challenges.json index 17c33353bc6..c8836c50549 100644 --- a/src/locales/de/challenges.json +++ b/src/locales/de/challenges.json @@ -1,10 +1,11 @@ { + "noneSelected": "Keine ausgewählt", "title": "Herausforderungsmodifikatoren", "illegalEvolution": "{{pokemon}} hat sich in ein Pokémon verwandelt, dass für diese Herausforderung nicht zulässig ist!", "singleGeneration": { "name": "Mono-Generation", "desc": "Du kannst nur Pokémon aus der {{gen}} Generation verwenden.", - "desc_default": "Du kannst nur Pokémon gewählten Generation verwenden.", + "desc_default": "Du kannst nur Pokémon aus der gewählten Generation verwenden.", "gen_1": "ersten", "gen_2": "zweiten", "gen_3": "dritten", diff --git a/src/locales/de/menu-ui-handler.json b/src/locales/de/menu-ui-handler.json index 56c03102b9c..93c3f4c38e8 100644 --- a/src/locales/de/menu-ui-handler.json +++ b/src/locales/de/menu-ui-handler.json @@ -25,5 +25,6 @@ "unlinkGoogle": "Google trennen", "cancel": "Abbrechen", "losingProgressionWarning": "Du wirst jeglichen Fortschritt seit Anfang dieses Kampfes verlieren. Fortfahren?", - "noEggs": "Du brütest aktuell keine Eier aus!" + "noEggs": "Du brütest aktuell keine Eier aus!", + "donate": "Spenden" } \ No newline at end of file diff --git a/src/locales/de/settings.json b/src/locales/de/settings.json index d72a026cf5a..31406f28d17 100644 --- a/src/locales/de/settings.json +++ b/src/locales/de/settings.json @@ -100,7 +100,7 @@ "moveTouchControls": "Bewegung Touch Steuerung", "shopOverlayOpacity": "Shop Overlay Deckkraft", "shopCursorTarget": "Shop-Cursor Ziel", - "items": "Items", + "rewards": "Items", "reroll": "Neu rollen", "shop": "Shop", "checkTeam": "Team überprüfen" diff --git a/src/locales/en/settings.json b/src/locales/en/settings.json index 6528f0368fe..301ebea9b2b 100644 --- a/src/locales/en/settings.json +++ b/src/locales/en/settings.json @@ -100,7 +100,7 @@ "moveTouchControls": "Move Touch Controls", "shopOverlayOpacity": "Shop Overlay Opacity", "shopCursorTarget": "Shop Cursor Target", - "items": "Items", + "rewards": "Rewards", "reroll": "Reroll", "shop": "Shop", "checkTeam": "Check Team" diff --git a/src/locales/es/arena-flyout.json b/src/locales/es/arena-flyout.json index b2881b5de76..e3ec1dc6d4a 100644 --- a/src/locales/es/arena-flyout.json +++ b/src/locales/es/arena-flyout.json @@ -1,21 +1,21 @@ { - "activeBattleEffects": "Efectos de Terreno Activos", + "activeBattleEffects": "Efectos de terreno activos", "player": "Jugador", "neutral": "Neutral", "enemy": "Enemigo", "sunny": "Sol", "rain": "Lluvia", - "sandstorm": "Tormenta de Arena", + "sandstorm": "Tormenta de arena", "hail": "Granizo", "snow": "Nieve", "fog": "Niebla", "heavyRain": "Diluvio", - "harshSun": "Sol Abrasador", + "harshSun": "Sol abrasador", "strongWinds": "Turbulencias", - "misty": "Campo de Niebla", - "electric": "Campo Eléctrico", - "grassy": "Campo de Hierba", - "psychic": "Campo Psíquico", + "misty": "Campo de niebla", + "electric": "Campo eléctrico", + "grassy": "Campo de hierba", + "psychic": "Campo psíquico", "mudSport": "Chapoteo Lodo", "waterSport": "Hidrochorro", "spikes": "Púas", @@ -37,4 +37,4 @@ "craftyShield": "Truco Defensa", "tailwind": "Viento Afín", "happyHour": "Paga Extra" -} \ No newline at end of file +} diff --git a/src/locales/es/arena-tag.json b/src/locales/es/arena-tag.json index 913876ddf87..0f63b62e784 100644 --- a/src/locales/es/arena-tag.json +++ b/src/locales/es/arena-tag.json @@ -1,4 +1,53 @@ { + "yourTeam": "tu equipo", + "opposingTeam": "el equipo rival", + "arenaOnRemove": "Los efectos de {{moveName}} desaparecieron.", + "arenaOnRemovePlayer": "Los efectos de {{moveName}}\ndesaparecieron en tu bando.", + "arenaOnRemoveEnemy": "Los efectos de {{moveName}}\ndesaparecieron en el bando rival.", + "mistOnAdd": "¡Neblina de {{pokemonNameWithAffix}}\nha cubierto a su equipo!", + "mistApply": "¡La neblina evita los cambios de estadísticas!", + "reflectOnAdd": "¡Reflejo redujo el daño físico!", + "reflectOnAddPlayer": "¡Reflejo redujo el daño físico en tu bando!", + "reflectOnAddEnemy": "Reflejo redujo el daño físico en el bando rival.", + "lightScreenOnAdd": "¡Pantalla de Luz redujo el daño físico!", + "lightScreenOnAddPlayer": "¡Pantalla de Luz redujo el daño físico en tu bando!", + "lightScreenOnAddEnemy": "¡Pantalla de Luz redujo el daño físico en el bando enemigo!", + "auroraVeilOnAdd": "¡Velo Aurora redujo el daño físico!", + "auroraVeilOnAddPlayer": "¡Velo Aurora redujo el daño físico en tu bando!", + "auroraVeilOnAddEnemy": "¡Velo Aurora redujo el daño físico en el bando rival!", + "conditionalProtectOnAdd": "¡{{moveName}} protege a su bando!", + "conditionalProtectOnAddPlayer": "¡{{moveName}} protege a tu bando!", + "conditionalProtectOnAddEnemy": "¡{{moveName}} protege al bando rival!", + "conditionalProtectApply": "¡{{pokemonNameWithAffix}} ha sido protegido por {{moveName}}!", + "matBlockOnAdd": "¡{{pokemonNameWithAffix}} va a usar un tatami para bloquear ataques!", + "noCritOnAddPlayer": "¡{{moveName}} protege a tu bando de golpes críticos!", + "noCritOnAddEnemy": "¡{{moveName}} protege al bando rival de golpes críticos!", + "noCritOnRemove": "¡Los efectos de {{moveName}} de {{pokemonNameWithAffix}} se han disipado!", + "wishTagOnAdd": "¡El deseo de {{pokemonNameWithAffix}} se ha hecho realidad!", + "mudSportOnAdd": "¡Se han debilitado los ataques de tipo Eléctrico!", + "mudSportOnRemove": "Chapoteo Lodo ha dejado de surtir efecto.", + "waterSportOnAdd": "¡Se han debilitado los ataques\nde tipo Fuego!", + "waterSportOnRemove": "Hidrochorro ha dejado de surtir efecto.", + "spikesOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por {{moveName}}!", + "spikesActivateTrap": "¡Las púas han herido a {{pokemonNameWithAffix}}!", + "toxicSpikesOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por {{moveName}}!", + "toxicSpikesActivateTrapPoison": "¡{{pokemonNameWithAffix}} ha sido herido por {{moveName}}!", + "stealthRockOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por piedras puntiagudas!", + "stealthRockActivateTrap": "¡Unas piedras puntiagudas han dañado a {{pokemonNameWithAffix}}!", + "stickyWebOnAdd": "¡Una {{moveName}} se extiende a los pies del bando rival!", + "stickyWebActivateTrap": "¡{{pokemonName}} ha caído en una red viscosa!", + "trickRoomOnAdd": "¡{{pokemonNameWithAffix}} ha alterado las dimensiones!", + "trickRoomOnRemove": "Se han restaurado las dimensiones alteradas.", + "gravityOnAdd": "¡La gravedad se ha incrementado!", + "gravityOnRemove": "La gravedad ha vuelto a su estado normal.", + "tailwindOnAdd": "¡Sopla un viento afín!", + "tailwindOnAddPlayer": "¡El viento sopla a favor de tu bando!", + "tailwindOnAddEnemy": "¡El viento sopla a favor del bando rival!", + "tailwindOnRemove": "Ha dejado de soplar el viento afín.", + "tailwindOnRemovePlayer": "Ha dejado de soplar el viento que favorecía a tu equipo.", + "tailwindOnRemoveEnemy": "Ha dejado de soplar el viento que favorecía al bando rival.", + "happyHourOnAdd": "¡La felicidad se respira en el aire!", + "happyHourOnRemove": "La felicidad ya no se respira en el aire.", "safeguardOnAdd": "¡Todos los Pokémon están protegidos por Velo Sagrado!", "safeguardOnAddPlayer": "¡Tu equipo se ha protegido con Velo Sagrado!", "safeguardOnAddEnemy": "¡El equipo enemigo se ha protegido con Velo Sagrado!", diff --git a/src/locales/es/battler-tags.json b/src/locales/es/battler-tags.json index 9e26dfeeb6e..d917b6c74b5 100644 --- a/src/locales/es/battler-tags.json +++ b/src/locales/es/battler-tags.json @@ -1 +1,71 @@ -{} \ No newline at end of file +{ + "trappedDesc": "trampa", + "flinchedDesc": "retroceso", + "confusedDesc": "confusión", + "infatuatedDesc": "enamoramiento", + "seedDesc": "drenado", + "nightmareDesc": "pesadillas", + "ingrainDesc": "raíces", + "drowsyDesc": "sueño", + "rechargingLapse": "¡{{pokemonNameWithAffix}} necesita\nrecuperarse de su ataque!", + "trappedOnAdd": "¡{{pokemonNameWithAffix}} no puede escapar!", + "trappedOnRemove": "¡{{pokemonNameWithAffix}} se ha\nliberado de {{moveName}}!", + "flinchedLapse": "¡{{pokemonNameWithAffix}} se amedrentó!", + "confusedOnAdd": "¡{{pokemonNameWithAffix}} se encuentra confuso!", + "confusedOnRemove": "¡{{pokemonNameWithAffix}} ya no está confuso!", + "confusedOnOverlap": "¡{{pokemonNameWithAffix}} ya está confuso!", + "confusedLapse": "¡{{pokemonNameWithAffix}} está confuso!", + "confusedLapseHurtItself": "¡Está tan confuso que se ha herido a sí mismo!", + "destinyBondLapseIsBoss": "Mismo Destino no afecta a {{pokemonNameWithAffix}}.", + "destinyBondLapse": "¡{{pokemonNameWithAffix2}} ha sufrido\nel mismo destino que {{pokemonNameWithAffix}}!", + "infatuatedOnAdd": "¡{{pokemonNameWithAffix}} se ha enamorado\nde {{sourcePokemonName}}!", + "infatuatedOnOverlap": "¡{{pokemonNameWithAffix}} ya está enamorado!", + "infatuatedLapse": "¡{{pokemonNameWithAffix}} se ha enamorado\ndebido a {{sourcePokemonName}}!", + "infatuatedLapseImmobilize": "¡El enamoramiento impide que\n{{pokemonNameWithAffix}} reaccione!", + "infatuatedOnRemove": "{{pokemonNameWithAffix}} ya no está enamorado.", + "seededOnAdd": "¡{{pokemonNameWithAffix}} ha sido infectado!", + "seededLapse": "¡Las drenadoras han restado salud a {{pokemonNameWithAffix}}!", + "seededLapseShed": "¡{{pokemonNameWithAffix}} ha absorbido el lodo líquido!", + "nightmareOnAdd": "¡{{pokemonNameWithAffix}} se ha sumido en una pesadilla!", + "nightmareOnOverlap": "¡{{pokemonNameWithAffix}} ya está teniendo pesadillas!", + "nightmareLapse": "¡{{pokemonNameWithAffix}} sufre pesadillas!", + "encoreOnAdd": "¡{{pokemonNameWithAffix}} sufre los efectos de Otra Vez!", + "encoreOnRemove": "¡{{pokemonNameWithAffix}} ya no sufre los efectos de Otra Vez!", + "helpingHandOnAdd": "¡{{pokemonNameWithAffix}} se prepara\npara ayudar a {{pokemonName}}!", + "ingrainLapse": "¡{{pokemonNameWithAffix}} ha absorbido\nnutrientes a través de sus raíces!", + "ingrainOnTrap": "¡{{pokemonNameWithAffix}} ha echado raíces!", + "aquaRingOnAdd": "¡{{pokemonNameWithAffix}} se ha rodeado de un manto de agua!", + "aquaRingLapse": "¡{{pokemonName}} restauró sus PS con {{moveName}}!", + "drowsyOnAdd": "¡{{pokemonNameWithAffix}} empieza a tener sueño!", + "damagingTrapLapse": "¡{{moveName}} hiere a {{pokemonNameWithAffix}}!", + "bindOnTrap": "¡{{moveName}} de {{sourcePokemonName}} oprime a {{pokemonNameWithAffix}}!", + "wrapOnTrap": "¡{{sourcePokemonName}} ha atrapado a {{pokemonNameWithAffix}} con una constricción!", + "vortexOnTrap": "¡{{pokemonNameWithAffix}} no puede salir del torbellino!", + "clampOnTrap": "¡{{sourcePokemonNameWithAffix}} ha atenazado a \n{{pokemonName}}!", + "sandTombOnTrap": "¡{{pokemonNameWithAffix}} ha sido atrapado por {{moveName}}!", + "magmaStormOnTrap": "¡La lluvia ígnea cae sobre {{pokemonNameWithAffix}}!", + "snapTrapOnTrap": "¡{{pokemonNameWithAffix}} cayó en un cepo!", + "thunderCageOnTrap": "¡{{sourcePokemonNameWithAffix}} ha enjaulado a {{pokemonNameWithAffix}}!", + "infestationOnTrap": "¡{{pokemonNameWithAffix}} es presa del acoso de {{sourcePokemonNameWithAffix}}!", + "protectedOnAdd": "{{pokemonNameWithAffix}}\nse está protegiendo.", + "protectedLapse": "¡{{pokemonNameWithAffix}}\nse ha protegido!", + "enduringOnAdd": "{{pokemonNameWithAffix}} se prepara para resistir los ataques...", + "enduringLapse": "¡{{pokemonNameWithAffix}} ha encajado el golpe!", + "sturdyLapse": "¡{{pokemonNameWithAffix}} ha encajado el golpe!", + "perishSongLapse": "La cuenta atrás de Canto Mortal de\n{{pokemonNameWithAffix}} ha bajado a {{turnCount}}.", + "centerOfAttentionOnAdd": "¡{{pokemonNameWithAffix}} es el centro de atención!", + "truantLapse": "{{pokemonNameWithAffix}} está holgazaneando...", + "slowStartOnAdd": "¡{{pokemonNameWithAffix}} no está dando todo de sí!", + "slowStartOnRemove": "¡{{pokemonNameWithAffix}} ya puede darlo todo!", + "highestStatBoostOnAdd": "¡{{pokemonNameWithAffix}} ha reforzado su {{statName}}!", + "highestStatBoostOnRemove": "¡Los efectos de {{abilityName}}\nde {{pokemonNameWithAffix}} han desaparecido!", + "magnetRisenOnAdd": "¡{{pokemonNameWithAffix}} levita gracias a un campo electromagnético!", + "magnetRisenOnRemove": "¡El campo electromagnético de {{pokemonNameWithAffix}} se ha disipado!", + "critBoostOnAdd": "¡{{pokemonNameWithAffix}} se está preparando para luchar!", + "critBoostOnRemove": "{{pokemonNameWithAffix}} se ha relajado.", + "saltCuredOnAdd": "¡{{pokemonNameWithAffix}} está en salazón!", + "saltCuredLapse": "¡{{moveName}} ha herido a {{pokemonNameWithAffix}}!", + "cursedOnAdd": "¡{{pokemonNameWithAffix}} sacrifica algunos PS y maldice a {{pokemonName}}!", + "cursedLapse": "¡{{pokemonNameWithAffix}} es víctima de una maldición!", + "stockpilingOnAdd": "¡{{pokemonNameWithAffix}} ha reservado energía por {{stockpiledCount}}ª vez!" +} diff --git a/src/locales/es/game-mode.json b/src/locales/es/game-mode.json index e7925900253..0dbccb45e1f 100644 --- a/src/locales/es/game-mode.json +++ b/src/locales/es/game-mode.json @@ -1,8 +1,8 @@ { - "classic": "Clásica", - "endless": "Infinita", - "endlessSpliced": "Infinita (Fusión)", - "dailyRun": "Diaria", - "unknown": "Desconicido", + "classic": "Clásico", + "endless": "Infinito", + "endlessSpliced": "Infinito (Fusión)", + "dailyRun": "Diario", + "unknown": "Desconocido", "challenge": "Desafío" -} \ No newline at end of file +} diff --git a/src/locales/es/party-ui-handler.json b/src/locales/es/party-ui-handler.json index 65552a1e1d5..0e59aee6fd1 100644 --- a/src/locales/es/party-ui-handler.json +++ b/src/locales/es/party-ui-handler.json @@ -1,4 +1,9 @@ { + "SEND_OUT": "Enviar", + "SUMMARY": "Resumen", + "CANCEL": "Cancelar", + "RELEASE": "Liberar", + "APPLY": "Aplicar", "TEACH": "Enseñar", "SPLICE": "Fusionar", "UNSPLICE": "Separar", @@ -7,23 +12,23 @@ "TRANSFER": "Transferir", "ALL": "Todo", "PASS_BATON": "Relevo", - "UNPAUSE_EVOLUTION": "Reanudar Evolución", + "UNPAUSE_EVOLUTION": "Reanudar evolución", "REVIVE": "Revivir", "RENAME": "Rename", "choosePokemon": "Elige a un Pokémon.", "doWhatWithThisPokemon": "¿Que quieres hacer con este Pokémon?", - "noEnergy": "¡A {{pokemonName}} no le quedan\nfuerzas para luchar!", - "hasEnergy": "¡A {{pokemonName}} le quedan\nfuerzas para luchar!", - "cantBeUsed": "¡{{pokemonName}} no puede usarse\nen este desafío!", - "tooManyItems": "¡{{pokemonName}} tiene demasiados\nde este objeto!", + "noEnergy": "¡A {{pokemonName}} no le\nquedan fuerzas para luchar!", + "hasEnergy": "¡A {{pokemonName}} le\nquedan fuerzas para luchar!", + "cantBeUsed": "¡{{pokemonName}} no puede usarse en este desafío!", + "tooManyItems": "¡{{pokemonName}} tiene\ndemasiado de este objeto!", "anyEffect": "No tendría ningún efecto.", - "unpausedEvolutions": "Se reanudó las evoluciones de {{pokemonName}}.", + "unpausedEvolutions": "Se reanudaron las evoluciones de {{pokemonName}}.", "unspliceConfirmation": "¿Seguro que quiere separar a {{fusionName}}\nde {{pokemonName}}? {{fusionName}} se perderá.", "wasReverted": "{{fusionName}} se revirtió a {{pokemonName}}.", "releaseConfirmation": "¿Quieres liberar a {{pokemonName}}?", "releaseInBattle": "¡No puedes liberar un Pokémon que está en batalla!", "selectAMove": "Selecciona un movimiento.", - "changeQuantity": "Selecciona un objeto equipado para transferir.\nUsa < y > para cambiar la cantidad.", + "changeQuantity": "Selecciona un ítem para transferir.\nUsa < y > para calibrar.", "selectAnotherPokemonToSplice": "Selecciona otro Pokémon para fusionar.", "cancel": "Salir", "able": "Apto", @@ -36,7 +41,7 @@ "thisIsWhereWePart": "¡Aquí es donde nos despedimos, {{pokemonName}}!", "illMissYou": "¡Te echaré de menos, {{pokemonName}}!", "illNeverForgetYou": "¡Nunca te olvidaré, {{pokemonName}}!", - "untilWeMeetAgain": "¡Hasta que nos volvamos a encontrar, {{pokemonName}}!", + "untilWeMeetAgain": "¡Hasta que nos volvamos a\nencontrar, {{pokemonName}}!", "sayonara": "¡Sayonara, {{pokemonName}}!", "smellYaLater": "¡Nos vemos luego, {{pokemonName}}!" -} \ No newline at end of file +} diff --git a/src/locales/es/settings.json b/src/locales/es/settings.json index 9c16fbb0fd6..dc441d48eb8 100644 --- a/src/locales/es/settings.json +++ b/src/locales/es/settings.json @@ -100,7 +100,7 @@ "moveTouchControls": "Controles táctiles", "shopOverlayOpacity": "Opacidad de la fase de compra", "shopCursorTarget": "Cursor de la tienda", - "items": "Objetos", + "rewards": "Objetos", "reroll": "Actualizar", "shop": "Tienda", "checkTeam": "Ver equipo" diff --git a/src/locales/fr/battle.json b/src/locales/fr/battle.json index 1c108c89ded..b8da3a953ae 100644 --- a/src/locales/fr/battle.json +++ b/src/locales/fr/battle.json @@ -94,5 +94,6 @@ "retryBattle": "Voulez-vous réessayer depuis le début du combat ?", "unlockedSomething": "{{unlockedThing}}\na été débloqué.", "congratulations": "Félicitations !", - "beatModeFirstTime": "{{speciesName}} a battu le mode {{gameMode}} pour la première fois !\nVous avez reçu {{newModifier}} !" -} \ No newline at end of file + "beatModeFirstTime": "{{speciesName}} a battu le mode {{gameMode}} pour la première fois !\nVous avez reçu {{newModifier}} !", + "eggSkipPrompt": "Aller directement au résumé des Œufs éclos ?" +} diff --git a/src/locales/fr/menu-ui-handler.json b/src/locales/fr/menu-ui-handler.json index 807b34f1315..b8627bf91b5 100644 --- a/src/locales/fr/menu-ui-handler.json +++ b/src/locales/fr/menu-ui-handler.json @@ -25,5 +25,6 @@ "unlinkGoogle": "Délier Google", "cancel": "Retour", "losingProgressionWarning": "Vous allez perdre votre progression depuis le début du combat. Continuer ?", - "noEggs": "Vous ne faites actuellement\néclore aucun Œuf !" -} \ No newline at end of file + "noEggs": "Vous ne faites actuellement\néclore aucun Œuf !", + "donate": "Faire un don" +} diff --git a/src/locales/fr/settings.json b/src/locales/fr/settings.json index 181a593cc99..c752b336b6e 100644 --- a/src/locales/fr/settings.json +++ b/src/locales/fr/settings.json @@ -100,7 +100,7 @@ "moveTouchControls": "Déplacer les contrôles tactiles", "shopOverlayOpacity": "Opacité boutique", "shopCursorTarget": "Choix après relance", - "items": "Obj. gratuits", + "rewards": "Obj. gratuits", "reroll": "Relance", "shop": "Boutique", "checkTeam": "Équipe" diff --git a/src/locales/it/settings.json b/src/locales/it/settings.json index 381503f21bd..c09f5e22d4d 100644 --- a/src/locales/it/settings.json +++ b/src/locales/it/settings.json @@ -8,7 +8,7 @@ "moveTouchControls": "Move Touch Controls", "shopOverlayOpacity": "Opacità Finestra Negozio", "shopCursorTarget": "Target Cursore Negozio", - "items": "Oggetti", + "rewards": "Oggetti", "reroll": "Rerolla", "shop": "Negozio", "checkTeam": "Squadra" diff --git a/src/locales/ja/settings.json b/src/locales/ja/settings.json index 4cb10c670de..55d39ee70a4 100644 --- a/src/locales/ja/settings.json +++ b/src/locales/ja/settings.json @@ -100,7 +100,7 @@ "moveTouchControls": "タッチ移動操作", "shopOverlayOpacity": "ショップオーバレイ不透明度", "shopCursorTarget": "ショップカーソル初位置", - "items": "アイテム", + "rewards": "ご褒美", "reroll": "選択肢変更", "shop": "ショップ", "checkTeam": "手持ちを確認" diff --git a/src/locales/ko/settings.json b/src/locales/ko/settings.json index b7fc01cb148..c10046385e1 100644 --- a/src/locales/ko/settings.json +++ b/src/locales/ko/settings.json @@ -100,7 +100,7 @@ "moveTouchControls": "터치 컨트롤 이동", "shopOverlayOpacity": "상점 오버레이 투명도", "shopCursorTarget": "상점 커서 위치", - "items": "아이템", + "rewards": "아이템", "reroll": "갱신", "shop": "상점", "checkTeam": "파티 확인" diff --git a/src/locales/pt_BR/settings.json b/src/locales/pt_BR/settings.json index 58ccb45f86d..74f3918bed8 100644 --- a/src/locales/pt_BR/settings.json +++ b/src/locales/pt_BR/settings.json @@ -100,7 +100,7 @@ "moveTouchControls": "Mover Controles de Toque", "shopOverlayOpacity": "Opacidade da Loja", "shopCursorTarget": "Alvo do Cursor da Loja", - "items": "Itens", + "rewards": "Itens", "reroll": "Atualizar", "shop": "Loja", "checkTeam": "Checar Time" diff --git a/src/locales/zh_CN/settings.json b/src/locales/zh_CN/settings.json index 3ae0fa8204c..dd001213b9e 100644 --- a/src/locales/zh_CN/settings.json +++ b/src/locales/zh_CN/settings.json @@ -99,7 +99,7 @@ "moveTouchControls": "移动触摸控制", "shopOverlayOpacity": "商店显示不透明度", "shopCursorTarget": "商店指针位置", - "items": "道具", + "rewards": "道具", "reroll": "刷新", "shop": "购买", "checkTeam": "检查队伍" diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 6e0658d4ccb..3f37095569a 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -161,9 +161,11 @@ export class EncounterPhase extends BattlePhase { return this.scene.reset(true); } this.doEncounter(); + this.scene.resetSeed(); }); } else { this.doEncounter(); + this.scene.resetSeed(); } }); }); diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 29bb6057722..50cc6177a84 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -946,7 +946,7 @@ export class GameData { return ret; } - private getSessionSaveData(scene: BattleScene): SessionSaveData { + public getSessionSaveData(scene: BattleScene): SessionSaveData { return { seed: scene.seed, playTime: scene.sessionPlayTime, diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 7b0fea95a98..6b46b6fe96c 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -25,6 +25,7 @@ const VOLUME_OPTIONS: SettingOption[] = new Array(11).fill(null).map((_, i) => i value: "Mute", label: getTranslation("settings:mute") }); + const SHOP_OVERLAY_OPACITY_OPTIONS: SettingOption[] = new Array(9).fill(null).map((_, i) => { const value = ((i + 1) * 10).toString(); return { @@ -32,6 +33,7 @@ const SHOP_OVERLAY_OPACITY_OPTIONS: SettingOption[] = new Array(9).fill(null).ma label: value, }; }); + const OFF_ON: SettingOption[] = [ { value: "Off", @@ -53,6 +55,40 @@ const AUTO_DISABLED: SettingOption[] = [ } ]; +const SHOP_CURSOR_TARGET_OPTIONS: SettingOption[] = [ + { + value: "Rewards", + label: i18next.t("settings:rewards") + }, + { + value: "Shop", + label: i18next.t("settings:shop") + }, + { + value: "Reroll", + label: i18next.t("settings:reroll") + }, + { + value: "Check Team", + label: i18next.t("settings:checkTeam") + } +]; + +const shopCursorTargetIndexMap = SHOP_CURSOR_TARGET_OPTIONS.map(option => { + switch (option.value) { + case "Rewards": + return ShopCursorTarget.REWARDS; + case "Shop": + return ShopCursorTarget.SHOP; + case "Reroll": + return ShopCursorTarget.REROLL; + case "Check Team": + return ShopCursorTarget.CHECK_TEAM; + default: + throw new Error(`Unknown value: ${option.value}`); + } +}); + /** * Types for helping separate settings to different menus */ @@ -103,7 +139,7 @@ export const SettingKeys = { Damage_Numbers: "DAMAGE_NUMBERS", Move_Animations: "MOVE_ANIMATIONS", Show_Stats_on_Level_Up: "SHOW_LEVEL_UP_STATS", - Reroll_Target: "REROLL_TARGET", + Shop_Cursor_Target: "SHOP_CURSOR_TARGET", Candy_Upgrade_Notification: "CANDY_UPGRADE_NOTIFICATION", Candy_Upgrade_Display: "CANDY_UPGRADE_DISPLAY", Move_Info: "MOVE_INFO", @@ -596,27 +632,10 @@ export const Setting: Array = [ isHidden: () => !hasTouchscreen() }, { - key: SettingKeys.Reroll_Target, + key: SettingKeys.Shop_Cursor_Target, label: i18next.t("settings:shopCursorTarget"), - options: [ - { - value:"Reroll", - label: i18next.t("settings:reroll") - }, - { - value:"Items", - label: i18next.t("settings:items") - }, - { - value:"Shop", - label: i18next.t("settings:shop") - }, - { - value:"Check Team", - label: i18next.t("settings:checkTeam") - } - ], - default: ShopCursorTarget.CHECK_TEAM, + options: SHOP_CURSOR_TARGET_OPTIONS, + default: 0, type: SettingType.DISPLAY }, { @@ -758,8 +777,10 @@ export function setSetting(scene: BattleScene, setting: string, value: integer): case SettingKeys.Show_Stats_on_Level_Up: scene.showLevelUpStats = Setting[index].options[value].value === "On"; break; - case SettingKeys.Reroll_Target: - scene.shopCursorTarget = value; + case SettingKeys.Shop_Cursor_Target: + const selectedValue = shopCursorTargetIndexMap[value]; + scene.shopCursorTarget = selectedValue; + break; case SettingKeys.EXP_Gains_Speed: scene.expGainsSpeed = value; break; diff --git a/src/test/items/dire_hit.test.ts b/src/test/items/dire_hit.test.ts index c43091d1f03..02f7c0d06a4 100644 --- a/src/test/items/dire_hit.test.ts +++ b/src/test/items/dire_hit.test.ts @@ -13,6 +13,7 @@ import { Button } from "#app/enums/buttons"; import { CommandPhase } from "#app/phases/command-phase"; import { NewBattlePhase } from "#app/phases/new-battle-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase"; +import { ShopCursorTarget } from "#app/enums/shop-cursor-target"; describe("Items - Dire Hit", () => { let phaserGame: Phaser.Game; @@ -77,8 +78,8 @@ describe("Items - Dire Hit", () => { game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => { const handler = game.scene.ui.getHandler() as ModifierSelectUiHandler; // Traverse to first modifier slot - handler.processInput(Button.LEFT); - handler.processInput(Button.UP); + handler.setCursor(0); + handler.setRowCursor(ShopCursorTarget.REWARDS); handler.processInput(Button.ACTION); }, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(NewBattlePhase), true); diff --git a/src/test/items/temp_stat_stage_booster.test.ts b/src/test/items/temp_stat_stage_booster.test.ts index e5b95c6c3b6..c81703220db 100644 --- a/src/test/items/temp_stat_stage_booster.test.ts +++ b/src/test/items/temp_stat_stage_booster.test.ts @@ -16,6 +16,7 @@ import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; import { TurnInitPhase } from "#app/phases/turn-init-phase"; import { BattleEndPhase } from "#app/phases/battle-end-phase"; import { EnemyCommandPhase } from "#app/phases/enemy-command-phase"; +import { ShopCursorTarget } from "#app/enums/shop-cursor-target"; describe("Items - Temporary Stat Stage Boosters", () => { @@ -154,8 +155,8 @@ describe("Items - Temporary Stat Stage Boosters", () => { game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => { const handler = game.scene.ui.getHandler() as ModifierSelectUiHandler; // Traverse to first modifier slot - handler.processInput(Button.LEFT); - handler.processInput(Button.UP); + handler.setCursor(0); + handler.setRowCursor(ShopCursorTarget.REWARDS); handler.processInput(Button.ACTION); }, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(NewBattlePhase), true); diff --git a/src/test/reload.test.ts b/src/test/reload.test.ts new file mode 100644 index 00000000000..0a712fcc7df --- /dev/null +++ b/src/test/reload.test.ts @@ -0,0 +1,137 @@ +import { Species } from "#app/enums/species"; +import { GameModes } from "#app/game-mode"; +import GameManager from "#test/utils/gameManager"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "./utils/testUtils"; +import { Moves } from "#app/enums/moves"; +import { Biome } from "#app/enums/biome"; + +describe("Reload", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + }); + + it("should not have RNG inconsistencies in a Classic run", async () => { + await game.classicMode.startBattle(); + + const preReloadRngState = Phaser.Math.RND.state(); + + await game.reload.reloadSession(); + + const postReloadRngState = Phaser.Math.RND.state(); + + expect(preReloadRngState).toBe(postReloadRngState); + }, 20000); + + it("should not have RNG inconsistencies after a biome switch", async () => { + game.override + .startingWave(10) + .startingBiome(Biome.CAVE) // Will lead to biomes with randomly generated weather + .battleType("single") + .startingLevel(100) + .enemyLevel(1000) + .disableTrainerWaves() + .moveset([Moves.KOWTOW_CLEAVE]) + .enemyMoveset(SPLASH_ONLY); + await game.dailyMode.startBattle(); + + // Transition from Daily Run Wave 10 to Wave 11 in order to trigger biome switch + game.move.select(Moves.KOWTOW_CLEAVE); + await game.phaseInterceptor.to("DamagePhase"); + await game.doKillOpponents(); + await game.toNextWave(); + expect(game.phaseInterceptor.log).toContain("NewBiomeEncounterPhase"); + + const preReloadRngState = Phaser.Math.RND.state(); + + await game.reload.reloadSession(); + + const postReloadRngState = Phaser.Math.RND.state(); + + expect(preReloadRngState).toBe(postReloadRngState); + }, 20000); + + it("should not have RNG inconsistencies at a Daily run wild Pokemon fight", async () => { + await game.dailyMode.startBattle(); + + const preReloadRngState = Phaser.Math.RND.state(); + + await game.reload.reloadSession(); + + const postReloadRngState = Phaser.Math.RND.state(); + + expect(preReloadRngState).toBe(postReloadRngState); + }, 20000); + + it("should not have RNG inconsistencies at a Daily run double battle", async () => { + game.override + .battleType("double"); + await game.dailyMode.startBattle(); + + const preReloadRngState = Phaser.Math.RND.state(); + + await game.reload.reloadSession(); + + const postReloadRngState = Phaser.Math.RND.state(); + + expect(preReloadRngState).toBe(postReloadRngState); + }, 20000); + + it("should not have RNG inconsistencies at a Daily run Gym Leader fight", async () => { + game.override + .battleType("single") + .startingWave(40); + await game.dailyMode.startBattle(); + + const preReloadRngState = Phaser.Math.RND.state(); + + await game.reload.reloadSession(); + + const postReloadRngState = Phaser.Math.RND.state(); + + expect(preReloadRngState).toBe(postReloadRngState); + }, 20000); + + it("should not have RNG inconsistencies at a Daily run regular trainer fight", async () => { + game.override + .battleType("single") + .startingWave(45); + await game.dailyMode.startBattle(); + + const preReloadRngState = Phaser.Math.RND.state(); + + await game.reload.reloadSession(); + + const postReloadRngState = Phaser.Math.RND.state(); + + expect(preReloadRngState).toBe(postReloadRngState); + }, 20000); + + it("should not have RNG inconsistencies at a Daily run wave 50 Boss fight", async () => { + game.override + .battleType("single") + .startingWave(50); + await game.runToFinalBossEncounter([Species.BULBASAUR], GameModes.DAILY); + + const preReloadRngState = Phaser.Math.RND.state(); + + await game.reload.reloadSession(); + + const postReloadRngState = Phaser.Math.RND.state(); + + expect(preReloadRngState).toBe(postReloadRngState); + }, 20000); +}); diff --git a/src/test/utils/gameManager.ts b/src/test/utils/gameManager.ts index 6724e05521c..998d10ddf12 100644 --- a/src/test/utils/gameManager.ts +++ b/src/test/utils/gameManager.ts @@ -45,6 +45,8 @@ import { ChallengeModeHelper } from "./helpers/challengeModeHelper"; import { MoveHelper } from "./helpers/moveHelper"; import { OverridesHelper } from "./helpers/overridesHelper"; import { SettingsHelper } from "./helpers/settingsHelper"; +import { ReloadHelper } from "./helpers/reloadHelper"; +import { CheckSwitchPhase } from "#app/phases/check-switch-phase"; /** * Class to manage the game state and transitions between phases. @@ -61,6 +63,7 @@ export default class GameManager { public readonly dailyMode: DailyModeHelper; public readonly challengeMode: ChallengeModeHelper; public readonly settings: SettingsHelper; + public readonly reload: ReloadHelper; /** * Creates an instance of GameManager. @@ -82,6 +85,7 @@ export default class GameManager { this.dailyMode = new DailyModeHelper(this); this.challengeMode = new ChallengeModeHelper(this); this.settings = new SettingsHelper(this); + this.reload = new ReloadHelper(this); } /** @@ -231,12 +235,12 @@ export default class GameManager { this.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => { const handler = this.scene.ui.getHandler() as ModifierSelectUiHandler; handler.processInput(Button.CANCEL); - }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase), true); + }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase) || this.isCurrentPhase(CheckSwitchPhase), true); this.onNextPrompt("SelectModifierPhase", Mode.CONFIRM, () => { const handler = this.scene.ui.getHandler() as ModifierSelectUiHandler; handler.processInput(Button.ACTION); - }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase)); + }, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(NewBattlePhase) || this.isCurrentPhase(CheckSwitchPhase)); } forceOpponentToSwitch() { diff --git a/src/test/utils/helpers/reloadHelper.ts b/src/test/utils/helpers/reloadHelper.ts new file mode 100644 index 00000000000..c15347b08c9 --- /dev/null +++ b/src/test/utils/helpers/reloadHelper.ts @@ -0,0 +1,53 @@ +import { GameManagerHelper } from "./gameManagerHelper"; +import { TitlePhase } from "#app/phases/title-phase"; +import { Mode } from "#app/ui/ui"; +import { vi } from "vitest"; +import { BattleStyle } from "#app/enums/battle-style"; +import { CommandPhase } from "#app/phases/command-phase"; +import { TurnInitPhase } from "#app/phases/turn-init-phase"; + +/** + * Helper to allow reloading sessions in unit tests. + */ +export class ReloadHelper extends GameManagerHelper { + /** + * Simulate reloading the session from the title screen, until reaching the + * beginning of the first turn (equivalent to running `startBattle()`) for + * the reloaded session. + */ + async reloadSession() : Promise { + const scene = this.game.scene; + const sessionData = scene.gameData.getSessionSaveData(scene); + const titlePhase = new TitlePhase(scene); + + scene.clearPhaseQueue(); + + // Set the last saved session to the desired session data + vi.spyOn(scene.gameData, "getSession").mockReturnValue( + new Promise((resolve, reject) => { + resolve(sessionData); + }) + ); + scene.unshiftPhase(titlePhase); + this.game.endPhase(); // End the currently ongoing battle + + titlePhase.loadSaveSlot(-1); // Load the desired session data + this.game.phaseInterceptor.shift(); // Loading the save slot also ended TitlePhase, clean it up + + // Run through prompts for switching Pokemon, copied from classicModeHelper.ts + if (this.game.scene.battleStyle === BattleStyle.SWITCH) { + this.game.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { + this.game.setMode(Mode.MESSAGE); + this.game.endPhase(); + }, () => this.game.isCurrentPhase(CommandPhase) || this.game.isCurrentPhase(TurnInitPhase)); + + this.game.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { + this.game.setMode(Mode.MESSAGE); + this.game.endPhase(); + }, () => this.game.isCurrentPhase(CommandPhase) || this.game.isCurrentPhase(TurnInitPhase)); + } + + await this.game.phaseInterceptor.to(CommandPhase); + console.log("==================[New Turn]=================="); + } +} diff --git a/src/test/utils/phaseInterceptor.ts b/src/test/utils/phaseInterceptor.ts index 389ae36635a..1141d0bf0d9 100644 --- a/src/test/utils/phaseInterceptor.ts +++ b/src/test/utils/phaseInterceptor.ts @@ -11,12 +11,14 @@ import { EndEvolutionPhase } from "#app/phases/end-evolution-phase"; import { EnemyCommandPhase } from "#app/phases/enemy-command-phase"; import { EvolutionPhase } from "#app/phases/evolution-phase"; import { FaintPhase } from "#app/phases/faint-phase"; +import { LevelCapPhase } from "#app/phases/level-cap-phase"; import { LoginPhase } from "#app/phases/login-phase"; import { MessagePhase } from "#app/phases/message-phase"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { MoveEndPhase } from "#app/phases/move-end-phase"; import { MovePhase } from "#app/phases/move-phase"; import { NewBattlePhase } from "#app/phases/new-battle-phase"; +import { NewBiomeEncounterPhase } from "#app/phases/new-biome-encounter-phase"; import { NextEncounterPhase } from "#app/phases/next-encounter-phase"; import { PostSummonPhase } from "#app/phases/post-summon-phase"; import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; @@ -62,6 +64,7 @@ export default class PhaseInterceptor { [TitlePhase, this.startPhase], [SelectGenderPhase, this.startPhase], [EncounterPhase, this.startPhase], + [NewBiomeEncounterPhase, this.startPhase], [SelectStarterPhase, this.startPhase], [PostSummonPhase, this.startPhase], [SummonPhase, this.startPhase], @@ -96,6 +99,7 @@ export default class PhaseInterceptor { [PartyHealPhase, this.startPhase], [EvolutionPhase, this.startPhase], [EndEvolutionPhase, this.startPhase], + [LevelCapPhase, this.startPhase], ]; private endBySetMode = [ @@ -237,6 +241,22 @@ export default class PhaseInterceptor { this.scene.shiftPhase(); } + /** + * Remove the current phase from the phase interceptor. + * + * Do not call this unless absolutely necessary. This function is intended + * for cleaning up the phase interceptor when, for whatever reason, a phase + * is manually ended without using the phase interceptor. + * + * @param shouldRun Whether or not the current scene should also be run. + */ + shift(shouldRun: boolean = false) : void { + this.onHold.shift(); + if (shouldRun) { + this.scene.shiftPhase(); + } + } + /** * Method to initialize phases and their corresponding methods. */ diff --git a/src/ui/command-ui-handler.ts b/src/ui/command-ui-handler.ts index b22ea5d20fc..27ff923e9a3 100644 --- a/src/ui/command-ui-handler.ts +++ b/src/ui/command-ui-handler.ts @@ -68,7 +68,11 @@ export default class CommandUiHandler extends UiHandler { messageHandler.movesWindowContainer.setVisible(false); messageHandler.message.setWordWrapWidth(1110); messageHandler.showText(i18next.t("commandUiHandler:actionMessage", {pokemonName: getPokemonNameWithAffix(commandPhase.getPokemon())}), 0); - this.setCursor(this.getCursor()); + if (this.getCursor() === Command.POKEMON) { + this.setCursor(Command.FIGHT); + } else { + this.setCursor(this.getCursor()); + } return true; } @@ -85,7 +89,7 @@ export default class CommandUiHandler extends UiHandler { if (button === Button.ACTION) { switch (cursor) { // Fight - case 0: + case Command.FIGHT: if ((this.scene.getCurrentPhase() as CommandPhase).checkFightOverride()) { return true; } @@ -93,17 +97,17 @@ export default class CommandUiHandler extends UiHandler { success = true; break; // Ball - case 1: + case Command.BALL: ui.setModeWithoutClear(Mode.BALL); success = true; break; // Pokemon - case 2: + case Command.POKEMON: ui.setMode(Mode.PARTY, PartyUiMode.SWITCH, (this.scene.getCurrentPhase() as CommandPhase).getPokemon().getFieldIndex(), null, PartyUiHandler.FilterNonFainted); success = true; break; // Run - case 3: + case Command.RUN: (this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.RUN, 0); success = true; break; diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index 0beaddbb517..4bbe88dabd9 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -95,9 +95,13 @@ export default class FightUiHandler extends UiHandler { messageHandler.bg.setVisible(false); messageHandler.commandWindow.setVisible(false); messageHandler.movesWindowContainer.setVisible(true); - this.setCursor(this.getCursor()); + const pokemon = (this.scene.getCurrentPhase() as CommandPhase).getPokemon(); + if (pokemon.battleSummonData.turnCount <= 1) { + this.setCursor(0); + } else { + this.setCursor(this.getCursor()); + } this.displayMoves(); - return true; } diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index 6e9a33df5d8..ca5d27f96a4 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -257,6 +257,9 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { if (this.scene.shopCursorTarget === ShopCursorTarget.CHECK_TEAM) { this.setRowCursor(0); this.setCursor(2); + } else if ((this.scene.shopCursorTarget === ShopCursorTarget.SHOP) && this.scene.gameMode.hasNoShop) { + this.setRowCursor(ShopCursorTarget.REWARDS); + this.setCursor(0); } else { this.setRowCursor(this.scene.shopCursorTarget); this.setCursor(0); diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 176a7098347..98a19402a2b 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -311,7 +311,7 @@ export default class PartyUiHandler extends MessageUiHandler { this.partyContainer.setVisible(true); this.partyBg.setTexture(`party_bg${this.scene.currentBattle.double ? "_double" : ""}`); this.populatePartySlots(); - this.setCursor(this.cursor < 6 ? this.cursor : 0); + this.setCursor(0); return true; }