Merge branch 'pagefaultgames:main' into main

This commit is contained in:
3ae3ae 2024-07-07 13:49:03 +09:00 committed by GitHub
commit b434b959c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
74 changed files with 809 additions and 296 deletions

View File

@ -1,41 +1,41 @@
{ {
"textures": [ "textures": [
{ {
"image": "774.png", "image": "774.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 37, "w": 37,
"h": 37 "h": 37
}, },
"scale": 1, "scale": 1,
"frames": [ "frames": [
{ {
"filename": "0001.png", "filename": "0001.png",
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"sourceSize": { "sourceSize": {
"w": 37, "w": 37,
"h": 35 "h": 37
}, },
"spriteSourceSize": { "spriteSourceSize": {
"x": 0, "x": 0,
"y": 0, "y": 0,
"w": 37, "w": 37,
"h": 35 "h": 37
}, },
"frame": { "frame": {
"x": 0, "x": 0,
"y": 0, "y": 0,
"w": 37, "w": 37,
"h": 35 "h": 37
} }
} }
] ]
} }
], ],
"meta": { "meta": {
"app": "https://www.codeandweb.com/texturepacker", "app": "https://www.codeandweb.com/texturepacker",
"version": "3.0", "version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:fa61a53a0684a1d00e0ed5d6737743af:3e6463caf33bbb58cfba4bd9c20890aa:37281ac0aa1e619ef385b889b64064b7$" "smartupdate": "$TexturePacker:SmartUpdate:241dff4083e172e8503b54a7f0210f8d:982b194223ffeef2ba672b3c5979a426:37281ac0aa1e619ef385b889b64064b7$"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -1,41 +1,41 @@
{ {
"textures": [ "textures": [
{ {
"image": "774.png", "image": "774.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 37, "w": 37,
"h": 37 "h": 37
}, },
"scale": 1, "scale": 1,
"frames": [ "frames": [
{ {
"filename": "0001.png", "filename": "0001.png",
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"sourceSize": { "sourceSize": {
"w": 37, "w": 37,
"h": 35 "h": 37
}, },
"spriteSourceSize": { "spriteSourceSize": {
"x": 0, "x": 0,
"y": 0, "y": 0,
"w": 37, "w": 37,
"h": 35 "h": 37
}, },
"frame": { "frame": {
"x": 0, "x": 0,
"y": 0, "y": 0,
"w": 37, "w": 37,
"h": 35 "h": 37
} }
} }
] ]
} }
], ],
"meta": { "meta": {
"app": "https://www.codeandweb.com/texturepacker", "app": "https://www.codeandweb.com/texturepacker",
"version": "3.0", "version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:29265d2eed2689ecb95874383b7e7da7:1339971def468ab6d7c93a72472c7b3d:37281ac0aa1e619ef385b889b64064b7$" "smartupdate": "$TexturePacker:SmartUpdate:566b51540ed595250ead15a4733d98d6:172aa05dcc207383119cd2f2f7977e0e:37281ac0aa1e619ef385b889b64064b7$"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1227,6 +1227,7 @@ export default class BattleScene extends SceneBase {
case Species.ZARUDE: case Species.ZARUDE:
case Species.SQUAWKABILLY: case Species.SQUAWKABILLY:
case Species.TATSUGIRI: case Species.TATSUGIRI:
case Species.GIMMIGHOUL:
case Species.PALDEA_TAUROS: case Species.PALDEA_TAUROS:
return Utils.randSeedInt(species.forms.length); return Utils.randSeedInt(species.forms.length);
case Species.PIKACHU: case Species.PIKACHU:

View File

@ -1296,6 +1296,7 @@ export class AddSecondStrikeAbAttr extends PreAttackAbAttr {
const multiplier = args[2] as Utils.NumberHolder; const multiplier = args[2] as Utils.NumberHolder;
if (this.canApplyPreAttack(move, numTargets)) { if (this.canApplyPreAttack(move, numTargets)) {
this.showAbility = !!hitCount?.value;
if (!!hitCount?.value) { if (!!hitCount?.value) {
hitCount.value *= 2; hitCount.value *= 2;
} }

View File

@ -935,7 +935,9 @@ export class ContactDamageProtectedTag extends ProtectedTag {
const effectPhase = pokemon.scene.getCurrentPhase(); const effectPhase = pokemon.scene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) { if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
const attacker = effectPhase.getPokemon(); const attacker = effectPhase.getPokemon();
attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); if (!attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
}
} }
} }

View File

@ -2961,9 +2961,29 @@ export class HpPowerAttr extends VariablePowerAttr {
} }
} }
/**
* Attribute used for moves whose base power scales with the opponent's HP
* Used for Crush Grip, Wring Out, and Hard Press
* maxBasePower 100 for Hard Press, 120 for others
*/
export class OpponentHighHpPowerAttr extends VariablePowerAttr { export class OpponentHighHpPowerAttr extends VariablePowerAttr {
maxBasePower: number;
constructor(maxBasePower: number) {
super();
this.maxBasePower = maxBasePower;
}
/**
* Changes the base power of the move to be the target's HP ratio times the maxBasePower with a min value of 1
* @param user n/a
* @param target the Pokemon being attacked
* @param move n/a
* @param args holds the base power of the move at args[0]
* @returns true
*/
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
(args[0] as Utils.NumberHolder).value = Math.max(Math.floor(120 * target.getHpRatio()), 1); (args[0] as Utils.NumberHolder).value = Math.max(Math.floor(this.maxBasePower * target.getHpRatio()), 1);
return true; return true;
} }
@ -6705,7 +6725,7 @@ export function initMoves() {
.target(MoveTarget.ALL_NEAR_ENEMIES) .target(MoveTarget.ALL_NEAR_ENEMIES)
.unimplemented(), .unimplemented(),
new AttackMove(Moves.WRING_OUT, Type.NORMAL, MoveCategory.SPECIAL, -1, 100, 5, -1, 0, 4) new AttackMove(Moves.WRING_OUT, Type.NORMAL, MoveCategory.SPECIAL, -1, 100, 5, -1, 0, 4)
.attr(OpponentHighHpPowerAttr) .attr(OpponentHighHpPowerAttr, 120)
.makesContact(), .makesContact(),
new SelfStatusMove(Moves.POWER_TRICK, Type.PSYCHIC, -1, 10, -1, 0, 4) new SelfStatusMove(Moves.POWER_TRICK, Type.PSYCHIC, -1, 10, -1, 0, 4)
.unimplemented(), .unimplemented(),
@ -6929,7 +6949,7 @@ export function initMoves() {
.triageMove() .triageMove()
.unimplemented(), .unimplemented(),
new AttackMove(Moves.CRUSH_GRIP, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 4) new AttackMove(Moves.CRUSH_GRIP, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 4)
.attr(OpponentHighHpPowerAttr), .attr(OpponentHighHpPowerAttr, 120),
new AttackMove(Moves.MAGMA_STORM, Type.FIRE, MoveCategory.SPECIAL, 100, 75, 5, -1, 0, 4) new AttackMove(Moves.MAGMA_STORM, Type.FIRE, MoveCategory.SPECIAL, 100, 75, 5, -1, 0, 4)
.attr(TrapAttr, BattlerTagType.MAGMA_STORM), .attr(TrapAttr, BattlerTagType.MAGMA_STORM),
new StatusMove(Moves.DARK_VOID, Type.DARK, 50, 10, -1, 0, 4) new StatusMove(Moves.DARK_VOID, Type.DARK, 50, 10, -1, 0, 4)
@ -8399,8 +8419,8 @@ export function initMoves() {
new AttackMove(Moves.TACHYON_CUTTER, Type.STEEL, MoveCategory.SPECIAL, 50, -1, 10, -1, 0, 9) new AttackMove(Moves.TACHYON_CUTTER, Type.STEEL, MoveCategory.SPECIAL, 50, -1, 10, -1, 0, 9)
.attr(MultiHitAttr, MultiHitType._2) .attr(MultiHitAttr, MultiHitType._2)
.slicingMove(), .slicingMove(),
new AttackMove(Moves.HARD_PRESS, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 9) new AttackMove(Moves.HARD_PRESS, Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 9)
.attr(OpponentHighHpPowerAttr), .attr(OpponentHighHpPowerAttr, 100),
new StatusMove(Moves.DRAGON_CHEER, Type.DRAGON, -1, 15, -1, 0, 9) new StatusMove(Moves.DRAGON_CHEER, Type.DRAGON, -1, 15, -1, 0, 9)
.attr(AddBattlerTagAttr, BattlerTagType.CRIT_BOOST, false, true) .attr(AddBattlerTagAttr, BattlerTagType.CRIT_BOOST, false, true)
.target(MoveTarget.NEAR_ALLY) .target(MoveTarget.NEAR_ALLY)

View File

@ -1618,7 +1618,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM) new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
], ],
[Species.GIMMIGHOUL]: [ [Species.GIMMIGHOUL]: [
new SpeciesEvolution(Species.GHOLDENGO, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.VERY_LONG),
new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.VERY_LONG)
] ]
}; };

View File

