From ad4b4a0af759962acc428d2606d9f6ce7e55f36c Mon Sep 17 00:00:00 2001 From: "gitlocalize-app[bot]" <55277160+gitlocalize-app[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 01:06:39 +0900 Subject: [PATCH 01/10] [Localisation] [ES] Reviewed and translated missing settings.json (#3865) * Translate settings.json via GitLocalize * Translate settings.json via GitLocalize --------- Co-authored-by: Rafa Co-authored-by: Asdar --- src/locales/es/settings.json | 102 ++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/src/locales/es/settings.json b/src/locales/es/settings.json index 2351abf04ae..ff37c8464bf 100644 --- a/src/locales/es/settings.json +++ b/src/locales/es/settings.json @@ -2,6 +2,106 @@ "boy": "Chico", "girl": "Chica", "general": "General", + "display": "Pantalla", "audio": "Audio", - "shopOverlayOpacity": "Opacidad de la fase de compra" + "gamepad": "Mando", + "keyboard": "Teclado", + "gameSpeed": "Veloc. del juego", + "hpBarSpeed": "Veloc. Barra PS", + "expGainsSpeed": "Veloc. de EXP", + "expPartyDisplay": "Mostrar EXP del Equipo", + "skipSeenDialogues": "Saltar diálogos leídos", + "battleStyle": "Estilo de lucha", + "enableRetries": "Activar reintento", + "hideIvs": "Ocultar escáner de IVs", + "tutorials": "Tutoriales", + "touchControls": "Control táctil", + "vibrations": "Vibración", + "normal": "Normal", + "fast": "+1", + "faster": "+2", + "skip": "Saltar", + "levelUpNotifications": "Aumentos de nivel", + "on": "Sí", + "off": "No", + "switch": "Cambiar", + "set": "Mantener", + "auto": "Auto.", + "disabled": "Desact.", + "language": "Idioma", + "change": "Cambiar", + "uiTheme": "Color UI", + "default": "Predet.", + "legacy": "Clásico", + "windowType": "Ventana", + "moneyFormat": "Formato Dinero", + "damageNumbers": "Cifras de daño", + "simple": "Simple", + "fancy": "Elegante", + "abbreviated": "Abreviado", + "moveAnimations": "Animación de Movs.", + "showStatsOnLevelUp": "Estadísticas al Aum. Nivel", + "candyUpgradeNotification": "Notificar Mejora Caramelo", + "passivesOnly": "Solo Pasivas", + "candyUpgradeDisplay": "Muestra Mejora Caramelo", + "icon": "Icono", + "animation": "Animación", + "moveInfo": "Info. Movimiento", + "showMovesetFlyout": "Descripción de Movimientos", + "showArenaFlyout": "Descripción de Escenarios", + "showTimeOfDayWidget": "Mostrar Hora del Día", + "timeOfDayAnimation": "Animación Hora del Día", + "bounce": "Rebote", + "timeOfDay_back": "Vuelta", + "spriteSet": "Set de Sprites", + "consistent": "Consistente", + "mixedAnimated": "Animación mixta", + "fusionPaletteSwaps": "Colores de fusión", + "playerGender": "Género del jugador", + "typeHints": "Pistas de tipos", + "masterVolume": "Volumen total", + "bgmVolume": "Volumen música", + "fieldVolume": "Volumen escenario", + "seVolume": "Volumen efectos", + "uiVolume": "Volumen sistema", + "musicPreference": "Preferencia musical", + "mixed": "Mixta", + "gamepadPleasePlug": "Conecta un mando o pulsa un botón", + "delete": "Eliminar", + "keyboardPleasePress": "Pulsa una tecla de tu teclado", + "reset": "Restablecer", + "requireReload": "Requiere reinicio", + "action": "Acción", + "back": "Atrás", + "pressToBind": "Pulsa para vincular", + "pressButton": "Pulsa un botón...", + "buttonUp": "Arriba", + "buttonDown": "Abajo", + "buttonLeft": "Izquierda", + "buttonRight": "Derecha", + "buttonAction": "Acción", + "buttonMenu": "Menú", + "buttonSubmit": "Confirmar", + "buttonCancel": "Cancelar", + "buttonStats": "Estadísticas", + "buttonCycleForm": "Cambiar forma", + "buttonCycleShiny": "Cambiar shiny", + "buttonCycleGender": "Cambiar género", + "buttonCycleAbility": "Cambiar habilidad", + "buttonCycleNature": "Cambiar naturaleza", + "buttonCycleVariant": "Cambiar variante", + "buttonSpeedUp": "Acelerar", + "buttonSlowDown": "Ralentizar", + "alt": " (Alt.)", + "mute": "Silenciar", + "controller": "Mando", + "gamepadSupport": "Soporte de mando", + "showBgmBar": "Mostrar título de canción", + "moveTouchControls": "Controles táctiles", + "shopOverlayOpacity": "Opacidad de la fase de compra", + "shopCursorTarget": "Cursor de la tienda", + "items": "Objetos", + "reroll": "Actualizar", + "shop": "Tienda", + "checkTeam": "Ver equipo" } From 170a5831bf928edf6de4c348889d9c9002c0e39b Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:01:15 -0700 Subject: [PATCH 02/10] [Bug] Updating ModifierItems' audio keys (#3853) Co-authored-by: frutescens --- src/modifier/modifier-type.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index beec048754e..938f73a1e08 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -57,7 +57,7 @@ export class ModifierType { this.localeKey = localeKey!; // TODO: is this bang correct? this.iconImage = iconImage!; // TODO: is this bang correct? this.group = group!; // TODO: is this bang correct? - this.soundName = soundName ?? "restore"; + this.soundName = soundName ?? "se/restore"; this.newModifierFunc = newModifierFunc; } @@ -169,7 +169,7 @@ class AddPokeballModifierType extends ModifierType { private count: integer; constructor(iconImage: string, pokeballType: PokeballType, count: integer) { - super("", iconImage, (_type, _args) => new Modifiers.AddPokeballModifier(this, pokeballType, count), "pb", "pb_bounce_1"); + super("", iconImage, (_type, _args) => new Modifiers.AddPokeballModifier(this, pokeballType, count), "pb", "se/pb_bounce_1"); this.pokeballType = pokeballType; this.count = count; } @@ -677,7 +677,7 @@ export class MoneyRewardModifierType extends ModifierType { private moneyMultiplierDescriptorKey: string; constructor(localeKey: string, iconImage: string, moneyMultiplier: number, moneyMultiplierDescriptorKey: string) { - super(localeKey, iconImage, (_type, _args) => new Modifiers.MoneyRewardModifier(this, moneyMultiplier), "money", "buy"); + super(localeKey, iconImage, (_type, _args) => new Modifiers.MoneyRewardModifier(this, moneyMultiplier), "money", "se/buy"); this.moneyMultiplier = moneyMultiplier; this.moneyMultiplierDescriptorKey = moneyMultiplierDescriptorKey; @@ -1462,7 +1462,7 @@ export const modifierTypes = { VOUCHER_PLUS: () => new AddVoucherModifierType(VoucherType.PLUS, 1), VOUCHER_PREMIUM: () => new AddVoucherModifierType(VoucherType.PREMIUM, 1), - GOLDEN_POKEBALL: () => new ModifierType("modifierType:ModifierType.GOLDEN_POKEBALL", "pb_gold", (type, _args) => new Modifiers.ExtraModifierModifier(type), undefined, "pb_bounce_1"), + GOLDEN_POKEBALL: () => new ModifierType("modifierType:ModifierType.GOLDEN_POKEBALL", "pb_gold", (type, _args) => new Modifiers.ExtraModifierModifier(type), undefined, "se/pb_bounce_1"), ENEMY_DAMAGE_BOOSTER: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_BOOSTER", "wl_item_drop", (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5)), ENEMY_DAMAGE_REDUCTION: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_REDUCTION", "wl_guard_spec", (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5)), From fd81a5d3b38bfb536e91536971c5ac4180991296 Mon Sep 17 00:00:00 2001 From: "gitlocalize-app[bot]" <55277160+gitlocalize-app[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 20:27:12 +0200 Subject: [PATCH 03/10] Translate settings.json via GitLocalize (#3867) Co-authored-by: Asdar --- src/locales/es/settings.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/locales/es/settings.json b/src/locales/es/settings.json index ff37c8464bf..9c16fbb0fd6 100644 --- a/src/locales/es/settings.json +++ b/src/locales/es/settings.json @@ -7,7 +7,7 @@ "gamepad": "Mando", "keyboard": "Teclado", "gameSpeed": "Veloc. del juego", - "hpBarSpeed": "Veloc. Barra PS", + "hpBarSpeed": "Veloc. barra PS", "expGainsSpeed": "Veloc. de EXP", "expPartyDisplay": "Mostrar EXP del Equipo", "skipSeenDialogues": "Saltar diálogos leídos", @@ -34,28 +34,28 @@ "default": "Predet.", "legacy": "Clásico", "windowType": "Ventana", - "moneyFormat": "Formato Dinero", + "moneyFormat": "Formato dinero", "damageNumbers": "Cifras de daño", "simple": "Simple", "fancy": "Elegante", "abbreviated": "Abreviado", - "moveAnimations": "Animación de Movs.", - "showStatsOnLevelUp": "Estadísticas al Aum. Nivel", - "candyUpgradeNotification": "Notificar Mejora Caramelo", - "passivesOnly": "Solo Pasivas", - "candyUpgradeDisplay": "Muestra Mejora Caramelo", + "moveAnimations": "Animación de movs.", + "showStatsOnLevelUp": "Estadísticas al aum. nivel", + "candyUpgradeNotification": "Aviso de caramelos", + "passivesOnly": "Solo pasivas", + "candyUpgradeDisplay": "Muestra de caramelos", "icon": "Icono", "animation": "Animación", - "moveInfo": "Info. Movimiento", - "showMovesetFlyout": "Descripción de Movimientos", - "showArenaFlyout": "Descripción de Escenarios", - "showTimeOfDayWidget": "Mostrar Hora del Día", - "timeOfDayAnimation": "Animación Hora del Día", + "moveInfo": "Info. de movimientos", + "showMovesetFlyout": "Descripción de movimientos", + "showArenaFlyout": "Descripción de escenarios", + "showTimeOfDayWidget": "Mostrar hora del día", + "timeOfDayAnimation": "Animación hora del día", "bounce": "Rebote", "timeOfDay_back": "Vuelta", - "spriteSet": "Set de Sprites", + "spriteSet": "Set de sprites", "consistent": "Consistente", - "mixedAnimated": "Animación mixta", + "mixedAnimated": "Mixto", "fusionPaletteSwaps": "Colores de fusión", "playerGender": "Género del jugador", "typeHints": "Pistas de tipos", From 447d47ef477bde42183f0d72560f413d4800fe5b Mon Sep 17 00:00:00 2001 From: "gitlocalize-app[bot]" <55277160+gitlocalize-app[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 20:29:15 +0200 Subject: [PATCH 04/10] Translate trainer-names.json via GitLocalize (#3860) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José Ricardo --- src/locales/pt_BR/trainer-names.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/locales/pt_BR/trainer-names.json b/src/locales/pt_BR/trainer-names.json index fc4e48de040..5500e2ddb46 100644 --- a/src/locales/pt_BR/trainer-names.json +++ b/src/locales/pt_BR/trainer-names.json @@ -138,11 +138,17 @@ "rood": "Rood", "xerosic": "Xerosic", "bryony": "Bryony", + "faba": "Faba", + "plumeria": "Plumeria", + "oleana": "Oleana", "maxie": "Maxie", "archie": "Archie", "cyrus": "Cyrus", "ghetsis": "Ghetsis", "lysandre": "Lysandre", + "lusamine": "Lusamine", + "guzma": "Guzma", + "rose": "Rose", "blue_red_double": "Blue & Red", "red_blue_double": "Red & Blue", "tate_liza_double": "Tate & Liza", @@ -153,4 +159,4 @@ "iris_alder_double": "Iris & Alder", "marnie_piers_double": "Marnie & Piers", "piers_marnie_double": "Piers & Marnie" -} \ No newline at end of file +} From e0bcb2ef27f02c510837087f1ffcabaa7ac22cdd Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Wed, 28 Aug 2024 12:00:38 -0700 Subject: [PATCH 05/10] [P3 Bug] Run History function saves the most-recent session data possible (#3838) Co-authored-by: frutescens --- src/phases/game-over-phase.ts | 72 ++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/src/phases/game-over-phase.ts b/src/phases/game-over-phase.ts index a42e8472952..78dd73057a1 100644 --- a/src/phases/game-over-phase.ts +++ b/src/phases/game-over-phase.ts @@ -1,19 +1,19 @@ -import { clientSessionId } from "#app/account.js"; -import BattleScene from "#app/battle-scene.js"; -import { BattleType } from "#app/battle.js"; -import { miscDialogue, getCharVariantFromDialogue } from "#app/data/dialogue.js"; -import { pokemonEvolutions } from "#app/data/pokemon-evolutions.js"; -import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species.js"; -import { trainerConfigs } from "#app/data/trainer-config.js"; -import { PlayerGender } from "#app/enums/player-gender.js"; -import { TrainerType } from "#app/enums/trainer-type.js"; -import Pokemon from "#app/field/pokemon.js"; -import { modifierTypes } from "#app/modifier/modifier-type.js"; -import { achvs, ChallengeAchv } from "#app/system/achv.js"; -import { Unlockables } from "#app/system/unlockables.js"; -import { Mode } from "#app/ui/ui.js"; +import { clientSessionId } from "#app/account"; +import BattleScene from "#app/battle-scene"; +import { BattleType } from "#app/battle"; +import { miscDialogue, getCharVariantFromDialogue } from "#app/data/dialogue"; +import { pokemonEvolutions } from "#app/data/pokemon-evolutions"; +import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species"; +import { trainerConfigs } from "#app/data/trainer-config"; +import { PlayerGender } from "#app/enums/player-gender"; +import { TrainerType } from "#app/enums/trainer-type"; +import Pokemon from "#app/field/pokemon"; +import { modifierTypes } from "#app/modifier/modifier-type"; +import { achvs, ChallengeAchv } from "#app/system/achv"; +import { Unlockables } from "#app/system/unlockables"; +import { Mode } from "#app/ui/ui"; import i18next from "i18next"; -import * as Utils from "#app/utils.js"; +import * as Utils from "#app/utils"; import { BattlePhase } from "./battle-phase"; import { CheckSwitchPhase } from "./check-switch-phase"; import { EncounterPhase } from "./encounter-phase"; @@ -23,6 +23,12 @@ import { SummonPhase } from "./summon-phase"; import { EndCardPhase } from "./end-card-phase"; import { PostGameOverPhase } from "./post-game-over-phase"; import { UnlockPhase } from "./unlock-phase"; +import { SessionSaveData } from "../system/game-data"; +import TrainerData from "../system/trainer-data"; +import PokemonData from "../system/pokemon-data"; +import PersistentModifierData from "../system/modifier-data"; +import ChallengeData from "../system/challenge-data"; +import ArenaData from "../system/arena-data"; export class GameOverPhase extends BattlePhase { private victory: boolean; @@ -98,13 +104,7 @@ export class GameOverPhase extends BattlePhase { this.scene.gameData.gameStats.dailyRunSessionsWon++; } } - this.scene.gameData.getSession(this.scene.sessionSlotId).then(sessionData => { - if (sessionData) { - this.scene.gameData.saveRunHistory(this.scene, sessionData, this.victory); - } - }).catch(err => { - console.error("Failed to save run to history.", err); - }); + this.scene.gameData.saveRunHistory(this.scene, this.getFinalSessionData(), this.victory); const fadeDuration = this.victory ? 10000 : 5000; this.scene.fadeOutBgm(fadeDuration, true); const activeBattlers = this.scene.getField().filter(p => p?.isActive(true)); @@ -207,4 +207,32 @@ export class GameOverPhase extends BattlePhase { this.firstRibbons.push(getPokemonSpecies(pokemon.species.getRootSpeciesId(forStarter))); } } + + /** + * This function mirrors game-data.ts' getSessionSaveData() to update the session data to reflect any changes that occurred within the last wave + * This means that level ups, item usage, evolutions, etc. will all be accurately reflected. + * @returns {@linkCode SessionSaveData} an updated version of the wave's SessionSaveData that accurately reflects the events of the wave + */ + private getFinalSessionData(): SessionSaveData { + return { + seed: this.scene.seed, + playTime: this.scene.sessionPlayTime, + gameMode: this.scene.gameMode.modeId, + party: this.scene.getParty().map(p => new PokemonData(p)), + enemyParty: this.scene.getEnemyParty().map(p => new PokemonData(p)), + modifiers: this.scene.findModifiers(() => true).map(m => new PersistentModifierData(m, true)), + enemyModifiers: this.scene.findModifiers(() => true, false).map(m => new PersistentModifierData(m, false)), + arena: new ArenaData(this.scene.arena), + pokeballCounts: this.scene.pokeballCounts, + money: this.scene.money, + score: this.scene.score, + waveIndex: this.scene.currentBattle.waveIndex, + battleType: this.scene.currentBattle.battleType, + trainer: this.scene.currentBattle.battleType === BattleType.TRAINER ? new TrainerData(this.scene.currentBattle.trainer) : null, + gameVersion: this.scene.game.config.gameVersion, + timestamp: new Date().getTime(), + challenges: this.scene.gameMode.challenges.map(c => new ChallengeData(c)) + } as SessionSaveData; + } } + From 35f522fd9944e896d47500e884a8796a6930ee93 Mon Sep 17 00:00:00 2001 From: EmberCM Date: Wed, 28 Aug 2024 19:17:18 -0500 Subject: [PATCH 06/10] Fix text disappearing while in transferMode (#3740) Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> --- src/ui/party-ui-handler.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 66c777944d1..e7c4069c16e 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -5,7 +5,7 @@ import { Command } from "./command-ui-handler"; import MessageUiHandler from "./message-ui-handler"; import { Mode } from "./ui"; import * as Utils from "../utils"; -import { PokemonBaseStatModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, SwitchEffectTransferModifier } from "../modifier/modifier"; +import { PokemonFormChangeItemModifier, PokemonHeldItemModifier, SwitchEffectTransferModifier } from "../modifier/modifier"; import { allMoves, ForceSwitchOutAttr } from "../data/move"; import { getGenderColor, getGenderSymbol } from "../data/gender"; import { StatusEffect } from "../data/status-effect"; @@ -989,14 +989,8 @@ export default class PartyUiHandler extends MessageUiHandler { optionText.setOrigin(0, 0); /** For every item that has stack bigger than 1, display the current quantity selection */ - if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && this.transferQuantitiesMax[option] > 1) { - const itemModifier = itemModifiers[option]; - - /** Not sure why getMaxHeldItemCount had an error, but it only checks the Pokemon parameter if the modifier is PokemonBaseStatModifier */ - if (itemModifier === undefined || itemModifier instanceof PokemonBaseStatModifier) { - continue; - } - + const itemModifier = itemModifiers[option]; + if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && this.transferQuantitiesMax[option] > 1 && !this.transferMode && itemModifier !== undefined && itemModifier.type.name === optionName) { let amountText = ` (${this.transferQuantities[option]})`; /** If the amount held is the maximum, display the count in red */ From 781e25848d2fc5822d43c26a77c2b3d7b1509d39 Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Wed, 28 Aug 2024 22:44:26 -0700 Subject: [PATCH 07/10] fixed infinite loop (#3887) Co-authored-by: frutescens --- src/system/game-data.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/system/game-data.ts b/src/system/game-data.ts index e7bc85d9037..d10d6288696 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -635,13 +635,13 @@ export class GameData { async saveRunHistory(scene: BattleScene, runEntry : SessionSaveData, isVictory: boolean): Promise { const runHistoryData = await this.getRunHistoryData(scene); // runHistoryData should always return run history or {} empty object - const timestamps = Object.keys(runHistoryData); - const timestampsNo = timestamps.map(Number); + let timestamps = Object.keys(runHistoryData).map(Number); // Arbitrary limit of 25 entries per user --> Can increase or decrease while (timestamps.length >= RUN_HISTORY_LIMIT ) { - const oldestTimestamp = Math.min.apply(Math, timestampsNo); + const oldestTimestamp = (Math.min.apply(Math, timestamps)).toString(); delete runHistoryData[oldestTimestamp]; + timestamps = Object.keys(runHistoryData).map(Number); } const timestamp = (runEntry.timestamp).toString(); From 8f2699e6ead79e3bfd1e09c96f37d27125776442 Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Thu, 29 Aug 2024 02:38:21 -0400 Subject: [PATCH 08/10] [Enhancement] Update Team Skull Sprites (#3886) * Update Team Skull Sprites * Add files via upload * Update skull_grunt_f.json * Update skull_grunt_m.json * Fix eol --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- public/images/trainer/guzma.png | Bin 848 -> 2312 bytes public/images/trainer/skull_grunt_f.json | 22 +++++++++++----------- public/images/trainer/skull_grunt_f.png | Bin 792 -> 905 bytes public/images/trainer/skull_grunt_m.json | 22 +++++++++++----------- public/images/trainer/skull_grunt_m.png | Bin 723 -> 966 bytes 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/public/images/trainer/guzma.png b/public/images/trainer/guzma.png index 97dadfbe6fddff6280b036d2b6c923ac7b74a405..6afd6f3b34a7f8766cf1e3a95743482dcb068763 100644 GIT binary patch delta 2277 zcmVP+CJ`QA#j0LZFcHY9o&{0Sr({L(5AGk`{y* zQ_7=8c?3|RXlyZv8Yr(8721Rtr3Mv=*ZgL8j%V-Qz4vzE?tgmz=-$1LbLKlUXU@#* zt&i@q)m2v+H6I?Jy845@yX?x-$D2ukGp^7s*B_~>!u^Km!)2j}oPVoZkmF2|md zICLHn6at$C6fpGp)rq47NGA080I0spbsadKkV*??Ap~e&%{I!JUZ6B1U}jJq+T53} z?RdgkYE;);5Py~oLoD_`aqR&0$@o9OMl@YGnaTMxqgH}>65x|5>%jZ47;43Ts zZ=-RrzC4b`JT*`P)ZgVu<#)i2HMn<#( zHBW#U7#h8PwHaPKE?RZkM`>AMR|VSAa+O)Pl%Al(^maP-UO5dMvVvxpj#jgdYhvEI zDFYNOUgm4Ny};ZARA6*S2tM}pB5G~$hrz<7&y1#riV_pw6A#mYPMm^z4u|Tht7!S^GCEvaOG$$VQ*LGkHC<^58wRkL zh{>5P^!JSy`TE*D`}q@*RXnxo1j;f(vrT8N(|@%2(`eYRVN^7|h(I$u~WrzFllba>wuoz-|9553UG__vMDno;9Upw>CK-< zzr91{)#Y^h^l93;VJD3n(uu~;Dy52&+3G$G)V)+5-01|WhAhs@HUKJ+k!0CXcbt}1 zR)6u@ydW9@-$LDw%|%m52lmMP&yBUppd0Ejkn z=s=qJ))q@p(JDUUVZxT6qD`0^G@ye*&s7=I`r zFI_m#LSs!yJ9F-Qh^7$fluVthoRb++zh89{Jcx%Ghk)vu)FCnZiHS)h!izUWsFy(b zY_dA2XiJ=!88jYdtUz^5!dziq(jYh*V8y|}d;y9I!}jV|_&Ndwz}ab2hmNHgGiW4D z>Y&&Xke-QVd-w439tl`I!G5xTDu2QBWh;?=)Jm(eW@F)veRi4@;h@Ffc3?nba8dw5 zw1lKvl5A8FrWVWz0mXxnV1xbgFj(_mdSeE?{6{PGO-SScA-uk}EWD!u&3^H91E*b* ze?Ip@AZS1(0cqX3%B@O?um&m5zEn!8AR&jGM(-G^5WbIL%=QX;zu)u)lJhVUHbTYG(c!q<`YOiHj zOagLMlv+?#u+yqcOmTJ~2$?^BXqdoWrgRGQ=G7hw62NQsm)XrMgDxqY#oF8U&L-;P z&tNIw-UXNUT|WqG7ED>$n^rH+}@=Va>B>=t4pW`N=`A1L>1suGAy=kopns!+P9VTTeZck|KtJxG!d)QXevdO8L^f zrmSG|GM^8D#67y{V_ULoUc!cCFAxGD8ejnk&FED<^SUyduzwj;tU=be6R4Iv*iJ|^ z7cD`t_aR_FScp(CQUWb&RySXHRwhYzWKN)7nlNWCQnizr($goqDuM2tbXZ9eBqNc2 z-GF+fRZCDereW5mJR?yOzIUNcbery|gx#rMFAHXzrrBxDES%JfaQ@amfvd=2wHD^d zaZRcdcCcP)6Mtidt(c%&=#aJ~jwW&a%RjV1dayF8JnM~D9 zR1*=lc;P(HU*b>#BF@!?mvV`mlebEs6*N5*4Bq1eYalX0?uwuKQ6EB+l8nnfoR)dS z>k);s0!J_9Wox)I0851d-`%`*(mA1*D=B-dZp@`peF-d=b(WsQe6}!^*F1ZlW1jg#1)!HDPPlS9t#KByK8plPUuy!rW8B delta 802 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 Br?~(C delta 666 zcmV;L0%iTi2h#;(iBL{Q4GJ0x0000DNk~Le0000(0000(2m=5B0Pqw@K>z>%Hc(7d zMF0Q*0000B2n7uc4GxmS6%`dNEGaoSHcm}RY-wbBN?NrvBfWcL$c}B!&d%PYd;ih3 z|Ns9Ndk|)kZzO*L97#k$R9M5U*wJ?EAP5D}P*M#vqw@bhdjXwxUUR&zKJ+Df9SLfj zU^L743r;zCr^Y{wAkV~liALwa}P?&CZ~F+=+u z1X&D)o#u#21@a<|E+;5ZOtwK9HTQfn-wIP!G|Jc{U}Ji(s&_3c*gK; z#Met8ucv>A#<`Gd#;%xz0u@m|r;5}xco~li;$2z-v6==M(5od{U1B>7!w+!-TD5pV z;`6}~3gbf79oLri@TaLlo4XrrZp(J5K{0$MTZAX*!w}+_Yc7e`z;?rfbA+R#gXcEa z>d!l) Date: Thu, 29 Aug 2024 03:57:22 -0500 Subject: [PATCH 09/10] [Sprite] Update Rose Sprite (#3890) --- public/images/trainer/rose.png | Bin 864 -> 1088 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/public/images/trainer/rose.png b/public/images/trainer/rose.png index a79a754e21b995ef415a2a1e2aa4d3e84a3f9ff4..f90da7568d4d58279b1186035a2f1ad429bdc440 100644 GIT binary patch delta 1067 zcmV+`1l0TB2EYiAB!2;OQb$4nuFf3k00004XF*Lt006O%3;baP0000sP)t-sCnhF8 zJUm!aQ@w~@pl3wdsC|G+F{YxbTv=W*F*=HdiBeKh|Ns9G5D=LyDc`kDy-G>|008sg z+hqU%01|XkPE-H?|NsC0|NsC0|NsC0|Ns90;=jKV00009aDPZya{vGf6951U69E94 zoEQKA19eG6K~z{rt=Ns4svr=6VFee6mE7+CX7`%`%gml2nSHj^j=s(C>uI?4jd$LV zqny>p@g2i3j-xT7X%>&J9|j|V$WJ49a5);;<^0I7yjvNsmk(LHM;mzT*=d~Y&yVfn zIcx3oBQbgJLw|X{E)KoRh2$<5@nSsbQLeKS=}pt`uZ^ek8_eM5glE%iZJbW#2X~Y9 z!=wFdw9`qCH(bWVo9vXzztqJ`y@azgo?`TK8+Ygd8uM#rJk!V>d!w=QJWqyU-ODqE z7p?;0DA%wGzIY@Uz2tYLUOA=yue}gy zH)%RNX}{nXf65a~yW_8TG@yF5%iw`Wx%2hzrQCjJy+xYutVi?35EJ#1pNzqEyx>)W z&z|H#gMS4t^`bEtfm#yWc!Bh?2Sw-eQBGLk(xuJxR3j=bwnqMisa(|ho-lUH|R`;HVmxI>KUhT3k{gLPo zm#^RF$7Ip-#`WdCEk-KT+ZDkp2i3b$_SPUNT8#TkcBOafxxELZVWeY;q=T{ zL4Vh>Val5)JQ*jeCdcQzJk=;SYy8qLtUBd_PqFuCF?F`yX8wGPw_aHW_^q}ijy*bf zow%L6z}P8X?b4#L_i~BSpLegiFC^Z3dEt_mbDk>wysSu#W$o+WF*i8ACwR(}iluuy zd9q=Uo)9c6T|8L|`gsiK;^~RRIZs20HGjdD3G!O+lLxq-)x{@Iw%`ulde+G+Ev5!xF9X$!a70?mLLqj>Oh-Yu)zr7>m!;@_9rxo$!jb<^|aol{1 zgUv^L=Z)hZA>YP6?oXrPGa9}odU#1V&F;y&>buq8*3;nWV)Hb>qo9D_c=9dNmL$qS l!I38T#ygI~Pk9%&+dpO1V;ywRJ!${|002ovPDHLkV1gx@BT)bV delta 821 zcmV-51Iqls2;c^gBt|e$OjJbx0000406920N>EZ_5D;@fL3??FoONQHous6Rd%ZkC z#TY5gu9VHXQr_O?_WJgvTdP_C0004WQchCmUpU zU~Di;o51_O?XexQ%~Wa!e54{xJ6B(SLs)`yFB@#l88z(9Mg;KMR5S?3lvXPuSa1Nn zS_=?8Y#4vRd=Cnj56ziRT~>f)L}6eCmyY%Eeng z8I2?0$6yFS4w3QjdcLR+%MtL?qgHr6pFyU+mdhWSZ_|4!0in^le#A8adA4@1=i9vw zLMtnOtwe8k6^X~|9SO+g#%uqb-3HKBY9u@J8<3N=mVlRcK8)&mcX^&K!vGwPPY&<$ z@rj4qLW#J)H_xNLdIv~y>MC!y+O!b=$>{ZRS6uxIPj}__hX#PIsh2koWodz*9+&X} z=#CdF_Vif4>iPc2cL_)W(&saTH^_ZB;^`fKi;E^CH|k;jwO0M8he^QPV!Oi^pj>@8FHgrroZ^^*6@y0lc^n-y#nd{NlnM6bzGBCbw%Rqf7To=09C& z{{s?+BZi(Hq}>1j01jnXNoGw=04e|g00;m8000000Mb*F00000NkvXXu0mjfl+}ZK From 59ff4e9941cf4e1f262d279bddd87c52b58631b0 Mon Sep 17 00:00:00 2001 From: Opaque02 <66582645+Opaque02@users.noreply.github.com> Date: Thu, 29 Aug 2024 19:22:01 +1000 Subject: [PATCH 10/10] Admin panel beta (#3846) * feat: Add hasAdminRole property to UserInfo interface and update initLoggedInUser and updateUserInfo functions This commit adds the hasAdminRole property to the UserInfo interface in the account.ts file. The initLoggedInUser function is updated to set the hasAdminRole property to false by default. The updateUserInfo function is also updated to set the hasAdminRole property to false when bypassLogin is true. This change allows for better management of user roles and permissions. Co-authored-by: frutescens Co-authored-by: Frederico Santos * Updated UI for admin panel and menu * Remove random blank line from merge * Fix imports in `src/ui/ui.ts` --------- Co-authored-by: Frederico Santos Co-authored-by: frutescens Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/account.ts | 5 +- src/ui/admin-ui-handler.ts | 85 +++++++++++++++++++++++++++++++++ src/ui/form-modal-ui-handler.ts | 4 +- src/ui/menu-ui-handler.ts | 32 ++++++++++--- src/ui/ui.ts | 8 +++- 5 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 src/ui/admin-ui-handler.ts diff --git a/src/account.ts b/src/account.ts index 6682e3e0b7c..c6d2f85489a 100644 --- a/src/account.ts +++ b/src/account.ts @@ -6,6 +6,7 @@ export interface UserInfo { lastSessionSlot: integer; discordId: string; googleId: string; + hasAdminRole: boolean; } export let loggedInUser: UserInfo | null = null; @@ -13,13 +14,13 @@ export let loggedInUser: UserInfo | null = null; export const clientSessionId = Utils.randomString(32); export function initLoggedInUser(): void { - loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: ""}; + loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: "", hasAdminRole: false }; } export function updateUserInfo(): Promise<[boolean, integer]> { return new Promise<[boolean, integer]>(resolve => { if (bypassLogin) { - loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: "" }; + loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: "", hasAdminRole: false}; let lastSessionSlot = -1; for (let s = 0; s < 5; s++) { if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) { diff --git a/src/ui/admin-ui-handler.ts b/src/ui/admin-ui-handler.ts new file mode 100644 index 00000000000..371604c00a2 --- /dev/null +++ b/src/ui/admin-ui-handler.ts @@ -0,0 +1,85 @@ +import BattleScene from "#app/battle-scene.js"; +import { ModalConfig } from "./modal-ui-handler"; +import { Mode } from "./ui"; +import * as Utils from "../utils"; +import { FormModalUiHandler } from "./form-modal-ui-handler"; +import { Button } from "#app/enums/buttons.js"; + +export default class AdminUiHandler extends FormModalUiHandler { + + constructor(scene: BattleScene, mode: Mode | null = null) { + super(scene, mode); + } + + setup(): void { + super.setup(); + } + + getModalTitle(config?: ModalConfig): string { + return "Admin panel"; + } + + getFields(config?: ModalConfig): string[] { + return ["Username", "Discord ID"]; + } + + getWidth(config?: ModalConfig): number { + return 160; + } + + getMargin(config?: ModalConfig): [number, number, number, number] { + return [0, 0, 48, 0]; + } + + getButtonLabels(config?: ModalConfig): string[] { + return ["Link account", "Cancel"]; + } + + processInput(button: Button): boolean { + if (button === Button.SUBMIT && this.submitAction) { + this.submitAction(); + return true; + } + + return false; + } + + show(args: any[]): boolean { + if (super.show(args)) { + const config = args[0] as ModalConfig; + const originalSubmitAction = this.submitAction; + this.submitAction = (_) => { + this.submitAction = originalSubmitAction; + this.scene.ui.setMode(Mode.LOADING, { buttonActions: [] }); + const onFail = error => { + this.scene.ui.setMode(Mode.ADMIN, Object.assign(config, { errorMessage: error?.trim() })); + this.scene.ui.playError(); + }; + if (!this.inputs[0].text) { + return onFail("Username is required"); + } + if (!this.inputs[1].text) { + return onFail("Discord Id is required"); + } + Utils.apiPost("admin/account/discord-link", `username=${encodeURIComponent(this.inputs[0].text)}&discordId=${encodeURIComponent(this.inputs[1].text)}`, "application/x-www-form-urlencoded", true) + .then(response => { + if (!response.ok) { + return response.text(); + } + return response.json(); + }) + .then(response => { + this.scene.ui.setMode(Mode.ADMIN, config); + }); + return false; + }; + return true; + } + return false; + + } + + clear(): void { + super.clear(); + } +} diff --git a/src/ui/form-modal-ui-handler.ts b/src/ui/form-modal-ui-handler.ts index 4516e39675c..8c4ea5f6768 100644 --- a/src/ui/form-modal-ui-handler.ts +++ b/src/ui/form-modal-ui-handler.ts @@ -6,7 +6,7 @@ import { WindowVariant, addWindow } from "./ui-theme"; import InputText from "phaser3-rex-plugins/plugins/inputtext"; import * as Utils from "../utils"; import i18next from "i18next"; -import {Button} from "#enums/buttons"; +import { Button } from "#enums/buttons"; export interface FormModalConfig extends ModalConfig { errorMessage?: string; @@ -60,7 +60,7 @@ export abstract class FormModalUiHandler extends ModalUiHandler { const inputBg = addWindow(this.scene, 0, 0, 80, 16, false, false, 0, 0, WindowVariant.XTHIN); const isPassword = field.includes(i18next.t("menu:password")) || field.includes(i18next.t("menu:confirmPassword")); - const input = addTextInputObject(this.scene, 4, -2, 440, 116, TextStyle.TOOLTIP_CONTENT, { type: isPassword ? "password" : "text", maxLength: isPassword ? 64 : 16 }); + const input = addTextInputObject(this.scene, 4, -2, 440, 116, TextStyle.TOOLTIP_CONTENT, { type: isPassword ? "password" : "text", maxLength: isPassword ? 64 : 18 }); input.setOrigin(0, 0); inputContainer.add(inputBg); diff --git a/src/ui/menu-ui-handler.ts b/src/ui/menu-ui-handler.ts index 6fdf98d14a3..0bbfe21e4f9 100644 --- a/src/ui/menu-ui-handler.ts +++ b/src/ui/menu-ui-handler.ts @@ -306,16 +306,34 @@ export default class MenuUiHandler extends MessageUiHandler { return true; }, keepOpen: true - }, - { - label: i18next.t("menuUiHandler:cancel"), + }]; + if (!bypassLogin && loggedInUser?.hasAdminRole) { + communityOptions.push({ + label: "Admin", handler: () => { - this.scene.ui.revertMode(); + ui.playSelect(); + ui.setOverlayMode(Mode.ADMIN, { + buttonActions: [ + () => { + ui.revertMode(); + }, + () => { + ui.revertMode(); + } + ] + }); return true; - } + }, + keepOpen: true + }); + } + communityOptions.push({ + label: i18next.t("menuUiHandler:cancel"), + handler: () => { + this.scene.ui.revertMode(); + return true; } - ]; - + }); this.communityConfig = { xOffset: 98, options: communityOptions diff --git a/src/ui/ui.ts b/src/ui/ui.ts index 250a21544dc..5e1c28eda2d 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -23,7 +23,7 @@ import OptionSelectUiHandler from "./settings/option-select-ui-handler"; import EggHatchSceneHandler from "./egg-hatch-scene-handler"; import EggListUiHandler from "./egg-list-ui-handler"; import EggGachaUiHandler from "./egg-gacha-ui-handler"; -import {addWindow} from "./ui-theme"; +import { addWindow } from "./ui-theme"; import LoginFormUiHandler from "./login-form-ui-handler"; import RegistrationFormUiHandler from "./registration-form-ui-handler"; import LoadingModalUiHandler from "./loading-modal-ui-handler"; @@ -46,6 +46,7 @@ import SettingsAudioUiHandler from "./settings/settings-audio-ui-handler"; import { PlayerGender } from "#enums/player-gender"; import BgmBar from "#app/ui/bgm-bar"; import RenameFormUiHandler from "./rename-form-ui-handler"; +import AdminUiHandler from "./admin-ui-handler"; import RunHistoryUiHandler from "./run-history-ui-handler"; import RunInfoUiHandler from "./run-info-ui-handler"; @@ -86,6 +87,7 @@ export enum Mode { OUTDATED, CHALLENGE_SELECT, RENAME_POKEMON, + ADMIN, RUN_HISTORY, RUN_INFO, } @@ -124,7 +126,8 @@ const noTransitionModes = [ Mode.SESSION_RELOAD, Mode.UNAVAILABLE, Mode.OUTDATED, - Mode.RENAME_POKEMON + Mode.RENAME_POKEMON, + Mode.ADMIN, ]; export default class UI extends Phaser.GameObjects.Container { @@ -188,6 +191,7 @@ export default class UI extends Phaser.GameObjects.Container { new RenameFormUiHandler(scene), new RunHistoryUiHandler(scene), new RunInfoUiHandler(scene), + new AdminUiHandler(scene), ]; }