mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-19 22:09:27 +02:00
Fixed main repo code to not expect snake cased locale strings
This commit is contained in:
parent
d2b0a3147b
commit
6b98afa34f
@ -44,7 +44,10 @@ import { PokemonData } from "#system/pokemon-data";
|
|||||||
import { MusicPreference } from "#system/settings";
|
import { MusicPreference } from "#system/settings";
|
||||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||||
import { isNullOrUndefined, NumberHolder, randInt, randSeedInt, randSeedItem, randSeedShuffle } from "#utils/common";
|
import { isNullOrUndefined, NumberHolder, randInt, randSeedInt, randSeedItem, randSeedShuffle } from "#utils/common";
|
||||||
|
import { getEnumKeys } from "#utils/enums";
|
||||||
|
import { getRandomLocaleKey } from "#utils/i18n";
|
||||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||||
|
import { toCamelCase } from "#utils/strings";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
@ -984,14 +987,17 @@ function doTradeReceivedSequence(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function generateRandomTraderName() {
|
function generateRandomTraderName() {
|
||||||
const length = TrainerType.YOUNGSTER - TrainerType.ACE_TRAINER + 1;
|
const allTrainerNames = getEnumKeys(TrainerType);
|
||||||
// +1 avoids TrainerType.UNKNOWN
|
// Exclude TrainerType.UNKNOWN and everything after Ace Trainers (grunts and unique trainers)
|
||||||
const classKey = `trainersCommon:${TrainerType[randInt(length) + 1]}`;
|
const eligibleNames = allTrainerNames.slice(
|
||||||
// Some trainers have 2 gendered pools, some do not
|
1,
|
||||||
const genderKey = i18next.exists(`${classKey}.MALE`) ? (randInt(2) === 0 ? ".MALE" : ".FEMALE") : "";
|
allTrainerNames.indexOf(TrainerType[TrainerType.YOUNGSTER] as keyof typeof TrainerType),
|
||||||
const trainerNameKey = randSeedItem(Object.keys(i18next.t(`${classKey}${genderKey}`, { returnObjects: true })));
|
);
|
||||||
const trainerNameString = i18next.t(`${classKey}${genderKey}.${trainerNameKey}`);
|
const randomTrainer = toCamelCase(randSeedItem(eligibleNames));
|
||||||
// Some names have an '&' symbol and need to be trimmed to a single name instead of a double name
|
const classKey = `trainersCommon:${randomTrainer}`;
|
||||||
const trainerNames = trainerNameString.split(" & ");
|
// Pick a random gender for ones with gendered pools, or access the raw object for ones without.
|
||||||
return trainerNames[randInt(trainerNames.length)];
|
const genderKey = i18next.exists(`${classKey}.male`) ? randSeedItem([".male", ".female"]) : "";
|
||||||
|
const trainerNameString = getRandomLocaleKey(`${classKey}${genderKey}`)[1];
|
||||||
|
// Split the string by &s (for duo trainers)
|
||||||
|
return randSeedItem(trainerNameString.split(" & "));
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,11 @@ import type { PersistentModifier } from "#modifiers/modifier";
|
|||||||
import { getIsInitialized, initI18n } from "#plugins/i18n";
|
import { getIsInitialized, initI18n } from "#plugins/i18n";
|
||||||
import type { TrainerConfig } from "#trainers/trainer-config";
|
import type { TrainerConfig } from "#trainers/trainer-config";
|
||||||
import { trainerConfigs } from "#trainers/trainer-config";
|
import { trainerConfigs } from "#trainers/trainer-config";
|
||||||
import {
|
import { TrainerPartyCompoundTemplate, type TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
||||||
TrainerPartyCompoundTemplate,
|
|
||||||
type TrainerPartyTemplate,
|
|
||||||
trainerPartyTemplates,
|
|
||||||
} from "#trainers/trainer-party-template";
|
|
||||||
import { randSeedInt, randSeedItem, randSeedWeightedItem } from "#utils/common";
|
import { randSeedInt, randSeedItem, randSeedWeightedItem } from "#utils/common";
|
||||||
|
import { getRandomLocaleKey } from "#utils/i18n";
|
||||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||||
import { toSnakeCase } from "#utils/strings";
|
import { toCamelCase, toSnakeCase } from "#utils/strings";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class Trainer extends Phaser.GameObjects.Container {
|
export class Trainer extends Phaser.GameObjects.Container {
|
||||||
@ -35,6 +32,18 @@ export class Trainer extends Phaser.GameObjects.Container {
|
|||||||
public partnerNameKey: string | undefined;
|
public partnerNameKey: string | undefined;
|
||||||
public originalIndexes: { [key: number]: number } = {};
|
public originalIndexes: { [key: number]: number } = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Trainer.
|
||||||
|
* @param trainerType - The {@linkcode TrainerType} for this trainer, used to determine
|
||||||
|
* name, sprite, party contents and other details.
|
||||||
|
* @param variant - The {@linkcode TrainerVariant} for this trainer (if any are available)
|
||||||
|
* @param partyTemplateIndex - If provided, will override the trainer's party template with the given
|
||||||
|
* version.
|
||||||
|
* @param nameKey - If provided, will override the name key of the trainer
|
||||||
|
* @param partnerNameKey - If provided, will override the
|
||||||
|
* @param trainerConfigOverride - If provided, will override the trainer config for the given trainer type
|
||||||
|
* @todo Review how many of these parameters we actually need
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
trainerType: TrainerType,
|
trainerType: TrainerType,
|
||||||
variant: TrainerVariant,
|
variant: TrainerVariant,
|
||||||
@ -44,13 +53,11 @@ export class Trainer extends Phaser.GameObjects.Container {
|
|||||||
trainerConfigOverride?: TrainerConfig,
|
trainerConfigOverride?: TrainerConfig,
|
||||||
) {
|
) {
|
||||||
super(globalScene, -72, 80);
|
super(globalScene, -72, 80);
|
||||||
this.config = trainerConfigs.hasOwnProperty(trainerType)
|
this.config =
|
||||||
|
trainerConfigOverride ??
|
||||||
|
(trainerConfigs.hasOwnProperty(trainerType)
|
||||||
? trainerConfigs[trainerType]
|
? trainerConfigs[trainerType]
|
||||||
: trainerConfigs[TrainerType.ACE_TRAINER];
|
: trainerConfigs[TrainerType.ACE_TRAINER]);
|
||||||
|
|
||||||
if (trainerConfigOverride) {
|
|
||||||
this.config = trainerConfigOverride;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.variant = variant;
|
this.variant = variant;
|
||||||
this.partyTemplateIndex = Math.min(
|
this.partyTemplateIndex = Math.min(
|
||||||
@ -59,20 +66,21 @@ export class Trainer extends Phaser.GameObjects.Container {
|
|||||||
: randSeedWeightedItem(this.config.partyTemplates.map((_, i) => i)),
|
: randSeedWeightedItem(this.config.partyTemplates.map((_, i) => i)),
|
||||||
this.config.partyTemplates.length - 1,
|
this.config.partyTemplates.length - 1,
|
||||||
);
|
);
|
||||||
const classKey = `trainersCommon:${TrainerType[trainerType]}`;
|
// TODO: Rework this and add actual error handling for missing names
|
||||||
|
const classKey = `trainersCommon:${toCamelCase(TrainerType[trainerType])}`;
|
||||||
if (i18next.exists(classKey, { returnObjects: true })) {
|
if (i18next.exists(classKey, { returnObjects: true })) {
|
||||||
if (nameKey) {
|
if (nameKey) {
|
||||||
this.nameKey = nameKey;
|
this.nameKey = nameKey;
|
||||||
|
this.name = i18next.t(nameKey);
|
||||||
} else {
|
} else {
|
||||||
const genderKey = i18next.exists(`${classKey}.MALE`)
|
const genderKey = i18next.exists(`${classKey}.male`)
|
||||||
? variant === TrainerVariant.FEMALE
|
? variant === TrainerVariant.FEMALE
|
||||||
? ".FEMALE"
|
? ".female"
|
||||||
: ".MALE"
|
: ".male"
|
||||||
: "";
|
: "";
|
||||||
const trainerKey = randSeedItem(Object.keys(i18next.t(`${classKey}${genderKey}`, { returnObjects: true })));
|
[this.nameKey, this.name] = getRandomLocaleKey(`${classKey}${genderKey}`);
|
||||||
this.nameKey = `${classKey}${genderKey}.${trainerKey}`;
|
|
||||||
}
|
}
|
||||||
this.name = i18next.t(this.nameKey);
|
|
||||||
if (variant === TrainerVariant.DOUBLE) {
|
if (variant === TrainerVariant.DOUBLE) {
|
||||||
if (this.config.doubleOnly) {
|
if (this.config.doubleOnly) {
|
||||||
if (partnerNameKey) {
|
if (partnerNameKey) {
|
||||||
@ -82,16 +90,8 @@ export class Trainer extends Phaser.GameObjects.Container {
|
|||||||
[this.name, this.partnerName] = this.name.split(" & ");
|
[this.name, this.partnerName] = this.name.split(" & ");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const partnerGenderKey = i18next.exists(`${classKey}.FEMALE`) ? ".FEMALE" : "";
|
const partnerGenderKey = i18next.exists(`${classKey}.fenale`) ? ".fenale" : "";
|
||||||
const partnerTrainerKey = randSeedItem(
|
[this.partnerNameKey, this.partnerName] = getRandomLocaleKey(`${classKey}${partnerGenderKey}`);
|
||||||
Object.keys(
|
|
||||||
i18next.t(`${classKey}${partnerGenderKey}`, {
|
|
||||||
returnObjects: true,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
this.partnerNameKey = `${classKey}${partnerGenderKey}.${partnerTrainerKey}`;
|
|
||||||
this.partnerName = i18next.t(this.partnerNameKey);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,10 +109,6 @@ export class Trainer extends Phaser.GameObjects.Container {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(
|
|
||||||
Object.keys(trainerPartyTemplates)[Object.values(trainerPartyTemplates).indexOf(this.getPartyTemplate())],
|
|
||||||
);
|
|
||||||
|
|
||||||
const getSprite = (hasShadow?: boolean, forceFemale?: boolean) => {
|
const getSprite = (hasShadow?: boolean, forceFemale?: boolean) => {
|
||||||
const ret = globalScene.addFieldSprite(
|
const ret = globalScene.addFieldSprite(
|
||||||
0,
|
0,
|
||||||
@ -157,9 +153,9 @@ export class Trainer extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the trainer based on the provided trainer slot and the option to include a title.
|
* Returns the name of the trainer based on the provided trainer slot and the option to include a title.
|
||||||
* @param {TrainerSlot} trainerSlot - The slot to determine which name to use. Defaults to TrainerSlot.NONE.
|
* @param rainerSlot - The slot to determine which name to use; default `TrainerSlot.NONE`
|
||||||
* @param {boolean} includeTitle - Whether to include the title in the returned name. Defaults to false.
|
* @param includeTitle - Whether to include the title in the returned name; default `false`
|
||||||
* @returns {string} - The formatted name of the trainer.
|
* @returns - The formatted name of the trainer
|
||||||
*/
|
*/
|
||||||
getName(trainerSlot: TrainerSlot = TrainerSlot.NONE, includeTitle = false): string {
|
getName(trainerSlot: TrainerSlot = TrainerSlot.NONE, includeTitle = false): string {
|
||||||
// Get the base title based on the trainer slot and variant.
|
// Get the base title based on the trainer slot and variant.
|
||||||
|
17
src/utils/i18n.ts
Normal file
17
src/utils/i18n.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { randSeedItem } from "#utils/common";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select a random i18n key from all nested keys in the given object.
|
||||||
|
* @param key - The i18n key to retrieve a random value of.
|
||||||
|
* The key's value should be an object containing numerical keys (starting from 1).
|
||||||
|
* @returns A typle containing the key and value pair.
|
||||||
|
* @privateRemarks
|
||||||
|
* The reason such "array-like" keys are not stored as actual arrays is due to the
|
||||||
|
* translation software used by the Translation Team (Mozilla Pontoon)
|
||||||
|
* not supporting arrays in any capacity.
|
||||||
|
*/
|
||||||
|
export function getRandomLocaleKey(key: string): [key: string, value: string] {
|
||||||
|
const keyName = `${key}.${randSeedItem(Object.keys(i18next.t("key", { returnObjects: true })))}`;
|
||||||
|
return [keyName, i18next.t(keyName)];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user