@ -38685,6 +38685,8 @@ export const tmSpecies: TmSpecies = {
Species.GOLDEEN, Species.GOLDEEN,
Species.SEAKING, Species.SEAKING,
Species.SCYTHER, Species.SCYTHER,
Species.ELECTABUZZ,
Species.MAGMAR,
Species.PINSIR, Species.PINSIR,
Species.OMANYTE, Species.OMANYTE,
Species.OMASTAR, Species.OMASTAR,
@ -38692,6 +38694,8 @@ export const tmSpecies: TmSpecies = {
Species.KABUTOPS, Species.KABUTOPS,
Species.MEWTWO, Species.MEWTWO,
Species.MEW, Species.MEW,
Species.BAYLEEF,
Species.MEGANIUM,
Species.SENTRET, Species.SENTRET,
Species.FURRET, Species.FURRET,
Species.LEDYBA, Species.LEDYBA,
@ -38708,8 +38712,10 @@ export const tmSpecies: TmSpecies = {
Species.SNEASEL, Species.SNEASEL,
Species.PHANPY, Species.PHANPY,
Species.DONPHAN, Species.DONPHAN,
Species.ELEKID,
Species.TYRANITAR, Species.TYRANITAR,
Species.BLAZIKEN, Species.BLAZIKEN,
Species.SWAMPERT,
Species.LOMBRE, Species.LOMBRE,
Species.LUDICOLO, Species.LUDICOLO,
Species.NUZLEAF, Species.NUZLEAF,
@ -38740,12 +38746,7 @@ export const tmSpecies: TmSpecies = {
Species.CHIMECHO, Species.CHIMECHO,
Species.ABSOL, Species.ABSOL,
Species.METAGROSS, Species.METAGROSS,
[ Species.DEOXYS,
Species.DEOXYS,
"",
"defense",
"speed",
],
Species.CHIMCHAR, Species.CHIMCHAR,
Species.MONFERNO, Species.MONFERNO,
Species.INFERNAPE, Species.INFERNAPE,
@ -38767,6 +38768,8 @@ export const tmSpecies: TmSpecies = {
Species.WEAVILE, Species.WEAVILE,
Species.LICKILICKY, Species.LICKILICKY,
Species.TANGROWTH, Species.TANGROWTH,
Species.ELECTIVIRE,
Species.MAGMORTAR,
Species.LEAFEON, Species.LEAFEON,
Species.GLISCOR, Species.GLISCOR,
Species.MAMOSWINE, Species.MAMOSWINE,
@ -38781,6 +38784,8 @@ export const tmSpecies: TmSpecies = {
Species.SNIVY, Species.SNIVY,
Species.SERVINE, Species.SERVINE,
Species.SERPERIOR, Species.SERPERIOR,
Species.PIGNITE,
Species.EMBOAR,
Species.OSHAWOTT, Species.OSHAWOTT,
Species.DEWOTT, Species.DEWOTT,
Species.SAMUROTT, Species.SAMUROTT,
@ -38837,6 +38842,8 @@ export const tmSpecies: TmSpecies = {
Species.ACCELGOR, Species.ACCELGOR,
Species.MIENFOO, Species.MIENFOO,
Species.MIENSHAO, Species.MIENSHAO,
Species.GOLETT,
Species.GOLURK,
Species.PAWNIARD, Species.PAWNIARD,
Species.BISHARP, Species.BISHARP,
Species.VULLABY, Species.VULLABY,
@ -38873,6 +38880,7 @@ export const tmSpecies: TmSpecies = {
Species.SALAZZLE, Species.SALAZZLE,
Species.STEENEE, Species.STEENEE,
Species.TSAREENA, Species.TSAREENA,
Species.COMFEY,
Species.ORANGURU, Species.ORANGURU,
Species.PASSIMIAN, Species.PASSIMIAN,
Species.GOLISOPOD, Species.GOLISOPOD,
@ -38945,6 +38953,7 @@ export const tmSpecies: TmSpecies = {
Species.GALAR_FARFETCHD, Species.GALAR_FARFETCHD,
Species.GALAR_ZAPDOS, Species.GALAR_ZAPDOS,
Species.GALAR_ZIGZAGOON, Species.GALAR_ZIGZAGOON,
Species.GALAR_LINOONE,
Species.HISUI_SAMUROTT, Species.HISUI_SAMUROTT,
Species.HISUI_ZORUA, Species.HISUI_ZORUA,
Species.HISUI_ZOROARK, Species.HISUI_ZOROARK,
@ -61853,6 +61862,7 @@ export const tmSpecies: TmSpecies = {
Species.METANG, Species.METANG,
Species.METAGROSS, Species.METAGROSS,
Species.JIRACHI, Species.JIRACHI,
Species.DEOXYS,
Species.BRONZOR, Species.BRONZOR,
Species.BRONZONG, Species.BRONZONG,
Species.GALLADE, Species.GALLADE,

View File

@ -1162,7 +1162,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return (!cancelled.value ? Number(typeMultiplier.value) : 0) as TypeDamageMultiplier; return (!cancelled.value ? Number(typeMultiplier.value) : 0) as TypeDamageMultiplier;
} }
getAttackTypeEffectiveness(moveType: Type, source?: Pokemon, ignoreStrongWinds: boolean = false): TypeDamageMultiplier { /**
* Calculates the type effectiveness multiplier for an attack type
* @param moveType Type of the move
* @param source the Pokemon using the move
* @param ignoreStrongWinds whether or not this ignores strong winds (anticipation, forewarn, stealth rocks)
* @param simulated tag to only apply the strong winds effect message when the move is used
* @returns a multiplier for the type effectiveness
*/
getAttackTypeEffectiveness(moveType: Type, source?: Pokemon, ignoreStrongWinds: boolean = false, simulated: boolean = true): TypeDamageMultiplier {
if (moveType === Type.STELLAR) { if (moveType === Type.STELLAR) {
return this.isTerastallized() ? 2 : 1; return this.isTerastallized() ? 2 : 1;
} }
@ -1183,8 +1191,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}).reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier; }).reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier;
// Handle strong winds lowering effectiveness of types super effective against pure flying // Handle strong winds lowering effectiveness of types super effective against pure flying
if (!ignoreStrongWinds && this.scene.arena.weather?.weatherType === WeatherType.STRONG_WINDS && !this.scene.arena.weather.isEffectSuppressed(this.scene) && multiplier >= 2 && this.isOfType(Type.FLYING) && getTypeDamageMultiplier(moveType, Type.FLYING) === 2) { if (!ignoreStrongWinds && this.scene.arena.weather?.weatherType === WeatherType.STRONG_WINDS && !this.scene.arena.weather.isEffectSuppressed(this.scene) && this.isOfType(Type.FLYING) && getTypeDamageMultiplier(moveType, Type.FLYING) === 2) {
multiplier /= 2; multiplier /= 2;
if (!simulated) {
this.scene.queueMessage(i18next.t("weather:strongWindsEffectMessage"));
}
} }
if (!!this.summonData?.tags.find((tag) => tag instanceof TypeImmuneTag && tag.immuneType === moveType)) { if (!!this.summonData?.tags.find((tag) => tag instanceof TypeImmuneTag && tag.immuneType === moveType)) {
@ -1739,7 +1750,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
const typeless = move.hasAttr(TypelessAttr); const typeless = move.hasAttr(TypelessAttr);
const typeMultiplier = new Utils.NumberHolder(!typeless && (moveCategory !== MoveCategory.STATUS || move.getAttrs(StatusMoveTypeImmunityAttr).find(attr => types.includes(attr.immuneType))) const typeMultiplier = new Utils.NumberHolder(!typeless && (moveCategory !== MoveCategory.STATUS || move.getAttrs(StatusMoveTypeImmunityAttr).find(attr => types.includes(attr.immuneType)))
? this.getAttackTypeEffectiveness(move.type, source) ? this.getAttackTypeEffectiveness(move.type, source, false, false)
: 1); : 1);
applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier); applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier);
if (typeless) { if (typeless) {

View File

@ -78,6 +78,7 @@ export class LoadingScene extends SceneBase {
this.loadImage("overlay_exp", "ui"); this.loadImage("overlay_exp", "ui");
this.loadImage("icon_owned", "ui"); this.loadImage("icon_owned", "ui");
this.loadImage("ability_bar_left", "ui"); this.loadImage("ability_bar_left", "ui");
this.loadImage("bgm_bar", "ui");
this.loadImage("party_exp_bar", "ui"); this.loadImage("party_exp_bar", "ui");
this.loadImage("achv_bar", "ui"); this.loadImage("achv_bar", "ui");
this.loadImage("achv_bar_2", "ui"); this.loadImage("achv_bar_2", "ui");

View File

@ -25,6 +25,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "Es hat keine Wirkung auf {{pokemonName}}…", "hitResultNoEffect": "Es hat keine Wirkung auf {{pokemonName}}…",
"hitResultOneHitKO": "Ein K.O.-Treffer!", "hitResultOneHitKO": "Ein K.O.-Treffer!",
"attackFailed": "Es ist fehlgeschlagen!", "attackFailed": "Es ist fehlgeschlagen!",
"attackMissed": "Die Attacke hat {{pokemonNameWithAffix}} verfehlt!",
"attackHitsCount": "{{count}}-mal getroffen!", "attackHitsCount": "{{count}}-mal getroffen!",
"rewardGain": "Du erhältst\n{{modifierName}}!", "rewardGain": "Du erhältst\n{{modifierName}}!",
"expGain": "{{pokemonName}} erhält\n{{exp}} Erfahrungspunkte!", "expGain": "{{pokemonName}} erhält\n{{exp}} Erfahrungspunkte!",

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const bgmName: SimpleTranslationEntries = { export const bgmName: SimpleTranslationEntries = {
"music": "Musik", "music": "Musik: ",
"missing_entries" : "{{name}}", "missing_entries" : "{{name}}",
"battle_kanto_champion": "S2W2 Vs. Kanto Champion", "battle_kanto_champion": "S2W2 Vs. Kanto Champion",
"battle_johto_champion": "S2W2 Vs. Johto Champion", "battle_johto_champion": "S2W2 Vs. Johto Champion",

View File

@ -40,5 +40,6 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "Alle Flug-Pokémon werden von rätselhaften Luftströmungen geschützt!", "strongWindsStartMessage": "Alle Flug-Pokémon werden von rätselhaften Luftströmungen geschützt!",
"strongWindsLapseMessage": "Die rätselhafte Luftströmung hält an.", "strongWindsLapseMessage": "Die rätselhafte Luftströmung hält an.",
"strongWindsEffectMessage": "Rätselhafte Luftströmungen haben den Angriff abgeschwächt!",
"strongWindsClearMessage": "Die rätselhafte Luftströmung hat sich wieder geleget.", "strongWindsClearMessage": "Die rätselhafte Luftströmung hat sich wieder geleget.",
}; };

View File

@ -25,6 +25,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "It doesn't affect {{pokemonName}}!", "hitResultNoEffect": "It doesn't affect {{pokemonName}}!",
"hitResultOneHitKO": "It's a one-hit KO!", "hitResultOneHitKO": "It's a one-hit KO!",
"attackFailed": "But it failed!", "attackFailed": "But it failed!",
"attackMissed": "{{pokemonNameWithAffix}} avoided the attack!",
"attackHitsCount": "Hit {{count}} time(s)!", "attackHitsCount": "Hit {{count}} time(s)!",
"rewardGain": "You received\n{{modifierName}}!", "rewardGain": "You received\n{{modifierName}}!",
"expGain": "{{pokemonName}} gained\n{{exp}} EXP. Points!", "expGain": "{{pokemonName}} gained\n{{exp}} EXP. Points!",

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const bgmName: SimpleTranslationEntries = { export const bgmName: SimpleTranslationEntries = {
"music": "Music", "music": "Music: ",
"missing_entries" : "{{name}}", "missing_entries" : "{{name}}",
"battle_kanto_champion": "B2W2 Kanto Champion Battle", "battle_kanto_champion": "B2W2 Kanto Champion Battle",
"battle_johto_champion": "B2W2 Johto Champion Battle", "battle_johto_champion": "B2W2 Johto Champion Battle",

View File

@ -40,5 +40,6 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "A heavy wind began!", "strongWindsStartMessage": "A heavy wind began!",
"strongWindsLapseMessage": "The wind blows intensely.", "strongWindsLapseMessage": "The wind blows intensely.",
"strongWindsEffectMessage": "The mysterious air current weakened the attack!",
"strongWindsClearMessage": "The heavy wind stopped." "strongWindsClearMessage": "The heavy wind stopped."
}; };

View File

@ -25,6 +25,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "No afecta a {{pokemonName}}!", "hitResultNoEffect": "No afecta a {{pokemonName}}!",
"hitResultOneHitKO": "¡KO en 1 golpe!", "hitResultOneHitKO": "¡KO en 1 golpe!",
"attackFailed": "¡Pero ha fallado!", "attackFailed": "¡Pero ha fallado!",
"attackMissed": "¡{{pokemonNameWithAffix}}\nha evitado el ataque!",
"attackHitsCount": "N.º de golpes: {{count}}.", "attackHitsCount": "N.º de golpes: {{count}}.",
"rewardGain": "¡Has obtenido\n{{modifierName}}!", "rewardGain": "¡Has obtenido\n{{modifierName}}!",
"expGain": "{{pokemonName}} ha ganado\n{{exp}} puntos de experiencia.", "expGain": "{{pokemonName}} ha ganado\n{{exp}} puntos de experiencia.",

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const bgmName: SimpleTranslationEntries = { export const bgmName: SimpleTranslationEntries = {
"music": "Música", "music": "Música: ",
"missing_entries" : "{{name}}", "missing_entries" : "{{name}}",
"battle_kanto_champion": "B2W2 - ¡Vs Campeón de Kanto!", "battle_kanto_champion": "B2W2 - ¡Vs Campeón de Kanto!",
"battle_johto_champion": "B2W2 - ¡Vs Campeón de Johto!", "battle_johto_champion": "B2W2 - ¡Vs Campeón de Johto!",

View File

@ -40,5 +40,6 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "¡Comenzó un fuerte viento!", "strongWindsStartMessage": "¡Comenzó un fuerte viento!",
"strongWindsLapseMessage": "El viento sopla intensamente.", "strongWindsLapseMessage": "El viento sopla intensamente.",
"strongWindsEffectMessage": "¡Las misteriosas turbulencias atenúan el ataque!",
"strongWindsClearMessage": "El fuerte viento cesó." "strongWindsClearMessage": "El fuerte viento cesó."
}; };

View File

@ -25,6 +25,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "Ça naffecte pas {{pokemonName}}…", "hitResultNoEffect": "Ça naffecte pas {{pokemonName}}…",
"hitResultOneHitKO": "K.O. en un coup !", "hitResultOneHitKO": "K.O. en un coup !",
"attackFailed": "Mais cela échoue !", "attackFailed": "Mais cela échoue !",
"attackMissed": "{{pokemonNameWithAffix}}\névite lattaque!",
"attackHitsCount": "Touché {{count}} fois !", "attackHitsCount": "Touché {{count}} fois !",
"rewardGain": "Vous recevez\n{{modifierName}} !", "rewardGain": "Vous recevez\n{{modifierName}} !",
"expGain": "{{pokemonName}} gagne\n{{exp}} Points dExp !", "expGain": "{{pokemonName}} gagne\n{{exp}} Points dExp !",

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const bgmName: SimpleTranslationEntries = { export const bgmName: SimpleTranslationEntries = {
"music": "Musique ", "music": "Musique : ",
"missing_entries" : "{{name}}", "missing_entries" : "{{name}}",
"battle_kanto_champion": "N2B2 - Vs. Maitre de Kanto", "battle_kanto_champion": "N2B2 - Vs. Maitre de Kanto",
"battle_johto_champion": "N2B2 - Vs. Maitre de Johto", "battle_johto_champion": "N2B2 - Vs. Maitre de Johto",

View File

@ -28,7 +28,7 @@ export const partyUiHandler: SimpleTranslationEntries = {
"unspliceConfirmation": "Voulez-vous vraiment séparer {{fusionName}}\nde {{pokemonName}} ? {{fusionName}} sera perdu.", "unspliceConfirmation": "Voulez-vous vraiment séparer {{fusionName}}\nde {{pokemonName}} ? {{fusionName}} sera perdu.",
"wasReverted": "{{fusionName}} est redevenu {{pokemonName}}.", "wasReverted": "{{fusionName}} est redevenu {{pokemonName}}.",
"releaseConfirmation": "Voulez-vous relâcher {{pokemonName}} ?", "releaseConfirmation": "Voulez-vous relâcher {{pokemonName}} ?",
"releaseInBattle": "Vous ne pouvez pas relâcher Pokémon en combat !", "releaseInBattle": "Vous ne pouvez pas relâcher un Pokémon en combat !",
"selectAMove": "Sélectionnez une capacité.", "selectAMove": "Sélectionnez une capacité.",
"changeQuantity": "Sélect. un objet à transférer.\nChangez la quantité avec < et >.", "changeQuantity": "Sélect. un objet à transférer.\nChangez la quantité avec < et >.",
"selectAnotherPokemonToSplice": "Sélectionnez un autre Pokémon à séparer.", "selectAnotherPokemonToSplice": "Sélectionnez un autre Pokémon à séparer.",
@ -44,7 +44,7 @@ export const partyUiHandler: SimpleTranslationEntries = {
"byebye": "Bye-bye, {{pokemonName}} !", "byebye": "Bye-bye, {{pokemonName}} !",
"farewell": "Adieu, {{pokemonName}} !", "farewell": "Adieu, {{pokemonName}} !",
"soLong": "Salut, {{pokemonName}} !", "soLong": "Salut, {{pokemonName}} !",
"thisIsWhereWePart": "Cest là quon se sépare, {{pokemonName}}!", "thisIsWhereWePart": "Cest là quon se sépare, {{pokemonName}} !",
"illMissYou": "Tu vas me manquer, {{pokemonName}} !", "illMissYou": "Tu vas me manquer, {{pokemonName}} !",
"illNeverForgetYou": "Je ne toublierai pas, {{pokemonName}} !", "illNeverForgetYou": "Je ne toublierai pas, {{pokemonName}} !",
"untilWeMeetAgain": "À la prochaine, {{pokemonName}} !", "untilWeMeetAgain": "À la prochaine, {{pokemonName}} !",

View File

@ -40,5 +40,6 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "Un vent mystérieux se lève !", "strongWindsStartMessage": "Un vent mystérieux se lève !",
"strongWindsLapseMessage": "Le vent mystérieux souffle violemment !", "strongWindsLapseMessage": "Le vent mystérieux souffle violemment !",
"strongWindsEffectMessage": "Le courant aérien mystérieux affaiblit lattaque!",
"strongWindsClearMessage": "Le vent mystérieux sest dissipé…" "strongWindsClearMessage": "Le vent mystérieux sest dissipé…"
}; };

View File

@ -5,8 +5,8 @@ export const battle: SimpleTranslationEntries = {
"trainerAppeared": "{{trainerName}}\nvuole combattere!", "trainerAppeared": "{{trainerName}}\nvuole combattere!",
"trainerAppearedDouble": "{{trainerName}}\nvogliono combattere!", "trainerAppearedDouble": "{{trainerName}}\nvogliono combattere!",
"trainerSendOut": "{{trainerName}} manda in campo\n{{pokemonName}}!", "trainerSendOut": "{{trainerName}} manda in campo\n{{pokemonName}}!",
"singleWildAppeared": "Appare {{pokemonName}} selvatico!", "singleWildAppeared": "È apparso {{pokemonName}} selvatico!",
"multiWildAppeared": "Appaiono {{pokemonName1}}\ne {{pokemonName2}} salvatici!", "multiWildAppeared": "Sono apparsi {{pokemonName1}}\ne {{pokemonName2}} salvatici!",
"playerComeBack": "Rientra, {{pokemonName}}!", "playerComeBack": "Rientra, {{pokemonName}}!",
"trainerComeBack": "{{trainerName}} ha ritirato {{pokemonName}}!", "trainerComeBack": "{{trainerName}} ha ritirato {{pokemonName}}!",
"playerGo": "Vai! {{pokemonName}}!", "playerGo": "Vai! {{pokemonName}}!",
@ -25,6 +25,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "Non ha effetto su {{pokemonName}}!", "hitResultNoEffect": "Non ha effetto su {{pokemonName}}!",
"hitResultOneHitKO": "KO con un colpo!", "hitResultOneHitKO": "KO con un colpo!",
"attackFailed": "Ma ha fallito!", "attackFailed": "Ma ha fallito!",
"attackMissed": "{{pokemonNameWithAffix}}\nevita lattacco!",
"attackHitsCount": "Colpito {{count}} volta/e!", "attackHitsCount": "Colpito {{count}} volta/e!",
"rewardGain": "You received\n{{modifierName}}!", "rewardGain": "You received\n{{modifierName}}!",
"expGain": "{{pokemonName}} ha guadagnato\n{{exp}} Punti Esperienza!", "expGain": "{{pokemonName}} ha guadagnato\n{{exp}} Punti Esperienza!",
@ -43,10 +44,10 @@ export const battle: SimpleTranslationEntries = {
"moveNotImplemented": "{{moveName}} non è ancora implementata e non può essere selezionata.", "moveNotImplemented": "{{moveName}} non è ancora implementata e non può essere selezionata.",
"moveNoPP": "Non ci sono PP rimanenti\nper questa mossa!", "moveNoPP": "Non ci sono PP rimanenti\nper questa mossa!",
"moveDisabled": "{{moveName}} è disabilitata!", "moveDisabled": "{{moveName}} è disabilitata!",
"noPokeballForce": "Una forza misteriosa\nimpedisce l'uso dell Poké Ball.", "noPokeballForce": "Una forza misteriosa\nimpedisce l'uso delle Poké Ball.",
"noPokeballTrainer": "Non puoi catturare\nPokémon di altri allenatori!", "noPokeballTrainer": "Non puoi catturare\nPokémon di altri allenatori!",
"noPokeballMulti": "Puoi lanciare una Poké Ball\nquando rimane un solo Pokémon!", "noPokeballMulti": "Puoi lanciare una Poké Ball\nsolo quando rimane un singolo Pokémon!",
"noPokeballStrong": "Il Pokémon avversario è troppo forte per essere catturato!\nDevi prima indebolirlo!", "noPokeballStrong": "Il Pokémon avversario è troppo forte per essere catturato!\nDevi prima indebolirlo.",
"noEscapeForce": "Una forza misteriosa\nimpedisce la fuga.", "noEscapeForce": "Una forza misteriosa\nimpedisce la fuga.",
"noEscapeTrainer": "Non puoi sottrarti\nalla lotta con un'allenatore!", "noEscapeTrainer": "Non puoi sottrarti\nalla lotta con un'allenatore!",
"noEscapePokemon": "{{moveName}} di {{pokemonName}}\npreviene la {{escapeVerb}}!", "noEscapePokemon": "{{moveName}} di {{pokemonName}}\npreviene la {{escapeVerb}}!",
@ -54,11 +55,11 @@ export const battle: SimpleTranslationEntries = {
"runAwayCannotEscape": "Non puoi fuggire!", "runAwayCannotEscape": "Non puoi fuggire!",
"escapeVerbSwitch": "cambiando", "escapeVerbSwitch": "cambiando",
"escapeVerbFlee": "fuggendo", "escapeVerbFlee": "fuggendo",
"notDisabled": "{{pokemonName}}'s {{moveName}} non è più\ndisabilitata!", "notDisabled": "{{moveName}} di {{pokemonName}} non è più\ndisabilitata!",
"turnEndHpRestore": "{{pokemonName}}'s HP was restored.", "turnEndHpRestore": "{{pokemonName}}'s HP was restored.",
"hpIsFull": "{{pokemonName}}'s\nHP is full!", "hpIsFull": "{{pokemonName}}'s\nHP is full!",
"skipItemQuestion": "Sei sicuro di non voler prendere nessun oggetto?", "skipItemQuestion": "Sei sicuro di non voler prendere nessun oggetto?",
"eggHatching": "Oh!", "eggHatching": "Oh?",
"ivScannerUseQuestion": "Vuoi usare lo scanner di IV su {{pokemonName}}?", "ivScannerUseQuestion": "Vuoi usare lo scanner di IV su {{pokemonName}}?",
"stealEatBerry": "{{pokemonName}} stole and ate\n{{targetName}}'s {{berryName}}!", "stealEatBerry": "{{pokemonName}} stole and ate\n{{targetName}}'s {{berryName}}!",
"wildPokemonWithAffix": "{{pokemonName}} selvatico", "wildPokemonWithAffix": "{{pokemonName}} selvatico",

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const bgmName: SimpleTranslationEntries = { export const bgmName: SimpleTranslationEntries = {
"music": "Music", "music": "Music: ",
"missing_entries" : "{{name}}", "missing_entries" : "{{name}}",
"battle_kanto_champion": "B2W2 Kanto Champion Battle", "battle_kanto_champion": "B2W2 Kanto Champion Battle",
"battle_johto_champion": "B2W2 Johto Champion Battle", "battle_johto_champion": "B2W2 Johto Champion Battle",

View File

@ -6,18 +6,18 @@ export const egg: SimpleTranslationEntries = {
"greatTier": "Raro", "greatTier": "Raro",
"ultraTier": "Epico", "ultraTier": "Epico",
"masterTier": "Leggendario", "masterTier": "Leggendario",
"hatchWavesMessageSoon": "Si sentono dei suoni provenienti dall'interno! Si schiuderà presto!", "hatchWavesMessageSoon": "Si sentono dei rumori provenienti dall'interno. Si schiuderà presto!",
"hatchWavesMessageClose": "Sembra muoversi di tanto in tanto. Potrebbe essere prossimo alla schiusa.", "hatchWavesMessageClose": "Sembra muoversi di tanto in tanto. Potrebbe essere prossimo alla schiusa.",
"hatchWavesMessageNotClose": "Cosa uscirà da qui? Non sembra si schiuderà presto.", "hatchWavesMessageNotClose": "Cosa uscirà da qui? Pare che non si schiuderà presto.",
"hatchWavesMessageLongTime": "Sembra che questo uovo impiegherà molto tempo per schiudersi.", "hatchWavesMessageLongTime": "Sembra che questo uovo impiegherà ancora molto tempo per schiudersi.",
"gachaTypeLegendary": "Tasso dei Leggendari Aumentato", "gachaTypeLegendary": "Tasso dei leggendari aumentato",
"gachaTypeMove": "Tasso delle Mosse Rare delle Uova Aumentato", "gachaTypeMove": "Tasso delle mosse rare da uova aumentato",
"gachaTypeShiny": "Tasso degli Shiny Aumentato", "gachaTypeShiny": "Tasso degli shiny aumentato",
"selectMachine": "Seleziona un distributore.", "selectMachine": "Seleziona un macchinario.",
"notEnoughVouchers": "Non hai abbastanza Biglietti!", "notEnoughVouchers": "Non hai abbastanza biglietti!",
"tooManyEggs": "Hai troppe Uova!", "tooManyEggs": "Hai troppe uova!",
"pull": "Tiro", "pull": "Estrazione",
"pulls": "Tiri", "pulls": "Estrazioni",
"sameSpeciesEgg": "{{species}} will hatch from this egg!", "sameSpeciesEgg": "{{species}} will hatch from this egg!",
"hatchFromTheEgg": "DallUovo è nato {{pokemonName}}!", "hatchFromTheEgg": "DallUovo è nato {{pokemonName}}!",
"eggMoveUnlock": "Egg Move unlocked: {{moveName}}", "eggMoveUnlock": "Egg Move unlocked: {{moveName}}",

View File

@ -2,23 +2,23 @@ import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const menuUiHandler: SimpleTranslationEntries = { export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": "Impostazioni", "GAME_SETTINGS": "Impostazioni",
"ACHIEVEMENTS": "Trofei", "ACHIEVEMENTS": "Obiettivi",
"STATS": "Statistiche", "STATS": "Statistiche",
"VOUCHERS": "Biglietti", "VOUCHERS": "Biglietti",
"EGG_LIST": "Lista Uova", "EGG_LIST": "Lista uova",
"EGG_GACHA": "Gacha Uova", "EGG_GACHA": "Macchine uova",
"MANAGE_DATA": "Gestisci Dati", "MANAGE_DATA": "Gestisci dati",
"COMMUNITY": "Community", "COMMUNITY": "Community",
"SAVE_AND_QUIT": "Salva ed Esci", "SAVE_AND_QUIT": "Salva ed esci",
"LOG_OUT": "Disconnettiti", "LOG_OUT": "Disconnettiti",
"slot": "Slot {{slotNumber}}", "slot": "Slot {{slotNumber}}",
"importSession": "Importa Sessione", "importSession": "Importa sessione",
"importSlotSelect": "Seleziona uno slot in cui importare.", "importSlotSelect": "Seleziona uno slot in cui importare.",
"exportSession": "Esporta Sessione", "exportSession": "Esporta sessione",
"exportSlotSelect": "Seleziona uno slot da cui esportare.", "exportSlotSelect": "Seleziona uno slot da cui esportare.",
"importData": "Importa Dati", "importData": "Importa dati",
"exportData": "Esporta Dati", "exportData": "Esporta dati",
"cancel": "Annulla", "cancel": "Annulla",
"losingProgressionWarning": "Perderai tutti i progressi dall'inizio della battaglia. Procedere?", "losingProgressionWarning": "Perderai tutti i progressi dall'inizio della battaglia. Confermi?",
"noEggs": "You are not hatching\nany eggs at the moment!" "noEggs": "You are not hatching\nany eggs at the moment!"
} as const; } as const;

View File

@ -13,18 +13,18 @@ export const modifierType: ModifierTypeTranslationEntries = {
"PokemonHeldItemModifierType": { "PokemonHeldItemModifierType": {
extra: { extra: {
"inoperable": "{{pokemonName}} non può prendere\nquesto oggetto!", "inoperable": "{{pokemonName}} non può prendere\nquesto oggetto!",
"tooMany": "{{pokemonName}} ne ha troppi\ndi questo oggetto!", "tooMany": "{{pokemonName}} possiede già\nquesto oggetto in abbondanza.",
} }
}, },
"PokemonHpRestoreModifierType": { "PokemonHpRestoreModifierType": {
description: "Restituisce {{restorePoints}} PS o {{restorePercent}}% PS ad un Pokémon, a seconda del valore più alto.", description: "Restituisce {{restorePoints}} PS o {{restorePercent}}% PS ad un Pokémon, a seconda del valore più alto.",
extra: { extra: {
"fully": "Restituisce tutti i PS ad un Pokémon.", "fully": "Restituisce tutti i PS ad un Pokémon.",
"fullyWithStatus": "Restituisce tutti i PS ad un Pokémon e lo cura da ogni stato.", "fullyWithStatus": "Restituisce tutti i PS ad un Pokémon e lo cura da ogni problema di stato.",
} }
}, },
"PokemonReviveModifierType": { "PokemonReviveModifierType": {
description: "Rianima un Pokémon esausto e gli restituisce il {{restorePercent}}% PS.", description: "Rianima un Pokémon esausto e gli restituisce il {{restorePercent}}% dei PS totali.",
}, },
"PokemonStatusHealModifierType": { "PokemonStatusHealModifierType": {
description: "Cura tutti i problemi di stato di un Pokémon.", description: "Cura tutti i problemi di stato di un Pokémon.",
@ -46,7 +46,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
}, },
"PokemonNatureChangeModifierType": { "PokemonNatureChangeModifierType": {
name: "Menta {{natureName}}.", name: "Menta {{natureName}}.",
description: "Cambia la natura del Pokémon in {{natureName}} e sblocca la natura per il Pokémon iniziale.", description: "Cambia la natura del Pokémon in {{natureName}} e sblocca la natura nel menu degli starter.",
}, },
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
description: "Raddoppia la possibilità di imbattersi in doppie battaglie per {{battleCount}} battaglie.", description: "Raddoppia la possibilità di imbattersi in doppie battaglie per {{battleCount}} battaglie.",
@ -67,7 +67,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
description: "Aumenta {{statName}} di base del possessore del 10%.", description: "Aumenta {{statName}} di base del possessore del 10%.",
}, },
"AllPokemonFullHpRestoreModifierType": { "AllPokemonFullHpRestoreModifierType": {
description: "Recupera il 100% dei PS per tutti i Pokémon.", description: "Restituisce il 100% dei PS a tutti i Pokémon.",
}, },
"AllPokemonFullReviveModifierType": { "AllPokemonFullReviveModifierType": {
description: "Rianima tutti i Pokémon esausti restituendogli tutti i PS.", description: "Rianima tutti i Pokémon esausti restituendogli tutti i PS.",
@ -75,7 +75,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
"MoneyRewardModifierType": { "MoneyRewardModifierType": {
description: "Garantisce una {{moneyMultiplier}} quantità di soldi (₽{{moneyAmount}}).", description: "Garantisce una {{moneyMultiplier}} quantità di soldi (₽{{moneyAmount}}).",
extra: { extra: {
"small": "poca", "small": "contenuta",
"moderate": "moderata", "moderate": "moderata",
"large": "grande", "large": "grande",
}, },
@ -90,7 +90,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
description: "Aumenta del 50% il guadagno di amicizia per vittoria.", description: "Aumenta del 50% il guadagno di amicizia per vittoria.",
}, },
"PokemonMoveAccuracyBoosterModifierType": { "PokemonMoveAccuracyBoosterModifierType": {
description: "Aumenta l'accuratezza delle mosse di {{accuracyAmount}} (massimo 100).", description: "Aumenta la precisione delle mosse di {{accuracyAmount}} (massimo 100).",
}, },
"PokemonMultiHitModifierType": { "PokemonMultiHitModifierType": {
description: "Gli attacchi colpiscono una volta in più al costo di una riduzione di potenza del 60/75/82,5% per mossa.", description: "Gli attacchi colpiscono una volta in più al costo di una riduzione di potenza del 60/75/82,5% per mossa.",
@ -117,7 +117,7 @@ export const modifierType: ModifierTypeTranslationEntries = {
description: "Teracristallizza in {{teraType}} il possessore per massimo 10 battaglie.", description: "Teracristallizza in {{teraType}} il possessore per massimo 10 battaglie.",
}, },
"ContactHeldItemTransferChanceModifierType": { "ContactHeldItemTransferChanceModifierType": {
description: "Quando si attacca, c'è una probabilità del {{chancePercent}}% che l'oggetto in possesso del nemico venga rubato.", description: "Quando il possessore attacca, c'è una probabilità del {{chancePercent}}% che l'oggetto in possesso del nemico gli venga rubato.",
}, },
"TurnHeldItemTransferModifierType": { "TurnHeldItemTransferModifierType": {
description: "Ogni turno, il possessore acquisisce un oggetto posseduto dal nemico.", description: "Ogni turno, il possessore acquisisce un oggetto posseduto dal nemico.",
@ -129,72 +129,71 @@ export const modifierType: ModifierTypeTranslationEntries = {
description: "Aggiunge una probabilità del {{probabilitàPercent}}% di resistere ad un colpo.", description: "Aggiunge una probabilità del {{probabilitàPercent}}% di resistere ad un colpo.",
}, },
"RARE_CANDY": { name: "Caramella Rara" }, "RARE_CANDY": { name: "Caramella rara" },
"RARER_CANDY": { name: "Caramella Molto Rara" }, "RARER_CANDY": { name: "Caramella molto rara" },
"MEGA_BRACELET": { name: "Megapolsiera", description: "Le Megapietre sono disponibili." }, "MEGA_BRACELET": { name: "Megapolsiera", description: "Le megapietre diventano disponibili." },
"DYNAMAX_BAND": { name: "Polsino Dynamax", description: "I Fungomax sono disponibili." }, "DYNAMAX_BAND": { name: "Polsino Dynamax", description: "I fungomax diventano disponibili." },
"TERA_ORB": { name: "Terasfera", description: "I Teraliti sono disponibili." }, "TERA_ORB": { name: "Terasfera", description: "I teraliti diventano disponibili." },
"MAP": { name: "Mappa", description: "Permette di scegliere la propria strada a un bivio." }, "MAP": { name: "Mappa", description: "Permette di scegliere la propria strada a un bivio." },
"POTION": { name: "Pozione" }, "POTION": { name: "Pozione" },
"SUPER_POTION": { name: "Superpozione" }, "SUPER_POTION": { name: "Superpozione" },
"HYPER_POTION": { name: "Iperpozione" }, "HYPER_POTION": { name: "Iperpozione" },
"MAX_POTION": { name: "Pozione Max" }, "MAX_POTION": { name: "Pozione max" },
"FULL_RESTORE": { name: "Ricarica Totale" }, "FULL_RESTORE": { name: "Ricarica totale" },
"REVIVE": { name: "Revitalizzante" }, "REVIVE": { name: "Revitalizzante" },
"MAX_REVIVE": { name: "Revitalizzante Max" }, "MAX_REVIVE": { name: "Revitalizzante max" },
"FULL_HEAL": { name: "Cura Totale" }, "FULL_HEAL": { name: "Cura totale" },
"SACRED_ASH": { name: "Cenere Magica" }, "SACRED_ASH": { name: "Cenere magica" },
"REVIVER_SEED": { name: "Revitalseme", description: "Il possessore recupera 1/2 di PS in caso di svenimento." }, "REVIVER_SEED": { name: "Revitalseme", description: "Il possessore recupera 1/2 di PS in caso di KO." },
"ETHER": { name: "Etere" }, "ETHER": { name: "Etere" },
"MAX_ETHER": { name: "Etere Max" }, "MAX_ETHER": { name: "Etere max" },
"ELIXIR": { name: "Elisir" }, "ELIXIR": { name: "Elisir" },
"MAX_ELIXIR": { name: "Elisir Max" }, "MAX_ELIXIR": { name: "Elisir max" },
"PP_UP": { name: "PP-su" }, "PP_UP": { name: "PP-su" },
"PP_MAX": { name: "PP-max" }, "PP_MAX": { name: "PP-max" },
"LURE": { name: "Profumo Invito" }, "LURE": { name: "Esca" },
"SUPER_LURE": { name: "Profumo Invito Super" }, "SUPER_LURE": { name: "Super esca" },
"MAX_LURE": { name: "Profumo Invito Max" }, "MAX_LURE": { name: "Esca max" },
"MEMORY_MUSHROOM": { name: "Fungo della Memoria", description: "Ricorda la mossa dimenticata di un Pokémon." }, "MEMORY_MUSHROOM": { name: "Fungo della memoria", description: "Permette di insegnare nuovamente una mossa dimenticata ad un Pokémon." },
"EXP_SHARE": { name: "Condividi Esperienza", description: "Tutti i Pokémon della squadra ricevono il 20% dei Punti Esperienza dalla lotta anche se non vi hanno partecipato." }, "EXP_SHARE": { name: "Condividi esperienza", description: "Tutti i Pokémon della squadra ricevono il 20% dei Punti Esperienza dalla lotta, anche se non vi hanno partecipato." },
"EXP_BALANCE": { name: "Bilancia Esperienza", description: "Bilancia i Punti Esperienza ricevuti verso i Pokémon del gruppo di livello inferiore." }, "EXP_BALANCE": { name: "Bilancia esperienza", description: "Bilancia i Punti Esperienza ricevuti verso i Pokémon della squadra di livello inferiore." },
"OVAL_CHARM": { name: "Ovamuleto", description: "Quando più Pokémon partecipano a una battaglia, ognuno di essi riceve il 10% in più dell'esperienza totale." }, "OVAL_CHARM": { name: "Ovamuleto", description: "Quando più Pokémon partecipano a una battaglia, ognuno di essi riceve il 10% in più dell'esperienza totale." },
"EXP_CHARM": { name: "Esperienzamuleto" }, "EXP_CHARM": { name: "Esperienzamuleto" },
"SUPER_EXP_CHARM": { name: "Esperienzamuleto Super" }, "SUPER_EXP_CHARM": { name: "Esperienzamuleto super" },
"GOLDEN_EXP_CHARM": { name: "Esperienzamuleto Oro" }, "GOLDEN_EXP_CHARM": { name: "Esperienzamuleto dorato" },
"LUCKY_EGG": { name: "Uovo Fortunato" }, "LUCKY_EGG": { name: "Fortunuovo" },
"GOLDEN_EGG": { name: "Uovo d'Oro" }, "GOLDEN_EGG": { name: "Uovo dorato" },
"SOOTHE_BELL": { name: "Calmanella" }, "SOOTHE_BELL": { name: "Calmanella" },
"EVIOLITE": { name: "Evolcondensa", description: "Misteriosa materia evolutiva. Aumenta la Difesa e la Difesa Speciale di un Pokémon che può ancora evolversi." }, "EVIOLITE": { name: "Evolcondensa", description: "Misteriosa materia evolutiva. Aumenta la Difesa e la Difesa Speciale di un Pokémon che può ancora evolversi." },
"SOUL_DEW": { name: "Cuorugiada", description: "Aumenta del 10% l'influenza della natura di un Pokémon sulle sue statistiche (Aggiuntivo)." }, "SOUL_DEW": { name: "Cuorugiada", description: "Aumenta del 10% l'influenza della natura di un Pokémon sulle sue statistiche (cumulativo)." },
"NUGGET": { name: "Pepita" }, "NUGGET": { name: "Pepita" },
"BIG_NUGGET": { name: "Granpepita" }, "BIG_NUGGET": { name: "Granpepita" },
"RELIC_GOLD": { name: " Dobloantico" }, "RELIC_GOLD": { name: "Dobloantico" },
"AMULET_COIN": { name: "Monetamuleto", description: "Aumenta le ricompense in denaro del 20%." }, "AMULET_COIN": { name: "Monetamuleto", description: "Aumenta le ricompense in denaro del 20%." },
"GOLDEN_PUNCH": { name: "Pugno Dorato", description: "Garantisce il 50% dei danni inflitti come denaro." }, "GOLDEN_PUNCH": { name: "Pugno dorato", description: "Fornisce il 50% dei danni inflitti sottoforma di denaro." },
"COIN_CASE": { name: " Salvadanaio", description: "Dopo ogni 10° battaglia, riceverete il 10% del vostro denaro in interessi." }, "COIN_CASE": { name: "Salvadanaio", description: "Dopo ogni 10° battaglia, fornisce il 10% del proprio denaro in interessi." },
"LOCK_CAPSULE": { name: "Capsula Scrigno", description: "Permette di bloccare le rarità degli oggetti quando si fa un reroll degli oggetti." }, "LOCK_CAPSULE": { name: "Capsula scrigno", description: "Permette di bloccare le rarità degli oggetti quando si fa un reroll (i costi variano in base alle rarità)." },
"GRIP_CLAW": { name: "Presartigli" }, "GRIP_CLAW": { name: "Presartigli" },
"WIDE_LENS": { name: "Grandelente" }, "WIDE_LENS": { name: "Grandelente" },
@ -202,18 +201,18 @@ export const modifierType: ModifierTypeTranslationEntries = {
"MULTI_LENS": { name: "Multilente" }, "MULTI_LENS": { name: "Multilente" },
"HEALING_CHARM": { name: "Curamuleto", description: "Aumenta del 10% l'efficacia delle mosse e degli oggetti che ripristinano i PS (escluse le rianimazioni)." }, "HEALING_CHARM": { name: "Curamuleto", description: "Aumenta del 10% l'efficacia delle mosse e degli oggetti che ripristinano i PS (escluse le rianimazioni)." },
"CANDY_JAR": { name: "Barattolo di caramelle", description: "Aumenta di 1 il numero di livelli aggiunti dalle Caramelle Rare." }, "CANDY_JAR": { name: "Barattolo di caramelle", description: "Aumenta di 1 il numero di livelli aggiunti dalle caramelle rare." },
"BERRY_POUCH": { name: "Porta Bacche", description: "Aggiunge il 30% di possibilità che una bacca usata non venga consumata." }, "BERRY_POUCH": { name: "Porta bacche", description: "Aggiunge il 30% di possibilità che una bacca usata non venga consumata." },
"FOCUS_BAND": { name: "Bandana", description: "Chi ce l'ha ottiene il 10% di possibilità aggiuntivo di evitare un potenziale KO e rimanere con un solo PS." }, "FOCUS_BAND": { name: "Bandana", description: "Il possessore ottiene il 10% di possibilità aggiuntivo di evitare un potenziale KO e rimanere con un solo PS." },
"QUICK_CLAW": { name: "Rapidartigli", description: "Aggiunge una probabilità del 10% di muoversi per primi, indipendentemente dalla velocità (dopo la priorità)." }, "QUICK_CLAW": { name: "Rapidartigli", description: "Aggiunge una probabilità del 10% di muoversi per primi, indipendentemente dalla velocità (priorità escluse)." },
"KINGS_ROCK": { name: "Roccia di re", description: "Aggiunge il 10% di possibilità che una mossa d'attacco faccia tentennare l'avversario." }, "KINGS_ROCK": { name: "Roccia di re", description: "Aggiunge il 10% di possibilità che una mossa d'attacco faccia tentennare l'avversario." },
"LEFTOVERS": { name: "Avanzi", description: "Ripristina 1/16 dei PS massimi di un Pokémon ogni turno." }, "LEFTOVERS": { name: "Avanzi", description: "Ripristina 1/16 dei PS massimi di un Pokémon ogni turno." },
"SHELL_BELL": { name: "Conchinella", description: "Guarisce 1/8 del danno inflitto a un Pokémon." }, "SHELL_BELL": { name: "Conchinella", description: "Cura il possessore di 1/8 del danno inflitto ad un Pokémon." },
"TOXIC_ORB": { name: "Tossicsfera", description: "Sfera bizzarra che iperavvelena chi lha con sé in una lotta." }, "TOXIC_ORB": { name: "Tossicsfera", description: "Sfera bizzarra che iperavvelena chi lha con sé in una lotta." },
"FLAME_ORB": { name: "Fiammosfera", description: "Sfera bizzarra che procura una scottatura a chi lha con sé in una lotta." }, "FLAME_ORB": { name: "Fiammosfera", description: "Sfera bizzarra che procura una scottatura a chi lha con sé in una lotta." },
@ -223,22 +222,22 @@ export const modifierType: ModifierTypeTranslationEntries = {
"SHINY_CHARM": { name: "Cromamuleto", description: "Misterioso amuleto luminoso che aumenta la probabilità di incontrare Pokémon cromatici." }, "SHINY_CHARM": { name: "Cromamuleto", description: "Misterioso amuleto luminoso che aumenta la probabilità di incontrare Pokémon cromatici." },
"ABILITY_CHARM": { name: "Abilitamuleto", description: "Aumenta drasticamente la possibilità che un Pokémon selvatico abbia un'abilità nascosta." }, "ABILITY_CHARM": { name: "Abilitamuleto", description: "Aumenta drasticamente la possibilità che un Pokémon selvatico abbia un'abilità nascosta." },
"IV_SCANNER": { name: "Scanner IV", description: "Permette di scansionare gli IV dei Pokémon selvatici. Vengono rivelati 2 IV per pila. I migliori IV vengono mostrati per primi." }, "IV_SCANNER": { name: "Scanner IV", description: "Permette di scansionare gli IV dei Pokémon selvatici. Vengono rivelati 2 IV per ogni scanner. I migliori IV vengono mostrati per primi." },
"DNA_SPLICERS": { name: " Cuneo DNA" }, "DNA_SPLICERS": { name: "Cuneo DNA" },
"MINI_BLACK_HOLE": { name: "Piccolo Buco Nero" }, "MINI_BLACK_HOLE": { name: "Piccolo buco nero" },
"GOLDEN_POKEBALL": { name: "Poké Ball Oro", description: "Aggiunge 1 opzione di oggetto extra alla fine di ogni battaglia." }, "GOLDEN_POKEBALL": { name: "Poké Ball dorata", description: "Aggiunge 1 opzione di oggetto extra alla fine di ogni battaglia." },
"ENEMY_DAMAGE_BOOSTER": { name: "Gettone del Danno", description: "Aumenta il danno del 5%." }, "ENEMY_DAMAGE_BOOSTER": { name: "Gettone del danno", description: "Aumenta i danni inflitti del 5%." },
"ENEMY_DAMAGE_REDUCTION": { name: "Gettone della Protezione", description: "Riduce i danni ricevuti del 2.5%." }, "ENEMY_DAMAGE_REDUCTION": { name: "Gettone della protezione", description: "Riduce i danni ricevuti del 2.5%." },
"ENEMY_HEAL": { name: "Gettone del Recupero", description: "Cura il 2% dei PS massimi ogni turno." }, "ENEMY_HEAL": { name: "Gettone del recupero", description: "Cura il 2% dei PS massimi ogni turno." },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Gettone del Veleno" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Gettone del veleno" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Gettone della Paralisi" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Gettone della paralisi" },
"ENEMY_ATTACK_BURN_CHANCE": { name: "Gettone della Bruciatura" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Gettone della bruciatura" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Gettone Guarigione Completa", description: "Aggiunge una probabilità del 2.5% a ogni turno di curare una condizione di stato." }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Gettone guarigione completa", description: "Aggiunge una probabilità del 2.5% a ogni turno di guarire da un problema di stato." },
"ENEMY_ENDURE_CHANCE": { name: "Gettone di Resistenza" }, "ENEMY_ENDURE_CHANCE": { name: "Gettone di resistenza" },
"ENEMY_FUSED_CHANCE": { name: "Gettone della fusione", description: "Aggiunge l'1% di possibilità che un Pokémon selvatico sia una fusione." }, "ENEMY_FUSED_CHANCE": { name: "Gettone della fusione", description: "Aggiunge l'1% di possibilità che un Pokémon selvatico sia una fusione." },
}, },
SpeciesBoosterItem: { SpeciesBoosterItem: {
@ -258,14 +257,14 @@ export const modifierType: ModifierTypeTranslationEntries = {
}, },
TempBattleStatBoosterStatName: { TempBattleStatBoosterStatName: {
"ATK": "Attack", "ATK": "Attacco",
"DEF": "Defense", "DEF": "Difesa",
"SPATK": "Sp. Atk", "SPATK": "Att. Speciale",
"SPDEF": "Sp. Def", "SPDEF": "Dif. Speciale",
"SPD": "Speed", "SPD": "Velocità",
"ACC": "Accuracy", "ACC": "Precisione",
"CRIT": "Critical Hit Ratio", "CRIT": "Tasso di brutti colpi",
"EVA": "Evasiveness", "EVA": "Elusione",
"DEFAULT": "???", "DEFAULT": "???",
}, },

View File

@ -40,5 +40,6 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "È apparsa una corrente d'aria misteriosa!", "strongWindsStartMessage": "È apparsa una corrente d'aria misteriosa!",
"strongWindsLapseMessage": "La corrente d'aria soffia intensamente.", "strongWindsLapseMessage": "La corrente d'aria soffia intensamente.",
"strongWindsEffectMessage": "La corrente misteriosa indebolisce lattacco!",
"strongWindsClearMessage": "La corrente d'aria è cessata." "strongWindsClearMessage": "La corrente d'aria è cessata."
}; };

View File

@ -24,7 +24,8 @@ export const battle: SimpleTranslationEntries = {
"hitResultNotVeryEffective": "효과가 별로인 듯하다…", "hitResultNotVeryEffective": "효과가 별로인 듯하다…",
"hitResultNoEffect": "{{pokemonName}}에게는\n효과가 없는 것 같다…", "hitResultNoEffect": "{{pokemonName}}에게는\n효과가 없는 것 같다…",
"hitResultOneHitKO": "일격필살!", "hitResultOneHitKO": "일격필살!",
"attackFailed": "하지만 실패했다!", "attackFailed": "그러나 실패하고 말았다!!",
"attackMissed": "{{pokemonNameWithAffix}}에게는\n맞지 않았다!",
"attackHitsCount": "{{count}}번 맞았다!", "attackHitsCount": "{{count}}번 맞았다!",
"rewardGain": "{{modifierName}}[[를]] 받았다!", "rewardGain": "{{modifierName}}[[를]] 받았다!",
"expGain": "{{pokemonName}}[[는]]\n{{exp}} 경험치를 얻었다!", "expGain": "{{pokemonName}}[[는]]\n{{exp}} 경험치를 얻었다!",

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const bgmName: SimpleTranslationEntries = { export const bgmName: SimpleTranslationEntries = {
"music": "Music", "music": "Music: ",
"missing_entries" : "{{name}}", "missing_entries" : "{{name}}",
"battle_kanto_champion": "BW2 관동 챔피언 배틀", "battle_kanto_champion": "BW2 관동 챔피언 배틀",
"battle_johto_champion": "BW2 성도 챔피언 배틀", "battle_johto_champion": "BW2 성도 챔피언 배틀",
@ -62,7 +62,7 @@ export const bgmName: SimpleTranslationEntries = {
"battle_legendary_calyrex": "SWSH 버드렉스 배틀", "battle_legendary_calyrex": "SWSH 버드렉스 배틀",
"battle_legendary_birds_galar": "SWSH 가라르 전설의 새 배틀", "battle_legendary_birds_galar": "SWSH 가라르 전설의 새 배틀",
"battle_legendary_ruinous": "SV 재앙의 보물 배틀", "battle_legendary_ruinous": "SV 재앙의 보물 배틀",
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle", "battle_legendary_kor_mir": "SV 에리어 제로 배틀",
"battle_legendary_loyal_three": "SV 세벗들 배틀", "battle_legendary_loyal_three": "SV 세벗들 배틀",
"battle_legendary_ogerpon": "SV 오거폰 배틀", "battle_legendary_ogerpon": "SV 오거폰 배틀",
"battle_legendary_terapagos": "SV 테라파고스 배틀", "battle_legendary_terapagos": "SV 테라파고스 배틀",
@ -74,16 +74,16 @@ export const bgmName: SimpleTranslationEntries = {
"battle_wild": "BW 야생 포켓몬 배틀", "battle_wild": "BW 야생 포켓몬 배틀",
"battle_wild_strong": "BW 강한 야생 포켓몬 조우 배틀", "battle_wild_strong": "BW 강한 야생 포켓몬 조우 배틀",
"end_summit": "불가사의 던전 구조대 DX 천공의 탑 꼭대기", "end_summit": "불가사의 던전 구조대 DX 천공의 탑 꼭대기",
"battle_rocket_grunt": "HGSS Team Rocket Battle", "battle_rocket_grunt": "HGSS 로켓단 배틀",
"battle_aqua_magma_grunt": "ORAS Team Aqua & Magma Battle", "battle_aqua_magma_grunt": "ORAS 아쿠아단 & 마그마단 배틀",
"battle_galactic_grunt": "BDSP Team Galactic Battle", "battle_galactic_grunt": "BDSP 갤럭시단 배틀",
"battle_plasma_grunt": "BW 플라스마단 배틀", "battle_plasma_grunt": "BW 플라스마단 배틀",
"battle_flare_grunt": "XY Team Flare Battle", "battle_flare_grunt": "XY 플레어단 배틀",
"battle_rocket_boss": "USUM Giovanni Battle", "battle_rocket_boss": "USUM 비주기 배틀",
"battle_aqua_magma_boss": "ORAS Archie & Maxie Battle", "battle_aqua_magma_boss": "ORAS 아강 & 마적 배틀",
"battle_galactic_boss": "BDSP Cyrus Battle", "battle_galactic_boss": "BDSP 태홍 배틀",
"battle_plasma_boss": "B2W2 Ghetsis Battle", "battle_plasma_boss": "B2W2 게치스 배틀",
"battle_flare_boss": "XY Lysandre Battle", "battle_flare_boss": "XY 플라드리 배틀",
// Biome Music // Biome Music
"abyss": "불가사의 던전 하늘의 탐험대 어둠의 화구", "abyss": "불가사의 던전 하늘의 탐험대 어둠의 화구",

View File

@ -2,7 +2,7 @@ import { TranslationEntries } from "#app/interfaces/locales";
export const challenges: TranslationEntries = { export const challenges: TranslationEntries = {
"title": "챌린지 조건 설정", "title": "챌린지 조건 설정",
"illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", "illegalEvolution": "{{pokemon}}[[는]] 현재의 챌린지에\n부적합한 포켓몬이 되었습니다!",
"singleGeneration": { "singleGeneration": {
"name": "단일 세대", "name": "단일 세대",
"desc": "{{gen}}의 포켓몬만 사용할 수 있습니다.", "desc": "{{gen}}의 포켓몬만 사용할 수 있습니다.",

View File

@ -20,5 +20,5 @@ export const menuUiHandler: SimpleTranslationEntries = {
"exportData": "데이터 내보내기", "exportData": "데이터 내보내기",
"cancel": "취소", "cancel": "취소",
"losingProgressionWarning": "전투 시작으로부터의 진행 상황을 잃게 됩니다. 계속하시겠습니까?", "losingProgressionWarning": "전투 시작으로부터의 진행 상황을 잃게 됩니다. 계속하시겠습니까?",
"noEggs": "You are not hatching\nany eggs at the moment!" "noEggs": "부화중인 알이 없습니다!"
} as const; } as const;

View File

@ -35,8 +35,8 @@ export const partyUiHandler: SimpleTranslationEntries = {
"cancel": "그만둔다", "cancel": "그만둔다",
// Slot TM text // Slot TM text
"able": "배울 수 있다", "able": "배운다!",
"notAble": "배울 수 없다", "notAble": "배우지 못함",
"learned": "알고 있다", "learned": "알고 있다",
// Releasing messages // Releasing messages

View File

@ -41,5 +41,6 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "수수께끼의 난기류가\n비행포켓몬을 지킨다!", "strongWindsStartMessage": "수수께끼의 난기류가\n비행포켓몬을 지킨다!",
"strongWindsLapseMessage": "수수께끼의 난기류가 강렬하게 불고 있다", "strongWindsLapseMessage": "수수께끼의 난기류가 강렬하게 불고 있다",
"strongWindsEffectMessage": "수수께끼의 난기류가 공격을 약하게 만들었다!",
"strongWindsClearMessage": "수수께끼의 난기류가 멈췄다!" // 임의번역 "strongWindsClearMessage": "수수께끼의 난기류가 멈췄다!" // 임의번역
}; };

View File

@ -25,6 +25,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "Isso não afeta {{pokemonName}}!", "hitResultNoEffect": "Isso não afeta {{pokemonName}}!",
"hitResultOneHitKO": "Foi um nocaute de um golpe!", "hitResultOneHitKO": "Foi um nocaute de um golpe!",
"attackFailed": "Mas falhou!", "attackFailed": "Mas falhou!",
"attackMissed": "{{pokemonNameWithAffix}} desviou do ataque!",
"attackHitsCount": "Acertou {{count}} vezes.", "attackHitsCount": "Acertou {{count}} vezes.",
"rewardGain": "Você recebeu\n{{modifierName}}!", "rewardGain": "Você recebeu\n{{modifierName}}!",
"expGain": "{{pokemonName}} ganhou\n{{exp}} pontos de experiência.", "expGain": "{{pokemonName}} ganhou\n{{exp}} pontos de experiência.",

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const bgmName: SimpleTranslationEntries = { export const bgmName: SimpleTranslationEntries = {
"music": "Music", "music": "Music: ",
"missing_entries" : "{{name}}", "missing_entries" : "{{name}}",
"battle_kanto_champion": "B2W2 Kanto Champion Battle", "battle_kanto_champion": "B2W2 Kanto Champion Battle",
"battle_johto_champion": "B2W2 Johto Champion Battle", "battle_johto_champion": "B2W2 Johto Champion Battle",

View File

@ -40,5 +40,6 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "Ventos fortes apareceram!", "strongWindsStartMessage": "Ventos fortes apareceram!",
"strongWindsLapseMessage": "Os ventos fortes continuam.", "strongWindsLapseMessage": "Os ventos fortes continuam.",
"strongWindsEffectMessage": "The mysterious air current weakened the attack!",
"strongWindsClearMessage": "Os ventos fortes diminuíram.", "strongWindsClearMessage": "Os ventos fortes diminuíram.",
}; };

View File

@ -25,6 +25,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "对{{pokemonName}}没有效果!!", "hitResultNoEffect": "对{{pokemonName}}没有效果!!",
"hitResultOneHitKO": "一击必杀!", "hitResultOneHitKO": "一击必杀!",
"attackFailed": "但是失败了!", "attackFailed": "但是失败了!",
"attackMissed": "没有命中{{pokemonNameWithAffix}}",
"attackHitsCount": "击中{{count}}次!", "attackHitsCount": "击中{{count}}次!",
"rewardGain": "你获得了\n{{modifierName}}", "rewardGain": "你获得了\n{{modifierName}}",
"expGain": "{{pokemonName}}获得了 {{exp}} 点经验值!", "expGain": "{{pokemonName}}获得了 {{exp}} 点经验值!",

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const bgmName: SimpleTranslationEntries = { export const bgmName: SimpleTranslationEntries = {
"music": "BGM", "music": "BGM: ",
"missing_entries" : "{{name}}", "missing_entries" : "{{name}}",
"battle_kanto_champion": "黑2白2「决战关都冠军」", "battle_kanto_champion": "黑2白2「决战关都冠军」",
"battle_johto_champion": "黑2白2「决战城都冠军」", "battle_johto_champion": "黑2白2「决战城都冠军」",

View File

@ -14,7 +14,7 @@ export const partyUiHandler: SimpleTranslationEntries = {
"TRANSFER": "交换", "TRANSFER": "交换",
"ALL": "全部道具", "ALL": "全部道具",
"PASS_BATON": "接棒", "PASS_BATON": "接棒",
"UNPAUSE_EVOLUTION": "接触进化暂停", "UNPAUSE_EVOLUTION": "解除进化暂停",
"REVIVE": "复活", "REVIVE": "复活",
"choosePokemon": "选择一只宝可梦。", "choosePokemon": "选择一只宝可梦。",

View File

@ -40,5 +40,6 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "吹起了神秘的乱流!", "strongWindsStartMessage": "吹起了神秘的乱流!",
"strongWindsLapseMessage": "神秘的乱流势头不减。", "strongWindsLapseMessage": "神秘的乱流势头不减。",
"strongWindsEffectMessage": "The mysterious air current weakened the attack!",
"strongWindsClearMessage": "神秘的乱流停止了。" "strongWindsClearMessage": "神秘的乱流停止了。"
}; };

View File

@ -22,6 +22,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "對 {{pokemonName}} 沒有效果!", "hitResultNoEffect": "對 {{pokemonName}} 沒有效果!",
"hitResultOneHitKO": "一擊切殺!", "hitResultOneHitKO": "一擊切殺!",
"attackFailed": "但是失敗了!", "attackFailed": "但是失敗了!",
"attackMissed": "沒有命中{{pokemonNameWithAffix}}",
"attackHitsCount": "擊中 {{count}} 次!", "attackHitsCount": "擊中 {{count}} 次!",
"rewardGain": "You received\n{{modifierName}}!", "rewardGain": "You received\n{{modifierName}}!",
"expGain": "{{pokemonName}} 獲得了 {{exp}} 經驗值!", "expGain": "{{pokemonName}} 獲得了 {{exp}} 經驗值!",

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/interfaces/locales"; import { SimpleTranslationEntries } from "#app/interfaces/locales";
export const bgmName: SimpleTranslationEntries = { export const bgmName: SimpleTranslationEntries = {
"music": "Music", "music": "Music: ",
"missing_entries" : "{{name}}", "missing_entries" : "{{name}}",
"battle_kanto_champion": "B2W2 Kanto Champion Battle", "battle_kanto_champion": "B2W2 Kanto Champion Battle",
"battle_johto_champion": "B2W2 Johto Champion Battle", "battle_johto_champion": "B2W2 Johto Champion Battle",

View File

@ -40,5 +40,6 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "吹起了神秘的亂流!", "strongWindsStartMessage": "吹起了神秘的亂流!",
"strongWindsLapseMessage": "神秘的亂流勢頭不減。", "strongWindsLapseMessage": "神秘的亂流勢頭不減。",
"strongWindsEffectMessage": "The mysterious air current weakened the attack!",
"strongWindsClearMessage": "神秘的亂流停止了。" "strongWindsClearMessage": "神秘的亂流停止了。"
}; };

View File

@ -2894,7 +2894,7 @@ export class MoveEffectPhase extends PokemonPhase {
if (!activeTargets.length || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]])) { if (!activeTargets.length || (!move.hasAttr(VariableTargetAttr) && !move.isMultiTarget() && !targetHitChecks[this.targets[0]])) {
this.stopMultiHit(); this.stopMultiHit();
if (activeTargets.length) { if (activeTargets.length) {
this.scene.queueMessage(getPokemonMessage(user, "'s\nattack missed!")); this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(this.getTarget()) }));
moveHistoryEntry.result = MoveResult.MISS; moveHistoryEntry.result = MoveResult.MISS;
applyMoveAttrs(MissEffectAttr, user, null, move); applyMoveAttrs(MissEffectAttr, user, null, move);
} else { } else {
@ -2912,7 +2912,7 @@ export class MoveEffectPhase extends PokemonPhase {
for (const target of targets) { for (const target of targets) {
if (!targetHitChecks[target.getBattlerIndex()]) { if (!targetHitChecks[target.getBattlerIndex()]) {
this.stopMultiHit(target); this.stopMultiHit(target);
this.scene.queueMessage(getPokemonMessage(user, "'s\nattack missed!")); this.scene.queueMessage(i18next.t("battle:attackMissed", { pokemonNameWithAffix: getPokemonNameWithAffix(target) }));
if (moveHistoryEntry.result === MoveResult.PENDING) { if (moveHistoryEntry.result === MoveResult.PENDING) {
moveHistoryEntry.result = MoveResult.MISS; moveHistoryEntry.result = MoveResult.MISS;
} }
@ -3616,7 +3616,9 @@ export class DamagePhase extends PokemonPhase {
super.start(); super.start();
if (this.damageResult === HitResult.ONE_HIT_KO) { if (this.damageResult === HitResult.ONE_HIT_KO) {
this.scene.toggleInvert(true); if (this.scene.moveAnimations) {
this.scene.toggleInvert(true);
}
this.scene.time.delayedCall(Utils.fixedInt(1000), () => { this.scene.time.delayedCall(Utils.fixedInt(1000), () => {
this.scene.toggleInvert(false); this.scene.toggleInvert(false);
this.applyDamage(); this.applyDamage();

View File

@ -316,10 +316,10 @@ export const achvs = {
CATCH_LEGENDARY: new Achv("CATCH_LEGENDARY", "", "CATCH_LEGENDARY.description","mb", 100).setSecret(), CATCH_LEGENDARY: new Achv("CATCH_LEGENDARY", "", "CATCH_LEGENDARY.description","mb", 100).setSecret(),
SEE_SHINY: new Achv("SEE_SHINY", "", "SEE_SHINY.description","pb_gold", 75), SEE_SHINY: new Achv("SEE_SHINY", "", "SEE_SHINY.description","pb_gold", 75),
SHINY_PARTY: new Achv("SHINY_PARTY", "", "SHINY_PARTY.description","shiny_charm", 100).setSecret(true), SHINY_PARTY: new Achv("SHINY_PARTY", "", "SHINY_PARTY.description","shiny_charm", 100).setSecret(true),
HATCH_MYTHICAL: new Achv("HATCH_MYTHICAL", "", "HATCH_MYTHICAL.description","pair_of_tickets", 75).setSecret(), HATCH_MYTHICAL: new Achv("HATCH_MYTHICAL", "", "HATCH_MYTHICAL.description","mystery_egg", 75).setSecret(),
HATCH_SUB_LEGENDARY: new Achv("HATCH_SUB_LEGENDARY","", "HATCH_SUB_LEGENDARY.description","mystic_ticket", 100).setSecret(), HATCH_SUB_LEGENDARY: new Achv("HATCH_SUB_LEGENDARY","", "HATCH_SUB_LEGENDARY.description","oval_stone", 100).setSecret(),
HATCH_LEGENDARY: new Achv("HATCH_LEGENDARY","", "HATCH_LEGENDARY.description","mystic_ticket", 125).setSecret(), HATCH_LEGENDARY: new Achv("HATCH_LEGENDARY","", "HATCH_LEGENDARY.description","lucky_egg", 125).setSecret(),
HATCH_SHINY: new Achv("HATCH_SHINY","", "HATCH_SHINY.description","golden_mystic_ticket", 100).setSecret(), HATCH_SHINY: new Achv("HATCH_SHINY","", "HATCH_SHINY.description","golden_egg", 100).setSecret(),
HIDDEN_ABILITY: new Achv("HIDDEN_ABILITY","", "HIDDEN_ABILITY.description","ability_charm", 75), HIDDEN_ABILITY: new Achv("HIDDEN_ABILITY","", "HIDDEN_ABILITY.description","ability_charm", 75),
PERFECT_IVS: new Achv("PERFECT_IVS","", "PERFECT_IVS.description","blunder_policy", 100), PERFECT_IVS: new Achv("PERFECT_IVS","", "PERFECT_IVS.description","blunder_policy", 100),
CLASSIC_VICTORY: new Achv("CLASSIC_VICTORY","", "CLASSIC_VICTORY.description","relic_crown", 150), CLASSIC_VICTORY: new Achv("CLASSIC_VICTORY","", "CLASSIC_VICTORY.description","relic_crown", 150),

View File

@ -0,0 +1,82 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import Phaser from "phaser";
import GameManager from "#app/test/utils/gameManager";
import * as overrides from "#app/overrides";
import { Species } from "#enums/species";
import {
TurnStartPhase,
} from "#app/phases";
import { Moves } from "#enums/moves";
import { getMovePosition } from "#app/test/utils/gameManagerUtils";
import { Abilities } from "#enums/abilities";
import { allMoves } from "#app/data/move.js";
describe("Weather - Strong Winds", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(10);
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.TAILLOW);
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.DELTA_STREAM);
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.THUNDERBOLT, Moves.ICE_BEAM, Moves.ROCK_SLIDE]);
});
it("electric type move is not very effective on Rayquaza", async () => {
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.RAYQUAZA);
await game.startBattle([Species.PIKACHU]);
const pikachu = game.scene.getPlayerPokemon();
const enemy = game.scene.getEnemyPokemon();
game.doAttack(getMovePosition(game.scene, 0, Moves.THUNDERBOLT));
await game.phaseInterceptor.to(TurnStartPhase);
expect(enemy.getAttackTypeEffectiveness(allMoves[Moves.THUNDERBOLT].type, pikachu)).toBe(0.5);
});
it("electric type move is neutral for flying type pokemon", async () => {
await game.startBattle([Species.PIKACHU]);
const pikachu = game.scene.getPlayerPokemon();
const enemy = game.scene.getEnemyPokemon();
game.doAttack(getMovePosition(game.scene, 0, Moves.THUNDERBOLT));
await game.phaseInterceptor.to(TurnStartPhase);
expect(enemy.getAttackTypeEffectiveness(allMoves[Moves.THUNDERBOLT].type, pikachu)).toBe(1);
});
it("ice type move is neutral for flying type pokemon", async () => {
await game.startBattle([Species.PIKACHU]);
const pikachu = game.scene.getPlayerPokemon();
const enemy = game.scene.getEnemyPokemon();
game.doAttack(getMovePosition(game.scene, 0, Moves.ICE_BEAM));
await game.phaseInterceptor.to(TurnStartPhase);
expect(enemy.getAttackTypeEffectiveness(allMoves[Moves.ICE_BEAM].type, pikachu)).toBe(1);
});
it("rock type move is neutral for flying type pokemon", async () => {
await game.startBattle([Species.PIKACHU]);
const pikachu = game.scene.getPlayerPokemon();
const enemy = game.scene.getEnemyPokemon();
game.doAttack(getMovePosition(game.scene, 0, Moves.ROCK_SLIDE));
await game.phaseInterceptor.to(TurnStartPhase);
expect(enemy.getAttackTypeEffectiveness(allMoves[Moves.ROCK_SLIDE].type, pikachu)).toBe(1);
});
});

View File

@ -0,0 +1,149 @@
import {
BattleStat,
getBattleStatLevelChangeDescription,
getBattleStatName,
} from "#app/data/battle-stat.js";
import { describe, expect, it } from "vitest";
import { arrayOfRange, mockI18next } from "./utils/testUtils";
const TEST_BATTLE_STAT = -99 as unknown as BattleStat;
const TEST_POKEMON = "Testmon";
const TEST_STAT = "Teststat";
describe("battle-stat", () => {
describe("getBattleStatName", () => {
it("should return the correct name for each BattleStat", () => {
mockI18next();
expect(getBattleStatName(BattleStat.ATK)).toBe("pokemonInfo:Stat.ATK");
expect(getBattleStatName(BattleStat.DEF)).toBe("pokemonInfo:Stat.DEF");
expect(getBattleStatName(BattleStat.SPATK)).toBe(
"pokemonInfo:Stat.SPATK"
);
expect(getBattleStatName(BattleStat.SPDEF)).toBe(
"pokemonInfo:Stat.SPDEF"
);
expect(getBattleStatName(BattleStat.SPD)).toBe("pokemonInfo:Stat.SPD");
expect(getBattleStatName(BattleStat.ACC)).toBe("pokemonInfo:Stat.ACC");
expect(getBattleStatName(BattleStat.EVA)).toBe("pokemonInfo:Stat.EVA");
});
it("should fall back to ??? for an unknown BattleStat", () => {
expect(getBattleStatName(TEST_BATTLE_STAT)).toBe("???");
});
});
describe("getBattleStatLevelChangeDescription", () => {
it("should return battle:statRose for +1", () => {
mockI18next();
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
1,
true
);
expect(message).toBe("battle:statRose");
});
it("should return battle:statSharplyRose for +2", () => {
mockI18next();
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
2,
true
);
expect(message).toBe("battle:statSharplyRose");
});
it("should return battle:statRoseDrastically for +3 to +6", () => {
mockI18next();
arrayOfRange(3, 6).forEach((n) => {
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
n,
true
);
expect(message).toBe("battle:statRoseDrastically");
});
});
it("should return battle:statWontGoAnyHigher for 7 or higher", () => {
mockI18next();
arrayOfRange(7, 10).forEach((n) => {
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
n,
true
);
expect(message).toBe("battle:statWontGoAnyHigher");
});
});
it("should return battle:statFell for -1", () => {
mockI18next();
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
1,
false
);
expect(message).toBe("battle:statFell");
});
it("should return battle:statHarshlyFell for -2", () => {
mockI18next();
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
2,
false
);
expect(message).toBe("battle:statHarshlyFell");
});
it("should return battle:statSeverelyFell for -3 to -6", () => {
mockI18next();
arrayOfRange(3, 6).forEach((n) => {
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
n,
false
);
expect(message).toBe("battle:statSeverelyFell");
});
});
it("should return battle:statWontGoAnyLower for -7 or lower", () => {
mockI18next();
arrayOfRange(7, 10).forEach((n) => {
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
n,
false
);
expect(message).toBe("battle:statWontGoAnyLower");
});
});
});
});

View File

@ -7,9 +7,9 @@ import {
getStatusEffectObtainText, getStatusEffectObtainText,
getStatusEffectOverlapText, getStatusEffectOverlapText,
} from "#app/data/status-effect"; } from "#app/data/status-effect";
import i18next, { ParseKeys } from "i18next"; import i18next from "i18next";
import { mockI18next } from "../utils/testUtils";
const tMock = (key: ParseKeys) => key;
const pokemonName = "PKM"; const pokemonName = "PKM";
const sourceText = "SOURCE"; const sourceText = "SOURCE";
@ -22,7 +22,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.NONE; const statusEffect = StatusEffect.NONE;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:none.obtain"); expect(text).toBe("statusEffect:none.obtain");
@ -32,7 +32,7 @@ describe("status-effect", () => {
}); });
it("should return the source-obtain text", () => { it("should return the source-obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName, sourceText); const text = getStatusEffectObtainText(statusEffect, pokemonName, sourceText);
expect(text).toBe("statusEffect:none.obtainSource"); expect(text).toBe("statusEffect:none.obtainSource");
@ -42,25 +42,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:none.activation"); expect(text).toBe("statusEffect:none.activation");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:none.overlap"); expect(text).toBe("statusEffect:none.overlap");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:none.heal"); expect(text).toBe("statusEffect:none.heal");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:none.description"); expect(text).toBe("statusEffect:none.description");
}); });
@ -70,7 +70,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.POISON; const statusEffect = StatusEffect.POISON;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:poison.obtain"); expect(text).toBe("statusEffect:poison.obtain");
@ -80,25 +80,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:poison.activation"); expect(text).toBe("statusEffect:poison.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:poison.description"); expect(text).toBe("statusEffect:poison.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:poison.heal"); expect(text).toBe("statusEffect:poison.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:poison.overlap"); expect(text).toBe("statusEffect:poison.overlap");
}); });
@ -108,7 +108,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.TOXIC; const statusEffect = StatusEffect.TOXIC;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:toxic.obtain"); expect(text).toBe("statusEffect:toxic.obtain");
@ -118,25 +118,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:toxic.activation"); expect(text).toBe("statusEffect:toxic.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:toxic.description"); expect(text).toBe("statusEffect:toxic.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:toxic.heal"); expect(text).toBe("statusEffect:toxic.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:toxic.overlap"); expect(text).toBe("statusEffect:toxic.overlap");
}); });
@ -146,7 +146,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.PARALYSIS; const statusEffect = StatusEffect.PARALYSIS;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:paralysis.obtain"); expect(text).toBe("statusEffect:paralysis.obtain");
@ -156,25 +156,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:paralysis.activation"); expect(text).toBe("statusEffect:paralysis.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:paralysis.description"); expect(text).toBe("statusEffect:paralysis.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:paralysis.heal"); expect(text).toBe("statusEffect:paralysis.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:paralysis.overlap"); expect(text).toBe("statusEffect:paralysis.overlap");
}); });
@ -184,7 +184,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.SLEEP; const statusEffect = StatusEffect.SLEEP;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:sleep.obtain"); expect(text).toBe("statusEffect:sleep.obtain");
@ -194,25 +194,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:sleep.activation"); expect(text).toBe("statusEffect:sleep.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:sleep.description"); expect(text).toBe("statusEffect:sleep.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:sleep.heal"); expect(text).toBe("statusEffect:sleep.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:sleep.overlap"); expect(text).toBe("statusEffect:sleep.overlap");
}); });
@ -222,7 +222,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.FREEZE; const statusEffect = StatusEffect.FREEZE;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:freeze.obtain"); expect(text).toBe("statusEffect:freeze.obtain");
@ -232,25 +232,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:freeze.activation"); expect(text).toBe("statusEffect:freeze.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:freeze.description"); expect(text).toBe("statusEffect:freeze.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:freeze.heal"); expect(text).toBe("statusEffect:freeze.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:freeze.overlap"); expect(text).toBe("statusEffect:freeze.overlap");
}); });
@ -260,7 +260,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.BURN; const statusEffect = StatusEffect.BURN;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:burn.obtain"); expect(text).toBe("statusEffect:burn.obtain");
@ -270,25 +270,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:burn.activation"); expect(text).toBe("statusEffect:burn.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:burn.description"); expect(text).toBe("statusEffect:burn.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:burn.heal"); expect(text).toBe("statusEffect:burn.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:burn.overlap"); expect(text).toBe("statusEffect:burn.overlap");
}); });

