diff --git a/public/images/pokemon/variant/exp/9-mega_2.json b/public/images/pokemon/variant/exp/9-mega_2.json new file mode 100644 index 00000000000..ab160a44451 --- /dev/null +++ b/public/images/pokemon/variant/exp/9-mega_2.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "9-mega_2.png", + "format": "RGBA8888", + "size": { + "w": 88, + "h": 88 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 88, + "h": 87 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 88, + "h": 87 + }, + "frame": { + "x": 0, + "y": 0, + "w": 88, + "h": 87 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:9b1bebbbe735399ba2678aa35a42b156:2dc7c20135acd855e9e97cb010985396:00f61506d33ec61875296e0fb5a82ee9$" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/9-mega_2.png b/public/images/pokemon/variant/exp/9-mega_2.png new file mode 100644 index 00000000000..c3c06c1eca7 Binary files /dev/null and b/public/images/pokemon/variant/exp/9-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/9-mega_3.json b/public/images/pokemon/variant/exp/9-mega_3.json new file mode 100644 index 00000000000..24363c06a12 --- /dev/null +++ b/public/images/pokemon/variant/exp/9-mega_3.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "9-mega_3.png", + "format": "RGBA8888", + "size": { + "w": 88, + "h": 88 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 88, + "h": 87 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 88, + "h": 87 + }, + "frame": { + "x": 0, + "y": 0, + "w": 88, + "h": 87 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:9b1bebbbe735399ba2678aa35a42b156:2dc7c20135acd855e9e97cb010985396:00f61506d33ec61875296e0fb5a82ee9$" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/9-mega_3.png b/public/images/pokemon/variant/exp/9-mega_3.png new file mode 100644 index 00000000000..d7a4b6f9140 Binary files /dev/null and b/public/images/pokemon/variant/exp/9-mega_3.png differ diff --git a/public/images/pokemon/variant/exp/back/9-mega_2.json b/public/images/pokemon/variant/exp/back/9-mega_2.json new file mode 100644 index 00000000000..42d17ca7d0a --- /dev/null +++ b/public/images/pokemon/variant/exp/back/9-mega_2.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "9-mega_2.png", + "format": "RGBA8888", + "size": { + "w": 77, + "h": 77 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 77, + "h": 77 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 77, + "h": 77 + }, + "frame": { + "x": 0, + "y": 0, + "w": 77, + "h": 77 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:5d9f38fc4da0e99e00a40be3452a927c:2c58504a78e2752d4c536f8a79dab703:00f61506d33ec61875296e0fb5a82ee9$" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/9-mega_2.png b/public/images/pokemon/variant/exp/back/9-mega_2.png new file mode 100644 index 00000000000..e961ace2e5c Binary files /dev/null and b/public/images/pokemon/variant/exp/back/9-mega_2.png differ diff --git a/public/images/pokemon/variant/exp/back/9-mega_3.json b/public/images/pokemon/variant/exp/back/9-mega_3.json new file mode 100644 index 00000000000..f108154d97a --- /dev/null +++ b/public/images/pokemon/variant/exp/back/9-mega_3.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "9-mega_3.png", + "format": "RGBA8888", + "size": { + "w": 77, + "h": 77 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 77, + "h": 77 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 77, + "h": 77 + }, + "frame": { + "x": 0, + "y": 0, + "w": 77, + "h": 77 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:5d9f38fc4da0e99e00a40be3452a927c:2c58504a78e2752d4c536f8a79dab703:00f61506d33ec61875296e0fb5a82ee9$" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/9-mega_3.png b/public/images/pokemon/variant/exp/back/9-mega_3.png new file mode 100644 index 00000000000..95a7babe58b Binary files /dev/null and b/public/images/pokemon/variant/exp/back/9-mega_3.png differ diff --git a/public/images/types/bug.png b/public/images/types/bug.png deleted file mode 100644 index 72681086ec6..00000000000 Binary files a/public/images/types/bug.png and /dev/null differ diff --git a/public/images/types/dark.png b/public/images/types/dark.png deleted file mode 100644 index 6605a95bb4c..00000000000 Binary files a/public/images/types/dark.png and /dev/null differ diff --git a/public/images/types/dragon.png b/public/images/types/dragon.png deleted file mode 100644 index 3554bc8bd68..00000000000 Binary files a/public/images/types/dragon.png and /dev/null differ diff --git a/public/images/types/electric.png b/public/images/types/electric.png deleted file mode 100644 index ea5008652c5..00000000000 Binary files a/public/images/types/electric.png and /dev/null differ diff --git a/public/images/types/fairy.png b/public/images/types/fairy.png deleted file mode 100644 index f8ca169d3aa..00000000000 Binary files a/public/images/types/fairy.png and /dev/null differ diff --git a/public/images/types/fighting.png b/public/images/types/fighting.png deleted file mode 100644 index 0fd87f3dbd9..00000000000 Binary files a/public/images/types/fighting.png and /dev/null differ diff --git a/public/images/types/fire.png b/public/images/types/fire.png deleted file mode 100644 index 08a550fcaff..00000000000 Binary files a/public/images/types/fire.png and /dev/null differ diff --git a/public/images/types/flying.png b/public/images/types/flying.png deleted file mode 100644 index 3a13e051222..00000000000 Binary files a/public/images/types/flying.png and /dev/null differ diff --git a/public/images/types/ghost.png b/public/images/types/ghost.png deleted file mode 100644 index f32896bed02..00000000000 Binary files a/public/images/types/ghost.png and /dev/null differ diff --git a/public/images/types/grass.png b/public/images/types/grass.png deleted file mode 100644 index 35dfecfc2d2..00000000000 Binary files a/public/images/types/grass.png and /dev/null differ diff --git a/public/images/types/ground.png b/public/images/types/ground.png deleted file mode 100644 index 0df975559b6..00000000000 Binary files a/public/images/types/ground.png and /dev/null differ diff --git a/public/images/types/ice.png b/public/images/types/ice.png deleted file mode 100644 index 57ea33f9b16..00000000000 Binary files a/public/images/types/ice.png and /dev/null differ diff --git a/public/images/types/normal.png b/public/images/types/normal.png deleted file mode 100644 index 92524168f5c..00000000000 Binary files a/public/images/types/normal.png and /dev/null differ diff --git a/public/images/types/poison.png b/public/images/types/poison.png deleted file mode 100644 index c898b4d14a9..00000000000 Binary files a/public/images/types/poison.png and /dev/null differ diff --git a/public/images/types/psychic.png b/public/images/types/psychic.png deleted file mode 100644 index ff55bc54a60..00000000000 Binary files a/public/images/types/psychic.png and /dev/null differ diff --git a/public/images/types/rock.png b/public/images/types/rock.png deleted file mode 100644 index 0a90b780a24..00000000000 Binary files a/public/images/types/rock.png and /dev/null differ diff --git a/public/images/types/steel.png b/public/images/types/steel.png deleted file mode 100644 index 34e2ad73db8..00000000000 Binary files a/public/images/types/steel.png and /dev/null differ diff --git a/public/images/types/stellar.png b/public/images/types/stellar.png deleted file mode 100644 index 6ca5e5bdbc4..00000000000 Binary files a/public/images/types/stellar.png and /dev/null differ diff --git a/public/images/types/unknown.png b/public/images/types/unknown.png deleted file mode 100644 index 607111adefb..00000000000 Binary files a/public/images/types/unknown.png and /dev/null differ diff --git a/public/images/types/water.png b/public/images/types/water.png deleted file mode 100644 index eb618008d00..00000000000 Binary files a/public/images/types/water.png and /dev/null differ diff --git a/src/@types/i18next.d.ts b/src/@types/i18next.d.ts index 0c76c169b51..c4a867b9d73 100644 --- a/src/@types/i18next.d.ts +++ b/src/@types/i18next.d.ts @@ -1,4 +1,4 @@ -import { AbilityTranslationEntries, SimpleTranslationEntries, AchievementTranslationEntries, BerryTranslationEntries, DialogueTranslationEntries, ModifierTypeTranslationEntries, MoveTranslationEntries, PokemonInfoTranslationEntries } from "#app/interfaces/locales"; +import { AbilityTranslationEntries, SimpleTranslationEntries, AchievementTranslationEntries, BerryTranslationEntries, DialogueTranslationEntries, ModifierTypeTranslationEntries, MoveTranslationEntries, PokemonInfoTranslationEntries, TranslationEntries } from "#app/interfaces/locales"; // Module declared to make referencing keys in the localization files type-safe. declare module "i18next" { @@ -14,6 +14,7 @@ declare module "i18next" { biome: SimpleTranslationEntries; challenges: SimpleTranslationEntries; commandUiHandler: SimpleTranslationEntries; + common: TranslationEntries; PGMachv: AchievementTranslationEntries; PGFachv: AchievementTranslationEntries; PGMdialogue: DialogueTranslationEntries; diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 163ca41a406..43224ab074b 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -3,6 +3,7 @@ import UI from "./ui/ui"; import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, MovePhase, TitlePhase, SwitchPhase } from "./phases"; import Pokemon, { PlayerPokemon, EnemyPokemon } from "./field/pokemon"; import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies } from "./data/pokemon-species"; +import { Constructor } from "#app/utils"; import * as Utils from "./utils"; import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, overrideModifiers, overrideHeldItems } from "./modifier/modifier"; import { PokeballType } from "./data/pokeball"; @@ -2340,8 +2341,14 @@ export default class BattleScene extends SceneBase { return false; } - getModifiers(modifierType: { new(...args: any[]): Modifier }, player: boolean = true): PersistentModifier[] { - return (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType); + /** + * Get all of the modifiers that match `modifierType` + * @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier} + * @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true` + * @returns the list of all modifiers that matched `modifierType`. + */ + getModifiers(modifierType: Constructor, player: boolean = true): T[] { + return (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType); } findModifiers(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier[] { @@ -2352,7 +2359,7 @@ export default class BattleScene extends SceneBase { return (player ? this.modifiers : this.enemyModifiers).find(m => (modifierFilter as ModifierPredicate)(m)); } - applyShuffledModifiers(scene: BattleScene, modifierType: { new(...args: any[]): Modifier }, player: boolean = true, ...args: any[]): PersistentModifier[] { + applyShuffledModifiers(scene: BattleScene, modifierType: Constructor, player: boolean = true, ...args: any[]): PersistentModifier[] { let modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args)); scene.executeWithSeedOffset(() => { const shuffleModifiers = mods => { @@ -2367,7 +2374,7 @@ export default class BattleScene extends SceneBase { return this.applyModifiersInternal(modifiers, player, args); } - applyModifiers(modifierType: { new(...args: any[]): Modifier }, player: boolean = true, ...args: any[]): PersistentModifier[] { + applyModifiers(modifierType: Constructor, player: boolean = true, ...args: any[]): PersistentModifier[] { const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args)); return this.applyModifiersInternal(modifiers, player, args); } @@ -2384,7 +2391,7 @@ export default class BattleScene extends SceneBase { return appliedModifiers; } - applyModifier(modifierType: { new(...args: any[]): Modifier }, player: boolean = true, ...args: any[]): PersistentModifier { + applyModifier(modifierType: Constructor, player: boolean = true, ...args: any[]): PersistentModifier { const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args)); for (const modifier of modifiers) { if (modifier.apply(args)) { @@ -2396,7 +2403,7 @@ export default class BattleScene extends SceneBase { return null; } - triggerPokemonFormChange(pokemon: Pokemon, formChangeTriggerType: { new(...args: any[]): SpeciesFormChangeTrigger }, delayed: boolean = false, modal: boolean = false): boolean { + triggerPokemonFormChange(pokemon: Pokemon, formChangeTriggerType: Constructor, delayed: boolean = false, modal: boolean = false): boolean { if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId)) { const matchingFormChange = pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.findTrigger(formChangeTriggerType) && fc.canChange(pokemon)); if (matchingFormChange) { @@ -2420,7 +2427,7 @@ export default class BattleScene extends SceneBase { return false; } - validateAchvs(achvType: { new(...args: any[]): Achv }, ...args: any[]): void { + validateAchvs(achvType: Constructor, ...args: unknown[]): void { const filteredAchvs = Object.values(achvs).filter(a => a instanceof achvType); for (const achv of filteredAchvs) { this.validateAchv(achv, args); diff --git a/src/data/ability.ts b/src/data/ability.ts index e1d047c7806..9cb4cae9db9 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -1,5 +1,6 @@ import Pokemon, { HitResult, PokemonMove } from "../field/pokemon"; import { Type } from "./type"; +import { Constructor } from "#app/utils"; import * as Utils from "../utils"; import { BattleStat, getBattleStatName } from "./battle-stat"; import { MovePhase, PokemonHealPhase, ShowAbilityPhase, StatChangePhase } from "../phases"; @@ -61,7 +62,7 @@ export class Ability implements Localizable { * @param attrType any attribute that extends {@linkcode AbAttr} * @returns Array of attributes that match `attrType`, Empty Array if none match. */ - getAttrs(attrType: new(...args: any[]) => T ): T[] { + getAttrs(attrType: Constructor ): T[] { return this.attrs.filter((a): a is T => a instanceof attrType); } @@ -70,18 +71,18 @@ export class Ability implements Localizable { * @param attrType any attribute that extends {@linkcode AbAttr} * @returns true if the ability has attribute `attrType` */ - hasAttr(attrType: new(...args: any[]) => T): boolean { + hasAttr(attrType: Constructor): boolean { return this.attrs.some((attr) => attr instanceof attrType); } - attr AbAttr>(AttrType: T, ...args: ConstructorParameters): Ability { + attr>(AttrType: T, ...args: ConstructorParameters): Ability { const attr = new AttrType(...args); this.attrs.push(attr); return this; } - conditionalAttr AbAttr>(condition: AbAttrCondition, AttrType: T, ...args: ConstructorParameters): Ability { + conditionalAttr>(condition: AbAttrCondition, AttrType: T, ...args: ConstructorParameters): Ability { const attr = new AttrType(...args); attr.addCondition(condition); this.attrs.push(attr); @@ -2483,6 +2484,9 @@ function getSheerForceHitDisableAbCondition(): AbAttrCondition { function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition { return (pokemon: Pokemon) => { + if (!pokemon.scene?.arena) { + return false; + } if (pokemon.scene.arena.weather?.isEffectSuppressed(pokemon.scene)) { return false; } @@ -3682,13 +3686,21 @@ export class PostSummonStatChangeOnArenaAbAttr extends PostSummonStatChangeAbAtt } /** - * Applies immunity to physical moves. + * Takes no damage from the first hit of a physical move. * This is used in Ice Face ability. */ -export class IceFaceMoveImmunityAbAttr extends MoveImmunityAbAttr { +export class IceFaceBlockPhysicalAbAttr extends ReceivedMoveDamageMultiplierAbAttr { + private multiplier: number; + + constructor(condition: PokemonDefendCondition, multiplier: number) { + super(condition, multiplier); + + this.multiplier = multiplier; + } + /** * Applies the Ice Face pre-defense ability to the Pokémon. - * Removes BattlerTagType.ICE_FACE hit by physical attack and is in Ice Face form. + * Removes BattlerTagType.ICE_FACE when hit by physical attack and is in Ice Face form. * * @param {Pokemon} pokemon - The Pokémon with the Ice Face ability. * @param {boolean} passive - Whether the ability is passive. @@ -3699,16 +3711,13 @@ export class IceFaceMoveImmunityAbAttr extends MoveImmunityAbAttr { * @returns {boolean} - Whether the immunity was applied. */ applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean { - const isImmune = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args); - - if (isImmune) { - const simulated = args.length > 1 && args[1]; - if (!simulated) { - pokemon.removeTag(BattlerTagType.ICE_FACE); - } + if (this.condition(pokemon, attacker, move)) { + (args[0] as Utils.NumberHolder).value = this.multiplier; + pokemon.removeTag(BattlerTagType.ICE_FACE); + return true; } - return isImmune; + return false; } /** @@ -3723,7 +3732,7 @@ export class IceFaceMoveImmunityAbAttr extends MoveImmunityAbAttr { } } -function applyAbAttrsInternal(attrType: { new(...args: any[]): TAttr }, +function applyAbAttrsInternal(attrType: Constructor, pokemon: Pokemon, applyFunc: AbAttrApplyFunc, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise { return new Promise(resolve => { if (!pokemon.canApplyAbility(passive)) { @@ -3738,7 +3747,7 @@ function applyAbAttrsInternal(attrType: { new(...args: any const attrs = ability.getAttrs(attrType); const clearSpliceQueueAndResolve = () => { - pokemon.scene.clearPhaseQueueSplice(); + pokemon.scene?.clearPhaseQueueSplice(); if (!passive) { return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve()); } else { @@ -3801,32 +3810,32 @@ function applyAbAttrsInternal(attrType: { new(...args: any }); } -export function applyAbAttrs(attrType: { new(...args: any[]): AbAttr }, pokemon: Pokemon, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { +export function applyAbAttrs(attrType: Constructor, pokemon: Pokemon, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.apply(pokemon, passive, cancelled, args), args); } -export function applyPostBattleInitAbAttrs(attrType: { new(...args: any[]): PostBattleInitAbAttr }, +export function applyPostBattleInitAbAttrs(attrType: Constructor, pokemon: Pokemon, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostBattleInit(pokemon, passive, args), args); } -export function applyPreDefendAbAttrs(attrType: { new(...args: any[]): PreDefendAbAttr }, +export function applyPreDefendAbAttrs(attrType: Constructor, pokemon: Pokemon, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { const simulated = args.length > 1 && args[1]; return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreDefend(pokemon, passive, attacker, move, cancelled, args), args, false, false, simulated); } -export function applyPostDefendAbAttrs(attrType: { new(...args: any[]): PostDefendAbAttr }, +export function applyPostDefendAbAttrs(attrType: Constructor, pokemon: Pokemon, attacker: Pokemon, move: Move, hitResult: HitResult, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostDefend(pokemon, passive, attacker, move, hitResult, args), args); } -export function applyPostMoveUsedAbAttrs(attrType: { new(...args: any[]): PostMoveUsedAbAttr }, +export function applyPostMoveUsedAbAttrs(attrType: Constructor, pokemon: Pokemon, move: PokemonMove, source: Pokemon, targets: BattlerIndex[], ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostMoveUsed(pokemon, move, source, targets, args), args); } -export function applyBattleStatMultiplierAbAttrs(attrType: { new(...args: any[]): BattleStatMultiplierAbAttr }, +export function applyBattleStatMultiplierAbAttrs(attrType: Constructor, pokemon: Pokemon, battleStat: BattleStat, statValue: Utils.NumberHolder, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyBattleStat(pokemon, passive, battleStat, statValue, args), args); } @@ -3841,98 +3850,98 @@ export function applyBattleStatMultiplierAbAttrs(attrType: { new(...args: any[]) * @param hasApplied {@linkcode Utils.BooleanHolder} whether or not a FieldMultiplyBattleStatAbAttr has already affected this stat * @param args unused */ -export function applyFieldBattleStatMultiplierAbAttrs(attrType: { new(...args: any[]): FieldMultiplyBattleStatAbAttr }, +export function applyFieldBattleStatMultiplierAbAttrs(attrType: Constructor, pokemon: Pokemon, stat: Stat, statValue: Utils.NumberHolder, checkedPokemon: Pokemon, hasApplied: Utils.BooleanHolder, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyFieldBattleStat(pokemon, passive, stat, statValue, checkedPokemon, hasApplied, args), args); } -export function applyPreAttackAbAttrs(attrType: { new(...args: any[]): PreAttackAbAttr }, +export function applyPreAttackAbAttrs(attrType: Constructor, pokemon: Pokemon, defender: Pokemon, move: Move, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreAttack(pokemon, passive, defender, move, args), args); } -export function applyPostAttackAbAttrs(attrType: { new(...args: any[]): PostAttackAbAttr }, +export function applyPostAttackAbAttrs(attrType: Constructor, pokemon: Pokemon, defender: Pokemon, move: Move, hitResult: HitResult, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostAttack(pokemon, passive, defender, move, hitResult, args), args); } -export function applyPostKnockOutAbAttrs(attrType: { new(...args: any[]): PostKnockOutAbAttr }, +export function applyPostKnockOutAbAttrs(attrType: Constructor, pokemon: Pokemon, knockedOut: Pokemon, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostKnockOut(pokemon, passive, knockedOut, args), args); } -export function applyPostVictoryAbAttrs(attrType: { new(...args: any[]): PostVictoryAbAttr }, +export function applyPostVictoryAbAttrs(attrType: Constructor, pokemon: Pokemon, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostVictory(pokemon, passive, args), args); } -export function applyPostSummonAbAttrs(attrType: { new(...args: any[]): PostSummonAbAttr }, +export function applyPostSummonAbAttrs(attrType: Constructor, pokemon: Pokemon, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostSummon(pokemon, passive, args), args); } -export function applyPreSwitchOutAbAttrs(attrType: { new(...args: any[]): PreSwitchOutAbAttr }, +export function applyPreSwitchOutAbAttrs(attrType: Constructor, pokemon: Pokemon, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreSwitchOut(pokemon, passive, args), args, false, true); } -export function applyPreStatChangeAbAttrs(attrType: { new(...args: any[]): PreStatChangeAbAttr }, +export function applyPreStatChangeAbAttrs(attrType: Constructor, pokemon: Pokemon, stat: BattleStat, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreStatChange(pokemon, passive, stat, cancelled, args), args); } -export function applyPostStatChangeAbAttrs(attrType: { new(...args: any[]): PostStatChangeAbAttr }, +export function applyPostStatChangeAbAttrs(attrType: Constructor, pokemon: Pokemon, stats: BattleStat[], levels: integer, selfTarget: boolean, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostStatChange(pokemon, stats, levels, selfTarget, args), args); } -export function applyPreSetStatusAbAttrs(attrType: { new(...args: any[]): PreSetStatusAbAttr }, +export function applyPreSetStatusAbAttrs(attrType: Constructor, pokemon: Pokemon, effect: StatusEffect, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { const simulated = args.length > 1 && args[1]; return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreSetStatus(pokemon, passive, effect, cancelled, args), args, false, false, !simulated); } -export function applyPreApplyBattlerTagAbAttrs(attrType: { new(...args: any[]): PreApplyBattlerTagAbAttr }, +export function applyPreApplyBattlerTagAbAttrs(attrType: Constructor, pokemon: Pokemon, tag: BattlerTag, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreApplyBattlerTag(pokemon, passive, tag, cancelled, args), args); } -export function applyPreWeatherEffectAbAttrs(attrType: { new(...args: any[]): PreWeatherEffectAbAttr }, +export function applyPreWeatherEffectAbAttrs(attrType: Constructor, pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreWeatherEffect(pokemon, passive, weather, cancelled, args), args, false, true); } -export function applyPostTurnAbAttrs(attrType: { new(...args: any[]): PostTurnAbAttr }, +export function applyPostTurnAbAttrs(attrType: Constructor, pokemon: Pokemon, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostTurn(pokemon, passive, args), args); } -export function applyPostWeatherChangeAbAttrs(attrType: { new(...args: any[]): PostWeatherChangeAbAttr }, +export function applyPostWeatherChangeAbAttrs(attrType: Constructor, pokemon: Pokemon, weather: WeatherType, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostWeatherChange(pokemon, passive, weather, args), args); } -export function applyPostWeatherLapseAbAttrs(attrType: { new(...args: any[]): PostWeatherLapseAbAttr }, +export function applyPostWeatherLapseAbAttrs(attrType: Constructor, pokemon: Pokemon, weather: Weather, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostWeatherLapse(pokemon, passive, weather, args), args); } -export function applyPostTerrainChangeAbAttrs(attrType: { new(...args: any[]): PostTerrainChangeAbAttr }, +export function applyPostTerrainChangeAbAttrs(attrType: Constructor, pokemon: Pokemon, terrain: TerrainType, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostTerrainChange(pokemon, passive, terrain, args), args); } -export function applyCheckTrappedAbAttrs(attrType: { new(...args: any[]): CheckTrappedAbAttr }, +export function applyCheckTrappedAbAttrs(attrType: Constructor, pokemon: Pokemon, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyCheckTrapped(pokemon, passive, trapped, otherPokemon, args), args, true); } -export function applyPostBattleAbAttrs(attrType: { new(...args: any[]): PostBattleAbAttr }, +export function applyPostBattleAbAttrs(attrType: Constructor, pokemon: Pokemon, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostBattle(pokemon, passive, args), args); } -export function applyPostFaintAbAttrs(attrType: { new(...args: any[]): PostFaintAbAttr }, +export function applyPostFaintAbAttrs(attrType: Constructor, pokemon: Pokemon, attacker: Pokemon, move: Move, hitResult: HitResult, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPostFaint(pokemon, passive, attacker, move, hitResult, args), args); } @@ -4768,7 +4777,7 @@ export function initAbilities() { .conditionalAttr(getWeatherCondition(WeatherType.HAIL, WeatherType.SNOW), PostSummonAddBattlerTagAbAttr, BattlerTagType.ICE_FACE, 0) // When weather changes to HAIL or SNOW while pokemon is fielded, add BattlerTagType.ICE_FACE .attr(PostWeatherChangeAddBattlerTagAttr, BattlerTagType.ICE_FACE, 0, WeatherType.HAIL, WeatherType.SNOW) - .attr(IceFaceMoveImmunityAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE)) + .attr(IceFaceBlockPhysicalAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0) .ignorable(), new Ability(Abilities.POWER_SPOT, 8) .attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL], 1.3), diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index db02803c5ea..4e2a4e06d3c 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -17,6 +17,7 @@ import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#enums/battler-tag-type"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import i18next from "#app/plugins/i18n.js"; export enum BattlerTagLapseType { FAINT, @@ -105,7 +106,7 @@ export class RechargingTag extends BattlerTag { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { super.lapse(pokemon, lapseType); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " must\nrecharge!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsRechargingLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); (pokemon.scene.getCurrentPhase() as MovePhase).cancel(); pokemon.getMoveQueue().shift(); @@ -134,7 +135,10 @@ export class TrappedTag extends BattlerTag { onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` was freed\nfrom ${this.getMoveName()}!`)); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsTrappedOnRemove", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + moveName: this.getMoveName() + })); } getDescriptor(): string { @@ -146,7 +150,7 @@ export class TrappedTag extends BattlerTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon, " can no\nlonger escape!"); + return i18next.t("battle:battlerTagsTrappedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } } @@ -169,7 +173,7 @@ export class FlinchedTag extends BattlerTag { super.lapse(pokemon, lapseType); (pokemon.scene.getCurrentPhase() as MovePhase).cancel(); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " flinched!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsFlinchedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); return true; } @@ -218,26 +222,26 @@ export class ConfusedTag extends BattlerTag { super.onAdd(pokemon); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " became\nconfused!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsConfusedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " snapped\nout of confusion!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsConfusedOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } onOverlap(pokemon: Pokemon): void { super.onOverlap(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nalready confused!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsConfusedOnOverlap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { const ret = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType); if (ret) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nconfused!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsConfusedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); // 1/3 chance of hitting self with a 40 base power move @@ -245,7 +249,7 @@ export class ConfusedTag extends BattlerTag { const atk = pokemon.getBattleStat(Stat.ATK); const def = pokemon.getBattleStat(Stat.DEF); const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100)); - pokemon.scene.queueMessage("It hurt itself in its\nconfusion!"); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsConfusedLapseHurtItself")); pokemon.damageAndUpdate(damage); pokemon.battleData.hitCount++; (pokemon.scene.getCurrentPhase() as MovePhase).cancel(); @@ -292,14 +296,17 @@ export class DestinyBondTag extends BattlerTag { return false; } - const targetMessage = getPokemonMessage(pokemon, ""); - if (pokemon.isBossImmune()) { - pokemon.scene.queueMessage(`${targetMessage} is unaffected\nby the effects of Destiny Bond.`); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsDestinyBondLapseIsBoss", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); return false; } - pokemon.scene.queueMessage(`${getPokemonMessage(source, ` took\n${targetMessage} down with it!`)}`); + pokemon.scene.queueMessage( + i18next.t("battle:battlerTagsDestinyBondLapse", { + pokemonNameWithAffix: getPokemonNameWithAffix(source), + pokemonNameWithAffix2: getPokemonNameWithAffix(pokemon) + }) + ); pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, false, true); return false; } @@ -317,24 +324,34 @@ export class InfatuatedTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` fell in love\nwith ${pokemon.scene.getPokemonById(this.sourceId).name}!`)); + pokemon.scene.queueMessage( + i18next.t("battle:battlerTagsInfatuatedOnAdd", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + sourcePokemonName: pokemon.scene.getPokemonById(this.sourceId).name + }) + ); } onOverlap(pokemon: Pokemon): void { super.onOverlap(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nalready in love!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsInfatuatedOnOverlap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); if (ret) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is in love\nwith ${pokemon.scene.getPokemonById(this.sourceId).name}!`)); + pokemon.scene.queueMessage( + i18next.t("battle:battlerTagsInfatuatedLapse", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + sourcePokemonName: pokemon.scene.getPokemonById(this.sourceId).name + }) + ); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT)); if (pokemon.randSeedInt(2)) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nimmobilized by love!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsInfatuatedLapseImmobilize", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); (pokemon.scene.getCurrentPhase() as MovePhase).cancel(); } } @@ -345,7 +362,7 @@ export class InfatuatedTag extends BattlerTag { onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " got over\nits infatuation.")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsInfatuatedOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } isSourceLinked(): boolean { @@ -380,7 +397,7 @@ export class SeedTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " was seeded!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsSeededOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); } @@ -400,7 +417,7 @@ export class SeedTag extends BattlerTag { const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr, false); pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(), !reverseDrain ? damage : damage * -1, - !reverseDrain ? getPokemonMessage(pokemon, "'s health is\nsapped by Leech Seed!") : getPokemonMessage(source, "'s Leech Seed\nsucked up the liquid ooze!"), + !reverseDrain ? i18next.t("battle:battlerTagsSeededLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }) : i18next.t("battle:battlerTagsSeededLapseShed", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), false, true)); } } @@ -422,20 +439,20 @@ export class NightmareTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " began\nhaving a Nightmare!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsNightmareOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } onOverlap(pokemon: Pokemon): void { super.onOverlap(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nalready locked in a Nightmare!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsNightmareOnOverlap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); if (ret) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is locked\nin a Nightmare!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsNightmareLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE)); // TODO: Update animation type const cancelled = new Utils.BooleanHolder(false); @@ -527,7 +544,7 @@ export class EncoreTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onRemove(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " got\nan Encore!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsEncoreOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); const movePhase = pokemon.scene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon); if (movePhase) { @@ -543,7 +560,7 @@ export class EncoreTag extends BattlerTag { onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, "'s Encore\nended!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsEncoreOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } } @@ -553,7 +570,12 @@ export class HelpingHandTag extends BattlerTag { } onAdd(pokemon: Pokemon): void { - pokemon.scene.queueMessage(getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` is ready to\nhelp ${pokemon.name}!`)); + pokemon.scene.queueMessage( + i18next.t("battle:battlerTagsHelpingHandOnAdd", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon.scene.getPokemonById(this.sourceId)), + pokemonName: pokemon.name + }) + ); } } @@ -581,15 +603,22 @@ export class IngrainTag extends TrappedTag { const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); if (ret) { - pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), Math.floor(pokemon.getMaxHp() / 16), - getPokemonMessage(pokemon, " absorbed\nnutrients with its roots!"), true)); + pokemon.scene.unshiftPhase( + new PokemonHealPhase( + pokemon.scene, + pokemon.getBattlerIndex(), + Math.floor(pokemon.getMaxHp() / 16), + i18next.t("battle:battlerTagsIngrainLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), + true + ) + ); } return ret; } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon, " planted its roots!"); + return i18next.t("battle:battlerTagsIngrainOnTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } getDescriptor(): string { @@ -605,15 +634,23 @@ export class AquaRingTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " surrounded\nitself with a veil of water!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsAquaRingOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); if (ret) { - pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), - Math.floor(pokemon.getMaxHp() / 16), `${this.getMoveName()} restored\n${pokemon.name}\'s HP!`, true)); + pokemon.scene.unshiftPhase( + new PokemonHealPhase( + pokemon.scene, + pokemon.getBattlerIndex(), + Math.floor(pokemon.getMaxHp() / 16), + i18next.t("battle:battlerTagsAquaRingLapse", { + moveName: this.getMoveName(), + pokemonName: pokemon.name + }), + true)); } return ret; @@ -659,7 +696,7 @@ export class DrowsyTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " grew drowsy!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsDrowsyOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -702,7 +739,12 @@ export abstract class DamagingTrapTag extends TrappedTag { const ret = super.lapse(pokemon, lapseType); if (ret) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is hurt\nby ${this.getMoveName()}!`)); + pokemon.scene.queueMessage( + i18next.t("battle:battlerTagsDamagingTrapLapse", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + moveName: this.getMoveName() + }) + ); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, this.commonAnim)); const cancelled = new Utils.BooleanHolder(false); @@ -723,7 +765,11 @@ export class BindTag extends DamagingTrapTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon, ` was squeezed by\n${pokemon.scene.getPokemonById(this.sourceId).name}'s ${this.getMoveName()}!`); + return i18next.t("battle:battlerTagsBindOnTrap", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + sourcePokemonName: pokemon.scene.getPokemonById(this.sourceId).name, + moveName: this.getMoveName() + }); } } @@ -733,7 +779,10 @@ export class WrapTag extends DamagingTrapTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon, ` was Wrapped\nby ${pokemon.scene.getPokemonById(this.sourceId).name}!`); + return i18next.t("battle:battlerTagsWrapOnTrap", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + sourcePokemonName: pokemon.scene.getPokemonById(this.sourceId).name + }); } } @@ -743,7 +792,7 @@ export abstract class VortexTrapTag extends DamagingTrapTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon, " was trapped\nin the vortex!"); + return i18next.t("battle:battlerTagsVortexOnTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } } @@ -765,7 +814,10 @@ export class ClampTag extends DamagingTrapTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` Clamped\n${pokemon.name}!`); + return i18next.t("battle:battlerTagsClampOnTrap", { + sourcePokemonNameWithAffix: getPokemonNameWithAffix(pokemon.scene.getPokemonById(this.sourceId)), + pokemonName: pokemon.name, + }); } } @@ -775,7 +827,10 @@ export class SandTombTag extends DamagingTrapTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon, ` became trapped\nby ${this.getMoveName()}!`); + return i18next.t("battle:battlerTagsSandTombOnTrap", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + moveName: this.getMoveName() + }); } } @@ -785,7 +840,7 @@ export class MagmaStormTag extends DamagingTrapTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon, " became trapped\nby swirling magma!"); + return i18next.t("battle:battlerTagsMagmaStormOnTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } } @@ -795,7 +850,7 @@ export class SnapTrapTag extends DamagingTrapTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon, " got trapped\nby a snap trap!"); + return i18next.t("battle:battlerTagsSnapTrapOnTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } } @@ -805,7 +860,10 @@ export class ThunderCageTag extends DamagingTrapTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon.scene.getPokemonById(this.sourceId), ` trapped\n${getPokemonNameWithAffix(pokemon)}!`); + return i18next.t("battle:battlerTagsThunderCageOnTrap", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + sourcePokemonNameWithAffix: getPokemonNameWithAffix(pokemon.scene.getPokemonById(this.sourceId)) + }); } } @@ -815,7 +873,10 @@ export class InfestationTag extends DamagingTrapTag { } getTrapMessage(pokemon: Pokemon): string { - return getPokemonMessage(pokemon, ` has been afflicted \nwith an infestation by ${getPokemonNameWithAffix(pokemon.scene.getPokemonById(this.sourceId))}!`); + return i18next.t("battle:battlerTagsInfestationOnTrap", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + sourcePokemonNameWithAffix: getPokemonNameWithAffix(pokemon.scene.getPokemonById(this.sourceId)) + }); } } @@ -828,13 +889,13 @@ export class ProtectedTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, "\nprotected itself!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsProtectedOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { if (lapseType === BattlerTagLapseType.CUSTOM) { new CommonBattleAnim(CommonAnim.PROTECT, pokemon).play(pokemon.scene); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, "\nprotected itself!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsProtectedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); return true; } @@ -959,12 +1020,12 @@ export class EnduringTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " braced\nitself!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsEnduringOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { if (lapseType === BattlerTagLapseType.CUSTOM) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " endured\nthe hit!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsEnduringLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); return true; } @@ -979,7 +1040,7 @@ export class SturdyTag extends BattlerTag { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { if (lapseType === BattlerTagLapseType.CUSTOM) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " endured\nthe hit!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsSturdyLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); return true; } @@ -1000,7 +1061,12 @@ export class PerishSongTag extends BattlerTag { const ret = super.lapse(pokemon, lapseType); if (ret) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, `\'s perish count fell to ${this.turnCount}.`)); + pokemon.scene.queueMessage( + i18next.t("battle:battlerTagsPerishSongLapse", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + turnCount: this.turnCount + }) + ); } else { pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, true, true); } @@ -1071,7 +1137,7 @@ export class TruantTag extends AbilityBattlerTag { if (lastMove && lastMove.move !== Moves.NONE) { (pokemon.scene.getCurrentPhase() as MovePhase).cancel(); pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, passive)); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nloafing around!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsTruantLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } return true; @@ -1086,7 +1152,7 @@ export class SlowStartTag extends AbilityBattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " can't\nget it going!"), null, false, null, true); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsSlowStartOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, false, null, true); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -1100,7 +1166,7 @@ export class SlowStartTag extends AbilityBattlerTag { onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " finally\ngot its act together!"), null, false, null); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsSlowStartOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), null, false, null); } } @@ -1146,13 +1212,13 @@ export class HighestStatBoostTag extends AbilityBattlerTag { break; } - pokemon.scene.queueMessage(getPokemonMessage(pokemon, `'s ${getStatName(highestStat)}\nwas heightened!`), null, false, null, true); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsHighestStatBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), statName: getStatName(highestStat) }), null, false, null, true); } onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - pokemon.scene.queueMessage(`The effects of ${getPokemonMessage(pokemon, `'s\n${allAbilities[this.ability].name} wore off!`)}`); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsHighestStatBoostOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: allAbilities[this.ability].name })); } } @@ -1286,7 +1352,7 @@ export class CritBoostTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is getting\npumped!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsCritBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { @@ -1296,7 +1362,7 @@ export class CritBoostTag extends BattlerTag { onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " relaxed.")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsCritBoostOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } } @@ -1331,7 +1397,7 @@ export class SaltCuredTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is being salt cured!")); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsSaltCuredOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); } @@ -1348,7 +1414,12 @@ export class SaltCuredTag extends BattlerTag { const pokemonSteelOrWater = pokemon.isOfType(Type.STEEL) || pokemon.isOfType(Type.WATER); pokemon.damageAndUpdate(Math.max(Math.floor(pokemonSteelOrWater ? pokemon.getMaxHp() / 4 : pokemon.getMaxHp() / 8), 1)); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is hurt by ${this.getMoveName()}!`)); + pokemon.scene.queueMessage( + i18next.t("battle:battlerTagsSaltCuredLapse", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + moveName: this.getMoveName() + }) + ); } } @@ -1374,8 +1445,6 @@ export class CursedTag extends BattlerTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - - pokemon.scene.queueMessage(getPokemonMessage(pokemon, " has been cursed!")); this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); } @@ -1390,7 +1459,7 @@ export class CursedTag extends BattlerTag { if (!cancelled.value) { pokemon.damageAndUpdate(Math.max(Math.floor(pokemon.getMaxHp() / 4), 1)); - pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is hurt by the ${this.getMoveName()}!`)); + pokemon.scene.queueMessage(i18next.t("battle:battlerTagsCursedLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } } diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 658381951c7..75b200b24ee 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -1,15 +1,18 @@ import * as Utils from "../utils"; import i18next from "i18next"; -import { GameData } from "#app/system/game-data.js"; -import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "./pokemon-species"; +import { DexAttrProps, GameData } from "#app/system/game-data.js"; +import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./pokemon-species"; import Pokemon from "#app/field/pokemon.js"; import { BattleType, FixedBattleConfig } from "#app/battle.js"; import Trainer, { TrainerVariant } from "#app/field/trainer.js"; import { GameMode } from "#app/game-mode.js"; import { Type } from "./type"; +import { pokemonEvolutions } from "./pokemon-evolutions"; +import { pokemonFormChanges } from "./pokemon-forms"; import { Challenges } from "#enums/challenges"; import { Species } from "#enums/species"; import { TrainerType } from "#enums/trainer-type"; +import { TypeColor, TypeShadow } from "#app/enums/color.js"; /** * An enum for all the challenge types. The parameter entries on these describe the @@ -158,7 +161,7 @@ export abstract class Challenge { if (overrideValue === undefined) { overrideValue = this.value; } - return i18next.t(`challenges:${this.geti18nKey()}.desc.${this.value}`); + return `${i18next.t("challenges:usePokemon")}${i18next.t(`challenges:${this.geti18nKey()}.desc.${this.value}`)}`; } /** @@ -277,8 +280,22 @@ export class SingleGenerationChallenge extends Challenge { case ChallengeType.STARTER_CHOICE: const species = args[0] as PokemonSpecies; const isValidStarter = args[1] as Utils.BooleanHolder; + const amountOfPokemon = args[3] as number; const starterGeneration = species.speciesId === Species.VICTINI ? 5 : species.generation; - if (starterGeneration !== this.value) { + const generations = [starterGeneration]; + if (amountOfPokemon > 0) { + const speciesToCheck = [species.speciesId]; + while (speciesToCheck.length) { + const checking = speciesToCheck.pop(); + if (pokemonEvolutions.hasOwnProperty(checking)) { + pokemonEvolutions[checking].forEach(e => { + speciesToCheck.push(e.speciesId); + generations.push(getPokemonSpecies(e.speciesId).generation); + }); + } + } + } + if (!generations.includes(this.value)) { isValidStarter.value = false; return true; } @@ -331,6 +348,37 @@ export class SingleGenerationChallenge extends Challenge { return this.value > 0 ? 1 : 0; } + /** + * Returns the textual representation of a challenge's current value. + * @param {value} overrideValue The value to check for. If undefined, gets the current value. + * @returns {string} The localised name for the current value. + */ + getValue(overrideValue?: integer): string { + if (overrideValue === undefined) { + overrideValue = this.value; + } + if (this.value === 0) { + return i18next.t("settings:off"); + } + return i18next.t(`starterSelectUiHandler:gen${this.value}`); + } + + /** + * Returns the description of a challenge's current value. + * @param {value} overrideValue The value to check for. If undefined, gets the current value. + * @returns {string} The localised description for the current value. + */ + getDescription(overrideValue?: integer): string { + if (overrideValue === undefined) { + overrideValue = this.value; + } + if (this.value === 0) { + return i18next.t("challenges:singleGeneration.desc_default"); + } + return i18next.t("challenges:singleGeneration.desc", { gen: i18next.t(`challenges:singleGeneration.gen_${this.value}`) }); + } + + static loadChallenge(source: SingleGenerationChallenge | any): SingleGenerationChallenge { const newChallenge = new SingleGenerationChallenge(); newChallenge.value = source.value; @@ -372,7 +420,32 @@ export class SingleTypeChallenge extends Challenge { case ChallengeType.STARTER_CHOICE: const species = args[0] as PokemonSpecies; const isValidStarter = args[1] as Utils.BooleanHolder; - if (!species.isOfType(this.value - 1)) { + const dexAttr = args[2] as DexAttrProps; + const amountOfPokemon = args[3] as number; + const speciesForm = getPokemonSpeciesForm(species.speciesId, dexAttr.formIndex); + const types = [speciesForm.type1, speciesForm.type2]; + if (amountOfPokemon > 0) { + const speciesToCheck = [species.speciesId]; + while (speciesToCheck.length) { + const checking = speciesToCheck.pop(); + if (pokemonEvolutions.hasOwnProperty(checking)) { + pokemonEvolutions[checking].forEach(e => { + speciesToCheck.push(e.speciesId); + types.push(getPokemonSpecies(e.speciesId).type1, getPokemonSpecies(e.speciesId).type2); + }); + } + if (pokemonFormChanges.hasOwnProperty(checking)) { + pokemonFormChanges[checking].forEach(f1 => { + getPokemonSpecies(checking).forms.forEach(f2 => { + if (f1.formKey === f2.formKey) { + types.push(f2.type1, f2.type2); + } + }); + }); + } + } + } + if (!types.includes(this.value - 1)) { isValidStarter.value = false; return true; } @@ -397,6 +470,34 @@ export class SingleTypeChallenge extends Challenge { return this.value > 0 ? 1 : 0; } + /** + * Returns the textual representation of a challenge's current value. + * @param {value} overrideValue The value to check for. If undefined, gets the current value. + * @returns {string} The localised name for the current value. + */ + getValue(overrideValue?: integer): string { + if (overrideValue === undefined) { + overrideValue = this.value; + } + return Type[this.value - 1].toLowerCase(); + } + + /** + * Returns the description of a challenge's current value. + * @param {value} overrideValue The value to check for. If undefined, gets the current value. + * @returns {string} The localised description for the current value. + */ + getDescription(overrideValue?: integer): string { + if (overrideValue === undefined) { + overrideValue = this.value; + } + const type = i18next.t(`pokemonInfo:Type.${Type[this.value - 1]}`); + const typeColor = `[color=${TypeColor[Type[this.value-1]]}][shadow=${TypeShadow[Type[this.value-1]]}]${type}[/shadow][/color]`; + const defaultDesc = i18next.t("challenges:singleType.desc_default"); + const typeDesc = i18next.t("challenges:singleType.desc", {type: typeColor}); + return this.value === 0 ? defaultDesc : typeDesc; + } + static loadChallenge(source: SingleTypeChallenge | any): SingleTypeChallenge { const newChallenge = new SingleTypeChallenge(); newChallenge.value = source.value; diff --git a/src/data/move.ts b/src/data/move.ts index 3f9d9685fd8..dec52b04c57 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2,10 +2,11 @@ import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./ import { BattleEndPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases"; import { BattleStat, getBattleStatName } from "./battle-stat"; import { EncoreTag } from "./battler-tags"; -import { getPokemonMessage } from "../messages"; +import { getPokemonMessage, getPokemonNameWithAffix } from "../messages"; import Pokemon, { AttackMoveResult, EnemyPokemon, HitResult, MoveResult, PlayerPokemon, PokemonMove, TurnMove } from "../field/pokemon"; import { StatusEffect, getStatusEffectHealText, isNonVolatileStatusEffect, getNonVolatileStatusEffects} from "./status-effect"; import { Type } from "./type"; +import { Constructor } from "#app/utils"; import * as Utils from "../utils"; import { WeatherType } from "./weather"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; @@ -156,7 +157,7 @@ export default class Move implements Localizable { * @param attrType any attribute that extends {@linkcode MoveAttr} * @returns Array of attributes that match `attrType`, Empty Array if none match. */ - getAttrs(attrType: new(...args: any[]) => T): T[] { + getAttrs(attrType: Constructor): T[] { return this.attrs.filter((a): a is T => a instanceof attrType); } @@ -165,7 +166,7 @@ export default class Move implements Localizable { * @param attrType any attribute that extends {@linkcode MoveAttr} * @returns true if the move has attribute `attrType` */ - hasAttr(attrType: new(...args: any[]) => T): boolean { + hasAttr(attrType: Constructor): boolean { return this.attrs.some((attr) => attr instanceof attrType); } @@ -185,7 +186,7 @@ export default class Move implements Localizable { * @param args the args needed to instantiate a the given class * @returns the called object {@linkcode Move} */ - attr MoveAttr>(AttrType: T, ...args: ConstructorParameters): this { + attr>(AttrType: T, ...args: ConstructorParameters): this { const attr = new AttrType(...args); this.attrs.push(attr); let attrCondition = attr.getCondition(); @@ -278,12 +279,14 @@ export default class Move implements Localizable { } /** - * Checks if the move is immune to certain types - * currently only look at case of Grass types and powder moves - * @param type {@linkcode Type} enum + * Checks if the move is immune to certain types. + * Currently looks at cases of Grass types with powder moves and Dark types with moves affected by Prankster. + * @param {Pokemon} user the source of this move + * @param {Pokemon} target the target of this move + * @param {Type} type the type of the move's target * @returns boolean */ - isTypeImmune(type: Type): boolean { + isTypeImmune(user: Pokemon, target: Pokemon, type: Type): boolean { if (this.moveTarget === MoveTarget.USER) { return false; } @@ -294,6 +297,11 @@ export default class Move implements Localizable { return true; } break; + case Type.DARK: + if (user.hasAbility(Abilities.PRANKSTER) && this.category === MoveCategory.STATUS && (user.isPlayer() !== target.isPlayer())) { + return true; + } + break; } return false; } @@ -3987,7 +3995,13 @@ export class CurseAttr extends MoveEffectAttr { } const curseRecoilDamage = Math.max(1, Math.floor(user.getMaxHp() / 2)); user.damageAndUpdate(curseRecoilDamage, HitResult.OTHER, false, true, true); - user.scene.queueMessage(getPokemonMessage(user, ` cut its own HP\nand laid a curse on the ${target.name}!`)); + user.scene.queueMessage( + i18next.t("battle:battlerTagsCursedOnAdd", { + pokemonNameWithAffix: getPokemonNameWithAffix(user), + pokemonName: target.name + }) + ); + target.addTag(BattlerTagType.CURSED, 0, move.id, user.id); return true; } else { @@ -4599,7 +4613,7 @@ export class RemoveTypeAttr extends MoveEffectAttr { export class CopyTypeAttr extends MoveEffectAttr { constructor() { - super(true); + super(false); } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { @@ -5494,7 +5508,7 @@ function applyMoveAttrsInternal(attrFilter: MoveAttrFilter, user: Pokemon, targe }); } -export function applyMoveAttrs(attrType: { new(...args: any[]): MoveAttr }, user: Pokemon, target: Pokemon, move: Move, ...args: any[]): Promise { +export function applyMoveAttrs(attrType: Constructor, user: Pokemon, target: Pokemon, move: Move, ...args: any[]): Promise { return applyMoveAttrsInternal((attr: MoveAttr) => attr instanceof attrType, user, target, move, args); } @@ -8314,8 +8328,7 @@ export function initMoves() { .attr(HealStatusEffectAttr, false, StatusEffect.FREEZE) .attr(StatusEffectAttr, StatusEffect.BURN) .target(MoveTarget.ALL_NEAR_ENEMIES) - .triageMove() - .partial(), + .triageMove(), new AttackMove(Moves.SYRUP_BOMB, Type.GRASS, MoveCategory.SPECIAL, 60, 85, 10, -1, 0, 9) .attr(StatChangeAttr, BattleStat.SPD, -1) //Temporary .ballBombMove() diff --git a/src/data/pokemon-forms.ts b/src/data/pokemon-forms.ts index cc05af50f6f..ad93bec44e4 100644 --- a/src/data/pokemon-forms.ts +++ b/src/data/pokemon-forms.ts @@ -3,6 +3,7 @@ import Pokemon from "../field/pokemon"; import { SpeciesFormKey } from "./pokemon-species"; import { StatusEffect } from "./status-effect"; import { MoveCategory, allMoves } from "./move"; +import { Constructor } from "#app/utils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; @@ -178,7 +179,7 @@ export class SpeciesFormChange { return true; } - findTrigger(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): SpeciesFormChangeTrigger { + findTrigger(triggerType: Constructor): SpeciesFormChangeTrigger { if (!this.trigger.hasTriggerType(triggerType)) { return null; } @@ -208,7 +209,7 @@ export abstract class SpeciesFormChangeTrigger { return true; } - hasTriggerType(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): boolean { + hasTriggerType(triggerType: Constructor): boolean { return this instanceof triggerType; } } @@ -236,7 +237,7 @@ export class SpeciesFormChangeCompoundTrigger { return true; } - hasTriggerType(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): boolean { + hasTriggerType(triggerType: Constructor): boolean { return !!this.triggers.find(t => t.hasTriggerType(triggerType)); } } diff --git a/src/enums/color.ts b/src/enums/color.ts new file mode 100644 index 00000000000..99c2d14cb63 --- /dev/null +++ b/src/enums/color.ts @@ -0,0 +1,83 @@ +export enum Color { + WHITE = "#ffffff", + OFF_WHITE = "#f8f8f8", + LIGHT_GREY = "#a0a0a0", + GREY = "#484848", + DARK_GREY = "#404040", + PINK = "#f89890", + RED = "#e13d3d", + RED2 = "#e70808", + REDORANGE = "#d64b00", + ORANGE = "#f8b050", + LIGHT_YELLOW = "#e8e8a8", + YELLOW = "#ccbe00", + DARK_YELLOW = "#a68e17", + GREEN = "#78c850", + BLUE = "#40c8f8", + COMMON = "#ffffff", + GREAT = "#3890f8", + ULTRA = "#f8d038", + ROGUE = "#d52929", + MASTER = "#e020c0", + LUXURY = "#e64a18" +} + +export enum TypeColor { + NORMAL = "#ADA594", + FIGHTING = "#A55239", + FLYING = "#9CADF7", + POISON = "#9141CB", + GROUND = "#AE7A3B", + ROCK = "#BDA55A", + BUG = "#ADBD21", + GHOST = "#6363B5", + STEEL = "#81A6BE", + FIRE = "#F75231", + WATER = "#399CFF", + GRASS = "#7BCE52", + ELECTRIC = "#FFC631", + PSYCHIC = "#EF4179", + ICE = "#5ACEE7", + DRAGON = "#7B63E7", + DARK = "#735A4A", + FAIRY = "#EF70EF", +} + +export enum TypeShadow { + NORMAL = "#574F4A", + FIGHTING = "#4E637C", + FLYING = "#4E637C", + POISON = "#352166", + GROUND = "#572D1E", + ROCK = "#5F442D", + BUG = "#5F5010", + GHOST = "#323D5B", + STEEL = "#415C5F", + FIRE = "#7C1818", + WATER = "#1C4E80", + GRASS = "#4F6729", + ELECTRIC = "#804618", + PSYCHIC = "#782155", + ICE = "#2D5C74", + DRAGON = "#313874", + DARK = "#392725", + FAIRY = "#663878", +} + +export enum ShadowColor { + GREY = "#636363", + PURPLE = "#6b5a73", + LIGHT_GREY = "#d0d0c8", + BROWN = "#69402a", + PINK = "#fca2a2", + BRIGHT_RED = "#f83018", + RED = "#984038", + MAROON = "#632929", + GREEN = "#306850", + BLUE = "#006090", + LIGHT_YELLOW = "#ded6b5", + YELLOW = "#ebd773", + DARK_YELLOW = "#a0a060", + ORANGE = "#c07800", + LIGHT_ORANGE = "#ffbd73", +} diff --git a/src/events/arena.ts b/src/events/arena.ts index 657acaeae7e..67b423f3b75 100644 --- a/src/events/arena.ts +++ b/src/events/arena.ts @@ -71,11 +71,18 @@ export class TagAddedEvent extends ArenaEvent { public arenaTagType: ArenaTagType; /** The {@linkcode ArenaTagSide} the tag is being placed on */ public arenaTagSide: ArenaTagSide; - constructor(arenaTagType: ArenaTagType, arenaTagSide: ArenaTagSide, duration: number) { + /** The current number of layers of the arena trap. */ + public arenaTagLayers: number; + /** The maximum amount of layers of the arena trap. */ + public arenaTagMaxLayers: number; + + constructor(arenaTagType: ArenaTagType, arenaTagSide: ArenaTagSide, duration: number, arenaTagLayers?: number, arenaTagMaxLayers?: number) { super(ArenaEventType.TAG_ADDED, duration); this.arenaTagType = arenaTagType; this.arenaTagSide = arenaTagSide; + this.arenaTagLayers = arenaTagLayers; + this.arenaTagMaxLayers = arenaTagMaxLayers; } } /** diff --git a/src/field/arena.ts b/src/field/arena.ts index 14280536a5f..a5e62872152 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -1,5 +1,6 @@ import BattleScene from "../battle-scene"; import { BiomePoolTier, PokemonPools, BiomeTierTrainerPools, biomePokemonPools, biomeTrainerPools } from "../data/biomes"; +import { Constructor } from "#app/utils"; import * as Utils from "../utils"; import PokemonSpecies, { getPokemonSpecies } from "../data/pokemon-species"; import { Weather, WeatherType, getTerrainClearMessage, getTerrainStartMessage, getWeatherClearMessage, getWeatherStartMessage } from "../data/weather"; @@ -7,7 +8,7 @@ import { CommonAnimPhase } from "../phases"; import { CommonAnim } from "../data/battle-anims"; import { Type } from "../data/type"; import Move from "../data/move"; -import { ArenaTag, ArenaTagSide, getArenaTag } from "../data/arena-tag"; +import { ArenaTag, ArenaTagSide, ArenaTrapTag, getArenaTag } from "../data/arena-tag"; import { BattlerIndex } from "../battle"; import { Terrain, TerrainType } from "../data/terrain"; import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability"; @@ -535,7 +536,7 @@ export class Arena { this.ignoreAbilities = ignoreAbilities; } - applyTagsForSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide, ...args: any[]): void { + applyTagsForSide(tagType: ArenaTagType | Constructor, side: ArenaTagSide, ...args: unknown[]): void { let tags = typeof tagType === "string" ? this.tags.filter(t => t.tagType === tagType) : this.tags.filter(t => t instanceof tagType); @@ -545,7 +546,7 @@ export class Arena { tags.forEach(t => t.apply(this, args)); } - applyTags(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, ...args: any[]): void { + applyTags(tagType: ArenaTagType | Constructor, ...args: unknown[]): void { this.applyTagsForSide(tagType, ArenaTagSide.BOTH, ...args); } @@ -553,6 +554,12 @@ export class Arena { const existingTag = this.getTagOnSide(tagType, side); if (existingTag) { existingTag.onOverlap(this); + + if (existingTag instanceof ArenaTrapTag) { + const { tagType, side, turnCount, layers, maxLayers } = existingTag as ArenaTrapTag; + this.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, layers, maxLayers)); + } + return false; } @@ -560,16 +567,18 @@ export class Arena { this.tags.push(newTag); newTag.onAdd(this, quiet); - this.eventTarget.dispatchEvent(new TagAddedEvent(newTag.tagType, newTag.side, newTag.turnCount)); + const { layers = 0, maxLayers = 0 } = newTag instanceof ArenaTrapTag ? newTag : {}; + + this.eventTarget.dispatchEvent(new TagAddedEvent(newTag.tagType, newTag.side, newTag.turnCount, layers, maxLayers)); return true; } - getTag(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }): ArenaTag { + getTag(tagType: ArenaTagType | Constructor): ArenaTag { return this.getTagOnSide(tagType, ArenaTagSide.BOTH); } - getTagOnSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide): ArenaTag { + getTagOnSide(tagType: ArenaTagType | Constructor, side: ArenaTagSide): ArenaTag { return typeof(tagType) === "string" ? this.tags.find(t => t.tagType === tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)) : this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index fcc55a645a0..5b37365bec1 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -5,6 +5,7 @@ import { variantData } from "#app/data/variant"; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info"; import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, VariableMoveTypeAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, MoveFlags } from "../data/move"; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species"; +import { Constructor } from "#app/utils"; import * as Utils from "../utils"; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type"; import { getLevelTotalExp } from "../data/exp"; @@ -1064,7 +1065,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {boolean} ignoreOverride If true, it ignores ability changing effects * @returns {boolean} Whether an ability with that attribute is present and active */ - hasAbilityWithAttr(attrType: { new(...args: any[]): AbAttr }, canApply: boolean = true, ignoreOverride?: boolean): boolean { + hasAbilityWithAttr(attrType: Constructor, canApply: boolean = true, ignoreOverride?: boolean): boolean { if ((!canApply || this.canApplyAbility()) && this.getAbility(ignoreOverride).hasAttr(attrType)) { return true; } @@ -1730,11 +1731,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (typeless) { typeMultiplier.value = 1; } - if (types.find(t => move.isTypeImmune(t))) { + if (types.find(t => move.isTypeImmune(source, this, t))) { typeMultiplier.value = 0; } - // Apply arena tags for conditional protection if (!move.checkFlag(MoveFlags.IGNORE_PROTECT, source, this) && !move.isAllyTarget()) { const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; @@ -2105,7 +2105,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return false; } - getTag(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag { + getTag(tagType: BattlerTagType | Constructor): BattlerTag { if (!this.summonData) { return null; } @@ -2121,7 +2121,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return this.summonData.tags.find(t => tagFilter(t)); } - getTags(tagType: BattlerTagType | { new(...args: any[]): BattlerTag }): BattlerTag[] { + getTags(tagType: BattlerTagType | Constructor): BattlerTag[] { if (!this.summonData) { return []; } diff --git a/src/form-change-phase.ts b/src/form-change-phase.ts index f2cf9933b17..7d4e8349775 100644 --- a/src/form-change-phase.ts +++ b/src/form-change-phase.ts @@ -278,7 +278,7 @@ export class QuietFormChangePhase extends BattlePhase { } end(): void { - if (this.pokemon.scene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS && this.pokemon instanceof EnemyPokemon) { + if (this.pokemon.scene?.currentBattle.battleSpec === BattleSpec.FINAL_BOSS && this.pokemon instanceof EnemyPokemon) { this.scene.playBgm(); this.pokemon.summonData.battleStats = [ 0, 0, 0, 0, 0, 0, 0 ]; this.scene.unshiftPhase(new PokemonHealPhase(this.scene, this.pokemon.getBattlerIndex(), this.pokemon.getMaxHp(), null, false, false, false, true)); diff --git a/src/interfaces/locales.ts b/src/interfaces/locales.ts index 21fbda7c468..d9b3d71474d 100644 --- a/src/interfaces/locales.ts +++ b/src/interfaces/locales.ts @@ -2,6 +2,9 @@ export interface Localizable { localize(): void; } +export interface TranslationEntries { + [key: string]: string | { [key: string]: string } +} export interface SimpleTranslationEntries { [key: string]: string } diff --git a/src/locales/de/battle.ts b/src/locales/de/battle.ts index 09310ca02bc..760f17c0c9a 100644 --- a/src/locales/de/battle.ts +++ b/src/locales/de/battle.ts @@ -71,4 +71,61 @@ export const battle: SimpleTranslationEntries = { "statSeverelyFell": "sinkt drastisch", "statWontGoAnyLower": "kann nicht weiter sinken", "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", + "battlerTagsRechargingLapse": "{{pokemonNameWithAffix}} kann sich wegen des Rückstoßes durch den Angriff nicht bewegen!", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}} kann nicht mehr fliehen!", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}} wurde von {{moveName}} befreit.", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}} ist zurückgeschreckt und kann nicht handeln!", + "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}} wurde verwirrt!", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}} ist nicht mehr verwirrt!", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}} ist bereits verwirrt!", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}} ist verwirrt!", + "battlerTagsConfusedLapseHurtItself": "Es hat sich vor Verwirrung selbst verletzt!", + "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}} ist immun gegen den Effekt von Abgangsbund!", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}} nimmt {{pokemonNameWithAffix2}} mit sich!", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}} hat sich in {{sourcePokemonName}} verliebt!", + "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}} ist bereits verliebt.", + "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}} ist in {{sourcePokemonName}} verliebt!", + "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}} ist starr vor Liebe!", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}} ist nicht mehr verliebt!", + "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}} wurde bepflanzt!", + "battlerTagsSeededLapse": "{{pokemonNameWithAffix}} wurden durch Egelsamen KP geraubt!", + "battlerTagsSeededLapseShed": "Egelsamen von {{pokemonNameWithAffix}} saugt Kloakensoße auf!", + "battlerTagsNightmareOnAdd": "Nachtmahr sucht {{pokemonNameWithAffix}} heim!", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}} wird bereits von Nachtmahr heimgesucht!", + "battlerTagsNightmareLapse": "Nachtmahr schadet {{pokemonNameWithAffix}}!", + "battlerTagsEncoreOnAdd": "({{pokemonNameWithAffix}} gibt eine Zugabe", + "battlerTagsEncoreOnRemove": "Die Zugabe von {{pokemonNameWithAffix}} ist beendet!", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}} will {{pokemonName}} helfen!", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}} nimmt über seine Wurzeln Nährstoffe auf!", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}} pflanzt seine Wurzeln!", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}} umgibt sich mit einem Wasserring!", + "battlerTagsAquaRingLapse": "{{moveName}} füllt KP von {{pokemonName}} wieder auf!", + "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}} wurde schläfrig gemacht!", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}} wurde durch {{moveName}} verletzt!", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}} wurde durch {{moveName}} von {{sourcePokemonName}} gequetscht!", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}} wurde von {{sourcePokemonName}} umwickelt!", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}} wird in dem Strudel gefangen!", + "battlerTagsClampOnTrap": "{{sourcePokemonNameWithAffix}} wurde von {{pokemonName}} geschnappt!", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}} wurde von {{moveName}} gefangen!", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}} wurde in wirbelndem Magma eingeschlossen!", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}} wurde durch Sandgrab gefangen!", + "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}} hat {{pokemonNameWithAffix}} gefangen!", + "battlerTagsInfestationOnTrap": "{{sourcePokemonNameWithAffix}} plagt {{pokemonNameWithAffix}}!", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}} schützt sich selbst!", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}} schützt sich selbst!", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}} sammelt sich, um die nächste Attacke zu überstehen!", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}} übersteht die Attacke!", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}} übersteht die Attacke!", + "battlerTagsPerishSongLapse": "Abgesang von {{pokemonNameWithAffix}} steht bei {{turnCount}}.", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}} faulenzt!", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}} kommt nicht in Fahrt!", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}} kriegt schließlich doch noch die Kurve!", + "battlerTagsHighestStatBoostOnAdd": "{{statName}} von {{pokemonNameWithAffix}} wird verstärkt!", + "battlerTagsHighestStatBoostOnRemove": "Der Effekt von {{abilityName}} von {{pokemonNameWithAffix}} lässt nach!", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}} läuft zu Hochtouren auf!", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}} entspannt.", + "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}} wurde eingepökelt!", + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} wurde durch {{moveName}} verletzt!", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} nimmt einen Teil seiner KP und legt einen Fluch auf {{pokemonName}}!", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} wurde durch den Fluch verletzt!" } as const; diff --git a/src/locales/de/challenges.ts b/src/locales/de/challenges.ts index b3e878f4649..176de9879b6 100644 --- a/src/locales/de/challenges.ts +++ b/src/locales/de/challenges.ts @@ -1,67 +1,26 @@ -import { SimpleTranslationEntries } from "#app/interfaces/locales"; +import { TranslationEntries } from "#app/interfaces/locales"; -export const challenges: SimpleTranslationEntries = { +export const challenges: TranslationEntries = { "title": "Herausforderungsmodifikatoren", - "confirm_start": "Mit diesen Modifikatoren fortfahren?", - "singleGeneration.name": "Mono-Generation", - "singleGeneration.value.0": "Aus", - "singleGeneration.desc.0": "Du kannst nur Pokémon aus der gewählten Generation verwenden.", - "singleGeneration.value.1": "Generation 1", - "singleGeneration.desc.1": "Du kannst nur Pokémon aus der ersten Generation verwenden.", - "singleGeneration.value.2": "Generation 2", - "singleGeneration.desc.2": "Du kannst nur Pokémon aus der zweiten Generation verwenden.", - "singleGeneration.value.3": "Generation 3", - "singleGeneration.desc.3": "Du kannst nur Pokémon aus der dritten Generation verwenden.", - "singleGeneration.value.4": "Generation 4", - "singleGeneration.desc.4": "Du kannst nur Pokémon aus der vierten Generation verwenden.", - "singleGeneration.value.5": "Generation 5", - "singleGeneration.desc.5": "Du kannst nur Pokémon aus der fünften Generation verwenden.", - "singleGeneration.value.6": "Generation 6", - "singleGeneration.desc.6": "Du kannst nur Pokémon aus der sechsten Generation verwenden.", - "singleGeneration.value.7": "Generation 7", - "singleGeneration.desc.7": "Du kannst nur Pokémon aus der siebten Generation verwenden.", - "singleGeneration.value.8": "Generation 8", - "singleGeneration.desc.8": "Du kannst nur Pokémon aus der achten Generation verwenden.", - "singleGeneration.value.9": "Generation 9", - "singleGeneration.desc.9": "Du kannst nur Pokémon aus der neunten Generation verwenden.", - "singleType.name": "Mono-Typ", - "singleType.value.0": "Aus", - "singleType.desc.0": "Du kannst nur Pokémon des gewählten Typs verwenden.", - "singleType.value.1": "Normal", - "singleType.desc.1": "Du kannst nur Pokémon des Typs Normal verwenden.", - "singleType.value.2": "Kampf", - "singleType.desc.2": "Du kannst nur Pokémon des Typs Kampf verwenden.", - "singleType.value.3": "Flug", - "singleType.desc.3": "Du kannst nur Pokémon des Typs Flug verwenden.", - "singleType.value.4": "Gift", - "singleType.desc.4": "Du kannst nur Pokémon des Typs Gift verwenden.", - "singleType.value.5": "Boden", - "singleType.desc.5": "Du kannst nur Pokémon des Typs Boden verwenden.", - "singleType.value.6": "Gestein", - "singleType.desc.6": "Du kannst nur Pokémon des Typs Gestein verwenden.", - "singleType.value.7": "Käfer", - "singleType.desc.7": "Du kannst nur Pokémon des Typs Käfer verwenden.", - "singleType.value.8": "Geist", - "singleType.desc.8": "Du kannst nur Pokémon des Typs Geist verwenden.", - "singleType.value.9": "Stahl", - "singleType.desc.9": "Du kannst nur Pokémon des Typs Stahl verwenden.", - "singleType.value.10": "Feuer", - "singleType.desc.10": "Du kannst nur Pokémon des Typs Feuer verwenden.", - "singleType.value.11": "Wasser", - "singleType.desc.11": "Du kannst nur Pokémon des Typs Wasser verwenden.", - "singleType.value.12": "Pflanze", - "singleType.desc.12": "Du kannst nur Pokémon des Typs Pflanze verwenden.", - "singleType.value.13": "Elektro", - "singleType.desc.13": "Du kannst nur Pokémon des Typs Elektro verwenden.", - "singleType.value.14": "Psycho", - "singleType.desc.14": "Du kannst nur Pokémon des Typs Psycho verwenden.", - "singleType.value.15": "Eis", - "singleType.desc.15": "Du kannst nur Pokémon des Typs Eis verwenden.", - "singleType.value.16": "Drache", - "singleType.desc.16": "Du kannst nur Pokémon des Typs Drache verwenden.", - "singleType.value.17": "Unlicht", - "singleType.desc.17": "Du kannst nur Pokémon des Typs Unlicht verwenden.", - "singleType.value.18": "Fee", - "singleType.desc.18": "Du kannst nur Pokémon des Typs Fee verwenden." - + "illegalEvolution": "{{pokemon}} hat sich in ein Pokémon verwandelt, dass für diese Herausforderung nicht zulässig ist!", + "singleGeneration": { + "name": "Mono-Generation", + "desc": "Du kannst nur Pokémon aus der {{gen}} Generation verwenden.", + "desc_default": "Du kannst nur Pokémon gewählten Generation verwenden.", + "gen_1": "ersten", + "gen_2": "zweiten", + "gen_3": "dritten", + "gen_4": "vierten", + "gen_5": "fünften", + "gen_6": "sechsten", + "gen_7": "siebten", + "gen_8": "achten", + "gen_9": "neunten", + }, + "singleType": { + "name": "Mono-Typ", + "desc": "Du kannst nur Pokémon des Typs {{type}} verwenden.", + "desc_default": "Du kannst nur Pokémon des gewählten Typs verwenden." + // types in pokemon-info + }, } as const; diff --git a/src/locales/de/common.ts b/src/locales/de/common.ts new file mode 100644 index 00000000000..82966b4ffeb --- /dev/null +++ b/src/locales/de/common.ts @@ -0,0 +1,5 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const common: SimpleTranslationEntries = { + "start": "Start", +} as const; diff --git a/src/locales/de/config.ts b/src/locales/de/config.ts index 16c25d6ca78..5f1bd541ad2 100644 --- a/src/locales/de/config.ts +++ b/src/locales/de/config.ts @@ -40,6 +40,7 @@ import { voucher } from "./voucher"; import { weather } from "./weather"; import { partyUiHandler } from "./party-ui-handler"; import { settings } from "#app/locales/de/settings.js"; +import { common } from "#app/locales/de/common.js"; export const deConfig = { ability: ability, @@ -50,6 +51,7 @@ export const deConfig = { biome: biome, challenges: challenges, commandUiHandler: commandUiHandler, + common: common, PGMachv: PGMachv, PGFachv: PGFachv, PGMdialogue: PGMdialogue, diff --git a/src/locales/de/settings.ts b/src/locales/de/settings.ts index ba040e91810..f7b8a1b0877 100644 --- a/src/locales/de/settings.ts +++ b/src/locales/de/settings.ts @@ -9,9 +9,9 @@ export const settings: SimpleTranslationEntries = { "gamepad": "Controller", "keyboard": "Tastatur", "gameSpeed": "Spielgeschwindigkeit", - "hpBarSpeed": "KP-Balken Geschwindigkeit", - "expGainsSpeed": "EXP-Balken Geschwindigkeit", - "expPartyDisplay": "Team-EXP anzeigen", + "hpBarSpeed": "KP-Balken Geschw.", + "expGainsSpeed": "EP-Balken Geschw.", + "expPartyDisplay": "Team-EP anzeigen", "skipSeenDialogues": "Gesehenen Dialog überspringen", "battleStyle": "Kampfstil", "enableRetries": "Erneut versuchen aktivieren", @@ -22,7 +22,7 @@ export const settings: SimpleTranslationEntries = { "fast": "Schnell", "faster": "Schneller", "skip": "Überspringen", - "levelUpNotifications": "Auflevelbenachrichtigung", + "levelUpNotifications": "Nur Lvl.-Up", "on": "An", "off": "Aus", "switch": "Wechsel", @@ -58,18 +58,18 @@ export const settings: SimpleTranslationEntries = { "consistent": "Konistent", "mixedAnimated": "Gemischt animiert", "fusionPaletteSwaps": "Fusion-Farbpalettenwechsel", - "playerGender": "Spieler Geschlecht", + "playerGender": "Spielergeschlecht", "typeHints": "Typhinweise", "masterVolume": "Gesamtlautstärke", "bgmVolume": "Hintergrundmusik", "seVolume": "Spezialeffekte", "musicPreference": "Musik Präferenz", - "mixed": "Gemisch", - "gamepadPleasePlug": "Bitte einen Controller anschließen oder eine Taste drücken", + "mixed": "Gemischt", + "gamepadPleasePlug": "Bitte einen Controller anschließen oder eine Taste drücken.", "delete": "Löschen", - "keyboardPleasePress": "Bitte eine Taste auf der Tastatur drücken", - "reset": "Zurücksetzen", - "requireReload": "Neuladen benötigt", + "keyboardPleasePress": "Bitte eine Taste auf der Tastatur drücken.", + "reset": "Reset", + "requireReload": "Neuladen", "action": "Aktion", "back": "Zurück", "pressToBind": "Zum Zuweisen drücken", @@ -92,7 +92,7 @@ export const settings: SimpleTranslationEntries = { "buttonSpeedUp": "Beschleunigen", "buttonSlowDown": "Verlangsamen", "alt": " (Alt)", - "mute": "Mute", + "mute": "Stumm", "controller": "Controller", - "gamepadSupport": "Gamepad Support" + "gamepadSupport": "Controllerunterstützung", } as const; diff --git a/src/locales/de/starter-select-ui-handler.ts b/src/locales/de/starter-select-ui-handler.ts index c82f579c341..2f5a98bb051 100644 --- a/src/locales/de/starter-select-ui-handler.ts +++ b/src/locales/de/starter-select-ui-handler.ts @@ -21,7 +21,6 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "passive": "Passiv:", "nature": "Wesen:", "eggMoves": "Ei-Attacken", - "start": "Start", "addToParty": "Zum Team hinzufügen", "toggleIVs": "DVs anzeigen/verbergen", "manageMoves": "Attacken ändern", diff --git a/src/locales/en/battle.ts b/src/locales/en/battle.ts index e5afe934492..304766a228f 100644 --- a/src/locales/en/battle.ts +++ b/src/locales/en/battle.ts @@ -71,4 +71,61 @@ export const battle: SimpleTranslationEntries = { "statSeverelyFell": "severely fell", "statWontGoAnyLower": "won't go any lower", "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", + "battlerTagsRechargingLapse": "{{pokemonNameWithAffix}} must\nrecharge!", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}} can no\nlonger escape!", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}} was freed\nfrom {{moveName}}", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}} flinched!", + "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}} became\nconfused!", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}} snapped\nout of confusion!", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}} is\nalready confused!", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}} is\nconfused!", + "battlerTagsConfusedLapseHurtItself": "It hurt itself in its\nconfusion!", + "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}} is unaffected\nby the effects of Destiny Bond.", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}} took\n{{pokemonNameWithAffix2}} down with it!", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}} fell in love\nwith {{sourcePokemonName}}!", + "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}} is\nalready in love!", + "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}} is in love\nwith {{sourcePokemonName}}!", + "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}} is\nimmobilized by love!", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}} got over\nits infatuation.", + "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}} was seeded!", + "battlerTagsSeededLapse": "{{pokemonNameWithAffix}}'s health is\nsapped by Leech Seed!", + "battlerTagsSeededLapseShed": "{{pokemonNameWithAffix}}'s Leech Seed\nsucked up the liquid ooze!", + "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}} began\nhaving a Nightmare!", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}} is\nalready locked in a Nightmare!", + "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}} is locked\nin a Nightmare!", + "battlerTagsEncoreOnAdd": "({{pokemonNameWithAffix}} got\nan Encore!", + "battlerTagsEncoreOnRemove": "{{pokemonNameWithAffix}}'s Encore\nended!", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}} is ready to\nhelp {{pokemonName}}!", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}} absorbed\nnutrients with its roots!", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}} planted its roots!", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}} surrounded\nitself with a veil of water!", + "battlerTagsAquaRingLapse": "{{moveName}} restored\n{{pokemonName}}'s HP!", + "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}} grew drowsy!", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}} is hurt\nby {{moveName}}!", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}} was squeezed by\n{{sourcePokemonName}}'s {{moveName}}!", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}} was Wrapped\nby {{sourcePokemonName}}!", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}} was trapped\nin the vortex!", + "battlerTagsClampOnTrap": "{{sourcePokemonNameWithAffix}} Clamped\n{{pokemonName}}!", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}} became trapped\nby {{moveName}}!", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}} became trapped\nby swirling magma!", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}} got trapped\nby a snap trap!", + "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}} trapped\n{{pokemonNameWithAffix}}!", + "battlerTagsInfestationOnTrap": "{{pokemonNameWithAffix}} has been afflicted \nwith an infestation by {{sourcePokemonNameWithAffix}}!", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}\nprotected itself!", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}\nprotected itself!", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}} braced\nitself!", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}} endured\nthe hit!", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}} endured\nthe hit!", + "battlerTagsPerishSongLapse": "{{pokemonNameWithAffix}}'s perish count fell to {{turnCount}}.", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}} is\nloafing around!", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}} can't\nget it going!", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}} finally\ngot its act together!", + "battlerTagsHighestStatBoostOnAdd": "{{pokemonNameWithAffix}}'s {{statName}}\nwas heightened!", + "battlerTagsHighestStatBoostOnRemove": "The effects of {{pokemonNameWithAffix}}'s\n{{abilityName}} wore off!", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}} is getting\npumped!", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}} relaxed.", + "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}} is being salt cured!", + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!" } as const; diff --git a/src/locales/en/challenges.ts b/src/locales/en/challenges.ts index 746a7e962d2..a40f05a0843 100644 --- a/src/locales/en/challenges.ts +++ b/src/locales/en/challenges.ts @@ -1,67 +1,26 @@ -import { SimpleTranslationEntries } from "#app/interfaces/locales"; +import { TranslationEntries } from "#app/interfaces/locales.js"; -export const challenges: SimpleTranslationEntries = { +export const challenges: TranslationEntries = { "title": "Challenge Modifiers", - "start": "Start", - "illegalEvolution": "{{pokemon}} changed into an ineligble pokemon\nfor this challenge!", - "singleGeneration.name": "Mono Gen", - "singleGeneration.value.0": "Off", - "singleGeneration.desc.0": "You can only use pokemon from the chosen generation.", - "singleGeneration.value.1": "Gen 1", - "singleGeneration.desc.1": "You can only use pokemon from generation one.", - "singleGeneration.value.2": "Gen 2", - "singleGeneration.desc.2": "You can only use pokemon from generation two.", - "singleGeneration.value.3": "Gen 3", - "singleGeneration.desc.3": "You can only use pokemon from generation three.", - "singleGeneration.value.4": "Gen 4", - "singleGeneration.desc.4": "You can only use pokemon from generation four.", - "singleGeneration.value.5": "Gen 5", - "singleGeneration.desc.5": "You can only use pokemon from generation five.", - "singleGeneration.value.6": "Gen 6", - "singleGeneration.desc.6": "You can only use pokemon from generation six.", - "singleGeneration.value.7": "Gen 7", - "singleGeneration.desc.7": "You can only use pokemon from generation seven.", - "singleGeneration.value.8": "Gen 8", - "singleGeneration.desc.8": "You can only use pokemon from generation eight.", - "singleGeneration.value.9": "Gen 9", - "singleGeneration.desc.9": "You can only use pokemon from generation nine.", - "singleType.name": "Mono Type", - "singleType.value.0": "Off", - "singleType.desc.0": "You can only use pokemon of the chosen type.", - "singleType.value.1": "Normal", - "singleType.desc.1": "You can only use pokemon with the Normal type.", - "singleType.value.2": "Fighting", - "singleType.desc.2": "You can only use pokemon with the Fighting type.", - "singleType.value.3": "Flying", - "singleType.desc.3": "You can only use pokemon with the Flying type.", - "singleType.value.4": "Poison", - "singleType.desc.4": "You can only use pokemon with the Poison type.", - "singleType.value.5": "Ground", - "singleType.desc.5": "You can only use pokemon with the Ground type.", - "singleType.value.6": "Rock", - "singleType.desc.6": "You can only use pokemon with the Rock type.", - "singleType.value.7": "Bug", - "singleType.desc.7": "You can only use pokemon with the Bug type.", - "singleType.value.8": "Ghost", - "singleType.desc.8": "You can only use pokemon with the Ghost type.", - "singleType.value.9": "Steel", - "singleType.desc.9": "You can only use pokemon with the Steel type.", - "singleType.value.10": "Fire", - "singleType.desc.10": "You can only use pokemon with the Fire type.", - "singleType.value.11": "Water", - "singleType.desc.11": "You can only use pokemon with the Water type.", - "singleType.value.12": "Grass", - "singleType.desc.12": "You can only use pokemon with the Grass type.", - "singleType.value.13": "Electric", - "singleType.desc.13": "You can only use pokemon with the Electric type.", - "singleType.value.14": "Psychic", - "singleType.desc.14": "You can only use pokemon with the Psychic type.", - "singleType.value.15": "Ice", - "singleType.desc.15": "You can only use pokemon with the Ice type.", - "singleType.value.16": "Dragon", - "singleType.desc.16": "You can only use pokemon with the Dragon type.", - "singleType.value.17": "Dark", - "singleType.desc.17": "You can only use pokemon with the Dark type.", - "singleType.value.18": "Fairy", - "singleType.desc.18": "You can only use pokemon with the Fairy type.", + "illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", + "singleGeneration": { + "name": "Mono Gen", + "desc": "You can only use Pokémon from Generation {{gen}}.", + "desc_default": "You can only use Pokémon from the chosen generation.", + "gen_1": "one", + "gen_2": "two", + "gen_3": "three", + "gen_4": "four", + "gen_5": "five", + "gen_6": "six", + "gen_7": "seven", + "gen_8": "eight", + "gen_9": "nine", + }, + "singleType": { + "name": "Mono Type", + "desc": "You can only use Pokémon with the {{type}} type.", + "desc_default": "You can only use Pokémon of the chosen type." + //types in pokemon-info + }, } as const; diff --git a/src/locales/en/common.ts b/src/locales/en/common.ts new file mode 100644 index 00000000000..82966b4ffeb --- /dev/null +++ b/src/locales/en/common.ts @@ -0,0 +1,5 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const common: SimpleTranslationEntries = { + "start": "Start", +} as const; diff --git a/src/locales/en/config.ts b/src/locales/en/config.ts index 98b36ea61ab..f37b707479a 100644 --- a/src/locales/en/config.ts +++ b/src/locales/en/config.ts @@ -1,3 +1,4 @@ +import { common } from "#app/locales/en/common.js"; import { settings } from "#app/locales/en/settings.js"; import { ability } from "./ability"; import { abilityTriggers } from "./ability-trigger"; @@ -50,6 +51,7 @@ export const enConfig = { biome: biome, challenges: challenges, commandUiHandler: commandUiHandler, + common: common, PGMachv: PGMachv, PGFachv: PGFachv, PGMdialogue: PGMdialogue, diff --git a/src/locales/en/starter-select-ui-handler.ts b/src/locales/en/starter-select-ui-handler.ts index 4b7c3194396..ae8443d8a20 100644 --- a/src/locales/en/starter-select-ui-handler.ts +++ b/src/locales/en/starter-select-ui-handler.ts @@ -21,7 +21,6 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "passive": "Passive:", "nature": "Nature:", "eggMoves": "Egg Moves", - "start": "Start", "addToParty": "Add to Party", "toggleIVs": "Toggle IVs", "manageMoves": "Manage Moves", diff --git a/src/locales/es/battle.ts b/src/locales/es/battle.ts index 76b6cd4e35e..7ba401b524d 100644 --- a/src/locales/es/battle.ts +++ b/src/locales/es/battle.ts @@ -71,4 +71,61 @@ export const battle: SimpleTranslationEntries = { "statSeverelyFell": "severely fell", "statWontGoAnyLower": "won't go any lower", "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", + "battlerTagsRechargingLapse": "{{pokemonNameWithAffix}} must\nrecharge!", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}} can no\nlonger escape!", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}} was freed\nfrom {{moveName}}", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}} flinched!", + "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}} became\nconfused!", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}} snapped\nout of confusion!", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}} is\nalready confused!", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}} is\nconfused!", + "battlerTagsConfusedLapseHurtItself": "It hurt itself in its\nconfusion!", + "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}} is unaffected\nby the effects of Destiny Bond.", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}} took\n{{pokemonNameWithAffix2}} down with it!", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}} fell in love\nwith {{sourcePokemonName}}!", + "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}} is\nalready in love!", + "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}} is in love\nwith {{sourcePokemonName}}!", + "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}} is\nimmobilized by love!", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}} got over\nits infatuation.", + "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}} was seeded!", + "battlerTagsSeededLapse": "{{pokemonNameWithAffix}}'s health is\nsapped by Leech Seed!", + "battlerTagsSeededLapseShed": "{{pokemonNameWithAffix}}'s Leech Seed\nsucked up the liquid ooze!", + "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}} began\nhaving a Nightmare!", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}} is\nalready locked in a Nightmare!", + "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}} is locked\nin a Nightmare!", + "battlerTagsEncoreOnAdd": "({{pokemonNameWithAffix}} got\nan Encore!", + "battlerTagsEncoreOnRemove": "{{pokemonNameWithAffix}}'s Encore\nended!", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}} is ready to\nhelp {{pokemonName}}!", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}} absorbed\nnutrients with its roots!", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}} planted its roots!", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}} surrounded\nitself with a veil of water!", + "battlerTagsAquaRingLapse": "{{moveName}} restored\n{{pokemonName}}'s HP!", + "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}} grew drowsy!", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}} is hurt\nby {{moveName}}!", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}} was squeezed by\n{{sourcePokemonName}}'s {{moveName}}!", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}} was Wrapped\nby {{sourcePokemonName}}!", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}} was trapped\nin the vortex!", + "battlerTagsClampOnTrap": "{{sourcePokemonNameWithAffix}} Clamped\n{{pokemonName}}!", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}} became trapped\nby {{moveName}}!", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}} became trapped\nby swirling magma!", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}} got trapped\nby a snap trap!", + "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}} trapped\n{{pokemonNameWithAffix}}!", + "battlerTagsInfestationOnTrap": "{{pokemonNameWithAffix}} has been afflicted \nwith an infestation by {{sourcePokemonNameWithAffix}}!", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}\nprotected itself!", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}\nprotected itself!", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}} braced\nitself!", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}} endured\nthe hit!", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}} endured\nthe hit!", + "battlerTagsPerishSongLapse": "{{pokemonNameWithAffix}}'s perish count fell to {{turnCount}}.", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}} is\nloafing around!", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}} can't\nget it going!", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}} finally\ngot its act together!", + "battlerTagsHighestStatBoostOnAdd": "{{pokemonNameWithAffix}}'s {{statName}}\nwas heightened!", + "battlerTagsHighestStatBoostOnRemove": "The effects of {{pokemonNameWithAffix}}'s\n{{abilityName}} wore off!", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}} is getting\npumped!", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}} relaxed.", + "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}} is being salt cured!", + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!" } as const; diff --git a/src/locales/es/challenges.ts b/src/locales/es/challenges.ts index 9bc5b0923fd..711be39b116 100644 --- a/src/locales/es/challenges.ts +++ b/src/locales/es/challenges.ts @@ -1,67 +1,25 @@ -import { SimpleTranslationEntries } from "#app/interfaces/locales"; +import { TranslationEntries } from "#app/interfaces/locales"; -export const challenges: SimpleTranslationEntries = { +export const challenges: TranslationEntries = { "title": "Parámetros de Desafíos", - "points": "Malas Ideas", - "confirm_start": "¿Continuar con estos desafíos?", - "singleGeneration.name": "Monogeneración", - "singleGeneration.value.0": "No", - "singleGeneration.desc.0": "Solo puedes usar Pokémon de la generación elegida.", - "singleGeneration.value.1": "Gen 1", - "singleGeneration.desc.1": "Solo puedes usar Pokémon de primera generación.", - "singleGeneration.value.2": "Gen 2", - "singleGeneration.desc.2": "Solo puedes usar Pokémon de segunda generación.", - "singleGeneration.value.3": "Gen 3", - "singleGeneration.desc.3": "Solo puedes usar Pokémon de tercera generación.", - "singleGeneration.value.4": "Gen 4", - "singleGeneration.desc.4": "Solo puedes usar Pokémon de cuarta generación.", - "singleGeneration.value.5": "Gen 5", - "singleGeneration.desc.5": "Solo puedes usar Pokémon de quinta generación.", - "singleGeneration.value.6": "Gen 6", - "singleGeneration.desc.6": "Solo puedes usar Pokémon de sexta generación.", - "singleGeneration.value.7": "Gen 7", - "singleGeneration.desc.7": "Solo puedes usar Pokémon de séptima generación.", - "singleGeneration.value.8": "Gen 8", - "singleGeneration.desc.8": "Solo puedes usar Pokémon de octava generación.", - "singleGeneration.value.9": "Gen 9", - "singleGeneration.desc.9": "Solo puedes usar Pokémon de novena generación.", - "singleType.name": "Monotipo", - "singleType.value.0": "No", - "singleType.desc.0": "Solo puedes usar Pokémon del tipo elegido", - "singleType.value.1": "Normal", - "singleType.desc.1": "Solo puedes usar Pokémon de tipo Normal.", - "singleType.value.2": "Lucha", - "singleType.desc.2": "Solo puedes usar Pokémon de tipo Lucha.", - "singleType.value.3": "Volador", - "singleType.desc.3": "Solo puedes usar Pokémon de tipo Volador.", - "singleType.value.4": "Veneno", - "singleType.desc.4": "Solo puedes usar Pokémon de tipo Veneno.", - "singleType.value.5": "Tierra", - "singleType.desc.5": "Solo puedes usar Pokémon de tipo Tierra.", - "singleType.value.6": "Roca", - "singleType.desc.6": "Solo puedes usar Pokémon de tipo Roca.", - "singleType.value.7": "Bicho", - "singleType.desc.7": "Solo puedes usar Pokémon de tipo Bicho.", - "singleType.value.8": "Fantasma", - "singleType.desc.8": "Solo puedes usar Pokémon de tipo Fantasma.", - "singleType.value.9": "Acero", - "singleType.desc.9": "Solo puedes usar Pokémon de tipo Acero.", - "singleType.value.10": "Fuego", - "singleType.desc.10": "Solo puedes usar Pokémon de tipo Fuego.", - "singleType.value.11": "Agua", - "singleType.desc.11": "Solo puedes usar Pokémon de tipo Agua.", - "singleType.value.12": "Planta", - "singleType.desc.12": "Solo puedes usar Pokémon de tipo Planta.", - "singleType.value.13": "Eléctrico", - "singleType.desc.13": "Solo puedes usar Pokémon de tipo Eléctrico.", - "singleType.value.14": "Psíquico", - "singleType.desc.14": "Solo puedes usar Pokémon de tipo Psíquico.", - "singleType.value.15": "Hielo", - "singleType.desc.15": "Solo puedes usar Pokémon de tipo Hielo.", - "singleType.value.16": "Dragón", - "singleType.desc.16": "Solo puedes usar Pokémon de tipo Dragón.", - "singleType.value.17": "Siniestro", - "singleType.desc.17": "Solo puedes usar Pokémon de tipo Siniestro.", - "singleType.value.18": "Hada", - "singleType.desc.18": "Solo puedes usar Pokémon de tipo Hada.", + "illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", + "singleGeneration": { + "name": "Monogeneración", + "desc": "Solo puedes usar Pokémon de {{gen}} generación.", + "desc_default": "Solo puedes usar Pokémon de la generación elegida.", + "gen_1": "primera", + "gen_2": "segunda", + "gen_3": "tercera", + "gen_4": "cuarta", + "gen_5": "quinta", + "gen_6": "sexta", + "gen_7": "séptima", + "gen_8": "octava", + "gen_9": "novena", + }, + "singleType": { + "name": "Monotipo", + "desc": "Solo puedes usar Pokémon with the {{type}} type.", + "desc_default": "Solo puedes usar Pokémon del tipo elegido.", + }, } as const; diff --git a/src/locales/es/common.ts b/src/locales/es/common.ts new file mode 100644 index 00000000000..82966b4ffeb --- /dev/null +++ b/src/locales/es/common.ts @@ -0,0 +1,5 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const common: SimpleTranslationEntries = { + "start": "Start", +} as const; diff --git a/src/locales/es/config.ts b/src/locales/es/config.ts index e85ba976be4..f3747b6c619 100644 --- a/src/locales/es/config.ts +++ b/src/locales/es/config.ts @@ -40,6 +40,7 @@ import { voucher } from "./voucher"; import { weather } from "./weather"; import { partyUiHandler } from "./party-ui-handler"; import { settings } from "#app/locales/es/settings.js"; +import { common } from "#app/locales/es/common.js"; export const esConfig = { ability: ability, @@ -50,6 +51,7 @@ export const esConfig = { biome: biome, challenges: challenges, commandUiHandler: commandUiHandler, + common: common, PGMachv: PGMachv, PGFachv: PGFachv, PGMdialogue: PGMdialogue, diff --git a/src/locales/es/starter-select-ui-handler.ts b/src/locales/es/starter-select-ui-handler.ts index 642d55ab5d8..a6ff2c921c3 100644 --- a/src/locales/es/starter-select-ui-handler.ts +++ b/src/locales/es/starter-select-ui-handler.ts @@ -21,7 +21,6 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "passive": "Pasiva:", "nature": "Natur:", "eggMoves": "Mov. Huevo", - "start": "Iniciar", "addToParty": "Añadir a Equipo", "toggleIVs": "Mostrar IVs", "manageMoves": "Gestionar Movs.", diff --git a/src/locales/fr/battle.ts b/src/locales/fr/battle.ts index e270539c781..e86e00029c6 100644 --- a/src/locales/fr/battle.ts +++ b/src/locales/fr/battle.ts @@ -62,13 +62,70 @@ export const battle: SimpleTranslationEntries = { "drainMessage": "L’énergie de {{pokemonName}}\nest drainée !", "regainHealth": "{{pokemonName}} récupère\ndes PV !", "fainted": "{{pokemonNameWithAffix}}\nest K.O. !", - "statRose": "rose", - "statSharplyRose": "sharply rose", - "statRoseDrastically": "rose drastically", - "statWontGoAnyHigher": "won't go any higher", - "statFell": "fell", - "statHarshlyFell": "harshly fell", - "statSeverelyFell": "severely fell", - "statWontGoAnyLower": "won't go any lower", - "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", + "statRose": "augmente", + "statSharplyRose": "augmente beaucoup", + "statRoseDrastically": "augmente énormément", + "statWontGoAnyHigher": "ne peut plus augmenter", + "statFell": "baisse", + "statHarshlyFell": "baisse beaucoup", + "statSeverelyFell": "baisse énormément", + "statWontGoAnyLower": "ne peut plus baisser", + "ppReduced": "Les PP de la capacité {{moveName}}\nde {{targetName}} sont réduits de {{reduction}} !", + "battlerTagsRechargingLapse": "Le contrecoup empêche {{pokemonNameWithAffix}}\n de bouger !", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}}\nne peut plus s’échapper !", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}} est libéré\nde la capacité {{moveName}} !", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}} a la trouille !\nIl ne peut plus attaquer !", + "battlerTagsConfusedOnAdd": "Ça rend {{pokemonNameWithAffix}}\nconfus !", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}}\nn’est plus confus !", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}}\nest déjà confus !", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}}\nest confus !", + "battlerTagsConfusedLapseHurtItself": "Il se blesse dans sa confusion.", + "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}} n’est pas affecté\nle Lien du Destin !", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}} entraine\n{{pokemonNameWithAffix2}} dans sa chute !", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}} est amoureux\nde {{sourcePokemonName}} !", + "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}} est\ndéjà amoureux !", + "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}}] est amoureux\nde {{sourcePokemonName}} !", + "battlerTagsInfatuatedLapseImmobilize": "L’amour empêche {{pokemonNameWithAffix}}\nd’agir !", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}}\nn’est plus amoureux !", + "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}} est infecté !", + "battlerTagsSeededLapse": "Vampigraine draine l’énergie\nde {{pokemonNameWithAffix}} !", + "battlerTagsSeededLapseShed": "La Vampigraine de {{pokemonNameWithAffix}}\naspire le suintement !", + "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}} commence à cauchemarder !", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}} est\ndéjà prisonnier d’un cauchemar !", + "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}}est\nprisonnier d’un cauchemar !", + "battlerTagsEncoreOnAdd": "({{pokemonNameWithAffix}} !\nEncore une fois !", + "battlerTagsEncoreOnRemove": "{{pokemonNameWithAffix}} n’est\nplus obligé d’utiliser la même capacité !", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}} est prêt\nà aider {{pokemonName}} !", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}} absorbe\ndes nutriments avec ses racines !", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}}\nplante ses racines !", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}} s’entoure\nd’un voile d’eau !", + "battlerTagsAquaRingLapse": "{{moveName}} restaure\nles PV de {{pokemonName}} !", + "battlerTagsDrowsyOnAdd": "Ça rend {{pokemonNameWithAffix}} somnolent !", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}} est blessé\npar la capacité {{moveName}} !", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}} est pris dans\nl’étreinte de {{sourcePokemonName}} !", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}} est ligoté\npar {{sourcePokemonName}} !", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}} est piégé\ndans le tourbillon !", + "battlerTagsClampOnTrap": "{{sourcePokemonNameWithAffix}} est pris dans le Claquoir\nde {{pokemonName}} !", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}} est piégé\npar {{moveName}} !", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}} est piégé\ndans un tourbillon de magma !", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}} est tombé\ndans un Troquenard !", + "battlerTagsThunderCageOnTrap": "{{pokemonNameWithAffix}} se fait emprisonner\npar {{sourcePokemonNameWithAffix}} !", + "battlerTagsInfestationOnTrap": "{{pokemonNameWithAffix}} est harcelé\npar {{sourcePokemonNameWithAffix}} !", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}\nest prêt à se protéger !", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}\nse protège !", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}} se prépare\nà encaisser les coups !", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !", + "battlerTagsPerishSongLapse": "Le compte à rebours de Requiem\nde {{pokemonNameWithAffix}} descend à {{turnCount}} !", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}} paresse !", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}}\nn’arrive pas à se motiver !", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}}\narrive enfin à s’y mettre sérieusement !", + "battlerTagsHighestStatBoostOnAdd": "{{statName}} de {{pokemonNameWithAffix}}\nest renforcée !", + "battlerTagsHighestStatBoostOnRemove": "L’effet du talent {{abilityName}}\nde {{pokemonNameWithAffix}} se dissipe !", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}}\nest prêt à tout donner !", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}} se détend.", + "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}}\nest couvert de sel !", + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} est blessé\npar la capacité {{moveName}} !", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} sacrifie des PV\net lance une malédiction sur {{pokemonName}} !", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} est touché par la malédiction !" } as const; diff --git a/src/locales/fr/challenges.ts b/src/locales/fr/challenges.ts index 6029cdc302a..d88960dbe3b 100644 --- a/src/locales/fr/challenges.ts +++ b/src/locales/fr/challenges.ts @@ -1,67 +1,26 @@ -import { SimpleTranslationEntries } from "#app/interfaces/locales"; +import { TranslationEntries } from "#app/interfaces/locales"; -export const challenges: SimpleTranslationEntries = { +export const challenges: TranslationEntries = { "title": "Paramètres du Challenge", - "start": "Démarrer", "illegalEvolution": "{{pokemon}} s’est transformé en Pokémon\ninéligible pour ce challenge !", - "singleGeneration.name": "Mono-génération", - "singleGeneration.value.0": "Désactivé", - "singleGeneration.desc.0": "Vous ne pouvez choisir que des Pokémon de la génération sélectionnée.", - "singleGeneration.value.1": "1G", - "singleGeneration.desc.1": "Vous ne pouvez choisir que des Pokémon de 1re génération.", - "singleGeneration.value.2": "2G", - "singleGeneration.desc.2": "Vous ne pouvez choisir que des Pokémon de 2e génération.", - "singleGeneration.value.3": "3G", - "singleGeneration.desc.3": "Vous ne pouvez choisir que des Pokémon de 3e génération.", - "singleGeneration.value.4": "4G", - "singleGeneration.desc.4": "Vous ne pouvez choisir que des Pokémon de 4e génération.", - "singleGeneration.value.5": "5G", - "singleGeneration.desc.5": "Vous ne pouvez choisir que des Pokémon de 5e génération.", - "singleGeneration.value.6": "6G", - "singleGeneration.desc.6": "Vous ne pouvez choisir que des Pokémon de 6e génération.", - "singleGeneration.value.7": "7G", - "singleGeneration.desc.7": "Vous ne pouvez choisir que des Pokémon de 7e génération.", - "singleGeneration.value.8": "8G", - "singleGeneration.desc.8": "Vous ne pouvez choisir que des Pokémon de 8e génération.", - "singleGeneration.value.9": "9G", - "singleGeneration.desc.9": "Vous ne pouvez choisir que des Pokémon de 9e génération.", - "singleType.name": "Mono-type", - "singleType.value.0": "Désactivé", - "singleType.desc.0": "Vous ne pouvez choisir que des Pokémon du type sélectionné.", - "singleType.value.1": "Normal", - "singleType.desc.1": "Vous ne pouvez choisir que des Pokémon de type Normal.", - "singleType.value.2": "Combat", - "singleType.desc.2": "Vous ne pouvez choisir que des Pokémon de type Combat.", - "singleType.value.3": "Vol", - "singleType.desc.3": "Vous ne pouvez choisir que des Pokémon de type Vol.", - "singleType.value.4": "Poison", - "singleType.desc.4": "Vous ne pouvez choisir que des Pokémon de type Poison.", - "singleType.value.5": "Sol", - "singleType.desc.5": "Vous ne pouvez choisir que des Pokémon de type Sol.", - "singleType.value.6": "Roche", - "singleType.desc.6": "Vous ne pouvez choisir que des Pokémon de type Roche.", - "singleType.value.7": "Insecte", - "singleType.desc.7": "Vous ne pouvez choisir que des Pokémon de type Insecte.", - "singleType.value.8": "Spectre", - "singleType.desc.8": "Vous ne pouvez choisir que des Pokémon de type Spectre.", - "singleType.value.9": "Acier", - "singleType.desc.9": "Vous ne pouvez choisir que des Pokémon de type Acier.", - "singleType.value.10": "Feu", - "singleType.desc.10": "Vous ne pouvez choisir que des Pokémon de type Feu.", - "singleType.value.11": "Eau", - "singleType.desc.11": "Vous ne pouvez choisir que des Pokémon de type Eau.", - "singleType.value.12": "Plante", - "singleType.desc.12": "Vous ne pouvez choisir que des Pokémon de type Plante.", - "singleType.value.13": "Électrik", - "singleType.desc.13": "Vous ne pouvez choisir que des Pokémon de type Électrik.", - "singleType.value.14": "Psy", - "singleType.desc.14": "Vous ne pouvez choisir que des Pokémon de type Psy.", - "singleType.value.15": "Glace", - "singleType.desc.15": "Vous ne pouvez choisir que des Pokémon de type Glace.", - "singleType.value.16": "Dragon", - "singleType.desc.16": "Vous ne pouvez choisir que des Pokémon de type Dragon.", - "singleType.value.17": "Ténèbres", - "singleType.desc.17": "Vous ne pouvez choisir que des Pokémon de type Ténèbres.", - "singleType.value.18": "Fée", - "singleType.desc.18": "Vous ne pouvez choisir que des Pokémon de type Fée.", + "singleGeneration": { + "name": "Mono-génération", + "desc": "Vous ne pouvez choisir que des Pokémon de {{gen}} génération.", + "desc_default": "Vous ne pouvez choisir que des Pokémon de la génération sélectionnée.", + "gen_1": "1re", + "gen_2": "2e", + "gen_3": "3e", + "gen_4": "4e", + "gen_5": "5e", + "gen_6": "6e", + "gen_7": "7e", + "gen_8": "8e", + "gen_9": "9e", + }, + "singleType": { + "name": "Mono-type", + "desc": "Vous ne pouvez choisir que des Pokémon de type {{type}}.", + "desc_default": "Vous ne pouvez choisir que des Pokémon du type sélectionné." + //type in pokemon-info + }, } as const; diff --git a/src/locales/fr/common.ts b/src/locales/fr/common.ts new file mode 100644 index 00000000000..e4ccc627f5e --- /dev/null +++ b/src/locales/fr/common.ts @@ -0,0 +1,5 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const common: SimpleTranslationEntries = { + "start": "Lancer", +} as const; diff --git a/src/locales/fr/config.ts b/src/locales/fr/config.ts index b5e7a4e383a..59e8eb9f307 100644 --- a/src/locales/fr/config.ts +++ b/src/locales/fr/config.ts @@ -40,6 +40,7 @@ import { voucher } from "./voucher"; import { weather } from "./weather"; import { partyUiHandler } from "./party-ui-handler"; import { settings } from "#app/locales/fr/settings.js"; +import { common } from "#app/locales/fr/common.js"; export const frConfig = { ability: ability, @@ -50,6 +51,7 @@ export const frConfig = { biome: biome, challenges: challenges, commandUiHandler: commandUiHandler, + common: common, PGMachv: PGMachv, PGFachv: PGFachv, PGMdialogue: PGMdialogue, diff --git a/src/locales/fr/starter-select-ui-handler.ts b/src/locales/fr/starter-select-ui-handler.ts index 0874c18d84c..87ede732f11 100644 --- a/src/locales/fr/starter-select-ui-handler.ts +++ b/src/locales/fr/starter-select-ui-handler.ts @@ -21,7 +21,6 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "passive": "Passif :", "nature": "Nature :", "eggMoves": "Capacités Œuf", - "start": "Lancer", "addToParty": "Ajouter à l’équipe", "toggleIVs": "Voir les IV", "manageMoves": "Modifier les Capacités", diff --git a/src/locales/it/battle.ts b/src/locales/it/battle.ts index 4f90a361ecb..a4b3c32db07 100644 --- a/src/locales/it/battle.ts +++ b/src/locales/it/battle.ts @@ -62,13 +62,70 @@ export const battle: SimpleTranslationEntries = { "drainMessage": "Viene prelevata energia\n da{{pokemonName}}!", "regainHealth": "{{pokemonName}} ha rigenerato\npunti salute!", "fainted": "{{pokemonNameWithAffix}} non è più in\ngrado di combattere!", - "statRose": "rose", - "statSharplyRose": "sharply rose", - "statRoseDrastically": "rose drastically", - "statWontGoAnyHigher": "won't go any higher", - "statFell": "fell", - "statHarshlyFell": "harshly fell", - "statSeverelyFell": "severely fell", - "statWontGoAnyLower": "won't go any lower", + "statRose": "è aumentato/a", + "statSharplyRose": "è aumentato/a molto", + "statRoseDrastically": "è aumentato/a drasticamente", + "statWontGoAnyHigher": "non può aumentare più di così", + "statFell": "è diminuito/a", + "statHarshlyFell": "è diminuito/a molto", + "statSeverelyFell": "è diminuito/a drasticamente", + "statWontGoAnyLower": "non può diminuire più di così", "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", + "battlerTagsRechargingLapse": "{{pokemonNameWithAffix}} deve\nricaricarsi!", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}} non può\npiù fuggire!", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}} è stato liberato\nda {{moveName}}", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}} tentenna!", + "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}} è\nconfuso!", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}} non\nè più confuso!", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}} è\ngià confuso!", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}} è\nconfuso!", + "battlerTagsConfusedLapseHurtItself": "Si colpisce da solo per via della\nconfusione!", + "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}} è immune\na Destinobbligato.", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}} trascina\ncon sé{{pokemonNameWithAffix2}}!", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}} si è infatuato\ndi {{sourcePokemonName}}!", + "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}} è\ngià infatuato!", + "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}} è infatuato\ndi {{sourcePokemonName}}!", + "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}} è\nimmobilizzato dall'infatuazione!", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}} non è\npiù infatuato.", + "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}} è pieno di semi!", + "battlerTagsSeededLapse": "La salute di {{pokemonNameWithAffix}}\nviene prelevata da Parassiseme!", + "battlerTagsSeededLapseShed": "Parassiseme di {{pokemonNameWithAffix}}\nha risucchiato la melma!", + "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}} sta\navendo un Incubo!", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}} sta\ngià avendo un Incubo!", + "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}} è bloccato\nin un Incubo!", + "battlerTagsEncoreOnAdd": "({{pokemonNameWithAffix}} ha\nsubito Ripeti!", + "battlerTagsEncoreOnRemove": "L'effetto di Ripeti su {{pokemonNameWithAffix}}\n è terminato!", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}} è pronto ad\naiutare {{pokemonName}}!", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}} assorbe\nnutrienti dalle sue radici!", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}} ha messo le radici!", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}} si è circondato\ncon un velo d'acqua!", + "battlerTagsAquaRingLapse": "{{moveName}} ha ripristinato\ni PS di {{pokemonName}}!", + "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}} sta per addormentarsi!", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}} subisce danni\nper via di {{moveName}}!", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}} viene schiacciato da\n{{moveName}} di {{sourcePokemonName}}!", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}} è stato avvinghiato\nda {{sourcePokemonName}}!", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}} è intrappolato\nnel vortice!", + "battlerTagsClampOnTrap": "{{sourcePokemonNameWithAffix}} sta intenagliando\n{{pokemonName}}!", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}} è intrappolato\nda {{moveName}}!", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}} è intrappolato\nnel magma vorticoso!", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}} è intrappolato\nin una tagliola!", + "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}} ha intrappolato\n{{pokemonNameWithAffix}}!", + "battlerTagsInfestationOnTrap": "{{pokemonNameWithAffix}} ha subito un\ninfestazione da parte di {{sourcePokemonNameWithAffix}}!", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}\nsi è protetto!", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}\nsi è protetto!", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}} si prepara a\nsubire il colpo!", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}} resiste\nal colpo!", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}} ha resistito\ngrazie a Vigore!", + "battlerTagsPerishSongLapse": "Il conto alla rovescia di Ultimocanto per {{pokemonNameWithAffix}} scende a {{turnCount}}.", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}} sta\nciondolando!", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}} non\ningrana!", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}} ritrova\nlo slancio!", + "battlerTagsHighestStatBoostOnAdd": "{{statName}} di {{pokemonNameWithAffix}}\nviene aumentato/a!", + "battlerTagsHighestStatBoostOnRemove": "Gli effetti di {{abilityName}}\ndi {{pokemonNameWithAffix}} sono cessati!", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}} si prepara\nalla lotta!", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}} si è rilassato.", + "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}} è stato messo sotto sale!", + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} viene colpito da {{moveName}}!", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} ha sacrificato metà dei suoi PS per\nlanciare una maledizione su {{pokemonName}}!", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} subisce la maledizione!" } as const; diff --git a/src/locales/it/challenges.ts b/src/locales/it/challenges.ts index 0a15b22f83e..2643b16d0f7 100644 --- a/src/locales/it/challenges.ts +++ b/src/locales/it/challenges.ts @@ -1,67 +1,25 @@ -import { SimpleTranslationEntries } from "#app/interfaces/locales"; +import { TranslationEntries } from "#app/interfaces/locales"; -export const challenges: SimpleTranslationEntries = { +export const challenges: TranslationEntries = { "title": "Modificatori delle sfide", - "points": "Pessime idee", - "confirm_start": "Procedere con le sfide selezionate?", - "singleGeneration.name": "Mono gen", - "singleGeneration.value.0": "Off", - "singleGeneration.desc.0": "Puoi usare solo Pokémon della generazione selezionata.", - "singleGeneration.value.1": "1ª gen", - "singleGeneration.desc.1": "Puoi usare solo Pokémon di 1ª generazione.", - "singleGeneration.value.2": "2ª gen", - "singleGeneration.desc.2": "Puoi usare solo Pokémon di 2ª generazione.", - "singleGeneration.value.3": "3ª gen", - "singleGeneration.desc.3": "Puoi usare solo Pokémon di 3ª generazione.", - "singleGeneration.value.4": "4ª gen", - "singleGeneration.desc.4": "Puoi usare solo Pokémon di 4ª generazione.", - "singleGeneration.value.5": "5ª gen", - "singleGeneration.desc.5": "Puoi usare solo Pokémon di 5ª generazione.", - "singleGeneration.value.6": "6ª gen", - "singleGeneration.desc.6": "Puoi usare solo Pokémon di 6ª generazione.", - "singleGeneration.value.7": "7ª gen", - "singleGeneration.desc.7": "Puoi usare solo Pokémon di 7ª generazione.", - "singleGeneration.value.8": "8ª gen", - "singleGeneration.desc.8": "Puoi usare solo Pokémon di 8ª generazione.", - "singleGeneration.value.9": "9ª gen", - "singleGeneration.desc.9": "Puoi usare solo Pokémon di 9ª generazione.", - "singleType.name": "Mono tipo", - "singleType.value.0": "Off", - "singleType.desc.0": "Puoi usare solo Pokémon del tipo selezionato.", - "singleType.value.1": "Normale", - "singleType.desc.1": "Puoi usare solo Pokémon di tipo normale.", - "singleType.value.2": "Lotta", - "singleType.desc.2": "Puoi usare solo Pokémon di tipo lotta.", - "singleType.value.3": "Volante", - "singleType.desc.3": "Puoi usare solo Pokémon di tipo volante.", - "singleType.value.4": "Veleno", - "singleType.desc.4": "Puoi usare solo Pokémon di tipo veleno.", - "singleType.value.5": "Terra", - "singleType.desc.5": "Puoi usare solo Pokémon di tipo terra.", - "singleType.value.6": "Roccia", - "singleType.desc.6": "Puoi usare solo Pokémon di tipo roccia.", - "singleType.value.7": "Coleottero", - "singleType.desc.7": "Puoi usare solo Pokémon di tipo coleottero.", - "singleType.value.8": "Spettro", - "singleType.desc.8": "Puoi usare solo Pokémon di tipo spettro.", - "singleType.value.9": "Acciaio", - "singleType.desc.9": "Puoi usare solo Pokémon di tipo acciaio.", - "singleType.value.10": "Fuoco", - "singleType.desc.10": "Puoi usare solo Pokémon di tipo fuoco.", - "singleType.value.11": "Acqua", - "singleType.desc.11": "Puoi usare solo Pokémon di tipo acqua.", - "singleType.value.12": "Erba", - "singleType.desc.12": "Puoi usare solo Pokémon di tipo erba.", - "singleType.value.13": "Elettro", - "singleType.desc.13": "Puoi usare solo Pokémon di tipo elettro.", - "singleType.value.14": "Psico", - "singleType.desc.14": "Puoi usare solo Pokémon di tipo psico.", - "singleType.value.15": "Ghiaccio", - "singleType.desc.15": "Puoi usare solo Pokémon di tipo ghiaccio.", - "singleType.value.16": "Drago", - "singleType.desc.16": "Puoi usare solo Pokémon di tipo drago.", - "singleType.value.17": "Buio", - "singleType.desc.17": "Puoi usare solo Pokémon di tipo buio.", - "singleType.value.18": "Folletto", - "singleType.desc.18": "Puoi usare solo Pokémon di tipo folletto.", + "illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", + "singleGeneration": { + "name": "Mono gen", + "desc": "Puoi usare solo Pokémon di {{gen}} generazione.", + "desc_default": "Puoi usare solo Pokémon della generazione selezionata.", + "gen_1": "1ª", + "gen_2": "2ª", + "gen_3": "3ª", + "gen_4": "4ª", + "gen_5": "5ª", + "gen_6": "6ª", + "gen_7": "7ª", + "gen_8": "8ª", + "gen_9": "9ª", + }, + "singleType": { + "name": "Mono tipo", + "desc": "Puoi usare solo Pokémon di tipo {{type}}.", + "desc_default": "Puoi usare solo Pokémon del tipo selezionato." + }, } as const; diff --git a/src/locales/it/common.ts b/src/locales/it/common.ts new file mode 100644 index 00000000000..f42fa311472 --- /dev/null +++ b/src/locales/it/common.ts @@ -0,0 +1,5 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const common: SimpleTranslationEntries = { + "start": "Inizia", +} as const; diff --git a/src/locales/it/config.ts b/src/locales/it/config.ts index 6f14aabda50..7cc063a6b23 100644 --- a/src/locales/it/config.ts +++ b/src/locales/it/config.ts @@ -40,6 +40,7 @@ import { voucher } from "./voucher"; import { weather } from "./weather"; import { partyUiHandler } from "./party-ui-handler"; import { settings } from "#app/locales/it/settings.js"; +import { common } from "#app/locales/it/common.js"; export const itConfig = { ability: ability, @@ -50,6 +51,7 @@ export const itConfig = { biome: biome, challenges: challenges, commandUiHandler: commandUiHandler, + common: common, PGMachv: PGMachv, PGFachv: PGFachv, PGMdialogue: PGMdialogue, diff --git a/src/locales/it/starter-select-ui-handler.ts b/src/locales/it/starter-select-ui-handler.ts index 8f68e5ff10d..5f9960561ca 100644 --- a/src/locales/it/starter-select-ui-handler.ts +++ b/src/locales/it/starter-select-ui-handler.ts @@ -21,7 +21,6 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "passive": "Passiva:", "nature": "Natura:", "eggMoves": "Mosse da uova", - "start": "Inizia", "addToParty": "Aggiungi al gruppo", "toggleIVs": "Vedi/Nascondi IV", "manageMoves": "Gestisci mosse", diff --git a/src/locales/ko/battle.ts b/src/locales/ko/battle.ts index 48f7339e9ce..70464c8487a 100644 --- a/src/locales/ko/battle.ts +++ b/src/locales/ko/battle.ts @@ -70,5 +70,62 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "[[가]] 크게 떨어졌다!", "statSeverelyFell": "[[가]] 매우 크게 떨어졌다!", "statWontGoAnyLower": "[[는]] 더 떨어지지 않는다!", - "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", + "ppReduced": "{{targetName}}의\n{{moveName}}[[를]] {{reduction}} 깎았다!", + "battlerTagsRechargingLapse": "공격의 반동으로\n{{pokemonNameWithAffix}}[[는]] 움직일 수 없다!", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}}[[는]]\n이제 도망칠 수 없다!", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}}[[는]]\n{{moveName}}로부터 풀려났다!", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}}[[는]] 풀이 죽어\n움직일 수 없었다!", + "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}}[[는]]\n혼란에 빠졌다!", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}}의\n혼란이 풀렸다!", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}}[[는]]\n이미 혼란에 빠져 있다", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}}[[는]]\n혼란에 빠져 있다!", + "battlerTagsConfusedLapseHurtItself": "영문도 모른채\n자신을 공격했다!", + "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}}[[는]]\n길동무의 영향을 받지 않는다.", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}}[[는]] {{pokemonNameWithAffix2}}[[를]]\n길동무로 삼았다!", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}}[[는]]\n헤롱헤롱해졌다!", + "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}}[[는]]\n이미 헤롱헤롱해있다!", + "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}}[[는]]\n{{sourcePokemonName}}에게 헤롱헤롱해 있다!", + "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}}[[는]] 헤롱헤롱해서\n기술을 쓸 수 없었다!", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}}[[는]]\n헤롱헤롱 상태에서 벗어났다.", + "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}}에게\n씨앗을 심었다!", + "battlerTagsSeededLapse": "씨뿌리기가 {{pokemonNameWithAffix}}의\n체력을 빼앗는다!", + "battlerTagsSeededLapseShed": "{{pokemonNameWithAffix}}[[는]]\n씨앗을 날려버렸다!", + "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}}[[는]]\n악몽을 꾸기 시작했다!", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}}[[는]]\n이미 악몽을 꾸고 있다!", + "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}}[[는]]\n악몽에 시달리고 있다!", + "battlerTagsEncoreOnAdd": "{{pokemonNameWithAffix}}[[는]]\n앙코르를 받았다!", + "battlerTagsEncoreOnRemove": "{{pokemonNameWithAffix}}의\n앙코르 상태가 풀렸다!", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}}[[는]] {{pokemonName}}에게\n도우미가 되어주려 한다!", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}}[[는]] 뿌리로부터\n양분을 흡수했다!", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}}[[는]] 뿌리를 뻗었다!", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}}[[는]]\n물의 베일을 둘러썼다!", + "battlerTagsAquaRingLapse": "{{moveName}} 효과로 \n{{pokemonName}}[[는]] HP를 회복했다!", + "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}}의\n졸음을 유도했다!", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}}[[는]] {{moveName}}의\n데미지를 입고 있다!", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}}[[는]] {{sourcePokemonName}}에게\n{{moveName}}[[를]] 당했다!", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}}[[는]] {{sourcePokemonName}}에게\n휘감겼다!", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}}[[는]]\n소용돌이 속에 갇혔다!", + "battlerTagsClampOnTrap": "{{sourcePokemonNameWithAffix}}[[는]] {{pokemonName}}의\n껍질에 꼈다!", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}}[[는]]\n{{moveName}}에 붙잡혔다!", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}}[[는]]\n마그마의 소용돌이에 갇혔다!", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}}[[는]]\n집게덫에 붙잡혔다!", + "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}}[[는]]\n{{pokemonNameWithAffix}}를 가두었다!", + "battlerTagsInfestationOnTrap": "{{pokemonNameWithAffix}}[[는]]\n{{sourcePokemonNameWithAffix}}에게 엉겨 붙었다!", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}[[는]]\n방어 태세에 들어갔다!", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}[[는]]\n공격으로부터 몸을 지켰다!", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}}[[는]]\n버티기 태세에 들어갔다!", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}}[[는]]\n공격을 버텼다!", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}}[[는]]\n공격을 버텼다!", + "battlerTagsPerishSongLapse": "{{pokemonNameWithAffix}}의 멸망의\n카운트가 {{turnCount}}[[가]] 되었다!", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}}[[는]] 게으름을 피우고 있다!", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}}[[는]] 컨디션이\n좋아지지 않는다!", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}} 는 마침내\n컨디션을 회복했다!", + "battlerTagsHighestStatBoostOnAdd": "{{pokemonNameWithAffix}}의\n{{statName}}[[가]] 올라갔다!", + "battlerTagsHighestStatBoostOnRemove": "The effects of {{pokemonNameWithAffix}}'s\n{{abilityName}} wore off!", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}}[[는]]\n의욕이 넘치고 있다!", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}}[[는]] 평소로 돌아왔다.", + "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}}[[는]]\n소금에 절여졌다!", + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}}[[는]] 소금절이의\n데미지를 입고 있다.", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}}[[는]]\n자신의 체력을 깎아서\n{{pokemonName}}에게 저주를 걸었다!", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}}[[는]]\n저주받고 있다!" } as const; diff --git a/src/locales/ko/challenges.ts b/src/locales/ko/challenges.ts index 64fa316b3bb..1f10c4f215a 100644 --- a/src/locales/ko/challenges.ts +++ b/src/locales/ko/challenges.ts @@ -1,67 +1,26 @@ -import { SimpleTranslationEntries } from "#app/interfaces/locales"; +import { TranslationEntries } from "#app/interfaces/locales"; -export const challenges: SimpleTranslationEntries = { +export const challenges: TranslationEntries = { "title": "챌린지 조건 설정", - "points": "Bad Ideas", - "confirm_start": "이 조건으로 챌린지를 진행하시겠습니까?", - "singleGeneration.name": "단일 세대", - "singleGeneration.value.0": "설정 안함", - "singleGeneration.desc.0": "선택한 세대의 포켓몬만 사용할 수 있습니다.", - "singleGeneration.value.1": "1세대", - "singleGeneration.desc.1": "1세대의 포켓몬만 사용할 수 있습니다.", - "singleGeneration.value.2": "2세대", - "singleGeneration.desc.2": "2세대의 포켓몬만 사용할 수 있습니다.", - "singleGeneration.value.3": "3세대", - "singleGeneration.desc.3": "3세대의 포켓몬만 사용할 수 있습니다.", - "singleGeneration.value.4": "4세대", - "singleGeneration.desc.4": "4세대의 포켓몬만 사용할 수 있습니다.", - "singleGeneration.value.5": "5세대", - "singleGeneration.desc.5": "5세대의 포켓몬만 사용할 수 있습니다.", - "singleGeneration.value.6": "6세대", - "singleGeneration.desc.6": "6세대의 포켓몬만 사용할 수 있습니다.", - "singleGeneration.value.7": "7세대", - "singleGeneration.desc.7": "7세대의 포켓몬만 사용할 수 있습니다.", - "singleGeneration.value.8": "8세대", - "singleGeneration.desc.8": "8세대의 포켓몬만 사용할 수 있습니다.", - "singleGeneration.value.9": "9세대", - "singleGeneration.desc.9": "9세대의 포켓몬만 사용할 수 있습니다.", - "singleType.name": "단일 타입", - "singleType.value.0": "설정 안함", - "singleType.desc.0": "선택한 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.1": "노말", - "singleType.desc.1": "노말 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.2": "격투", - "singleType.desc.2": "격투 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.3": "비행", - "singleType.desc.3": "비행 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.4": "독", - "singleType.desc.4": "독 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.5": "땅", - "singleType.desc.5": "땅 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.6": "바위 ", - "singleType.desc.6": "바위 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.7": "벌레", - "singleType.desc.7": "벌레 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.8": "고스트", - "singleType.desc.8": "고스트 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.9": "강철", - "singleType.desc.9": "강철 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.10": "불꽃", - "singleType.desc.10": "불꽃 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.11": "물", - "singleType.desc.11": "물 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.12": "풀", - "singleType.desc.12": "풀 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.13": "전기", - "singleType.desc.13": "전기 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.14": "에스퍼", - "singleType.desc.14": "에스퍼 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.15": "얼음", - "singleType.desc.15": "얼음 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.16": "드래곤", - "singleType.desc.16": "드래곤 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.17": "악", - "singleType.desc.17": "악 타입의 포켓몬만 사용할 수 있습니다.", - "singleType.value.18": "페어리", - "singleType.desc.18": "페어리 타입의 포켓몬만 사용할 수 있습니다.", + "illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", + "singleGeneration": { + "name": "단일 세대", + "desc": "{{gen}}의 포켓몬만 사용할 수 있습니다.", + "desc_default": "선택한 세대의 포켓몬만 사용할 수 있습니다.", + "gen_1": "1세대", + "gen_2": "2세대", + "gen_3": "3세대", + "gen_4": "4세대", + "gen_5": "5세대", + "gen_6": "6세대", + "gen_7": "7세대", + "gen_8": "8세대", + "gen_9": "9세대", + }, + "singleType": { + "name": "단일 타입", + "desc": "{{type}} 타입의 포켓몬만 사용할 수 있습니다.", + "desc_default": "선택한 타입의 포켓몬만 사용할 수 있습니다." + //type in pokemon-info + }, } as const; diff --git a/src/locales/ko/common.ts b/src/locales/ko/common.ts new file mode 100644 index 00000000000..d87be482f99 --- /dev/null +++ b/src/locales/ko/common.ts @@ -0,0 +1,5 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const common: SimpleTranslationEntries = { + "start": "시작", +} as const; diff --git a/src/locales/ko/config.ts b/src/locales/ko/config.ts index 99cf5ddd8ea..3ec162abd34 100644 --- a/src/locales/ko/config.ts +++ b/src/locales/ko/config.ts @@ -40,6 +40,7 @@ import { voucher } from "./voucher"; import { weather } from "./weather"; import { partyUiHandler } from "./party-ui-handler"; import { settings } from "#app/locales/ko/settings.js"; +import { common } from "#app/locales/ko/common.js"; export const koConfig = { ability: ability, @@ -50,6 +51,7 @@ export const koConfig = { biome: biome, challenges: challenges, commandUiHandler: commandUiHandler, + common: common, PGMachv: PGMachv, PGFachv: PGFachv, PGMdialogue: PGMdialogue, diff --git a/src/locales/ko/modifier-type.ts b/src/locales/ko/modifier-type.ts index 479e1ca02e2..a0bae4ea703 100644 --- a/src/locales/ko/modifier-type.ts +++ b/src/locales/ko/modifier-type.ts @@ -250,14 +250,14 @@ export const modifierType: ModifierTypeTranslationEntries = { }, TempBattleStatBoosterStatName: { - "ATK": "Attack", - "DEF": "Defense", - "SPATK": "Sp. Atk", - "SPDEF": "Sp. Def", - "SPD": "Speed", - "ACC": "Accuracy", - "CRIT": "Critical Hit Ratio", - "EVA": "Evasiveness", + "ATK": "공격", + "DEF": "방어", + "SPATK": "특수공격", + "SPDEF": "특수방어", + "SPD": "스피드", + "ACC": "명중률", + "CRIT": "급소율", + "EVA": "회피율", "DEFAULT": "???", }, diff --git a/src/locales/ko/settings.ts b/src/locales/ko/settings.ts index 08f0c635199..28fe99f265f 100644 --- a/src/locales/ko/settings.ts +++ b/src/locales/ko/settings.ts @@ -92,7 +92,7 @@ export const settings: SimpleTranslationEntries = { "buttonSpeedUp": "속도 올리기", "buttonSlowDown": "속도 내리기", "alt": " (대체)", - "mute": "Mute", - "controller": "Controller", - "gamepadSupport": "Gamepad Support" + "mute": "음소거", + "controller": "컨트롤러", + "gamepadSupport": "게임패드 지원" } as const; diff --git a/src/locales/ko/starter-select-ui-handler.ts b/src/locales/ko/starter-select-ui-handler.ts index ab155a4a048..f78e760c4e0 100644 --- a/src/locales/ko/starter-select-ui-handler.ts +++ b/src/locales/ko/starter-select-ui-handler.ts @@ -6,7 +6,7 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales"; * account interactions, descriptive text, etc. */ export const starterSelectUiHandler: SimpleTranslationEntries = { - "confirmStartTeam":"이 포켓몬들로 시작하시겠습니까?", + "confirmStartTeam": "이 포켓몬들로 시작하시겠습니까?", "gen1": "1세대", "gen2": "2세대", "gen3": "3세대", @@ -21,11 +21,12 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "passive": "패시브:", "nature": "성격:", "eggMoves": "알 기술", - "start": "시작", "addToParty": "파티에 추가", "toggleIVs": "개체값 토글", "manageMoves": "기술 관리", + "manageNature": "성격 관리", "useCandies": "사탕 사용", + "selectNature": "교체할 성격을 선택해주세요.", "selectMoveSwapOut": "교체할 기술을 선택해주세요.", "selectMoveSwapWith": "교체될 기술을 선택해주세요. 대상:", "unlockPassive": "패시브 해금", diff --git a/src/locales/ko/trainers.ts b/src/locales/ko/trainers.ts index 374b0180364..429ab13b223 100644 --- a/src/locales/ko/trainers.ts +++ b/src/locales/ko/trainers.ts @@ -112,7 +112,7 @@ export const trainerClasses: SimpleTranslationEntries = { "school_kid": "학원끝난 아이", "school_kid_female": "학원끝난 아이", "school_kids": "학원끝난 아이", - "swimmer": "수연팬티 소년", + "swimmer": "수영팬티 소년", "swimmer_female": "비키니 아가씨", "swimmers": "수영팬티 소년 & 비키니 아가씨", // 확인 필요 "twins": "쌍둥이", diff --git a/src/locales/pt_BR/battle.ts b/src/locales/pt_BR/battle.ts index 036c761bca7..e7a3adf4b31 100644 --- a/src/locales/pt_BR/battle.ts +++ b/src/locales/pt_BR/battle.ts @@ -71,4 +71,61 @@ export const battle: SimpleTranslationEntries = { "statSeverelyFell": "diminuiu severamente", "statWontGoAnyLower": "não vai mais diminuir", "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", + "battlerTagsRechargingLapse": "{{pokemonNameWithAffix}} must\nrecharge!", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}} can no\nlonger escape!", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}} was freed\nfrom {{moveName}}", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}} flinched!", + "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}} became\nconfused!", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}} snapped\nout of confusion!", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}} is\nalready confused!", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}} is\nconfused!", + "battlerTagsConfusedLapseHurtItself": "It hurt itself in its\nconfusion!", + "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}} is unaffected\nby the effects of Destiny Bond.", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}} took\n{{pokemonNameWithAffix2}} down with it!", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}} fell in love\nwith {{sourcePokemonName}}!", + "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}} is\nalready in love!", + "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}} is in love\nwith {{sourcePokemonName}}!", + "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}} is\nimmobilized by love!", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}} got over\nits infatuation.", + "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}} was seeded!", + "battlerTagsSeededLapse": "{{pokemonNameWithAffix}}'s health is\nsapped by Leech Seed!", + "battlerTagsSeededLapseShed": "{{pokemonNameWithAffix}}'s Leech Seed\nsucked up the liquid ooze!", + "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}} began\nhaving a Nightmare!", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}} is\nalready locked in a Nightmare!", + "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}} is locked\nin a Nightmare!", + "battlerTagsEncoreOnAdd": "({{pokemonNameWithAffix}} got\nan Encore!", + "battlerTagsEncoreOnRemove": "{{pokemonNameWithAffix}}'s Encore\nended!", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}} is ready to\nhelp {{pokemonName}}!", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}} absorbed\nnutrients with its roots!", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}} planted its roots!", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}} surrounded\nitself with a veil of water!", + "battlerTagsAquaRingLapse": "{{moveName}} restored\n{{pokemonName}}'s HP!", + "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}} grew drowsy!", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}} is hurt\nby {{moveName}}!", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}} was squeezed by\n{{sourcePokemonName}}'s {{moveName}}!", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}} was Wrapped\nby {{sourcePokemonName}}!", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}} was trapped\nin the vortex!", + "battlerTagsClampOnTrap": "{{sourcePokemonNameWithAffix}} Clamped\n{{pokemonName}}!", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}} became trapped\nby {{moveName}}!", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}} became trapped\nby swirling magma!", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}} got trapped\nby a snap trap!", + "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}} trapped\n{{pokemonNameWithAffix}}!", + "battlerTagsInfestationOnTrap": "{{pokemonNameWithAffix}} has been afflicted \nwith an infestation by {{sourcePokemonNameWithAffix}}!", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}\nprotected itself!", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}\nprotected itself!", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}} braced\nitself!", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}} endured\nthe hit!", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}} endured\nthe hit!", + "battlerTagsPerishSongLapse": "{{pokemonNameWithAffix}}'s perish count fell to {{turnCount}}.", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}} is\nloafing around!", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}} can't\nget it going!", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}} finally\ngot its act together!", + "battlerTagsHighestStatBoostOnAdd": "{{pokemonNameWithAffix}}'s {{statName}}\nwas heightened!", + "battlerTagsHighestStatBoostOnRemove": "The effects of {{pokemonNameWithAffix}}'s\n{{abilityName}} wore off!", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}} is getting\npumped!", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}} relaxed.", + "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}} is being salt cured!", + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!" } as const; diff --git a/src/locales/pt_BR/challenges.ts b/src/locales/pt_BR/challenges.ts index 98731fe890b..fd07fb5de3d 100644 --- a/src/locales/pt_BR/challenges.ts +++ b/src/locales/pt_BR/challenges.ts @@ -1,67 +1,25 @@ -import { SimpleTranslationEntries } from "#app/interfaces/locales"; +import { TranslationEntries } from "#app/interfaces/locales"; -export const challenges: SimpleTranslationEntries = { +export const challenges: TranslationEntries = { "title": "Desafios", - "start": "Iniciar", "illegalEvolution": "{{pokemon}} não pode ser escolhido\nnesse desafio!", - "singleGeneration.name": "Geração Única", - "singleGeneration.value.0": "Desligado", - "singleGeneration.desc.0": "Você só pode user Pokémon de uma única geração.", - "singleGeneration.value.1": "Geração 1", - "singleGeneration.desc.1": "Você só pode user Pokémon da primeira geração.", - "singleGeneration.value.2": "Geração 2", - "singleGeneration.desc.2": "Você só pode user Pokémon da segunda geração.", - "singleGeneration.value.3": "Geração 3", - "singleGeneration.desc.3": "Você só pode user Pokémon da terceira geração.", - "singleGeneration.value.4": "Geração 4", - "singleGeneration.desc.4": "Você só pode user Pokémon da quarta geração.", - "singleGeneration.value.5": "Geração 5", - "singleGeneration.desc.5": "Você só pode user Pokémon da quinta geração.", - "singleGeneration.value.6": "Geração 6", - "singleGeneration.desc.6": "Você só pode user Pokémon da sexta geração.", - "singleGeneration.value.7": "Geração 7", - "singleGeneration.desc.7": "Você só pode user Pokémon da sétima geração.", - "singleGeneration.value.8": "Geração 8", - "singleGeneration.desc.8": "Você só pode user Pokémon da oitava geração.", - "singleGeneration.value.9": "Geração 9", - "singleGeneration.desc.9": "Você só pode user Pokémon da nona geração.", - "singleType.name": "Tipo Único", - "singleType.value.0": "Desligado", - "singleType.desc.0": "Você só pode user Pokémon de um único tipo.", - "singleType.value.1": "Normal", - "singleType.desc.1": "Você só pode user Pokémon do tipo Normal.", - "singleType.value.2": "Lutador", - "singleType.desc.2": "Você só pode user Pokémon do tipo Lutador.", - "singleType.value.3": "Voador", - "singleType.desc.3": "Você só pode user Pokémon do tipo Voador.", - "singleType.value.4": "Veneno", - "singleType.desc.4": "Você só pode user Pokémon do tipo Veneno.", - "singleType.value.5": "Terra", - "singleType.desc.5": "Você só pode user Pokémon do tipo Terra.", - "singleType.value.6": "Pedra", - "singleType.desc.6": "Você só pode user Pokémon do tipo Pedra.", - "singleType.value.7": "Inseto", - "singleType.desc.7": "Você só pode user Pokémon do tipo Inseto.", - "singleType.value.8": "Fantasma", - "singleType.desc.8": "Você só pode user Pokémon do tipo Fantasma.", - "singleType.value.9": "Aço", - "singleType.desc.9": "Você só pode user Pokémon do tipo Aço.", - "singleType.value.10": "Fogo", - "singleType.desc.10": "Você só pode user Pokémon do tipo Fogo.", - "singleType.value.11": "Água", - "singleType.desc.11": "Você só pode user Pokémon do tipo Água.", - "singleType.value.12": "Grama", - "singleType.desc.12": "Você só pode user Pokémon do tipo Grama.", - "singleType.value.13": "Elétrico", - "singleType.desc.13": "Você só pode user Pokémon do tipo Elétrico.", - "singleType.value.14": "Psíquico", - "singleType.desc.14": "Você só pode user Pokémon do tipo Psíquico.", - "singleType.value.15": "Gelo", - "singleType.desc.15": "Você só pode user Pokémon do tipo Gelo.", - "singleType.value.16": "Dragão", - "singleType.desc.16": "Você só pode user Pokémon do tipo Dragão.", - "singleType.value.17": "Sombrio", - "singleType.desc.17": "Você só pode user Pokémon do tipo Sombrio.", - "singleType.value.18": "Fada", - "singleType.desc.18": "Você só pode user Pokémon do tipo Fada.", + "singleGeneration": { + "name": "Geração Única", + "desc": "Você só pode user Pokémon da {{gen}} geração.", + "desc_default": "Você só pode user Pokémon de uma única geração.", + "gen_1": "primeira", + "gen_2": "segunda", + "gen_3": "terceira", + "gen_4": "quarta", + "gen_5": "quinta", + "gen_6": "sexta", + "gen_7": "sétima", + "gen_8": "oitava", + "gen_9": "nona", + }, + "singleType": { + "name": "Tipo Único", + "desc": "Você só pode user Pokémon do tipo {{type}}.", + "desc_default": "Você só pode user Pokémon de um único tipo." + }, } as const; diff --git a/src/locales/pt_BR/common.ts b/src/locales/pt_BR/common.ts new file mode 100644 index 00000000000..d7cbfd5d052 --- /dev/null +++ b/src/locales/pt_BR/common.ts @@ -0,0 +1,5 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const common: SimpleTranslationEntries = { + "start": "Iniciar", +} as const; diff --git a/src/locales/pt_BR/config.ts b/src/locales/pt_BR/config.ts index 8d34c1539ef..ba658d43938 100644 --- a/src/locales/pt_BR/config.ts +++ b/src/locales/pt_BR/config.ts @@ -40,6 +40,7 @@ import { voucher } from "./voucher"; import { weather } from "./weather"; import { partyUiHandler } from "./party-ui-handler"; import { settings } from "#app/locales/pt_BR/settings.js"; +import { common } from "#app/locales/pt_BR/common.js"; export const ptBrConfig = { ability: ability, @@ -50,6 +51,7 @@ export const ptBrConfig = { biome: biome, challenges: challenges, commandUiHandler: commandUiHandler, + common: common, PGMachv: PGMachv, PGFachv: PGFachv, PGMdialogue: PGMdialogue, diff --git a/src/locales/pt_BR/menu.ts b/src/locales/pt_BR/menu.ts index 7490ea64ba8..2837ff55e26 100644 --- a/src/locales/pt_BR/menu.ts +++ b/src/locales/pt_BR/menu.ts @@ -52,5 +52,5 @@ export const menu: SimpleTranslationEntries = { "yes": "Sim", "no": "Não", "disclaimer": "AVISO", - "disclaimerDescription": "Este jogo é um produto inacabado; ele pode ter problemas de jogabilidade (incluindo possíveis perdas de dados salvos),\n sofrer alterações sem aviso prévio e pode ou não ser atualizado ou concluído.", + "disclaimerDescription": "Este jogo é um produto inacabado; ele pode ter problemas de jogabilidade (incluindo possíveis\n perdas de dados salvos), sofrer alterações sem aviso prévio e pode ou não ser atualizado ou concluído." } as const; diff --git a/src/locales/pt_BR/settings.ts b/src/locales/pt_BR/settings.ts index 873d4ffd4a8..f094e64d495 100644 --- a/src/locales/pt_BR/settings.ts +++ b/src/locales/pt_BR/settings.ts @@ -3,96 +3,96 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales.js"; export const settings: SimpleTranslationEntries = { "boy": "Menino", "girl": "Menina", - "general": "General", - "display": "Display", - "audio": "Audio", - "gamepad": "Gamepad", - "keyboard": "Keyboard", - "gameSpeed": "Game Speed", - "hpBarSpeed": "HP Bar Speed", - "expGainsSpeed": "EXP Gains Speed", - "expPartyDisplay": "Show EXP Party", - "skipSeenDialogues": "Skip Seen Dialogues", - "battleStyle": "Battle Style", - "enableRetries": "Enable Retries", - "tutorials": "Tutorials", - "touchControls": "Touch Controls", - "vibrations": "Vibrations", + "general": "Geral", + "display": "Exibição", + "audio": "Áudio", + "gamepad": "Controle", + "keyboard": "Teclado", + "gameSpeed": "Velocidade do Jogo", + "hpBarSpeed": "Velocidade da Barra de PS", + "expGainsSpeed": "Velocidade do Ganho de EXP", + "expPartyDisplay": "Exibição de EXP da Equipe", + "skipSeenDialogues": "Pular Diálogos Vistos", + "battleStyle": "Estilo de Batalha", + "enableRetries": "Habilitar Novas Tentativas", + "tutorials": "Tutorial", + "touchControls": "Controles de Toque", + "vibrations": "Vibração", "normal": "Normal", - "fast": "Fast", - "faster": "Faster", - "skip": "Skip", - "levelUpNotifications": "Level Up Notifications", - "on": "On", - "off": "Off", - "switch": "Switch", - "set": "Set", - "auto": "Auto", - "disabled": "Disabled", - "language": "Language", - "change": "Change", - "uiTheme": "UI Theme", - "default": "Default", - "legacy": "Legacy", - "windowType": "Window Type", - "moneyFormat": "Money Format", - "damageNumbers": "Damage Numbers", - "simple": "Simple", - "fancy": "Fancy", - "abbreviated": "Abbreviated", - "moveAnimations": "Move Animations", - "showStatsOnLevelUp": "Show Stats on Level Up", - "candyUpgradeNotification": "Candy Upgrade Notification", - "passivesOnly": "Passives Only", - "candyUpgradeDisplay": "Candy Upgrade Display", - "icon": "Icon", - "animation": "Animation", - "moveInfo": "Move Info", - "showMovesetFlyout": "Show Moveset Flyout", - "showArenaFlyout": "Show Arena Flyout", - "showTimeOfDayWidget": "Show Time of Day Widget", - "timeOfDayAnimation": "Time of Day Animation", - "bounce": "Bounce", - "timeOfDay_back": "Back", - "spriteSet": "Sprite Set", - "consistent": "Consistent", - "mixedAnimated": "Mixed Animated", - "fusionPaletteSwaps": "Fusion Palette Swaps", - "playerGender": "Player Gender", - "typeHints": "Type Hints", - "masterVolume": "Master Volume", - "bgmVolume": "BGM Volume", - "seVolume": "SE Volume", - "musicPreference": "Music Preference", - "mixed": "Mixed", - "gamepadPleasePlug": "Please Plug in a Gamepad or Press a Button", - "delete": "Delete", - "keyboardPleasePress": "Please Press a Key on Your Keyboard", - "reset": "Reset", - "requireReload": "Reload Required", - "action": "Action", - "back": "Back", - "pressToBind": "Press to Bind", - "pressButton": "Press a Button...", - "buttonUp": "Up", - "buttonDown": "Down", - "buttonLeft": "Left", - "buttonRight": "Right", - "buttonAction": "Action", + "fast": "Rápido", + "faster": "Mais Rápido", + "skip": "Pular", + "levelUpNotifications": "Notificação", + "on": "Ligado", + "off": "Desligado", + "switch": "Alternar", + "set": "Definido", + "auto": "Automático", + "disabled": "Desativado", + "language": "Idioma", + "change": "Mudar", + "uiTheme": "Tema da Interface", + "default": "Padrão", + "legacy": "Legado", + "windowType": "Estilo da Janela", + "moneyFormat": "Formatação do Dinheiro", + "damageNumbers": "Números de Dano", + "simple": "Simples", + "fancy": "Detalhado", + "abbreviated": "Abreviado", + "moveAnimations": "Animações de Movimento", + "showStatsOnLevelUp": "Mostrar Atributos ao Subir de Nível", + "candyUpgradeNotification": "Exibir Melhorias com Doce", + "passivesOnly": "Passivas", + "candyUpgradeDisplay": "Modo Melhorias com Doce", + "icon": "Ícone", + "animation": "Animação", + "moveInfo": "Informações de Movimento", + "showMovesetFlyout": "Mostrar Flutuante de Movimentos", + "showArenaFlyout": "Mostrar Flutuante de Bioma", + "showTimeOfDayWidget": "Widget da Hora do Dia", + "timeOfDayAnimation": "Animação da Hora do Dia", + "bounce": "Saltar", + "timeOfDay_back": "Voltar", + "spriteSet": "Conjunto de Sprites", + "consistent": "Consistente", + "mixedAnimated": "Animado", + "fusionPaletteSwaps": "Cores da Paleta de Fusão", + "playerGender": "Gênero do Jogador", + "typeHints": "Dicas de Tipo", + "masterVolume": "Volume Mestre", + "bgmVolume": "Volume de BGM", + "seVolume": "Volume de SE", + "musicPreference": "Preferência de Música", + "mixed": "Misto", + "gamepadPleasePlug": "Conecte um controle ou pressione um botão", + "delete": "Deletar", + "keyboardPleasePress": "Pressione uma tecla", + "reset": "Redefinir", + "requireReload": "Requer Reinício", + "action": "Ação", + "back": "Voltar", + "pressToBind": "Pressione para Atribuir", + "pressButton": "Pressione um Botão...", + "buttonUp": "Cima", + "buttonDown": "Baixo", + "buttonLeft": "Esquerda", + "buttonRight": "Direita", + "buttonAction": "Ação", "buttonMenu": "Menu", - "buttonSubmit": "Submit", - "buttonCancel": "Cancel", - "buttonStats": "Stats", - "buttonCycleForm": "Cycle Form", - "buttonCycleShiny": "Cycle Shiny", - "buttonCycleGender": "Cycle Gender", - "buttonCycleAbility": "Cycle Ability", - "buttonCycleNature": "Cycle Nature", - "buttonCycleVariant": "Cycle Variant", - "buttonSpeedUp": "Speed Up", - "buttonSlowDown": "Slow Down", + "buttonSubmit": "Confirmar", + "buttonCancel": "Cancelar", + "buttonStats": "Atributos", + "buttonCycleForm": "Próxima Forma", + "buttonCycleShiny": "Próximo Shiny", + "buttonCycleGender": "Próximo Gênero", + "buttonCycleAbility": "Próxima Habilidade", + "buttonCycleNature": "Próxima Natureza", + "buttonCycleVariant": "Próxima Variante", + "buttonSpeedUp": "Acelerar", + "buttonSlowDown": "Desacelerar", "alt": " (Alt)", - "mute": "Mute", - "controller": "Controller", - "gamepadSupport": "Gamepad Support" + "mute": "Mudo", + "controller": "Controle", + "gamepadSupport": "Suporte para Controle" } as const; diff --git a/src/locales/pt_BR/starter-select-ui-handler.ts b/src/locales/pt_BR/starter-select-ui-handler.ts index 64a2ceff7c3..0b349468aee 100644 --- a/src/locales/pt_BR/starter-select-ui-handler.ts +++ b/src/locales/pt_BR/starter-select-ui-handler.ts @@ -21,7 +21,6 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "passive": "Passiva:", "nature": "Natureza:", "eggMoves": "Mov. de Ovo", - "start": "Iniciar", "addToParty": "Adicionar à equipe", "toggleIVs": "Mostrar IVs", "manageMoves": "Mudar Movimentos", diff --git a/src/locales/zh_CN/battle.ts b/src/locales/zh_CN/battle.ts index 4b2b881f6b2..09bcb5b1c3d 100644 --- a/src/locales/zh_CN/battle.ts +++ b/src/locales/zh_CN/battle.ts @@ -71,4 +71,61 @@ export const battle: SimpleTranslationEntries = { "statSeverelyFell": "极大幅降低了!", "statWontGoAnyLower": "已经无法再降低了!", "ppReduced": "降低了 {{targetName}} 的\n{{moveName}} 的PP{{reduction}}点!", + "battlerTagsRechargingLapse": "{{pokemonNameWithAffix}} 因为技能\n无法动弹!", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}} 不能逃跑!", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}} 摆脱了\n {{moveName}}", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}} 畏缩了!", + "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}} 混乱了!", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}} 的混乱\n解除了!", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}} 已经\n混乱了。", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}} 正在\n混乱中!", + "battlerTagsConfusedLapseHurtItself": "不知所以地\n攻击了自己!", + "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}} 不再受到\n同命的影响", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}} 和\n{{pokemonNameWithAffix2}} 同归于尽了!", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}} 对\n {{sourcePokemonName}}着迷了!", + "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}} 已经\n着迷了!", + "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}} 对\n{{sourcePokemonName}}着迷中!", + "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}} 不会着迷!", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}} 治愈了\n着迷状态!", + "battlerTagsSeededOnAdd": "将种子种植在了\n{{pokemonNameWithAffix}} 身上!", + "battlerTagsSeededLapse": "{{pokemonNameWithAffix}}用寄生种子\n回复了体力!", + "battlerTagsSeededLapseShed": "{{pokemonNameWithAffix}}的寄生种子\n被乌泥浆吸干了!", + "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}} 被恶梦缠身!", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}} 已经被恶梦缠身!", + "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}} 正被恶梦缠身!", + "battlerTagsEncoreOnAdd": "({{pokemonNameWithAffix}} 接受了再来一次!", + "battlerTagsEncoreOnRemove": "{{pokemonNameWithAffix}} 的再来一次\n状态解除了!", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}} 摆出了帮助\n {{pokemonName}} 的架势!", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}} 用扎根回复了体力!", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}} 扎根了!", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}} 用水流环\n包裹了自己!", + "battlerTagsAquaRingLapse": "{{moveName}} 回复了\n{{pokemonName}}的体力!", + "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}} 产生睡意了!", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}} 受到了\n {{moveName}}的伤害!", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}} 被\n{{sourcePokemonName}}的 {{moveName}}紧紧束缚住了!", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}} 被\n{{sourcePokemonName}}绑紧了!", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}} 被困在了\n旋涡之中!", + "battlerTagsClampOnTrap": "{{sourcePokemonNameWithAffix}} 用贝壳夹住了\n{{pokemonName}}!", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}} 被\nby {{moveName}}困住了!", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}} 被困在了\n熔岩旋涡之中!", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}} 被捕兽夹\n困住了!", + "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}} 困住了\n{{pokemonNameWithAffix}}!", + "battlerTagsInfestationOnTrap": "{{pokemonNameWithAffix}} 受到了 \n{{sourcePokemonNameWithAffix}} 的死缠烂打!", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}\n摆出了防守的架势!", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}\n在攻击中\n保护了自己!", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}} 摆出了\n挺住攻击的架势!", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}} 挺住了攻击!", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}} 挺住了攻击!", + "battlerTagsPerishSongLapse": "{{pokemonNameWithAffix}} 的\n灭亡计时变成 {{turnCount}} 了!", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}} 正在偷懒!", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}}\n无法拿出平时的水平!", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}}\n恢复了平时的水平!", + "battlerTagsHighestStatBoostOnAdd": "{{pokemonNameWithAffix}} 的 {{statName}}\n升高了!", + "battlerTagsHighestStatBoostOnRemove": " {{pokemonNameWithAffix}} 的\n{{abilityName}}效果解除了!", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}} \n现在干劲十足!", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}} \n如释重负似地放松了下来。", + "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}} 陷入了盐腌状态!", + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} 受到了 {{moveName}} 的伤害!", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} 削减了自己的体力,\n并诅咒了 {{pokemonName}}!", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} 正受到诅咒!" } as const; diff --git a/src/locales/zh_CN/challenges.ts b/src/locales/zh_CN/challenges.ts index 697a97bda09..d15a725fbb0 100644 --- a/src/locales/zh_CN/challenges.ts +++ b/src/locales/zh_CN/challenges.ts @@ -1,67 +1,25 @@ -import { SimpleTranslationEntries } from "#app/interfaces/locales"; +import { TranslationEntries } from "#app/interfaces/locales"; -export const challenges: SimpleTranslationEntries = { +export const challenges: TranslationEntries = { "title": "适用挑战条件", - "points": "Bad Ideas", - "confirm_start": "要执行这些挑战吗?", - "singleGeneration.name": "单一世代", - "singleGeneration.value.0": "关闭", - "singleGeneration.desc.0": "你只能使用所选世代的宝可梦", - "singleGeneration.value.1": "第一世代", - "singleGeneration.desc.1": "你只能使用第一世代的宝可梦", - "singleGeneration.value.2": "第二世代", - "singleGeneration.desc.2": "你只能使用第二世代的宝可梦", - "singleGeneration.value.3": "第三世代", - "singleGeneration.desc.3": "你只能使用第三世代的宝可梦", - "singleGeneration.value.4": "第四世代", - "singleGeneration.desc.4": "你只能使用第四世代的宝可梦", - "singleGeneration.value.5": "第五世代", - "singleGeneration.desc.5": "你只能使用第五世代的宝可梦", - "singleGeneration.value.6": "第六世代", - "singleGeneration.desc.6": "你只能使用第六世代的宝可梦", - "singleGeneration.value.7": "第七世代", - "singleGeneration.desc.7": "你只能使用第七世代的宝可梦", - "singleGeneration.value.8": "第八世代", - "singleGeneration.desc.8": "你只能使用第八世代的宝可梦", - "singleGeneration.value.9": "第九世代", - "singleGeneration.desc.9": "你只能使用第九世代的宝可梦", - "singleType.name": "单属性", - "singleType.value.0": "关闭", - "singleType.desc.0": "你只能使用所选属性的宝可梦", - "singleType.value.1": "普通", - "singleType.desc.1": "你只能使用普通属性的宝可梦", - "singleType.value.2": "格斗", - "singleType.desc.2": "你只能使用格斗属性的宝可梦", - "singleType.value.3": "飞行", - "singleType.desc.3": "你只能使用飞行属性的宝可梦", - "singleType.value.4": "毒", - "singleType.desc.4": "你只能使用毒属性的宝可梦", - "singleType.value.5": "地面", - "singleType.desc.5": "你只能使用地面属性的宝可梦", - "singleType.value.6": "岩石", - "singleType.desc.6": "你只能使用岩石属性的宝可梦", - "singleType.value.7": "虫", - "singleType.desc.7": "你只能使用虫属性的宝可梦", - "singleType.value.8": "幽灵", - "singleType.desc.8": "你只能使用幽灵属性的宝可梦", - "singleType.value.9": "钢", - "singleType.desc.9": "你只能使用钢属性的宝可梦", - "singleType.value.10": "火", - "singleType.desc.10": "你只能使用火属性的宝可梦", - "singleType.value.11": "水", - "singleType.desc.11": "你只能使用水属性的宝可梦", - "singleType.value.12": "草", - "singleType.desc.12": "你只能使用草属性的宝可梦", - "singleType.value.13": "电", - "singleType.desc.13": "你只能使用电属性的宝可梦", - "singleType.value.14": "超能", - "singleType.desc.14": "你只能使用超能属性的宝可梦", - "singleType.value.15": "冰", - "singleType.desc.15": "你只能使用冰属性的宝可梦", - "singleType.value.16": "龙", - "singleType.desc.16": "你只能使用龙属性的宝可梦", - "singleType.value.17": "恶", - "singleType.desc.17": "你只能使用恶属性的宝可梦", - "singleType.value.18": "妖精", - "singleType.desc.18": "你只能使用妖精属性的宝可梦", + "illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", + "singleGeneration": { + "name": "单一世代", + "desc": "你只能使用第{{gen}}世代的宝可梦", + "desc_default": "你只能使用所选世代的宝可梦", + "gen_1": "一", + "gen_2": "二", + "gen_3": "三", + "gen_4": "四", + "gen_5": "五", + "gen_6": "六", + "gen_7": "七", + "gen_8": "八", + "gen_9": "九", + }, + "singleType": { + "name": "单属性", + "desc": "你只能使用{{type}}属性的宝可梦", + "desc_default": "你只能使用所选属性的宝可梦" + }, } as const; diff --git a/src/locales/zh_CN/common.ts b/src/locales/zh_CN/common.ts new file mode 100644 index 00000000000..29f54ff0dc9 --- /dev/null +++ b/src/locales/zh_CN/common.ts @@ -0,0 +1,5 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const common: SimpleTranslationEntries = { + "start": "开始", +} as const; diff --git a/src/locales/zh_CN/config.ts b/src/locales/zh_CN/config.ts index fdc54cb2be0..ecef682581f 100644 --- a/src/locales/zh_CN/config.ts +++ b/src/locales/zh_CN/config.ts @@ -40,6 +40,7 @@ import { voucher } from "./voucher"; import { weather } from "./weather"; import { partyUiHandler } from "./party-ui-handler"; import { settings } from "#app/locales/zh_CN/settings.js"; +import { common } from "#app/locales/zh_CN/common.js"; export const zhCnConfig = { ability: ability, @@ -50,6 +51,7 @@ export const zhCnConfig = { biome: biome, challenges: challenges, commandUiHandler: commandUiHandler, + common: common, PGMachv: PGMachv, PGFachv: PGFachv, PGMdialogue: PGMdialogue, diff --git a/src/locales/zh_CN/settings.ts b/src/locales/zh_CN/settings.ts index 04df61d7dbe..f37a59613f5 100644 --- a/src/locales/zh_CN/settings.ts +++ b/src/locales/zh_CN/settings.ts @@ -52,8 +52,8 @@ export const settings: SimpleTranslationEntries = { "showArenaFlyout": "显示战场弹窗", "showTimeOfDayWidget": "显示时间指示器", "timeOfDayAnimation": "时间指示器动画", - "bounce": "彈一下", - "timeOfDay_back": "不彈", + "bounce": "弹跳", + "timeOfDay_back": "不弹", "spriteSet": "宝可梦动画", "consistent": "默认", "mixedAnimated": "全部动画", diff --git a/src/locales/zh_CN/starter-select-ui-handler.ts b/src/locales/zh_CN/starter-select-ui-handler.ts index 669b8a5bb80..05824853e40 100644 --- a/src/locales/zh_CN/starter-select-ui-handler.ts +++ b/src/locales/zh_CN/starter-select-ui-handler.ts @@ -21,7 +21,6 @@ export const starterSelectUiHandler: SimpleTranslationEntries = { "passive": "被动:", "nature": "性格:", "eggMoves": "蛋招式", - "start": "开始", "addToParty": "加入队伍", "toggleIVs": "切换个体值", "manageMoves": "管理招式", diff --git a/src/locales/zh_TW/battle.ts b/src/locales/zh_TW/battle.ts index f8179c50887..b4d0aa9d50e 100644 --- a/src/locales/zh_TW/battle.ts +++ b/src/locales/zh_TW/battle.ts @@ -68,4 +68,61 @@ export const battle: SimpleTranslationEntries = { "statSeverelyFell": "severely fell", "statWontGoAnyLower": "won't go any lower", "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", + "battlerTagsRechargingLapse": "{{pokemonNameWithAffix}} must\nrecharge!", + "battlerTagsTrappedOnAdd": "{{pokemonNameWithAffix}} can no\nlonger escape!", + "battlerTagsTrappedOnRemove": "{{pokemonNameWithAffix}} was freed\nfrom {{moveName}}", + "battlerTagsFlinchedLapse": "{{pokemonNameWithAffix}} flinched!", + "battlerTagsConfusedOnAdd": "{{pokemonNameWithAffix}} became\nconfused!", + "battlerTagsConfusedOnRemove": "{{pokemonNameWithAffix}} snapped\nout of confusion!", + "battlerTagsConfusedOnOverlap": "{{pokemonNameWithAffix}} is\nalready confused!", + "battlerTagsConfusedLapse": "{{pokemonNameWithAffix}} is\nconfused!", + "battlerTagsConfusedLapseHurtItself": "It hurt itself in its\nconfusion!", + "battlerTagsDestinyBondLapseIsBoss": "{{pokemonNameWithAffix}} is unaffected\nby the effects of Destiny Bond.", + "battlerTagsDestinyBondLapse": "{{pokemonNameWithAffix}} took\n{{pokemonNameWithAffix2}} down with it!", + "battlerTagsInfatuatedOnAdd": "{{pokemonNameWithAffix}} fell in love\nwith {{sourcePokemonName}}!", + "battlerTagsInfatuatedOnOverlap": "{{pokemonNameWithAffix}} is\nalready in love!", + "battlerTagsInfatuatedLapse": "{{pokemonNameWithAffix}} is in love\nwith {{sourcePokemonName}}!", + "battlerTagsInfatuatedLapseImmobilize": "{{pokemonNameWithAffix}} is\nimmobilized by love!", + "battlerTagsInfatuatedOnRemove": "{{pokemonNameWithAffix}} got over\nits infatuation.", + "battlerTagsSeededOnAdd": "{{pokemonNameWithAffix}} was seeded!", + "battlerTagsSeededLapse": "{{pokemonNameWithAffix}}'s health is\nsapped by Leech Seed!", + "battlerTagsSeededLapseShed": "{{pokemonNameWithAffix}}'s Leech Seed\nsucked up the liquid ooze!", + "battlerTagsNightmareOnAdd": "{{pokemonNameWithAffix}} began\nhaving a Nightmare!", + "battlerTagsNightmareOnOverlap": "{{pokemonNameWithAffix}} is\nalready locked in a Nightmare!", + "battlerTagsNightmareLapse": "{{pokemonNameWithAffix}} is locked\nin a Nightmare!", + "battlerTagsEncoreOnAdd": "({{pokemonNameWithAffix}} got\nan Encore!", + "battlerTagsEncoreOnRemove": "{{pokemonNameWithAffix}}'s Encore\nended!", + "battlerTagsHelpingHandOnAdd": "{{pokemonNameWithAffix}} is ready to\nhelp {{pokemonName}}!", + "battlerTagsIngrainLapse": "{{pokemonNameWithAffix}} absorbed\nnutrients with its roots!", + "battlerTagsIngrainOnTrap": "{{pokemonNameWithAffix}} planted its roots!", + "battlerTagsAquaRingOnAdd": "{{pokemonNameWithAffix}} surrounded\nitself with a veil of water!", + "battlerTagsAquaRingLapse": "{{moveName}} restored\n{{pokemonName}}'s HP!", + "battlerTagsDrowsyOnAdd": "{{pokemonNameWithAffix}} grew drowsy!", + "battlerTagsDamagingTrapLapse": "{{pokemonNameWithAffix}} is hurt\nby {{moveName}}!", + "battlerTagsBindOnTrap": "{{pokemonNameWithAffix}} was squeezed by\n{{sourcePokemonName}}'s {{moveName}}!", + "battlerTagsWrapOnTrap": "{{pokemonNameWithAffix}} was Wrapped\nby {{sourcePokemonName}}!", + "battlerTagsVortexOnTrap": "{{pokemonNameWithAffix}} was trapped\nin the vortex!", + "battlerTagsClampOnTrap": "{{sourcePokemonNameWithAffix}} Clamped\n{{pokemonName}}!", + "battlerTagsSandTombOnTrap": "{{pokemonNameWithAffix}} became trapped\nby {{moveName}}!", + "battlerTagsMagmaStormOnTrap": "{{pokemonNameWithAffix}} became trapped\nby swirling magma!", + "battlerTagsSnapTrapOnTrap": "{{pokemonNameWithAffix}} got trapped\nby a snap trap!", + "battlerTagsThunderCageOnTrap": "{{sourcePokemonNameWithAffix}} trapped\n{{pokemonNameWithAffix}}!", + "battlerTagsInfestationOnTrap": "{{pokemonNameWithAffix}} has been afflicted \nwith an infestation by {{sourcePokemonNameWithAffix}}!", + "battlerTagsProtectedOnAdd": "{{pokemonNameWithAffix}}\nprotected itself!", + "battlerTagsProtectedLapse": "{{pokemonNameWithAffix}}\nprotected itself!", + "battlerTagsEnduringOnAdd": "{{pokemonNameWithAffix}} braced\nitself!", + "battlerTagsEnduringLapse": "{{pokemonNameWithAffix}} endured\nthe hit!", + "battlerTagsSturdyLapse": "{{pokemonNameWithAffix}} endured\nthe hit!", + "battlerTagsPerishSongLapse": "{{pokemonNameWithAffix}}'s perish count fell to {{turnCount}}.", + "battlerTagsTruantLapse": "{{pokemonNameWithAffix}} is\nloafing around!", + "battlerTagsSlowStartOnAdd": "{{pokemonNameWithAffix}} can't\nget it going!", + "battlerTagsSlowStartOnRemove": "{{pokemonNameWithAffix}} finally\ngot its act together!", + "battlerTagsHighestStatBoostOnAdd": "{{pokemonNameWithAffix}}'s {{statName}}\nwas heightened!", + "battlerTagsHighestStatBoostOnRemove": "The effects of {{pokemonNameWithAffix}}'s\n{{abilityName}} wore off!", + "battlerTagsCritBoostOnAdd": "{{pokemonNameWithAffix}} is getting\npumped!", + "battlerTagsCritBoostOnRemove": "{{pokemonNameWithAffix}} relaxed.", + "battlerTagsSaltCuredOnAdd": "{{pokemonNameWithAffix}} is being salt cured!", + "battlerTagsSaltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!", + "battlerTagsCursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!", + "battlerTagsCursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!" } as const; diff --git a/src/locales/zh_TW/challenges.ts b/src/locales/zh_TW/challenges.ts index 9da058001b1..6b46ac8c7ab 100644 --- a/src/locales/zh_TW/challenges.ts +++ b/src/locales/zh_TW/challenges.ts @@ -1,67 +1,25 @@ -import { SimpleTranslationEntries } from "#app/interfaces/locales"; +import { TranslationEntries } from "#app/interfaces/locales"; -export const challenges: SimpleTranslationEntries = { +export const challenges: TranslationEntries = { "title": "適用挑戰條件", - "points": "Bad Ideas", - "confirm_start": "要執行這些挑戰嗎?", - "singleGeneration.name": "單一世代", - "singleGeneration.value.0": "關閉", - "singleGeneration.desc.0": "你只能使用所選世代的寶可夢", - "singleGeneration.value.1": "第一世代", - "singleGeneration.desc.1": "你只能使用第一世代的寶可夢", - "singleGeneration.value.2": "第二世代", - "singleGeneration.desc.2": "你只能使用第二世代的寶可夢", - "singleGeneration.value.3": "第三世代", - "singleGeneration.desc.3": "你只能使用第三世代的寶可夢", - "singleGeneration.value.4": "第四世代", - "singleGeneration.desc.4": "你只能使用第四世代的寶可夢", - "singleGeneration.value.5": "第五世代", - "singleGeneration.desc.5": "你只能使用第五世代的寶可夢", - "singleGeneration.value.6": "第六世代", - "singleGeneration.desc.6": "你只能使用第六世代的寶可夢", - "singleGeneration.value.7": "第七世代", - "singleGeneration.desc.7": "你只能使用第七世代的寶可夢", - "singleGeneration.value.8": "第八世代", - "singleGeneration.desc.8": "你只能使用第八世代的寶可夢", - "singleGeneration.value.9": "第九世代", - "singleGeneration.desc.9": "你只能使用第九世代的寶可夢", - "singleType.name": "單屬性", - "singleType.value.0": "關閉", - "singleType.desc.0": "你只能使用所選屬性的寶可夢", - "singleType.value.1": "普通", - "singleType.desc.1": "你只能使用普通屬性的寶可夢", - "singleType.value.2": "格鬥", - "singleType.desc.2": "你只能使用格鬥屬性的寶可夢", - "singleType.value.3": "飛行", - "singleType.desc.3": "你只能使用飛行屬性的寶可夢", - "singleType.value.4": "毒", - "singleType.desc.4": "你只能使用毒屬性的寶可夢", - "singleType.value.5": "地面", - "singleType.desc.5": "你只能使用地面屬性的寶可夢", - "singleType.value.6": "岩石", - "singleType.desc.6": "你只能使用岩石屬性的寶可夢", - "singleType.value.7": "蟲", - "singleType.desc.7": "你只能使用蟲屬性的寶可夢", - "singleType.value.8": "幽靈", - "singleType.desc.8": "你只能使用幽靈屬性的寶可夢", - "singleType.value.9": "鋼", - "singleType.desc.9": "你只能使用鋼屬性的寶可夢", - "singleType.value.10": "火", - "singleType.desc.10": "你只能使用火屬性的寶可夢", - "singleType.value.11": "水", - "singleType.desc.11": "你只能使用水屬性的寶可夢", - "singleType.value.12": "草", - "singleType.desc.12": "你只能使用草屬性的寶可夢", - "singleType.value.13": "電", - "singleType.desc.13": "你只能使用電屬性的寶可夢", - "singleType.value.14": "超能", - "singleType.desc.14": "你只能使用超能屬性的寶可夢", - "singleType.value.15": "冰", - "singleType.desc.15": "你只能使用冰屬性的寶可夢", - "singleType.value.16": "龍", - "singleType.desc.16": "你只能使用龍屬性的寶可夢", - "singleType.value.17": "惡", - "singleType.desc.17": "你只能使用惡屬性的寶可夢", - "singleType.value.18": "妖精", - "singleType.desc.18": "你只能使用妖精屬性的寶可夢", + "illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", + "singleGeneration": { + "name": "單一世代", + "desc": "你只能使用第{{gen}}世代的寶可夢", + "desc_default": "你只能使用所選世代的寶可夢", + "gen_1": "一", + "gen_2": "二", + "gen_3": "三", + "gen_4": "四", + "gen_5": "五", + "gen_6": "六", + "gen_7": "七", + "gen_8": "八", + "gen_9": "九", + }, + "singleType": { + "name": "單屬性", + "desc": "你只能使用{{type}}屬性的寶可夢", + "desc_default": "你只能使用所選屬性的寶可夢" + }, } as const; diff --git a/src/locales/zh_TW/common.ts b/src/locales/zh_TW/common.ts new file mode 100644 index 00000000000..c3dc42785ee --- /dev/null +++ b/src/locales/zh_TW/common.ts @@ -0,0 +1,5 @@ +import { SimpleTranslationEntries } from "#app/interfaces/locales"; + +export const common: SimpleTranslationEntries = { + "start": "開始", +} as const; diff --git a/src/locales/zh_TW/config.ts b/src/locales/zh_TW/config.ts index 5d6a2dd978d..08063f9f154 100644 --- a/src/locales/zh_TW/config.ts +++ b/src/locales/zh_TW/config.ts @@ -40,6 +40,7 @@ import { voucher } from "./voucher"; import { weather } from "./weather"; import { partyUiHandler } from "./party-ui-handler"; import { settings } from "#app/locales/zh_TW/settings.js"; +import { common } from "#app/locales/zh_TW/common.js"; export const zhTwConfig = { ability: ability, @@ -50,6 +51,7 @@ export const zhTwConfig = { biome: biome, challenges: challenges, commandUiHandler: commandUiHandler, + common: common, PGMachv: PGMachv, PGFachv: PGFachv, PGMdialogue: PGMdialogue, diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 181cf6744c0..626d744eef2 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -525,6 +525,10 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { //Applies to items with chance of activating secondary effects ie Kings Rock getSecondaryChanceMultiplier(pokemon: Pokemon): integer { + // Temporary quickfix to stop game from freezing when the opponet uses u-turn while holding on to king's rock + if (!pokemon.getLastXMoves(0)[0]) { + return 1; + } const sheerForceAffected = allMoves[pokemon.getLastXMoves(0)[0].move].chance >= 0 && pokemon.hasAbility(Abilities.SHEER_FORCE); if (sheerForceAffected) { diff --git a/src/scene-base.ts b/src/scene-base.ts index 48b7238387c..1d7a2518300 100644 --- a/src/scene-base.ts +++ b/src/scene-base.ts @@ -1,6 +1,19 @@ export const legacyCompatibleImages: string[] = []; export class SceneBase extends Phaser.Scene { + /** + * Since everything is scaled up by 6 by default using the game.canvas is annoying + * Until such point that we use the canvas normally, this will be easier than + * having to divide every width and heigh by 6 to position and scale the ui + * @readonly + * @defaultValue + * width: `320` + * height: `180` + */ + public readonly scaledCanvas = { + width: 1920 / 6, + height: 1080 / 6 + }; constructor(config?: string | Phaser.Types.Scenes.SettingsConfig) { super(config); } diff --git a/src/test/abilities/ice_face.test.ts b/src/test/abilities/ice_face.test.ts index 759b036770a..09fd8733f93 100644 --- a/src/test/abilities/ice_face.test.ts +++ b/src/test/abilities/ice_face.test.ts @@ -4,6 +4,7 @@ import GameManager from "#app/test/utils/gameManager"; import * as overrides from "#app/overrides"; import { Species } from "#enums/species"; import { + MoveEffectPhase, MoveEndPhase, TurnEndPhase, TurnInitPhase, @@ -52,6 +53,34 @@ describe("Abilities - Ice Face", () => { expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBe(undefined); }); + it("takes no damage from the first hit of multihit physical move and transforms to Noice", async () => { + vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SURGING_STRIKES]); + vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(5); + await game.startBattle([Species.HITMONLEE]); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SURGING_STRIKES)); + + const eiscue = game.scene.getEnemyPokemon(); + expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBeDefined(); + + // First hit + await game.phaseInterceptor.to(MoveEffectPhase); + expect(eiscue.hp).equals(eiscue.getMaxHp()); + expect(eiscue.formIndex).toBe(icefaceForm); + expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBeUndefined(); + + // Second hit + await game.phaseInterceptor.to(MoveEffectPhase); + expect(eiscue.hp).lessThan(eiscue.getMaxHp()); + expect(eiscue.formIndex).toBe(noiceForm); + + await game.phaseInterceptor.to(MoveEndPhase); + + expect(eiscue.hp).lessThan(eiscue.getMaxHp()); + expect(eiscue.formIndex).toBe(noiceForm); + expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBeUndefined(); + }); + it("takes damage from special moves", async () => { await game.startBattle([Species.MAGIKARP]); diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index 18ff40aec50..f81f24af9bb 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -18,7 +18,7 @@ const timedEvents: TimedEvent[] = [ eventType: EventType.SHINY, shinyMultiplier: 2, startDate: new Date(Date.UTC(2024, 5, 14, 0)), - endDate: new Date(Date.UTC(2024, 5, 21, 0)), + endDate: new Date(Date.UTC(2024, 5, 22, 0)), bannerFilename: "pride-update" }, ]; diff --git a/src/ui-inputs.ts b/src/ui-inputs.ts index 33752a7ff5d..9288fd35892 100644 --- a/src/ui-inputs.ts +++ b/src/ui-inputs.ts @@ -190,12 +190,12 @@ export class UiInputs { buttonSpeedChange(up = true): void { const settingGameSpeed = settingIndex(SettingKeys.Game_Speed); if (up && this.scene.gameSpeed < 5) { - this.scene.gameData.saveSetting(SettingKeys.Game_Speed, Setting[settingGameSpeed].options.findIndex((item) => item.value === `${this.scene.gameSpeed}x`) + 1); + this.scene.gameData.saveSetting(SettingKeys.Game_Speed, Setting[settingGameSpeed].options.findIndex((item) => item.label === `${this.scene.gameSpeed}x`) + 1); if (this.scene.ui?.getMode() === Mode.SETTINGS) { (this.scene.ui.getHandler() as SettingsUiHandler).show([]); } } else if (!up && this.scene.gameSpeed > 1) { - this.scene.gameData.saveSetting(SettingKeys.Game_Speed, Math.max(Setting[settingGameSpeed].options.findIndex((item) => item.value === `${this.scene.gameSpeed}x`) - 1, 0)); + this.scene.gameData.saveSetting(SettingKeys.Game_Speed, Math.max(Setting[settingGameSpeed].options.findIndex((item) => item.label === `${this.scene.gameSpeed}x`) - 1, 0)); if (this.scene.ui?.getMode() === Mode.SETTINGS) { (this.scene.ui.getHandler() as SettingsUiHandler).show([]); } diff --git a/src/ui/arena-flyout.ts b/src/ui/arena-flyout.ts index 0568d1524aa..963b1ac4eb1 100644 --- a/src/ui/arena-flyout.ts +++ b/src/ui/arena-flyout.ts @@ -1,6 +1,6 @@ import { addTextObject, TextStyle } from "./text"; import BattleScene from "#app/battle-scene.js"; -import { ArenaTagSide } from "#app/data/arena-tag.js"; +import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag.js"; import { WeatherType } from "#app/data/weather.js"; import { TerrainType } from "#app/data/terrain.js"; import { addWindow, WindowVariant } from "./ui-theme"; @@ -23,12 +23,14 @@ interface ArenaEffectInfo { /** The enum string representation of the effect */ name: string; /** {@linkcode ArenaEffectType} type of effect */ - type: ArenaEffectType, + effecType: ArenaEffectType, /** The maximum duration set by the effect */ maxDuration: number; /** The current duration left on the effect */ duration: number; + /** The arena tag type being added */ + tagType?: ArenaTagType; } export default class ArenaFlyout extends Phaser.GameObjects.Container { @@ -213,7 +215,7 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { // Creates a proxy object to decide which text object needs to be updated let textObject: Phaser.GameObjects.Text; - switch (fieldEffectInfo.type) { + switch (fieldEffectInfo.effecType) { case ArenaEffectType.PLAYER: textObject = this.flyoutTextPlayer; break; @@ -231,7 +233,7 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { } textObject.text += this.formatText(fieldEffectInfo.name); - if (fieldEffectInfo.type === ArenaEffectType.TERRAIN) { + if (fieldEffectInfo.effecType === ArenaEffectType.TERRAIN) { textObject.text += " Terrain"; // Adds 'Terrain' since the enum does not contain it } @@ -257,19 +259,42 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { switch (arenaEffectChangedEvent.constructor) { case TagAddedEvent: const tagAddedEvent = arenaEffectChangedEvent as TagAddedEvent; + const isArenaTrapTag = this.battleScene.arena.getTag(tagAddedEvent.arenaTagType) instanceof ArenaTrapTag; + let arenaEffectType: ArenaEffectType; + + if (tagAddedEvent.arenaTagSide === ArenaTagSide.BOTH) { + arenaEffectType = ArenaEffectType.FIELD; + } else if (tagAddedEvent.arenaTagSide === ArenaTagSide.PLAYER) { + arenaEffectType = ArenaEffectType.PLAYER; + } else { + arenaEffectType = ArenaEffectType.ENEMY; + } + + const existingTrapTagIndex = isArenaTrapTag ? this.fieldEffectInfo.findIndex(e => tagAddedEvent.arenaTagType === e.tagType && arenaEffectType === e.effecType) : -1; + let name: string = ArenaTagType[tagAddedEvent.arenaTagType]; + + if (isArenaTrapTag && tagAddedEvent.arenaTagMaxLayers > 1) { + if (existingTrapTagIndex !== -1) { + this.fieldEffectInfo[existingTrapTagIndex].name = `${name} (${tagAddedEvent.arenaTagLayers})`; + break; + } else { + name = `${name} (${tagAddedEvent.arenaTagLayers})`; + } + } + + this.fieldEffectInfo.push({ - name: ArenaTagType[tagAddedEvent.arenaTagType], - type: tagAddedEvent.arenaTagSide === ArenaTagSide.BOTH - ? ArenaEffectType.FIELD - : tagAddedEvent.arenaTagSide === ArenaTagSide.PLAYER - ? ArenaEffectType.PLAYER - : ArenaEffectType.ENEMY, + name, + effecType: arenaEffectType, maxDuration: tagAddedEvent.duration, - duration: tagAddedEvent.duration}); + duration: tagAddedEvent.duration, + tagType: tagAddedEvent.arenaTagType + }); break; case TagRemovedEvent: const tagRemovedEvent = arenaEffectChangedEvent as TagRemovedEvent; - foundIndex = this.fieldEffectInfo.findIndex(info => info.name === ArenaTagType[tagRemovedEvent.arenaTagType]); + foundIndex = this.fieldEffectInfo.findIndex(info => info.tagType === tagRemovedEvent.arenaTagType); + if (foundIndex !== -1) { // If the tag was being tracked, remove it this.fieldEffectInfo.splice(foundIndex, 1); } @@ -290,7 +315,7 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { fieldEffectChangedEvent instanceof WeatherChangedEvent ? WeatherType[fieldEffectChangedEvent.newWeatherType] : TerrainType[fieldEffectChangedEvent.newTerrainType], - type: fieldEffectChangedEvent instanceof WeatherChangedEvent + effecType: fieldEffectChangedEvent instanceof WeatherChangedEvent ? ArenaEffectType.WEATHER : ArenaEffectType.TERRAIN, maxDuration: fieldEffectChangedEvent.duration, diff --git a/src/ui/challenges-select-ui-handler.ts b/src/ui/challenges-select-ui-handler.ts index 1104b048f93..67703b63aee 100644 --- a/src/ui/challenges-select-ui-handler.ts +++ b/src/ui/challenges-select-ui-handler.ts @@ -6,7 +6,11 @@ import { addWindow } from "./ui-theme"; import {Button} from "#enums/buttons"; import i18next from "i18next"; import { SelectStarterPhase, TitlePhase } from "#app/phases.js"; -import { Challenge } from "#app/data/challenge.js"; +import { Challenge, ChallengeType } from "#app/data/challenge.js"; +import * as Utils from "../utils"; +import { Challenges } from "#app/enums/challenges.js"; +import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; +import { Color, ShadowColor } from "#app/enums/color.js"; /** * Handles all the UI for choosing optional challenges. @@ -21,10 +25,9 @@ export default class GameChallengesUiHandler extends UiHandler { // private difficultyText: Phaser.GameObjects.Text; - private descriptionText: Phaser.GameObjects.Text; + private descriptionText: BBCodeText; - private challengeLabels: Phaser.GameObjects.Text[]; - private challengeValueLabels: Phaser.GameObjects.Text[]; + private challengeLabels: Array<{ label: Phaser.GameObjects.Text, value: Phaser.GameObjects.Text | Phaser.GameObjects.Sprite }>; private cursorObj: Phaser.GameObjects.NineSlice; @@ -38,14 +41,22 @@ export default class GameChallengesUiHandler extends UiHandler { const ui = this.getUi(); this.challengesContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1); + this.challengesContainer.setName("container-challenges"); this.challengesContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains); + const bgOverlay = this.scene.add.rectangle(-1, -1, this.scene.scaledCanvas.width, this.scene.scaledCanvas.height, 0x424242, 0.8); + bgOverlay.setName("rect-challenge-overlay"); + bgOverlay.setOrigin(0, 0); + this.challengesContainer.add(bgOverlay); + // TODO: Change this back to /9 when adding in difficulty const headerBg = addWindow(this.scene, 0, 0, (this.scene.game.canvas.width / 6), 24); + headerBg.setName("window-header-bg"); headerBg.setOrigin(0, 0); const headerText = addTextObject(this.scene, 0, 0, i18next.t("challenges:title"), TextStyle.SETTINGS_LABEL); + headerText.setName("text-header"); headerText.setOrigin(0, 0); headerText.setPositionRelative(headerBg, 8, 4); @@ -62,45 +73,78 @@ export default class GameChallengesUiHandler extends UiHandler { // difficultyName.setPositionRelative(difficultyBg, difficultyBg.width - difficultyName.displayWidth - 8, 4); this.optionsBg = addWindow(this.scene, 0, headerBg.height, (this.scene.game.canvas.width / 9), (this.scene.game.canvas.height / 6) - headerBg.height - 2); + this.optionsBg.setName("window-options-bg"); this.optionsBg.setOrigin(0, 0); const descriptionBg = addWindow(this.scene, 0, headerBg.height, (this.scene.game.canvas.width / 18) - 2, (this.scene.game.canvas.height / 6) - headerBg.height - 26); + descriptionBg.setName("window-desc-bg"); descriptionBg.setOrigin(0, 0); descriptionBg.setPositionRelative(this.optionsBg, this.optionsBg.width, 0); - this.descriptionText = addTextObject(this.scene, 0, 0, "", TextStyle.SETTINGS_LABEL); + this.descriptionText = new BBCodeText(this.scene, descriptionBg.x + 6, descriptionBg.y + 4, "", { + fontFamily: "emerald, unifont", + fontSize: 96, + color: Color.ORANGE, + padding: { + bottom: 6 + }, + wrap: { + mode: "word", + width: (descriptionBg.width - 12) * 6, + } + }); + this.descriptionText.setName("text-desc"); + this.scene.add.existing(this.descriptionText); + this.descriptionText.setScale(1/6); + this.descriptionText.setShadow(4, 5, ShadowColor.ORANGE); this.descriptionText.setOrigin(0, 0); - this.descriptionText.setWordWrapWidth(500, true); - this.descriptionText.setPositionRelative(descriptionBg, 6, 4); const startBg = addWindow(this.scene, 0, 0, descriptionBg.width, 24); + startBg.setName("window-start-bg"); startBg.setOrigin(0, 0); startBg.setPositionRelative(descriptionBg, 0, descriptionBg.height); - const startText = addTextObject(this.scene, 0, 0, i18next.t("challenges:start"), TextStyle.SETTINGS_LABEL); + const startText = addTextObject(this.scene, 0, 0, i18next.t("common:start"), TextStyle.SETTINGS_LABEL); + startText.setName("text-start"); startText.setOrigin(0, 0); startText.setPositionRelative(startBg, 8, 4); this.startCursor = this.scene.add.nineslice(0, 0, "summary_moves_cursor", null, (this.scene.game.canvas.width / 18) - 10, 16, 1, 1, 1, 1); + this.startCursor.setName("9s-start-cursor"); this.startCursor.setOrigin(0, 0); this.startCursor.setPositionRelative(startBg, 4, 4); this.startCursor.setVisible(false); this.valuesContainer = this.scene.add.container(0, 0); + this.valuesContainer.setName("container-values"); this.challengeLabels = []; - this.challengeValueLabels = []; - for (let i = 0; i < 9; i++) { - this.challengeLabels[i] = addTextObject(this.scene, 8, 28 + i * 16, "", TextStyle.SETTINGS_LABEL); - this.challengeLabels[i].setOrigin(0, 0); + for (let i = 0; i < Object.keys(ChallengeType).length; i++) { + const label = addTextObject(this.scene, 8, 28 + i * 16, "", TextStyle.SETTINGS_LABEL); + label.setName(`text-challenge-label-${i}`); + label.setOrigin(0, 0); - this.valuesContainer.add(this.challengeLabels[i]); + this.valuesContainer.add(label); - this.challengeValueLabels[i] = addTextObject(this.scene, 0, 28 + i * 16, "", TextStyle.SETTINGS_LABEL); - this.challengeValueLabels[i].setPositionRelative(this.challengeLabels[i], 100, 0); + let value; + if (i === Challenges.SINGLE_TYPE) { + const type = `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`; + value = this.scene.add.sprite(8, 98, type); + value.setName("sprite-single-type"); + value.setScale(0.86); + value.setPositionRelative(label, 113, 8); + } else { + value = addTextObject(this.scene, 0, 28 + i * 16, "", TextStyle.SETTINGS_LABEL); + value.setName(`text-challenge-value-label-${i}`); + value.setPositionRelative(label, 100, 0); + } - this.valuesContainer.add(this.challengeValueLabels[i]); + this.valuesContainer.add(value); + this.challengeLabels[i] = { + label: label, + value: value + }; } this.challengesContainer.add(headerBg); @@ -124,31 +168,49 @@ export default class GameChallengesUiHandler extends UiHandler { this.challengesContainer.setVisible(false); } + /** + * Adds the default text color to the description text + * @param text text to set to the BBCode description + */ + setDescription(text: string): void { + this.descriptionText.setText(`[color=${Color.ORANGE}][shadow=${ShadowColor.ORANGE}]${text}`); + } + /** + * initLabels + * init all challenge labels + */ + initLabels(): void { + this.setDescription(this.scene.gameMode.challenges[this.cursor].getDescription()); + this.scene.gameMode.challenges.forEach((challenge, i) => { + this.challengeLabels[i].label.setVisible(true); + this.challengeLabels[i].value.setVisible(true); + this.challengeLabels[i].label.setText(challenge.getName()); + if (this.challengeLabels[i].value.type.toLowerCase() === "sprite") { + (this.challengeLabels[i].value as Phaser.GameObjects.Sprite).setFrame(challenge.getValue()); + } else { + (this.challengeLabels[i].value as Phaser.GameObjects.Text).setText(challenge.getValue()); + } + }); + } + + /** + * update the text the cursor is on + */ updateText(): void { - if (this.scene.gameMode.challenges.length > 0) { - this.descriptionText.text = this.getActiveChallenge().getDescription(); - this.descriptionText.updateText(); - } + const challenge = this.getActiveChallenge(); + const { id } = challenge; + this.setDescription(this.getActiveChallenge().getDescription()); + if (this.challengeLabels[id].value.type.toLowerCase() === "sprite") { + (this.challengeLabels[id].value as Phaser.GameObjects.Sprite).setFrame(challenge.getValue()); + } else { + (this.challengeLabels[id].value as Phaser.GameObjects.Text).setText(challenge.getValue()); + } // const totalDifficulty = this.scene.gameMode.challenges.reduce((v, c) => v + c.getDifficulty(), 0); // const totalMinDifficulty = this.scene.gameMode.challenges.reduce((v, c) => v + c.getMinDifficulty(), 0); // this.difficultyText.text = `${totalDifficulty}` + (totalMinDifficulty ? `/${totalMinDifficulty}` : ""); // this.difficultyText.updateText(); - - for (let i = 0; i < this.challengeLabels.length; i++) { - if (i + this.scrollCursor < this.scene.gameMode.challenges.length) { - this.challengeLabels[i].setVisible(true); - this.challengeValueLabels[i].setVisible(true); - this.challengeLabels[i].text = this.scene.gameMode.challenges[i + this.scrollCursor].getName(); - this.challengeValueLabels[i].text = this.scene.gameMode.challenges[i + this.scrollCursor].getValue(); - this.challengeLabels[i].updateText(); - this.challengeValueLabels[i].updateText(); - } else { - this.challengeLabels[i].setVisible(false); - this.challengeValueLabels[i].setVisible(false); - } - } } show(args: any[]): boolean { @@ -158,7 +220,7 @@ export default class GameChallengesUiHandler extends UiHandler { this.challengesContainer.setVisible(true); this.setCursor(0); - this.updateText(); + this.initLabels(); this.getUi().moveTo(this.challengesContainer, this.getUi().length - 1); diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 2c4a413f2f1..34ee83b0f50 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -432,7 +432,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.valueLimitLabel.setOrigin(0.5, 0); this.starterSelectContainer.add(this.valueLimitLabel); - const startLabel = addTextObject(this.scene, 124, 162, i18next.t("starterSelectUiHandler:start"), TextStyle.TOOLTIP_CONTENT); + const startLabel = addTextObject(this.scene, 124, 162, i18next.t("common:start"), TextStyle.TOOLTIP_CONTENT); startLabel.setOrigin(0.5, 0); this.starterSelectContainer.add(startLabel); @@ -547,11 +547,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonSprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true }); this.starterSelectContainer.add(this.pokemonSprite); - this.type1Icon = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); this.type1Icon.setScale(0.5); + this.type1Icon = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); + this.type1Icon.setScale(0.5); this.type1Icon.setOrigin(0, 0); this.starterSelectContainer.add(this.type1Icon); - this.type2Icon = this.scene.add.sprite(26, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); this.type2Icon.setScale(0.5); + this.type2Icon = this.scene.add.sprite(26, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); + this.type2Icon.setScale(0.5); this.type2Icon.setOrigin(0, 0); this.starterSelectContainer.add(this.type2Icon); @@ -1097,7 +1099,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const species = this.genSpecies[this.getGenCursorWithScroll()][this.cursor]; const isValidForChallenge = new Utils.BooleanHolder(true); - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor), this.starterGens.length); if (!isDupe && isValidForChallenge.value && this.tryUpdateValue(this.scene.gameData.getSpeciesStarterValue(species.speciesId))) { const cursorObj = this.starterCursorObjs[this.starterCursors.length]; @@ -2216,8 +2218,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonSprite.setVisible(!this.statsMode); }); - (this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite) - .setTexture(species.getIconAtlasKey(formIndex, shiny, variant), species.getIconId(female, formIndex, shiny, variant)); + + const isValidForChallenge = new Utils.BooleanHolder(true); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor), this.starterGens.length); + const starterSprite = this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite; + starterSprite.setTexture(species.getIconAtlasKey(formIndex, shiny, variant), species.getIconId(female, formIndex, shiny, variant)); + starterSprite.setAlpha(isValidForChallenge.value ? 1 : 0.375); this.checkIconId((this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite), species, female, formIndex, shiny, variant); this.canCycleShiny = !!(dexEntry.caughtAttr & DexAttr.NON_SHINY && dexEntry.caughtAttr & DexAttr.SHINY); this.canCycleGender = !!(dexEntry.caughtAttr & DexAttr.MALE && dexEntry.caughtAttr & DexAttr.FEMALE); @@ -2434,7 +2440,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { * we change to can AddParty value to true since the user has enough cost to choose this pokemon and this pokemon registered too. */ const isValidForChallenge = new Utils.BooleanHolder(true); - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, this.genSpecies[g][s], isValidForChallenge); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, this.genSpecies[g][s], isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(this.genSpecies[g][s], this.scene.gameData.getSpeciesDefaultDexAttr(this.genSpecies[g][s], false, true)), this.starterGens.length + (add ? 1 : 0)); const canBeChosen = remainValue >= speciesStarterValue && isValidForChallenge.value; diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 5b4dc2cf84f..73edda0ba44 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -15,7 +15,7 @@ import { Stat, getStatName } from "../data/pokemon-stat"; import { PokemonHeldItemModifier } from "../modifier/modifier"; import { StatusEffect } from "../data/status-effect"; import { getBiomeName } from "../data/biomes"; -import { Nature, getNatureStatMultiplier } from "../data/nature"; +import { getNatureName, getNatureStatMultiplier } from "../data/nature"; import { loggedInUser } from "../account"; import { Variant, getVariantTint } from "#app/data/variant"; import {Button} from "#enums/buttons"; @@ -796,7 +796,7 @@ export default class SummaryUiHandler extends UiHandler { this.passiveContainer?.nameText.setVisible(false); this.passiveContainer?.descriptionText.setVisible(false); - const memoString = `${getBBCodeFrag(Utils.toReadableString(Nature[this.pokemon.getNature()]), TextStyle.SUMMARY_RED)}${getBBCodeFrag(" nature,", TextStyle.WINDOW_ALT)}\n${getBBCodeFrag(`${this.pokemon.metBiome === -1 ? "apparently " : ""}met at Lv`, TextStyle.WINDOW_ALT)}${getBBCodeFrag(this.pokemon.metLevel.toString(), TextStyle.SUMMARY_RED)}${getBBCodeFrag(",", TextStyle.WINDOW_ALT)}\n${getBBCodeFrag(getBiomeName(this.pokemon.metBiome), TextStyle.SUMMARY_RED)}${getBBCodeFrag(".", TextStyle.WINDOW_ALT)}`; + const memoString = `${getBBCodeFrag(Utils.toReadableString(getNatureName(this.pokemon.getNature())), TextStyle.SUMMARY_RED)}${getBBCodeFrag(" nature,", TextStyle.WINDOW_ALT)}\n${getBBCodeFrag(`${this.pokemon.metBiome === -1 ? "apparently " : ""}met at Lv`, TextStyle.WINDOW_ALT)}${getBBCodeFrag(this.pokemon.metLevel.toString(), TextStyle.SUMMARY_RED)}${getBBCodeFrag(",", TextStyle.WINDOW_ALT)}\n${getBBCodeFrag(getBiomeName(this.pokemon.metBiome), TextStyle.SUMMARY_RED)}${getBBCodeFrag(".", TextStyle.WINDOW_ALT)}`; const memoText = addBBCodeTextObject(this.scene, 7, 113, memoString, TextStyle.WINDOW_ALT); memoText.setOrigin(0, 0); diff --git a/src/ui/ui.ts b/src/ui/ui.ts index 55982d049cf..75ccfc40f59 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -182,7 +182,7 @@ export default class UI extends Phaser.GameObjects.Container { } setup(): void { - this.setName("container-ui"); + this.setName(`container-ui-${Mode[this.mode]}`); for (const handler of this.handlers) { handler.setup(); } diff --git a/src/utils.ts b/src/utils.ts index 7c1a24a6d5e..6667d2522f5 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -361,6 +361,9 @@ export function apiPost(path: string, data?: any, contentType: string = "applica }) : new Promise(() => {}); } +/** Alias for the constructor of a class */ +export type Constructor = new(...args: unknown[]) => T; + export class BooleanHolder { public value: boolean;