Compare commits

...

6 Commits

Author SHA1 Message Date
fabske0
149593bc4d
Merge 7dfe1ce216 into 6c0253ada4 2025-08-11 15:50:25 +00:00
fabske0
7dfe1ce216 change bgm name locales use 2025-08-11 17:49:56 +02:00
fabske0
1accc20b37 Change berry locales use 2025-08-11 11:47:20 +02:00
Jimmybald1
6c0253ada4
[Misc] Expanded Daily Run custom seeds (#6248)
* Modify custom starters and added boss, biome and luck custom seed overrides

* Added form index to boss custom seed

* Fix circular dependency in daily-run.ts

* Review for PR 6248

- Use early returns

- Update TSDocs

- Use `getEnumValues` instead of `Object.values` for `enum`s

- Add console logging for invalid seeds

---------

Co-authored-by: Jimmybald1 <147992650+IBBCalc@users.noreply.github.com>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2025-08-10 23:43:31 -04:00
AJ Fontaine
2b3b47cc07
Remove random unused empty Palossand exp variant masterlist entry (#6253)
Remove random unused empty Palossand exp variant masterlist entry
2025-08-10 21:40:08 -04:00
fabske0
64b9427f11 Change Achv locales 2025-08-10 22:08:52 +02:00
9 changed files with 404 additions and 273 deletions

View File

@ -132,7 +132,6 @@
"763": [0, 1, 1], "763": [0, 1, 1],
"767": [0, 1, 1], "767": [0, 1, 1],
"768": [0, 1, 1], "768": [0, 1, 1],
"770": [0, 0, 0],
"771": [0, 2, 2], "771": [0, 2, 2],
"772": [0, 1, 1], "772": [0, 1, 1],
"773-fighting": [0, 1, 1], "773-fighting": [0, 1, 1],

View File

@ -11,11 +11,11 @@ import { NumberHolder, randSeedInt, toDmgValue } from "#utils/common";
import i18next from "i18next"; import i18next from "i18next";
export function getBerryName(berryType: BerryType): string { export function getBerryName(berryType: BerryType): string {
return i18next.t(`berry:${BerryType[berryType]}.name`); return i18next.t(`berry:${BerryType[berryType].toLowerCase()}.name`);
} }
export function getBerryEffectDescription(berryType: BerryType): string { export function getBerryEffectDescription(berryType: BerryType): string {
return i18next.t(`berry:${BerryType[berryType]}.effect`); return i18next.t(`berry:${BerryType[berryType].toLowerCase()}.effect`);
} }
export type BerryPredicate = (pokemon: Pokemon) => boolean; export type BerryPredicate = (pokemon: Pokemon) => boolean;

View File

@ -5,10 +5,9 @@ import type { PokemonSpeciesForm } from "#data/pokemon-species";
import { PokemonSpecies } from "#data/pokemon-species"; import { PokemonSpecies } from "#data/pokemon-species";
import { BiomeId } from "#enums/biome-id"; import { BiomeId } from "#enums/biome-id";
import { PartyMemberStrength } from "#enums/party-member-strength"; import { PartyMemberStrength } from "#enums/party-member-strength";
import type { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { PlayerPokemon } from "#field/pokemon";
import type { Starter } from "#ui/starter-select-ui-handler"; import type { Starter } from "#ui/starter-select-ui-handler";
import { randSeedGauss, randSeedInt, randSeedItem } from "#utils/common"; import { isNullOrUndefined, randSeedGauss, randSeedInt, randSeedItem } from "#utils/common";
import { getEnumValues } from "#utils/enums"; import { getEnumValues } from "#utils/enums";
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils"; import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
@ -32,15 +31,9 @@ export function getDailyRunStarters(seed: string): Starter[] {
() => { () => {
const startingLevel = globalScene.gameMode.getStartingLevel(); const startingLevel = globalScene.gameMode.getStartingLevel();
if (/\d{18}$/.test(seed)) { const eventStarters = getDailyEventSeedStarters(seed);
for (let s = 0; s < 3; s++) { if (!isNullOrUndefined(eventStarters)) {
const offset = 6 + s * 6; starters.push(...eventStarters);
const starterSpeciesForm = getPokemonSpeciesForm(
Number.parseInt(seed.slice(offset, offset + 4)) as SpeciesId,
Number.parseInt(seed.slice(offset + 4, offset + 6)),
);
starters.push(getDailyRunStarter(starterSpeciesForm, startingLevel));
}
return; return;
} }
@ -72,18 +65,7 @@ function getDailyRunStarter(starterSpeciesForm: PokemonSpeciesForm, startingLeve
const starterSpecies = const starterSpecies =
starterSpeciesForm instanceof PokemonSpecies ? starterSpeciesForm : getPokemonSpecies(starterSpeciesForm.speciesId); starterSpeciesForm instanceof PokemonSpecies ? starterSpeciesForm : getPokemonSpecies(starterSpeciesForm.speciesId);
const formIndex = starterSpeciesForm instanceof PokemonSpecies ? undefined : starterSpeciesForm.formIndex; const formIndex = starterSpeciesForm instanceof PokemonSpecies ? undefined : starterSpeciesForm.formIndex;
const pokemon = new PlayerPokemon( const pokemon = globalScene.addPlayerPokemon(starterSpecies, startingLevel, undefined, formIndex);
starterSpecies,
startingLevel,
undefined,
formIndex,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
);
const starter: Starter = { const starter: Starter = {
species: starterSpecies, species: starterSpecies,
dexAttr: pokemon.getDexAttr(), dexAttr: pokemon.getDexAttr(),
@ -145,6 +127,11 @@ const dailyBiomeWeights: BiomeWeights = {
}; };
export function getDailyStartingBiome(): BiomeId { export function getDailyStartingBiome(): BiomeId {
const eventBiome = getDailyEventSeedBiome(globalScene.seed);
if (!isNullOrUndefined(eventBiome)) {
return eventBiome;
}
const biomes = getEnumValues(BiomeId).filter(b => b !== BiomeId.TOWN && b !== BiomeId.END); const biomes = getEnumValues(BiomeId).filter(b => b !== BiomeId.TOWN && b !== BiomeId.END);
let totalWeight = 0; let totalWeight = 0;
@ -169,3 +156,126 @@ export function getDailyStartingBiome(): BiomeId {
// TODO: should this use `randSeedItem`? // TODO: should this use `randSeedItem`?
return biomes[randSeedInt(biomes.length)]; return biomes[randSeedInt(biomes.length)];
} }
/**
* If this is Daily Mode and the seed is longer than a default seed
* then it has been modified and could contain a custom event seed. \
* Default seeds are always exactly 24 characters.
* @returns `true` if it is a Daily Event Seed.
*/
export function isDailyEventSeed(seed: string): boolean {
return globalScene.gameMode.isDaily && seed.length > 24;
}
/**
* Expects the seed to contain `/starters\d{18}/`
* where the digits alternate between 4 digits for the species ID and 2 digits for the form index
* (left padded with `0`s as necessary).
* @returns An array of {@linkcode Starter}s, or `null` if no valid match.
*/
export function getDailyEventSeedStarters(seed: string): Starter[] | null {
if (!isDailyEventSeed(seed)) {
return null;
}
const starters: Starter[] = [];
const match = /starters(\d{4})(\d{2})(\d{4})(\d{2})(\d{4})(\d{2})/g.exec(seed);
if (!match || match.length !== 7) {
return null;
}
for (let i = 1; i < match.length; i += 2) {
const speciesId = Number.parseInt(match[i]) as SpeciesId;
const formIndex = Number.parseInt(match[i + 1]);
if (!getEnumValues(SpeciesId).includes(speciesId)) {
console.warn("Invalid species ID used for custom daily run seed starter:", speciesId);
return null;
}
const starterForm = getPokemonSpeciesForm(speciesId, formIndex);
const startingLevel = globalScene.gameMode.getStartingLevel();
const starter = getDailyRunStarter(starterForm, startingLevel);
starters.push(starter);
}
return starters;
}
/**
* Expects the seed to contain `/boss\d{4}\d{2}/`
* where the first 4 digits are the species ID and the next 2 digits are the form index
* (left padded with `0`s as necessary).
* @returns A {@linkcode PokemonSpeciesForm} to be used for the boss, or `null` if no valid match.
*/
export function getDailyEventSeedBoss(seed: string): PokemonSpeciesForm | null {
if (!isDailyEventSeed(seed)) {
return null;
}
const match = /boss(\d{4})(\d{2})/g.exec(seed);
if (!match || match.length !== 3) {
return null;
}
const speciesId = Number.parseInt(match[1]) as SpeciesId;
const formIndex = Number.parseInt(match[2]);
if (!getEnumValues(SpeciesId).includes(speciesId)) {
console.warn("Invalid species ID used for custom daily run seed boss:", speciesId);
return null;
}
const starterForm = getPokemonSpeciesForm(speciesId, formIndex);
return starterForm;
}
/**
* Expects the seed to contain `/biome\d{2}/` where the 2 digits are a biome ID (left padded with `0` if necessary).
* @returns The biome to use or `null` if no valid match.
*/
export function getDailyEventSeedBiome(seed: string): BiomeId | null {
if (!isDailyEventSeed(seed)) {
return null;
}
const match = /biome(\d{2})/g.exec(seed);
if (!match || match.length !== 2) {
return null;
}
const startingBiome = Number.parseInt(match[1]) as BiomeId;
if (!getEnumValues(BiomeId).includes(startingBiome)) {
console.warn("Invalid biome ID used for custom daily run seed:", startingBiome);
return null;
}
return startingBiome;
}
/**
* Expects the seed to contain `/luck\d{2}/` where the 2 digits are a number between `0` and `14`
* (left padded with `0` if necessary).
* @returns The custom luck value or `null` if no valid match.
*/
export function getDailyEventSeedLuck(seed: string): number | null {
if (!isDailyEventSeed(seed)) {
return null;
}
const match = /luck(\d{2})/g.exec(seed);
if (!match || match.length !== 2) {
return null;
}
const luck = Number.parseInt(match[1]);
if (luck < 0 || luck > 14) {
console.warn("Invalid luck value used for custom daily run seed:", luck);
return null;
}
return luck;
}

View File

@ -39,6 +39,7 @@ import {
TrappedTag, TrappedTag,
TypeImmuneTag, TypeImmuneTag,
} from "#data/battler-tags"; } from "#data/battler-tags";
import { getDailyEventSeedBoss } from "#data/daily-run";
import { allAbilities, allMoves } from "#data/data-lists"; import { allAbilities, allMoves } from "#data/data-lists";
import { getLevelTotalExp } from "#data/exp"; import { getLevelTotalExp } from "#data/exp";
import { import {
@ -6256,6 +6257,11 @@ export class EnemyPokemon extends Pokemon {
this.species.forms[Overrides.OPP_FORM_OVERRIDES[speciesId]] this.species.forms[Overrides.OPP_FORM_OVERRIDES[speciesId]]
) { ) {
this.formIndex = Overrides.OPP_FORM_OVERRIDES[speciesId]; this.formIndex = Overrides.OPP_FORM_OVERRIDES[speciesId];
} else if (globalScene.gameMode.isDaily && globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex)) {
const eventBoss = getDailyEventSeedBoss(globalScene.seed);
if (!isNullOrUndefined(eventBoss)) {
this.formIndex = eventBoss.formIndex;
}
} }
if (!dataSource) { if (!dataSource) {

View File

@ -3,7 +3,7 @@ import { CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES, CLASSIC_MODE_MYSTERY_ENCOUNTER_
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import Overrides from "#app/overrides"; import Overrides from "#app/overrides";
import { allChallenges, type Challenge, copyChallenge } from "#data/challenge"; import { allChallenges, type Challenge, copyChallenge } from "#data/challenge";
import { getDailyStartingBiome } from "#data/daily-run"; import { getDailyEventSeedBoss, getDailyStartingBiome } from "#data/daily-run";
import { allSpecies } from "#data/data-lists"; import { allSpecies } from "#data/data-lists";
import type { PokemonSpecies } from "#data/pokemon-species"; import type { PokemonSpecies } from "#data/pokemon-species";
import { BiomeId } from "#enums/biome-id"; import { BiomeId } from "#enums/biome-id";
@ -15,6 +15,7 @@ import type { Arena } from "#field/arena";
import { classicFixedBattles, type FixedBattleConfigs } from "#trainers/fixed-battle-configs"; import { classicFixedBattles, type FixedBattleConfigs } from "#trainers/fixed-battle-configs";
import { applyChallenges } from "#utils/challenge-utils"; import { applyChallenges } from "#utils/challenge-utils";
import { BooleanHolder, isNullOrUndefined, randSeedInt, randSeedItem } from "#utils/common"; import { BooleanHolder, isNullOrUndefined, randSeedInt, randSeedItem } from "#utils/common";
import { getPokemonSpecies } from "#utils/pokemon-utils";
import i18next from "i18next"; import i18next from "i18next";
interface GameModeConfig { interface GameModeConfig {
@ -211,6 +212,12 @@ export class GameMode implements GameModeConfig {
getOverrideSpecies(waveIndex: number): PokemonSpecies | null { getOverrideSpecies(waveIndex: number): PokemonSpecies | null {
if (this.isDaily && this.isWaveFinal(waveIndex)) { if (this.isDaily && this.isWaveFinal(waveIndex)) {
const eventBoss = getDailyEventSeedBoss(globalScene.seed);
if (!isNullOrUndefined(eventBoss)) {
// Cannot set form index here, it will be overriden when adding it as enemy pokemon.
return getPokemonSpecies(eventBoss.speciesId);
}
const allFinalBossSpecies = allSpecies.filter( const allFinalBossSpecies = allSpecies.filter(
s => s =>
(s.subLegendary || s.legendary || s.mythical) && (s.subLegendary || s.legendary || s.mythical) &&

View File

@ -6,6 +6,7 @@ import Overrides from "#app/overrides";
import { EvolutionItem, pokemonEvolutions } from "#balance/pokemon-evolutions"; import { EvolutionItem, pokemonEvolutions } from "#balance/pokemon-evolutions";
import { tmPoolTiers, tmSpecies } from "#balance/tms"; import { tmPoolTiers, tmSpecies } from "#balance/tms";
import { getBerryEffectDescription, getBerryName } from "#data/berry"; import { getBerryEffectDescription, getBerryName } from "#data/berry";
import { getDailyEventSeedLuck } from "#data/daily-run";
import { allMoves, modifierTypes } from "#data/data-lists"; import { allMoves, modifierTypes } from "#data/data-lists";
import { SpeciesFormChangeItemTrigger } from "#data/form-change-triggers"; import { SpeciesFormChangeItemTrigger } from "#data/form-change-triggers";
import { getNatureName, getNatureStatMultiplier } from "#data/nature"; import { getNatureName, getNatureStatMultiplier } from "#data/nature";
@ -2921,6 +2922,12 @@ export function getPartyLuckValue(party: Pokemon[]): number {
const DailyLuck = new NumberHolder(0); const DailyLuck = new NumberHolder(0);
globalScene.executeWithSeedOffset( globalScene.executeWithSeedOffset(
() => { () => {
const eventLuck = getDailyEventSeedLuck(globalScene.seed);
if (!isNullOrUndefined(eventLuck)) {
DailyLuck.value = eventLuck;
return;
}
DailyLuck.value = randSeedInt(15); // Random number between 0 and 14 DailyLuck.value = randSeedInt(15); // Random number between 0 and 14
}, },
0, 0,
@ -2928,6 +2935,7 @@ export function getPartyLuckValue(party: Pokemon[]): number {
); );
return DailyLuck.value; return DailyLuck.value;
} }
const eventSpecies = timedEventManager.getEventLuckBoostedSpecies(); const eventSpecies = timedEventManager.getEventLuckBoostedSpecies();
const luck = Phaser.Math.Clamp( const luck = Phaser.Math.Clamp(
party party

View File

@ -214,242 +214,243 @@ export function getAchievementDescription(localizationKey: string): string {
const genderStr = PlayerGender[genderIndex].toLowerCase(); const genderStr = PlayerGender[genderIndex].toLowerCase();
switch (localizationKey) { switch (localizationKey) {
case "10K_MONEY": case "10KMoney":
return i18next.t("achv:MoneyAchv.description", { return i18next.t("achv:moneyAchv.description", {
context: genderStr, context: genderStr,
moneyAmount: achvs._10K_MONEY.moneyAmount.toLocaleString("en-US"), moneyAmount: achvs._10K_MONEY.moneyAmount.toLocaleString("en-US"),
}); });
case "100K_MONEY": case "100KMoney":
return i18next.t("achv:MoneyAchv.description", { return i18next.t("achv:moneyAchv.description", {
context: genderStr, context: genderStr,
moneyAmount: achvs._100K_MONEY.moneyAmount.toLocaleString("en-US"), moneyAmount: achvs._100K_MONEY.moneyAmount.toLocaleString("en-US"),
}); });
case "1M_MONEY": case "1MMoney":
return i18next.t("achv:MoneyAchv.description", { return i18next.t("achv:moneyAchv.description", {
context: genderStr, context: genderStr,
moneyAmount: achvs._1M_MONEY.moneyAmount.toLocaleString("en-US"), moneyAmount: achvs._1M_MONEY.moneyAmount.toLocaleString("en-US"),
}); });
case "10M_MONEY": case "10MMoney":
return i18next.t("achv:MoneyAchv.description", { return i18next.t("achv:moneyAchv.description", {
context: genderStr, context: genderStr,
moneyAmount: achvs._10M_MONEY.moneyAmount.toLocaleString("en-US"), moneyAmount: achvs._10M_MONEY.moneyAmount.toLocaleString("en-US"),
}); });
case "250_DMG": case "250Dmg":
return i18next.t("achv:DamageAchv.description", { return i18next.t("achv:damageAchv.description", {
context: genderStr, context: genderStr,
damageAmount: achvs._250_DMG.damageAmount.toLocaleString("en-US"), damageAmount: achvs._250_DMG.damageAmount.toLocaleString("en-US"),
}); });
case "1000_DMG": case "1000Dmg":
return i18next.t("achv:DamageAchv.description", { return i18next.t("achv:damageAchv.description", {
context: genderStr, context: genderStr,
damageAmount: achvs._1000_DMG.damageAmount.toLocaleString("en-US"), damageAmount: achvs._1000_DMG.damageAmount.toLocaleString("en-US"),
}); });
case "2500_DMG": case "2500Dmg":
return i18next.t("achv:DamageAchv.description", { return i18next.t("achv:damageAchv.description", {
context: genderStr, context: genderStr,
damageAmount: achvs._2500_DMG.damageAmount.toLocaleString("en-US"), damageAmount: achvs._2500_DMG.damageAmount.toLocaleString("en-US"),
}); });
case "10000_DMG": case "10000Dmg":
return i18next.t("achv:DamageAchv.description", { return i18next.t("achv:damageAchv.description", {
context: genderStr, context: genderStr,
damageAmount: achvs._10000_DMG.damageAmount.toLocaleString("en-US"), damageAmount: achvs._10000_DMG.damageAmount.toLocaleString("en-US"),
}); });
case "250_HEAL": case "250Heal":
return i18next.t("achv:HealAchv.description", { return i18next.t("achv:healAchv.description", {
context: genderStr, context: genderStr,
healAmount: achvs._250_HEAL.healAmount.toLocaleString("en-US"), healAmount: achvs._250_HEAL.healAmount.toLocaleString("en-US"),
HP: i18next.t(getShortenedStatKey(Stat.HP)), HP: i18next.t(getShortenedStatKey(Stat.HP)),
}); });
case "1000_HEAL": case "1000Heal":
return i18next.t("achv:HealAchv.description", { return i18next.t("achv:healAchv.description", {
context: genderStr, context: genderStr,
healAmount: achvs._1000_HEAL.healAmount.toLocaleString("en-US"), healAmount: achvs._1000_HEAL.healAmount.toLocaleString("en-US"),
HP: i18next.t(getShortenedStatKey(Stat.HP)), HP: i18next.t(getShortenedStatKey(Stat.HP)),
}); });
case "2500_HEAL": case "2500Heal":
return i18next.t("achv:HealAchv.description", { return i18next.t("achv:healAchv.description", {
context: genderStr, context: genderStr,
healAmount: achvs._2500_HEAL.healAmount.toLocaleString("en-US"), healAmount: achvs._2500_HEAL.healAmount.toLocaleString("en-US"),
HP: i18next.t(getShortenedStatKey(Stat.HP)), HP: i18next.t(getShortenedStatKey(Stat.HP)),
}); });
case "10000_HEAL": case "10000Heal":
return i18next.t("achv:HealAchv.description", { return i18next.t("achv:healAchv.description", {
context: genderStr, context: genderStr,
healAmount: achvs._10000_HEAL.healAmount.toLocaleString("en-US"), healAmount: achvs._10000_HEAL.healAmount.toLocaleString("en-US"),
HP: i18next.t(getShortenedStatKey(Stat.HP)), HP: i18next.t(getShortenedStatKey(Stat.HP)),
}); });
case "LV_100": case "lv100":
return i18next.t("achv:LevelAchv.description", { return i18next.t("achv:levelAchv.description", {
context: genderStr, context: genderStr,
level: achvs.LV_100.level, level: achvs.LV_100.level,
}); });
case "LV_250": case "lv250":
return i18next.t("achv:LevelAchv.description", { return i18next.t("achv:levelAchv.description", {
context: genderStr, context: genderStr,
level: achvs.LV_250.level, level: achvs.LV_250.level,
}); });
case "LV_1000": case "lv1000":
return i18next.t("achv:LevelAchv.description", { return i18next.t("achv:levelAchv.description", {
context: genderStr, context: genderStr,
level: achvs.LV_1000.level, level: achvs.LV_1000.level,
}); });
case "10_RIBBONS": case "10Ribbons":
return i18next.t("achv:RibbonAchv.description", { return i18next.t("achv:ribbonAchv.description", {
context: genderStr, context: genderStr,
ribbonAmount: achvs._10_RIBBONS.ribbonAmount.toLocaleString("en-US"), ribbonAmount: achvs._10_RIBBONS.ribbonAmount.toLocaleString("en-US"),
}); });
case "25_RIBBONS": case "25Ribbons":
return i18next.t("achv:RibbonAchv.description", { return i18next.t("achv:ribbonAchv.description", {
context: genderStr, context: genderStr,
ribbonAmount: achvs._25_RIBBONS.ribbonAmount.toLocaleString("en-US"), ribbonAmount: achvs._25_RIBBONS.ribbonAmount.toLocaleString("en-US"),
}); });
case "50_RIBBONS": case "50Ribbons":
return i18next.t("achv:RibbonAchv.description", { return i18next.t("achv:ribbonAchv.description", {
context: genderStr, context: genderStr,
ribbonAmount: achvs._50_RIBBONS.ribbonAmount.toLocaleString("en-US"), ribbonAmount: achvs._50_RIBBONS.ribbonAmount.toLocaleString("en-US"),
}); });
case "75_RIBBONS": case "75Ribbons":
return i18next.t("achv:RibbonAchv.description", { return i18next.t("achv:ribbonAchv.description", {
context: genderStr, context: genderStr,
ribbonAmount: achvs._75_RIBBONS.ribbonAmount.toLocaleString("en-US"), ribbonAmount: achvs._75_RIBBONS.ribbonAmount.toLocaleString("en-US"),
}); });
case "100_RIBBONS": case "100Ribbons":
return i18next.t("achv:RibbonAchv.description", { return i18next.t("achv:ribbonAchv.description", {
context: genderStr, context: genderStr,
ribbonAmount: achvs._100_RIBBONS.ribbonAmount.toLocaleString("en-US"), ribbonAmount: achvs._100_RIBBONS.ribbonAmount.toLocaleString("en-US"),
}); });
case "TRANSFER_MAX_STAT_STAGE": case "transferMaxStatStage":
return i18next.t("achv:TRANSFER_MAX_STAT_STAGE.description", { return i18next.t("achv:transferMaxStatStage.description", {
context: genderStr, context: genderStr,
}); });
case "MAX_FRIENDSHIP": case "maxFriendship":
return i18next.t("achv:MAX_FRIENDSHIP.description", { return i18next.t("achv:maxFriendship.description", {
context: genderStr, context: genderStr,
}); });
case "MEGA_EVOLVE": case "megaEvolve":
return i18next.t("achv:MEGA_EVOLVE.description", { context: genderStr }); return i18next.t("achv:megaEvolve.description", { context: genderStr });
case "GIGANTAMAX": case "gigantamax":
return i18next.t("achv:GIGANTAMAX.description", { context: genderStr }); return i18next.t("achv:gigantamax.description", { context: genderStr });
case "TERASTALLIZE": case "terastallize":
return i18next.t("achv:TERASTALLIZE.description", { context: genderStr }); return i18next.t("achv:terastallize.description", { context: genderStr });
case "STELLAR_TERASTALLIZE": case "stellarTerastallize":
return i18next.t("achv:STELLAR_TERASTALLIZE.description", { return i18next.t("achv:stellarTerastallize.description", {
context: genderStr, context: genderStr,
}); });
case "SPLICE": case "Splice":
return i18next.t("achv:SPLICE.description", { context: genderStr }); return i18next.t("achv:Splice.description", { context: genderStr });
case "MINI_BLACK_HOLE": case "miniBlackHole":
return i18next.t("achv:MINI_BLACK_HOLE.description", { return i18next.t("achv:miniBlackHole.description", {
context: genderStr, context: genderStr,
}); });
case "CATCH_MYTHICAL": case "catchMythical":
return i18next.t("achv:CATCH_MYTHICAL.description", { return i18next.t("achv:catchMythical.description", {
context: genderStr, context: genderStr,
}); });
case "CATCH_SUB_LEGENDARY": case "catchSubLegendary":
return i18next.t("achv:CATCH_SUB_LEGENDARY.description", { return i18next.t("achv:catchSubLegendary.description", {
context: genderStr, context: genderStr,
}); });
case "CATCH_LEGENDARY": case "catchLegendary":
return i18next.t("achv:CATCH_LEGENDARY.description", { return i18next.t("achv:catchLegendary.description", {
context: genderStr, context: genderStr,
}); });
case "SEE_SHINY": case "seeShiny":
return i18next.t("achv:SEE_SHINY.description", { context: genderStr }); return i18next.t("achv:seeShiny.description", { context: genderStr });
case "SHINY_PARTY": case "shinyParty":
return i18next.t("achv:SHINY_PARTY.description", { context: genderStr }); return i18next.t("achv:shinyParty.description", { context: genderStr });
case "HATCH_MYTHICAL": case "hatchMythical":
return i18next.t("achv:HATCH_MYTHICAL.description", { return i18next.t("achv:hatchMythical.description", {
context: genderStr, context: genderStr,
}); });
case "HATCH_SUB_LEGENDARY": case "hatchSubLegendary":
return i18next.t("achv:HATCH_SUB_LEGENDARY.description", { return i18next.t("achv:hatchSubLegendary.description", {
context: genderStr, context: genderStr,
}); });
case "HATCH_LEGENDARY": case "hatchLegendary":
return i18next.t("achv:HATCH_LEGENDARY.description", { return i18next.t("achv:hatchLegendary.description", {
context: genderStr, context: genderStr,
}); });
case "HATCH_SHINY": case "hatchShiny":
return i18next.t("achv:HATCH_SHINY.description", { context: genderStr }); return i18next.t("achv:hatchShiny.description", { context: genderStr });
case "HIDDEN_ABILITY": case "hiddenAbility":
return i18next.t("achv:HIDDEN_ABILITY.description", { return i18next.t("achv:hiddenAbility.description", {
context: genderStr, context: genderStr,
}); });
case "PERFECT_IVS": case "perfectIvs":
return i18next.t("achv:PERFECT_IVS.description", { context: genderStr }); return i18next.t("achv:perfectIvs.description", { context: genderStr });
case "CLASSIC_VICTORY": case "classicVictory":
return i18next.t("achv:CLASSIC_VICTORY.description", { return i18next.t("achv:classicVictory.description", {
context: genderStr, context: genderStr,
}); });
case "UNEVOLVED_CLASSIC_VICTORY": case "unevolvedClassicVictory":
return i18next.t("achv:UNEVOLVED_CLASSIC_VICTORY.description", { return i18next.t("achv:unevolvedClassicVictory.description", {
context: genderStr, context: genderStr,
}); });
case "MONO_GEN_ONE": case "monoGenOne":
return i18next.t("achv:MONO_GEN_ONE.description", { context: genderStr }); return i18next.t("achv:monoGenOne.description", { context: genderStr });
case "MONO_GEN_TWO": case "monoGenTwo":
return i18next.t("achv:MONO_GEN_TWO.description", { context: genderStr }); return i18next.t("achv:monoGenTwo.description", { context: genderStr });
case "MONO_GEN_THREE": case "monoGenThree":
return i18next.t("achv:MONO_GEN_THREE.description", { return i18next.t("achv:monoGenThree.description", {
context: genderStr, context: genderStr,
}); });
case "MONO_GEN_FOUR": case "monoGenFour":
return i18next.t("achv:MONO_GEN_FOUR.description", { return i18next.t("achv:monoGenFour.description", {
context: genderStr, context: genderStr,
}); });
case "MONO_GEN_FIVE": case "monoGenFive":
return i18next.t("achv:MONO_GEN_FIVE.description", { return i18next.t("achv:monoGenFive.description", {
context: genderStr, context: genderStr,
}); });
case "MONO_GEN_SIX": case "monoGenSix":
return i18next.t("achv:MONO_GEN_SIX.description", { context: genderStr }); return i18next.t("achv:monoGenSix.description", { context: genderStr });
case "MONO_GEN_SEVEN": case "monoGenSeven":
return i18next.t("achv:MONO_GEN_SEVEN.description", { return i18next.t("achv:monoGenSeven.description", {
context: genderStr, context: genderStr,
}); });
case "MONO_GEN_EIGHT": case "monoGenEight":
return i18next.t("achv:MONO_GEN_EIGHT.description", { return i18next.t("achv:monoGenEight.description", {
context: genderStr, context: genderStr,
}); });
case "MONO_GEN_NINE": case "monoGenNine":
return i18next.t("achv:MONO_GEN_NINE.description", { return i18next.t("achv:monoGenNine.description", {
context: genderStr, context: genderStr,
}); });
case "MONO_NORMAL": case "monoNormal":
case "MONO_FIGHTING": case "monoFighting":
case "MONO_FLYING": case "monoFlying":
case "MONO_POISON": case "monoPoison":
case "MONO_GROUND": case "monoGround":
case "MONO_ROCK": case "monoRock":
case "MONO_BUG": case "monoBug":
case "MONO_GHOST": case "monoGhost":
case "MONO_STEEL": case "monoSteel":
case "MONO_FIRE": case "monoFire":
case "MONO_WATER": case "monoWater":
case "MONO_GRASS": case "monoGrass":
case "MONO_ELECTRIC": case "monoElectric":
case "MONO_PSYCHIC": case "monoPsychic":
case "MONO_ICE": case "monoIce":
case "MONO_DRAGON": case "monoDragon":
case "MONO_DARK": case "monoDark":
case "MONO_FAIRY": case "monoFairy":
return i18next.t("achv:MonoType.description", { return i18next.t("achv:monoType.description", {
context: genderStr, context: genderStr,
type: i18next.t(`pokemonInfo:Type.${localizationKey.slice(5)}`), // Todo: Remove the `toUpperCase()` again after changing the `pokemonInfo.json` locales
type: i18next.t(`pokemonInfo:Type.${localizationKey.slice(4).toUpperCase()}`),
}); });
case "FRESH_START": case "freshStart":
return i18next.t("achv:FRESH_START.description", { context: genderStr }); return i18next.t("achv:freshStart.description", { context: genderStr });
case "INVERSE_BATTLE": case "inverseBattle":
return i18next.t("achv:INVERSE_BATTLE.description", { return i18next.t("achv:inverseBattle.description", {
context: genderStr, context: genderStr,
}); });
case "FLIP_STATS": case "flipStats":
return i18next.t("achv:FLIP_STATS.description", { context: genderStr }); return i18next.t("achv:flipStats.description", { context: genderStr });
case "FLIP_INVERSE": case "flipInverse":
return i18next.t("achv:FLIP_INVERSE.description", { context: genderStr }); return i18next.t("achv:flipInverse.description", { context: genderStr });
case "BREEDERS_IN_SPACE": case "breedersInSpace":
return i18next.t("achv:BREEDERS_IN_SPACE.description", { return i18next.t("achv:breedersInSpace.description", {
context: genderStr, context: genderStr,
}); });
default: default:
@ -458,84 +459,84 @@ export function getAchievementDescription(localizationKey: string): string {
} }
export const achvs = { export const achvs = {
_10K_MONEY: new MoneyAchv("10K_MONEY", "", 10000, "nugget", 10), _10K_MONEY: new MoneyAchv("10KMoney", "", 10000, "nugget", 10),
_100K_MONEY: new MoneyAchv("100K_MONEY", "", 100000, "big_nugget", 25).setSecret(true), _100K_MONEY: new MoneyAchv("100KMoney", "", 100000, "big_nugget", 25).setSecret(true),
_1M_MONEY: new MoneyAchv("1M_MONEY", "", 1000000, "relic_gold", 50).setSecret(true), _1M_MONEY: new MoneyAchv("1MMoney", "", 1000000, "relic_gold", 50).setSecret(true),
_10M_MONEY: new MoneyAchv("10M_MONEY", "", 10000000, "coin_case", 100).setSecret(true), _10M_MONEY: new MoneyAchv("10MMoney", "", 10000000, "coin_case", 100).setSecret(true),
_250_DMG: new DamageAchv("250_DMG", "", 250, "lucky_punch", 10), _250_DMG: new DamageAchv("250Dmg", "", 250, "lucky_punch", 10),
_1000_DMG: new DamageAchv("1000_DMG", "", 1000, "lucky_punch_great", 25).setSecret(true), _1000_DMG: new DamageAchv("1000Dmg", "", 1000, "lucky_punch_great", 25).setSecret(true),
_2500_DMG: new DamageAchv("2500_DMG", "", 2500, "lucky_punch_ultra", 50).setSecret(true), _2500_DMG: new DamageAchv("2500Dmg", "", 2500, "lucky_punch_ultra", 50).setSecret(true),
_10000_DMG: new DamageAchv("10000_DMG", "", 10000, "lucky_punch_master", 100).setSecret(true), _10000_DMG: new DamageAchv("10000Dmg", "", 10000, "lucky_punch_master", 100).setSecret(true),
_250_HEAL: new HealAchv("250_HEAL", "", 250, "potion", 10), _250_HEAL: new HealAchv("250Heal", "", 250, "potion", 10),
_1000_HEAL: new HealAchv("1000_HEAL", "", 1000, "super_potion", 25).setSecret(true), _1000_HEAL: new HealAchv("1000Heal", "", 1000, "super_potion", 25).setSecret(true),
_2500_HEAL: new HealAchv("2500_HEAL", "", 2500, "hyper_potion", 50).setSecret(true), _2500_HEAL: new HealAchv("2500Heal", "", 2500, "hyper_potion", 50).setSecret(true),
_10000_HEAL: new HealAchv("10000_HEAL", "", 10000, "max_potion", 100).setSecret(true), _10000_HEAL: new HealAchv("10000Heal", "", 10000, "max_potion", 100).setSecret(true),
LV_100: new LevelAchv("LV_100", "", 100, "rare_candy", 25).setSecret(), LV_100: new LevelAchv("lv100", "", 100, "rare_candy", 25).setSecret(),
LV_250: new LevelAchv("LV_250", "", 250, "rarer_candy", 50).setSecret(true), LV_250: new LevelAchv("lv250", "", 250, "rarer_candy", 50).setSecret(true),
LV_1000: new LevelAchv("LV_1000", "", 1000, "candy_jar", 100).setSecret(true), LV_1000: new LevelAchv("lv1000", "", 1000, "candy_jar", 100).setSecret(true),
_10_RIBBONS: new RibbonAchv("10_RIBBONS", "", 10, "bronze_ribbon", 10), _10_RIBBONS: new RibbonAchv("10Ribbons", "", 10, "bronze_ribbon", 10),
_25_RIBBONS: new RibbonAchv("25_RIBBONS", "", 25, "great_ribbon", 25).setSecret(true), _25_RIBBONS: new RibbonAchv("25Ribbons", "", 25, "great_ribbon", 25).setSecret(true),
_50_RIBBONS: new RibbonAchv("50_RIBBONS", "", 50, "ultra_ribbon", 50).setSecret(true), _50_RIBBONS: new RibbonAchv("50Ribbons", "", 50, "ultra_ribbon", 50).setSecret(true),
_75_RIBBONS: new RibbonAchv("75_RIBBONS", "", 75, "rogue_ribbon", 75).setSecret(true), _75_RIBBONS: new RibbonAchv("75Ribbons", "", 75, "rogue_ribbon", 75).setSecret(true),
_100_RIBBONS: new RibbonAchv("100_RIBBONS", "", 100, "master_ribbon", 100).setSecret(true), _100_RIBBONS: new RibbonAchv("100Ribbons", "", 100, "master_ribbon", 100).setSecret(true),
TRANSFER_MAX_STAT_STAGE: new Achv("TRANSFER_MAX_STAT_STAGE", "", "TRANSFER_MAX_STAT_STAGE.description", "baton", 20), TRANSFER_MAX_STAT_STAGE: new Achv("transferMaxStatStage", "", "transferMaxStatStage.description", "baton", 20),
MAX_FRIENDSHIP: new Achv("MAX_FRIENDSHIP", "", "MAX_FRIENDSHIP.description", "soothe_bell", 25), MAX_FRIENDSHIP: new Achv("maxFriendship", "", "maxFriendship.description", "soothe_bell", 25),
MEGA_EVOLVE: new Achv("MEGA_EVOLVE", "", "MEGA_EVOLVE.description", "mega_bracelet", 50), MEGA_EVOLVE: new Achv("megaEvolve", "", "megaEvolve.description", "mega_bracelet", 50),
GIGANTAMAX: new Achv("GIGANTAMAX", "", "GIGANTAMAX.description", "dynamax_band", 50), GIGANTAMAX: new Achv("gigantamax", "", "gigantamax.description", "dynamax_band", 50),
TERASTALLIZE: new Achv("TERASTALLIZE", "", "TERASTALLIZE.description", "tera_orb", 25), TERASTALLIZE: new Achv("terastallize", "", "terastallize.description", "tera_orb", 25),
STELLAR_TERASTALLIZE: new Achv( STELLAR_TERASTALLIZE: new Achv(
"STELLAR_TERASTALLIZE", "stellarTerastallize",
"", "",
"STELLAR_TERASTALLIZE.description", "stellarTerastallize.description",
"stellar_tera_shard", "stellar_tera_shard",
25, 25,
).setSecret(true), ).setSecret(true),
SPLICE: new Achv("SPLICE", "", "SPLICE.description", "dna_splicers", 10), SPLICE: new Achv("Splice", "", "Splice.description", "dna_splicers", 10),
MINI_BLACK_HOLE: new ModifierAchv( MINI_BLACK_HOLE: new ModifierAchv(
"MINI_BLACK_HOLE", "miniBlackHole",
"", "",
"MINI_BLACK_HOLE.description", "miniBlackHole.description",
"mini_black_hole", "mini_black_hole",
25, 25,
modifier => modifier instanceof TurnHeldItemTransferModifier, modifier => modifier instanceof TurnHeldItemTransferModifier,
).setSecret(), ).setSecret(),
CATCH_MYTHICAL: new Achv("CATCH_MYTHICAL", "", "CATCH_MYTHICAL.description", "strange_ball", 50).setSecret(), CATCH_MYTHICAL: new Achv("catchMythical", "", "catchMythical.description", "strange_ball", 50).setSecret(),
CATCH_SUB_LEGENDARY: new Achv("CATCH_SUB_LEGENDARY", "", "CATCH_SUB_LEGENDARY.description", "rb", 75).setSecret(), CATCH_SUB_LEGENDARY: new Achv("catchSubLegendary", "", "catchSubLegendary.description", "rb", 75).setSecret(),
CATCH_LEGENDARY: new Achv("CATCH_LEGENDARY", "", "CATCH_LEGENDARY.description", "mb", 100).setSecret(), CATCH_LEGENDARY: new Achv("catchLegendary", "", "catchLegendary.description", "mb", 100).setSecret(),
SEE_SHINY: new Achv("SEE_SHINY", "", "SEE_SHINY.description", "pb_gold", 75), SEE_SHINY: new Achv("seeShiny", "", "seeShiny.description", "pb_gold", 75),
SHINY_PARTY: new Achv("SHINY_PARTY", "", "SHINY_PARTY.description", "shiny_charm", 100).setSecret(true), SHINY_PARTY: new Achv("shinyParty", "", "shinyParty.description", "shiny_charm", 100).setSecret(true),
HATCH_MYTHICAL: new Achv("HATCH_MYTHICAL", "", "HATCH_MYTHICAL.description", "mystery_egg", 75).setSecret(), HATCH_MYTHICAL: new Achv("hatchMythical", "", "hatchMythical.description", "mystery_egg", 75).setSecret(),
HATCH_SUB_LEGENDARY: new Achv( HATCH_SUB_LEGENDARY: new Achv(
"HATCH_SUB_LEGENDARY", "hatchSubLegendary",
"", "",
"HATCH_SUB_LEGENDARY.description", "hatchSubLegendary.description",
"oval_stone", "oval_stone",
100, 100,
).setSecret(), ).setSecret(),
HATCH_LEGENDARY: new Achv("HATCH_LEGENDARY", "", "HATCH_LEGENDARY.description", "lucky_egg", 125).setSecret(), HATCH_LEGENDARY: new Achv("hatchLegendary", "", "hatchLegendary.description", "lucky_egg", 125).setSecret(),
HATCH_SHINY: new Achv("HATCH_SHINY", "", "HATCH_SHINY.description", "golden_egg", 100).setSecret(), HATCH_SHINY: new Achv("hatchShiny", "", "hatchShiny.description", "golden_egg", 100).setSecret(),
HIDDEN_ABILITY: new Achv("HIDDEN_ABILITY", "", "HIDDEN_ABILITY.description", "ability_charm", 75), HIDDEN_ABILITY: new Achv("hiddenAbility", "", "hiddenAbility.description", "ability_charm", 75),
PERFECT_IVS: new Achv("PERFECT_IVS", "", "PERFECT_IVS.description", "blunder_policy", 100), PERFECT_IVS: new Achv("perfectIvs", "", "perfectIvs.description", "blunder_policy", 100),
CLASSIC_VICTORY: new Achv( CLASSIC_VICTORY: new Achv(
"CLASSIC_VICTORY", "classicVictory",
"", "",
"CLASSIC_VICTORY.description", "classicVictory.description",
"relic_crown", "relic_crown",
150, 150,
_ => globalScene.gameData.gameStats.sessionsWon === 0, _ => globalScene.gameData.gameStats.sessionsWon === 0,
), ),
UNEVOLVED_CLASSIC_VICTORY: new Achv( UNEVOLVED_CLASSIC_VICTORY: new Achv(
"UNEVOLVED_CLASSIC_VICTORY", "unevolvedClassicVictory",
"", "",
"UNEVOLVED_CLASSIC_VICTORY.description", "unevolvedClassicVictory.description",
"eviolite", "eviolite",
175, 175,
_ => globalScene.getPlayerParty().some(p => p.getSpeciesForm(true).speciesId in pokemonEvolutions), _ => globalScene.getPlayerParty().some(p => p.getSpeciesForm(true).speciesId in pokemonEvolutions),
), ),
MONO_GEN_ONE_VICTORY: new ChallengeAchv( MONO_GEN_ONE_VICTORY: new ChallengeAchv(
"MONO_GEN_ONE", "monoGenOne",
"", "",
"MONO_GEN_ONE.description", "monoGenOne.description",
"ribbon_gen1", "ribbon_gen1",
100, 100,
c => c =>
@ -546,9 +547,9 @@ export const achvs = {
), ),
), ),
MONO_GEN_TWO_VICTORY: new ChallengeAchv( MONO_GEN_TWO_VICTORY: new ChallengeAchv(
"MONO_GEN_TWO", "monoGenTwo",
"", "",
"MONO_GEN_TWO.description", "monoGenTwo.description",
"ribbon_gen2", "ribbon_gen2",
100, 100,
c => c =>
@ -559,9 +560,9 @@ export const achvs = {
), ),
), ),
MONO_GEN_THREE_VICTORY: new ChallengeAchv( MONO_GEN_THREE_VICTORY: new ChallengeAchv(
"MONO_GEN_THREE", "monoGenThree",
"", "",
"MONO_GEN_THREE.description", "monoGenThree.description",
"ribbon_gen3", "ribbon_gen3",
100, 100,
c => c =>
@ -572,9 +573,9 @@ export const achvs = {
), ),
), ),
MONO_GEN_FOUR_VICTORY: new ChallengeAchv( MONO_GEN_FOUR_VICTORY: new ChallengeAchv(
"MONO_GEN_FOUR", "monoGenFour",
"", "",
"MONO_GEN_FOUR.description", "monoGenFour.description",
"ribbon_gen4", "ribbon_gen4",
100, 100,
c => c =>
@ -585,9 +586,9 @@ export const achvs = {
), ),
), ),
MONO_GEN_FIVE_VICTORY: new ChallengeAchv( MONO_GEN_FIVE_VICTORY: new ChallengeAchv(
"MONO_GEN_FIVE", "monoGenFive",
"", "",
"MONO_GEN_FIVE.description", "monoGenFive.description",
"ribbon_gen5", "ribbon_gen5",
100, 100,
c => c =>
@ -598,9 +599,9 @@ export const achvs = {
), ),
), ),
MONO_GEN_SIX_VICTORY: new ChallengeAchv( MONO_GEN_SIX_VICTORY: new ChallengeAchv(
"MONO_GEN_SIX", "monoGenSix",
"", "",
"MONO_GEN_SIX.description", "monoGenSix.description",
"ribbon_gen6", "ribbon_gen6",
100, 100,
c => c =>
@ -611,9 +612,9 @@ export const achvs = {
), ),
), ),
MONO_GEN_SEVEN_VICTORY: new ChallengeAchv( MONO_GEN_SEVEN_VICTORY: new ChallengeAchv(
"MONO_GEN_SEVEN", "monoGenSeven",
"", "",
"MONO_GEN_SEVEN.description", "monoGenSeven.description",
"ribbon_gen7", "ribbon_gen7",
100, 100,
c => c =>
@ -624,9 +625,9 @@ export const achvs = {
), ),
), ),
MONO_GEN_EIGHT_VICTORY: new ChallengeAchv( MONO_GEN_EIGHT_VICTORY: new ChallengeAchv(
"MONO_GEN_EIGHT", "monoGenEight",
"", "",
"MONO_GEN_EIGHT.description", "monoGenEight.description",
"ribbon_gen8", "ribbon_gen8",
100, 100,
c => c =>
@ -637,9 +638,9 @@ export const achvs = {
), ),
), ),
MONO_GEN_NINE_VICTORY: new ChallengeAchv( MONO_GEN_NINE_VICTORY: new ChallengeAchv(
"MONO_GEN_NINE", "monoGenNine",
"", "",
"MONO_GEN_NINE.description", "monoGenNine.description",
"ribbon_gen9", "ribbon_gen9",
100, 100,
c => c =>
@ -650,9 +651,9 @@ export const achvs = {
), ),
), ),
MONO_NORMAL: new ChallengeAchv( MONO_NORMAL: new ChallengeAchv(
"MONO_NORMAL", "monoNormal",
"", "",
"MONO_NORMAL.description", "monoNormal.description",
"silk_scarf", "silk_scarf",
100, 100,
c => c =>
@ -663,9 +664,9 @@ export const achvs = {
), ),
), ),
MONO_FIGHTING: new ChallengeAchv( MONO_FIGHTING: new ChallengeAchv(
"MONO_FIGHTING", "monoFighting",
"", "",
"MONO_FIGHTING.description", "monoFighting.description",
"black_belt", "black_belt",
100, 100,
c => c =>
@ -676,9 +677,9 @@ export const achvs = {
), ),
), ),
MONO_FLYING: new ChallengeAchv( MONO_FLYING: new ChallengeAchv(
"MONO_FLYING", "monoFlying",
"", "",
"MONO_FLYING.description", "monoFlying.description",
"sharp_beak", "sharp_beak",
100, 100,
c => c =>
@ -689,9 +690,9 @@ export const achvs = {
), ),
), ),
MONO_POISON: new ChallengeAchv( MONO_POISON: new ChallengeAchv(
"MONO_POISON", "monoPoison",
"", "",
"MONO_POISON.description", "monoPoison.description",
"poison_barb", "poison_barb",
100, 100,
c => c =>
@ -702,9 +703,9 @@ export const achvs = {
), ),
), ),
MONO_GROUND: new ChallengeAchv( MONO_GROUND: new ChallengeAchv(
"MONO_GROUND", "monoGround",
"", "",
"MONO_GROUND.description", "monoGround.description",
"soft_sand", "soft_sand",
100, 100,
c => c =>
@ -715,9 +716,9 @@ export const achvs = {
), ),
), ),
MONO_ROCK: new ChallengeAchv( MONO_ROCK: new ChallengeAchv(
"MONO_ROCK", "monoRock",
"", "",
"MONO_ROCK.description", "monoRock.description",
"hard_stone", "hard_stone",
100, 100,
c => c =>
@ -728,9 +729,9 @@ export const achvs = {
), ),
), ),
MONO_BUG: new ChallengeAchv( MONO_BUG: new ChallengeAchv(
"MONO_BUG", "monoBug",
"", "",
"MONO_BUG.description", "monoBug.description",
"silver_powder", "silver_powder",
100, 100,
c => c =>
@ -741,9 +742,9 @@ export const achvs = {
), ),
), ),
MONO_GHOST: new ChallengeAchv( MONO_GHOST: new ChallengeAchv(
"MONO_GHOST", "monoGhost",
"", "",
"MONO_GHOST.description", "monoGhost.description",
"spell_tag", "spell_tag",
100, 100,
c => c =>
@ -754,9 +755,9 @@ export const achvs = {
), ),
), ),
MONO_STEEL: new ChallengeAchv( MONO_STEEL: new ChallengeAchv(
"MONO_STEEL", "monoSteel",
"", "",
"MONO_STEEL.description", "monoSteel.description",
"metal_coat", "metal_coat",
100, 100,
c => c =>
@ -767,9 +768,9 @@ export const achvs = {
), ),
), ),
MONO_FIRE: new ChallengeAchv( MONO_FIRE: new ChallengeAchv(
"MONO_FIRE", "monoFire",
"", "",
"MONO_FIRE.description", "monoFire.description",
"charcoal", "charcoal",
100, 100,
c => c =>
@ -780,9 +781,9 @@ export const achvs = {
), ),
), ),
MONO_WATER: new ChallengeAchv( MONO_WATER: new ChallengeAchv(
"MONO_WATER", "monoWater",
"", "",
"MONO_WATER.description", "monoWater.description",
"mystic_water", "mystic_water",
100, 100,
c => c =>
@ -793,9 +794,9 @@ export const achvs = {
), ),
), ),
MONO_GRASS: new ChallengeAchv( MONO_GRASS: new ChallengeAchv(
"MONO_GRASS", "monoGrass",
"", "",
"MONO_GRASS.description", "monoGrass.description",
"miracle_seed", "miracle_seed",
100, 100,
c => c =>
@ -806,9 +807,9 @@ export const achvs = {
), ),
), ),
MONO_ELECTRIC: new ChallengeAchv( MONO_ELECTRIC: new ChallengeAchv(
"MONO_ELECTRIC", "monoElectric",
"", "",
"MONO_ELECTRIC.description", "monoElectric.description",
"magnet", "magnet",
100, 100,
c => c =>
@ -819,9 +820,9 @@ export const achvs = {
), ),
), ),
MONO_PSYCHIC: new ChallengeAchv( MONO_PSYCHIC: new ChallengeAchv(
"MONO_PSYCHIC", "monoPsychic",
"", "",
"MONO_PSYCHIC.description", "monoPsychic.description",
"twisted_spoon", "twisted_spoon",
100, 100,
c => c =>
@ -832,9 +833,9 @@ export const achvs = {
), ),
), ),
MONO_ICE: new ChallengeAchv( MONO_ICE: new ChallengeAchv(
"MONO_ICE", "monoIce",
"", "",
"MONO_ICE.description", "monoIce.description",
"never_melt_ice", "never_melt_ice",
100, 100,
c => c =>
@ -845,9 +846,9 @@ export const achvs = {
), ),
), ),
MONO_DRAGON: new ChallengeAchv( MONO_DRAGON: new ChallengeAchv(
"MONO_DRAGON", "monoDragon",
"", "",
"MONO_DRAGON.description", "monoDragon.description",
"dragon_fang", "dragon_fang",
100, 100,
c => c =>
@ -858,9 +859,9 @@ export const achvs = {
), ),
), ),
MONO_DARK: new ChallengeAchv( MONO_DARK: new ChallengeAchv(
"MONO_DARK", "monoDark",
"", "",
"MONO_DARK.description", "monoDark.description",
"black_glasses", "black_glasses",
100, 100,
c => c =>
@ -871,9 +872,9 @@ export const achvs = {
), ),
), ),
MONO_FAIRY: new ChallengeAchv( MONO_FAIRY: new ChallengeAchv(
"MONO_FAIRY", "monoFairy",
"", "",
"MONO_FAIRY.description", "monoFairy.description",
"fairy_feather", "fairy_feather",
100, 100,
c => c =>
@ -884,9 +885,9 @@ export const achvs = {
), ),
), ),
FRESH_START: new ChallengeAchv( FRESH_START: new ChallengeAchv(
"FRESH_START", "freshStart",
"", "",
"FRESH_START.description", "freshStart.description",
"reviver_seed", "reviver_seed",
100, 100,
c => c =>
@ -897,25 +898,25 @@ export const achvs = {
), ),
), ),
INVERSE_BATTLE: new ChallengeAchv( INVERSE_BATTLE: new ChallengeAchv(
"INVERSE_BATTLE", "inverseBattle",
"", "",
"INVERSE_BATTLE.description", "inverseBattle.description",
"inverse", "inverse",
100, 100,
c => c instanceof InverseBattleChallenge && c.value > 0, c => c instanceof InverseBattleChallenge && c.value > 0,
), ),
FLIP_STATS: new ChallengeAchv( FLIP_STATS: new ChallengeAchv(
"FLIP_STATS", "flipStats",
"", "",
"FLIP_STATS.description", "flipStats.description",
"dubious_disc", "dubious_disc",
100, 100,
c => c instanceof FlipStatChallenge && c.value > 0, c => c instanceof FlipStatChallenge && c.value > 0,
), ),
FLIP_INVERSE: new ChallengeAchv( FLIP_INVERSE: new ChallengeAchv(
"FLIP_INVERSE", "flipInverse",
"", "",
"FLIP_INVERSE.description", "flipInverse.description",
"cracked_pot", "cracked_pot",
100, 100,
c => c =>
@ -925,9 +926,9 @@ export const achvs = {
).setSecret(), ).setSecret(),
// TODO: Decide on icon // TODO: Decide on icon
NUZLOCKE: new ChallengeAchv( NUZLOCKE: new ChallengeAchv(
"NUZLOCKE", "nuzlocke",
"", "",
"NUZLOCKE.description", "nuzlocke.description",
"leaf_stone", "leaf_stone",
100, 100,
c => c =>
@ -936,7 +937,7 @@ export const achvs = {
globalScene.gameMode.challenges.some(c => c.id === Challenges.HARDCORE && c.value > 0) && globalScene.gameMode.challenges.some(c => c.id === Challenges.HARDCORE && c.value > 0) &&
globalScene.gameMode.challenges.some(c => c.id === Challenges.FRESH_START && c.value > 0), globalScene.gameMode.challenges.some(c => c.id === Challenges.FRESH_START && c.value > 0),
), ),
BREEDERS_IN_SPACE: new Achv("BREEDERS_IN_SPACE", "", "BREEDERS_IN_SPACE.description", "moon_stone", 50).setSecret(), BREEDERS_IN_SPACE: new Achv("breedersInSpace", "", "breedersInSpace.description", "moon_stone", 50).setSecret(),
}; };
export function initAchievements() { export function initAchievements() {

View File

@ -96,7 +96,7 @@ export class AchvsUiHandler extends MessageUiHandler {
const genderIndex = globalScene.gameData.gender ?? PlayerGender.MALE; const genderIndex = globalScene.gameData.gender ?? PlayerGender.MALE;
const genderStr = PlayerGender[genderIndex].toLowerCase(); const genderStr = PlayerGender[genderIndex].toLowerCase();
this.achvsName = i18next.t("achv:Achievements.name", { context: genderStr }); this.achvsName = i18next.t("achv:achievements.name", { context: genderStr });
this.vouchersName = i18next.t("voucher:vouchers"); this.vouchersName = i18next.t("voucher:vouchers");
this.iconsBg = addWindow(0, this.headerBg.height, WIDTH - 2, HEIGHT - this.headerBg.height - 68).setOrigin(0); this.iconsBg = addWindow(0, this.headerBg.height, WIDTH - 2, HEIGHT - this.headerBg.height - 68).setOrigin(0);
@ -214,7 +214,7 @@ export class AchvsUiHandler extends MessageUiHandler {
this.showText(!hidden ? achv.description : ""); this.showText(!hidden ? achv.description : "");
this.scoreText.setText(`${achv.score}pt`); this.scoreText.setText(`${achv.score}pt`);
this.unlockText.setText( this.unlockText.setText(
unlocked ? new Date(achvUnlocks[achv.id]).toLocaleDateString() : i18next.t("achv:Locked.name"), unlocked ? new Date(achvUnlocks[achv.id]).toLocaleDateString() : i18next.t("achv:locked.name"),
); );
} }

View File

@ -1,7 +1,7 @@
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { TextStyle } from "#enums/text-style"; import { TextStyle } from "#enums/text-style";
import { addTextObject } from "#ui/text"; import { addTextObject } from "#ui/text";
import { toTitleCase } from "#utils/strings"; import { toCamelCase, toTitleCase } from "#utils/strings";
import i18next from "i18next"; import i18next from "i18next";
const hiddenX = -150; const hiddenX = -150;
@ -100,7 +100,7 @@ export class BgmBar extends Phaser.GameObjects.Container {
} }
getRealBgmName(bgmName: string): string { getRealBgmName(bgmName: string): string {
return i18next.t([`bgmName:${bgmName}`, "bgmName:missing_entries"], { return i18next.t([`bgmName:${toCamelCase(bgmName)}`, "bgmName:missingEntries"], {
name: toTitleCase(bgmName), name: toTitleCase(bgmName),
}); });
} }