View File

@ -0,0 +1,83 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import Phaser from "phaser";
import GameManager from "#app/test/utils/gameManager";
import * as overrides from "#app/overrides";
import { Species } from "#enums/species";
import {
MoveEffectPhase,
} from "#app/phases";
import { Moves } from "#enums/moves";
import { getMovePosition } from "#app/test/utils/gameManagerUtils";
import { Abilities } from "#enums/abilities";
import { NumberHolder } from "#app/utils.js";
import Move from "#app/data/move.js";
import Pokemon from "#app/field/pokemon.js";
import { allMoves, OpponentHighHpPowerAttr } from "#app/data/move.js";
describe("Moves - Hard Press", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.SNORLAX);
vi.spyOn(overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.NONE);
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.HARD_PRESS]);
});
it("power varies between 1 and 100, and is greater the more HP the target has", async () => {
await game.startBattle([Species.GRAVELER]);
const moveToBeUsed = allMoves[Moves.HARD_PRESS];
game.doAttack(getMovePosition(game.scene, 0, moveToBeUsed));
await game.phaseInterceptor.to(MoveEffectPhase);
const enemy = game.scene.getEnemyPokemon();
const movePower = getMockedMovePower(enemy, game.scene.getPlayerPokemon(), moveToBeUsed);
const moveMaxBasePower = getMoveMaxBasePower(moveToBeUsed);
expect(movePower).toBe(moveMaxBasePower * enemy.getHpRatio());
});
});
/**
* Calculates the mocked move power based on the attributes of the move and the opponent's high HP.
*
* @param defender - The defending Pokémon.
* @param attacker - The attacking Pokémon.
* @param move - The move being used.
* @returns The calculated move power.
*/
const getMockedMovePower = (defender: Pokemon, attacker: Pokemon, move: Move) => {
const powerHolder = new NumberHolder(move.power);
if (move.hasAttr(OpponentHighHpPowerAttr)) {
const attr = move.getAttrs(OpponentHighHpPowerAttr);
attr[0].apply(attacker, defender, move, [ powerHolder ]);
}
return powerHolder.value;
};
/**
* Retrieves the maximum base power of a move based on its attributes.
*
* @param move - The move which maximum base power is being retrieved.
* @returns The maximum base power of the move.
*/
const getMoveMaxBasePower = (move: Move) => {
const attr = move.getAttrs(OpponentHighHpPowerAttr);
return (attr[0] as OpponentHighHpPowerAttr)["maxBasePower"];
};

