[Refactor] Add support for showing separate species form names (#5294)
* Support for localization of regional form names * Show names of regional and other forms where appropriate * Add form name to evolution screen * Remove formKey parameter * Update docstrings * More SpeciesFormKey Co-authored-by: Wlowscha <54003515+Wlowscha@users.noreply.github.com> * Clean up * Fix inconsistent key name --------- Co-authored-by: Wlowscha <54003515+Wlowscha@users.noreply.github.com>
This commit is contained in:
parent
b31d5fd23e
commit
7fea8603f3
|
@ -690,6 +690,56 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the name of species with proper attachments for regionals and separate starter forms (Floette, Ursaluna)
|
||||||
|
* @returns a string with the region name or other form name attached
|
||||||
|
*/
|
||||||
|
getExpandedSpeciesName(): string {
|
||||||
|
if (this.speciesId < 2000) {
|
||||||
|
return this.name; // Other special cases could be put here too
|
||||||
|
} else { // Everything beyond this point essentially follows the pattern of FORMNAME_SPECIES
|
||||||
|
return i18next.t(`pokemonForm:appendForm.${Species[this.speciesId].split("_")[0]}`, { pokemonName: this.name });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the form name for species with just one form (regional variants, Floette, Ursaluna)
|
||||||
|
* @param formIndex The form index to check (defaults to 0)
|
||||||
|
* @param append Whether to append the species name to the end (defaults to false)
|
||||||
|
* @returns the pokemon-form locale key for the single form name ("Alolan Form", "Eternal Flower" etc)
|
||||||
|
*/
|
||||||
|
getFormNameToDisplay(formIndex: number = 0, append: boolean = false): string {
|
||||||
|
const formKey = this.forms?.[formIndex!]?.formKey;
|
||||||
|
const formText = Utils.capitalizeString(formKey, "-", false, false) || "";
|
||||||
|
const speciesName = Utils.capitalizeString(Species[this.speciesId], "_", true, false);
|
||||||
|
let ret: string = "";
|
||||||
|
|
||||||
|
const region = this.getRegion();
|
||||||
|
if (this.speciesId === Species.ARCEUS) {
|
||||||
|
ret = i18next.t(`pokemonInfo:Type.${formText?.toUpperCase()}`);
|
||||||
|
} else if ([ SpeciesFormKey.MEGA, SpeciesFormKey.MEGA_X, SpeciesFormKey.MEGA_Y, SpeciesFormKey.PRIMAL, SpeciesFormKey.GIGANTAMAX, SpeciesFormKey.GIGANTAMAX_RAPID, SpeciesFormKey.GIGANTAMAX_SINGLE, SpeciesFormKey.ETERNAMAX ].includes(formKey as SpeciesFormKey)) {
|
||||||
|
return i18next.t(`battlePokemonForm:${formKey}`, { pokemonName: (append ? this.name : "") });
|
||||||
|
} else if (region === Region.NORMAL || (this.speciesId === Species.GALAR_DARMANITAN && formIndex > 0) || this.speciesId === Species.PALDEA_TAUROS) { // More special cases can be added here
|
||||||
|
const i18key = `pokemonForm:${speciesName}${formText}`;
|
||||||
|
if (i18next.exists(i18key)) {
|
||||||
|
ret = i18next.t(i18key);
|
||||||
|
} else {
|
||||||
|
const rootSpeciesName = Utils.capitalizeString(Species[this.getRootSpeciesId()], "_", true, false);
|
||||||
|
const i18RootKey = `pokemonForm:${rootSpeciesName}${formText}`;
|
||||||
|
ret = i18next.exists(i18RootKey) ? i18next.t(i18RootKey) : formText;
|
||||||
|
}
|
||||||
|
} else if (append) { // Everything beyond this has an expanded name
|
||||||
|
return this.getExpandedSpeciesName();
|
||||||
|
} else if (this.speciesId === Species.ETERNAL_FLOETTE) { // Not a real form, so the key is made up
|
||||||
|
return i18next.t("pokemonForm:floetteEternalFlower");
|
||||||
|
} else if (this.speciesId === Species.BLOODMOON_URSALUNA) { // Not a real form, so the key is made up
|
||||||
|
return i18next.t("pokemonForm:ursalunaBloodmoon");
|
||||||
|
} else { // Only regional forms should be left at this point
|
||||||
|
return i18next.t(`pokemonForm:regionalForm.${Region[region]}`);
|
||||||
|
}
|
||||||
|
return append ? i18next.t("pokemonForm:appendForm.GENERIC", { pokemonName: this.name, formName: ret }) : ret;
|
||||||
|
}
|
||||||
|
|
||||||
localize(): void {
|
localize(): void {
|
||||||
this.name = i18next.t(`pokemon:${Species[this.speciesId].toLowerCase()}`);
|
this.name = i18next.t(`pokemon:${Species[this.speciesId].toLowerCase()}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { globalScene } from "#app/global-scene";
|
||||||
import type { Egg } from "#app/data/egg";
|
import type { Egg } from "#app/data/egg";
|
||||||
import { EggCountChangedEvent } from "#app/events/egg";
|
import { EggCountChangedEvent } from "#app/events/egg";
|
||||||
import type { PlayerPokemon } from "#app/field/pokemon";
|
import type { PlayerPokemon } from "#app/field/pokemon";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
|
||||||
import { Phase } from "#app/phase";
|
import { Phase } from "#app/phase";
|
||||||
import { achvs } from "#app/system/achv";
|
import { achvs } from "#app/system/achv";
|
||||||
import EggCounterContainer from "#app/ui/egg-counter-container";
|
import EggCounterContainer from "#app/ui/egg-counter-container";
|
||||||
|
@ -356,7 +355,7 @@ export class EggHatchPhase extends Phase {
|
||||||
|
|
||||||
globalScene.playSoundWithoutBgm("evolution_fanfare");
|
globalScene.playSoundWithoutBgm("evolution_fanfare");
|
||||||
|
|
||||||
globalScene.ui.showText(i18next.t("egg:hatchFromTheEgg", { pokemonName: getPokemonNameWithAffix(this.pokemon) }), null, () => {
|
globalScene.ui.showText(i18next.t("egg:hatchFromTheEgg", { pokemonName: this.pokemon.species.getExpandedSpeciesName() }), null, () => {
|
||||||
globalScene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
|
globalScene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
|
||||||
globalScene.gameData.setPokemonCaught(this.pokemon, true, true).then(() => {
|
globalScene.gameData.setPokemonCaught(this.pokemon, true, true).then(() => {
|
||||||
globalScene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex).then((value) => {
|
globalScene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex).then((value) => {
|
||||||
|
|
|
@ -270,7 +270,7 @@ export class EvolutionPhase extends Phase {
|
||||||
globalScene.playSoundWithoutBgm("evolution_fanfare");
|
globalScene.playSoundWithoutBgm("evolution_fanfare");
|
||||||
|
|
||||||
evolvedPokemon.destroy();
|
evolvedPokemon.destroy();
|
||||||
globalScene.ui.showText(i18next.t("menu:evolutionDone", { pokemonName: this.preEvolvedPokemonName, evolvedPokemonName: this.pokemon.name }), null, () => this.end(), null, true, Utils.fixedInt(4000));
|
globalScene.ui.showText(i18next.t("menu:evolutionDone", { pokemonName: this.preEvolvedPokemonName, evolvedPokemonName: this.pokemon.species.getExpandedSpeciesName() }), null, () => this.end(), null, true, Utils.fixedInt(4000));
|
||||||
globalScene.time.delayedCall(Utils.fixedInt(4250), () => globalScene.playBgm());
|
globalScene.time.delayedCall(Utils.fixedInt(4250), () => globalScene.playBgm());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,7 +15,6 @@ import type { SpeciesFormChange } from "#app/data/pokemon-forms";
|
||||||
import { pokemonFormChanges } from "#app/data/pokemon-forms";
|
import { pokemonFormChanges } from "#app/data/pokemon-forms";
|
||||||
import type { LevelMoves } from "#app/data/balance/pokemon-level-moves";
|
import type { LevelMoves } from "#app/data/balance/pokemon-level-moves";
|
||||||
import { pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "#app/data/balance/pokemon-level-moves";
|
import { pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "#app/data/balance/pokemon-level-moves";
|
||||||
import type { PokemonForm } from "#app/data/pokemon-species";
|
|
||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
import type PokemonSpecies from "#app/data/pokemon-species";
|
||||||
import { allSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
import { allSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
||||||
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
|
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
|
@ -44,7 +43,7 @@ import { Species } from "#enums/species";
|
||||||
import { Button } from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
import { EggSourceType } from "#enums/egg-source-types";
|
import { EggSourceType } from "#enums/egg-source-types";
|
||||||
import { getPassiveCandyCount, getValueReductionCandyCounts, getSameSpeciesEggCandyCounts } from "#app/data/balance/starters";
|
import { getPassiveCandyCount, getValueReductionCandyCounts, getSameSpeciesEggCandyCounts } from "#app/data/balance/starters";
|
||||||
import { BooleanHolder, capitalizeString, getLocalizedSpriteKey, isNullOrUndefined, NumberHolder, padInt, rgbHexToRgba, toReadableString } from "#app/utils";
|
import { BooleanHolder, getLocalizedSpriteKey, isNullOrUndefined, NumberHolder, padInt, rgbHexToRgba, toReadableString } from "#app/utils";
|
||||||
import type { Nature } from "#enums/nature";
|
import type { Nature } from "#enums/nature";
|
||||||
import BgmBar from "./bgm-bar";
|
import BgmBar from "./bgm-bar";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
|
@ -899,43 +898,6 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Assign a form string to a given species and form
|
|
||||||
* @param formKey the form to format
|
|
||||||
* @param species the species to format
|
|
||||||
* @param speciesId whether the name of the species should be shown at the end
|
|
||||||
* @returns the formatted string
|
|
||||||
*/
|
|
||||||
getFormString(formKey: string, species: PokemonSpecies, append: boolean = false): string {
|
|
||||||
let label: string;
|
|
||||||
const formText = capitalizeString(formKey, "-", false, false) ?? "";
|
|
||||||
const speciesName = capitalizeString(this.getStarterSpecies(species).name, "_", true, false) ?? "";
|
|
||||||
if (species.speciesId === Species.ARCEUS) {
|
|
||||||
label = i18next.t(`pokemonInfo:Type.${formText?.toUpperCase()}`);
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
label = formText ? i18next.t(`pokemonForm:${speciesName}${formText}`) : "";
|
|
||||||
if (label === `${speciesName}${formText}`) {
|
|
||||||
label = i18next.t(`battlePokemonForm:${formKey}`, { pokemonName:species.name });
|
|
||||||
} else {
|
|
||||||
// If the label is only the form, we can append the name of the pokemon
|
|
||||||
label += append ? ` ${species.name}` : "";
|
|
||||||
}
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the name of the region for regional species
|
|
||||||
* @param species the species to check
|
|
||||||
* @returns a string with the region name
|
|
||||||
*/
|
|
||||||
getRegionName(species: PokemonSpecies): string {
|
|
||||||
const name = species.name;
|
|
||||||
const label = Species[species.speciesId];
|
|
||||||
const suffix = label.includes("_") ? " (" + label.split("_")[0].toLowerCase() + ")" : "";
|
|
||||||
return name + suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
processInput(button: Button): boolean {
|
processInput(button: Button): boolean {
|
||||||
if (this.blockInput) {
|
if (this.blockInput) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1375,13 +1337,14 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||||
});
|
});
|
||||||
this.prevolutions.map(pre => {
|
this.prevolutions.map(pre => {
|
||||||
const preSpecies = allSpecies.find(species => species.speciesId === pokemonPrevolutions[this.species.speciesId]);
|
const preSpecies = allSpecies.find(species => species.speciesId === pokemonPrevolutions[this.species.speciesId]);
|
||||||
|
const preFormIndex: number = preSpecies?.forms.find(f => f.formKey === pre.preFormKey)?.formIndex ?? 0;
|
||||||
|
|
||||||
const conditionText: string = pre.description;
|
const conditionText: string = pre.description;
|
||||||
|
|
||||||
options.push({
|
options.push({
|
||||||
label: pre.preFormKey ?
|
label: pre.preFormKey ?
|
||||||
this.getFormString(pre.preFormKey, preSpecies ?? this.species, true) :
|
(preSpecies ?? this.species).getFormNameToDisplay(preFormIndex, true) :
|
||||||
this.getRegionName(preSpecies ?? this.species),
|
(preSpecies ?? this.species).getExpandedSpeciesName(),
|
||||||
handler: () => {
|
handler: () => {
|
||||||
const newSpecies = allSpecies.find(species => species.speciesId === pokemonPrevolutions[pre.speciesId]);
|
const newSpecies = allSpecies.find(species => species.speciesId === pokemonPrevolutions[pre.speciesId]);
|
||||||
// Attempts to find the formIndex of the prevolved species
|
// Attempts to find the formIndex of the prevolved species
|
||||||
|
@ -1421,8 +1384,8 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||||
|
|
||||||
options.push({
|
options.push({
|
||||||
label: evo.evoFormKey ?
|
label: evo.evoFormKey ?
|
||||||
this.getFormString(evo.evoFormKey, evoSpecies ?? this.species, true) :
|
(evoSpecies ?? this.species).getFormNameToDisplay(newFormIndex, true) :
|
||||||
this.getRegionName(evoSpecies ?? this.species),
|
(evoSpecies ?? this.species).getExpandedSpeciesName(),
|
||||||
style: isCaughtEvo && isFormCaughtEvo ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
style: isCaughtEvo && isFormCaughtEvo ? TextStyle.WINDOW : TextStyle.SHADOW_TEXT,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
this.starterAttributes.form = newFormIndex;
|
this.starterAttributes.form = newFormIndex;
|
||||||
|
@ -1445,6 +1408,8 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||||
handler: () => false
|
handler: () => false
|
||||||
});
|
});
|
||||||
this.battleForms.map(bf => {
|
this.battleForms.map(bf => {
|
||||||
|
const matchingForm = this.species?.forms.find(form => form.formKey === bf.formKey);
|
||||||
|
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
||||||
|
|
||||||
let conditionText:string = "";
|
let conditionText:string = "";
|
||||||
if (bf.trigger) {
|
if (bf.trigger) {
|
||||||
|
@ -1452,12 +1417,10 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||||
} else {
|
} else {
|
||||||
conditionText = "";
|
conditionText = "";
|
||||||
}
|
}
|
||||||
let label: string = this.getFormString(bf.formKey, this.species);
|
let label: string = this.species.getFormNameToDisplay(newFormIndex);
|
||||||
if (label === "") {
|
if (label === "") {
|
||||||
label = this.species.name;
|
label = this.species.name;
|
||||||
}
|
}
|
||||||
const matchingForm = this.species?.forms.find(form => form.formKey === bf.formKey);
|
|
||||||
const newFormIndex = matchingForm ? matchingForm.formIndex : 0;
|
|
||||||
const isFormCaught = this.isFormCaught(this.species, newFormIndex);
|
const isFormCaught = this.isFormCaught(this.species, newFormIndex);
|
||||||
|
|
||||||
if (conditionText) {
|
if (conditionText) {
|
||||||
|
@ -2313,7 +2276,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||||
if (isFormCaught || isFormSeen) {
|
if (isFormCaught || isFormSeen) {
|
||||||
const speciesForm = getPokemonSpeciesForm(species.speciesId, formIndex!); // TODO: is the bang correct?
|
const speciesForm = getPokemonSpeciesForm(species.speciesId, formIndex!); // TODO: is the bang correct?
|
||||||
this.setTypeIcons(speciesForm.type1, speciesForm.type2);
|
this.setTypeIcons(speciesForm.type1, speciesForm.type2);
|
||||||
this.pokemonFormText.setText(this.getFormString((speciesForm as PokemonForm).formKey, species));
|
this.pokemonFormText.setText(species.getFormNameToDisplay(formIndex));
|
||||||
this.pokemonFormText.setVisible(true);
|
this.pokemonFormText.setVisible(true);
|
||||||
if (!isFormCaught) {
|
if (!isFormCaught) {
|
||||||
this.pokemonFormText.setY(18);
|
this.pokemonFormText.setY(18);
|
||||||
|
|
|
@ -13,7 +13,6 @@ import ConfirmUiHandler from "./confirm-ui-handler";
|
||||||
import { StatsContainer } from "./stats-container";
|
import { StatsContainer } from "./stats-container";
|
||||||
import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor } from "./text";
|
import { TextStyle, addBBCodeTextObject, addTextObject, getTextColor } from "./text";
|
||||||
import { addWindow } from "./ui-theme";
|
import { addWindow } from "./ui-theme";
|
||||||
import { Species } from "#enums/species";
|
|
||||||
|
|
||||||
interface LanguageSetting {
|
interface LanguageSetting {
|
||||||
infoContainerTextSize: string;
|
infoContainerTextSize: string;
|
||||||
|
@ -218,23 +217,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container {
|
||||||
this.pokemonGenderText.setVisible(false);
|
this.pokemonGenderText.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const formKey = (pokemon.species?.forms?.[pokemon.formIndex!]?.formKey);
|
const formName = pokemon.species.getFormNameToDisplay(pokemon.formIndex);
|
||||||
const formText = Utils.capitalizeString(formKey, "-", false, false) || "";
|
|
||||||
const speciesName = Utils.capitalizeString(Species[pokemon.species.speciesId], "_", true, false);
|
|
||||||
|
|
||||||
let formName = "";
|
|
||||||
if (pokemon.species.speciesId === Species.ARCEUS) {
|
|
||||||
formName = i18next.t(`pokemonInfo:Type.${formText?.toUpperCase()}`);
|
|
||||||
} else {
|
|
||||||
const i18key = `pokemonForm:${speciesName}${formText}`;
|
|
||||||
if (i18next.exists(i18key)) {
|
|
||||||
formName = i18next.t(i18key);
|
|
||||||
} else {
|
|
||||||
const rootSpeciesName = Utils.capitalizeString(Species[pokemon.species.getRootSpeciesId()], "_", true, false);
|
|
||||||
const i18RootKey = `pokemonForm:${rootSpeciesName}${formText}`;
|
|
||||||
formName = i18next.exists(i18RootKey) ? i18next.t(i18RootKey) : formText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formName) {
|
if (formName) {
|
||||||
this.pokemonFormLabelText.setVisible(true);
|
this.pokemonFormLabelText.setVisible(true);
|
||||||
|
|
|
@ -53,7 +53,7 @@ import { EncounterPhase } from "#app/phases/encounter-phase";
|
||||||
import { TitlePhase } from "#app/phases/title-phase";
|
import { TitlePhase } from "#app/phases/title-phase";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { getPassiveCandyCount, getValueReductionCandyCounts, getSameSpeciesEggCandyCounts } from "#app/data/balance/starters";
|
import { getPassiveCandyCount, getValueReductionCandyCounts, getSameSpeciesEggCandyCounts } from "#app/data/balance/starters";
|
||||||
import { BooleanHolder, capitalizeString, fixedInt, getLocalizedSpriteKey, isNullOrUndefined, NumberHolder, padInt, randIntRange, rgbHexToRgba, toReadableString } from "#app/utils";
|
import { BooleanHolder, fixedInt, getLocalizedSpriteKey, isNullOrUndefined, NumberHolder, padInt, randIntRange, rgbHexToRgba, toReadableString } from "#app/utils";
|
||||||
import type { Nature } from "#enums/nature";
|
import type { Nature } from "#enums/nature";
|
||||||
import { PLAYER_PARTY_MAX_SIZE } from "#app/constants";
|
import { PLAYER_PARTY_MAX_SIZE } from "#app/constants";
|
||||||
|
|
||||||
|
@ -3408,15 +3408,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||||
}) as StarterMoveset;
|
}) as StarterMoveset;
|
||||||
|
|
||||||
const speciesForm = getPokemonSpeciesForm(species.speciesId, formIndex!); // TODO: is the bang correct?
|
const speciesForm = getPokemonSpeciesForm(species.speciesId, formIndex!); // TODO: is the bang correct?
|
||||||
const formText = capitalizeString(species?.forms[formIndex!]?.formKey, "-", false, false); // TODO: is the bang correct?
|
const formText = species.getFormNameToDisplay(formIndex);
|
||||||
|
this.pokemonFormText.setText(formText);
|
||||||
const speciesName = capitalizeString(Species[species.speciesId], "_", true, false);
|
|
||||||
|
|
||||||
if (species.speciesId === Species.ARCEUS) {
|
|
||||||
this.pokemonFormText.setText(i18next.t(`pokemonInfo:Type.${formText?.toUpperCase()}`));
|
|
||||||
} else {
|
|
||||||
this.pokemonFormText.setText(formText ? i18next.t(`pokemonForm:${speciesName}${formText}`) : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setTypeIcons(speciesForm.type1, speciesForm.type2);
|
this.setTypeIcons(speciesForm.type1, speciesForm.type2);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue