mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-19 13:59: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 type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
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 { toCamelCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
@ -984,14 +987,17 @@ function doTradeReceivedSequence(
|
||||
}
|
||||
|
||||
function generateRandomTraderName() {
|
||||
const length = TrainerType.YOUNGSTER - TrainerType.ACE_TRAINER + 1;
|
||||
// +1 avoids TrainerType.UNKNOWN
|
||||
const classKey = `trainersCommon:${TrainerType[randInt(length) + 1]}`;
|
||||
// Some trainers have 2 gendered pools, some do not
|
||||
const genderKey = i18next.exists(`${classKey}.MALE`) ? (randInt(2) === 0 ? ".MALE" : ".FEMALE") : "";
|
||||
const trainerNameKey = randSeedItem(Object.keys(i18next.t(`${classKey}${genderKey}`, { returnObjects: true })));
|
||||
const trainerNameString = i18next.t(`${classKey}${genderKey}.${trainerNameKey}`);
|
||||
// Some names have an '&' symbol and need to be trimmed to a single name instead of a double name
|
||||
const trainerNames = trainerNameString.split(" & ");
|
||||
return trainerNames[randInt(trainerNames.length)];
|
||||
const allTrainerNames = getEnumKeys(TrainerType);
|
||||
// Exclude TrainerType.UNKNOWN and everything after Ace Trainers (grunts and unique trainers)
|
||||
const eligibleNames = allTrainerNames.slice(
|
||||
1,
|
||||
allTrainerNames.indexOf(TrainerType[TrainerType.YOUNGSTER] as keyof typeof TrainerType),
|
||||
);
|
||||
const randomTrainer = toCamelCase(randSeedItem(eligibleNames));
|
||||
const classKey = `trainersCommon:${randomTrainer}`;
|
||||
// Pick a random gender for ones with gendered pools, or access the raw object for ones without.
|
||||
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 type { TrainerConfig } from "#trainers/trainer-config";
|
||||
import { trainerConfigs } from "#trainers/trainer-config";
|
||||
import {
|
||||
TrainerPartyCompoundTemplate,
|
||||
type TrainerPartyTemplate,
|
||||
trainerPartyTemplates,
|
||||
} from "#trainers/trainer-party-template";
|
||||
import { TrainerPartyCompoundTemplate, type TrainerPartyTemplate } from "#trainers/trainer-party-template";
|
||||
import { randSeedInt, randSeedItem, randSeedWeightedItem } from "#utils/common";
|
||||
import { getRandomLocaleKey } from "#utils/i18n";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
import { toSnakeCase } from "#utils/strings";
|
||||
import { toCamelCase, toSnakeCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
|
||||
export class Trainer extends Phaser.GameObjects.Container {
|
||||
@ -35,6 +32,18 @@ export class Trainer extends Phaser.GameObjects.Container {
|
||||
public partnerNameKey: string | undefined;
|
||||
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(
|
||||
trainerType: TrainerType,
|
||||
variant: TrainerVariant,
|
||||
@ -44,13 +53,11 @@ export class Trainer extends Phaser.GameObjects.Container {
|
||||
trainerConfigOverride?: TrainerConfig,
|
||||
) {
|
||||
super(globalScene, -72, 80);
|
||||
this.config = trainerConfigs.hasOwnProperty(trainerType)
|
||||
? trainerConfigs[trainerType]
|
||||
: trainerConfigs[TrainerType.ACE_TRAINER];
|
||||
|
||||
if (trainerConfigOverride) {
|
||||
this.config = trainerConfigOverride;
|
||||
}
|
||||
this.config =
|
||||
trainerConfigOverride ??
|
||||
(trainerConfigs.hasOwnProperty(trainerType)
|
||||
? trainerConfigs[trainerType]
|
||||
: trainerConfigs[TrainerType.ACE_TRAINER]);
|
||||
|
||||
this.variant = variant;
|
||||
this.partyTemplateIndex = Math.min(
|
||||
@ -59,20 +66,21 @@ export class Trainer extends Phaser.GameObjects.Container {
|
||||
: randSeedWeightedItem(this.config.partyTemplates.map((_, i) => i)),
|
||||
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 (nameKey) {
|
||||
this.nameKey = nameKey;
|
||||
this.name = i18next.t(nameKey);
|
||||
} else {
|
||||
const genderKey = i18next.exists(`${classKey}.MALE`)
|
||||
const genderKey = i18next.exists(`${classKey}.male`)
|
||||
? variant === TrainerVariant.FEMALE
|
||||
? ".FEMALE"
|
||||
: ".MALE"
|
||||
? ".female"
|
||||
: ".male"
|
||||
: "";
|
||||
const trainerKey = randSeedItem(Object.keys(i18next.t(`${classKey}${genderKey}`, { returnObjects: true })));
|
||||
this.nameKey = `${classKey}${genderKey}.${trainerKey}`;
|
||||
[this.nameKey, this.name] = getRandomLocaleKey(`${classKey}${genderKey}`);
|
||||
}
|
||||
this.name = i18next.t(this.nameKey);
|
||||
|
||||
if (variant === TrainerVariant.DOUBLE) {
|
||||
if (this.config.doubleOnly) {
|
||||
if (partnerNameKey) {
|
||||
@ -82,16 +90,8 @@ export class Trainer extends Phaser.GameObjects.Container {
|
||||
[this.name, this.partnerName] = this.name.split(" & ");
|
||||
}
|
||||
} else {
|
||||
const partnerGenderKey = i18next.exists(`${classKey}.FEMALE`) ? ".FEMALE" : "";
|
||||
const partnerTrainerKey = randSeedItem(
|
||||
Object.keys(
|
||||
i18next.t(`${classKey}${partnerGenderKey}`, {
|
||||
returnObjects: true,
|
||||
}),
|
||||
),
|
||||
);
|
||||
this.partnerNameKey = `${classKey}${partnerGenderKey}.${partnerTrainerKey}`;
|
||||
this.partnerName = i18next.t(this.partnerNameKey);
|
||||
const partnerGenderKey = i18next.exists(`${classKey}.fenale`) ? ".fenale" : "";
|
||||
[this.partnerNameKey, this.partnerName] = getRandomLocaleKey(`${classKey}${partnerGenderKey}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,10 +109,6 @@ export class Trainer extends Phaser.GameObjects.Container {
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(
|
||||
Object.keys(trainerPartyTemplates)[Object.values(trainerPartyTemplates).indexOf(this.getPartyTemplate())],
|
||||
);
|
||||
|
||||
const getSprite = (hasShadow?: boolean, forceFemale?: boolean) => {
|
||||
const ret = globalScene.addFieldSprite(
|
||||
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.
|
||||
* @param {TrainerSlot} trainerSlot - The slot to determine which name to use. Defaults to TrainerSlot.NONE.
|
||||
* @param {boolean} includeTitle - Whether to include the title in the returned name. Defaults to false.
|
||||
* @returns {string} - The formatted name of the trainer.
|
||||
* @param rainerSlot - The slot to determine which name to use; default `TrainerSlot.NONE`
|
||||
* @param includeTitle - Whether to include the title in the returned name; default `false`
|
||||
* @returns - The formatted name of the trainer
|
||||
*/
|
||||
getName(trainerSlot: TrainerSlot = TrainerSlot.NONE, includeTitle = false): string {
|
||||
// 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