View File

@ -0,0 +1,100 @@
import { BerryType } from "#app/enums/berry-type";
import { Moves } from "#app/enums/moves";
import { Species } from "#app/enums/species";
import { Button } from "#app/enums/buttons";
import * as overrides from "#app/overrides";
import {
BattleEndPhase,
SelectModifierPhase
} from "#app/phases";
import GameManager from "#app/test/utils/gameManager";
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
import PartyUiHandler, { PartyUiMode } from "#app/ui/party-ui-handler";
import { Mode } from "#app/ui/ui";
import Phaser from "phaser";
import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { getMovePosition } from "../utils/gameManagerUtils";
describe("UI - Transfer Items", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(async () => {
game = new GameManager(phaserGame);
vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true);
vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100);
vi.spyOn(overrides, "STARTING_WAVE_OVERRIDE", "get").mockReturnValue(1);
vi.spyOn(overrides, "STARTING_HELD_ITEMS_OVERRIDE", "get").mockReturnValue([
{ name: "BERRY", count: 1, type: BerryType.SITRUS },
{ name: "BERRY", count: 2, type: BerryType.APICOT },
{ name: "BERRY", count: 2, type: BerryType.LUM },
]);
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.DRAGON_CLAW]);
vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP);
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH]);
await game.startBattle([Species.RAYQUAZA, Species.RAYQUAZA, Species.RAYQUAZA]);
game.doAttack(getMovePosition(game.scene, 0, Moves.DRAGON_CLAW));
game.onNextPrompt("SelectModifierPhase", Mode.MODIFIER_SELECT, () => {
expect(game.scene.ui.getHandler()).toBeInstanceOf(ModifierSelectUiHandler);
const handler = game.scene.ui.getHandler() as ModifierSelectUiHandler;
handler.setCursor(1);
handler.processInput(Button.ACTION);
game.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER);
});
await game.phaseInterceptor.to(BattleEndPhase);
});
it("check red tint for held item limit in transfer menu", async () => {
game.onNextPrompt("SelectModifierPhase", Mode.PARTY, () => {
expect(game.scene.ui.getHandler()).toBeInstanceOf(PartyUiHandler);
const handler = game.scene.ui.getHandler() as PartyUiHandler;
handler.processInput(Button.ACTION);
expect(handler.optionsContainer.list.some((option) => (option as BBCodeText).text?.includes("Sitrus Berry"))).toBe(true);
expect(handler.optionsContainer.list.some((option) => (option as BBCodeText).text?.includes("Apicot Berry (2)"))).toBe(true);
expect(handler.optionsContainer.list.some((option) => RegExp(/Lum Berry\[color.*(2)/).exec((option as BBCodeText).text))).toBe(true);
game.phaseInterceptor.unlock();
});
await game.phaseInterceptor.to(SelectModifierPhase);
}, 20000);
it("check transfer option for pokemon to transfer to", async () => {
game.onNextPrompt("SelectModifierPhase", Mode.PARTY, () => {
expect(game.scene.ui.getHandler()).toBeInstanceOf(PartyUiHandler);
const handler = game.scene.ui.getHandler() as PartyUiHandler;
handler.processInput(Button.ACTION); // select Pokemon
handler.processInput(Button.ACTION); // select held item (Sitrus Berry)
handler.setCursor(1); // move to other Pokemon
handler.processInput(Button.ACTION); // select Pokemon
expect(handler.optionsContainer.list.some((option) => (option as BBCodeText).text?.includes("Transfer"))).toBe(true);
game.phaseInterceptor.unlock();
});
await game.phaseInterceptor.to(SelectModifierPhase);
}, 20000);
});

