From 2d067ec7ce82e9559f4117cd2896b8bec3d6fa6d Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Fri, 21 Feb 2025 07:23:08 +1100 Subject: [PATCH] [UI][Enhancement] Allow tera type choice on starter select (#5366) * Allow tera type choice on starter select * Make tera type actually apply in run * Remove logging statement * Add support for alternate forms --- index.css | 2 +- index.html | 2 +- src/configs/inputs/cfg_keyboard_qwerty.ts | 6 +- src/configs/inputs/pad_dualshock.ts | 4 +- src/configs/inputs/pad_generic.ts | 4 +- src/configs/inputs/pad_procon.ts | 4 +- src/configs/inputs/pad_unlicensedSNES.ts | 4 +- src/configs/inputs/pad_xbox360.ts | 4 +- src/data/challenge.ts | 1 + src/enums/buttons.ts | 4 +- src/phases/select-starter-phase.ts | 7 ++ src/system/game-data.ts | 2 + src/system/settings/settings-gamepad.ts | 8 +- src/system/settings/settings-keyboard.ts | 16 ++-- .../settingMenu/rebinding_setting.test.ts | 8 +- src/test/utils/fakeMobile.html | 4 +- src/ui-inputs.ts | 6 +- src/ui/pokedex-ui-handler.ts | 5 +- src/ui/starter-select-ui-handler.ts | 79 +++++++++++++++++-- 19 files changed, 121 insertions(+), 49 deletions(-) diff --git a/index.css b/index.css index d32d9da9bb1..9226f968e3e 100644 --- a/index.css +++ b/index.css @@ -170,7 +170,7 @@ input:-internal-autofill-selected { #touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT']) #apadCycleNature, #touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX_PAGE'], [data-ui-mode='RUN_INFO']) #apadCycleAbility, #touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX_PAGE']) #apadCycleGender, -#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX']) #apadCycleVariant { +#touchControls:not(.config-mode):not([data-ui-mode='STARTER_SELECT'], [data-ui-mode='POKEDEX']) #apadCycleTera { display: none; } diff --git a/index.html b/index.html index 390a29fb365..91367cf73ec 100644 --- a/index.html +++ b/index.html @@ -129,7 +129,7 @@
N
-
+
V
diff --git a/src/configs/inputs/cfg_keyboard_qwerty.ts b/src/configs/inputs/cfg_keyboard_qwerty.ts index 5ddc12e8784..c1b00a833c0 100644 --- a/src/configs/inputs/cfg_keyboard_qwerty.ts +++ b/src/configs/inputs/cfg_keyboard_qwerty.ts @@ -180,9 +180,9 @@ const cfg_keyboard_qwerty = { [SettingKeyboard.Button_Cycle_Gender]: Button.CYCLE_GENDER, [SettingKeyboard.Button_Cycle_Ability]: Button.CYCLE_ABILITY, [SettingKeyboard.Button_Cycle_Nature]: Button.CYCLE_NATURE, - [SettingKeyboard.Button_Cycle_Variant]: Button.V, [SettingKeyboard.Button_Speed_Up]: Button.SPEED_UP, [SettingKeyboard.Button_Slow_Down]: Button.SLOW_DOWN, + [SettingKeyboard.Button_Cycle_Tera]: Button.CYCLE_TERA, [SettingKeyboard.Alt_Button_Up]: Button.UP, [SettingKeyboard.Alt_Button_Down]: Button.DOWN, [SettingKeyboard.Alt_Button_Left]: Button.LEFT, @@ -197,9 +197,9 @@ const cfg_keyboard_qwerty = { [SettingKeyboard.Alt_Button_Cycle_Gender]: Button.CYCLE_GENDER, [SettingKeyboard.Alt_Button_Cycle_Ability]: Button.CYCLE_ABILITY, [SettingKeyboard.Alt_Button_Cycle_Nature]: Button.CYCLE_NATURE, - [SettingKeyboard.Alt_Button_Cycle_Variant]: Button.V, [SettingKeyboard.Alt_Button_Speed_Up]: Button.SPEED_UP, [SettingKeyboard.Alt_Button_Slow_Down]: Button.SLOW_DOWN, + [SettingKeyboard.Alt_Button_Cycle_Tera]: Button.CYCLE_TERA, }, default: { KEY_ARROW_UP: SettingKeyboard.Button_Up, @@ -216,7 +216,7 @@ const cfg_keyboard_qwerty = { KEY_G: SettingKeyboard.Button_Cycle_Gender, KEY_E: SettingKeyboard.Button_Cycle_Ability, KEY_N: SettingKeyboard.Button_Cycle_Nature, - KEY_V: SettingKeyboard.Button_Cycle_Variant, + KEY_V: SettingKeyboard.Button_Cycle_Tera, KEY_PLUS: -1, KEY_MINUS: -1, KEY_A: SettingKeyboard.Alt_Button_Left, diff --git a/src/configs/inputs/pad_dualshock.ts b/src/configs/inputs/pad_dualshock.ts index 2fbdd0ddfaa..265b39fdad5 100644 --- a/src/configs/inputs/pad_dualshock.ts +++ b/src/configs/inputs/pad_dualshock.ts @@ -53,7 +53,7 @@ const pad_dualshock = { [SettingGamepad.Button_Action]: Button.ACTION, [SettingGamepad.Button_Cancel]: Button.CANCEL, [SettingGamepad.Button_Cycle_Nature]: Button.CYCLE_NATURE, - [SettingGamepad.Button_Cycle_Variant]: Button.V, + [SettingGamepad.Button_Cycle_Tera]: Button.CYCLE_TERA, [SettingGamepad.Button_Menu]: Button.MENU, [SettingGamepad.Button_Stats]: Button.STATS, [SettingGamepad.Button_Cycle_Form]: Button.CYCLE_FORM, @@ -72,7 +72,7 @@ const pad_dualshock = { RC_S: SettingGamepad.Button_Action, RC_E: SettingGamepad.Button_Cancel, RC_W: SettingGamepad.Button_Cycle_Nature, - RC_N: SettingGamepad.Button_Cycle_Variant, + RC_N: SettingGamepad.Button_Cycle_Tera, START: SettingGamepad.Button_Menu, SELECT: SettingGamepad.Button_Stats, LB: SettingGamepad.Button_Cycle_Form, diff --git a/src/configs/inputs/pad_generic.ts b/src/configs/inputs/pad_generic.ts index 256af8f0fe3..cd91fcd8b17 100644 --- a/src/configs/inputs/pad_generic.ts +++ b/src/configs/inputs/pad_generic.ts @@ -51,7 +51,7 @@ const pad_generic = { [SettingGamepad.Button_Action]: Button.ACTION, [SettingGamepad.Button_Cancel]: Button.CANCEL, [SettingGamepad.Button_Cycle_Nature]: Button.CYCLE_NATURE, - [SettingGamepad.Button_Cycle_Variant]: Button.V, + [SettingGamepad.Button_Cycle_Tera]: Button.CYCLE_TERA, [SettingGamepad.Button_Menu]: Button.MENU, [SettingGamepad.Button_Stats]: Button.STATS, [SettingGamepad.Button_Cycle_Form]: Button.CYCLE_FORM, @@ -69,7 +69,7 @@ const pad_generic = { RC_S: SettingGamepad.Button_Action, RC_E: SettingGamepad.Button_Cancel, RC_W: SettingGamepad.Button_Cycle_Nature, - RC_N: SettingGamepad.Button_Cycle_Variant, + RC_N: SettingGamepad.Button_Cycle_Tera, START: SettingGamepad.Button_Menu, SELECT: SettingGamepad.Button_Stats, LB: SettingGamepad.Button_Cycle_Form, diff --git a/src/configs/inputs/pad_procon.ts b/src/configs/inputs/pad_procon.ts index 98d17c4ef57..a7ae5383fbe 100644 --- a/src/configs/inputs/pad_procon.ts +++ b/src/configs/inputs/pad_procon.ts @@ -52,7 +52,7 @@ const pad_procon = { [SettingGamepad.Button_Action]: Button.ACTION, [SettingGamepad.Button_Cancel]: Button.CANCEL, [SettingGamepad.Button_Cycle_Nature]: Button.CYCLE_NATURE, - [SettingGamepad.Button_Cycle_Variant]: Button.V, + [SettingGamepad.Button_Cycle_Tera]: Button.CYCLE_TERA, [SettingGamepad.Button_Menu]: Button.MENU, [SettingGamepad.Button_Stats]: Button.STATS, [SettingGamepad.Button_Cycle_Form]: Button.CYCLE_FORM, @@ -70,7 +70,7 @@ const pad_procon = { RC_S: SettingGamepad.Button_Action, RC_E: SettingGamepad.Button_Cancel, RC_W: SettingGamepad.Button_Cycle_Nature, - RC_N: SettingGamepad.Button_Cycle_Variant, + RC_N: SettingGamepad.Button_Cycle_Tera, START: SettingGamepad.Button_Menu, SELECT: SettingGamepad.Button_Stats, LB: SettingGamepad.Button_Cycle_Form, diff --git a/src/configs/inputs/pad_unlicensedSNES.ts b/src/configs/inputs/pad_unlicensedSNES.ts index 77e68e6a644..fbde98b3fa2 100644 --- a/src/configs/inputs/pad_unlicensedSNES.ts +++ b/src/configs/inputs/pad_unlicensedSNES.ts @@ -43,7 +43,7 @@ const pad_unlicensedSNES = { [SettingGamepad.Button_Action]: Button.ACTION, [SettingGamepad.Button_Cancel]: Button.CANCEL, [SettingGamepad.Button_Cycle_Nature]: Button.CYCLE_NATURE, - [SettingGamepad.Button_Cycle_Variant]: Button.V, + [SettingGamepad.Button_Cycle_Tera]: Button.CYCLE_TERA, [SettingGamepad.Button_Menu]: Button.MENU, [SettingGamepad.Button_Stats]: Button.STATS, [SettingGamepad.Button_Cycle_Form]: Button.CYCLE_FORM, @@ -61,7 +61,7 @@ const pad_unlicensedSNES = { RC_S: SettingGamepad.Button_Action, RC_E: SettingGamepad.Button_Cancel, RC_W: SettingGamepad.Button_Cycle_Nature, - RC_N: SettingGamepad.Button_Cycle_Variant, + RC_N: SettingGamepad.Button_Cycle_Tera, START: SettingGamepad.Button_Menu, SELECT: SettingGamepad.Button_Stats, LB: SettingGamepad.Button_Cycle_Form, diff --git a/src/configs/inputs/pad_xbox360.ts b/src/configs/inputs/pad_xbox360.ts index 6afc452f50b..88fee731d1d 100644 --- a/src/configs/inputs/pad_xbox360.ts +++ b/src/configs/inputs/pad_xbox360.ts @@ -51,7 +51,7 @@ const pad_xbox360 = { [SettingGamepad.Button_Action]: Button.ACTION, [SettingGamepad.Button_Cancel]: Button.CANCEL, [SettingGamepad.Button_Cycle_Nature]: Button.CYCLE_NATURE, - [SettingGamepad.Button_Cycle_Variant]: Button.V, + [SettingGamepad.Button_Cycle_Tera]: Button.CYCLE_TERA, [SettingGamepad.Button_Menu]: Button.MENU, [SettingGamepad.Button_Stats]: Button.STATS, [SettingGamepad.Button_Cycle_Form]: Button.CYCLE_FORM, @@ -69,7 +69,7 @@ const pad_xbox360 = { RC_S: SettingGamepad.Button_Action, RC_E: SettingGamepad.Button_Cancel, RC_W: SettingGamepad.Button_Cycle_Nature, - RC_N: SettingGamepad.Button_Cycle_Variant, + RC_N: SettingGamepad.Button_Cycle_Tera, START: SettingGamepad.Button_Menu, SELECT: SettingGamepad.Button_Stats, LB: SettingGamepad.Button_Cycle_Form, diff --git a/src/data/challenge.ts b/src/data/challenge.ts index c6e85be2389..30c2c9a6ce4 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -708,6 +708,7 @@ export class FreshStartChallenge extends Challenge { pokemon.variant = 0; // Not shiny pokemon.formIndex = 0; // Froakie should be base form pokemon.ivs = [ 15, 15, 15, 15, 15, 15 ]; // Default IVs of 15 for all stats (Updated to 15 from 10 in 1.2.0) + pokemon.teraType = pokemon.species.type1; // Always primary tera type return true; } diff --git a/src/enums/buttons.ts b/src/enums/buttons.ts index fe26023f8e7..f828b280d45 100644 --- a/src/enums/buttons.ts +++ b/src/enums/buttons.ts @@ -13,7 +13,7 @@ export enum Button { CYCLE_GENDER, CYCLE_ABILITY, CYCLE_NATURE, - V, + CYCLE_TERA, SPEED_UP, - SLOW_DOWN + SLOW_DOWN, } diff --git a/src/phases/select-starter-phase.ts b/src/phases/select-starter-phase.ts index 79012901a3a..b7ad15533a6 100644 --- a/src/phases/select-starter-phase.ts +++ b/src/phases/select-starter-phase.ts @@ -12,6 +12,7 @@ import type { Starter } from "#app/ui/starter-select-ui-handler"; import { Mode } from "#app/ui/ui"; import type { Species } from "#enums/species"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; +import * as Utils from "../utils"; export class SelectStarterPhase extends Phase { @@ -79,6 +80,12 @@ export class SelectStarterPhase extends Phase { starterPokemon.nickname = starter.nickname; } + if (!Utils.isNullOrUndefined(starter.teraType)) { + starterPokemon.teraType = starter.teraType; + } else { + starterPokemon.teraType = starterPokemon.species.type1; + } + if (globalScene.gameMode.isSplicedOnly || Overrides.STARTER_FUSION_OVERRIDE) { starterPokemon.generateFusionSpecies(true); } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 63d79d47fba..6b25013795f 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -55,6 +55,7 @@ import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-e import type { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; import { ArenaTrapTag } from "#app/data/arena-tag"; +import type { Type } from "#enums/type"; export const defaultStarterSpecies: Species[] = [ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, @@ -229,6 +230,7 @@ export interface StarterAttributes { shiny?: boolean; favorite?: boolean; nickname?: string; + tera?: Type; } export interface StarterPreferences { diff --git a/src/system/settings/settings-gamepad.ts b/src/system/settings/settings-gamepad.ts index d26c0c9f019..840304ab1ba 100644 --- a/src/system/settings/settings-gamepad.ts +++ b/src/system/settings/settings-gamepad.ts @@ -21,7 +21,7 @@ export enum SettingGamepad { Button_Cycle_Gender = "BUTTON_CYCLE_GENDER", Button_Cycle_Ability = "BUTTON_CYCLE_ABILITY", Button_Cycle_Nature = "BUTTON_CYCLE_NATURE", - Button_Cycle_Variant = "BUTTON_CYCLE_VARIANT", + Button_Cycle_Tera = "BUTTON_CYCLE_TERA", Button_Speed_Up = "BUTTON_SPEED_UP", Button_Slow_Down = "BUTTON_SLOW_DOWN", Button_Submit = "BUTTON_SUBMIT", @@ -45,7 +45,7 @@ export const settingGamepadOptions = { [SettingGamepad.Button_Cycle_Gender]: [ `KEY ${Button.CYCLE_GENDER.toString()}`, pressAction ], [SettingGamepad.Button_Cycle_Ability]: [ `KEY ${Button.CYCLE_ABILITY.toString()}`, pressAction ], [SettingGamepad.Button_Cycle_Nature]: [ `KEY ${Button.CYCLE_NATURE.toString()}`, pressAction ], - [SettingGamepad.Button_Cycle_Variant]: [ `KEY ${Button.V.toString()}`, pressAction ], + [SettingGamepad.Button_Cycle_Tera]: [ `KEY ${Button.CYCLE_TERA.toString()}`, pressAction ], [SettingGamepad.Button_Speed_Up]: [ `KEY ${Button.SPEED_UP.toString()}`, pressAction ], [SettingGamepad.Button_Slow_Down]: [ `KEY ${Button.SLOW_DOWN.toString()}`, pressAction ], [SettingGamepad.Button_Submit]: [ `KEY ${Button.SUBMIT.toString()}`, pressAction ], @@ -67,7 +67,7 @@ export const settingGamepadDefaults = { [SettingGamepad.Button_Cycle_Gender]: 0, [SettingGamepad.Button_Cycle_Ability]: 0, [SettingGamepad.Button_Cycle_Nature]: 0, - [SettingGamepad.Button_Cycle_Variant]: 0, + [SettingGamepad.Button_Cycle_Tera]: 0, [SettingGamepad.Button_Speed_Up]: 0, [SettingGamepad.Button_Slow_Down]: 0, [SettingGamepad.Button_Submit]: 0, @@ -96,7 +96,7 @@ export function setSettingGamepad(setting: SettingGamepad, value: number): boole case SettingGamepad.Button_Cycle_Gender: case SettingGamepad.Button_Cycle_Ability: case SettingGamepad.Button_Cycle_Nature: - case SettingGamepad.Button_Cycle_Variant: + case SettingGamepad.Button_Cycle_Tera: case SettingGamepad.Button_Speed_Up: case SettingGamepad.Button_Slow_Down: case SettingGamepad.Button_Submit: diff --git a/src/system/settings/settings-keyboard.ts b/src/system/settings/settings-keyboard.ts index 95ad4ba41f1..1a7db1b10c2 100644 --- a/src/system/settings/settings-keyboard.ts +++ b/src/system/settings/settings-keyboard.ts @@ -32,8 +32,8 @@ export enum SettingKeyboard { Alt_Button_Cycle_Ability = "ALT_BUTTON_CYCLE_ABILITY", Button_Cycle_Nature = "BUTTON_CYCLE_NATURE", Alt_Button_Cycle_Nature = "ALT_BUTTON_CYCLE_NATURE", - Button_Cycle_Variant = "BUTTON_CYCLE_VARIANT", - Alt_Button_Cycle_Variant = "ALT_BUTTON_CYCLE_VARIANT", + Button_Cycle_Tera = "BUTTON_CYCLE_TERA", + Alt_Button_Cycle_Tera = "ALT_BUTTON_CYCLE_TERA", Button_Speed_Up = "BUTTON_SPEED_UP", Alt_Button_Speed_Up = "ALT_BUTTON_SPEED_UP", Button_Slow_Down = "BUTTON_SLOW_DOWN", @@ -73,8 +73,8 @@ export const settingKeyboardOptions = { [SettingKeyboard.Alt_Button_Cycle_Ability]: [ `KEY ${Button.CYCLE_ABILITY.toString()}`, pressAction ], [SettingKeyboard.Button_Cycle_Nature]: [ `KEY ${Button.CYCLE_NATURE.toString()}`, pressAction ], [SettingKeyboard.Alt_Button_Cycle_Nature]: [ `KEY ${Button.CYCLE_NATURE.toString()}`, pressAction ], - [SettingKeyboard.Button_Cycle_Variant]: [ `KEY ${Button.V.toString()}`, pressAction ], - [SettingKeyboard.Alt_Button_Cycle_Variant]: [ `KEY ${Button.V.toString()}`, pressAction ], + [SettingKeyboard.Button_Cycle_Tera]: [ `KEY ${Button.CYCLE_TERA.toString()}`, pressAction ], + [SettingKeyboard.Alt_Button_Cycle_Tera]: [ `KEY ${Button.CYCLE_TERA.toString()}`, pressAction ], [SettingKeyboard.Button_Speed_Up]: [ `KEY ${Button.SPEED_UP.toString()}`, pressAction ], [SettingKeyboard.Alt_Button_Speed_Up]: [ `KEY ${Button.SPEED_UP.toString()}`, pressAction ], [SettingKeyboard.Button_Slow_Down]: [ `KEY ${Button.SLOW_DOWN.toString()}`, pressAction ], @@ -112,8 +112,8 @@ export const settingKeyboardDefaults = { [SettingKeyboard.Alt_Button_Cycle_Ability]: 0, [SettingKeyboard.Button_Cycle_Nature]: 0, [SettingKeyboard.Alt_Button_Cycle_Nature]: 0, - [SettingKeyboard.Button_Cycle_Variant]: 0, - [SettingKeyboard.Alt_Button_Cycle_Variant]: 0, + [SettingKeyboard.Button_Cycle_Tera]: 0, + [SettingKeyboard.Alt_Button_Cycle_Tera]: 0, [SettingKeyboard.Button_Speed_Up]: 0, [SettingKeyboard.Alt_Button_Speed_Up]: 0, [SettingKeyboard.Button_Slow_Down]: 0, @@ -148,7 +148,7 @@ export function setSettingKeyboard(setting: SettingKeyboard, value: number): boo case SettingKeyboard.Button_Cycle_Gender: case SettingKeyboard.Button_Cycle_Ability: case SettingKeyboard.Button_Cycle_Nature: - case SettingKeyboard.Button_Cycle_Variant: + case SettingKeyboard.Button_Cycle_Tera: case SettingKeyboard.Button_Speed_Up: case SettingKeyboard.Button_Slow_Down: case SettingKeyboard.Alt_Button_Up: @@ -164,7 +164,7 @@ export function setSettingKeyboard(setting: SettingKeyboard, value: number): boo case SettingKeyboard.Alt_Button_Cycle_Gender: case SettingKeyboard.Alt_Button_Cycle_Ability: case SettingKeyboard.Alt_Button_Cycle_Nature: - case SettingKeyboard.Alt_Button_Cycle_Variant: + case SettingKeyboard.Alt_Button_Cycle_Tera: case SettingKeyboard.Alt_Button_Speed_Up: case SettingKeyboard.Alt_Button_Slow_Down: case SettingKeyboard.Alt_Button_Submit: diff --git a/src/test/settingMenu/rebinding_setting.test.ts b/src/test/settingMenu/rebinding_setting.test.ts index cae2df363d8..46a37f4e137 100644 --- a/src/test/settingMenu/rebinding_setting.test.ts +++ b/src/test/settingMenu/rebinding_setting.test.ts @@ -406,9 +406,9 @@ describe("Test Rebinding", () => { }); it("check to delete all the binds of an action", () => { - inGame.whenWePressOnKeyboard("V").weShouldTriggerTheButton("Button_Cycle_Variant"); - inTheSettingMenu.whenCursorIsOnSetting("Alt_Button_Cycle_Variant").thereShouldBeNoIcon().weWantThisBindInstead("K").confirm(); - inTheSettingMenu.whenCursorIsOnSetting("Alt_Button_Cycle_Variant").iconDisplayedIs("KEY_K").whenWeDelete().thereShouldBeNoIconAnymore(); - inTheSettingMenu.whenCursorIsOnSetting("Button_Cycle_Variant").iconDisplayedIs("KEY_V").whenWeDelete().thereShouldBeNoIconAnymore(); + inGame.whenWePressOnKeyboard("V").weShouldTriggerTheButton("Button_Cycle_Tera"); + inTheSettingMenu.whenCursorIsOnSetting("Alt_Button_Cycle_Tera").thereShouldBeNoIcon().weWantThisBindInstead("K").confirm(); + inTheSettingMenu.whenCursorIsOnSetting("Alt_Button_Cycle_Tera").iconDisplayedIs("KEY_K").whenWeDelete().thereShouldBeNoIconAnymore(); + inTheSettingMenu.whenCursorIsOnSetting("Button_Cycle_Tera").iconDisplayedIs("KEY_V").whenWeDelete().thereShouldBeNoIconAnymore(); }); }); diff --git a/src/test/utils/fakeMobile.html b/src/test/utils/fakeMobile.html index 4b566d592d9..263b03969d4 100644 --- a/src/test/utils/fakeMobile.html +++ b/src/test/utils/fakeMobile.html @@ -35,7 +35,7 @@
R
-
+
V
@@ -59,7 +59,7 @@
N
-
+
V
diff --git a/src/ui-inputs.ts b/src/ui-inputs.ts index e6a0ed7a69c..951aec2a3b6 100644 --- a/src/ui-inputs.ts +++ b/src/ui-inputs.ts @@ -86,7 +86,7 @@ export class UiInputs { [Button.CYCLE_GENDER]: () => this.buttonCycleOption(Button.CYCLE_GENDER), [Button.CYCLE_ABILITY]: () => this.buttonCycleOption(Button.CYCLE_ABILITY), [Button.CYCLE_NATURE]: () => this.buttonCycleOption(Button.CYCLE_NATURE), - [Button.V]: () => this.buttonCycleOption(Button.V), + [Button.CYCLE_TERA]: () => this.buttonCycleOption(Button.CYCLE_TERA), [Button.SPEED_UP]: () => this.buttonSpeedChange(), [Button.SLOW_DOWN]: () => this.buttonSpeedChange(false), }; @@ -109,7 +109,7 @@ export class UiInputs { [Button.CYCLE_GENDER]: () => undefined, [Button.CYCLE_ABILITY]: () => undefined, [Button.CYCLE_NATURE]: () => undefined, - [Button.V]: () => this.buttonInfo(false), + [Button.CYCLE_TERA]: () => undefined, [Button.SPEED_UP]: () => undefined, [Button.SLOW_DOWN]: () => undefined, }; @@ -197,7 +197,7 @@ export class UiInputs { const uiHandler = globalScene.ui?.getHandler(); if (whitelist.some(handler => uiHandler instanceof handler)) { globalScene.ui.processInput(button); - } else if (button === Button.V) { + } else if (button === Button.CYCLE_TERA) { this.buttonInfo(true); } } diff --git a/src/ui/pokedex-ui-handler.ts b/src/ui/pokedex-ui-handler.ts index 5180d7bd956..1ba1b846224 100644 --- a/src/ui/pokedex-ui-handler.ts +++ b/src/ui/pokedex-ui-handler.ts @@ -919,7 +919,7 @@ export default class PokedexUiHandler extends MessageUiHandler { } else { error = true; } - } else if (button === Button.V) { + } else if (button === Button.CYCLE_TERA) { if (!this.filterTextMode && !this.showingTray) { this.cursorObj.setVisible(false); this.setSpecies(null); @@ -1170,9 +1170,6 @@ export default class PokedexUiHandler extends MessageUiHandler { case SettingKeyboard.Button_Cycle_Shiny: iconPath = "R.png"; break; - case SettingKeyboard.Button_Cycle_Variant: - iconPath = "V.png"; - break; case SettingKeyboard.Button_Cycle_Form: iconPath = "F.png"; break; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index b919679be00..a102fc9dc08 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -56,6 +56,8 @@ import { getPassiveCandyCount, getValueReductionCandyCounts, getSameSpeciesEggCa import { BooleanHolder, fixedInt, getLocalizedSpriteKey, isNullOrUndefined, NumberHolder, padInt, randIntRange, rgbHexToRgba, toReadableString } from "#app/utils"; import type { Nature } from "#enums/nature"; import { PLAYER_PARTY_MAX_SIZE } from "#app/constants"; +import { achvs } from "#app/system/achv"; +import * as Utils from "../utils"; export type StarterSelectCallback = (starters: Starter[]) => void; @@ -68,6 +70,7 @@ export interface Starter { moveset?: StarterMoveset; pokerus: boolean; nickname?: string; + teraType?: Type; } interface LanguageSetting { @@ -212,6 +215,7 @@ interface SpeciesDetails { abilityIndex?: number, natureIndex?: number, forSeen?: boolean, // default = false + teraType?: Type, } export default class StarterSelectUiHandler extends MessageUiHandler { @@ -262,6 +266,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { private pokemonShinyIcon: Phaser.GameObjects.Sprite; private pokemonPassiveDisabledIcon: Phaser.GameObjects.Sprite; private pokemonPassiveLockedIcon: Phaser.GameObjects.Sprite; + private teraIcon: Phaser.GameObjects.Sprite; private activeTooltip: "ABILITY" | "PASSIVE" | "CANDY" | undefined; private instructionsContainer: Phaser.GameObjects.Container; @@ -271,12 +276,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { private abilityIconElement: Phaser.GameObjects.Sprite; private genderIconElement: Phaser.GameObjects.Sprite; private natureIconElement: Phaser.GameObjects.Sprite; + private teraIconElement: Phaser.GameObjects.Sprite; private goFilterIconElement: Phaser.GameObjects.Sprite; private shinyLabel: Phaser.GameObjects.Text; private formLabel: Phaser.GameObjects.Text; private genderLabel: Phaser.GameObjects.Text; private abilityLabel: Phaser.GameObjects.Text; private natureLabel: Phaser.GameObjects.Text; + private teraLabel: Phaser.GameObjects.Text; private goFilterLabel: Phaser.GameObjects.Text; private starterSelectMessageBox: Phaser.GameObjects.NineSlice; @@ -292,6 +299,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { private dexAttrCursor: bigint = 0n; private abilityCursor: number = -1; private natureCursor: number = -1; + private teraCursor: Type = Type.UNKNOWN; private filterBarCursor: number = 0; private starterMoveset: StarterMoveset | null; private scrollCursor: number; @@ -304,6 +312,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { private starterAttr: bigint[] = []; private starterAbilityIndexes: number[] = []; private starterNatures: Nature[] = []; + private starterTeras: Type[] = []; private starterMovesets: StarterMoveset[] = []; private speciesStarterDexEntry: DexEntry | null; private speciesStarterMoves: Moves[]; @@ -312,6 +321,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { private canCycleGender: boolean; private canCycleAbility: boolean; private canCycleNature: boolean; + private canCycleTera: boolean; private assetLoadCancelled: BooleanHolder | null; public cursorObj: Phaser.GameObjects.Image; @@ -823,6 +833,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterSelectContainer.add(this.pokemonEggMovesContainer); + this.teraIcon = globalScene.add.sprite(85, 63, "button_tera"); + this.teraIcon.setName("terrastallize-icon"); + this.teraIcon.setFrame("fire"); + this.starterSelectContainer.add(this.teraIcon); + // The font size should be set per language const instructionTextSize = textSettings.instructionTextSize; @@ -867,6 +882,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.natureLabel = addTextObject(this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleNature"), TextStyle.PARTY, { fontSize: instructionTextSize }); this.natureLabel.setName("text-nature-label"); + this.teraIconElement = new Phaser.GameObjects.Sprite(globalScene, this.instructionRowX, this.instructionRowY, "keyboard", "V.png"); + this.teraIconElement.setName("sprite-tera-icon-element"); + this.teraIconElement.setScale(0.675); + this.teraIconElement.setOrigin(0.0, 0.0); + this.teraLabel = addTextObject(this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleTera"), TextStyle.PARTY, { fontSize: instructionTextSize }); + this.teraLabel.setName("text-tera-label"); + this.goFilterIconElement = new Phaser.GameObjects.Sprite(globalScene, this.filterInstructionRowX, this.filterInstructionRowY, "keyboard", "C.png"); this.goFilterIconElement.setName("sprite-goFilter-icon-element"); this.goFilterIconElement.setScale(0.675); @@ -1497,6 +1519,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const props = globalScene.gameData.getSpeciesDexAttrProps(randomSpecies, dexAttr); const abilityIndex = this.abilityCursor; const nature = this.natureCursor as unknown as Nature; + const teraType = this.teraCursor; const moveset = this.starterMoveset?.slice(0) as StarterMoveset; const starterCost = globalScene.gameData.getSpeciesStarterValue(randomSpecies.speciesId); const speciesForm = getPokemonSpeciesForm(randomSpecies.speciesId, props.formIndex); @@ -1505,7 +1528,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { .loadAssets(props.female, props.formIndex, props.shiny, props.variant, true) .then(() => { if (this.tryUpdateValue(starterCost, true)) { - this.addToParty(randomSpecies, dexAttr, abilityIndex, nature, moveset, true); + this.addToParty(randomSpecies, dexAttr, abilityIndex, nature, moveset, teraType, true); ui.playSelect(); } }); @@ -1585,7 +1608,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const cursorObj = this.starterCursorObjs[this.starterSpecies.length]; cursorObj.setVisible(true); cursorObj.setPosition(this.cursorObj.x, this.cursorObj.y); - this.addToParty(this.lastSpecies, this.dexAttrCursor, this.abilityCursor, this.natureCursor as unknown as Nature, this.starterMoveset?.slice(0) as StarterMoveset); + this.addToParty(this.lastSpecies, this.dexAttrCursor, this.abilityCursor, this.natureCursor as unknown as Nature, this.starterMoveset?.slice(0) as StarterMoveset, this.teraCursor); ui.playSelect(); } else { ui.playError(); // this should be redundant as there is now a trigger for when a pokemon can't be added to party @@ -2066,7 +2089,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } } while (newFormIndex !== props.formIndex); starterAttributes.form = newFormIndex; // store the selected form - this.setSpeciesDetails(this.lastSpecies, { formIndex: newFormIndex }); + starterAttributes.tera = this.lastSpecies.forms[newFormIndex].type1; + this.setSpeciesDetails(this.lastSpecies, { formIndex: newFormIndex, teraType: starterAttributes.tera }); success = true; } break; @@ -2125,6 +2149,19 @@ export default class StarterSelectUiHandler extends MessageUiHandler { success = true; } break; + case Button.CYCLE_TERA: + if (this.canCycleTera) { + const speciesForm = getPokemonSpeciesForm(this.lastSpecies.speciesId, starterAttributes.form ?? 0); + if (speciesForm.type1 === this.teraCursor && !Utils.isNullOrUndefined(speciesForm.type2)) { + starterAttributes.tera = speciesForm.type2!; + this.setSpeciesDetails(this.lastSpecies, { teraType: speciesForm.type2! }); + } else { + starterAttributes.tera = speciesForm.type1; + this.setSpeciesDetails(this.lastSpecies, { teraType: speciesForm.type1 }); + } + success = true; + } + break; case Button.UP: if (!this.starterIconsCursorObj.visible) { if (currentRow > 0) { @@ -2289,7 +2326,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { return [ isDupe, removeIndex ]; } - addToParty(species: PokemonSpecies, dexAttr: bigint, abilityIndex: number, nature: Nature, moveset: StarterMoveset, randomSelection: boolean = false) { + addToParty(species: PokemonSpecies, dexAttr: bigint, abilityIndex: number, nature: Nature, moveset: StarterMoveset, teraType: Type, randomSelection: boolean = false) { const props = globalScene.gameData.getSpeciesDexAttrProps(species, dexAttr); this.starterIcons[this.starterSpecies.length].setTexture(species.getIconAtlasKey(props.formIndex, props.shiny, props.variant)); this.starterIcons[this.starterSpecies.length].setFrame(species.getIconId(props.female, props.formIndex, props.shiny, props.variant)); @@ -2299,6 +2336,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterAttr.push(dexAttr); this.starterAbilityIndexes.push(abilityIndex); this.starterNatures.push(nature); + this.starterTeras.push(teraType); this.starterMovesets.push(moveset); if (this.speciesLoaded.get(species.speciesId) || randomSelection ) { getPokemonSpeciesForm(species.speciesId, props.formIndex).cry(); @@ -2379,6 +2417,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { case SettingKeyboard.Button_Cycle_Nature: iconPath = "N.png"; break; + case SettingKeyboard.Button_Cycle_Tera: + iconPath = "V.png"; + break; case SettingKeyboard.Button_Stats: iconPath = "C.png"; break; @@ -2459,6 +2500,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (this.canCycleNature) { this.updateButtonIcon(SettingKeyboard.Button_Cycle_Nature, gamepadType, this.natureIconElement, this.natureLabel); } + if (this.canCycleTera) { + this.updateButtonIcon(SettingKeyboard.Button_Cycle_Tera, gamepadType, this.teraIconElement, this.teraLabel); + } } // if filter mode is inactivated and gamepadType is not undefined, update the button icons @@ -2876,6 +2920,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.dexAttrCursor = species ? this.getCurrentDexProps(species.speciesId) : 0n; this.abilityCursor = species ? globalScene.gameData.getStarterSpeciesDefaultAbilityIndex(species) : 0; this.natureCursor = species ? globalScene.gameData.getSpeciesDefaultNature(species) : 0; + this.teraCursor = species ? species.type1 : Type.UNKNOWN; if (!species && globalScene.ui.getTooltip().visible) { globalScene.ui.hideTooltip(); @@ -2894,6 +2939,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { // load default ability from stater save data, if set this.abilityCursor = starterAttributes.ability; } + if (starterAttributes?.tera) { + // load default tera from starter save data, if set + this.teraCursor = starterAttributes.tera; + } if (this.statsMode) { if (this.speciesStarterDexEntry?.caughtAttr) { @@ -3035,7 +3084,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { female: props.female, variant: props.variant, abilityIndex: this.starterAbilityIndexes[starterIndex], - natureIndex: this.starterNatures[starterIndex] + natureIndex: this.starterNatures[starterIndex], + teraType: this.starterTeras[starterIndex] }); } else { const defaultDexAttr = this.getCurrentDexProps(species.speciesId); @@ -3083,6 +3133,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonCaughtHatchedContainer.setVisible(false); this.pokemonCandyContainer.setVisible(false); this.pokemonFormText.setVisible(false); + this.teraIcon.setVisible(false); const defaultDexAttr = globalScene.gameData.getSpeciesDefaultDexAttr(species, true, true); const defaultAbilityIndex = globalScene.gameData.getStarterSpeciesDefaultAbilityIndex(species); @@ -3117,6 +3168,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonCaughtHatchedContainer.setVisible(false); this.pokemonCandyContainer.setVisible(false); this.pokemonFormText.setVisible(false); + this.teraIcon.setVisible(false); this.setSpeciesDetails(species!, { // TODO: is this bang correct? shiny: false, @@ -3131,7 +3183,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } setSpeciesDetails(species: PokemonSpecies, options: SpeciesDetails = {}): void { - let { shiny, formIndex, female, variant, abilityIndex, natureIndex } = options; + let { shiny, formIndex, female, variant, abilityIndex, natureIndex, teraType } = options; const forSeen: boolean = options.forSeen ?? false; const oldProps = species ? globalScene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor) : null; const oldAbilityIndex = this.abilityCursor > -1 ? this.abilityCursor : globalScene.gameData.getStarterSpeciesDefaultAbilityIndex(species); @@ -3139,6 +3191,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.dexAttrCursor = 0n; this.abilityCursor = -1; this.natureCursor = -1; + this.teraCursor = Type.UNKNOWN; // We will only update the sprite if there is a change to form, shiny/variant // or gender for species with gender sprite differences const shouldUpdateSprite = (species?.genderDiffs && !isNullOrUndefined(female)) @@ -3168,6 +3221,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.dexAttrCursor |= globalScene.gameData.getFormAttr(formIndex !== undefined ? formIndex : (formIndex = oldProps!.formIndex)); // TODO: is this bang correct? this.abilityCursor = abilityIndex !== undefined ? abilityIndex : (abilityIndex = oldAbilityIndex); this.natureCursor = natureIndex !== undefined ? natureIndex : (natureIndex = oldNatureIndex); + this.teraCursor = !Utils.isNullOrUndefined(teraType) ? teraType : (teraType = species.type1); const [ isInParty, partyIndex ]: [boolean, number] = this.isInParty(species); // we use this to firstly check if the pokemon is in the party, and if so, to get the party index in order to update the icon image if (isInParty) { this.updatePartyIcon(species, partyIndex); @@ -3179,6 +3233,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonPassiveText.setVisible(false); this.pokemonPassiveDisabledIcon.setVisible(false); this.pokemonPassiveLockedIcon.setVisible(false); + this.teraIcon.setVisible(false); if (this.assetLoadCancelled) { this.assetLoadCancelled.value = true; @@ -3230,6 +3285,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterAttr[starterIndex] = this.dexAttrCursor; this.starterAbilityIndexes[starterIndex] = this.abilityCursor; this.starterNatures[starterIndex] = this.natureCursor; + this.starterTeras[starterIndex] = this.teraCursor; } const assetLoadCancelled = new BooleanHolder(false); @@ -3288,7 +3344,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.canCycleForm = species.forms.filter(f => f.isStarterSelectable || !pokemonFormChanges[species.speciesId]?.find(fc => fc.formKey)) .map((_, f) => dexEntry.caughtAttr & globalScene.gameData.getFormAttr(f)).filter(f => f).length > 1; this.canCycleNature = globalScene.gameData.getNaturesForAttr(dexEntry.natureAttr).length > 1; - + this.canCycleTera = globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) && !Utils.isNullOrUndefined(getPokemonSpeciesForm(species.speciesId, formIndex ?? 0).type2); } if (dexEntry.caughtAttr && species.malePercent !== null) { @@ -3412,10 +3468,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonFormText.setText(formText); this.setTypeIcons(speciesForm.type1, speciesForm.type2); + + this.teraIcon.setFrame(Type[this.teraCursor].toLowerCase()); + this.teraIcon.setVisible(!this.statsMode && globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id)); } else { this.pokemonAbilityText.setText(""); this.pokemonPassiveText.setText(""); this.pokemonNatureText.setText(""); + this.teraIcon.setVisible(false); this.setTypeIcons(null, null); } } else { @@ -3426,6 +3486,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonAbilityText.setText(""); this.pokemonPassiveText.setText(""); this.pokemonNatureText.setText(""); + this.teraIcon.setVisible(false); this.setTypeIcons(null, null); } @@ -3479,6 +3540,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.starterAttr.splice(index, 1); this.starterAbilityIndexes.splice(index, 1); this.starterNatures.splice(index, 1); + this.starterTeras.splice(index, 1); this.starterMovesets.splice(index, 1); for (let s = 0; s < this.starterSpecies.length; s++) { @@ -3690,6 +3752,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { abilityIndex: thisObj.starterAbilityIndexes[i], passive: !(globalScene.gameData.starterData[starterSpecies.speciesId].passiveAttr ^ (PassiveAttr.ENABLED | PassiveAttr.UNLOCKED)), nature: thisObj.starterNatures[i] as Nature, + teraType: thisObj.starterTeras[i] as Type, moveset: thisObj.starterMovesets[i], pokerus: thisObj.pokerusSpecies.includes(starterSpecies), nickname: thisObj.starterPreferences[starterSpecies.speciesId]?.nickname, @@ -3816,6 +3879,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.abilityLabel.setVisible(false); this.natureIconElement.setVisible(false); this.natureLabel.setVisible(false); + this.teraIconElement.setVisible(false); + this.teraLabel.setVisible(false); this.goFilterIconElement.setVisible(false); this.goFilterLabel.setVisible(false); }