Compare commits

...

10 Commits

Author SHA1 Message Date
Terrorforge
6917db7429
[Balance] give Goomy Regenerator (#2248) 2024-06-15 12:23:32 -04:00
Tempoanon
fdf139d529
[Bug] Add rest of trailblaze Pokemon (#2239) 2024-06-15 12:18:52 -04:00
chaosgrimmon
4e8a2e87d2
[Sprite] Replace Togedemaru Animation Datafiles (#2255)
* [Sprite] Replace Exp front Togedemaru .json

animation stretched 11% upon artist request: https://discord.com/channels/1125469663833370665/1229465263532019712/1251422382745325609

* [Sprite] Replace exp back Togedemaru .json

taken from exp/back/shiny/777.json

* [Sprite] Extend exp front shiny Togedemaru .json

animation stretched 11% upon artist request: https://discord.com/channels/1125469663833370665/1229465263532019712/1251422382745325609
2024-06-15 12:14:59 -04:00
Adrian T
dbecb72890
[Bug] add ability revelead for trace, refactor (#2258) 2024-06-15 12:13:59 -04:00
Adrian T
0b019d9823
[Ability] Implement Wonder Skin (#2231)
* implement wonder skin

* add unit tests

* fixes

* move applyPreDefendAbAttrs
2024-06-15 17:06:32 +01:00
Adam Clemons
422a561dfe
[Feature] Add Missing Champion Dialogue (#2120)
* Add Alder dialogue

* Add Kieran dialogue

* Add line breaks

* typo fix

* Add placeholder dialogue
2024-06-15 16:47:44 +01:00
Lugiad
523f818e12
[Localization] Many corrections of recent French translations (#2257)
* Update ability-trigger.ts

* Update achv.ts

* Update battle.ts

* Update challenges.ts

* Update battle.ts

* Update party-ui-handler.ts

* Update pokemon-info-container.ts

* Update trainers.ts

* Update achv.ts

* Update achv.ts

* Update achv.ts

* Update splash-messages.ts

* Update achv.ts

* Update achv.ts

* Update trainers.ts

* Update src/locales/fr/achv.ts

Co-authored-by: Dakurei <maxime.palanchini@gmail.com>

* Update challenges.ts

* Update src/locales/fr/battle.ts

Co-authored-by: Dakurei <maxime.palanchini@gmail.com>

* Update battle.ts

* Update battle.ts

---------

Co-authored-by: Dakurei <maxime.palanchini@gmail.com>
2024-06-15 16:28:33 +01:00
Alexis Faizeau
8e5b454c87
[Localization] Fix french translations (#2253)
* Translate missing fr keys for acheviements

* Translate missing fr keys for ability triggers

* Translate missing fr keys for battle

* Translate missing fr keys for fight ui handler

* Translate missing fr keys for challenge

* Translate missing fr keys for party ui handler

* Translate missing fr keys for pokémon infos container

* Translate missing fr keys for trainers
2024-06-15 13:06:57 +02:00
Franck TROUILLEZ
a4b07158f9
[QoL] Add ALL option when transferring items to Pokemons (#1694)
* Add ALL option to transfer menu

It adds a new attribute to the PartyUiHandler to track whether the transfer is meant for all items of only for a particular one

It also introduces translations for PartyUiHandler, even though only the 'ALL' option can be translated for now.

* Use updated translation key for i18n for partyUiHandler:ALL

* Fix duplicated import

* Use optionCursor instead of optionCursorWithScroll to check if we need to transfer ALL
2024-06-15 12:32:15 +02:00
EmberCM
16084878c3
Remove random trailing commas (#2245) 2024-06-15 12:13:54 +02:00
31 changed files with 3708 additions and 5291 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -574,6 +574,24 @@ export class MoveImmunityAbAttr extends PreDefendAbAttr {
}
}
/**
* Reduces the accuracy of status moves used against the Pokémon with this ability to 50%.
* Used by Wonder Skin.
*
* @extends PreDefendAbAttr
*/
export class WonderSkinAbAttr extends PreDefendAbAttr {
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const moveAccuracy = args[0] as Utils.NumberHolder;
if (move.category === MoveCategory.STATUS && moveAccuracy.value >= 50) {
moveAccuracy.value = 50;
return true;
}
return false;
}
}
export class MoveImmunityStatChangeAbAttr extends MoveImmunityAbAttr {
private stat: BattleStat;
private levels: integer;
@ -1881,6 +1899,7 @@ export class TraceAbAttr extends PostSummonAbAttr {
pokemon.summonData.ability = target.getAbility().id;
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` traced ${target.name}'s\n${allAbilities[target.getAbility().id].name}!`));
setAbilityRevealed(target);
return true;
}
@ -2439,9 +2458,7 @@ export class FriskAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
for (const opponent of pokemon.getOpponents()) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " frisked " + opponent.name + "'s " + opponent.getAbility().name + "!"));
if (opponent.battleData) {
opponent.battleData.abilityRevealed = true;
}
setAbilityRevealed(opponent);
}
return true;
}
@ -3802,6 +3819,17 @@ function queueShowAbility(pokemon: Pokemon, passive: boolean): void {
pokemon.scene.clearPhaseQueueSplice();
}
/**
* Sets the ability of a Pokémon as revealed.
*
* @param pokemon - The Pokémon whose ability is being revealed.
*/
function setAbilityRevealed(pokemon: Pokemon): void {
if (pokemon.battleData) {
pokemon.battleData.abilityRevealed = true;
}
}
export const allAbilities = [ new Ability(Abilities.NONE, 3) ];
export function initAbilities() {
@ -4250,8 +4278,8 @@ export function initAbilities() {
.attr(BlockWeatherDamageAttr, WeatherType.SANDSTORM)
.condition(getWeatherCondition(WeatherType.SANDSTORM)),
new Ability(Abilities.WONDER_SKIN, 5)
.ignorable()
.unimplemented(),
.attr(WonderSkinAbAttr)
.ignorable(),
new Ability(Abilities.ANALYTIC, 5)
.attr(MovePowerBoostAbAttr, (user, target, move) => !!target.getLastXMoves(1).find(m => m.turn === target.scene.currentBattle.turn) || user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command !== Command.FIGHT, 1.3),
new Ability(Abilities.ILLUSION, 5)

View File

@ -2934,7 +2934,7 @@ export function initBiomes() {
[ Species.AZUMARILL, Type.WATER, Type.FAIRY, [
[ Biome.LAKE, BiomePoolTier.COMMON, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ],
[ Biome.LAKE, BiomePoolTier.BOSS, [ TimeOfDay.DUSK, TimeOfDay.NIGHT ] ],
[ Biome.FAIRY_CAVE, BiomePoolTier.COMMON ],
[ Biome.FAIRY_CAVE, BiomePoolTier.COMMON ]
]
],
[ Species.SUDOWOODO, Type.ROCK, -1, [
@ -3630,7 +3630,7 @@ export function initBiomes() {
[ Species.FLYGON, Type.GROUND, Type.DRAGON, [
[ Biome.DESERT, BiomePoolTier.RARE, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ],
[ Biome.WASTELAND, BiomePoolTier.COMMON ],
[ Biome.WASTELAND, BiomePoolTier.BOSS ],
[ Biome.WASTELAND, BiomePoolTier.BOSS ]
]
],
[ Species.CACNEA, Type.GRASS, -1, [
@ -3694,14 +3694,14 @@ export function initBiomes() {
[ Species.BALTOY, Type.GROUND, Type.PSYCHIC, [
[ Biome.RUINS, BiomePoolTier.COMMON ],
[ Biome.SPACE, BiomePoolTier.UNCOMMON ],
[ Biome.TEMPLE, BiomePoolTier.UNCOMMON ],
[ Biome.TEMPLE, BiomePoolTier.UNCOMMON ]
]
],
[ Species.CLAYDOL, Type.GROUND, Type.PSYCHIC, [
[ Biome.RUINS, BiomePoolTier.COMMON ],
[ Biome.RUINS, BiomePoolTier.BOSS ],
[ Biome.SPACE, BiomePoolTier.UNCOMMON ],
[ Biome.TEMPLE, BiomePoolTier.UNCOMMON ],
[ Biome.TEMPLE, BiomePoolTier.UNCOMMON ]
]
],
[ Species.LILEEP, Type.ROCK, Type.GRASS, [
@ -4199,14 +4199,14 @@ export function initBiomes() {
[ Species.SKORUPI, Type.POISON, Type.BUG, [
[ Biome.SWAMP, BiomePoolTier.UNCOMMON ],
[ Biome.DESERT, BiomePoolTier.COMMON ],
[ Biome.TEMPLE, BiomePoolTier.UNCOMMON ],
[ Biome.TEMPLE, BiomePoolTier.UNCOMMON ]
]
],
[ Species.DRAPION, Type.POISON, Type.DARK, [
[ Biome.SWAMP, BiomePoolTier.UNCOMMON ],
[ Biome.DESERT, BiomePoolTier.COMMON ],
[ Biome.DESERT, BiomePoolTier.BOSS ],
[ Biome.TEMPLE, BiomePoolTier.UNCOMMON ],
[ Biome.TEMPLE, BiomePoolTier.UNCOMMON ]
]
],
[ Species.CROAGUNK, Type.POISON, Type.FIGHTING, [
@ -4793,7 +4793,7 @@ export function initBiomes() {
]
],
[ Species.CINCCINO, Type.NORMAL, -1, [
[ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ],
[ Biome.MEADOW, BiomePoolTier.BOSS, [ TimeOfDay.DAWN, TimeOfDay.DAY ] ]
]
],
[ Species.GOTHITA, Type.PSYCHIC, -1, [
@ -4898,7 +4898,7 @@ export function initBiomes() {
]
],
[ Species.JOLTIK, Type.BUG, Type.ELECTRIC, [
[ Biome.JUNGLE, BiomePoolTier.UNCOMMON ],
[ Biome.JUNGLE, BiomePoolTier.UNCOMMON ]
]
],
[ Species.GALVANTULA, Type.BUG, Type.ELECTRIC, [

View File

@ -2290,6 +2290,28 @@ export const trainerTypeDialogue: TrainerTypeDialogue = {
"dialogue:raihan_elite.defeat.2"
]
},
[TrainerType.ALDER]: {
encounter: [
"dialogue:alder.encounter.1"
],
victory: [
"dialogue:alder.victory.1"
],
defeat: [
"dialogue:alder.defeat.1"
]
},
[TrainerType.KIERAN]: {
encounter: [
"dialogue:kieran.encounter.1"
],
victory: [
"dialogue:kieran.victory.1"
],
defeat: [
"dialogue:kieran.defeat.1"
]
},
[TrainerType.RIVAL]: [
{
encounter: [

View File

@ -3634,7 +3634,7 @@ export const starterPassiveAbilities = {
[Species.HAWLUCHA]: Abilities.MOXIE,
[Species.DEDENNE]: Abilities.PIXILATE,
[Species.CARBINK]: Abilities.SOLID_ROCK,
[Species.GOOMY]: Abilities.DRIZZLE,
[Species.GOOMY]: Abilities.REGENERATOR,
[Species.KLEFKI]: Abilities.LEVITATE,
[Species.PHANTUMP]: Abilities.RIPEN,
[Species.PUMPKABOO]: Abilities.WELL_BAKED_BODY,

View File

@ -63324,12 +63324,18 @@ export const tmSpecies: TmSpecies = {
Species.HYDRAPPLE,
],
[Moves.TRAILBLAZE]: [
Species.BULBASAUR,
Species.IVYSAUR,
Species.VENUSAUR,
Species.EKANS,
Species.ARBOK,
Species.PIKACHU,
Species.RAICHU,
Species.JIGGLYPUFF,
Species.WIGGLYTUFF,
Species.ODDISH,
Species.GLOOM,
Species.VILEPLUME,
Species.MEOWTH,
Species.PERSIAN,
Species.PSYDUCK,
@ -63337,8 +63343,10 @@ export const tmSpecies: TmSpecies = {
Species.BELLSPROUT,
Species.WEEPINBELL,
Species.VICTREEBEL,
Species.DODRIO,
Species.DROWZEE,
Species.HYPNO,
Species.HITMONCHAN,
Species.CHANSEY,
Species.SCYTHER,
Species.TAUROS,
@ -63349,6 +63357,12 @@ export const tmSpecies: TmSpecies = {
Species.SNORLAX,
Species.MEWTWO,
Species.MEW,
Species.CHIKORITA,
Species.BAYLEEF,
Species.MEGANIUM,
Species.TOTODILE,
Species.CROCONAW,
Species.FERALIGATR,
Species.SENTRET,
Species.FURRET,
Species.SPINARAK,
@ -63358,6 +63372,7 @@ export const tmSpecies: TmSpecies = {
Species.MAREEP,
Species.FLAAFFY,
Species.AMPHAROS,
Species.BELLOSSOM,
Species.MARILL,
Species.AZUMARILL,
Species.SUDOWOODO,
@ -63372,6 +63387,8 @@ export const tmSpecies: TmSpecies = {
Species.ESPEON,
Species.UMBREON,
Species.GIRAFARIG,
Species.SNUBBULL,
Species.GRANBULL,
Species.SCIZOR,
Species.HERACROSS,
Species.SNEASEL,
@ -63385,7 +63402,14 @@ export const tmSpecies: TmSpecies = {
Species.PHANPY,
Species.DONPHAN,
Species.STANTLER,
Species.ELEKID,
Species.BLISSEY,
Species.RAIKOU,
Species.ENTEI,
Species.SUICUNE,
Species.TREECKO,
Species.GROVYLE,
Species.SCEPTILE,
Species.POOCHYENA,
Species.MIGHTYENA,
Species.LOTAD,
@ -63398,6 +63422,8 @@ export const tmSpecies: TmSpecies = {
Species.SLAKING,
Species.MEDITITE,
Species.MEDICHAM,
Species.PLUSLE,
Species.MINUN,
Species.VOLBEAT,
Species.ILLUMISE,
Species.NUMEL,
@ -63422,6 +63448,10 @@ export const tmSpecies: TmSpecies = {
Species.SHINX,
Species.LUXIO,
Species.LUXRAY,
Species.CRANIDOS,
Species.RAMPARDOS,
Species.SHIELDON,
Species.BASTIODON,
Species.PACHIRISU,
Species.AMBIPOM,
Species.STUNKY,
@ -63433,9 +63463,21 @@ export const tmSpecies: TmSpecies = {
Species.SNOVER,
Species.ABOMASNOW,
Species.WEAVILE,
Species.ELECTIVIRE,
Species.LEAFEON,
Species.GLACEON,
Species.MAMOSWINE,
Species.FROSLASS,
Species.SHAYMIN,
Species.ARCEUS,
Species.SNIVY,
Species.SERVINE,
Species.SERPERIOR,
Species.TEPIG,
Species.PIGNITE,
Species.EMBOAR,
Species.BLITZLE,
Species.ZEBSTRIKA,
Species.SEWADDLE,
Species.SWADLOON,
Species.LEAVANNY,
@ -63444,6 +63486,8 @@ export const tmSpecies: TmSpecies = {
Species.SCRAGGY,
Species.SCRAFTY,
Species.DUCKLETT,
Species.MINCCINO,
Species.CINCCINO,
Species.SWANNA,
Species.DEERLING,
Species.SAWSBUCK,
@ -63475,6 +63519,8 @@ export const tmSpecies: TmSpecies = {
Species.FLORGES,
Species.SKIDDO,
Species.GOGOAT,
Species.MEOWSTIC,
Species.MALAMAR,
Species.SYLVEON,
Species.HAWLUCHA,
Species.DEDENNE,
@ -63490,6 +63536,8 @@ export const tmSpecies: TmSpecies = {
Species.RIBOMBEE,
Species.ROCKRUFF,
Species.LYCANROC,
Species.DEWPIDER,
Species.ARAQUANID,
Species.FOMANTIS,
Species.LURANTIS,
Species.SALANDIT,
@ -63497,6 +63545,7 @@ export const tmSpecies: TmSpecies = {
Species.BOUNSWEET,
Species.STEENEE,
Species.TSAREENA,
Species.COMFEY,
Species.ORANGURU,
Species.PASSIMIAN,
Species.KOMALA,
@ -63508,6 +63557,7 @@ export const tmSpecies: TmSpecies = {
Species.RABOOT,
Species.CINDERACE,
Species.SKWOVET,
Species.GREEDENT,
Species.FLAPPLE,
Species.APPLETUN,
Species.TOXTRICITY,

View File

@ -2349,6 +2349,32 @@ export const PGMdialogue: DialogueTranslationEntries = {
2: "Du bist in meinen Sturm geraten! Viel Glück beim nächsten Mal!"
}
},
"alder": {
"encounter": {
1: "Prepare yourself for a match against the strongest Trainer in Unova!"
},
"victory": {
1: "Well done! You certainly are an unmatched talent."
},
"defeat": {
1: `A fresh wind blows through my heart...
$What an extraordinary effort!`
}
},
"kieran": {
"encounter": {
1: `Through hard work, I become stronger and stronger!
$I don't lose.`
},
"victory": {
1: `I don't believe it...
$What a fun and heart-pounding battle!`
},
"defeat": {
1: `Wowzers, what a battle!
$Time for you to train even harder.`
}
},
"rival": {
"encounter": {

View File

@ -27,6 +27,7 @@ import { menuUiHandler } from "./menu-ui-handler";
import { modifierType } from "./modifier-type";
import { move } from "./move";
import { nature } from "./nature";
import { partyUiHandler } from "./party-ui-handler";
import { pokeball } from "./pokeball";
import { pokemon } from "./pokemon";
import { pokemonInfo } from "./pokemon-info";
@ -38,7 +39,6 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
import { tutorial } from "./tutorial";
import { voucher } from "./voucher";
import { weather } from "./weather";
import { partyUiHandler } from "./party-ui-handler";
export const enConfig = {
ability: ability,
@ -69,6 +69,7 @@ export const enConfig = {
modifierType: modifierType,
move: move,
nature: nature,
partyUiHandler: partyUiHandler,
pokeball: pokeball,
pokemon: pokemon,
pokemonInfo: pokemonInfo,
@ -82,5 +83,4 @@ export const enConfig = {
tutorial: tutorial,
voucher: voucher,
weather: weather,
partyUiHandler: partyUiHandler
};

View File

@ -2287,6 +2287,32 @@ export const PGMdialogue: DialogueTranslationEntries = {
2: "You got caught in my storm! Better luck next time!"
}
},
"alder": {
"encounter": {
1: "Prepare yourself for a match against the strongest Trainer in Unova!"
},
"victory": {
1: "Well done! You certainly are an unmatched talent."
},
"defeat": {
1: `A fresh wind blows through my heart...
$What an extraordinary effort!`
}
},
"kieran": {
"encounter": {
1: `Through hard work, I become stronger and stronger!
$I don't lose.`
},
"victory": {
1: `I don't believe it...
$What a fun and heart-pounding battle!`
},
"defeat": {
1: `Wowzers, what a battle!
$Time for you to train even harder.`
}
},
"rival": {
"encounter": {
1: `@c{smile}Hey, I was looking for you! I knew you were eager to get going but I expected at least a goodbye…

View File

@ -1,6 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"ALL": "All",
"SEND_OUT": "Send Out",
"SUMMARY": "Summary",
"CANCEL": "Cancel",

View File

@ -2107,6 +2107,32 @@ export const PGMdialogue: DialogueTranslationEntries = {
2: "You got caught in my storm! Better luck next time!"
}
},
"alder": {
"encounter": {
1: "Prepare yourself for a match against the strongest Trainer in Unova!"
},
"victory": {
1: "Well done! You certainly are an unmatched talent."
},
"defeat": {
1: `A fresh wind blows through my heart...
$What an extraordinary effort!`
}
},
"kieran": {
"encounter": {
1: `Through hard work, I become stronger and stronger!
$I don't lose.`
},
"victory": {
1: `I don't believe it...
$What a fun and heart-pounding battle!`
},
"defeat": {
1: `Wowzers, what a battle!
$Time for you to train even harder.`
}
},
"rival": {
"encounter": {
1: `@c{smile}Hey, I was looking for you! I knew you were eager to get going but I expected at least a goodbye…

View File

@ -4,5 +4,7 @@ export const abilityTriggers: SimpleTranslationEntries = {
"blockRecoilDamage" : "{{abilityName}}\nde {{pokemonName}} le protège du contrecoup !",
"badDreams": "{{pokemonName}} a le sommeil agité !",
"windPowerCharged": "{{pokemonName}} a été touché par la capacité {{moveName}} et se charge en électricité !",
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!"
"perishBody": "{{abilityName}} de {{pokemonName}}\nmettra les deux Pokémon K.O. dans trois tours !",
"poisonHeal": "{{abilityName}} de {{pokemonName}}\nrestaure un peu ses PV !",
"iceFaceAvoidedDamage": "{{pokemonName}} évite les dégâts\navec {{abilityName}} !"
} as const;

View File

@ -162,7 +162,7 @@ export const PGMachv: AchievementTranslationEntries = {
description: "Capturer un Pokémon possédant un talent caché",
},
"PERFECT_IVS": {
name: "Certificat dAuthenticité",
name: "Certificat dauthenticité",
description: "Avoir des IV parfaits sur un Pokémon",
},
"CLASSIC_VICTORY": {
@ -171,98 +171,98 @@ export const PGMachv: AchievementTranslationEntries = {
},
"MONO_GEN_ONE": {
name: "The Original Rival",
description: "Complete the generation one only challenge.",
name: "Le rival originel",
description: "Terminer un challenge avec uniquement des Pokémon de 1re génération.",
},
"MONO_GEN_TWO": {
name: "Generation 1.5",
description: "Complete the generation two only challenge.",
name: "Entre tradition et modernité",
description: "Terminer un challenge avec uniquement des Pokémon de 2e génération.",
},
"MONO_GEN_THREE": {
name: "Too much water?",
description: "Complete the generation three only challenge.",
name: "Too much water ?",
description: "Terminer un challenge avec uniquement des Pokémon de 3e génération.",
},
"MONO_GEN_FOUR": {
name: "Is she really the hardest?",
description: "Complete the generation four only challenge.",
name: "Réellement la plus difficile ?",
description: "Terminer un challenge avec uniquement des Pokémon de 4e génération.",
},
"MONO_GEN_FIVE": {
name: "All Original",
description: "Complete the generation five only challenge.",
name: "Recast complet",
description: "Terminer un challenge avec uniquement des Pokémon de 5e génération.",
},
"MONO_GEN_SIX": {
name: "Almost Royalty",
description: "Complete the generation six only challenge.",
name: "Aristocrate",
description: "Terminer un challenge avec uniquement des Pokémon de 6e génération.",
},
"MONO_GEN_SEVEN": {
name: "Only Technically",
description: "Complete the generation seven only challenge.",
name: "Seulement techniquement",
description: "Terminer un challenge avec uniquement des Pokémon de 7e génération.",
},
"MONO_GEN_EIGHT": {
name: "A Champion Time!",
description: "Complete the generation eight only challenge.",
name: "Lheure de gloire",
description: "Terminer un challenge avec uniquement des Pokémon de 8e génération.",
},
"MONO_GEN_NINE": {
name: "She was going easy on you",
description: "Complete the generation nine only challenge.",
name: "Ça va, cétait EZ",
description: "Terminer un challenge avec uniquement des Pokémon de 9e génération.",
},
"MonoType": {
description: "Complete the {{type}} monotype challenge.",
description: "Terminer un challenge en monotype {{type}}.",
},
"MONO_NORMAL": {
name: "Mono NORMAL",
name: "Extraordinairement banal",
},
"MONO_FIGHTING": {
name: "I Know Kung Fu",
name: "Je connais le kung-fu",
},
"MONO_FLYING": {
name: "Mono FLYING",
name: "Angry Birds",
},
"MONO_POISON": {
name: "Kanto's Favourite",
name: "Touche moi je tempoisonne !",
},
"MONO_GROUND": {
name: "Mono GROUND",
name: "Prévisions : Séisme",
},
"MONO_ROCK": {
name: "Brock Hard",
name: "Comme un roc",
},
"MONO_BUG": {
name: "Sting Like A Beedrill",
name: "Une chenille !",
},
"MONO_GHOST": {
name: "Who you gonna call?",
name: "SOS Fantômes",
},
"MONO_STEEL": {
name: "Mono STEEL",
name: "De type Acier !",
},
"MONO_FIRE": {
name: "Mono FIRE",
name: "Allumer le feu",
},
"MONO_WATER": {
name: "When It Rains, It Pours",
name: "Vacances en Bretagne",
},
"MONO_GRASS": {
name: "Mono GRASS",
name: "Ne pas toucher !",
},
"MONO_ELECTRIC": {
name: "Mono ELECTRIC",
name: "À la masse",
},
"MONO_PSYCHIC": {
name: "Mono PSYCHIC",
name: "Grocervo",
},
"MONO_ICE": {
name: "Mono ICE",
name: "Froid comme la glace",
},
"MONO_DRAGON": {
name: "Mono DRAGON",
name: "Légendes du club, ou presque",
},
"MONO_DARK": {
name: "It's just a phase",
name: "Ça va lui passer",
},
"MONO_FAIRY": {
name: "Mono FAIRY",
name: "Hey ! Listen !",
},
} as const;

View File

@ -54,12 +54,12 @@ export const battle: SimpleTranslationEntries = {
"escapeVerbFlee": "la fuite",
"notDisabled": "La capacité {{moveName}}\nde {{pokemonName}} nest plus sous entrave !",
"skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre dobjet ?",
"eggHatching": "Oh ?",
"eggHatching": "Hein ?",
"ivScannerUseQuestion": "Utiliser le Scanner dIV sur {{pokemonName}} ?",
"wildPokemonWithAffix": "{{pokemonName}} sauvage",
"foePokemonWithAffix": "{{pokemonName}} ennemi",
"useMove": "{{pokemonNameWithAffix}} utilise\n{{moveName}} !",
"drainMessage": "{{pokemonName}} had its\nenergy drained!",
"regainHealth": "{{pokemonName}} a récupéré\ndes PV!",
"fainted": "{{pokemonNameWithAffix}} est tombé KO!"
"drainMessage": "Lénergie de {{pokemonName}}\nest drainée !",
"regainHealth": "{{pokemonName}} récupère\ndes PV !",
"fainted": "{{pokemonNameWithAffix}}\nest K.O. !"
} as const;

View File

@ -2,8 +2,8 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const challenges: SimpleTranslationEntries = {
"title": "Paramètres du Challenge",
"points": "Bad Ideas",
"confirm_start": "Continuer avec ces paramètres ?",
"start": "Démarrer",
"illegalEvolution": "{{pokemon}} sest transformé en Pokémon\ninéligible pour ce challenge !",
"singleGeneration.name": "Mono-génération",
"singleGeneration.value.0": "Désactivé",
"singleGeneration.desc.0": "Vous ne pouvez choisir que des Pokémon de la génération sélectionnée.",

View File

@ -2107,6 +2107,32 @@ export const PGMdialogue: DialogueTranslationEntries = {
2: "You got caught in my storm! Better luck next time!"
}
},
"alder": {
"encounter": {
1: "Prepare yourself for a match against the strongest Trainer in Unova!"
},
"victory": {
1: "Well done! You certainly are an unmatched talent."
},
"defeat": {
1: `A fresh wind blows through my heart...
$What an extraordinary effort!`
}
},
"kieran": {
"encounter": {
1: `Through hard work, I become stronger and stronger!
$I don't lose.`
},
"victory": {
1: `I don't believe it...
$What a fun and heart-pounding battle!`
},
"defeat": {
1: `Wowzers, what a battle!
$Time for you to train even harder.`
}
},
"rival": {
"encounter": {
1: `@c{smile}Ah, je te cherchais ! Je savais que tétais pressée de partir, mais je mattendais quand même à un au revoir…

View File

@ -4,6 +4,6 @@ export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP",
"power": "Puissance",
"accuracy": "Précision",
"abilityFlyInText": " {{pokemonName}}'s {{passive}}{{abilityName}}",
"passive": "Passive ", // The space at the end is important
"abilityFlyInText": " {{passive}}{{abilityName}} de {{pokemonName}}",
"passive": "Passif ", // The space at the end is important
} as const;

View File

@ -1,10 +1,11 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const partyUiHandler: SimpleTranslationEntries = {
"SEND_OUT": "Send Out",
"SUMMARY": "Summary",
"CANCEL": "Cancel",
"RELEASE": "Release",
"APPLY": "Apply",
"TEACH": "Teach"
"ALL": "Tout",
"SEND_OUT": "Envoyer",
"SUMMARY": "Résumé",
"CANCEL": "Annuler",
"RELEASE": "Relâcher",
"APPLY": "Appliquer",
"TEACH": "Apprendre"
} as const;

View File

@ -7,5 +7,6 @@ export const pokemonInfoContainer: SimpleTranslationEntries = {
"nature": "Nature :",
"epic": "Épique",
"rare": "Rare",
"common": "Commun"
"common": "Commun",
"form": "Forme :"
} as const;

View File

@ -28,7 +28,7 @@ export const splashMessages: SimpleTranslationEntries = {
"mostlyConsistentSeeds": "Des seeds à peu près stables !",
"achievementPointsDontDoAnything": "Les Points de Succès servent à rien !",
"youDoNotStartAtLevel": "Ne commence pas au Niveau 2000 !",
"dontTalkAboutTheManaphyEggIncident": "Ne parle pas de l'incident de lŒuf de Manaphy !",
"dontTalkAboutTheManaphyEggIncident": "Ne parle pas de lincident de lŒuf de Manaphy !",
"alsoTryPokengine": "Essaye aussi Pokéngine !",
"alsoTryEmeraldRogue": "Essaye aussi Emerald Rogue!",
"alsoTryRadicalRed": "Essaye aussi Radical Red !",

View File

@ -13,6 +13,12 @@ export const titles: SimpleTranslationEntries = {
"rival": "Rival·e", //Written in gender-inclusive language in wait of a potential split of the entry
"professor": "Professeur·e", //Written in gender-inclusive language in wait of a potential split of the entry
"frontier_brain": "Meneur·euse de Zone", //Written in gender-inclusive language in wait of a potential split of the entry
"rocket_boss": "Leader de la Team Rocket",
"magma_boss": "Leader de la Team Magma",
"aqua_boss": "Leader de la Team Aqua",
"galactic_boss": "Leader de la Team Galaxie",
"plasma_boss": "Leader de la Team Plasma",
"flare_boss": "Leader de la Team Flare",
// Maybe if we add the evil teams we can add "Team Rocket" and "Team Aqua" etc. here as well as "Team Rocket Boss" and "Team Aqua Admin" etc.
} as const;
@ -118,7 +124,19 @@ export const trainerClasses: SimpleTranslationEntries = {
"worker": "Ouvrier",
"worker_female": "Ouvrière",
"workers": "Ouvriers",
"youngster": "Gamin"
"youngster": "Gamin",
"rocket_grunt": "Sbire de la Team Rocket",
"rocket_grunt_female": "Sbire de la Team Rocket",
"magma_grunt": "Sbire de la Team Magma",
"magma_grunt_female": "Sbire de la Team Magma",
"aqua_grunt": "Sbire de la Team Aqua",
"aqua_grunt_female": "Sbire de la Team Aqua",
"galactic_grunt": "Sbire de la Team Galaxie",
"galactic_grunt_female": "Sbire Team Galaxie",
"plasma_grunt": "Sbire de la Team Plasma",
"plasma_grunt_female": "Sbire de la Team Plasma",
"flare_grunt": "Sbire de la Team Flare",
"flare_grunt_female": "Sbire de la Team Flare",
} as const;
// Names of special trainers like gym leaders, elite four, and the champion

View File

@ -2107,6 +2107,32 @@ export const PGMdialogue: DialogueTranslationEntries = {
2: "You got caught in my storm! Better luck next time!"
}
},
"alder": {
"encounter": {
1: "Prepare yourself for a match against the strongest Trainer in Unova!"
},
"victory": {
1: "Well done! You certainly are an unmatched talent."
},
"defeat": {
1: `A fresh wind blows through my heart...
$What an extraordinary effort!`
}
},
"kieran": {
"encounter": {
1: `Through hard work, I become stronger and stronger!
$I don't lose.`
},
"victory": {
1: `I don't believe it...
$What a fun and heart-pounding battle!`
},
"defeat": {
1: `Wowzers, what a battle!
$Time for you to train even harder.`
}
},
"rival": {
"encounter": {
1: `@c{smile}Hey, I was looking for you! I knew you were eager to get going but I expected at least a goodbye…

View File

@ -2287,6 +2287,32 @@ export const PGMdialogue: DialogueTranslationEntries = {
2: "넌 내 폭풍을 잡아냈잖아! 다음엔 더 잘해봐!"
}
},
"alder": {
"encounter": {
1: "Prepare yourself for a match against the strongest Trainer in Unova!"
},
"victory": {
1: "Well done! You certainly are an unmatched talent."
},
"defeat": {
1: `A fresh wind blows through my heart...
$What an extraordinary effort!`
}
},
"kieran": {
"encounter": {
1: `Through hard work, I become stronger and stronger!
$I don't lose.`
},
"victory": {
1: `I don't believe it...
$What a fun and heart-pounding battle!`
},
"defeat": {
1: `Wowzers, what a battle!
$Time for you to train even harder.`
}
},
"rival": {
"encounter": {
1: `@c{smile}오, 찾았다! 떠나려는 건 알고 있었지만\n인사정도는 해줄 줄 알았는데…

View File

@ -2096,6 +2096,32 @@ export const PGMdialogue: DialogueTranslationEntries = {
2: "Você foi pego na minha tempestade! Melhor sorte na próxima vez!"
}
},
"alder": {
"encounter": {
1: "Prepare yourself for a match against the strongest Trainer in Unova!"
},
"victory": {
1: "Well done! You certainly are an unmatched talent."
},
"defeat": {
1: `A fresh wind blows through my heart...
$What an extraordinary effort!`
}
},
"kieran": {
"encounter": {
1: `Through hard work, I become stronger and stronger!
$I don't lose.`
},
"victory": {
1: `I don't believe it...
$What a fun and heart-pounding battle!`
},
"defeat": {
1: `Wowzers, what a battle!
$Time for you to train even harder.`
}
},
"rival": {
"encounter": {
1: `@c{smile}Eai, estava procurando você! Sabia que você estava ansioso para começar, mas esperava pelo menos um tchau…

View File

@ -2007,6 +2007,32 @@ export const PGMdialogue: DialogueTranslationEntries = {
2: "你被我的风暴卷入了!祝你下次好运!",
}
},
"alder": {
"encounter": {
1: "Prepare yourself for a match against the strongest Trainer in Unova!"
},
"victory": {
1: "Well done! You certainly are an unmatched talent."
},
"defeat": {
1: `A fresh wind blows through my heart...
$What an extraordinary effort!`
}
},
"kieran": {
"encounter": {
1: `Through hard work, I become stronger and stronger!
$I don't lose.`
},
"victory": {
1: `I don't believe it...
$What a fun and heart-pounding battle!`
},
"defeat": {
1: `Wowzers, what a battle!
$Time for you to train even harder.`
}
},
"rival": {
"encounter": {
1: "@c{smile}嘿,我在找你呢!我知道你急着上路,\n但至少说个再见吧…$@c{smile_eclosed}所以你终于要开始追逐梦想了?\n我几乎不敢相信。$@c{serious_smile_fists}来都来了,来一场对战怎么样?\n毕竟我想看看你是不是准备周全了。$@c{serious_mopen_fists}不要手下留情,我想让你全力以赴!",

View File

@ -2007,6 +2007,32 @@ export const PGMdialogue: DialogueTranslationEntries = {
2: "你被我的風暴捲入了!祝你下次好運!",
}
},
"alder": {
"encounter": {
1: "Prepare yourself for a match against the strongest Trainer in Unova!"
},
"victory": {
1: "Well done! You certainly are an unmatched talent."
},
"defeat": {
1: `A fresh wind blows through my heart...
$What an extraordinary effort!`
}
},
"kieran": {
"encounter": {
1: `Through hard work, I become stronger and stronger!
$I don't lose.`
},
"victory": {
1: `I don't believe it...
$What a fun and heart-pounding battle!`
},
"defeat": {
1: `Wowzers, what a battle!
$Time for you to train even harder.`
}
},
"rival": {
"encounter": {
1: "@c{smile}嘿,我在找你呢!我知道你急著上路,\n但至少說個再見吧…$@c{smile_eclosed}所以你終於要開始追逐夢想了?\n我幾乎不敢相信。$@c{serious_smile_fists}來都來了,來一場對戰怎麼樣?\n畢竟我想看看你是不是準備周全了。$@c{serious_mopen_fists}不要手下留情,我想讓你全力以赴!",

View File

@ -26,7 +26,7 @@ import { Gender } from "./data/gender";
import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather";
import { TempBattleStat } from "./data/temp-battle-stat";
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, IgnoreOpponentEvasionAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr, PokemonTypeChangeAbAttr, applyPreAttackAbAttrs, applyPostMoveUsedAbAttrs, PostMoveUsedAbAttr, MaxMultiHitAbAttr, HealFromBerryUseAbAttr } from "./data/ability";
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, IgnoreOpponentEvasionAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr, PokemonTypeChangeAbAttr, applyPreAttackAbAttrs, applyPostMoveUsedAbAttrs, PostMoveUsedAbAttr, MaxMultiHitAbAttr, HealFromBerryUseAbAttr, WonderSkinAbAttr, applyPreDefendAbAttrs } from "./data/ability";
import { Unlockables, getUnlockableName } from "./system/unlockables";
import { getBiomeKey } from "./field/arena";
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
@ -3012,6 +3012,7 @@ export class MoveEffectPhase extends PokemonPhase {
const moveAccuracy = new Utils.NumberHolder(this.move.getMove().accuracy);
applyMoveAttrs(VariableAccuracyAttr, user, target, this.move.getMove(), moveAccuracy);
applyPreDefendAbAttrs(WonderSkinAbAttr, target, user, this.move.getMove(), { value: false }, moveAccuracy);
if (moveAccuracy.value === -1) {
return true;

View File

@ -0,0 +1,138 @@
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 { TurnEndPhase, } from "#app/phases";
import { Moves } from "#enums/moves";
import { getMovePosition } from "#app/test/utils/gameManagerUtils";
import { Abilities } from "#enums/abilities";
import Move, { allMoves } from "#app/data/move.js";
import { MoveAbilityBypassAbAttr, WonderSkinAbAttr } from "#app/data/ability.js";
import { NumberHolder } from "#app/utils.js";
import Pokemon from "#app/field/pokemon.js";
describe("Abilities - Wonder Skin", () => {
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_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.WONDER_SKIN);
vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([Moves.TACKLE, Moves.CHARM]);
vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]);
});
it("lowers accuracy of status moves to 50%", async () => {
await game.startBattle([Species.MAGIKARP]);
game.doAttack(getMovePosition(game.scene, 0, Moves.CHARM));
const appliedAccuracy = getAppliedMoveAccuracy(game.scene.getEnemyPokemon(), game.scene.getPlayerPokemon(), allMoves[Moves.CHARM]);
await game.phaseInterceptor.to(TurnEndPhase);
expect(appliedAccuracy).not.toBe(undefined);
expect(appliedAccuracy).not.toBe(100);
expect(appliedAccuracy).toBe(50);
});
it("does not lower accuracy of non-status moves", async () => {
await game.startBattle([Species.MAGIKARP]);
game.doAttack(getMovePosition(game.scene, 0, Moves.TACKLE));
const appliedAccuracy = getAppliedMoveAccuracy(game.scene.getEnemyPokemon(), game.scene.getPlayerPokemon(), allMoves[Moves.TACKLE]);
await game.phaseInterceptor.to(TurnEndPhase);
expect(appliedAccuracy).not.toBe(undefined);
expect(appliedAccuracy).toBe(100);
expect(appliedAccuracy).not.toBe(50);
});
it("does not affect pokemon with Mold Breaker", async () => {
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.MOLD_BREAKER);
await game.startBattle([Species.MAGIKARP]);
game.doAttack(getMovePosition(game.scene, 0, Moves.CHARM));
const appliedAccuracy = getAppliedMoveAccuracy(game.scene.getEnemyPokemon(), game.scene.getPlayerPokemon(), allMoves[Moves.CHARM]);
await game.phaseInterceptor.to(TurnEndPhase);
expect(appliedAccuracy).not.toBe(undefined);
expect(appliedAccuracy).toBe(100);
expect(appliedAccuracy).not.toBe(50);
});
it("does not affect pokemon with Teravolt", async () => {
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.TERAVOLT);
await game.startBattle([Species.MAGIKARP]);
game.doAttack(getMovePosition(game.scene, 0, Moves.CHARM));
const appliedAccuracy = getAppliedMoveAccuracy(game.scene.getEnemyPokemon(), game.scene.getPlayerPokemon(), allMoves[Moves.CHARM]);
await game.phaseInterceptor.to(TurnEndPhase);
expect(appliedAccuracy).not.toBe(undefined);
expect(appliedAccuracy).toBe(100);
expect(appliedAccuracy).not.toBe(50);
});
it("does not affect pokemon with Turboblaze", async () => {
vi.spyOn(overrides, "ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.TURBOBLAZE);
await game.startBattle([Species.MAGIKARP]);
game.doAttack(getMovePosition(game.scene, 0, Moves.CHARM));
const appliedAccuracy = getAppliedMoveAccuracy(game.scene.getEnemyPokemon(), game.scene.getPlayerPokemon(), allMoves[Moves.CHARM]);
await game.phaseInterceptor.to(TurnEndPhase);
expect(appliedAccuracy).not.toBe(undefined);
expect(appliedAccuracy).toBe(100);
expect(appliedAccuracy).not.toBe(50);
});
});
/**
* Calculates the adjusted applied accuracy of a move.
*
* @param defender - The defending Pokémon.
* @param attacker - The attacking Pokémon.
* @param move - The move being used by the attacker.
* @returns The adjusted accuracy of the move.
*/
const getAppliedMoveAccuracy = (defender: Pokemon, attacker: Pokemon, move: Move) => {
const accuracyHolder = new NumberHolder(move.accuracy);
/**
* Simulate ignoring ability
* @see MoveAbilityBypassAbAttr
*/
if (attacker.hasAbilityWithAttr(MoveAbilityBypassAbAttr)) {
return accuracyHolder.value;
}
const wonderSkinInstance = new WonderSkinAbAttr();
wonderSkinInstance.applyPreDefend(defender, false, attacker, move, { value: false }, [ accuracyHolder ]);
return accuracyHolder.value;
};

View File

@ -57,7 +57,8 @@ export enum PartyOption {
MOVE_1 = 3000,
MOVE_2,
MOVE_3,
MOVE_4
MOVE_4,
ALL = 4000
}
export type PartySelectCallback = (cursor: integer, option: PartyOption) => void;
@ -96,6 +97,8 @@ export default class PartyUiHandler extends MessageUiHandler {
private transferQuantities: integer[];
/** Stack size of every item that the selected pokemon is holding */
private transferQuantitiesMax: integer[];
/** Whether to transfer all items */
private transferAll: boolean;
private lastCursor: integer = 0;
private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback;
@ -294,6 +297,8 @@ export default class PartyUiHandler extends MessageUiHandler {
} else if ((option !== PartyOption.SUMMARY && option !== PartyOption.UNPAUSE_EVOLUTION && option !== PartyOption.UNSPLICE && option !== PartyOption.RELEASE && option !== PartyOption.CANCEL)
|| (option === PartyOption.RELEASE && this.partyUiMode === PartyUiMode.RELEASE)) {
let filterResult: string;
const getTransferrableItemsFromPokemon = (pokemon: PlayerPokemon) =>
this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === pokemon.id) as PokemonHeldItemModifier[];
if (option !== PartyOption.TRANSFER && option !== PartyOption.SPLICE) {
filterResult = (this.selectFilter as PokemonSelectFilter)(pokemon);
if (filterResult === null && (option === PartyOption.SEND_OUT || option === PartyOption.PASS_BATON)) {
@ -303,10 +308,7 @@ export default class PartyUiHandler extends MessageUiHandler {
filterResult = this.moveSelectFilter(pokemon.moveset[this.optionsCursor]);
}
} else {
const transferPokemon = this.scene.getParty()[this.transferCursor];
const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === transferPokemon.id) as PokemonHeldItemModifier[];
filterResult = (this.selectFilter as PokemonModifierTransferSelectFilter)(pokemon, itemModifiers[this.transferOptionCursor]);
filterResult = (this.selectFilter as PokemonModifierTransferSelectFilter)(pokemon, getTransferrableItemsFromPokemon(this.scene.getParty()[this.transferCursor])[this.transferOptionCursor]);
}
if (filterResult === null) {
if (this.partyUiMode !== PartyUiMode.SPLICE) {
@ -315,7 +317,11 @@ export default class PartyUiHandler extends MessageUiHandler {
if (this.selectCallback && this.partyUiMode !== PartyUiMode.CHECK) {
if (option === PartyOption.TRANSFER) {
if (this.transferCursor !== this.cursor) {
(this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, this.transferOptionCursor, this.transferQuantities[this.transferOptionCursor], this.cursor);
if (this.transferAll) {
getTransferrableItemsFromPokemon(this.scene.getParty()[this.transferCursor]).forEach((_, i) => (this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, i, this.transferQuantitiesMax[i], this.cursor));
} else {
(this.selectCallback as PartyModifierTransferSelectCallback)(this.transferCursor, this.transferOptionCursor, this.transferQuantities[this.transferOptionCursor], this.cursor);
}
}
this.clearTransfer();
} else if (this.partyUiMode === PartyUiMode.SPLICE) {
@ -430,7 +436,9 @@ export default class PartyUiHandler extends MessageUiHandler {
case Button.UP:
/** If currently selecting items to transfer, reset quantity selection */
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
this.transferQuantities[option] = this.transferQuantitiesMax[option];
if (option !== PartyOption.ALL) {
this.transferQuantities[option] = this.transferQuantitiesMax[option];
}
this.updateOptions();
}
success = this.setCursor(this.optionsCursor ? this.optionsCursor - 1 : this.options.length - 1); /** Move cursor */
@ -438,7 +446,9 @@ export default class PartyUiHandler extends MessageUiHandler {
case Button.DOWN:
/** If currently selecting items to transfer, reset quantity selection */
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
this.transferQuantities[option] = this.transferQuantitiesMax[option];
if (option !== PartyOption.ALL) {
this.transferQuantities[option] = this.transferQuantitiesMax[option];
}
this.updateOptions();
}
success = this.setCursor(this.optionsCursor < this.options.length - 1 ? this.optionsCursor + 1 : 0); /** Move cursor */
@ -770,6 +780,9 @@ export default class PartyUiHandler extends MessageUiHandler {
for (let im = 0; im < itemModifiers.length; im++) {
this.options.push(im);
}
if (itemModifiers.length > 1) {
this.options.push(PartyOption.ALL);
}
}
this.optionsScrollTotal = this.options.length;
@ -843,11 +856,15 @@ export default class PartyUiHandler extends MessageUiHandler {
optionName = allMoves[move].name;
altText = !pokemon.getSpeciesForm().getLevelMoves().find(plm => plm[1] === move);
} 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]})`;
if (option === PartyOption.ALL) {
optionName = i18next.t("partyUiHandler:ALL");
} 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]})`;
}
}
}
@ -876,12 +893,14 @@ export default class PartyUiHandler extends MessageUiHandler {
this.transferMode = true;
this.transferCursor = this.cursor;
this.transferOptionCursor = this.getOptionsCursorWithScroll();
this.transferAll = this.options[this.optionsCursor] === PartyOption.ALL;
this.partySlots[this.transferCursor].setTransfer(true);
}
clearTransfer(): void {
this.transferMode = false;
this.transferAll = false;
this.partySlots[this.transferCursor].setTransfer(false);
}