View File

@ -0,0 +1,23 @@
import i18next, { type ParseKeys } from "i18next";
import { vi } from "vitest";
/**
* Sets up the i18next mock.
* Includes a i18next.t mocked implementation only returning the raw key (`(key) => key`)
*
* @returns A spy/mock of i18next
*/
export function mockI18next() {
return vi.spyOn(i18next, "t").mockImplementation((key: ParseKeys) => key);
}
/**
* Creates an array of range `start - end`
*
* @param start start number e.g. 1
* @param end end number e.g. 10
* @returns an array of numbers
*/
export function arrayOfRange(start: integer, end: integer) {
return Array.from({ length: end - start }, (_v, k) => k + start);
}

View File

@ -3,24 +3,16 @@ import {addTextObject, TextStyle} from "./text";
import i18next from "i18next"; import i18next from "i18next";
import * as Utils from "#app/utils"; import * as Utils from "#app/utils";
const hiddenX = -150; const hiddenX = -150;
const shownX = 0; const shownX = 0;
const baseY = 0; const baseY = 0;
export default class BgmBar extends Phaser.GameObjects.Container { export default class BgmBar extends Phaser.GameObjects.Container {
private defaultWidth: number; private defaultWidth: number;
private defaultHeight: number; private defaultHeight: number;
private bg: Phaser.GameObjects.NineSlice; private bg: Phaser.GameObjects.NineSlice;
private musicText: Phaser.GameObjects.Text; private musicText: Phaser.GameObjects.Text;
private noteText: Phaser.GameObjects.Text;
private tween: Phaser.Tweens.Tween;
private autoHideTimer: NodeJS.Timeout;
private queue: (string)[] = [];
public shown: boolean; public shown: boolean;
@ -29,19 +21,15 @@ export default class BgmBar extends Phaser.GameObjects.Container {
} }
setup(): void { setup(): void {
this.defaultWidth = 200; this.defaultWidth = 230;
this.defaultHeight = 100; this.defaultHeight = 100;
this.bg = this.scene.add.nineslice(-5, -5, "ability_bar_left", null, this.defaultWidth, this.defaultHeight, 0, 0, 10, 10); this.bg = this.scene.add.nineslice(-5, -5, "bgm_bar", null, this.defaultWidth, this.defaultHeight, 0, 0, 10, 10);
this.bg.setOrigin(0, 0); this.bg.setOrigin(0, 0);
this.add(this.bg); this.add(this.bg);
this.noteText = addTextObject(this.scene, 5, 5, "", TextStyle.MESSAGE, {fontSize: "72px"}); this.musicText = addTextObject(this.scene, 5, 5, "", TextStyle.BGM_BAR);
this.noteText.setOrigin(0, 0);
this.add(this.noteText);
this.musicText = addTextObject(this.scene, 30, 5, "", TextStyle.MESSAGE, {fontSize: "72px"});
this.musicText.setOrigin(0, 0); this.musicText.setOrigin(0, 0);
this.musicText.setWordWrapWidth(650, true); this.musicText.setWordWrapWidth(650, true);
@ -56,16 +44,15 @@ export default class BgmBar extends Phaser.GameObjects.Container {
* @param {string} bgmName The name of the BGM to set. * @param {string} bgmName The name of the BGM to set.
*/ */
setBgmToBgmBar(bgmName: string): void { setBgmToBgmBar(bgmName: string): void {
this.noteText.setText(`${i18next.t("bgmName:music")}:`); this.musicText.setText(`${i18next.t("bgmName:music")}${this.getRealBgmName(bgmName)}`);
this.musicText.setText(`${this.getRealBgmName(bgmName)}`);
if (!(this.scene as BattleScene).showBgmBar) { if (!(this.scene as BattleScene).showBgmBar) {
return; return;
} }
this.musicText.width = this.bg.width - 20; this.musicText.width = this.bg.width - 20;
this.musicText.setWordWrapWidth(this.defaultWidth * 4); this.musicText.setWordWrapWidth(this.defaultWidth * 4);
this.bg.width = Math.min(this.defaultWidth, this.noteText.displayWidth + this.musicText.displayWidth + 30);
this.bg.width = Math.min(this.defaultWidth, this.musicText.displayWidth + 23);
this.bg.height = Math.min(this.defaultHeight, this.musicText.displayHeight + 20); this.bg.height = Math.min(this.defaultHeight, this.musicText.displayHeight + 20);
(this.scene as BattleScene).fieldUI.bringToTop(this); (this.scene as BattleScene).fieldUI.bringToTop(this);
@ -97,5 +84,3 @@ export default class BgmBar extends Phaser.GameObjects.Container {
return i18next.t([`bgmName:${bgmName}`, "bgmName:missing_entries"], {name: Utils.formatText(bgmName)}); return i18next.t([`bgmName:${bgmName}`, "bgmName:missing_entries"], {name: Utils.formatText(bgmName)});
} }
} }

View File

@ -1,12 +1,12 @@
import { CommandPhase, SelectModifierPhase } from "../phases"; import { CommandPhase, SelectModifierPhase } from "../phases";
import BattleScene from "../battle-scene"; import BattleScene from "../battle-scene";
import { PlayerPokemon, PokemonMove } from "../field/pokemon"; import { PlayerPokemon, PokemonMove } from "../field/pokemon";
import { addTextObject, TextStyle } from "./text"; import { addBBCodeTextObject, addTextObject, getTextColor, TextStyle } from "./text";
import { Command } from "./command-ui-handler"; import { Command } from "./command-ui-handler";
import MessageUiHandler from "./message-ui-handler"; import MessageUiHandler from "./message-ui-handler";
import { Mode } from "./ui"; import { Mode } from "./ui";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { PokemonFormChangeItemModifier, PokemonHeldItemModifier, SwitchEffectTransferModifier } from "../modifier/modifier"; import { PokemonBaseStatModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier, SwitchEffectTransferModifier } from "../modifier/modifier";
import { allMoves } from "../data/move"; import { allMoves } from "../data/move";
import { getGenderColor, getGenderSymbol } from "../data/gender"; import { getGenderColor, getGenderSymbol } from "../data/gender";
import { StatusEffect } from "../data/status-effect"; import { StatusEffect } from "../data/status-effect";
@ -19,6 +19,7 @@ import {Button} from "#enums/buttons";
import { applyChallenges, ChallengeType } from "#app/data/challenge.js"; import { applyChallenges, ChallengeType } from "#app/data/challenge.js";
import MoveInfoOverlay from "./move-info-overlay"; import MoveInfoOverlay from "./move-info-overlay";
import i18next from "i18next"; import i18next from "i18next";
import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
const defaultMessage = i18next.t("partyUiHandler:choosePokemon"); const defaultMessage = i18next.t("partyUiHandler:choosePokemon");
@ -85,7 +86,8 @@ export default class PartyUiHandler extends MessageUiHandler {
private optionsCursor: integer = 0; private optionsCursor: integer = 0;
private optionsScrollCursor: integer = 0; private optionsScrollCursor: integer = 0;
private optionsScrollTotal: integer = 0; private optionsScrollTotal: integer = 0;
private optionsContainer: Phaser.GameObjects.Container; /** This is only public for test/ui/transfer-item.test.ts */
public optionsContainer: Phaser.GameObjects.Container;
private optionsBg: Phaser.GameObjects.NineSlice; private optionsBg: Phaser.GameObjects.NineSlice;
private optionsCursorObj: Phaser.GameObjects.Image; private optionsCursorObj: Phaser.GameObjects.Image;
private options: integer[]; private options: integer[];
@ -819,7 +821,7 @@ export default class PartyUiHandler extends MessageUiHandler {
optionEndIndex = this.options.length; optionEndIndex = this.options.length;
let widestOptionWidth = 0; let widestOptionWidth = 0;
const optionTexts: Phaser.GameObjects.Text[] = []; const optionTexts: BBCodeText[] = [];
for (let o = optionStartIndex; o < optionEndIndex; o++) { for (let o = optionStartIndex; o < optionEndIndex; o++) {
const option = this.options[this.options.length - (o + 1)]; const option = this.options[this.options.length - (o + 1)];
@ -861,27 +863,42 @@ export default class PartyUiHandler extends MessageUiHandler {
const move = learnableLevelMoves[option]; const move = learnableLevelMoves[option];
optionName = allMoves[move].name; optionName = allMoves[move].name;
altText = !pokemon.getSpeciesForm().getLevelMoves().find(plm => plm[1] === move); altText = !pokemon.getSpeciesForm().getLevelMoves().find(plm => plm[1] === move);
} else if (option === PartyOption.ALL) {
optionName = i18next.t("partyUiHandler:ALL");
} else { } else {
if (option === PartyOption.ALL) { const itemModifier = itemModifiers[option];
optionName = i18next.t("partyUiHandler:ALL"); optionName = itemModifier.type.name;
} else {
const itemModifier = itemModifiers[option];
optionName = itemModifier.type.name;
/** For every item that has stack bigger than 1, display the current quantity selection */
if (this.transferQuantitiesMax[option] > 1) {
optionName += ` (${this.transferQuantities[option]})`;
}
}
} }
const yCoord = -6 - 16 * o; const yCoord = -6 - 16 * o;
const optionText = addTextObject(this.scene, 0, yCoord - 16, optionName, TextStyle.WINDOW); const optionText = addBBCodeTextObject(this.scene, 0, yCoord - 16, optionName, TextStyle.WINDOW, { maxLines: 1 });
if (altText) { if (altText) {
optionText.setColor("#40c8f8"); optionText.setColor("#40c8f8");
optionText.setShadowColor("#006090"); optionText.setShadowColor("#006090");
} }
optionText.setOrigin(0, 0); optionText.setOrigin(0, 0);
/** For every item that has stack bigger than 1, display the current quantity selection */
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && this.transferQuantitiesMax[option] > 1) {
const itemModifier = itemModifiers[option];
/** Not sure why getMaxHeldItemCount had an error, but it only checks the Pokemon parameter if the modifier is PokemonBaseStatModifier */
if (itemModifier === undefined || itemModifier instanceof PokemonBaseStatModifier) {
continue;
}
let amountText = ` (${this.transferQuantities[option]})`;
/** If the amount held is the maximum, display the count in red */
if (this.transferQuantitiesMax[option] === itemModifier.getMaxHeldItemCount(undefined)) {
amountText = `[color=${getTextColor(TextStyle.SUMMARY_RED)}]${amountText}[/color]`;
}
optionText.setText(optionName + amountText);
}
optionText.setText(`[shadow]${optionText.text}[/shadow]`);
optionTexts.push(optionText); optionTexts.push(optionText);
widestOptionWidth = Math.max(optionText.displayWidth, widestOptionWidth); widestOptionWidth = Math.max(optionText.displayWidth, widestOptionWidth);

View File

@ -34,7 +34,8 @@ export enum TextStyle {
MOVE_PP_HALF_FULL, MOVE_PP_HALF_FULL,
MOVE_PP_NEAR_EMPTY, MOVE_PP_NEAR_EMPTY,
MOVE_PP_EMPTY, MOVE_PP_EMPTY,
SMALLER_WINDOW_ALT SMALLER_WINDOW_ALT,
BGM_BAR
} }
export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text { export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text {
@ -146,6 +147,11 @@ export function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraSty
shadowXpos = 3; shadowXpos = 3;
shadowYpos = 3; shadowYpos = 3;
break; break;
case TextStyle.BGM_BAR:
styleOptions.fontSize = defaultFontSize - 24;
shadowXpos = 3;
shadowYpos = 3;
break;
} }
const shadowColor = getTextColor(style, true, uiTheme); const shadowColor = getTextColor(style, true, uiTheme);
@ -235,6 +241,8 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: Ui
return !shadow ? "#f88880" : "#f83018"; return !shadow ? "#f88880" : "#f83018";
case TextStyle.SMALLER_WINDOW_ALT: case TextStyle.SMALLER_WINDOW_ALT:
return !shadow ? "#484848" : "#d0d0c8"; return !shadow ? "#484848" : "#d0d0c8";
case TextStyle.BGM_BAR:
return !shadow ? "#f8f8f8" : "#6b5a73";
} }
} }