diff --git a/public/images/events/egg-update_de.png b/public/images/events/egg-update_de.png new file mode 100644 index 00000000000..5de94877d5c Binary files /dev/null and b/public/images/events/egg-update_de.png differ diff --git a/public/images/events/egg-update_en.png b/public/images/events/egg-update_en.png new file mode 100644 index 00000000000..7104d340ca0 Binary files /dev/null and b/public/images/events/egg-update_en.png differ diff --git a/public/images/events/egg-update_es.png b/public/images/events/egg-update_es.png new file mode 100644 index 00000000000..ec5f5c46d17 Binary files /dev/null and b/public/images/events/egg-update_es.png differ diff --git a/public/images/events/egg-update_fr.png b/public/images/events/egg-update_fr.png new file mode 100644 index 00000000000..e0505fa96dd Binary files /dev/null and b/public/images/events/egg-update_fr.png differ diff --git a/public/images/events/egg-update_it.png b/public/images/events/egg-update_it.png new file mode 100644 index 00000000000..fc347bce9cf Binary files /dev/null and b/public/images/events/egg-update_it.png differ diff --git a/public/images/events/egg-update_ja.png b/public/images/events/egg-update_ja.png new file mode 100644 index 00000000000..2259cbb4d9a Binary files /dev/null and b/public/images/events/egg-update_ja.png differ diff --git a/public/images/events/egg-update_ko.png b/public/images/events/egg-update_ko.png new file mode 100644 index 00000000000..99dcc662402 Binary files /dev/null and b/public/images/events/egg-update_ko.png differ diff --git a/public/images/events/egg-update_pt-BR.png b/public/images/events/egg-update_pt-BR.png new file mode 100644 index 00000000000..ee347d35654 Binary files /dev/null and b/public/images/events/egg-update_pt-BR.png differ diff --git a/public/images/events/egg-update_zh-CN.png b/public/images/events/egg-update_zh-CN.png new file mode 100644 index 00000000000..02d780fab89 Binary files /dev/null and b/public/images/events/egg-update_zh-CN.png differ diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 94dc3acce48..42a6d364dd6 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -301,8 +301,6 @@ export default class BattleScene extends SceneBase { public eventManager: TimedEventManager; - public biomeChangeMode: boolean = false; - /** * Allows subscribers to listen for events * @@ -850,9 +848,9 @@ export default class BattleScene extends SceneBase { return activeOnly ? this.infoToggles.filter(t => t?.isActive()) : this.infoToggles; } - getPokemonById(pokemonId: integer): Pokemon | undefined { + getPokemonById(pokemonId: integer): Pokemon | null { const findInParty = (party: Pokemon[]) => party.find(p => p.id === pokemonId); - return (findInParty(this.getParty()) || findInParty(this.getEnemyParty())) || undefined; + return (findInParty(this.getParty()) || findInParty(this.getEnemyParty())) ?? null; } addPlayerPokemon(species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData, postProcess?: (playerPokemon: PlayerPokemon) => void): PlayerPokemon { @@ -879,7 +877,7 @@ export default class BattleScene extends SceneBase { overrideModifiers(this, false); overrideHeldItems(this, pokemon, false); if (boss && !dataSource) { - const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967296)); + const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967296, undefined, "IVs")); for (let s = 0; s < pokemon.ivs.length; s++) { pokemon.ivs[s] = Math.round(Phaser.Math.Linear(Math.min(pokemon.ivs[s], secondaryIvs[s]), Math.max(pokemon.ivs[s], secondaryIvs[s]), 0.75)); @@ -1007,7 +1005,6 @@ export default class BattleScene extends SceneBase { setSeed(seed: string): void { this.seed = seed; this.rngCounter = 0; - //this.setScoreText("RNG: 0") this.waveCycleOffset = this.getGeneratedWaveCycleOffset(); this.offsetGym = this.gameMode.isClassic && this.getGeneratedOffsetGym(); } @@ -1196,12 +1193,12 @@ export default class BattleScene extends SceneBase { this.setScoreText(txt.join(" / ")) } - newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean): Battle { + newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean): Battle | null { const _startingWave = Overrides.STARTING_WAVE_OVERRIDE || startingWave; const newWaveIndex = waveIndex || ((this.currentBattle?.waveIndex || (_startingWave - 1)) + 1); - var newDouble; - var newBattleType; - var newTrainer; + let newDouble: boolean | undefined; + let newBattleType: BattleType; + let newTrainer: Trainer | undefined; let battleConfig: FixedBattleConfig | null = null; @@ -1237,13 +1234,13 @@ export default class BattleScene extends SceneBase { const doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance); playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, false, doubleChance)); - doubleTrainer = !Utils.randSeedInt(doubleChance.value); + doubleTrainer = !Utils.randSeedInt(doubleChance.value, undefined, "Double battle roll"); // Add a check that special trainers can't be double except for tate and liza - they should use the normal double chance if (trainerConfigs[trainerType].trainerTypeDouble && ![ TrainerType.TATE, TrainerType.LIZA ].includes(trainerType)) { doubleTrainer = false; } } - const variant = doubleTrainer ? TrainerVariant.DOUBLE : (Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT); + const variant = doubleTrainer ? TrainerVariant.DOUBLE : (Utils.randSeedInt(2, undefined, "Trainer gender") ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT); newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, variant); this.field.add(newTrainer); } @@ -1254,9 +1251,9 @@ export default class BattleScene extends SceneBase { const doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance); playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, false, doubleChance)); - newDouble = !Utils.randSeedInt(doubleChance.value); + newDouble = !Utils.randSeedInt(doubleChance.value, undefined, "Double battle roll"); } else if (newBattleType === BattleType.TRAINER) { - newDouble = newTrainer.variant === TrainerVariant.DOUBLE; + newDouble = newTrainer?.variant === TrainerVariant.DOUBLE; } } else if (!battleConfig) { newDouble = !!double; @@ -1408,19 +1405,19 @@ export default class BattleScene extends SceneBase { case Species.TATSUGIRI: case Species.GIMMIGHOUL: case Species.PALDEA_TAUROS: - return Utils.randSeedInt(species.forms.length); + return Utils.randSeedInt(species.forms.length, undefined, "General form selection"); case Species.PIKACHU: - return Utils.randSeedInt(8); + return Utils.randSeedInt(8, undefined, "Pikachu form selection"); case Species.EEVEE: - return Utils.randSeedInt(2); + return Utils.randSeedInt(2, undefined, "Eevee form selection"); case Species.GRENINJA: - return Utils.randSeedInt(2); + return Utils.randSeedInt(2, undefined, "Greninja form selection"); case Species.ZYGARDE: - return Utils.randSeedInt(3); + return Utils.randSeedInt(3, undefined, "Zygarde form selection"); case Species.MINIOR: - return Utils.randSeedInt(6); + return Utils.randSeedInt(6, undefined, "Minior color selection"); case Species.ALCREMIE: - return Utils.randSeedInt(9); + return Utils.randSeedInt(9, undefined, "Alcremie form selection"); case Species.MEOWSTIC: case Species.INDEEDEE: case Species.BASCULEGION: @@ -1440,7 +1437,7 @@ export default class BattleScene extends SceneBase { case Species.WORMADAM: case Species.ROTOM: case Species.LYCANROC: - return Utils.randSeedInt(species.forms.length); + return Utils.randSeedInt(species.forms.length, undefined, "Non-area-specific form selection"); } return 0; } @@ -1451,7 +1448,7 @@ export default class BattleScene extends SceneBase { private getGeneratedOffsetGym(): boolean { let ret = false; this.executeWithSeedOffset(() => { - ret = !Utils.randSeedInt(2); + ret = !Utils.randSeedInt(2, undefined, "Random gym offset"); }, 0, this.seed.toString()); return ret; } @@ -1459,7 +1456,7 @@ export default class BattleScene extends SceneBase { private getGeneratedWaveCycleOffset(): integer { let ret = 0; this.executeWithSeedOffset(() => { - ret = Utils.randSeedInt(8) * 5; + ret = Utils.randSeedInt(8, undefined, "Random day/night cycle offset 5 x") * 5; }, 0, this.seed.toString()); return ret; } @@ -1481,7 +1478,7 @@ export default class BattleScene extends SceneBase { isBoss = true; } else { this.executeWithSeedOffset(() => { - isBoss = waveIndex % 10 === 0 || (this.gameMode.hasRandomBosses && Utils.randSeedInt(100) < Math.min(Math.max(Math.ceil((waveIndex - 250) / 50), 0) * 2, 30)); + isBoss = waveIndex % 10 === 0 || (this.gameMode.hasRandomBosses && Utils.randSeedInt(100, undefined, "Boss HP segments") < Math.min(Math.max(Math.ceil((waveIndex - 250) / 50), 0) * 2, 30)); }, waveIndex << 2); } if (!isBoss) { @@ -1508,7 +1505,7 @@ export default class BattleScene extends SceneBase { const infectedIndexes: integer[] = []; const spread = (index: number, spreadTo: number) => { const partyMember = party[index + spreadTo]; - if (!partyMember.pokerus && !Utils.randSeedInt(10)) { + if (!partyMember.pokerus && !Utils.randSeedInt(10, undefined, "Pokerus spread chance")) { partyMember.pokerus = true; infectedIndexes.push(index + spreadTo); } @@ -1556,7 +1553,6 @@ export default class BattleScene extends SceneBase { this.rngCounter = 0; this.battleRNGState = Phaser.Math.RND.state() this.battleBaseRNGState = Phaser.Math.RND.state() - //this.setScoreText("RNG: 0") } executeWithSeedOffset(func: Function, offset: integer, seedOverride?: string): void { @@ -1573,7 +1569,6 @@ export default class BattleScene extends SceneBase { this.rngSeedOverride = seedOverride || ""; func(); Phaser.Math.RND.state(state); - //this.setScoreText("RNG: " + tempRngCounter + " (Last sim: " + this.rngCounter + ")") this.rngCounter = tempRngCounter; this.rngOffset = tempRngOffset; this.rngSeedOverride = tempRngSeedOverride; @@ -1819,7 +1814,7 @@ export default class BattleScene extends SceneBase { } return s; }))] : allSpecies.filter(s => s.isCatchable()); - return filteredSpecies[Utils.randSeedInt(filteredSpecies.length)]; + return filteredSpecies[Utils.randSeedInt(filteredSpecies.length, undefined, "Random Species")]; } generateRandomBiome(waveIndex: integer): Biome { @@ -1835,7 +1830,7 @@ export default class BattleScene extends SceneBase { biomeThresholds.push(totalWeight); } - const randInt = Utils.randSeedInt(totalWeight); + const randInt = Utils.randSeedInt(totalWeight, undefined, "Random biome"); for (const biome of biomes) { if (randInt < biomeThresholds[biome]) { @@ -1843,7 +1838,7 @@ export default class BattleScene extends SceneBase { } } - return biomes[Utils.randSeedInt(biomes.length)]; + return biomes[Utils.randSeedInt(biomes.length, undefined, "Random biome (initial roll failed)")]; } isBgmPlaying(): boolean { @@ -2671,7 +2666,7 @@ export default class BattleScene extends SceneBase { pokemonModifierChance = Math.ceil(pokemonModifierChance * this.currentBattle.trainer.getPartyMemberModifierChanceMultiplier(i)); // eslint-disable-line let count = 0; for (let c = 0; c < chances; c++) { - if (!Utils.randSeedInt(modifierChance)) { + if (!Utils.randSeedInt(modifierChance, undefined, "Modifier roll")) { count++; } } @@ -2796,7 +2791,7 @@ export default class BattleScene extends SceneBase { if (mods.length < 1) { return mods; } - const rand = Utils.randSeedInt(mods.length); + const rand = Utils.randSeedInt(mods.length, undefined, "Apply shuffled modifiers"); return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))]; }; modifiers = shuffleModifiers(modifiers); @@ -2928,20 +2923,20 @@ export default class BattleScene extends SceneBase { const keys: string[] = []; const playerParty = this.getParty(); playerParty.forEach(p => { - keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant)); - keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant, true)); - keys.push("cry/" + p.species.getCryKey(p.species.formIndex)); - if (p.fusionSpecies && p.getSpeciesForm() !== p.getFusionSpeciesForm()) { - keys.push("cry/"+p.getFusionSpeciesForm().getCryKey(p.fusionSpecies.formIndex)); + keys.push(p.getSpriteKey(true)); + keys.push(p.getBattleSpriteKey(true, true)); + keys.push("cry/" + p.species.getCryKey(p.formIndex)); + if (p.fusionSpecies) { + keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex)); } }); // enemyParty has to be operated on separately from playerParty because playerPokemon =/= enemyPokemon const enemyParty = this.getEnemyParty(); enemyParty.forEach(p => { - keys.push(p.species.getSpriteKey(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant)); - keys.push("cry/" + p.species.getCryKey(p.species.formIndex)); - if (p.fusionSpecies && p.getSpeciesForm() !== p.getFusionSpeciesForm()) { - keys.push("cry/"+p.getFusionSpeciesForm().getCryKey(p.fusionSpecies.formIndex)); + keys.push(p.getSpriteKey(true)); + keys.push("cry/" + p.species.getCryKey(p.formIndex)); + if (p.fusionSpecies) { + keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex)); } }); return keys; diff --git a/src/battle.ts b/src/battle.ts index 0030b61bbd7..772773bf67d 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -387,7 +387,7 @@ export default class Battle { * @param min The minimum integer to pick, default `0` * @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1) */ - randSeedInt(scene: BattleScene, range: number, min: number = 0, reason: string = "Unlabeled randSeedInt"): number { + randSeedInt(scene: BattleScene, range: number, min: number = 0, reason?: string): number { if (range <= 1) { return min; } @@ -402,8 +402,7 @@ export default class Battle { } scene.rngCounter = this.rngCounter++; scene.rngSeedOverride = this.battleSeed; - const ret = Utils.randSeedInt(range, min); - console.log("[RNG] " + reason, ret) + const ret = Utils.randSeedInt(range, min, reason); this.battleSeedState = Phaser.Math.RND.state(); Phaser.Math.RND.state(state); //scene.setScoreText("RNG: " + tempRngCounter + " (Last sim: " + this.rngCounter + ")") @@ -474,7 +473,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand scene.executeWithSeedOffset(() => { for (const trainerPoolEntry of trainerPool) { const trainerType = Array.isArray(trainerPoolEntry) - ? Utils.randSeedItem(trainerPoolEntry) + ? Utils.randSeedItem(trainerPoolEntry, "Random trainer helper function") : trainerPoolEntry; trainerTypes.push(trainerType); } @@ -482,7 +481,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand let trainerGender = TrainerVariant.DEFAULT; if (randomGender) { - trainerGender = (Utils.randInt(2) === 0) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT; + trainerGender = (Utils.randInt(2, undefined, "Random trainer helper function") === 0) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT; } /* 1/3 chance for evil team grunts to be double battles */ @@ -490,7 +489,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]); if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) { - return new Trainer(scene, trainerTypes[rand], (Utils.randInt(3) === 0) ? TrainerVariant.DOUBLE : trainerGender); + return new Trainer(scene, trainerTypes[rand], (Utils.randInt(3, undefined, "Evil grunt selection") === 0) ? TrainerVariant.DOUBLE : trainerGender); } return new Trainer(scene, trainerTypes[rand], trainerGender); @@ -511,7 +510,7 @@ export interface FixedBattleConfigs { */ export const classicFixedBattles: FixedBattleConfigs = { [5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) - .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), + .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.YOUNGSTER, Utils.randSeedInt(2, undefined, "Youngster gender") ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), [8]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), [25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) diff --git a/src/data/ability.ts b/src/data/ability.ts index d54f1b5e608..ec1c8ded419 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -859,7 +859,7 @@ export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr { applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status && (this.chance === -1 || pokemon.randSeedInt(100, undefined, "Random chance to apply effect after something makes contact") < this.chance)) { - const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length, undefined, "Selecting an effect to apply")]; + const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length, undefined, "Choosing status to apply")]; if (simulated) { return attacker.canSetStatus(effect, true, false, pokemon); } else { @@ -1708,7 +1708,7 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr { applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { /**Status inflicted by abilities post attacking are also considered additional effects.*/ if (!attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && !simulated && pokemon !== attacker && (!this.contactRequired || move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100, undefined, "Chance to apply status after attacking") < this.chance && !pokemon.status) { - const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length, undefined, "Selecting a status to apply")]; + const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length, undefined, "Choosing effect to apply")]; return attacker.trySetStatus(effect, true, pokemon); } @@ -1761,7 +1761,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr { if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) { const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferrable); if (heldItems.length) { - const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length, undefined, "Choosing an item to steal")]; + const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length, undefined, "Choosing item to steal (guaranteed steal)")]; pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false).then(success => { if (success) { pokemon.scene.queueMessage(i18next.t("abilityTriggers:postDefendStealHeldItem", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), attackerName: attacker.name, stolenItemType: stolenItem.type.name })); @@ -2256,7 +2256,7 @@ export class PostSummonCopyAbilityAbAttr extends PostSummonAbAttr { let target: Pokemon; if (targets.length > 1) { - pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); + pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets, "Target to copy ability from"), pokemon.scene.currentBattle.waveIndex); } else { target = targets[0]; } @@ -2377,7 +2377,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { let target: Pokemon; if (targets.length > 1) { - pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); + pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets, "Target to transform into"), pokemon.scene.currentBattle.waveIndex); } else { target = targets[0]; } @@ -2676,7 +2676,7 @@ export class ConfusionOnStatusEffectAbAttr extends PostAttackAbAttr { if (simulated) { return defender.canAddTag(BattlerTagType.CONFUSED); } else { - return defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedIntRange(2, 5, "Duration of Confusion effect"), move.id, defender.id); + return defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedIntRange(2, 5, "Chance to apply effect after attacking"), move.id, defender.id); } } return false; @@ -3447,7 +3447,7 @@ export class PostTurnLootAbAttr extends PostTurnAbAttr { return true; } - const randomIdx = Utils.randSeedInt(berriesEaten.length); + const randomIdx = Utils.randSeedInt(berriesEaten.length, undefined, "Randomly select a berry to regenerate"); const chosenBerryType = berriesEaten[randomIdx]; const chosenBerry = new BerryModifierType(chosenBerryType); berriesEaten.splice(randomIdx); // Remove berry from memory @@ -3500,12 +3500,12 @@ export class MoodyAbAttr extends PostTurnAbAttr { if (!simulated) { if (canRaise.length > 0) { - const raisedStat = canRaise[pokemon.randSeedInt(canRaise.length)]; + const raisedStat = canRaise[pokemon.randSeedInt(canRaise.length, undefined, "Choosing a random raisable stat to increase")]; canLower = canRaise.filter(s => s !== raisedStat); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ raisedStat ], 2)); } if (canLower.length > 0) { - const loweredStat = canLower[pokemon.randSeedInt(canLower.length)]; + const loweredStat = canLower[pokemon.randSeedInt(canLower.length, undefined, "Choosing a random lowerable stat to decrease")]; pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ loweredStat ], -1)); } } @@ -3943,7 +3943,7 @@ export class PostBattleLootAbAttr extends PostBattleAbAttr { applyPostBattle(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { const postBattleLoot = pokemon.scene.currentBattle.postBattleLoot; if (!simulated && postBattleLoot.length) { - const randItem = Utils.randSeedItem(postBattleLoot); + const randItem = Utils.randSeedItem(postBattleLoot, "Randomly selecting item to Pickup"); //@ts-ignore - TODO see below if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, true, 1, true)) { // TODO: fix. This is a promise!? postBattleLoot.splice(postBattleLoot.indexOf(randItem), 1); @@ -4712,11 +4712,6 @@ export function applyPreDefendAbAttrs(attrType: Constructor, pokemon: Pokemon, attacker: Pokemon, move: Move | null, cancelled: Utils.BooleanHolder | null, simulated: boolean = false, ...args: any[]): Promise { return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args), args, false, simulated); } -export function applyPreDefendAbAttrsNoApply(attrType: Constructor, - pokemon: Pokemon, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { - const simulated = args.length > 1 && args[1]; - return applyAbAttrsInternalNoApply(attrType, pokemon, (attr, passive) => attr.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args), args, false, false, simulated); -} export function applyPostDefendAbAttrs(attrType: Constructor, pokemon: Pokemon, attacker: Pokemon, move: Move, hitResult: HitResult | null, simulated: boolean = false, ...args: any[]): Promise { @@ -5066,7 +5061,7 @@ export function initAbilities() { .bypassFaint() .ignorable(), new Ability(Abilities.SHED_SKIN, 3) - .conditionalAttr(pokemon => !Utils.randSeedInt(3), PostTurnResetStatusAbAttr), + .conditionalAttr(pokemon => !Utils.randSeedInt(3, undefined, "Random chance to activate Shed Skin"), PostTurnResetStatusAbAttr), new Ability(Abilities.GUTS, 3) .attr(BypassBurnDamageReductionAbAttr) .conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), StatMultiplierAbAttr, Stat.ATK, 1.5), @@ -5281,7 +5276,7 @@ export function initAbilities() { .attr(PostDefendMoveDisableAbAttr, 30) .bypassFaint(), new Ability(Abilities.HEALER, 5) - .conditionalAttr(pokemon => pokemon.getAlly() && Utils.randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true), + .conditionalAttr(pokemon => pokemon.getAlly() && Utils.randSeedInt(10, undefined, "Random chance to apply Healer") < 3, PostTurnResetStatusAbAttr, true), new Ability(Abilities.FRIEND_GUARD, 5) .ignorable() .unimplemented(), diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index a0f34cf85fc..a4fa3ef16ef 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -601,7 +601,7 @@ export class ConfusedTag extends BattlerTag { pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); // 1/3 chance of hitting self with a 40 base power move - if (pokemon.randSeedInt(3, undefined, "Self-hit confusion roll") === 0) { + if (pokemon.randSeedInt(3, undefined, "Confusion chance") === 0) { const atk = pokemon.getEffectiveStat(Stat.ATK); const def = pokemon.getEffectiveStat(Stat.DEF); const damage = Utils.toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedIntRange(85, 100, "Damage roll for Confusion") / 100)); @@ -853,12 +853,6 @@ export class FrenzyTag extends BattlerTag { } } -export class ChargingTag extends BattlerTag { - constructor(sourceMove: Moves, sourceId: number) { - super(BattlerTagType.CHARGING, BattlerTagLapseType.CUSTOM, 1, sourceMove, sourceId); - } -} - export class EncoreTag extends BattlerTag { public moveId: Moves; diff --git a/src/data/berry.ts b/src/data/berry.ts index 01325ee39dd..eabe93ce110 100644 --- a/src/data/berry.ts +++ b/src/data/berry.ts @@ -114,7 +114,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { if (pokemon.battleData) { pokemon.battleData.berriesEaten.push(berryType); } - const randStat = Utils.randSeedInt(Stat.SPD, Stat.ATK); + const randStat = Utils.randSeedInt(Stat.SPD, Stat.ATK, "Randomly selecting a stat to raise"); const stages = new Utils.NumberHolder(2); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randStat ], stages.value)); diff --git a/src/data/biomes.ts b/src/data/biomes.ts index 0e37cc94ff5..a2b63034886 100644 --- a/src/data/biomes.ts +++ b/src/data/biomes.ts @@ -7666,7 +7666,7 @@ export function initBiomes() { if (biome === Biome.END) { const biomeList = Object.keys(Biome).filter(key => !isNaN(Number(key))); biomeList.pop(); // Removes Biome.END from the list - const randIndex = Utils.randInt(biomeList.length, 1); // Will never be Biome.TOWN + const randIndex = Utils.randInt(biomeList.length, 1, "Traversing biomes"); // Will never be Biome.TOWN biome = Biome[biomeList[randIndex]]; } const linkedBiomes: (Biome | [ Biome, integer ])[] = Array.isArray(biomeLinks[biome]) diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 2205519c532..5e51badfc40 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -464,7 +464,7 @@ export class SingleGenerationChallenge extends Challenge { trainerTypes = [ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL ]; break; case 190: - trainerTypes = [ TrainerType.BLUE, Utils.randSeedItem([ TrainerType.RED, TrainerType.LANCE_CHAMPION ]), Utils.randSeedItem([ TrainerType.STEVEN, TrainerType.WALLACE ]), TrainerType.CYNTHIA, Utils.randSeedItem([ TrainerType.ALDER, TrainerType.IRIS ]), TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, Utils.randSeedItem([ TrainerType.GEETA, TrainerType.NEMONA ]) ]; + trainerTypes = [ TrainerType.BLUE, Utils.randSeedItem([ TrainerType.RED, TrainerType.LANCE_CHAMPION ], "Champion (Gen 2)"), Utils.randSeedItem([ TrainerType.STEVEN, TrainerType.WALLACE ], "Champion (Gen 3)"), TrainerType.CYNTHIA, Utils.randSeedItem([ TrainerType.ALDER, TrainerType.IRIS ], "Champion (Gen 5)"), TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, Utils.randSeedItem([ TrainerType.GEETA, TrainerType.NEMONA ], "Champion (Gen 9+)") ]; break; } if (trainerTypes.length === 0) { diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index 370b13ea3a3..801640a5549 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -49,7 +49,7 @@ export function getDailyRunStarters(scene: BattleScene, seed: string): Starter[] const costSpecies = Object.keys(speciesStarters) .map(s => parseInt(s) as Species) .filter(s => speciesStarters[s] === cost); - const randPkmSpecies = getPokemonSpecies(Utils.randSeedItem(costSpecies)); + const randPkmSpecies = getPokemonSpecies(Utils.randSeedItem(costSpecies, "Daily starters")); const starterSpecies = getPokemonSpecies(randPkmSpecies.getTrainerSpeciesForLevel(startingLevel, true, PartyMemberStrength.STRONGER)); starters.push(getDailyRunStarter(scene, starterSpecies, startingLevel)); } diff --git a/src/data/dialogue.ts b/src/data/dialogue.ts index a2ba06b657f..355f05523d1 100644 --- a/src/data/dialogue.ts +++ b/src/data/dialogue.ts @@ -1569,8 +1569,7 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { "dialogue:roark.victory.1", "dialogue:roark.victory.2", "dialogue:roark.victory.3", - "dialogue:roark.victory.4", - "dialogue:roark.victory.5" + "dialogue:roark.victory.4" ], defeat: [ "dialogue:roark.defeat.1", diff --git a/src/data/egg.ts b/src/data/egg.ts index ce27030ebef..91cec2d756f 100644 --- a/src/data/egg.ts +++ b/src/data/egg.ts @@ -151,7 +151,7 @@ export class Egg { this.checkForPityTierOverrides(eggOptions.scene!); // TODO: is this bang correct? } - this._id = eggOptions?.id ?? Utils.randInt(EGG_SEED, EGG_SEED * this._tier); + this._id = eggOptions?.id ?? Utils.randInt(EGG_SEED, EGG_SEED * this._tier, "eg"); this._sourceType = eggOptions?.sourceType ?? undefined; this._hatchWaves = eggOptions?.hatchWaves ?? this.getEggTierDefaultHatchWaves(); @@ -223,14 +223,14 @@ export class Egg { let pokemonSpecies = getPokemonSpecies(this._species); // Special condition to have Phione eggs also have a chance of generating Manaphy if (this._species === Species.PHIONE) { - pokemonSpecies = getPokemonSpecies(Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) ? Species.PHIONE : Species.MANAPHY); + pokemonSpecies = getPokemonSpecies(Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE, undefined, "Chance of Manaphy Egg not scamming you") ? Species.PHIONE : Species.MANAPHY); } // Sets the hidden ability if a hidden ability exists and // the override is set or the egg hits the chance let abilityIndex: number | undefined = undefined; - const sameSpeciesEggHACheck = (this._sourceType === EggSourceType.SAME_SPECIES_EGG && !Utils.randSeedInt(SAME_SPECIES_EGG_HA_RATE)); - const gachaEggHACheck = (!(this._sourceType === EggSourceType.SAME_SPECIES_EGG) && !Utils.randSeedInt(GACHA_EGG_HA_RATE)); + const sameSpeciesEggHACheck = (this._sourceType === EggSourceType.SAME_SPECIES_EGG && !Utils.randSeedInt(SAME_SPECIES_EGG_HA_RATE, undefined, "Hidden Ability chance (Candy egg)")); + const gachaEggHACheck = (!(this._sourceType === EggSourceType.SAME_SPECIES_EGG) && !Utils.randSeedInt(GACHA_EGG_HA_RATE, undefined, "Hidden Ability chance (Gacha)")); if (pokemonSpecies.abilityHidden && (this._overrideHiddenAbility || sameSpeciesEggHACheck || gachaEggHACheck)) { abilityIndex = 2; } @@ -240,7 +240,7 @@ export class Egg { ret.shiny = this._isShiny; ret.variant = this._variantTier; - const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295)); + const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295, undefined, "Egg IVs")); for (let s = 0; s < ret.ivs.length; s++) { ret.ivs[s] = Math.max(ret.ivs[s], secondaryIvs[s]); @@ -326,7 +326,7 @@ export class Egg { break; } - return Utils.randSeedInt(baseChance * Math.pow(2, 3 - this.tier)) ? Utils.randSeedInt(3) : 3; + return Utils.randSeedInt(baseChance * Math.pow(2, 3 - this.tier), undefined, "Choosing whether to give Rare Egg Move or not") ? Utils.randSeedInt(3, undefined, "Common Egg Move selection") : 3; } private getEggTierDefaultHatchWaves(eggTier?: EggTier): number { @@ -347,7 +347,7 @@ export class Egg { private rollEggTier(): EggTier { const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? 1 : 0; - const tierValue = Utils.randInt(256); + const tierValue = Utils.randInt(256, undefined, "Choosing egg tier"); return tierValue >= 52 + tierValueOffset ? EggTier.COMMON : tierValue >= 8 + tierValueOffset ? EggTier.GREAT : tierValue >= 1 + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER; } @@ -361,11 +361,11 @@ export class Egg { * the species that was the legendary focus at the time */ if (this.isManaphyEgg()) { - const rand = Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE); + const rand = Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE, undefined, "Manaphy Egg chance"); return rand ? Species.PHIONE : Species.MANAPHY; } else if (this.tier === EggTier.MASTER && this._sourceType === EggSourceType.GACHA_LEGENDARY) { - if (!Utils.randSeedInt(2)) { + if (!Utils.randSeedInt(2, undefined, "Chance to replace Legendary Egg with gacha target")) { return getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp); } } @@ -437,7 +437,7 @@ export class Egg { let species: Species; - const rand = Utils.randSeedInt(totalWeight); + const rand = Utils.randSeedInt(totalWeight, undefined, "Random egg species"); for (let s = 0; s < speciesWeights.length; s++) { if (rand < speciesWeights[s]) { species = speciesPool[s]; @@ -472,7 +472,7 @@ export class Egg { break; } - return !Utils.randSeedInt(shinyChance); + return !Utils.randSeedInt(shinyChance, undefined, "Shiny chance"); } // Uses the same logic as pokemon.generateVariant(). I would like to only have this logic in one @@ -482,7 +482,7 @@ export class Egg { return VariantTier.COMMON; } - const rand = Utils.randSeedInt(10); + const rand = Utils.randSeedInt(10, undefined, "Shiny variant selection"); if (rand >= 4) { return VariantTier.COMMON; // 6/10 } else if (rand >= 1) { diff --git a/src/data/move.ts b/src/data/move.ts index bda9125bf9e..ca32ebeae4d 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1980,6 +1980,13 @@ export class StatusEffectAttr extends MoveEffectAttr { return false; } } + + if (user !== target && target.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY)) { + if (move.category === MoveCategory.STATUS) { + user.scene.queueMessage(i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(target)})); + } + return false; + } if ((!pokemon.status || (pokemon.status.effect === this.effect && moveChance < 0)) && pokemon.trySetStatus(this.effect, true, user, this.cureTurn)) { applyPostAttackAbAttrs(ConfusionOnStatusEffectAbAttr, user, target, move, null, false, this.effect); @@ -2004,7 +2011,7 @@ export class MultiStatusEffectAttr extends StatusEffectAttr { } apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - this.effect = Utils.randSeedItem(this.effects); + this.effect = Utils.randSeedItem(this.effects, "Selecting status effect to apply"); const result = super.apply(user, target, move, args); return result; } @@ -2080,6 +2087,7 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr { } //*/ + console.log("realInRange direct call @ StealHeldItemChanceAttr: " + rand) if (rand >= this.chance) { return resolve(false); } @@ -2632,7 +2640,7 @@ export class StatStageChangeAttr extends MoveEffectAttr { } const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); - if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100, undefined, "Chance to apply status condition") < moveChance) { + if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100, undefined, "Random chance to raise stat") < moveChance) { const stages = this.getLevels(user); user.scene.unshiftPhase(new StatStageChangePhase(user.scene, (this.selfTarget ? user : target).getBattlerIndex(), this.selfTarget, this.stats, stages, this.showMessage)); return true; @@ -2718,7 +2726,7 @@ export class AcupressureStatStageChangeAttr extends MoveEffectAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { const randStats = BATTLE_STATS.filter(s => target.getStatStage(s) < 6); if (randStats.length > 0) { - const boostStat = [randStats[user.randSeedInt(randStats.length)]]; + const boostStat = [randStats[user.randSeedInt(randStats.length, undefined, "Choosing stat to raise")]]; user.scene.unshiftPhase(new StatStageChangePhase(user.scene, target.getBattlerIndex(), this.selfTarget, boostStat, 2)); return true; } @@ -3051,7 +3059,7 @@ export class BeatUpAttr extends VariablePowerAttr { const doublePowerChanceMessageFunc = (user: Pokemon, target: Pokemon, move: Move) => { let message: string = ""; user.scene.executeWithSeedOffset(() => { - const rand = Utils.randSeedInt(100); + const rand = Utils.randSeedInt(100, undefined, "Doubled power chance (applying message)"); if (rand < move.chance) { message = i18next.t("moveTriggers:goingAllOutForAttack", {pokemonName: getPokemonNameWithAffix(user)}); } @@ -3062,7 +3070,7 @@ const doublePowerChanceMessageFunc = (user: Pokemon, target: Pokemon, move: Move export class DoublePowerChanceAttr extends VariablePowerAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { let rand: integer; - user.scene.executeWithSeedOffset(() => rand = Utils.randSeedInt(100), user.scene.currentBattle.turn << 6, user.scene.waveSeed); + user.scene.executeWithSeedOffset(() => rand = Utils.randSeedInt(100, undefined, "Doubled power chance (applying move)"), user.scene.currentBattle.turn << 6, user.scene.waveSeed); if (rand! < move.chance) { const power = args[0] as Utils.NumberHolder; power.value *= 2; @@ -3323,7 +3331,7 @@ const magnitudeMessageFunc = (user: Pokemon, target: Pokemon, move: Move) => { user.scene.executeWithSeedOffset(() => { const magnitudeThresholds = [ 5, 15, 35, 65, 75, 95 ]; - const rand = Utils.randSeedInt(100); + const rand = Utils.randSeedInt(100, undefined, "Magnitude selection (message)"); let m = 0; for (; m < magnitudeThresholds.length; m++) { @@ -3346,7 +3354,7 @@ export class MagnitudePowerAttr extends VariablePowerAttr { let rand: integer; - user.scene.executeWithSeedOffset(() => rand = Utils.randSeedInt(100), user.scene.currentBattle.turn << 6, user.scene.waveSeed); + user.scene.executeWithSeedOffset(() => rand = Utils.randSeedInt(100, undefined, "Magnitude selection (move)"), user.scene.currentBattle.turn << 6, user.scene.waveSeed); let m = 0; for (; m < magnitudeThresholds.length; m++) { @@ -3471,7 +3479,7 @@ export class PresentPowerAttr extends VariablePowerAttr { */ const firstHit = (user.turnData.hitCount === user.turnData.hitsLeft); - const powerSeed = Utils.randSeedInt(firstHit ? 100 : 80); + const powerSeed = Utils.randSeedInt(firstHit ? 100 : 80, undefined, "Present healing chance"); if (powerSeed <= 40) { (args[0] as Utils.NumberHolder).value = 40; } else if (40 < powerSeed && powerSeed <= 70) { @@ -3919,7 +3927,7 @@ export class ShellSideArmCategoryAttr extends VariableMoveCategoryAttr { } else if (atkRatio === specialRatio && args[1] == "SIM") { category.value = MoveCategory.PHYSICAL; return true; - } else if (atkRatio === specialRatio && user.randSeedInt(2, undefined, "Randomly selecting an attack type for Shell Side Arm") === 0) { + } else if (atkRatio === specialRatio && user.randSeedInt(2, undefined, "Random category for Shell Side Arm") === 0) { category.value = MoveCategory.PHYSICAL; return true; } @@ -4394,7 +4402,7 @@ export class FrenzyAttr extends MoveEffectAttr { } if (!user.getTag(BattlerTagType.FRENZY) && !user.getMoveQueue().length) { - const turnCount = user.randSeedIntRange(1, 2, "Frenzy targeting"); + const turnCount = user.randSeedIntRange(1, 2, "Frenzy duration"); new Array(turnCount).fill(null).map(() => user.getMoveQueue().push({ move: move.id, targets: [ target.getBattlerIndex() ], ignorePP: true })); user.addTag(BattlerTagType.FRENZY, turnCount, move.id, user.id); } else { @@ -4446,8 +4454,8 @@ export class AddBattlerTagAttr extends MoveEffectAttr { } const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); - if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100, undefined, "Chance to apply battler tag") < moveChance) { - return (this.selfTarget ? user : target).addTag(this.tagType, user.randSeedIntRange(this.turnCountMin, this.turnCountMax, "Duration of effect"), move.id, user.id); + if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100, undefined, "Chance to add Battler Tag") < moveChance) { + return (this.selfTarget ? user : target).addTag(this.tagType, user.randSeedIntRange(this.turnCountMin, this.turnCountMax, "Battler Tag duration"), move.id, user.id); } return false; @@ -4572,7 +4580,7 @@ export class JawLockAttr extends AddBattlerTagAttr { } const moveChance = this.getMoveChance(user, target, move, this.selfTarget); - if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) { + if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100, undefined, "Chance to apply Trap tag (Jaw Lock)") < moveChance) { /** * Add the tag to both the user and the target. * The target's tag source is considered to be the user and vice versa @@ -4666,6 +4674,17 @@ export class ConfuseAttr extends AddBattlerTagAttr { constructor(selfTarget?: boolean) { super(BattlerTagType.CONFUSED, selfTarget, false, 2, 5); } + + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (!this.selfTarget && target.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY)) { + if (move.category === MoveCategory.STATUS) { + user.scene.queueMessage(i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(target)})); + } + return false; + } + + return super.apply(user, target, move, args); + } } export class RechargeAttr extends AddBattlerTagAttr { @@ -4699,7 +4718,7 @@ export class ProtectAttr extends AddBattlerTagAttr { timesUsed++; } if (timesUsed) { - return !user.randSeedInt(Math.pow(3, timesUsed), undefined, "Chance for Protect-like move to fail"); + return !user.randSeedInt(Math.pow(3, timesUsed), undefined, "Chance for Protection move to succeed"); } return true; }); @@ -4855,7 +4874,7 @@ export class AddArenaTrapTagHitAttr extends AddArenaTagAttr { const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); const side = (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; const tag = user.scene.arena.getTagOnSide(this.tagType, side) as ArenaTrapTag; - if ((moveChance < 0 || moveChance === 100 || user.randSeedInt(100, undefined, "Chance to apply trap") < moveChance) && user.getLastXMoves(1)[0].result === MoveResult.SUCCESS) { + if ((moveChance < 0 || moveChance === 100 || user.randSeedInt(100, undefined, "Chance to add arena tag on hit") < moveChance) && user.getLastXMoves(1)[0].result === MoveResult.SUCCESS) { user.scene.arena.addTag(this.tagType, 0, move.id, user.id, side); if (!tag) { return true; @@ -5009,7 +5028,7 @@ export class RevivalBlessingAttr extends MoveEffectAttr { && user.scene.getEnemyParty().findIndex(p => p.isFainted() && !p.isBoss()) > -1) { // Selects a random fainted pokemon const faintedPokemon = user.scene.getEnemyParty().filter(p => p.isFainted() && !p.isBoss()); - const pokemon = faintedPokemon[user.randSeedInt(faintedPokemon.length, undefined, "Randomly selecting a Pokemon to revive")]; + const pokemon = faintedPokemon[user.randSeedInt(faintedPokemon.length, undefined, "Choosing Pokemon to revive")]; const slotIndex = user.scene.getEnemyParty().findIndex(p => pokemon.id === p.id); pokemon.resetStatus(); pokemon.heal(Math.min(Utils.toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp())); @@ -5319,7 +5338,7 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr { const moveset = (!this.enemyMoveset ? user : target).getMoveset(); const moves = moveset.filter(m => !m?.getMove().hasFlag(MoveFlags.IGNORE_VIRTUAL)); if (moves.length) { - const move = moves[user.randSeedInt(moves.length, undefined, "Randomly selecting a known move")]; + const move = moves[user.randSeedInt(moves.length, undefined, "Choosing random move from moveset")]; const moveIndex = moveset.findIndex(m => m?.moveId === move?.moveId); const moveTargets = getMoveTargets(user, move?.moveId!); // TODO: is this bang correct? if (!moveTargets.targets.length) { @@ -6458,7 +6477,7 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr { if (!validTypes.length) { return false; } - const type = validTypes[user.randSeedInt(validTypes.length, undefined, "Randomly selecting a type for Conversion2 that resists Type." + Utils.getEnumKeys(Type)[moveData.type])]; + const type = validTypes[user.randSeedInt(validTypes.length, undefined, "Choosing type to transform into (Conversion2)")]; user.summonData.types = [ type ]; user.scene.queueMessage(i18next.t("battle:transformedIntoType", {pokemonName: getPokemonNameWithAffix(user), type: Utils.toReadableString(Type[type])})); user.updateInfo(); @@ -7211,7 +7230,7 @@ export function initMoves() { .attr(FriendshipPowerAttr, true), new StatusMove(Moves.SAFEGUARD, Type.NORMAL, -1, 25, -1, 0, 2) .target(MoveTarget.USER_SIDE) - .unimplemented(), + .attr(AddArenaTagAttr, ArenaTagType.SAFEGUARD, 5, true, true), new StatusMove(Moves.PAIN_SPLIT, Type.NORMAL, -1, 20, -1, 0, 2) .attr(HpSplitAttr) .condition(failOnBossCondition), @@ -7400,7 +7419,7 @@ export function initMoves() { .attr(RemoveScreensAttr), new StatusMove(Moves.YAWN, Type.NORMAL, -1, 10, -1, 0, 3) .attr(AddBattlerTagAttr, BattlerTagType.DROWSY, false, true) - .condition((user, target, move) => !target.status), + .condition((user, target, move) => !target.status && !target.scene.arena.getTagOnSide(ArenaTagType.SAFEGUARD, target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY)), new AttackMove(Moves.KNOCK_OFF, Type.DARK, MoveCategory.PHYSICAL, 65, 100, 20, -1, 0, 3) .attr(MovePowerMultiplierAttr, (user, target, move) => target.getHeldItems().filter(i => i.isTransferrable).length > 0 ? 1.5 : 1) .attr(RemoveHeldItemAttr, false), @@ -8954,8 +8973,8 @@ export function initMoves() { new AttackMove(Moves.SKITTER_SMACK, Type.BUG, MoveCategory.PHYSICAL, 70, 90, 10, 100, 0, 8) .attr(StatStageChangeAttr, [ Stat.SPATK ], -1), new AttackMove(Moves.BURNING_JEALOUSY, Type.FIRE, MoveCategory.SPECIAL, 70, 100, 5, 100, 0, 8) - .target(MoveTarget.ALL_NEAR_ENEMIES) - .partial(), + .attr(StatusIfBoostedAttr, StatusEffect.BURN) + .target(MoveTarget.ALL_NEAR_ENEMIES), new AttackMove(Moves.LASH_OUT, Type.DARK, MoveCategory.PHYSICAL, 75, 100, 5, -1, 0, 8) .attr(MovePowerMultiplierAttr, (user, _target, _move) => user.turnData.statStagesDecreased ? 2 : 1), new AttackMove(Moves.POLTERGEIST, Type.GHOST, MoveCategory.PHYSICAL, 110, 90, 5, -1, 0, 8) @@ -9405,12 +9424,11 @@ export function initMoves() { new AttackMove(Moves.HARD_PRESS, Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 9) .attr(OpponentHighHpPowerAttr, 100), new StatusMove(Moves.DRAGON_CHEER, Type.DRAGON, -1, 15, -1, 0, 9) - .attr(AddBattlerTagAttr, BattlerTagType.CRIT_BOOST, false, true) - .target(MoveTarget.NEAR_ALLY) - .partial(), + .attr(AddBattlerTagAttr, BattlerTagType.DRAGON_CHEER, false, true) + .target(MoveTarget.NEAR_ALLY), new AttackMove(Moves.ALLURING_VOICE, Type.FAIRY, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 9) - .soundBased() - .partial(), + .attr(AddBattlerTagIfBoostedAttr, BattlerTagType.CONFUSED) + .soundBased(), new AttackMove(Moves.TEMPER_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 75, 100, 10, -1, 0, 9) .attr(MovePowerMultiplierAttr, (user, target, move) => user.getLastXMoves(2)[1]?.result === MoveResult.MISS || user.getLastXMoves(2)[1]?.result === MoveResult.FAIL ? 2 : 1), new AttackMove(Moves.SUPERCELL_SLAM, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 95, 15, -1, 0, 9) @@ -9433,4 +9451,4 @@ export function initMoves() { selfStatLowerMoves.push(m.id); } }); -} \ No newline at end of file +} diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index dd0942756b1..87458dbfdc9 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -1157,7 +1157,7 @@ export const pokemonEvolutions: PokemonEvolutions = { [Species.TANDEMAUS]: [ new SpeciesFormEvolution(Species.MAUSHOLD, "", "three", 25, null, new SpeciesEvolutionCondition(p => { let ret = false; - p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); + p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4, undefined, "Tandemaus form selection"), p.id); return ret; })), new SpeciesEvolution(Species.MAUSHOLD, 25, null, null) @@ -1325,7 +1325,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new SpeciesEvolutionCondition(p => { let ret = false; if (p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0) { - p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); + p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4, undefined, "Dudunsparce form selection"), p.id); } return ret; }), SpeciesWildEvolutionDelay.LONG), diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 0c30582fa39..e79595d5119 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -761,7 +761,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali return this.speciesId; } - const randValue = evolutionPool.size === 1 ? 0 : Utils.randSeedInt(totalWeight); + const randValue = evolutionPool.size === 1 ? 0 : Utils.randSeedInt(totalWeight, undefined, "Random levelled species"); for (const weight of evolutionPool.keys()) { if (randValue < weight) { @@ -3340,7 +3340,7 @@ export function getPokerusStarters(scene: BattleScene): PokemonSpecies[] { date.setUTCHours(0, 0, 0, 0); scene.executeWithSeedOffset(() => { while (pokerusStarters.length < starterCount) { - const randomSpeciesId = parseInt(Utils.randSeedItem(Object.keys(speciesStarters)), 10); + const randomSpeciesId = parseInt(Utils.randSeedItem(Object.keys(speciesStarters), "Get Pokerus starters"), 10); const species = getPokemonSpecies(randomSpeciesId); if (!pokerusStarters.includes(species)) { pokerusStarters.push(species); diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index a6cf4247f27..30d391f60fd 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -994,7 +994,7 @@ function getGymLeaderPartyTemplate(scene: BattleScene) { function getRandomPartyMemberFunc(speciesPool: Species[], trainerSlot: TrainerSlot = TrainerSlot.TRAINER, ignoreEvolution: boolean = false, postProcess?: (enemyPokemon: EnemyPokemon) => void): PartyMemberFunc { return (scene: BattleScene, level: integer, strength: PartyMemberStrength) => { - let species = Utils.randSeedItem(speciesPool); + let species = Utils.randSeedItem(speciesPool, "Get random party member"); if (!ignoreEvolution) { species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength, scene.currentBattle.waveIndex); } @@ -1015,9 +1015,9 @@ function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, types?: T const ret: PersistentModifier[] = []; const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i); for (let t = 0; t < Math.min(count, party.length); t++) { - const randomIndex = Utils.randSeedItem(partyMemberIndexes); + const randomIndex = Utils.randSeedItem(partyMemberIndexes, "Get random tera modifiers"); partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1); - ret.push(modifierTypes.TERA_SHARD().generateType([], [Utils.randSeedItem(types ? types : party[randomIndex].getTypes())])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); // TODO: is the bang correct? + ret.push(modifierTypes.TERA_SHARD().generateType([], [Utils.randSeedItem(types ? types : party[randomIndex].getTypes(), "Selecting Tera Type")])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); // TODO: is the bang correct? } return ret; } @@ -1868,7 +1868,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; - p.formIndex = Utils.randSeedInt(5); + p.formIndex = Utils.randSeedInt(5, undefined, "Random form for Genesect"); })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BASCULEGION, Species.JELLICENT ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); diff --git a/src/data/weather.ts b/src/data/weather.ts index 2421f719e6e..06665e5ab98 100644 --- a/src/data/weather.ts +++ b/src/data/weather.ts @@ -88,12 +88,14 @@ export class Weather { return 1; } - isMoveWeatherCancelled(move: Move): boolean { + isMoveWeatherCancelled(user: Pokemon, move: Move): boolean { + const moveType = user.getMoveType(move); + switch (this.weatherType) { case WeatherType.HARSH_SUN: - return move instanceof AttackMove && move.type === Type.WATER; + return move instanceof AttackMove && moveType === Type.WATER; case WeatherType.HEAVY_RAIN: - return move instanceof AttackMove && move.type === Type.FIRE; + return move instanceof AttackMove && moveType === Type.FIRE; } return false; @@ -376,7 +378,7 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a let totalWeight = 0; weatherPool.forEach(w => totalWeight += w.weight); - const rand = Utils.randSeedInt(totalWeight); + const rand = Utils.randSeedInt(totalWeight, undefined, "Weather selection"); let w = 0; for (const weather of weatherPool) { w += weather.weight; diff --git a/src/field/arena.ts b/src/field/arena.ts index 262fce256de..2f0ba3f3cb2 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -90,7 +90,7 @@ export class Arena { if (typeof luckValue !== "undefined") { luckModifier = luckValue * (isBoss ? 0.5 : 2); } - const tierValue = Utils.randSeedInt(randVal - luckModifier); + const tierValue = Utils.randSeedInt(randVal - luckModifier, undefined, "Selecting rarity tier for encounter"); let tier = !isBoss ? tierValue >= 156 ? BiomePoolTier.COMMON : tierValue >= 32 ? BiomePoolTier.UNCOMMON : tierValue >= 6 ? BiomePoolTier.RARE : tierValue >= 1 ? BiomePoolTier.SUPER_RARE : BiomePoolTier.ULTRA_RARE : tierValue >= 20 ? BiomePoolTier.BOSS : tierValue >= 6 ? BiomePoolTier.BOSS_RARE : tierValue >= 1 ? BiomePoolTier.BOSS_SUPER_RARE : BiomePoolTier.BOSS_ULTRA_RARE; @@ -118,7 +118,7 @@ export class Arena { if (!tierPool.length) { ret = this.scene.randomSpecies(waveIndex, level); } else { - const entry = tierPool[Utils.randSeedInt(tierPool.length)]; + const entry = tierPool[Utils.randSeedInt(tierPool.length, undefined, "Selecting rarity tier but for real this time")]; let species: Species; if (typeof entry === "number") { species = entry as Species; @@ -129,7 +129,7 @@ export class Arena { if (level >= levelThreshold) { const speciesIds = entry[levelThreshold]; if (speciesIds.length > 1) { - species = speciesIds[Utils.randSeedInt(speciesIds.length)]; + species = speciesIds[Utils.randSeedInt(speciesIds.length, undefined, "Randomly selecting encounter species")]; } else { species = speciesIds[0]; } @@ -175,7 +175,7 @@ export class Arena { const isBoss = !!this.trainerPool[BiomePoolTier.BOSS].length && this.scene.gameMode.isTrainerBoss(waveIndex, this.biomeType, this.scene.offsetGym); console.log(isBoss, this.trainerPool); - const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64); + const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64, undefined, "Selecting random trainer"); let tier = !isBoss ? tierValue >= 156 ? BiomePoolTier.COMMON : tierValue >= 32 ? BiomePoolTier.UNCOMMON : tierValue >= 6 ? BiomePoolTier.RARE : tierValue >= 1 ? BiomePoolTier.SUPER_RARE : BiomePoolTier.ULTRA_RARE : tierValue >= 20 ? BiomePoolTier.BOSS : tierValue >= 6 ? BiomePoolTier.BOSS_RARE : tierValue >= 1 ? BiomePoolTier.BOSS_SUPER_RARE : BiomePoolTier.BOSS_ULTRA_RARE; @@ -185,7 +185,7 @@ export class Arena { tier--; } const tierPool = this.trainerPool[tier] || []; - return !tierPool.length ? TrainerType.BREEDER : tierPool[Utils.randSeedInt(tierPool.length)]; + return !tierPool.length ? TrainerType.BREEDER : tierPool[Utils.randSeedInt(tierPool.length, undefined, "Selecting trainer type")]; } getSpeciesFormIndex(species: PokemonSpecies): integer { @@ -303,7 +303,7 @@ export class Arena { /** * Sets weather to the override specified in overrides.ts - * @param weather new {@linkcode WeatherType} to set + * @param weather new weather to set of type WeatherType * @returns true to force trySetWeather to return true */ trySetWeatherOverride(weather: WeatherType): boolean { @@ -315,8 +315,8 @@ export class Arena { /** * Attempts to set a new weather to the battle - * @param weather {@linkcode WeatherType} new {@linkcode WeatherType} to set - * @param hasPokemonSource boolean if the new weather is from a pokemon + * @param weather new weather to set of type WeatherType + * @param hasPokemonSource is the new weather from a pokemon * @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use */ trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean { @@ -405,8 +405,8 @@ export class Arena { return true; } - isMoveWeatherCancelled(move: Move) { - return this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(move); + isMoveWeatherCancelled(user: Pokemon, move: Move) { + return this.weather && !this.weather.isEffectSuppressed(this.scene) && this.weather.isMoveWeatherCancelled(user, move); } isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move) { @@ -587,12 +587,6 @@ export class Arena { this.ignoreAbilities = ignoreAbilities; } - /** - * Applies each `ArenaTag` in this Arena, based on which side (self, enemy, or both) is passed in as a parameter - * @param tagType Either an {@linkcode ArenaTagType} string, or an actual {@linkcode ArenaTag} class to filter which ones to apply - * @param side {@linkcode ArenaTagSide} which side's arena tags to apply - * @param args array of parameters that the called upon tags may need - */ applyTagsForSide(tagType: ArenaTagType | Constructor, side: ArenaTagSide, ...args: unknown[]): void { let tags = typeof tagType === "string" ? this.tags.filter(t => t.tagType === tagType) @@ -603,28 +597,11 @@ export class Arena { tags.forEach(t => t.apply(this, args)); } - /** - * Applies the specified tag to both sides (ie: both user and trainer's tag that match the Tag specified) - * by calling {@linkcode applyTagsForSide()} - * @param tagType Either an {@linkcode ArenaTagType} string, or an actual {@linkcode ArenaTag} class to filter which ones to apply - * @param args array of parameters that the called upon tags may need - */ applyTags(tagType: ArenaTagType | Constructor, ...args: unknown[]): void { this.applyTagsForSide(tagType, ArenaTagSide.BOTH, ...args); } - /** - * Adds a new tag to the arena - * @param tagType {@linkcode ArenaTagType} the tag being added - * @param turnCount How many turns the tag lasts - * @param sourceMove {@linkcode Moves} the move the tag came from, or `undefined` if not from a move - * @param sourceId The ID of the pokemon in play the tag came from (see {@linkcode BattleScene.getPokemonById}) - * @param side {@linkcode ArenaTagSide} which side(s) the tag applies to - * @param quiet If a message should be queued on screen to announce the tag being added - * @param targetIndex The {@linkcode BattlerIndex} of the target pokemon - * @returns `false` if there already exists a tag of this type in the Arena - */ - addTag(tagType: ArenaTagType, turnCount: number, sourceMove: Moves | undefined, sourceId: number, side: ArenaTagSide = ArenaTagSide.BOTH, quiet: boolean = false, targetIndex?: BattlerIndex): boolean { + addTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId: integer, side: ArenaTagSide = ArenaTagSide.BOTH, quiet: boolean = false, targetIndex?: BattlerIndex): boolean { const existingTag = this.getTagOnSide(tagType, side); if (existingTag) { existingTag.onOverlap(this); @@ -637,7 +614,6 @@ export class Arena { return false; } - // creates a new tag object const newTag = getArenaTag(tagType, turnCount || 0, sourceMove, sourceId, targetIndex, side); if (newTag) { this.tags.push(newTag); @@ -651,11 +627,6 @@ export class Arena { return true; } - /** - * Attempts to get a tag from the Arena via {@linkcode getTagOnSide} that applies to both sides - * @param tagType The {@linkcode ArenaTagType} or {@linkcode ArenaTag} to get - * @returns either the {@linkcode ArenaTag}, or `undefined` if it isn't there - */ getTag(tagType: ArenaTagType | Constructor): ArenaTag | undefined { return this.getTagOnSide(tagType, ArenaTagSide.BOTH); } @@ -664,35 +635,16 @@ export class Arena { return !!this.getTag(tagType); } - /** - * Attempts to get a tag from the Arena from a specific side (the tag passed in has to either apply to both sides, or the specific side only) - * - * eg: `MIST` only applies to the user's side, while `MUD_SPORT` applies to both user and enemy side - * @param tagType The {@linkcode ArenaTagType} or {@linkcode ArenaTag} to get - * @param side The {@linkcode ArenaTagSide} to look at - * @returns either the {@linkcode ArenaTag}, or `undefined` if it isn't there - */ getTagOnSide(tagType: ArenaTagType | Constructor, side: ArenaTagSide): ArenaTag | undefined { return typeof(tagType) === "string" ? this.tags.find(t => t.tagType === tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)) : this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)); } - /** - * Uses {@linkcode findTagsOnSide} to filter (using the parameter function) for specific tags that apply to both sides - * @param tagPredicate a function mapping {@linkcode ArenaTag}s to `boolean`s - * @returns array of {@linkcode ArenaTag}s from which the Arena's tags return true and apply to both sides - */ findTags(tagPredicate: (t: ArenaTag) => boolean): ArenaTag[] { return this.findTagsOnSide(tagPredicate, ArenaTagSide.BOTH); } - /** - * Returns specific tags from the arena that pass the `tagPredicate` function passed in as a parameter, and apply to the given side - * @param tagPredicate a function mapping {@linkcode ArenaTag}s to `boolean`s - * @param side The {@linkcode ArenaTagSide} to look at - * @returns array of {@linkcode ArenaTag}s from which the Arena's tags return `true` and apply to the given side - */ findTagsOnSide(tagPredicate: (t: ArenaTag) => boolean, side: ArenaTagSide): ArenaTag[] { return this.tags.filter(t => tagPredicate(t) && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)); } @@ -922,7 +874,7 @@ export class ArenaBase extends Phaser.GameObjects.Container { if (!this.player) { (this.scene as BattleScene).executeWithSeedOffset(() => { this.propValue = propValue === undefined - ? hasProps ? Utils.randSeedInt(8) : 0 + ? hasProps ? Utils.randSeedInt(8, undefined, "Selecting biome prop(?)") : 0 : propValue; this.props.forEach((prop, p) => { const propKey = `${biomeKey}_b${hasProps ? `_${p + 1}` : ""}`; diff --git a/src/field/pokemon-sprite-sparkle-handler.ts b/src/field/pokemon-sprite-sparkle-handler.ts index ccf6a098667..008a301b242 100644 --- a/src/field/pokemon-sprite-sparkle-handler.ts +++ b/src/field/pokemon-sprite-sparkle-handler.ts @@ -31,7 +31,7 @@ export default class PokemonSpriteSparkleHandler { const parent = (pokemon || s).parentContainer; const texture = s.texture; const [ width, height ] = [ texture.source[0].width, texture.source[0].height ]; - const [ pixelX, pixelY ] = [ Utils.randInt(width), Utils.randInt(height) ]; + const [ pixelX, pixelY ] = [ Utils.randInt(width, undefined, "Pixel X"), Utils.randInt(height, undefined, "Pixel Y") ]; const ratioX = s.width / width; const ratioY = s.height / height; const pixel = texture.manager.getPixel(pixelX, pixelY, texture.key, "__BASE"); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index eb3b4f17cae..59ae9b5b3b6 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -157,8 +157,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.abilityIndex = abilityIndex; // Use the provided ability index if it is defined } else { // If abilityIndex is not provided, determine it based on species and hidden ability - const hasHiddenAbility = !Utils.randSeedInt(hiddenAbilityChance.value); - const randAbilityIndex = Utils.randSeedInt(2); + const hasHiddenAbility = !Utils.randSeedInt(hiddenAbilityChance.value, undefined, "Hidden Ability chance"); + const randAbilityIndex = Utils.randSeedInt(2, undefined, "Selecting ability index"); if (species.abilityHidden && hasHiddenAbility) { // If the species has a hidden ability and the hidden ability is present this.abilityIndex = 2; @@ -211,7 +211,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.fusionLuck = dataSource.fusionLuck; this.usedTMs = dataSource.usedTMs ?? []; } else { - this.id = Utils.randSeedInt(4294967296); + this.id = Utils.randSeedInt(4294967296, undefined, "Generating a Pokemon ID to create Pokemon's IVs"); this.ivs = ivs || Utils.getIvsFromId(this.id); if (this.gender === undefined) { @@ -924,7 +924,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (naturePool === undefined) { naturePool = Utils.getEnumValues(Nature); } - const nature = naturePool[Utils.randSeedInt(naturePool.length)]; + const nature = naturePool[Utils.randSeedInt(naturePool.length, undefined, "Random nature")]; this.setNature(nature); } @@ -1466,26 +1466,22 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } let multiplier = types.map(defType => { - const multiplier = new Utils.NumberHolder(getTypeDamageMultiplier(moveType, defType)); - applyChallenges(this.scene.gameMode, ChallengeType.TYPE_EFFECTIVENESS, multiplier); if (source) { const ignoreImmunity = new Utils.BooleanHolder(false); if (source.isActive(true) && source.hasAbilityWithAttr(IgnoreTypeImmunityAbAttr)) { applyAbAttrs(IgnoreTypeImmunityAbAttr, source, ignoreImmunity, simulated, moveType, defType); } if (ignoreImmunity.value) { - if (multiplier.value === 0) { - return 1; - } + return 1; } const exposedTags = this.findTags(tag => tag instanceof ExposedTag) as ExposedTag[]; if (exposedTags.some(t => t.ignoreImmunity(defType, moveType))) { - if (multiplier.value === 0) { - return 1; - } + return 1; } } + const multiplier = new Utils.NumberHolder(getTypeDamageMultiplier(moveType, defType)); + applyChallenges(this.scene.gameMode, ChallengeType.TYPE_EFFECTIVENESS, multiplier); return multiplier.value; }).reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier; @@ -1732,10 +1728,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (!this.shiny || (!variantData.hasOwnProperty(variantDataIndex) && !variantData.hasOwnProperty(this.species.speciesId))) { return 0; } - const rand = Utils.randSeedInt(10); - if (rand >= 4) { + const rand = new Utils.IntegerHolder(0) + this.scene.executeWithSeedOffset(() => { + rand.value = Utils.randSeedInt(10, undefined, "Random variant selection"); + }, this.id, this.scene.waveSeed) + if (rand.value >= 4) { return 0; // 6/10 - } else if (rand >= 1) { + } else if (rand.value >= 1) { return 1; // 3/10 } else { return 2; // 1/10 @@ -1748,8 +1747,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); } - const hasHiddenAbility = !Utils.randSeedInt(hiddenAbilityChance.value); - const randAbilityIndex = Utils.randSeedInt(2); + const hasHiddenAbility = !Utils.randSeedInt(hiddenAbilityChance.value, undefined, "Whether the Pokemon has its HA or not"); + const randAbilityIndex = Utils.randSeedInt(2, undefined, "Ability slot (if no HA)"); const filter = !forStarter ? this.species.getCompatibleFusionSpeciesFilter() : species => { @@ -1922,7 +1921,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (stabMovePool.length) { const totalWeight = stabMovePool.reduce((v, m) => v + m[1], 0); - let rand = Utils.randSeedInt(totalWeight); + let rand = Utils.randSeedInt(totalWeight, undefined, "Selecting a STAB move to include"); let index = 0; while (rand > stabMovePool[index][1]) { rand -= stabMovePool[index++][1]; @@ -1933,7 +1932,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const attackMovePool = baseWeights.filter(m => allMoves[m[0]].category !== MoveCategory.STATUS); if (attackMovePool.length) { const totalWeight = attackMovePool.reduce((v, m) => v + m[1], 0); - let rand = Utils.randSeedInt(totalWeight); + let rand = Utils.randSeedInt(totalWeight, undefined, "Selecting a damage dealing move to include"); let index = 0; while (rand > attackMovePool[index][1]) { rand -= attackMovePool[index++][1]; @@ -1952,7 +1951,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId)); } const totalWeight = movePool.reduce((v, m) => v + m[1], 0); - let rand = Utils.randSeedInt(totalWeight); + let rand = Utils.randSeedInt(totalWeight, undefined, "Selecting moves"); let index = 0; while (rand > movePool[index][1]) { rand -= movePool[index++][1]; @@ -2972,7 +2971,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return this.fusionFaintCry(callback); } - const key = `cry/${this.getSpeciesForm().getCryKey(this.formIndex)}`; + const key = `cry/${this.species.getCryKey(this.formIndex)}`; //eslint-disable-next-line @typescript-eslint/no-unused-vars let i = 0; let rate = 0.85; @@ -3030,7 +3029,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } private fusionFaintCry(callback: Function): void { - const key = `cry/${this.getSpeciesForm().getCryKey(this.formIndex)}`; + const key = `cry/${this.species.getCryKey(this.formIndex)}`; let i = 0; let rate = 0.85; const cry = this.scene.playSound(key, { rate: rate }) as AnySound; @@ -3038,7 +3037,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const tintSprite = this.getTintSprite(); let duration = cry.totalDuration * 1000; - const fusionCryKey = `cry/${this.getFusionSpeciesForm().getCryKey(this.fusionFormIndex)}`; + const fusionCryKey = `cry/${this.fusionSpecies?.getCryKey(this.fusionFormIndex)}`; let fusionCry = this.scene.playSound(fusionCryKey, { rate: rate }) as AnySound; fusionCry.stop(); duration = Math.min(duration, fusionCry.totalDuration * 1000); @@ -3661,7 +3660,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param min The minimum integer to pick, default `0` * @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1) */ - randSeedInt(range: integer, min: integer = 0, reason: string = "Pokémon randSeedInt"): integer { + randSeedInt(range: integer, min: integer = 0, reason?: string): integer { return this.scene.currentBattle ? this.scene.randBattleSeedInt(range, min, reason) : Utils.randSeedInt(range, min, reason); @@ -3673,7 +3672,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param max The maximum integer to generate * @returns a random integer between {@linkcode min} and {@linkcode max} inclusive */ - randSeedIntRange(min: integer, max: integer, reason: string = "Pokémon randSeedInt"): integer { + randSeedIntRange(min: integer, max: integer, reason?: string): integer { return this.randSeedInt((max - min) + 1, min, reason); } @@ -3725,7 +3724,6 @@ export default interface Pokemon { export class PlayerPokemon extends Pokemon { public compatibleTms: Moves[]; - public usedTms: Moves[]; constructor(scene: BattleScene, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData) { super(scene, 106, 148, species, level, abilityIndex, formIndex, gender, shiny, variant, ivs, nature, dataSource); @@ -3749,7 +3747,6 @@ export class PlayerPokemon extends Pokemon { } } this.generateCompatibleTms(); - this.usedTms = []; } initBattleInfo(): void { @@ -4286,6 +4283,7 @@ export class EnemyPokemon extends Pokemon { * @returns this Pokemon's next move in the format {move, moveTargets} */ getNextMove(): QueuedMove { + console.log("Starting getNextMove() for " + this.name) // If this Pokemon has a move already queued, return it. const queuedMove = this.getMoveQueue().length ? this.getMoveset().find(m => m?.moveId === this.getMoveQueue()[0].move) @@ -4298,9 +4296,11 @@ export class EnemyPokemon extends Pokemon { this.flyout.setText(i) } } + console.log(" Move was already selected") return { move: queuedMove.moveId, targets: this.getMoveQueue()[0].targets, ignorePP: this.getMoveQueue()[0].ignorePP }; } else { this.getMoveQueue().shift(); + console.log(" Selected move cannot be used") return this.getNextMove(); } } @@ -4312,7 +4312,8 @@ export class EnemyPokemon extends Pokemon { // If there's only 1 move in the move pool, use it. if (movePool.length === 1) { this.flyout.setText(this.getMoveset().indexOf(movePool[0])) - return { move: movePool[0]!.moveId, targets: this.getNextTargets(movePool[0]!.moveId) }; + console.log(" Only one move to select") + return { move: movePool[0]!.moveId, targets: this.getNextTargets(movePool[0]!.moveId) }; // TODO: are the bangs correct? } // If a move is forced because of Encore, use it. const encoreTag = this.getTag(EncoreTag) as EncoreTag; @@ -4320,11 +4321,12 @@ export class EnemyPokemon extends Pokemon { const encoreMove = movePool.find(m => m?.moveId === encoreTag.moveId); if (encoreMove) { this.flyout.setText(this.getMoveset().indexOf(encoreMove)) + console.log(" Locked into Encore") return { move: encoreMove.moveId, targets: this.getNextTargets(encoreMove.moveId) }; } } switch (this.aiType) { - case AiType.RANDOM: + case AiType.RANDOM: // No enemy should spawn with this AI type in-game var i = this.scene.randBattleSeedInt(movePool.length, undefined, "Move selection roll (RANDOM)") const moveId = movePool[i]!.moveId; this.flyout.setText(i) @@ -4409,22 +4411,25 @@ export class EnemyPokemon extends Pokemon { }); let r = 0; if (this.aiType === AiType.SMART_RANDOM) { - while (r < sortedMovePool.length - 1 && this.scene.randBattleSeedInt(8, undefined, "Move selection roll (SMART_RANDOM)") >= 5) { + // Has a 5/8 chance to select the best move, and a 3/8 chance to advance to the next best move (and repeat this roll) + while (r < sortedMovePool.length - 1 && this.scene.randBattleSeedInt(8, undefined, "Smart-Random AI Move Selection") >= 5) { r++; } } else if (this.aiType === AiType.SMART) { // The chance to advance to the next best move increases when the compared moves' scores are closer to each other. while (r < sortedMovePool.length - 1 && (moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) >= 0 - && this.scene.randBattleSeedInt(100, undefined, "Move selection roll (SMART)") < Math.round((moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) * 50)) { + && this.scene.randBattleSeedInt(100, undefined, "Smart AI Move Selection") < Math.round((moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) * 50)) { r++; } } console.log(movePool.map(m => m!.getName()), moveScores, r, sortedMovePool.map(m => m!.getName())); this.flyout.setText(movePool.indexOf(sortedMovePool[r])) + console.log(" Selected " + sortedMovePool[r]!.getName()) return { move: sortedMovePool[r]!.moveId, targets: moveTargets[sortedMovePool[r]!.moveId] }; } } this.flyout.setText() + console.log(" Selected Struggle") return { move: Moves.STRUGGLE, targets: this.getNextTargets(Moves.STRUGGLE) }; } @@ -4434,10 +4439,12 @@ export class EnemyPokemon extends Pokemon { * @returns The indexes of the Pokemon the given move would target */ getNextTargets(moveId: Moves): BattlerIndex[] { + console.log("Starting getNextTargets() for " + this.name + " with move " + Utils.getEnumKeys(Moves)[moveId]) const moveTargets = getMoveTargets(this, moveId); const targets = this.scene.getField(true).filter(p => moveTargets.targets.indexOf(p.getBattlerIndex()) > -1); // If the move is multi-target, return all targets' indexes if (moveTargets.multiple) { + console.log(" Multi-target move") return targets.map(p => p.getBattlerIndex()); } @@ -4461,9 +4468,10 @@ export class EnemyPokemon extends Pokemon { // Set target to BattlerIndex.ATTACKER when using a counter move // This is the same as when the player does so if (move.hasAttr(CounterDamageAttr)) { + console.log(" Counter move") return [BattlerIndex.ATTACKER]; } - + console.log(" No targets available") return []; } @@ -4497,7 +4505,7 @@ export class EnemyPokemon extends Pokemon { * then select the first target whose cumulative weight (with all previous targets' weights) * is greater than that random number. */ - const randValue = this.scene.randBattleSeedInt(totalWeight, undefined, "Random target selection"); + const randValue = this.scene.randBattleSeedInt(totalWeight, undefined, "Random move target"); let targetIndex: integer = 0; thresholds.every((t, i) => { @@ -4508,6 +4516,8 @@ export class EnemyPokemon extends Pokemon { targetIndex = i; return false; }); + console.log("Target selection thresholds", thresholds) + console.log(" Randomly selected position " + sortedBenefitScores[targetIndex][0] + " as target") return [ sortedBenefitScores[targetIndex][0] ]; } @@ -4617,7 +4627,7 @@ export class EnemyPokemon extends Pokemon { } // Pick a random stat from the leftover stats to increase its stages - const randInt = Utils.randSeedInt(totalWeight); + const randInt = Utils.randSeedInt(totalWeight, undefined, "Random stat to raise from breaking a segment"); for (const i in statThresholds) { if (randInt < statThresholds[i]) { boostedStat = leftoverStats[i]; diff --git a/src/field/trainer.ts b/src/field/trainer.ts index 6d6c0444404..e78bb2b363a 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -45,7 +45,7 @@ export default class Trainer extends Phaser.GameObjects.Container { this.config.partyTemplates.length - 1); if (trainerNamePools.hasOwnProperty(trainerType)) { const namePool = trainerNamePools[trainerType]; - this.name = name || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[variant === TrainerVariant.FEMALE ? 1 : 0] : namePool); + this.name = name || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[variant === TrainerVariant.FEMALE ? 1 : 0] : namePool, "Trainer name 1"); if (variant === TrainerVariant.DOUBLE) { if (this.config.doubleOnly) { if (partnerName) { @@ -54,7 +54,7 @@ export default class Trainer extends Phaser.GameObjects.Container { [this.name, this.partnerName] = this.name.split(" & "); } } else { - this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool); + this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool, "Trainer name 2"); } } } @@ -236,7 +236,7 @@ export default class Trainer extends Phaser.GameObjects.Container { title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`); console.log("Localized grunt name: " + title); // Since grunts are not named we can just return the title - return title; + //return title; } // If the trainer has a name (not null or undefined). @@ -487,7 +487,7 @@ export default class Trainer extends Phaser.GameObjects.Container { let species: PokemonSpecies; if (this.config.speciesPools) { - const tierValue = Utils.randSeedInt(512); + const tierValue = Utils.randSeedInt(512, undefined, "Randomly selecting species for trainer party"); let tier = tierValue >= 156 ? TrainerPoolTier.COMMON : tierValue >= 32 ? TrainerPoolTier.UNCOMMON : tierValue >= 6 ? TrainerPoolTier.RARE : tierValue >= 1 ? TrainerPoolTier.SUPER_RARE : TrainerPoolTier.ULTRA_RARE; console.log(TrainerPoolTier[tier]); while (!this.config.speciesPools.hasOwnProperty(tier) || !this.config.speciesPools[tier].length) { @@ -495,7 +495,7 @@ export default class Trainer extends Phaser.GameObjects.Container { tier--; } const tierPool = this.config.speciesPools[tier]; - species = getPokemonSpecies(Utils.randSeedItem(tierPool)); + species = getPokemonSpecies(Utils.randSeedItem(tierPool, "Random party member species")); } else { species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter); } @@ -587,7 +587,7 @@ export default class Trainer extends Phaser.GameObjects.Container { if (maxScorePartyMemberIndexes.length > 1) { let rand: integer; - this.scene.executeWithSeedOffset(() => rand = Utils.randSeedInt(maxScorePartyMemberIndexes.length), this.scene.currentBattle.turn << 2); + this.scene.executeWithSeedOffset(() => rand = Utils.randSeedInt(maxScorePartyMemberIndexes.length, undefined, "Randomly selecting who to send out next"), this.scene.currentBattle.turn << 2); return maxScorePartyMemberIndexes[rand!]; } diff --git a/src/game-mode.ts b/src/game-mode.ts index f5dadad6f1b..2441a79b0f1 100644 --- a/src/game-mode.ts +++ b/src/game-mode.ts @@ -161,7 +161,7 @@ export class GameMode implements GameModeConfig { } else if (w < waveIndex) { arena.scene.executeWithSeedOffset(() => { const waveTrainerChance = arena.getTrainerChance(); - if (!Utils.randSeedInt(waveTrainerChance)) { + if (!Utils.randSeedInt(waveTrainerChance, undefined, "Random chance of wave being a Trainer Battle")) { allowTrainerBattle = false; } }, w); @@ -171,7 +171,7 @@ export class GameMode implements GameModeConfig { } } } - return Boolean(allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance)); + return Boolean(allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance, undefined, "Random chance of wave being a Trainer Battle")); } return false; } @@ -189,7 +189,7 @@ export class GameMode implements GameModeConfig { if (this.isDaily && this.isWaveFinal(waveIndex)) { const allFinalBossSpecies = allSpecies.filter(s => (s.subLegendary || s.legendary || s.mythical) && s.baseTotal >= 600 && s.speciesId !== Species.ETERNATUS && s.speciesId !== Species.ARCEUS); - return Utils.randSeedItem(allFinalBossSpecies); + return Utils.randSeedItem(allFinalBossSpecies, "Final Boss override"); } return null; diff --git a/src/interfaces/locales.ts b/src/interfaces/locales.ts index 39fd938074b..4405095e0fe 100644 --- a/src/interfaces/locales.ts +++ b/src/interfaces/locales.ts @@ -20,8 +20,7 @@ export interface MoveTranslationEntries { export interface AbilityTranslationEntry { name: string, - description: string, - partial?: string + description: string } export interface AbilityTranslationEntries { diff --git a/src/loading-scene.ts b/src/loading-scene.ts index d908f582f35..1203ad1e122 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -7,15 +7,15 @@ import { WindowVariant, getWindowVariantSuffix } from "./ui/ui-theme"; import { isMobile } from "./touch-controls"; import * as Utils from "./utils"; import { initI18n } from "./plugins/i18n"; -import {initPokemonPrevolutions} from "#app/data/pokemon-evolutions"; -import {initBiomes} from "#app/data/biomes"; -import {initEggMoves} from "#app/data/egg-moves"; -import {initPokemonForms} from "#app/data/pokemon-forms"; -import {initSpecies} from "#app/data/pokemon-species"; -import {initMoves} from "#app/data/move"; -import {initAbilities} from "#app/data/ability"; -import {initAchievements} from "#app/system/achv"; -import {initTrainerTypeDialogue} from "#app/data/dialogue"; +import { initPokemonPrevolutions } from "#app/data/pokemon-evolutions"; +import { initBiomes } from "#app/data/biomes"; +import { initEggMoves } from "#app/data/egg-moves"; +import { initPokemonForms } from "#app/data/pokemon-forms"; +import { initSpecies } from "#app/data/pokemon-species"; +import { initMoves } from "#app/data/move"; +import { initAbilities } from "#app/data/ability"; +import { initAchievements } from "#app/system/achv"; +import { initTrainerTypeDialogue } from "#app/data/dialogue"; import { initChallenges } from "./data/challenge"; import i18next from "i18next"; import { initStatsKeys } from "./ui/game-stats-ui-handler"; @@ -379,9 +379,9 @@ export class LoadingScene extends SceneBase { } const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN"]; if (lang && availableLangs.includes(lang)) { - this.loadImage("september-update-"+lang, "events"); + this.loadImage("egg-update_"+lang, "events"); } else { - this.loadImage("september-update-en", "events"); + this.loadImage("egg-update_en", "events"); } this.loadAtlas("statuses", ""); diff --git a/src/locales/de/ability-trigger.json b/src/locales/de/ability-trigger.json index 379692c45ae..60f3432df98 100644 --- a/src/locales/de/ability-trigger.json +++ b/src/locales/de/ability-trigger.json @@ -12,7 +12,6 @@ "typeImmunityHeal": "{{abilityName}} von {{pokemonNameWithAffix}} füllte einige KP auf!", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} vermeidet Schaden mit {{abilityName}}!", "disguiseAvoidedDamage": "Die Tarnung von {{pokemonNameWithAffix}} ist aufgeflogen!!", - "fullHpResistType": "Der Panzer von {{pokemonNameWithAffix}} funkelt und verzerrt die Wechselwirkungen zwischen den Typen!", "moveImmunity": "Es hat keine Wirkung auf {{pokemonNameWithAffix}}...", "reverseDrain": "{{pokemonNameWithAffix}} saugt Kloakensoße auf!", "postDefendTypeChange": "{{abilityName}} von {{pokemonNameWithAffix}} macht es zu einem {{typeName}}-Typ!", @@ -52,7 +51,6 @@ "postSummonTeravolt": "{{pokemonNameWithAffix}} strahlt eine knisternde Aura aus!", "postSummonDarkAura": "{{pokemonNameWithAffix}} strahlt eine dunkle Aura aus!", "postSummonFairyAura": "{{pokemonNameWithAffix}} strahlt eine Feenaura aus!", - "postSummonAuraBreak": "{{pokemonNameWithAffix}} kehrt die Wirkung aller Aura-Fähigkeiten um!", "postSummonNeutralizingGas": "Reaktionsgas von {{pokemonNameWithAffix}} hat sich in der Umgebung ausgebreitet!", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} verfügt über zwei Fähigkeiten!", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} verfügt über zwei Fähigkeiten!", @@ -61,4 +59,4 @@ "postSummonTabletsOfRuin": "Unheilstafeln von {{pokemonNameWithAffix}} schwächt {{statName}} aller Pokémon im Umkreis!", "postSummonBeadsOfRuin": "Unheilsjuwelen von {{pokemonNameWithAffix}} schwächt {{statName}} aller Pokémon im Umkreis!", "preventBerryUse": "{{pokemonNameWithAffix}} kriegt vor Anspannung keine Beeren mehr runter!" -} +} \ No newline at end of file diff --git a/src/locales/de/battle.json b/src/locales/de/battle.json index 38e36d4b2da..05205b001b6 100644 --- a/src/locales/de/battle.json +++ b/src/locales/de/battle.json @@ -44,7 +44,6 @@ "moveNotImplemented": "{{moveName}} ist noch nicht implementiert und kann nicht ausgewählt werden.", "moveNoPP": "Es sind keine AP für diese Attacke mehr übrig!", "moveDisabled": "{{moveName}} ist deaktiviert!", - "disableInterruptedMove": "{{moveName}} von {{pokemonNameWithAffix}} ist blockiert!", "noPokeballForce": "Eine unsichtbare Kraft verhindert die Nutzung von Pokébällen.", "noPokeballTrainer": "Du kannst das Pokémon eines anderen Trainers nicht fangen!", "noPokeballMulti": "Du kannst erst einen Pokéball werfen, wenn nur noch ein Pokémon übrig ist!", @@ -97,4 +96,4 @@ "congratulations": "Glückwunsch!", "beatModeFirstTime": "{{speciesName}} hat den {{gameMode}} Modus zum ersten Mal beendet! Du erhältst {{newModifier}}!", "eggSkipPrompt": "Zur Ei-Zusammenfassung springen?" -} +} \ No newline at end of file diff --git a/src/locales/de/battler-tags.json b/src/locales/de/battler-tags.json index e65e1ddfe75..5509cc11b0a 100644 --- a/src/locales/de/battler-tags.json +++ b/src/locales/de/battler-tags.json @@ -67,7 +67,5 @@ "saltCuredLapse": "{{pokemonNameWithAffix}} wurde durch {{moveName}} verletzt!", "cursedOnAdd": "{{pokemonNameWithAffix}} nimmt einen Teil seiner KP und legt einen Fluch auf {{pokemonName}}!", "cursedLapse": "{{pokemonNameWithAffix}} wurde durch den Fluch verletzt!", - "stockpilingOnAdd": "{{pokemonNameWithAffix}} hortet {{stockpiledCount}}!", - "disabledOnAdd": " {{moveName}} von {{pokemonNameWithAffix}} wurde blockiert!", - "disabledLapse": "{{moveName}} von {{pokemonNameWithAffix}} ist nicht länger blockiert!" -} + "stockpilingOnAdd": "{{pokemonNameWithAffix}} hortet {{stockpiledCount}}!" +} \ No newline at end of file diff --git a/src/locales/de/menu.json b/src/locales/de/menu.json index 0e2ba4dc0b3..e5c1c700425 100644 --- a/src/locales/de/menu.json +++ b/src/locales/de/menu.json @@ -51,7 +51,5 @@ "renamePokemon": "Pokémon umbennenen", "rename": "Umbenennen", "nickname": "Spitzname", - "errorServerDown": "Ups! Es gab einen Fehler beim Versuch\nden Server zu kontaktieren\nLasse dieses Fenster offen\nDu wirst automatisch neu verbunden.", - "noSaves": "Du hast keine gespeicherten Dateien!", - "tooManySaves": "Du hast zu viele gespeicherte Dateien!" -} + "errorServerDown": "Ups! Es gab einen Fehler beim Versuch\nden Server zu kontaktieren\nLasse dieses Fenster offen\nDu wirst automatisch neu verbunden." +} \ No newline at end of file diff --git a/src/locales/de/modifier-type.json b/src/locales/de/modifier-type.json index 7c7972343d6..8e2372cb447 100644 --- a/src/locales/de/modifier-type.json +++ b/src/locales/de/modifier-type.json @@ -47,14 +47,10 @@ "description": "Ändert das Wesen zu {{natureName}}. Schaltet dieses Wesen permanent für diesen Starter frei." }, "DoubleBattleChanceBoosterModifierType": { - "description": "Vervierfacht die Chance, dass ein Kampf ein Doppelkampf wird, für bis zu {{battleCount}} Kämpfe." + "description": "Verdoppelt die Wahrscheinlichkeit, dass die nächsten {{battleCount}} Begegnungen mit wilden Pokémon ein Doppelkampf sind." }, "TempStatStageBoosterModifierType": { - "description": "Erhöht {{stat}} aller Teammitglieder um {{amount}} für bis zu 5 Kämpfe.", - "extra": { - "stage": "eine Stufe", - "percentage": "30%" - } + "description": "Erhöht die {{stat}} aller Teammitglieder für 5 Kämpfe um eine Stufe." }, "AttackTypeBoosterModifierType": { "description": "Erhöht die Stärke aller {{moveType}}-Attacken eines Pokémon um 20%." diff --git a/src/locales/en/ability-trigger.json b/src/locales/en/ability-trigger.json index da21d80e3c7..a7383cea16b 100644 --- a/src/locales/en/ability-trigger.json +++ b/src/locales/en/ability-trigger.json @@ -3,7 +3,7 @@ "badDreams": "{{pokemonName}} is tormented!", "costar": "{{pokemonName}} copied {{allyName}}'s stat changes!", "iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} avoided\ndamage with {{abilityName}}!", - "perishBody": "{{pokemonName}}'s {{abilityName}}\nwill faint both Pokémon in 3 turns!", + "perishBody": "{{pokemonName}}'s {{abilityName}}\nwill faint both pokemon in 3 turns!", "poisonHeal": "{{pokemonName}}'s {{abilityName}}\nrestored its HP a little!", "trace": "{{pokemonName}} copied {{targetName}}'s\n{{abilityName}}!", "windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!", @@ -61,4 +61,4 @@ "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}'s Tablets of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}'s Beads of Ruin lowered the {{statName}}\nof all surrounding Pokémon!", "preventBerryUse": "{{pokemonNameWithAffix}} is too\nnervous to eat berries!" -} +} \ No newline at end of file diff --git a/src/locales/en/challenges.json b/src/locales/en/challenges.json index 7792755d626..7d330401407 100644 --- a/src/locales/en/challenges.json +++ b/src/locales/en/challenges.json @@ -1,6 +1,6 @@ { "title": "Challenge Modifiers", - "illegalEvolution": "{{pokemon}} changed into an ineligible Pokémon\nfor this challenge!", + "illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", "noneSelected": "None Selected", "singleGeneration": { "name": "Mono Gen", @@ -34,4 +34,4 @@ "value.0": "Off", "value.1": "On" } -} +} \ No newline at end of file diff --git a/src/locales/es/ability-trigger.json b/src/locales/es/ability-trigger.json index 4380c84b8e9..8bbcc80662c 100644 --- a/src/locales/es/ability-trigger.json +++ b/src/locales/es/ability-trigger.json @@ -12,7 +12,6 @@ "blockItemTheft": "¡{{pokemonNameWithAffix}} evitó el robo gracias a {{abilityName}}!", "typeImmunityHeal": "¡{{pokemonNameWithAffix}} restauró algunos de sus PS gracias a {{abilityName}}!", "nonSuperEffectiveImmunity": "¡{{pokemonNameWithAffix}} evitó el daño gracias a {{abilityName}}!", - "fullHpResistType": "¡{{pokemonNameWithAffix}} ha hecho brillar su caparazón\ny ha alterado su compatibilidad entre tipos!", "moveImmunity": "¡No afecta a {{pokemonNameWithAffix}}!", "reverseDrain": "¡{{pokemonNameWithAffix}} absorbió lodo líquido!", "postDefendTypeChange": "¡{{abilityName}} de {{pokemonNameWithAffix}} cambió a tipo {{typeName}}!", @@ -52,7 +51,6 @@ "postSummonTeravolt": "¡{{pokemonNameWithAffix}} irradia un aura chisporroteante!", "postSummonDarkAura": "¡{{pokemonNameWithAffix}} irradia un aura oscura!", "postSummonFairyAura": "¡{{pokemonNameWithAffix}} irradia un aura feérica!", - "postSummonAuraBreak": "¡{{pokemonNameWithAffix}} ha invertido todas las auras!", "postSummonNeutralizingGas": "¡El Gas Reactivo de {{pokemonNameWithAffix}} se propaga por toda la zona!", "postSummonAsOneGlastrier": "¡{{pokemonNameWithAffix}} tiene dos Habilidades!", "postSummonAsOneSpectrier": "¡{{pokemonNameWithAffix}} tiene dos Habilidades!", diff --git a/src/locales/es/battle.json b/src/locales/es/battle.json index c79315f297b..8573f74a94e 100644 --- a/src/locales/es/battle.json +++ b/src/locales/es/battle.json @@ -42,7 +42,6 @@ "moveNotImplemented": "{{moveName}} aún no está implementado y no se puede seleccionar.", "moveNoPP": "¡No hay suficientes PP\npara este movimiento!", "moveDisabled": "!No puede usar {{moveName}} porque ha sido anulado!", - "disableInterruptedMove": "¡Se ha anulado el movimiento {{moveName}}\nde {{pokemonNameWithAffix}}!", "noPokeballForce": "Una fuerza misteriosa\nte impide usar Poké Balls.", "noPokeballTrainer": "¡No puedes atrapar a los\nPokémon de los demás!", "noPokeballMulti": "¡No se pueden lanzar Poké Balls\ncuando hay más de un Pokémon!", @@ -86,4 +85,4 @@ "statSeverelyFell_other": "¡{{stats}} de\n{{pokemonNameWithAffix}} han bajado muchísimo!", "statWontGoAnyLower_one": "¡El {{stats}} de {{pokemonNameWithAffix}} no puede bajar más!", "statWontGoAnyLower_other": "¡{{stats}} de\n{{pokemonNameWithAffix}} no pueden bajar más!" -} +} \ No newline at end of file diff --git a/src/locales/es/battler-tags.json b/src/locales/es/battler-tags.json index 891fda53c5d..d917b6c74b5 100644 --- a/src/locales/es/battler-tags.json +++ b/src/locales/es/battler-tags.json @@ -67,7 +67,5 @@ "saltCuredLapse": "¡{{moveName}} ha herido a {{pokemonNameWithAffix}}!", "cursedOnAdd": "¡{{pokemonNameWithAffix}} sacrifica algunos PS y maldice a {{pokemonName}}!", "cursedLapse": "¡{{pokemonNameWithAffix}} es víctima de una maldición!", - "stockpilingOnAdd": "¡{{pokemonNameWithAffix}} ha reservado energía por {{stockpiledCount}}ª vez!", - "disabledOnAdd": "¡Se ha anulado el movimiento {{moveName}}\nde {{pokemonNameWithAffix}}!", - "disabledLapse": "¡El movimiento {{moveName}} de {{pokemonNameWithAffix}} \n ya no está anulado!" + "stockpilingOnAdd": "¡{{pokemonNameWithAffix}} ha reservado energía por {{stockpiledCount}}ª vez!" } diff --git a/src/locales/es/menu.json b/src/locales/es/menu.json index ef1ae93dd82..3f2caafac21 100644 --- a/src/locales/es/menu.json +++ b/src/locales/es/menu.json @@ -51,7 +51,5 @@ "renamePokemon": "Renombrar Pokémon.", "rename": "Renombrar", "nickname": "Apodo", - "errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta, el juego se reconectará automáticamente.", - "noSaves": "No tienes ninguna partida guardada registrada!", - "tooManySaves": "¡Tienes demasiadas partidas guardadas registradas!" + "errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta, el juego se reconectará automáticamente." } diff --git a/src/locales/es/modifier-type.json b/src/locales/es/modifier-type.json index 3ac4d85f793..e18cb19244d 100644 --- a/src/locales/es/modifier-type.json +++ b/src/locales/es/modifier-type.json @@ -47,14 +47,10 @@ "description": "Cambia la naturaleza de un Pokémon a {{natureName}} y desbloquea permanentemente dicha naturaleza para el inicial." }, "DoubleBattleChanceBoosterModifierType": { - "description": "Cuadruplica la posibilidad de que un encuentro sea una combate doble durante {{battleCount}} combates." + "description": "Duplica la posibilidad de que un encuentro sea una combate doble durante {{battleCount}} combates." }, "TempStatStageBoosterModifierType": { - "description": "Aumenta la est. {{stat}} de todos los miembros del equipo en {{amount}} durante 5 combates.", - "extra": { - "stage": "1 nivel", - "percentage": "30%" - } + "description": "Aumenta la est. {{stat}} de todos los miembros del equipo en 1 nivel durante 5 combates." }, "AttackTypeBoosterModifierType": { "description": "Aumenta la potencia de los movimientos de tipo {{moveType}} de un Pokémon en un 20%." diff --git a/src/locales/fr/ability-trigger.json b/src/locales/fr/ability-trigger.json index 761242b3d94..d10fc18a146 100644 --- a/src/locales/fr/ability-trigger.json +++ b/src/locales/fr/ability-trigger.json @@ -3,15 +3,14 @@ "badDreams": "{{pokemonName}} a le sommeil agité !", "costar": "{{pokemonName}} copie les changements de stats\nde {{allyName}} !", "iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} évite les dégâts\navec {{abilityName}} !", - "perishBody": "{{abilityName}} de {{pokemonName}}\nmettra les deux Pokémon K.O. dans trois tours !", - "poisonHeal": "{{abilityName}} de {{pokemonName}}\nrestaure un peu ses PV !", + "perishBody": "{{abilityName}} de {{pokemonName}}\nmettra les deux Pokémon K.O. dans trois tours !", + "poisonHeal": "{{abilityName}} de {{pokemonName}}\nrestaure un peu ses PV !", "trace": "{{pokemonName}} copie le talent {{abilityName}}\nde {{targetName}} !", - "windPowerCharged": "{{pokemonName}} a été touché par la capacité {{moveName}} et se charge en électricité !", + "windPowerCharged": "{{pokemonName}} a été touché par la capacité {{moveName}} et se charge en électricité !", "quickDraw": "Tir Vif permet à {{pokemonName}}\nd’agir plus vite que d’habitude !", "blockItemTheft": "{{abilityName}} de {{pokemonNameWithAffix}}\nempêche son objet d’être volé !", - "typeImmunityHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", + "typeImmunityHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} évite\nles dégâts avec {{abilityName}} !", - "fullHpResistType": "{{pokemonNameWithAffix}} fait briller sa carapace\net fausse les affinités de type !", "disguiseAvoidedDamage": "Le déguisement de {{pokemonNameWithAffix}}\ntombe !", "moveImmunity": "Ça n’affecte pas {{pokemonNameWithAffix}}…", "reverseDrain": "{{pokemonNameWithAffix}} aspire\nle suintement !", @@ -34,12 +33,12 @@ "battlerTagImmunity": "{{abilityName}} de {{pokemonNameWithAffix}}\nempêche {{battlerTagName}} !", "forewarn": "La capacité {{moveName}}\nde {{pokemonNameWithAffix}} a été détectée !", "frisk": "{{pokemonNameWithAffix}} fouille {{opponentName}}\net trouve son talent {{opponentAbilityName}} !", - "postWeatherLapseHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", + "postWeatherLapseHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "postWeatherLapseDamage": "{{pokemonNameWithAffix}} est blessé\npar son talent {{abilityName}} !", "postTurnLootCreateEatenBerry": "{{pokemonNameWithAffix}} a récolté\nune {{berryName}} !", - "postTurnHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", + "postTurnHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "fetchBall": "{{pokemonNameWithAffix}} trouve\nune {{pokeballName}} !", - "healFromBerryUse": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", + "healFromBerryUse": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "arenaTrap": "{{pokemonNameWithAffix}} empêche\nles changements grâce à son talent {{abilityName}} !", "postBattleLoot": "{{pokemonNameWithAffix}} ramasse\nl’objet {{itemName}} !", "postFaintContactDamage": "{{pokemonNameWithAffix}} est blessé\npar son talent {{abilityName}} !", @@ -50,9 +49,8 @@ "postSummonAnticipation": "{{pokemonNameWithAffix}}\nest tout tremblant !", "postSummonTurboblaze": "{{pokemonNameWithAffix}} dégage\nune aura de flammes incandescentes !", "postSummonTeravolt": "{{pokemonNameWithAffix}} dégage\nune aura électrique instable !", - "postSummonDarkAura": "{{pokemonNameWithAffix}} dégage\nune aura ténébreuse !", + "postSummonDarkAura": "{{pokemonNameWithAffix}} dégage\nune aura ténébreuse !", "postSummonFairyAura": "{{pokemonNameWithAffix}} dégage\nune aura enchanteresse !", - "postSummonAuraBreak": "{{pokemonNameWithAffix}} inverse\ntoutes les auras !", "postSummonNeutralizingGas": "Le gaz inhibiteur {{pokemonNameWithAffix}}\nenvahit les lieux !", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}}\na deux talents !", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}}\na deux talents !", diff --git a/src/locales/fr/achv.json b/src/locales/fr/achv.json index a557a423db7..3e95f9326ca 100644 --- a/src/locales/fr/achv.json +++ b/src/locales/fr/achv.json @@ -227,7 +227,7 @@ "name": "Angry Birds" }, "MONO_POISON": { - "name": "Touche moi je t’empoisonne !" + "name": "Touche moi je t’empoisonne !" }, "MONO_GROUND": { "name": "Prévisions : Séisme" @@ -242,7 +242,7 @@ "name": "SOS Fantômes" }, "MONO_STEEL": { - "name": "De type Acier !" + "name": "De type Acier !" }, "MONO_FIRE": { "name": "Allumer le feu" diff --git a/src/locales/fr/arena-tag.json b/src/locales/fr/arena-tag.json index 9cb2f342068..c3c705290fa 100644 --- a/src/locales/fr/arena-tag.json +++ b/src/locales/fr/arena-tag.json @@ -54,4 +54,4 @@ "safeguardOnRemove": "Le terrain n’est plus protégé\npar le voile mystérieux !", "safeguardOnRemovePlayer": "Votre équipe n’est plus protégée\npar le voile mystérieux !", "safeguardOnRemoveEnemy": "L’équipe ennemie n’est plus protégée\npar le voile mystérieux !" -} +} \ No newline at end of file diff --git a/src/locales/fr/battle.json b/src/locales/fr/battle.json index 7b78c963187..b8da3a953ae 100644 --- a/src/locales/fr/battle.json +++ b/src/locales/fr/battle.json @@ -1,71 +1,70 @@ { "bossAppeared": "Un {{bossName}} apparait.", - "trainerAppeared": "Un combat est lancé\npar {{trainerName}} !", - "trainerAppearedDouble": "Un combat est lancé\npar {{trainerName}} !", + "trainerAppeared": "Un combat est lancé\npar {{trainerName}} !", + "trainerAppearedDouble": "Un combat est lancé\npar {{trainerName}} !", "trainerSendOut": "{{pokemonName}} est envoyé par\n{{trainerName}} !", - "singleWildAppeared": "Un {{pokemonName}} sauvage apparait !", - "multiWildAppeared": "Un {{pokemonName1}} et un {{pokemonName2}}\nsauvages apparaissent !", - "playerComeBack": "{{pokemonName}} !\nReviens !", - "trainerComeBack": "{{trainerName}} retire\n{{pokemonName}} !", - "playerGo": "{{pokemonName}} ! Go !", - "trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !", - "switchQuestion": "Voulez-vous changer\n{{pokemonName}} ?", - "trainerDefeated": "Vous avez battu\n{{trainerName}} !", - "moneyWon": "Vous remportez\n{{moneyAmount}} ₽ !", + "singleWildAppeared": "Un {{pokemonName}} sauvage apparait !", + "multiWildAppeared": "Un {{pokemonName1}} et un {{pokemonName2}}\nsauvages apparaissent !", + "playerComeBack": "{{pokemonName}} !\nReviens !", + "trainerComeBack": "{{trainerName}} retire {{pokemonName}} !", + "playerGo": "{{pokemonName}} ! Go !", + "trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !", + "switchQuestion": "Voulez-vous changer\nvotre {{pokemonName}} ?", + "trainerDefeated": "Vous avez battu\n{{trainerName}} !", + "moneyWon": "Vous remportez\n{{moneyAmount}} ₽ !", "moneyPickedUp": "Vous obtenez {{moneyAmount}} ₽ !", - "pokemonCaught": "Vous avez attrapé\n{{pokemonName}} !", + "pokemonCaught": "Vous avez attrapé {{pokemonName}} !", "addedAsAStarter": "{{pokemonName}} est ajouté\ncomme starter !", "partyFull": "Votre équipe est pleine.\nRelâcher un Pokémon pour {{pokemonName}} ?", - "pokemon": "de Pokémon", - "sendOutPokemon": "{{pokemonName}} ! Go !", + "pokemon": "Pokémon", + "sendOutPokemon": "{{pokemonName}} ! Go !", "hitResultCriticalHit": "Coup critique !", "hitResultSuperEffective": "C’est super efficace !", "hitResultNotVeryEffective": "Ce n’est pas très efficace…", "hitResultNoEffect": "Ça n’affecte pas {{pokemonName}}…", "hitResultImmune": "{{pokemonName}} n’est pas affecté !", "hitResultOneHitKO": "K.O. en un coup !", - "attackFailed": "Mais cela échoue !", + "attackFailed": "Mais cela échoue !", "attackMissed": "{{pokemonNameWithAffix}}\névite l’attaque !", - "attackHitsCount": "Touché {{count}} fois !", + "attackHitsCount": "Touché {{count}} fois !", "rewardGain": "Vous recevez\n{{modifierName}} !", - "expGain": "{{pokemonName}} gagne\n{{exp}} Points d’Exp !", - "levelUp": "{{pokemonName}} monte au\nN. {{level}} !", - "learnMove": "{{pokemonName}} apprend\n{{moveName}} !", + "expGain": "{{pokemonName}} gagne\n{{exp}} Points d’Exp !", + "levelUp": "{{pokemonName}} monte au\nN. {{level}} !", + "learnMove": "{{pokemonName}} apprend\n{{moveName}} !", "learnMovePrompt": "{{pokemonName}} veut apprendre\n{{moveName}}.", "learnMoveLimitReached": "Cependant, {{pokemonName}} connait\ndéjà quatre capacités.", - "learnMoveReplaceQuestion": "Voulez-vous oublier une capacité\net la remplacer par {{moveName}} ?", - "learnMoveStopTeaching": "Arrêter d’apprendre\n{{moveName}} ?", + "learnMoveReplaceQuestion": "Voulez-vous oublier une capacité\net la remplacer par {{moveName}} ?", + "learnMoveStopTeaching": "Arrêter d’apprendre\n{{moveName}} ?", "learnMoveNotLearned": "{{pokemonName}} n’a pas appris\n{{moveName}}.", - "learnMoveForgetQuestion": "Quelle capacité doit être oubliée ?", + "learnMoveForgetQuestion": "Quelle capacité doit être oubliée ?", "learnMoveForgetSuccess": "{{pokemonName}} oublie comment\nutiliser {{moveName}}.", "countdownPoof": "@d{32}1, @d{15}2, @d{15}et@d{15}… @d{15}… @d{15}… @d{15}@s{se/pb_bounce_1}Tadaaa !", "learnMoveAnd": "Et…", - "levelCapUp": "La limite de niveau\na été augmentée à {{levelCap}} !", + "levelCapUp": "La limite de niveau\na été augmentée à {{levelCap}} !", "moveNotImplemented": "{{moveName}} n’est pas encore implémenté et ne peut pas être sélectionné.", "moveNoPP": "Il n’y a plus de PP pour\ncette capacité !", - "moveDisabled": "{{moveName}} est sous entrave !", - "disableInterruptedMove": "Il y a une entrave sur la capacité {{moveName}}\nde{{pokemonNameWithAffix}} !", + "moveDisabled": "{{moveName}} est sous entrave !", "noPokeballForce": "Une force mystérieuse\nempêche l’utilisation des Poké Balls.", - "noPokeballTrainer": "Le Dresseur détourne la Ball\nVoler, c’est mal !", - "noPokeballMulti": "Impossible ! On ne peut pas viser\nquand il y a deux Pokémon !", - "noPokeballStrong": "Le Pokémon est trop fort pour être capturé !\nVous devez d’abord l’affaiblir !", + "noPokeballTrainer": "Le Dresseur détourne la Ball\nVoler, c’est mal !", + "noPokeballMulti": "Impossible ! On ne peut pas viser\nquand il y a deux Pokémon !", + "noPokeballStrong": "Le Pokémon est trop fort pour être capturé !\nVous devez d’abord l’affaiblir !", "noEscapeForce": "Une force mystérieuse\nempêche la fuite.", - "noEscapeTrainer": "On ne s’enfuit pas d’un\ncombat de Dresseurs !", - "noEscapePokemon": "{{moveName}} de {{pokemonName}}\nempêche {{escapeVerb}} !", - "runAwaySuccess": "Vous prenez la fuite !", - "runAwayCannotEscape": "Fuite impossible !", + "noEscapeTrainer": "On ne s’enfuit pas d’un\ncombat de Dresseurs !", + "noEscapePokemon": "{{moveName}} de {{pokemonName}}\nempêche {{escapeVerb}} !", + "runAwaySuccess": "Vous prenez la fuite !", + "runAwayCannotEscape": "Fuite impossible !", "escapeVerbSwitch": "le changement", "escapeVerbFlee": "la fuite", - "notDisabled": "La capacité {{moveName}}\nde {{pokemonName}} n’est plus sous entrave !", + "notDisabled": "La capacité {{moveName}}\nde {{pokemonName}} n’est plus sous entrave !", "turnEndHpRestore": "{{pokemonName}} récupère des PV !", "hpIsFull": "Les PV de {{pokemonName}}\nsont au maximum !", - "skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre d’objet ?", + "skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre d’objet ?", "itemStackFull": "Quantité maximale de {{fullItemName}} atteinte.\nVous recevez {{itemName}} à la place.", - "eggHatching": "Hein ?", - "ivScannerUseQuestion": "Utiliser le Scanner d’IV\nsur {{pokemonName}} ?", + "eggHatching": "Hein ?", + "ivScannerUseQuestion": "Utiliser le Scanner d’IV\nsur {{pokemonName}} ?", "wildPokemonWithAffix": "{{pokemonName}} sauvage", "foePokemonWithAffix": "{{pokemonName}} ennemi", - "useMove": "{{pokemonNameWithAffix}} utilise\n{{moveName}} !", + "useMove": "{{pokemonNameWithAffix}} utilise\n{{moveName}} !", "stealEatBerry": "{{pokemonName}} vole et mange\nla {{berryName}} de {{targetName}} !", "ppHealBerry": "La {{berryName}} de {{pokemonNameWithAffix}}\nrestaure les PP de sa capacité {{moveName}} !", "hpHealBerry": "La {{berryName}} de {{pokemonNameWithAffix}}\nrestaure son énergie !", @@ -74,27 +73,27 @@ "fainted": "{{pokemonNameWithAffix}}\nest K.O. !", "statsAnd": "et", "stats": "Les stats", - "statRose_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente !", - "statRose_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent !", - "statSharplyRose_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente beaucoup !", - "statSharplyRose_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent beaucoup !", - "statRoseDrastically_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente énormément !", - "statRoseDrastically_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent énormément !", - "statWontGoAnyHigher_one": "{{stats}} de {{pokemonNameWithAffix}}\nne peut plus augmenter !", - "statWontGoAnyHigher_other": "{{stats}}\nde {{pokemonNameWithAffix}} ne peuvent plus augmenter !", - "statFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse !", - "statFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent !", - "statHarshlyFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse beaucoup !", - "statHarshlyFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent beaucoup !", - "statSeverelyFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse énormément !", - "statSeverelyFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent énormément !", - "statWontGoAnyLower_one": "{{stats}} de {{pokemonNameWithAffix}}\nne peut plus baisser !", - "statWontGoAnyLower_other": "{{stats}}\nde {{pokemonNameWithAffix}} ne peuvent plus baisser !", - "transformedIntoType": "{{pokemonName}} prend\nle type {{type}} !", - "ppReduced": "Les PP de la capacité {{moveName}}\nde {{targetName}} baissent de {{reduction}} !", - "retryBattle": "Voulez-vous réessayer depuis le début du combat ?", + "statRose_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente !", + "statRose_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent !", + "statSharplyRose_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente beaucoup !", + "statSharplyRose_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent beaucoup !", + "statRoseDrastically_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente énormément !", + "statRoseDrastically_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent énormément !", + "statWontGoAnyHigher_one": "{{stats}} de {{pokemonNameWithAffix}}\nne peut plus augmenter !", + "statWontGoAnyHigher_other": "{{stats}}\nde {{pokemonNameWithAffix}} ne peuvent plus augmenter !", + "statFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse !", + "statFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent !", + "statHarshlyFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse beaucoup !", + "statHarshlyFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent beaucoup !", + "statSeverelyFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse énormément !", + "statSeverelyFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent énormément !", + "statWontGoAnyLower_one": "{{stats}} de {{pokemonNameWithAffix}}\nne peut plus baisser !", + "statWontGoAnyLower_other": "{{stats}}\nde {{pokemonNameWithAffix}} ne peuvent plus baisser !", + "transformedIntoType": "{{pokemonName}} transformed\ninto the {{type}} type!", + "ppReduced": "Les PP de la capacité {{moveName}}\nde {{targetName}} baissent de {{reduction}} !", + "retryBattle": "Voulez-vous réessayer depuis le début du combat ?", "unlockedSomething": "{{unlockedThing}}\na été débloqué.", - "congratulations": "Félicitations !", - "beatModeFirstTime": "{{speciesName}} a battu le mode {{gameMode}} pour la première fois !\nVous avez reçu {{newModifier}} !", - "eggSkipPrompt": "Aller directement au résumé des Œufs éclos ?" + "congratulations": "Félicitations !", + "beatModeFirstTime": "{{speciesName}} a battu le mode {{gameMode}} pour la première fois !\nVous avez reçu {{newModifier}} !", + "eggSkipPrompt": "Aller directement au résumé des Œufs éclos ?" } diff --git a/src/locales/fr/battler-tags.json b/src/locales/fr/battler-tags.json index f523eb7f07d..46b086938b3 100644 --- a/src/locales/fr/battler-tags.json +++ b/src/locales/fr/battler-tags.json @@ -29,8 +29,8 @@ "nightmareOnAdd": "{{pokemonNameWithAffix}} commence à cauchemarder !", "nightmareOnOverlap": "{{pokemonNameWithAffix}} est\ndéjà prisonnier d’un cauchemar !", "nightmareLapse": "{{pokemonNameWithAffix}}est\nprisonnier d’un cauchemar !", - "encoreOnAdd": "{{pokemonNameWithAffix}} !\nEncore une fois !", - "encoreOnRemove": "{{pokemonNameWithAffix}} n’est\nplus obligé d’utiliser la même capacité !", + "encoreOnAdd": "{{pokemonNameWithAffix}} !\nEncore une fois !", + "encoreOnRemove": "{{pokemonNameWithAffix}} n’est\nplus obligé d’utiliser la même capacité !", "helpingHandOnAdd": "{{pokemonNameWithAffix}} est prêt\nà aider {{pokemonName}} !", "ingrainLapse": "{{pokemonNameWithAffix}} absorbe\ndes nutriments avec ses racines !", "ingrainOnTrap": "{{pokemonNameWithAffix}}\nplante ses racines !", @@ -50,24 +50,22 @@ "protectedOnAdd": "{{pokemonNameWithAffix}}\nest prêt à se protéger !", "protectedLapse": "{{pokemonNameWithAffix}}\nse protège !", "enduringOnAdd": "{{pokemonNameWithAffix}} se prépare\nà encaisser les coups !", - "enduringLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !", - "sturdyLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !", + "enduringLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !", + "sturdyLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !", "perishSongLapse": "Le compte à rebours de Requiem\nde {{pokemonNameWithAffix}} descend à {{turnCount}} !", - "centerOfAttentionOnAdd": "{{pokemonNameWithAffix}} devient\nle centre de l’attention !", - "truantLapse": "{{pokemonNameWithAffix}} paresse !", - "slowStartOnAdd": "{{pokemonNameWithAffix}}\nn’arrive pas à se motiver !", - "slowStartOnRemove": "{{pokemonNameWithAffix}}\narrive enfin à s’y mettre sérieusement !", - "highestStatBoostOnAdd": "{{statName}} de {{pokemonNameWithAffix}}\nest renforcée !", - "highestStatBoostOnRemove": "L’effet du talent {{abilityName}}\nde {{pokemonNameWithAffix}} se dissipe !", - "magnetRisenOnAdd": "{{pokemonNameWithAffix}} lévite\nsur un champ magnétique !", - "magnetRisenOnRemove": "Le magnétisme de{{pokemonNameWithAffix}}\nse dissipe !", + "centerOfAttentionOnAdd": "{{pokemonNameWithAffix}} devient\nle centre de l’attention !", + "truantLapse": "{{pokemonNameWithAffix}} paresse !", + "slowStartOnAdd": "{{pokemonNameWithAffix}}\nn’arrive pas à se motiver !", + "slowStartOnRemove": "{{pokemonNameWithAffix}}\narrive enfin à s’y mettre sérieusement !", + "highestStatBoostOnAdd": "{{statName}} de {{pokemonNameWithAffix}}\nest renforcée !", + "highestStatBoostOnRemove": "L’effet du talent {{abilityName}}\nde {{pokemonNameWithAffix}} se dissipe !", + "magnetRisenOnAdd": "{{pokemonNameWithAffix}} lévite\nsur un champ magnétique !", + "magnetRisenOnRemove": "Le magnétisme de{{pokemonNameWithAffix}}\nse dissipe !", "critBoostOnAdd": "{{pokemonNameWithAffix}}\nest prêt à tout donner !", "critBoostOnRemove": "{{pokemonNameWithAffix}} se détend.", - "saltCuredOnAdd": "{{pokemonNameWithAffix}}\nest couvert de sel !", + "saltCuredOnAdd": "{{pokemonNameWithAffix}}\nest couvert de sel !", "saltCuredLapse": "{{pokemonNameWithAffix}} est blessé\npar la capacité {{moveName}} !", "cursedOnAdd": "{{pokemonNameWithAffix}} sacrifie des PV\net lance une malédiction sur {{pokemonName}} !", "cursedLapse": "{{pokemonNameWithAffix}} est touché par la malédiction !", - "stockpilingOnAdd": "{{pokemonNameWithAffix}} utilise\nla capacité Stockage {{stockpiledCount}} fois !", - "disabledOnAdd": "La capacité {{moveName}}\nde {{pokemonNameWithAffix}} est mise sous entrave !", - "disabledLapse": "La capacité {{moveName}}\nde {{pokemonNameWithAffix}} n’est plus sous entrave !" -} + "stockpilingOnAdd": "{{pokemonNameWithAffix}} utilise\nla capacité Stockage {{stockpiledCount}} fois !" +} \ No newline at end of file diff --git a/src/locales/fr/command-ui-handler.json b/src/locales/fr/command-ui-handler.json index 82733837375..a991c618820 100644 --- a/src/locales/fr/command-ui-handler.json +++ b/src/locales/fr/command-ui-handler.json @@ -3,5 +3,5 @@ "ball": "Ball", "pokemon": "Pokémon", "run": "Fuite", - "actionMessage": "Que doit faire\n{{pokemonName}} ?" -} + "actionMessage": "Que doit faire\n{{pokemonName}} ?" +} \ No newline at end of file diff --git a/src/locales/fr/dialogue-double-battle.json b/src/locales/fr/dialogue-double-battle.json index fbc5d56ed26..d35e9d87ced 100644 --- a/src/locales/fr/dialogue-double-battle.json +++ b/src/locales/fr/dialogue-double-battle.json @@ -1,83 +1,83 @@ { "blue_red_double": { "encounter": { - "1": "Blue : Hé Red, montrons-lui de quel bois on se chauffe !\n$Red : …\n$Blue : Voilà la puissance du Bourg Palette !" + "1": "Blue : Hé Red, montrons-lui de quel bois on se chauffe !\n$Red : …\n$Blue : Voilà la puissance du Bourg Palette !" }, "victory": { - "1": "Blue : C’était un magnifique combat !\n$Red : …" + "1": "Blue : C’était un magnifique combat !\n$Red : …" } }, "red_blue_double": { "encounter": { - "1": "Red : … !\n$Blue : Il est pas très loquace.\n$Blue : Mais ne te laisse pas avoir, ça reste un Maitre Pokémon !" + "1": "Red : … !\n$Blue : Il est pas très loquace.\n$Blue : Mais ne te laisse pas avoir, ça reste un Maitre Pokémon !" }, "victory": { - "1": "Red : … !\n$Blue : La prochaine fois, on va te battre !" + "1": "Red : … !\n$Blue : La prochaine fois, on va te battre !" } }, "tate_liza_double": { "encounter": { - "1": "Lévy : Héhéhé… Tu en fais une drôle de tête.\n$Tatia : Tu ne t’attendais pas à rencontrer deux Champions, n’est-ce pas ?\n$Lévy : Nous sommes des jumeaux !\n$Tatia : Nous n’avons pas besoin de parler entre nous !\n$Lévy : Tu crois pouvoir briser…\n$Tatia : … Notre duo parfait ?" + "1": "Lévy : Héhéhé… Tu en fais une drôle de tête.\n$Tatia : Tu ne t’attendais pas à rencontrer deux Champions, n’est-ce pas ?\n$Lévy : Nous sommes des jumeaux !\n$Tatia : Nous n’avons pas besoin de parler entre nous !\n$Lévy : Tu crois pouvoir briser…\n$Tatia : … Notre duo parfait ?" }, "victory": { - "1": "Lévy : Quoi ? Notre combinaison était parfaite !\n$Tatia : Nous avons encore besoin d’entrainement…" + "1": "Lévy : Quoi ? Notre combinaison était parfaite !\n$Tatia : Nous avons encore besoin d’entrainement…" } }, "liza_tate_double": { "encounter": { - "1": "Tatia : Hihih… Si tu voyais ta tête !\n$Lévy : Oui, nous sommes deux Champions en un !\n$Tatia : Voici mon frère, Lévy…\n$Lévy : … Et ma sœur, Tatia !\n$Tatia : Tu ne penses pas que notre combinaison est parfaite ?" + "1": "Tatia : Hihih… Si tu voyais ta tête !\n$Lévy : Oui, nous sommes deux Champions en un !\n$Tatia : Voici mon frère, Lévy…\n$Lévy : … Et ma sœur, Tatia !\n$Tatia : Tu ne penses pas que notre combinaison est parfaite ?" }, "victory": { - "1": "Tatia : Quoi ? Notre combinaison…\n$Lévy : … a échoué !" + "1": "Tatia : Quoi ? Notre combinaison…\n$Lévy : … a échoué !" } }, "wallace_steven_double": { "encounter": { - "1": "Pierre R. : Marc, montrons-lui la puissance des Maitres !\n$Marc : Tu vas gouter au pouvoir de Hoenn !\n$Pierre R. : C’est parti !" + "1": "Pierre R. : Marc, montrons-lui la puissance des Maitres !\n$Marc : Tu vas gouter au pouvoir de Hoenn !\n$Pierre R. : C’est parti !" }, "victory": { - "1": "Pierre R. : C’était un beau combat !\n$Marc : Ce sera notre tour la prochaine fois !" + "1": "Pierre R. : C’était un beau combat !\n$Marc : Ce sera notre tour la prochaine fois !" } }, "steven_wallace_double": { "encounter": { - "1": "Pierre R. : Excuse-moi, aurais-tu des Pokémon rares ?\n$Marc : Pierre… Nous sommes là pour nous battre, pas pour frimer avec nos Pokémon.\n$Pierre R. : Oh… Je vois… Commençons alors !" + "1": "Pierre R. : Excuse-moi, aurais-tu des Pokémon rares ?\n$Marc : Pierre… Nous sommes là pour nous battre, pas pour frimer avec nos Pokémon.\n$Pierre R. : Oh… Je vois… Commençons alors !" }, "victory": { - "1": "Pierre R. : Bien, maintenant que ce combat est clos, montrons-nous nos Pokémon !\n$Marc : Pierre…" + "1": "Pierre R. : Bien, maintenant que ce combat est clos, montrons-nous nos Pokémon !\n$Marc : Pierre…" } }, "alder_iris_double": { "encounter": { - "1": "Goyah : Nous sommes l’élite des Dresseurs d’Unys !\n$Iris : Rien de mieux que des combats contre des prodiges !" + "1": "Goyah : Nous sommes l’élite des Dresseurs d’Unys !\n$Iris : Rien de mieux que des combats contre des prodiges !" }, "victory": { - "1": "Goyah : INCROYABLE ! T’es trop doué !\n$Iris : On gagnera la prochaine fois !" + "1": "Goyah : INCROYABLE ! T’es trop doué !\n$Iris : On gagnera la prochaine fois !" } }, "iris_alder_double": { "encounter": { - "1": "Iris : Bienvenue, Dresseur ! Je suis LA Maitresse d’Unys !\n$Goyah : Iris, concentre-toi s’il te plait…" + "1": "Iris : Bienvenue, Dresseur ! Je suis LA Maitresse d’Unys !\n$Goyah : Iris, concentre-toi s’il te plait…" }, "victory": { - "1": "Iris : On a tout donné et pourtant…\n$Goyah : Cette défaite ne pourra que nous être bénéfique !" + "1": "Iris : On a tout donné et pourtant…\n$Goyah : Cette défaite ne pourra que nous être bénéfique !" } }, "piers_marnie_double": { "encounter": { - "1": "Rosemary : Frérot, montrons-lui la puissance de Smashings !\n$Peterson : Nous sommes les ténèbres !" + "1": "Rosemary : Frérot, montrons-lui la puissance de Smashings !\n$Peterson : Nous sommes les ténèbres !" }, "victory": { - "1": "Rosemary : T’as amené la lumière dans les ténèbres !\n$Peterson : P’têtre un peu trop…" + "1": "Rosemary : T’as amené la lumière dans les ténèbres !\n$Peterson : P’têtre un peu trop…" } }, "marnie_piers_double": { "encounter": { - "1": "Peterson : Chauds pour un concert ?\n$Rosemary : Frérot… Il est pas là pour chanter, mais se battre…", - "1_female": "Peterson : Chauds pour un concert ?\n$Rosemary : Frérot… Elle est pas là pour chanter, mais se battre…" + "1": "Peterson : Chauds pour un concert ?\n$Rosemary : Frérot… Il est pas là pour chanter, mais se battre…", + "1_female": "Peterson : Chauds pour un concert ?\n$Rosemary : Frérot… Elle est pas là pour chanter, mais se battre…" }, "victory": { - "1": "Peterson : Ça c’est du rock !\n$Rosemary : Frérot…" + "1": "Peterson : Ça c’est du rock !\n$Rosemary : Frérot…" } } } diff --git a/src/locales/fr/dialogue-final-boss.json b/src/locales/fr/dialogue-final-boss.json index b7226ebb480..c5a5e3b7d89 100644 --- a/src/locales/fr/dialogue-final-boss.json +++ b/src/locales/fr/dialogue-final-boss.json @@ -1,6 +1,6 @@ { - "encounter": "Une fois de plus, te revoilà.\nSais-tu que ce n’est point là ta première venue ?\n$Tu as été appelé ici parce que t’y es déjà venu.\nUn nombre inimaginable de fois.\n$Mais allons-y, faisons le décompte.\nTu en es très précisément à ton {{cycleCount}}e cycle.\n$Chaque cycle réinitialise ton souvenir du précédent.\nMais étrangement, des bribes subsistent en toi.\n$Jusqu’à maintenant, tu as toujours échoué. Mais je ressens quelque chose de différent cette fois-ci.\n\n$Tu es la seule présence ici, bien que j’ai le sentiment d’en ressentir… une autre.\n$Vas-tu enfin me livrer un affrontement digne de ce nom ?\nCe challenge dont je rêve depuis un millénaire ?\n$Commençons.", - "encounter_female": "Une fois de plus, te revoilà.\nSais-tu que ce n’est point là ta première venue ?\n$Tu as été appelée ici parce que t’y es déjà venue.\nUn nombre inimaginable de fois.\n$Mais allons-y, faisons le décompte.\nTu en es très précisément à ton {{cycleCount}}e cycle.\n$Chaque cycle réinitialise ton souvenir du précédent.\nMais étrangement, des bribes subsistent en toi.\n$Jusqu’à maintenant, tu as toujours échoué. Mais je ressens quelque chose de différent cette fois-ci.\n\n$Tu es la seule présence ici, bien que j’ai le sentiment d’en ressentir… une autre.\n$Vas-tu enfin me livrer un affrontement digne de ce nom ?\nCe challenge dont je rêve depuis un millénaire ?\n$Commençons.", + "encounter": "Une fois de plus, te revoilà.\nSais-tu que ce n’est point là ta première venue ?\n$Tu as été appelé ici parce que t’y es déjà venu.\nUn nombre inimaginable de fois.\n$Mais allons-y, faisons le décompte.\nTu en es très précisément à ton {{cycleCount}}e cycle.\n$Chaque cycle réinitialise ton souvenir du précédent.\nMais étrangement, des bribes subsistent en toi.\n$Jusqu’à maintenant, tu as toujours échoué. Mais je ressens quelque chose de différent cette fois-ci.\n\n$Tu es la seule présence ici, bien que j’ai le sentiment d’en ressentir… une autre.\n$Vas-tu enfin me livrer un affrontement digne de ce nom ?\nCe challenge dont je rêve depuis un millénaire ?\n$Commençons.", + "encounter_female": "Une fois de plus, te revoilà.\nSais-tu que ce n’est point là ta première venue ?\n$Tu as été appelée ici parce que t’y es déjà venue.\nUn nombre inimaginable de fois.\n$Mais allons-y, faisons le décompte.\nTu en es très précisément à ton {{cycleCount}}e cycle.\n$Chaque cycle réinitialise ton souvenir du précédent.\nMais étrangement, des bribes subsistent en toi.\n$Jusqu’à maintenant, tu as toujours échoué. Mais je ressens quelque chose de différent cette fois-ci.\n\n$Tu es la seule présence ici, bien que j’ai le sentiment d’en ressentir… une autre.\n$Vas-tu enfin me livrer un affrontement digne de ce nom ?\nCe challenge dont je rêve depuis un millénaire ?\n$Commençons.", "firstStageWin": "Je vois. Cette présence était bien réelle.\nJe n’ai donc plus besoin de retenir mes coups.\n$Ne me déçoit pas.", "secondStageWin": "… Magnifique." -} +} \ No newline at end of file diff --git a/src/locales/fr/dialogue-misc.json b/src/locales/fr/dialogue-misc.json index 864bd53eab5..c8c781002b9 100644 --- a/src/locales/fr/dialogue-misc.json +++ b/src/locales/fr/dialogue-misc.json @@ -1,6 +1,6 @@ { - "ending": "@c{shock}T’es revenu ?@d{32} Ça veut dire…@d{96} que t’as gagné ?!\n@c{smile_ehalf}J’aurais dû m’en douter.\n$@c{smile_eclosed}Bien sûr… J’ai toujours eu ce sentiment.\n@c{smile}C’est fini maintenant hein ? T’as brisé ce cycle.\n$@c{smile_ehalf}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$Je serai la seule à me souvenir de ce que t’as fait.\n@c{angry_mopen}Je tâcherai de ne pas oublier !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile}Jamais j’oublierai.@d{32}\nTa légende vivra à jamais dans nos cœurs.\n$@c{smile_wave}Bon,@d{64} il se fait tard…@d{96} je crois ?\nDifficile à dire ici.\n$Rentrons, @c{smile_wave_wink}et demain on se fera un p’tit combat, comme au bon vieux temps ?", - "ending_female": "@c{smile}Oh ? T’as gagné ?@d{96} @c{smile_eclosed}J’aurais dû m’en douter.\nMais te voilà enfin de retour.\n$@c{smile}C’est terminé.@d{64} T’as brisé ce cycle infernal.\n$@c{serious_smile_fists}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$@c{neutral}Je suis le seul à me souvenir de ce que t’as fait.@d{96}\nJe pense que ça ira, non ?\n$@c{serious_smile_fists}Ta légende vivra à jamais dans nos cœurs.\n$@c{smile_eclosed}Bref, j’en ai un peu marre de ce endroit, pas toi ? Rentrons à la maison.\n$@c{serious_smile_fists}On se fera un p’tit combat une fois rentrés ?\nSi t’es d’accord.", - "ending_endless": "Félicitations ! Vous avez atteint la fin actuelle.\nPlus de contenu à venir bientôt !", + "ending": "@c{shock}T’es revenu ?@d{32} Ça veut dire…@d{96} que t’as gagné ?!\n@c{smile_ehalf}J’aurais dû m’en douter.\n$@c{smile_eclosed}Bien sûr… J’ai toujours eu ce sentiment.\n@c{smile}C’est fini maintenant hein ? T’as brisé ce cycle.\n$@c{smile_ehalf}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$Je serai la seule à me souvenir de ce que t’as fait.\n@c{angry_mopen}Je tâcherai de ne pas oublier !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile}Jamais j’oublierai.@d{32}\nTa légende vivra à jamais dans nos cœurs.\n$@c{smile_wave}Bon,@d{64} il se fait tard…@d{96} je crois ?\nDifficile à dire ici.\n$Rentrons, @c{smile_wave_wink}et demain on se fera un p’tit combat, comme au bon vieux temps ?", + "ending_female": "@c{smile}Oh ? T’as gagné ?@d{96} @c{smile_eclosed}J’aurais dû m’en douter.\nMais te voilà enfin de retour.\n$@c{smile}C’est terminé.@d{64} T’as brisé ce cycle infernal.\n$@c{serious_smile_fists}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$@c{neutral}Je suis le seul à me souvenir de ce que t’as fait.@d{96}\nJe pense que ça ira, non ?\n$@c{serious_smile_fists}Ta légende vivra à jamais dans nos cœurs.\n$@c{smile_eclosed}Bref, j’en ai un peu marre de ce endroit, pas toi ? Rentrons à la maison.\n$@c{serious_smile_fists}On se fera un p’tit combat une fois rentrés ?\nSi t’es d’accord.", + "ending_endless": "Félicitations ! Vous avez atteint la fin actuelle.\nPlus de contenu à venir bientôt !", "ending_name": "Les devs" } diff --git a/src/locales/fr/dialogue.json b/src/locales/fr/dialogue.json index dddd0d8e5b7..d9d13a8f1e8 100644 --- a/src/locales/fr/dialogue.json +++ b/src/locales/fr/dialogue.json @@ -1,50 +1,50 @@ { "youngster": { "encounter": { - "1": "Hé ! Combat ?", - "2": "Toi aussi tu débutes ?", - "3": "Hé, j’me souviens pas de ta tête. Combat !", - "4": "J’ai perdu, alors j’essaye de capturer d’autres Pokémon.\nHé, t’as l’air faible toi ! Allez, combat !", - "5": "On s’connait ? J’ai comme un doute. Dans tous les cas, sympa de te rencontrer !", - "6": "Allez, c’est parti !", - "7": "Attention, me voilà !\nTu vas voir comment j’suis fort !", - "8": "Coucou… Tu veux voir mes bô Pokémon ?", - "9": "Trêve de mondanités. Ramène-toi quand tu le sens !", + "1": "Hé ! Combat ?", + "2": "Toi aussi tu débutes ?", + "3": "Hé, j’me souviens pas de ta tête. Combat !", + "4": "J’ai perdu, alors j’essaye de capturer d’autres Pokémon.\nHé, t’as l’air faible toi ! Allez, combat !", + "5": "On s’connait ? J’ai comme un doute. Dans tous les cas, sympa de te rencontrer !", + "6": "Allez, c’est parti !", + "7": "Attention, me voilà !\nTu vas voir comment j’suis fort !", + "8": "Coucou… Tu veux voir mes bô Pokémon ?", + "9": "Trêve de mondanités. Ramène-toi quand tu le sens !", "10": "Baisse pas ta garde si tu veux pas pleurer d’avoir perdu face à un gamin.", - "11": "J’ai tout donné pour élever mes Pokémon. Attention à toi si tu leur fait du mal !", - "12": "Incroyable que t’y sois parvenu ! Mais la suite va pas être une partie de plaisir.", - "12_female": "Incroyable que t’y sois parvenue ! Mais la suite va pas être une partie de plaisir.", - "13": "Les combats sont éternels ! Bienvenue dans un monde sans fin !" + "11": "J’ai tout donné pour élever mes Pokémon. Attention à toi si tu leur fait du mal !", + "12": "Incroyable que t’y sois parvenu ! Mais la suite va pas être une partie de plaisir.", + "12_female": "Incroyable que t’y sois parvenue ! Mais la suite va pas être une partie de plaisir.", + "13": "Les combats sont éternels ! Bienvenue dans un monde sans fin !" }, "victory": { - "1": "Hé, mais t’es trop fort !", - "1_female": "Hé, mais t’es trop forte !", - "2": "En vrai j’avais aucune chance hein ?", - "3": "J’te retrouverai un jour, et là j’te battrai !", + "1": "Hé, mais t’es trop fort !", + "1_female": "Hé, mais t’es trop forte !", + "2": "En vrai j’avais aucune chance hein ?", + "3": "J’te retrouverai un jour, et là j’te battrai !", "4": "Arg… J’ai plus aucun Pokémon.", - "5": "Non… IMPOSSIBLE ! Pourquoi j’ai encore perdu…", - "6": "Non ! J’ai perdu !", - "7": "Waah ! T’es trop incroyable ! J’suis bouche bée !", + "5": "Non… IMPOSSIBLE ! Pourquoi j’ai encore perdu…", + "6": "Non ! J’ai perdu !", + "7": "Waah ! T’es trop incroyable ! J’suis bouche bée !", "8": "Pourquoi… Comment… Pourtant on est les plus forts, mes Pokémon et moi…", - "9": "J’perdrai pas la prochaine fois ! Remettons ça un jour !", - "10": "Weeeesh ! Tu vois que j’suis qu’un gamin ? C’est pas juste de me bully comme ça !", - "11": "Tes Pokémon sont trop incroyables !\n… P’tit échange ?", - "12": "Je me suis fait un peu aider plus tôt, mais de quel taf je parlais ?", - "13": "Ahaha ! Et voilà, ça y est !\nT’es déjà comme chez toi dans ce monde !" + "9": "J’perdrai pas la prochaine fois ! Remettons ça un jour !", + "10": "Weeeesh ! Tu vois que j’suis qu’un gamin ? C’est pas juste de me bully comme ça !", + "11": "Tes Pokémon sont trop incroyables !\n… P’tit échange ?", + "12": "Je me suis fait un peu aider plus tôt, mais de quel taf je parlais ?", + "13": "Ahaha ! Et voilà, ça y est !\nT’es déjà comme chez toi dans ce monde !" } }, "lass": { "encounter": { - "1": "Affrontons-nous, d’accord ?", - "2": "T’as l’air d’un nouveau Dresseur. Battons nous !", - "2_female": "T’as l’air d’une nouvelle Dresseuse. Battons nous !", - "3": "Je te connais pas. Ça te dis de te battre ?", - "4": "Prenons du bon temps avec ce combat Pokémon !", - "5": "Je vais t’apprendre à te battre avec tes Pokémon !", + "1": "Affrontons-nous, d’accord ?", + "2": "T’as l’air d’un nouveau Dresseur. Battons nous !", + "2_female": "T’as l’air d’une nouvelle Dresseuse. Battons nous !", + "3": "Je te connais pas. Ça te dis de te battre ?", + "4": "Prenons du bon temps avec ce combat Pokémon !", + "5": "Je vais t’apprendre à te battre avec tes Pokémon !", "6": "Un combat doit toujours être pris au sérieux.\nT’es prêt à te battre ?", - "6_female": "Un combat doit toujours être pris au sérieux.\nT’es prête à te battre ?", + "6_female": "Un combat doit toujours être pris au sérieux.\nT’es prête à te battre ?", "7": "Tu seras pas jeune éternellement. T’as qu’une chance pendant un combat. Bientôt, tu seras plus qu’un souvenir.", - "8": "Tu ferais mieux d’y aller doucement avec moi. Mais je vais me battre sérieusement !", + "8": "Tu ferais mieux d’y aller doucement avec moi. Mais je vais me battre sérieusement !", "9": "Je m’ennuie à l’école. Y’a rien à y faire. *Baille*\nJe me bats juste pour passer le temps." }, "victory": { @@ -52,12 +52,12 @@ "2": "Je ne pensais pas que je perdrais comme ça…", "2_female": "Je pensais pas que je perdrais comme ça…", "3": "J’espère que j’aurai ma revanche un jour.", - "4": "C’était super amusant ! Mais ce combat m’a épuisée…", - "5": "Tu m’as appris une belle leçon ! T’es vraiment incroyable !", - "6": "Vraiment ? J’ai perdu… ? C’est des choses qui arrivent, ça me déprime mais tu es vraiment très cool.", - "6_female": "Vraiment ? J’ai perdu… ? C’est des choses qui arrivent, ça me déprime mais t’es vraiment très cool.", + "4": "C’était super amusant ! Mais ce combat m’a épuisée…", + "5": "Tu m’as appris une belle leçon ! T’es vraiment incroyable !", + "6": "Vraiment ? J’ai perdu… ? C’est des choses qui arrivent, ça me déprime mais tu es vraiment très cool.", + "6_female": "Vraiment ? J’ai perdu… ? C’est des choses qui arrivent, ça me déprime mais t’es vraiment très cool.", "7": "J’ai pas besoin de ce genre de souvenirs.\n*Suppression de mémoire en cours…*", - "8": "Hé ! Je t’avais dit d’y aller doucement avec moi ! Mais t’es vraiment si cool quand tu te bats sérieusement…", + "8": "Hé ! Je t’avais dit d’y aller doucement avec moi ! Mais t’es vraiment si cool quand tu te bats sérieusement…", "9": "J’en ai marre des combats Pokémon…\nJe vais chercher d’autres trucs à faire…" } }, @@ -123,7 +123,7 @@ "encounter": { "1": "C’est l’heure de plonger dans le vif !", "2": "C’est le moment de surfer sur les vagues de la victoire !", - "3": "Je vais t’éclabousser de mon talent !" + "3": "Je vais t’éclabousser de mon talent !" }, "victory": { "1": "Tu m’as complètement séché", @@ -169,10 +169,10 @@ }, "parasol_lady": { "encounter": { - "1": "Honorons ce terrain de combat avec élégance et équilibre !" + "1": "Honorons ce terrain de combat avec élégance et équilibre !" }, "victory": { - "1": "Mon élégance demeure inébranlable !" + "1": "Mon élégance demeure inébranlable !" } }, "rocket_grunt": { @@ -528,14 +528,14 @@ "3": "Ouah ! T’es super balèze !" }, "defeat": { - "1": "Qu’en dis-tu ? C’est ça, la puissance des Pokémon Eau !", + "1": "Qu’en dis-tu? C’est ça, la puissance des Pokémon Eau !", "2": "J’espère que t’as pris note des élégantes techniques de nage de mes Pokémon !", "3": "Tes Pokémon ne jouent visiblement pas dans le même bassin…" } }, "lt_surge": { "encounter": { - "1": "T’as pas froid aux yeux, soldat ! Les combats Pokémon, c’est la guerre !", + "1": "T’as pas froid aux yeux, soldat ! Les combats Pokémon, c’est la guerre !", "2": "Tu as du guts pour venir me fight ici ! Je vais te shock !", "3": "Compte tes dents, tu vas morfler !\nMes Pokémon Électrik vont t’atomiser !" }, @@ -573,56 +573,56 @@ }, "alder": { "encounter": { - "1": "Prépare-toi pour un combat contre le meilleur Dresseur d’Unys !" + "1": "Prépare-toi pour un combat contre le meilleur Dresseur d’Unys !" }, "victory": { - "1": "Bien joué ! Tu as sans aucun doute un talent inégalé." + "1": "Bien joué ! Tu as sans aucun doute un talent inégalé." }, "defeat": { - "1": "Une brise fraiche traverse mon cœur…\n$Quel effort extraordinaire !" + "1": "Une brise fraiche traverse mon cœur…\n$Quel effort extraordinaire !" } }, "kieran": { "encounter": { - "1": "Grâce à un travail acharné, je deviens de plus en plus fort !\n$Je ne perdrai pas." + "1": "Grâce à un travail acharné, je deviens de plus en plus fort !\n$Je ne perdrai pas." }, "victory": { - "1": "Je n’y crois pas…\n$Quel combat amusant et palpitant !" + "1": "Je n’y crois pas…\n$Quel combat amusant et palpitant !" }, "defeat": { - "1": "Eh beh, quel combat !\n$Il est temps pour toi de t’entrainer encore plus dur." + "1": "Eh beh, quel combat !\n$Il est temps pour toi de t’entrainer encore plus dur." } }, "rival": { "encounter": { - "1": "@c{smile}Ah, je te cherchais ! Je savais que t’étais pressée de partir, mais je m’attendais quand même à un au revoir…\n$@c{smile_eclosed}T’as finalement décidé de réaliser ton rêve ?\nJ’ai peine à y croire.\n$@c{serious_smile_fists}Vu que t’es là, ça te dis un petit combat ?\nJe voudrais quand même m’assurer que t’es prête.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que t’as !" + "1": "@c{smile}Ah, je te cherchais ! Je savais que t’étais pressée de partir, mais je m’attendais quand même à un au revoir…\n$@c{smile_eclosed}T’as finalement décidé de réaliser ton rêve ?\nJ’ai peine à y croire.\n$@c{serious_smile_fists}Vu que t’es là, ça te dis un petit combat ?\nJe voudrais quand même m’assurer que t’es prête.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que t’as !" }, "victory": { - "1": "@c{shock}Wah… Tu m’as vraiment lavé.\nT’es vraiment une débutante ?\n$@c{smile}T’as peut-être eu de la chance, mais…\nPeut-être que t’arriveras jusqu’au bout du chemin.\n$D’ailleurs, le prof m’a demandé de te filer ces objets.\nIls ont l’air sympas.\n$@c{serious_smile_fists}Bonne chance à toi !" + "1": "@c{shock}Wah… Tu m’as vraiment lavé.\nT’es vraiment une débutante ?\n$@c{smile}T’as peut-être eu de la chance, mais…\nPeut-être que t’arriveras jusqu’au bout du chemin.\n$D’ailleurs, le prof m’a demandé de te filer ces objets.\nIls ont l’air sympas.\n$@c{serious_smile_fists}Bonne chance à toi !" } }, "rival_female": { "encounter": { - "1": "@c{smile_wave}Ah, te voilà ! Je t’ai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}T’as décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de m’avoir oubliée,\nà une condition. @c{smile_wave_wink}Que tu m’affronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant d’avoir commencé, hein ?" + "1": "@c{smile_wave}Ah, te voilà ! Je t’ai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}T’as décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de m’avoir oubliée,\nà une condition. @c{smile_wave_wink}Que tu m’affronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant d’avoir commencé, hein ?" }, "victory": { - "1": "@c{shock}Tu viens de commencer et t’es déjà si fort ?!@d{96}\n@c{angry}T’as triché non ? Avoue !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile_eclosed}J’ai perdu dans les règles…\nJ’ai le sentiment que tu vas très bien t’en sortir.\n$@c{smile}D’ailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !\n$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !" + "1": "@c{shock}Tu viens de commencer et t’es déjà si fort ?!@d{96}\n@c{angry}T’as triché non ? Avoue !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile_eclosed}J’ai perdu dans les règles…\nJ’ai le sentiment que tu vas très bien t’en sortir.\n$@c{smile}D’ailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !\n$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !" } }, "rival_2": { "encounter": { - "1": "@c{smile}Hé, toi aussi t’es là ?\n@c{smile_eclosed}Toujours invaincue, hein… ?\n$@c{serious_mopen_fists}Je sais que j’ai l’air de t’avoir suivie ici, mais c’est pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait d’avoir une revanche depuis que tu m’as battu.\n$Je me suis beaucoup entrainé, alors sois sure que je vais pas retenir mes coups cette fois.\n$@c{serious_mopen_fists}Et comme la dernière fois, ne te retiens pas !\nC’est parti !" + "1": "@c{smile}Hé, toi aussi t’es là ?\n@c{smile_eclosed}Toujours invaincue, hein… ?\n$@c{serious_mopen_fists}Je sais que j’ai l’air de t’avoir suivie ici, mais c’est pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait d’avoir une revanche depuis que tu m’as battu.\n$Je me suis beaucoup entrainé, alors sois sure que je vais pas retenir mes coups cette fois.\n$@c{serious_mopen_fists}Et comme la dernière fois, ne te retiens pas !\nC’est parti !" }, "victory": { - "1": "@c{neutral_eclosed}Oh. Je crois que j’ai trop pris la confiance.\n$@c{smile}Pas grave, c’est OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus m’entrainer !\n\n$@c{smile}Ah, et pas que t’aies réellement besoin d’aide, mais j’ai ça en trop sur moi qui pourrait t’intéresser.\n\n$@c{serious_smile_fists}Mais n’espère plus en avoir d’autres !\nJe peux pas passer mon temps à aider mon adversaire.\n$@c{smile}Bref, prends soin de toi !" + "1": "@c{neutral_eclosed}Oh. Je crois que j’ai trop pris la confiance.\n$@c{smile}Pas grave, c’est OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus m’entrainer !\n\n$@c{smile}Ah, et pas que t’aies réellement besoin d’aide, mais j’ai ça en trop sur moi qui pourrait t’intéresser.\n\n$@c{serious_smile_fists}Mais n’espère plus en avoir d’autres !\nJe peux pas passer mon temps à aider mon adversaire.\n$@c{smile}Bref, prends soin de toi !" } }, "rival_2_female": { "encounter": { - "1": "@c{smile_wave}Hé, sympa de te croiser ici. T’as toujours l’air invaincu. @c{angry_mopen}Eh… Pas mal !\n$@c{angry_mopen}Je sais à quoi tu penses et non, je t’espionne pas.\n@c{smile_eclosed}C’est juste que j’étais aussi dans le coin.\n$@c{smile_ehalf}Heureuse pour toi, mais je veux juste te rappeler que c’est pas grave de perdre parfois.\n$@c{smile}On apprend de nos erreurs, souvent plus que si on ne connaissait que le succès.\n$@c{angry_mopen}Dans tous les cas je me suis bien entrainée pour cette revanche, t’as intérêt à tout donner !" + "1": "@c{smile_wave}Hé, sympa de te croiser ici. T’as toujours l’air invaincu. @c{angry_mopen}Eh… Pas mal !\n$@c{angry_mopen}Je sais à quoi tu penses et non, je t’espionne pas.\n@c{smile_eclosed}C’est juste que j’étais aussi dans le coin.\n$@c{smile_ehalf}Heureuse pour toi, mais je veux juste te rappeler que c’est pas grave de perdre parfois.\n$@c{smile}On apprend de nos erreurs, souvent plus que si on ne connaissait que le succès.\n$@c{angry_mopen}Dans tous les cas je me suis bien entrainée pour cette revanche, t’as intérêt à tout donner !" }, "victory": { - "1": "@c{neutral}Je… J’étais pas encore supposée perdre…\n$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus m’entrainer !\n$@c{smile_wave}J’ai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.\n$@c{angry_mopen}C’étaient les derniers, terminé les cadeaux après ceux-là !\n$@c{smile_wave}Allez, tiens le coup !" + "1": "@c{neutral}Je… J’étais pas encore supposée perdre…\n$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus m’entrainer !\n$@c{smile_wave}J’ai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.\n$@c{angry_mopen}C’étaient les derniers, terminé les cadeaux après ceux-là !\n$@c{smile_wave}Allez, tiens le coup !" }, "defeat": { "1": "Je suppose que c’est parfois normal de perdre…" @@ -630,18 +630,18 @@ }, "rival_3": { "encounter": { - "1": "@c{smile}Hé, mais qui voilà ! Ça fait un bail.\n@c{neutral}T’es… toujours invaincue ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nC’est plus pareil sans toi au village.\n$@c{serious}Je sais que c’est égoïste, mais j’ai besoin d’expier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, c’est juste irréaliste.\nGrandir, c’est parfois aussi savoir perdre.\n$@c{neutral_eclosed}T’as un beau parcours, mais il y a encore tellement à venir et ça va pas s’arranger. @c{neutral}T’es prête pour ça ?\n$@c{serious_mopen_fists}Si tu l’es, alors prouve-le." + "1": "@c{smile}Hé, mais qui voilà ! Ça fait un bail.\n@c{neutral}T’es… toujours invaincue ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nC’est plus pareil sans toi au village.\n$@c{serious}Je sais que c’est égoïste, mais j’ai besoin d’expier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, c’est juste irréaliste.\nGrandir, c’est parfois aussi savoir perdre.\n$@c{neutral_eclosed}T’as un beau parcours, mais il y a encore tellement à venir et ça va pas s’arranger. @c{neutral}T’es prête pour ça ?\n$@c{serious_mopen_fists}Si tu l’es, alors prouve-le." }, "victory": { - "1": "@c{angry_mhalf}C’est lunaire… J’ai presque fait que m’entrainer…\nAlors pourquoi il y a encore un tel écart entre nous ?" + "1": "@c{angry_mhalf}C’est lunaire… J’ai presque fait que m’entrainer…\nAlors pourquoi il y a encore un tel écart entre nous ?" } }, "rival_3_female": { "encounter": { - "1": "@c{smile_wave}Ça fait une éternité ! Toujours debout hein ?\n@c{angry}Tu commences à me pousser à bout là. @c{smile_wave_wink}T’inquiètes j’déconne !\n$@c{smile_ehalf}Mais en vrai, ta maison te manque pas ? Ou… Moi ?\nJ… Je veux dire… Tu me manques vraiment beaucoup.\n$@c{smile_eclosed}Je te soutiendrai toujours dans tes ambitions, mais la vérité est que tu finiras par perdre un jour ou l’autre.\n$@c{smile}Quand ça arrivera, je serai là pour toi, comme toujours.\n@c{angry_mopen}Maintenant, montre-moi à quel point t’es devenu fort !" + "1": "@c{smile_wave}Ça fait une éternité ! Toujours debout hein ?\n@c{angry}Tu commences à me pousser à bout là. @c{smile_wave_wink}T’inquiètes j’déconne !\n$@c{smile_ehalf}Mais en vrai, ta maison te manque pas ? Ou… Moi ?\nJ… Je veux dire… Tu me manques vraiment beaucoup.\n$@c{smile_eclosed}Je te soutiendrai toujours dans tes ambitions, mais la vérité est que tu finiras par perdre un jour ou l’autre.\n$@c{smile}Quand ça arrivera, je serai là pour toi, comme toujours.\n@c{angry_mopen}Maintenant, montre-moi à quel point t’es devenu fort !" }, "victory": { - "1": "@c{shock}Après tout ça… Ça te suffit toujours pas… ?\nTu reviendras jamais à ce rythme…" + "1": "@c{shock}Après tout ça… Ça te suffit toujours pas… ?\nTu reviendras jamais à ce rythme…" }, "defeat": { "1": "T’as fait de ton mieux.\nAllez, rentrons à la maison." @@ -652,15 +652,15 @@ "1": "@c{neutral}Hé.\n$Je vais pas y aller par quatre chemins avec toi.\n@c{neutral_eclosed}Je suis là pour gagner. Simple, basique.\n$@c{serious_mhalf_fists}J’ai appris à maximiser tout mon potentiel en m’entrainant d’arrachepied.\n$@c{smile}C’est fou tout le temps que tu peux te dégager si tu dors pas en sacrifiant ta vie sociale.\n$@c{serious_mopen_fists}Plus rien n’a d’importance désormais, pas tant que j’aurai pas gagné.\n$@c{neutral_eclosed}J’ai atteint un stade où je ne peux plus perdre.\n@c{smile_eclosed}Je présume que ta philosophie était pas si fausse finalement.\n$@c{angry_mhalf}La défaite, c’est pour les faibles, et je ne suis plus un faible.\n$@c{serious_mopen_fists}Tiens-toi prête." }, "victory": { - "1": "@c{neutral}Que…@d{64} Qui es-tu ?" + "1": "@c{neutral}Que…@d{64} Qui es-tu ?" } }, "rival_4_female": { "encounter": { - "1": "@c{neutral}C’est moi ! Tu m’as pas encore oubliée… n’est-ce pas ?\n$@c{smile}Tu devrais être fier d’être arrivé aussi loin. GG !\nMais c’est certainement pas la fin de ton aventure.\n$@c{smile_eclosed}T’as éveillé en moi quelque chose que j’ignorais.\nTout mon temps passe dans l’entrainement.\n$@c{smile_ehalf}Je dors et je mange à peine, je m’entraine juste tous les jours, et deviens de plus en plus forte.\n$@c{neutral}En vrai, Je… J’ai de la peine à me reconnaitre.\n$Mais maintenant, je suis au top de mes capacités.\nJe doute que tu sois de nouveau capable de me battre.\n$Et tu sais quoi ? Tout ça, c’est de ta faute.\n@c{smile_ehalf}Et j’ignore si je dois te remercier ou te haïr.\n$@c{angry_mopen}Tiens-toi prêt." + "1": "@c{neutral}C’est moi ! Tu m’as pas encore oubliée… n’est-ce pas ?\n$@c{smile}Tu devrais être fier d’être arrivé aussi loin. GG !\nMais c’est certainement pas la fin de ton aventure.\n$@c{smile_eclosed}T’as éveillé en moi quelque chose que j’ignorais.\nTout mon temps passe dans l’entrainement.\n$@c{smile_ehalf}Je dors et je mange à peine, je m’entraine juste tous les jours, et deviens de plus en plus forte.\n$@c{neutral}En vrai, Je… J’ai de la peine à me reconnaitre.\n$Mais maintenant, je suis au top de mes capacités.\nJe doute que tu sois de nouveau capable de me battre.\n$Et tu sais quoi ? Tout ça, c’est de ta faute.\n@c{smile_ehalf}Et j’ignore si je dois te remercier ou te haïr.\n$@c{angry_mopen}Tiens-toi prêt." }, "victory": { - "1": "@c{neutral}Que…@d{64} Qui es-tu ?" + "1": "@c{neutral}Que…@d{64} Qui es-tu ?" }, "defeat": { "1": "$@c{smile}Tu devrais être fier d’être arrivé jusque là." @@ -687,7 +687,7 @@ }, "rival_6": { "encounter": { - "1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}J’ai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}C’est même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}J’ignore si je serai capable de l’accomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il m’a l’air familier, comme si j’y avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et c’est comme si quelque chose ici me parlait.\n$Comme si c’était tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus qu’un lointain souvenir.\n$@c{neutral_eclosed}D’ailleurs, qui peut dire aujourd’hui qu’ils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu t’arrêtes, ça n’aura jamais de fin et t’es la seule à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que c’est la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu n’as aucune chance." + "1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}J’ai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}C’est même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}J’ignore si je serai capable de l’accomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il m’a l’air familier, comme si j’y avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et c’est comme si quelque chose ici me parlait.\n$Comme si c’était tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus qu’un lointain souvenir.\n$@c{neutral_eclosed}D’ailleurs, qui peut dire aujourd’hui qu’ils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu t’arrêtes, ça n’aura jamais de fin et t’es la seule à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que c’est la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu n’as aucune chance." }, "victory": { "1": "@c{smile_eclosed}J’ai fait ce que j’avais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison." @@ -695,7 +695,7 @@ }, "rival_6_female": { "encounter": { - "1": "@c{smile_ehalf}C’est donc encore entre toi et moi.\n$@c{smile_eclosed}Tu sais, j’ai beau retouner ça dans tous les sens…\n$@c{smile_ehalf}Quelque chose peut expliquer tout ça, pourquoi tout semble si étrange…\n$@c{smile}T’as tes rêves, j’ai mes ambitions…\n$J’ai juste le sentiment qu’il y a un grand dessein derrière tout ça, derrière ce qu’on fait toi et moi.\n$@c{smile_eclosed}Je crois que mon but est de… repousser tes limites.\n$@c{smile_ehalf}Je suis pas certaine de bien être douée à cet exercice, mais je fais de mon mieux.\n$Cet endroit épouvantable cache quelque chose d’étrange… Tout semble si limpide…\n$Comme… si c’était tout ce que ce monde avait toujours connu.\n$@c{smile_eclosed}J’ai le sentiment que nos précieux moments ensemble sont devenus si flous.\n$@c{smile_ehalf}Ont-ils au moins été réels ? Tout semble si loin maintenant…\n$@c{angry_mopen}Il faut que tu persévères. Si tu t’arrêtes, ça n’aura jamais de fin et t’es le seul à en être capable.\n$@c{smile_ehalf}Je… j’ignore le sens de tout ça… Mais je sais que c’est la réalité.\n$@c{neutral}Si tu ne parviens pas à me battre ici et maintenant, tu n’as aucune chance." + "1": "@c{smile_ehalf}C’est donc encore entre toi et moi.\n$@c{smile_eclosed}Tu sais, j’ai beau retouner ça dans tous les sens…\n$@c{smile_ehalf}Quelque chose peut expliquer tout ça, pourquoi tout semble si étrange…\n$@c{smile}T’as tes rêves, j’ai mes ambitions…\n$J’ai juste le sentiment qu’il y a un grand dessein derrière tout ça, derrière ce qu’on fait toi et moi.\n$@c{smile_eclosed}Je crois que mon but est de… repousser tes limites.\n$@c{smile_ehalf}Je suis pas certaine de bien être douée à cet exercice, mais je fais de mon mieux.\n$Cet endroit épouvantable cache quelque chose d’étrange… Tout semble si limpide…\n$Comme… si c’était tout ce que ce monde avait toujours connu.\n$@c{smile_eclosed}J’ai le sentiment que nos précieux moments ensemble sont devenus si flous.\n$@c{smile_ehalf}Ont-ils au moins été réels ? Tout semble si loin maintenant…\n$@c{angry_mopen}Il faut que tu persévères. Si tu t’arrêtes, ça n’aura jamais de fin et t’es le seul à en être capable.\n$@c{smile_ehalf}Je… j’ignore le sens de tout ça… Mais je sais que c’est la réalité.\n$@c{neutral}Si tu ne parviens pas à me battre ici et maintenant, tu n’as aucune chance." }, "victory": { "1": "@c{smile_ehalf}Je… Je crois que j’ai rempli ma mission…\n$@c{smile_eclosed}Promets-moi… Après avoir réparé ce monde… Reviens à la maison sain et sauf.\n$@c{smile_ehalf}… Merci." diff --git a/src/locales/fr/egg.json b/src/locales/fr/egg.json index cbc912e9d50..64f22aa330d 100644 --- a/src/locales/fr/egg.json +++ b/src/locales/fr/egg.json @@ -4,7 +4,7 @@ "ultraTier": "Épique", "masterTier": "Légendaire", "defaultTier": "Commun", - "hatchWavesMessageSoon": "Il fait du bruit.\nIl va éclore !", + "hatchWavesMessageSoon": "Il fait du bruit. Il va éclore !", "hatchWavesMessageClose": "Il bouge de temps en temps. Il devrait bientôt éclore.", "hatchWavesMessageNotClose": "Qu’est-ce qui va en sortir ? Ça va mettre du temps.", "hatchWavesMessageLongTime": "Cet Œuf va surement mettre du temps à éclore.", @@ -16,7 +16,7 @@ "tooManyEggs": "Vous avez trop d’Œufs !", "pull": "Tirage", "pulls": "Tirages", - "sameSpeciesEgg": "Un {{species}} sortira de cet Œuf !", + "sameSpeciesEgg": "{{species}} sortira de cet Œuf !", "hatchFromTheEgg": "{{pokemonName}} sort de l’Œuf !", "eggMoveUnlock": "Capacité Œuf débloquée :\n{{moveName}}", "rareEggMoveUnlock": "Capacité Œuf Rare débloquée :\n{{moveName}}", diff --git a/src/locales/fr/menu.json b/src/locales/fr/menu.json index 277b0f5fd04..83626a1f33f 100644 --- a/src/locales/fr/menu.json +++ b/src/locales/fr/menu.json @@ -6,7 +6,7 @@ "newGame": "Nouvelle partie", "settings": "Paramètres", "selectGameMode": "Sélectionnez un mode de jeu.", - "logInOrCreateAccount": "Connectez-vous ou créez un compte pour commencer.\nAucun e-mail requis !", + "logInOrCreateAccount": "Connectez-vous ou créez un compte pour commencer. Aucun e-mail requis !", "username": "Nom d’utilisateur", "password": "Mot de passe", "login": "Connexion", @@ -19,29 +19,29 @@ "invalidRegisterPassword": "Le mot de passe doit contenir 6 caractères ou plus", "usernameAlreadyUsed": "Le nom d’utilisateur est déjà utilisé", "accountNonExistent": "Le nom d’utilisateur n’existe pas", - "unmatchingPassword": "Le mot de passe est incorrect", + "unmatchingPassword": "Le mot de passe n’est pas correct", "passwordNotMatchingConfirmPassword": "Les mots de passe ne correspondent pas", "confirmPassword": "Confirmer le MDP", - "registrationAgeWarning": "En vous inscrivant, vous certifiez que vous avez 13 ans ou plus.", + "registrationAgeWarning": "Vous confirmez en vous inscrivant que vous avez 13 ans ou plus.", "backToLogin": "Retour", "failedToLoadSaveData": "Échec du chargement des données. Veuillez recharger\nla page. Si cela persiste, contactez l’administrateur.", "sessionSuccess": "Session chargée avec succès.", "failedToLoadSession": "Vos données de session n’ont pas pu être chargées.\nElles pourraient être corrompues.", - "boyOrGirl": "Es-tu un garçon ou une fille ?", + "boyOrGirl": "Es-tu un garçon ou une fille ?", "evolving": "Quoi ?\n{{pokemonName}} évolue !", - "stoppedEvolving": "Hein ?\n{{pokemonName}} n’évolue plus !", - "pauseEvolutionsQuestion": "Interrompre les évolutions pour {{pokemonName}} ?\nElles peuvent être réactivées depuis l’écran d’équipe.", - "evolutionsPaused": "Les évolutions de {{pokemonName}}\nsont interrompues.", + "stoppedEvolving": "Hein ?\n{{pokemonName}} n’évolue plus !", + "pauseEvolutionsQuestion": "Mettre en pause les évolutions pour {{pokemonName}} ?\nElles peuvent être réactivées depuis l’écran d’équipe.", + "evolutionsPaused": "Les évolutions ont été mises en pause pour {{pokemonName}}.", "evolutionDone": "Félicitations !\n{{pokemonName}} a évolué en {{evolvedPokemonName}} !", - "dailyRankings": "Classement du jour", - "weeklyRankings": "Classement de la semaine", - "noRankings": "Pas de classement", + "dailyRankings": "Classement du Jour", + "weeklyRankings": "Classement de la Semaine", + "noRankings": "Pas de Classement", "positionIcon": "#", "usernameScoreboard": "Utilisateur", "score": "Score", "wave": "Vague", "loading": "Chargement…", - "loadingAsset": "Chargement des ressources : {{assetName}}", + "loadingAsset": "Chargement de la ressource : {{assetName}}", "playersOnline": "Joueurs connectés", "yes": "Oui", "no": "Non", @@ -51,7 +51,5 @@ "renamePokemon": "Renommer le Pokémon", "rename": "Renommer", "nickname": "Surnom", - "errorServerDown": "Oupsi ! Un problème de connexion au serveur est survenu.\n\nVous pouvez garder cette fenêtre ouverte,\nle jeu se reconnectera automatiquement.", - "noSaves": "Vous n’avez aucune sauvegarde enregistrée !", - "tooManySaves": "Vous avez trop de sauvegardes enregistrées !" + "errorServerDown": "Oupsi ! Un problème de connexion au serveur est survenu.\n\nVous pouvez garder cette fenêtre ouverte,\nle jeu se reconnectera automatiquement." } diff --git a/src/locales/fr/modifier-type.json b/src/locales/fr/modifier-type.json index 78be62cd88f..509a8b11112 100644 --- a/src/locales/fr/modifier-type.json +++ b/src/locales/fr/modifier-type.json @@ -2,7 +2,7 @@ "ModifierType": { "AddPokeballModifierType": { "name": "{{pokeballName}} x{{modifierCount}}", - "description": "Recevez {{modifierCount}} {{pokeballName}}·s. (Inventaire : {{pokeballAmount}})\nTaux de capture : {{catchRate}}" + "description": "Recevez {{modifierCount}} {{pokeballName}}·s. (Inventaire : {{pokeballAmount}})\nTaux de capture : {{catchRate}}" }, "AddVoucherModifierType": { "name": "{{voucherTypeName}} x{{modifierCount}}", @@ -10,8 +10,8 @@ }, "PokemonHeldItemModifierType": { "extra": { - "inoperable": "{{pokemonName}} ne peut pas\nporter cet objet !", - "tooMany": "{{pokemonName}} porte trop\nd’exemplaires de cet objet !" + "inoperable": "{{pokemonName}} ne peut pas\nporter cet objet !", + "tooMany": "{{pokemonName}} porte trop\nd’exemplaires de cet objet !" } }, "PokemonHpRestoreModifierType": { @@ -47,14 +47,10 @@ "description": "Donne la nature {{natureName}} à un Pokémon et la débloque pour le starter lui étant lié." }, "DoubleBattleChanceBoosterModifierType": { - "description": "Quadruple les chances de tomber sur un combat double pendant {{battleCount}} combats." + "description": "Double les chances de tomber sur un combat double pendant {{battleCount}} combats." }, "TempStatStageBoosterModifierType": { - "description": "Augmente {{amount}} {{stat}} de toute l’équipe pendant 5 combats.", - "extra": { - "stage": "d’un cran", - "percentage": "de 30%" - } + "description": "Augmente d’un cran {{stat}} pour toute l’équipe pendant 5 combats." }, "AttackTypeBoosterModifierType": { "description": "Augmente de 20% la puissance des capacités de type {{moveType}} d’un Pokémon." @@ -89,7 +85,7 @@ "description": "Augmente de {{boostPercent}}% le gain de Points d’Exp du porteur." }, "PokemonFriendshipBoosterModifierType": { - "description": "Augmente le gain de bonheur de 50% par victoire." + "description": "Augmente le gain d’amitié de 50% par victoire." }, "PokemonMoveAccuracyBoosterModifierType": { "description": "Augmente de {{accuracyAmount}} la précision des capacités (maximum 100)." @@ -106,17 +102,17 @@ "description": "Apprend la capacité {{moveName}} à un Pokémon.\n(Maintenez C ou Maj pour plus d’infos)" }, "EvolutionItemModifierType": { - "description": "Permet à certains Pokémon d’évoluer à son contact." + "description": "Permet à certains Pokémon d’évoluer." }, "FormChangeItemModifierType": { - "description": "Permet à certains Pokémon de changer de forme à son contact." + "description": "Permet à certains Pokémon de changer de forme." }, "FusePokemonModifierType": { "description": "Fusionne deux Pokémon (transfère le talent, sépare les stats de base et les types, partage les capacités)." }, "TerastallizeModifierType": { "name": "Téra-Éclat {{teraType}}", - "description": "Téracristallise son porteur en type {{teraType}} pendant 10 combats." + "description": "{{teraType}} Téracristallise son porteur pendant 10 combats." }, "ContactHeldItemTransferChanceModifierType": { "description": "{{chancePercent}}% de chances de voler un objet de l’adversaire en l’attaquant." @@ -251,7 +247,7 @@ }, "SpeciesBoosterItem": { "LIGHT_BALL": { "name": "Balle Lumière", "description": "À faire tenir à Pikachu. Un orbe énigmatique qui double son Attaque et son Atq. Spé. ." }, - "THICK_CLUB": { "name": "Masse Os", "description": "À faire tenir à Osselait ou à Ossatueur, formes d’Alola incluses. Un os dur qui double leur Attaque." }, + "THICK_CLUB": { "name": "Masse Os", "description": "À faire tenir à Osselait ou Ossatueur. Un os dur qui double leur Attaque." }, "METAL_POWDER": { "name": "Poudre Métal", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Défense." }, "QUICK_POWDER": { "name": "Poudre Vite", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Vitesse." } }, diff --git a/src/locales/fr/modifier.json b/src/locales/fr/modifier.json index 101b1d56164..0ec228a22c2 100644 --- a/src/locales/fr/modifier.json +++ b/src/locales/fr/modifier.json @@ -3,7 +3,7 @@ "turnHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par les {{typeName}} !", "hitHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par le {{typeName}} !", "pokemonInstantReviveApply": "{{pokemonNameWithAffix}} a repris connaissance\navec sa {{typeName}} et est prêt à se battre de nouveau !", - "resetNegativeStatStageApply": "Les stats baissées de {{pokemonNameWithAffix}}\nsont restaurées par l’{{typeName}} !", + "resetNegativeStatStageApply": "Les stats baissées de {{pokemonNameWithAffix}}\nsont restaurées par l’{{typeName}} !", "moneyInterestApply": "La {{typeName}} vous rapporte\n{{moneyAmount}} ₽ d’intérêts !", "turnHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est absorbé·e\npar le {{typeName}} de {{pokemonName}} !", "contactHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est volé·e\npar l’{{typeName}} de {{pokemonName}} !", diff --git a/src/locales/fr/move-trigger.json b/src/locales/fr/move-trigger.json index d9d800c52cc..b9bc929c619 100644 --- a/src/locales/fr/move-trigger.json +++ b/src/locales/fr/move-trigger.json @@ -3,10 +3,10 @@ "cutHpPowerUpMove": "{{pokemonName}} sacrifie des PV\net augmente la puissance ses capacités !", "absorbedElectricity": "{{pokemonName}} absorbe de l’électricité !", "switchedStatChanges": "{{pokemonName}} permute\nles changements de stats avec ceux de sa cible !", - "switchedTwoStatChanges": "{{pokemonName}} permute les changements de {{firstStat} et de {{secondStat}} avec ceux de sa cible !", - "switchedStat": "{{pokemonName}} et sa cible échangent leur {{stat}} !", - "sharedGuard": "{{pokemonName}} additionne sa garde à celle de sa cible et redistribue le tout équitablement !", - "sharedPower": "{{pokemonName}} additionne sa force à celle de sa cible et redistribue le tout équitablement !", + "switchedTwoStatChanges": "{{pokemonName}} permute les changements de {{firstStat} et de {{secondStat}} avec ceux de sa cible !", + "switchedStat": "{{pokemonName}} et sa cible échangent leur {{stat}} !", + "sharedGuard": "{{pokemonName}} additionne sa garde à celle de sa cible et redistribue le tout équitablement !", + "sharedPower": "{{pokemonName}} additionne sa force à celle de sa cible et redistribue le tout équitablement !", "goingAllOutForAttack": "{{pokemonName}} a pris\ncette capacité au sérieux !", "regainedHealth": "{{pokemonName}}\nrécupère des PV !", "keptGoingAndCrashed": "{{pokemonName}}\ns’écrase au sol !", @@ -22,7 +22,7 @@ "loweredItsHead": "{{pokemonName}}\nbaisse la tête !", "isGlowing": "{{pokemonName}} est entouré\nd’une lumière intense !", "bellChimed": "Un grelot sonne !", - "foresawAnAttack": "{{pokemonName}}\nprévoit une attaque !", + "foresawAnAttack": "{{pokemonName}}\nprévoit une attaque !", "isTighteningFocus": "{{pokemonName}} se concentre\nau maximum !", "hidUnderwater": "{{pokemonName}}\nse cache sous l’eau !", "soothingAromaWaftedThroughArea": "Une odeur apaisante flotte dans l’air !", @@ -34,7 +34,7 @@ "becameCloakedInFreezingAir": "{{pokemonName}} est entouré\nd’un air glacial !", "isChargingPower": "{{pokemonName}}\nconcentre son énergie !", "burnedItselfOut": "Le feu intérieur de {{pokemonName}}\ns’est entièrement consumé !", - "startedHeatingUpBeak": "{{pokemonName}}\nfait chauffer son bec !", + "startedHeatingUpBeak": "{{pokemonName}}\nfait chauffer son bec !", "setUpShellTrap": "{{pokemonName}} déclenche\nle Carapiège !", "isOverflowingWithSpacePower": "La puissance du cosmos afflue dans le corps\nde {{pokemonName}} !", "usedUpAllElectricity": "{{pokemonName}}a utilisé\ntoute son électricité !", @@ -66,5 +66,5 @@ "revivalBlessing": "{{pokemonName}} a repris connaissance\net est prêt à se battre de nouveau !", "swapArenaTags": "Les effets affectant chaque côté du terrain\nont été échangés par {{pokemonName}} !", "exposedMove": "{{targetPokemonName}} est identifié\npar {{pokemonName}} !", - "safeguard": "{{targetName}} est protégé\npar la capacité Rune Protect !" -} + "safeguard": "{{targetName}} est protégé\npar la capacité Rune Protect !" +} \ No newline at end of file diff --git a/src/locales/fr/pokemon-info-container.json b/src/locales/fr/pokemon-info-container.json index 084310f7c94..46b5b80bab0 100644 --- a/src/locales/fr/pokemon-info-container.json +++ b/src/locales/fr/pokemon-info-container.json @@ -1,7 +1,7 @@ { "moveset": "Capacités", - "gender": "Sexe :", - "ability": "Talent :", - "nature": "Nature :", + "gender": "Sexe :", + "ability": "Talent :", + "nature": "Nature :", "form": "Forme :" -} +} \ No newline at end of file diff --git a/src/locales/fr/pokemon-info.json b/src/locales/fr/pokemon-info.json index a23b320ea3e..1160ec95b75 100644 --- a/src/locales/fr/pokemon-info.json +++ b/src/locales/fr/pokemon-info.json @@ -6,9 +6,9 @@ "ATKshortened": "Atq", "DEF": "Défense", "DEFshortened": "Déf", - "SPATK": "Atq. Spé.", + "SPATK": "Atq. Spé.", "SPATKshortened": "AtqSp", - "SPDEF": "Déf. Spé.", + "SPDEF": "Déf. Spé.", "SPDEFshortened": "DéfSp", "SPD": "Vitesse", "SPDshortened": "Vit", diff --git a/src/locales/fr/splash-messages.json b/src/locales/fr/splash-messages.json index 9dd3e86fb32..499a32d2cbd 100644 --- a/src/locales/fr/splash-messages.json +++ b/src/locales/fr/splash-messages.json @@ -1,36 +1,36 @@ { - "battlesWon": "combats gagnés !", - "joinTheDiscord": "Rejoins le Discord !", - "infiniteLevels": "Niveaux infinis !", - "everythingStacks": "Tout se cumule !", - "optionalSaveScumming": "Optional Save Scumming !", - "biomes": "35 biomes !", - "openSource": "Open Source !", - "playWithSpeed": "Joue en vitesse x5 !", - "liveBugTesting": "Tests de bugs en direct !", - "heavyInfluence": "Grosse influence de RoR2 !", - "pokemonRiskAndPokemonRain": "Pokémon Risk et Pokémon Rain !", - "nowWithMoreSalt": "Désormais avec 33% de sel en plus !", - "infiniteFusionAtHome": "Infinite Fusion, chez vous !", - "brokenEggMoves": "Des Capacités Œuf craquées !", - "magnificent": "Magnifique !", - "mubstitute": "Mubstitute !", - "thatsCrazy": "C’est une dinguerie !", - "oranceJuice": "Jus d’orange !", - "questionableBalancing": "Équilibrage douteux !", - "coolShaders": "Cool shaders !", - "aiFree": "Garanti sans IA !", - "suddenDifficultySpikes": "De soudains pics de difficultés !", - "basedOnAnUnfinishedFlashGame": "Basé sur un jeu Flash abandonné !", - "moreAddictiveThanIntended": "Plus addictif que prévu !", - "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 !", - "alsoTryPokengine": "Essaye aussi Pokéngine !", + "battlesWon": "combats gagnés !", + "joinTheDiscord": "Rejoins le Discord !", + "infiniteLevels": "Niveaux infinis !", + "everythingStacks": "Tout se cumule !", + "optionalSaveScumming": "Optional Save Scumming!", + "biomes": "35 biomes !", + "openSource": "Open Source !", + "playWithSpeed": "Joue en vitesse x5 !", + "liveBugTesting": "Tests de bugs en direct !", + "heavyInfluence": "Grosse influence de RoR2 !", + "pokemonRiskAndPokemonRain": "Pokémon Risk et Pokémon Rain !", + "nowWithMoreSalt": "Désormais avec 33% de sel en plus !", + "infiniteFusionAtHome": "Infinite Fusion, chez vous !", + "brokenEggMoves": "Des Capacités Œuf craquées !", + "magnificent": "Magnifique !", + "mubstitute": "Mubstitute !", + "thatsCrazy": "C’est une dinguerie !", + "oranceJuice": "Jus d’orange !", + "questionableBalancing": "Équilibrage douteux !", + "coolShaders": "Cool shaders !", + "aiFree": "Garanti sans IA !", + "suddenDifficultySpikes": "De soudains pics de difficultés !", + "basedOnAnUnfinishedFlashGame": "Basé sur un jeu Flash abandonné !", + "moreAddictiveThanIntended": "Plus addictif que prévu !", + "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 !", + "alsoTryPokengine": "Essaye aussi Pokéngine !", "alsoTryEmeraldRogue": "Essaye aussi Emerald Rogue!", - "alsoTryRadicalRed": "Essaye aussi Radical Red !", - "eeveeExpo": "Eevee Expo !", - "ynoproject": "YNOproject !", + "alsoTryRadicalRed": "Essaye aussi Radical Red !", + "eeveeExpo": "Eevee Expo !", + "ynoproject": "YNOproject !", "breedersInSpace": "Des Éleveurs dans l’espace !" -} +} \ No newline at end of file diff --git a/src/locales/fr/status-effect.json b/src/locales/fr/status-effect.json index bfb7121f522..4a58f804906 100644 --- a/src/locales/fr/status-effect.json +++ b/src/locales/fr/status-effect.json @@ -33,7 +33,7 @@ "obtainSource": "{{pokemonNameWithAffix}} est paralysé\npar {{sourceText}} ! Il aura du mal à attaquer !", "activation": "{{pokemonNameWithAffix}} est paralysé !\nIl n’a pas pu attaquer !", "overlap": "{{pokemonNameWithAffix}} est\ndéjà paralysé.", - "heal": "{{pokemonNameWithAffix}} n’est\nplus paralysé !" + "heal": "{{pokemonNameWithAffix}} n’est\nplus paralysé !" }, "sleep": { "name": "Sommeil", @@ -62,4 +62,4 @@ "overlap": "{{pokemonNameWithAffix}} est\ndéjà brulé.", "heal": "{{pokemonNameWithAffix}} n’est\nplus brulé !" } -} +} \ No newline at end of file diff --git a/src/locales/fr/tutorial.json b/src/locales/fr/tutorial.json index f15a7c7c6d4..53ec05c7d81 100644 --- a/src/locales/fr/tutorial.json +++ b/src/locales/fr/tutorial.json @@ -1,10 +1,10 @@ { - "intro": "Bienvenue dans PokéRogue, un fangame axé sur les combats Pokémon avec des éléments roguelite !\n$Ce jeu n’est pas monétisé et nous ne prétendons à la propriété d’aucun élément sous copyright utilisé.\n$Bien qu’en développement permanent, PokéRogue reste entièrement jouable.\n$Tout signalement de bugs et d’erreurs quelconques passe par le serveur Discord.\n$Si le jeu est lent, vérifiez que l’Accélération Matérielle est activée dans les paramètres du navigateur.", - "accessMenu": "Accédez au menu avec M ou Échap lors de l’attente d’une\naction.\n$Il contient les paramètres et diverses fonctionnalités.", - "menu": "Vous pouvez accéder aux paramètres depuis ce menu.\n$Vous pouvez entre autres y changer la vitesse du jeu ou le style de fenêtre…\n$Mais également des tonnes d’autres fonctionnalités, jetez-y un œil !", - "starterSelect": "Choisissez vos starters depuis cet écran avec Z ou Espace.\nIls formeront votre équipe de départ.\n$Chacun possède une valeur. Votre équipe peut avoir jusqu’à 6 membres, sans dépasser un cout de 10.\n$Vous pouvez aussi choisir le sexe, le talent et la forme en\nfonction des variants déjà capturés ou éclos.\n$Les IV d’un starter sont les meilleurs de tous ceux de son espèce déjà possédés. Obtenez-en plusieurs !", - "pokerus": "Chaque jour, 3 starters tirés aléatoirement ont un contour violet.\n$Si un starter que vous possédez l’a, essayez de l’ajouter à votre équipe. Vérifiez bien son résumé !", - "statChange": "Les changements de stats persistent à travers les combats tant que le Pokémon n’est pas rappelé.\n$Vos Pokémon sont rappelés avant un combat de Dresseur et avant d’entrer dans un nouveau biome.\n$Vous pouvez voir en combat les changements de stats d’un Pokémon en maintenant C ou Maj.\n$Vous pouvez également voir les capacités de l’adversaire en maintenant V.\n$Seules les capacités que le Pokémon a utilisées dans ce combat sont consultables.", - "selectItem": "Après chaque combat, vous avez le choix entre 3 objets\ntirés au sort. Vous ne pouvez en prendre qu’un.\n$Cela peut être des objets consommables, des objets à\nfaire tenir, ou des objets passifs aux effets permanents.\n$La plupart des effets des objets non-consommables se cumuleront de diverses manières.\n$Certains objets n’apparaitront que s’ils ont une utilité immédiate, comme les objets d’évolution.\n$Vous pouvez aussi transférer des objets tenus entre Pokémon en utilisant l’option de transfert.\n$L’option de transfert apparait en bas à droite dès qu’un Pokémon de l’équipe porte un objet.\n$Vous pouvez acheter des consommables avec de l’argent.\nPlus vous progressez, plus le choix sera large.\n$Choisir un des objets gratuits déclenchera le prochain combat, donc faites bien tous vos achats avant.", - "eggGacha": "Depuis cet écran, vous pouvez utiliser vos coupons\npour recevoir Œufs de Pokémon au hasard.\n$Les Œufs éclosent après avoir remporté un certain nombre de combats. Plus ils sont rares, plus ils mettent de temps.\n$Les Pokémon éclos ne rejoindront pas votre équipe, mais seront ajoutés à vos starters.\n$Les Pokémon issus d’Œufs ont généralement de meilleurs IV que les Pokémon sauvages.\n$Certains Pokémon ne peuvent être obtenus que dans des Œufs.\n$Il y a 3 différentes machines à actionner avec différents\nbonus, prenez celle qui vous convient le mieux !" -} + "intro": "Bienvenue dans PokéRogue, un fangame axé sur les combats Pokémon avec des éléments roguelite !\n$Ce jeu n’est pas monétisé et nous ne prétendons pas à la propriété de Pokémon, ni des éléments sous copyright\n$utilisés.\n$Ce jeu est toujours en développement, mais entièrement jouable.\n$Tout signalement de bugs passe par le serveur Discord.\n$Si le jeu est lent, vérifiez que l’Accélération Matérielle est activée dans les paramètres du navigateur.", + "accessMenu": "Accédez au menu avec M ou Échap lors de l’attente d’une\naction.\n$Il contient les paramètres et diverses fonctionnalités", + "menu": "Vous pouvez accéder aux paramètres depuis ce menu.\n$Vous pouvez entre autres y changer la vitesse du jeu ou le style de fenêtre.\n$Il y a également toute une variété d’autres fonctionnalités,\n$jetez-y un œil !", + "starterSelect": "Choisissez vos starters depuis cet écran avec Z ou Espace.\nIls formeront votre équipe de départ.\n$Chacun possède une valeur. Votre équipe peut avoir jusqu’à\n6 membres, tant que vous ne dépassez pas un cout de 10.\n$Vous pouvez aussi choisir le sexe, le talent et la forme en\nfonction des variants déjà capturés ou éclos.\n$Les IVs d’un starter sont les meilleurs de tous ceux de son\nespèce déjà obtenus. Essayez donc d’en obtenir plusieurs !", + "pokerus": "Chaque jour, 3 starters tirés aléatoirement ont un contour\n$violet. Si un starter que vous possédez l’a, essayez de\n$l’ajouter à votre équipe. Vérifiez bien son résumé !", + "statChange": "Les changements de stats restent à travers les combats tant que le Pokémon n’est pas rappelé.\n$Vos Pokémon sont rappelés avant un combat de Dresseur et avant d’entrer dans un nouveau biome.\n$Vous pouvez voir en combat les changements de stats d’un Pokémon en maintenant C ou Maj.\n$Vous pouvez également voir les capacités de l’adversaire en maintenant V.\n$Seules les capacités que le Pokémon a utilisées dans ce combat sont consultables.", + "selectItem": "Après chaque combat, vous avez le choix entre 3 objets\ntirés au sort. Vous ne pouvez en prendre qu’un.\n$Cela peut être des objets consommables, des objets à\nfaire tenir, ou des objets passifs aux effets permanents.\n$La plupart des effets des objets non-consommables se cumuleront de diverses manières.\n$Certains objets apparaitront s’ils peuvent être utilisés, comme les objets d’évolution.\n$Vous pouvez aussi transférer des objets tenus entre Pokémon en utilisant l’option de transfert.\n$L’option de transfert apparait en bas à droite dès que vous avez obtenu un objet à faire tenir.\n$Vous pouvez acheter des consommables avec de l’argent.\nPlus vous progressez, plus le choix sera varié.\n$Choisir un des objets gratuits déclenchera le prochain combat, donc faites bien tous vos achats avant.", + "eggGacha": "Depuis cet écran, vous pouvez échanger vos coupons\ncontre des Œufs de Pokémon.\n$Les Œufs éclosent après avoir remporté un certain nombre\nde combats. Les plus rares mettent plus de temps.\n$Les Pokémon éclos ne rejoindront pas votre équipe,\nmais seront ajoutés à vos starters.\n$Les Pokémon issus d’Œufs ont généralement de\nmeilleurs IVs que les Pokémon sauvages.\n$Certains Pokémon ne peuvent être obtenus\nque dans des Œufs.\n$Il y a 3 différentes machines à actionner avec différents\nbonus, prenez celle qui vous convient le mieux !" +} \ No newline at end of file diff --git a/src/locales/fr/voucher.json b/src/locales/fr/voucher.json index ef6126b4435..5e26adfcc49 100644 --- a/src/locales/fr/voucher.json +++ b/src/locales/fr/voucher.json @@ -1,9 +1,9 @@ { "vouchers": "Coupons", - "eggVoucher": "Coupon Œuf", - "eggVoucherPlus": "Coupon Œuf +", - "eggVoucherPremium": "Coupon Œuf Premium", - "eggVoucherGold": "Coupon Œuf Or", + "eggVoucher": "Coupon Œuf", + "eggVoucherPlus": "Coupon Œuf +", + "eggVoucherPremium": "Coupon Œuf Premium", + "eggVoucherGold": "Coupon Œuf Or", "locked": "Verrouillé", "defeatTrainer": "Vaincre {{trainerName}}" -} +} \ No newline at end of file diff --git a/src/locales/fr/weather.json b/src/locales/fr/weather.json index 7afe538b064..7cd8a83fd09 100644 --- a/src/locales/fr/weather.json +++ b/src/locales/fr/weather.json @@ -1,32 +1,32 @@ { - "sunnyStartMessage": "Les rayons du soleil brillent !", - "sunnyLapseMessage": "Les rayons du soleil brillent fort !", - "sunnyClearMessage": "Les rayons du soleil s’affaiblissent !", - "rainStartMessage": "Il commence à pleuvoir !", - "rainLapseMessage": "La pluie continue de tomber !", - "rainClearMessage": "La pluie s’est arrêtée !", - "sandstormStartMessage": "Une tempête de sable se prépare !", - "sandstormLapseMessage": "La tempête de sable fait rage !", - "sandstormClearMessage": "La tempête de sable se calme !", - "sandstormDamageMessage": "La tempête de sable inflige des dégâts\nà {{pokemonNameWithAffix}} !", - "hailStartMessage": "Il commence à grêler !", - "hailLapseMessage": "La grêle continue de tomber !", - "hailClearMessage": "La grêle s’est arrêtée !", - "hailDamageMessage": "La grêle inflige des dégâts\nà {{pokemonNameWithAffix}} !", - "snowStartMessage": "Il commence à neiger !", - "snowLapseMessage": "Il y a une tempête de neige !", - "snowClearMessage": "La neige s’est arrêtée !", + "sunnyStartMessage": "Les rayons du soleil brillent !", + "sunnyLapseMessage": "Les rayons du soleil brillent fort !", + "sunnyClearMessage": "Les rayons du soleil s’affaiblissent !", + "rainStartMessage": "Il commence à pleuvoir !", + "rainLapseMessage": "La pluie continue de tomber !", + "rainClearMessage": "La pluie s’est arrêtée !", + "sandstormStartMessage": "Une tempête de sable se prépare !", + "sandstormLapseMessage": "La tempête de sable fait rage !", + "sandstormClearMessage": "La tempête de sable se calme !", + "sandstormDamageMessage": "La tempête de sable inflige des dégâts\nà {{pokemonNameWithAffix}} !", + "hailStartMessage": "Il commence à grêler !", + "hailLapseMessage": "La grêle continue de tomber !", + "hailClearMessage": "La grêle s’est arrêtée !", + "hailDamageMessage": "La grêle inflige des dégâts\nà {{pokemonNameWithAffix}} !", + "snowStartMessage": "Il commence à neiger !", + "snowLapseMessage": "Il y a une tempête de neige !", + "snowClearMessage": "La neige s’est arrêtée !", "fogStartMessage": "Le brouillard devient épais…", - "fogLapseMessage": "Le brouillard continue !", - "fogClearMessage": "Le brouillard s’est dissipé !", - "heavyRainStartMessage": "Une pluie battante s’abat soudainement !", + "fogLapseMessage": "Le brouillard continue !", + "fogClearMessage": "Le brouillard s’est dissipé !", + "heavyRainStartMessage": "Une pluie battante s’abat soudainement !", "heavyRainLapseMessage": "La pluie battante continue.", "heavyRainClearMessage": "La pluie battante s’est arrêtée…", - "harshSunStartMessage": "Les rayons du soleil s’intensifient !", - "harshSunLapseMessage": "Les rayons du soleil sont brulants !", - "harshSunClearMessage": "Les rayons du soleil s’affaiblissent !", - "strongWindsStartMessage": "Un vent mystérieux se lève !", - "strongWindsLapseMessage": "Le vent mystérieux souffle violemment !", - "strongWindsEffectMessage": "Le courant aérien mystérieux affaiblit l’attaque !", + "harshSunStartMessage": "Les rayons du soleil s’intensifient !", + "harshSunLapseMessage": "Les rayons du soleil sont brulants !", + "harshSunClearMessage": "Les rayons du soleil s’affaiblissent !", + "strongWindsStartMessage": "Un vent mystérieux se lève !", + "strongWindsLapseMessage": "Le vent mystérieux souffle violemment !", + "strongWindsEffectMessage": "Le courant aérien mystérieux affaiblit l’attaque !", "strongWindsClearMessage": "Le vent mystérieux s’est dissipé…" -} +} \ No newline at end of file diff --git a/src/locales/it/ability-trigger.json b/src/locales/it/ability-trigger.json index 333cb5719d8..7f55b289c0b 100644 --- a/src/locales/it/ability-trigger.json +++ b/src/locales/it/ability-trigger.json @@ -11,7 +11,6 @@ "blockItemTheft": "{{abilityName}} di {{pokemonNameWithAffix}}\nlo rende immune ai furti!", "typeImmunityHeal": "{{pokemonName}} recupera alcuni PS\ncon {{abilityName}}!", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} evita il colpo\ncon {{abilityName}}!", - "fullHpResistType": "{{pokemonNameWithAffix}} fa risplendere la sua corazza\ne altera i rapporti tra i tipi!", "disguiseAvoidedDamage": "{{pokemonNameWithAffix}} è stato smascherato!", "moveImmunity": "Non ha effetto su {{pokemonNameWithAffix}}!", "reverseDrain": "{{pokemonNameWithAffix}} ha assorbito la melma!", @@ -52,7 +51,6 @@ "postSummonTeravolt": "{{pokemonNameWithAffix}} emana un’aura repulsiva!", "postSummonDarkAura": "L’abilità Auratetra di {{pokemonNameWithAffix}} è attiva.", "postSummonFairyAura": "L’abilità Aurafolletto di {{pokemonNameWithAffix}} è attiva.", - "postSummonAuraBreak": "{{pokemonNameWithAffix}} inverte gli effetti di tutte le aure!", "postSummonNeutralizingGas": "Il Gas Reagente di {{pokemonNameWithAffix}}\nsi diffonde tutt’intorno!", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} ha due abilità!", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} ha due abilità!", @@ -61,4 +59,4 @@ "postSummonTabletsOfRuin": "La/l'{{statName}} dei Pokémon intorno si indebolisce a causa\ndell'abilità Amuleto Nefasto di {{pokemonNameWithAffix}}!", "postSummonBeadsOfRuin": "La/l'{{statName}} dei Pokémon intorno si indebolisce a causa\ndell'abilità Monile Nefasto di {{pokemonNameWithAffix}}!", "preventBerryUse": "{{pokemonNameWithAffix}} non riesce a\nmangiare le bacche per l'agitazione!" -} +} \ No newline at end of file diff --git a/src/locales/it/battle.json b/src/locales/it/battle.json index 9b187756025..f0339f761c7 100644 --- a/src/locales/it/battle.json +++ b/src/locales/it/battle.json @@ -44,7 +44,6 @@ "moveNotImplemented": "{{moveName}} non è ancora implementata e non può essere selezionata.", "moveNoPP": "Non ci sono PP rimanenti\nper questa mossa!", "moveDisabled": "{{moveName}} è disabilitata!", - "disableInterruptedMove": "La mossa {{moveName}} di\n{{pokemonNameWithAffix}} è bloccata!", "noPokeballForce": "Una forza misteriosa\nimpedisce l'uso delle Poké Ball.", "noPokeballTrainer": "Non puoi catturare\nPokémon di altri allenatori!", "noPokeballMulti": "Puoi lanciare una Poké Ball\nsolo quando rimane un singolo Pokémon!", @@ -96,4 +95,4 @@ "congratulations": "Congratulazioni!", "beatModeFirstTime": "{{speciesName}} ha completato la modalità {{gameMode}} per la prima volta!\nHai ricevuto {{newModifier}}!", "ppReduced": "I PP della mossa {{moveName}} di\n{{targetName}} sono stati ridotti di {{reduction}}!" -} +} \ No newline at end of file diff --git a/src/locales/it/battler-tags.json b/src/locales/it/battler-tags.json index e8bda9cfd1e..a0f852141f9 100644 --- a/src/locales/it/battler-tags.json +++ b/src/locales/it/battler-tags.json @@ -67,7 +67,5 @@ "saltCuredLapse": "{{pokemonNameWithAffix}} viene colpito da {{moveName}}!", "cursedOnAdd": "{{pokemonNameWithAffix}} ha sacrificato metà dei suoi PS per\nlanciare una maledizione su {{pokemonName}}!", "cursedLapse": "{{pokemonNameWithAffix}} subisce la maledizione!", - "stockpilingOnAdd": "{{pokemonNameWithAffix}} ha usato Accumulo per la\n{{stockpiledCount}}ª volta!", - "disabledOnAdd": "La mossa {{moveName}} di\n{{pokemonNameWithAffix}} è stata bloccata!", - "disabledLapse": "La mossa {{moveName}} di\n{{pokemonNameWithAffix}} non è più bloccata!" -} + "stockpilingOnAdd": "{{pokemonNameWithAffix}} ha usato Accumulo per la\n{{stockpiledCount}}ª volta!" +} \ No newline at end of file diff --git a/src/locales/it/menu.json b/src/locales/it/menu.json index 5a40ae05087..2d37f9db912 100644 --- a/src/locales/it/menu.json +++ b/src/locales/it/menu.json @@ -51,7 +51,5 @@ "renamePokemon": "Rinomina un Pokémon", "rename": "Rinomina", "nickname": "Nickname", - "errorServerDown": "Poffarbacco! C'è stato un errore nella comunicazione col server.\n\nPuoi lasciare questa finestra aperta,\nil gioco si riconnetterà automaticamente.", - "noSaves": "Non ci sono file di salvataggio registrati!", - "tooManySaves": "Ci sono troppi file di salvataggio registrati!" -} + "errorServerDown": "Poffarbacco! C'è stato un errore nella comunicazione col server.\n\nPuoi lasciare questa finestra aperta,\nil gioco si riconnetterà automaticamente." +} \ No newline at end of file diff --git a/src/locales/it/modifier-type.json b/src/locales/it/modifier-type.json index f06755bdfa0..99c06bb2038 100644 --- a/src/locales/it/modifier-type.json +++ b/src/locales/it/modifier-type.json @@ -47,14 +47,10 @@ "description": "Cambia la natura del Pokémon in {{natureName}} e sblocca la natura nel menu degli starter." }, "DoubleBattleChanceBoosterModifierType": { - "description": "Quadruplica la possibilità di imbattersi in doppie battaglie per {{battleCount}} battaglie." + "description": "Raddoppia la possibilità di imbattersi in doppie battaglie per {{battleCount}} battaglie." }, "TempStatStageBoosterModifierType": { - "description": "Aumenta la statistica {{stat}} di {{amount}}\na tutti i Pokémon nel gruppo per 5 battaglie", - "extra": { - "stage": "un livello", - "percentage": "30%" - } + "description": "Aumenta la statistica {{stat}} di un livello\na tutti i Pokémon nel gruppo per 5 battaglie." }, "AttackTypeBoosterModifierType": { "description": "Aumenta la potenza delle mosse di tipo {{moveType}} del 20% per un Pokémon." diff --git a/src/locales/ja/ability-trigger.json b/src/locales/ja/ability-trigger.json index 26d27701aef..f1d93baee2b 100644 --- a/src/locales/ja/ability-trigger.json +++ b/src/locales/ja/ability-trigger.json @@ -8,11 +8,10 @@ "trace": "{{pokemonName}}は 相手の {{targetName}}の\n{{abilityName}}を トレースした!", "windPowerCharged": "{{pokemonNameWithAffix}}は\n{{moveName}}を 受けて じゅうでんした!", "quickDraw": "{{pokemonName}}は クイックドロウで\n行動が はやくなった!", - "disguiseAvoidedDamage": "{{pokemonNameWithAffix}}の\nばけのかわが はがれた!", + "disguiseAvoidedDamage": "{{pokemonNameWithAffix}}'s disguise was busted!", "blockItemTheft": "{{pokemonNameWithAffix}}の {{abilityName}}で\n道具を うばわれない!", "typeImmunityHeal": "{{pokemonNameWithAffix}}は {{abilityName}}で\n体力を 回復した!", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}}は {{abilityName}}で\nダメージを 受けない。", - "fullHpResistType": "{{pokemonNameWithAffix}}は\n甲羅を かがやかせ タイプ相性を 歪める!", "moveImmunity": "{{pokemonNameWithAffix}}には\n効果が ないようだ…", "reverseDrain": "{{pokemonNameWithAffix}}は\nヘドロえきを 吸い取った!", "postDefendTypeChange": "{{pokemonNameWithAffix}}は {{abilityName}}で\n{{typeName}}タイプに なった!", @@ -52,7 +51,6 @@ "postSummonTeravolt": "{{pokemonNameWithAffix}}は\n弾(はじ)ける オーラを 放っている!", "postSummonDarkAura": "{{pokemonNameWithAffix}}は\nダークオーラを 放っている!", "postSummonFairyAura": "{{pokemonNameWithAffix}}は\nフェアリーオーラを 放っている!", - "postSummonAuraBreak": "{{pokemonNameWithAffix}}は\nすべての オーラを 制圧する!", "postSummonNeutralizingGas": "あたりに かがくへんかガスが 充満した!", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}}は\nふたつの 特性を あわせ持つ!", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}}は\nふたつの 特性を あわせ持つ!", diff --git a/src/locales/ja/battle.json b/src/locales/ja/battle.json index 1fe24068cdf..e84bccbd047 100644 --- a/src/locales/ja/battle.json +++ b/src/locales/ja/battle.json @@ -44,7 +44,6 @@ "moveNotImplemented": "{{moveName}}は まだ 実装されておらず 選択できません。", "moveNoPP": "しかし 技の\n残りポイントが なかった!", "moveDisabled": "かなしばりで\n{{moveName}}が 出せない!", - "disableInterruptedMove": "{{pokemonNameWithAffix}}は かなしばりで\n{{moveName}}が 出せない!", "noPokeballForce": "見えない 力の せいで\nボールが 投げられない!", "noPokeballTrainer": "人の ものを 取ったら 泥棒!", "noPokeballMulti": "相手の ポケモンが 一つしか\nいない 前に ボールが 使えない!", @@ -97,4 +96,4 @@ "congratulations": "おめでとうございます!!", "beatModeFirstTime": "初めて {{speciesName}}が {{gameMode}}モードを クリアした!\n{{newModifier}}を 手に入れた!", "ppReduced": "{{targetName}}の {{moveName}}を {{reduction}}削った!" -} +} \ No newline at end of file diff --git a/src/locales/ja/battler-tags.json b/src/locales/ja/battler-tags.json index 2b6382a3a9f..25412c971e9 100644 --- a/src/locales/ja/battler-tags.json +++ b/src/locales/ja/battler-tags.json @@ -67,7 +67,5 @@ "saltCuredLapse": "{{pokemonNameWithAffix}}は {{moveName}}の\n ダメージを 受けている", "cursedOnAdd": "{{pokemonNameWithAffix}}は 自分の 体力を 削って\n{{pokemonName}}に のろいを かけた!", "cursedLapse": "{{pokemonNameWithAffix}}は のろわれている!", - "stockpilingOnAdd": "{{pokemonNameWithAffix}}は {{stockpiledCount}}つ たくわえた!", - "disabledOnAdd": "{{pokemonNameWithAffix}}の\n{{moveName}}\nを 封じこめた!", - "disabledLapse": "{{pokemonNameWithAffix}}の\nかなしばりが 解けた!" + "stockpilingOnAdd": "{{pokemonNameWithAffix}}は {{stockpiledCount}}つ たくわえた!" } diff --git a/src/locales/ja/menu.json b/src/locales/ja/menu.json index f0914a7941c..576be0e15f8 100644 --- a/src/locales/ja/menu.json +++ b/src/locales/ja/menu.json @@ -51,7 +51,5 @@ "renamePokemon": "ニックネームを変える", "rename": "名前を変える", "nickname": "ニックネーム", - "errorServerDown": "おや!\nサーバーとの 接続中に 問題が 発生しました。\nゲームは 自動的に 再接続されます から\nウィンドウは 開いたままに しておいても よろしいです。", - "noSaves": "何の セーブファイルも ありません!", - "tooManySaves": "セーブファイルが いっぱいです!" + "errorServerDown": "おや!\nサーバーとの 接続中に 問題が 発生しました。\nゲームは 自動的に 再接続されます から\nウィンドウは 開いたままに しておいても よろしいです。" } diff --git a/src/locales/ja/modifier-type.json b/src/locales/ja/modifier-type.json index e78ffaf652e..e249e3c430f 100644 --- a/src/locales/ja/modifier-type.json +++ b/src/locales/ja/modifier-type.json @@ -47,14 +47,10 @@ "description": "ポケモンのせいかくを {{natureName}}にかえて スターターのせいかくをえいきゅうにかいじょする" }, "DoubleBattleChanceBoosterModifierType": { - "description": "バトル{{battleCount}}回の間  ダブルバトルになる  確率を 4倍に する" + "description": "バトル{{battleCount}}かいのあいだ ダブルバトルになるかくりつを2ばいにする" }, "TempStatStageBoosterModifierType": { - "description": "全員の 手持ちポケモンの {{stat}}を 最大5回の バトルの間に {{amount}}あげる.", - "extra": { - "stage": "1段階", - "percentage": "30%" - } + "description": "すべてのパーティメンバーの {{stat}}を5かいのバトルのあいだ 1だんかいあげる" }, "AttackTypeBoosterModifierType": { "description": "ポケモンの {{moveType}}タイプのわざのいりょくを20パーセントあげる" diff --git a/src/locales/ko/ability-trigger.json b/src/locales/ko/ability-trigger.json index b1f100c5c36..5cf94e92235 100644 --- a/src/locales/ko/ability-trigger.json +++ b/src/locales/ko/ability-trigger.json @@ -12,7 +12,6 @@ "blockItemTheft": "{{pokemonNameWithAffix}}의 {{abilityName}}에 의해\n도구를 빼앗기지 않는다!", "typeImmunityHeal": "{{pokemonNameWithAffix}}[[는]]\n{{abilityName}}[[로]] 체력이 회복되었다!", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}}[[는]] {{abilityName}} 때문에\n데미지를 입지 않는다!", - "fullHpResistType": "{{pokemonNameWithAffix}}[[는]] 등껍질을 빛나게 하여\n타입 상성을 왜곡시켰다!!", "moveImmunity": "{{pokemonNameWithAffix}}에게는\n효과가 없는 것 같다...", "reverseDrain": "{{pokemonNameWithAffix}}[[는]]\n해감액을 흡수했다!", "postDefendTypeChange": "{{pokemonNameWithAffix}}[[는]] {{abilityName}}[[로]] 인해\n{{typeName}}타입이 됐다!", @@ -52,7 +51,6 @@ "postSummonTeravolt": "{{pokemonNameWithAffix}}[[는]]\n세차게 튀는 오라를 발산하고 있다!", "postSummonDarkAura": "{{pokemonNameWithAffix}}[[는]]\n다크오라를 발산하고 있다!", "postSummonFairyAura": "{{pokemonNameWithAffix}}[[는]]\n페어리오라를 발산하고 있다!", - "postSummonAuraBreak": "{{pokemonNameWithAffix}}[[는]]\n모든 오라를 제압한다!", "postSummonNeutralizingGas": "주위가 화학변화가스로 가득 찼다!", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}}[[는]]\n두 가지 특성을 겸비한다!", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}}[[는]]\n두 가지 특성을 겸비한다!", @@ -61,4 +59,4 @@ "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}의 재앙의목간에 의해\n주위의 {{statName}}[[가]] 약해졌다!", "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}의 재앙의구슬에 의해\n주위의 {{statName}}[[가]] 약해졌다!", "preventBerryUse": "{{pokemonNameWithAffix}}[[는]] 긴장해서\n나무열매를 먹을 수 없게 되었다!" -} +} \ No newline at end of file diff --git a/src/locales/ko/battle.json b/src/locales/ko/battle.json index fd715fd0e7e..001720e4e5c 100644 --- a/src/locales/ko/battle.json +++ b/src/locales/ko/battle.json @@ -44,7 +44,6 @@ "moveNotImplemented": "{{moveName}}[[는]] 아직 구현되지 않아 사용할 수 없다…", "moveNoPP": "기술의 남은 포인트가 없다!", "moveDisabled": "{{moveName}}[[를]] 쓸 수 없다!", - "disableInterruptedMove": "{{pokemonNameWithAffix}}의 {{moveName}}[[는]]\n사용할 수 없다.", "noPokeballForce": "본 적 없는 힘이\n볼을 사용하지 못하게 한다.", "noPokeballTrainer": "다른 트레이너의 포켓몬은 잡을 수 없다!", "noPokeballMulti": "안돼! 2마리 있어서\n목표를 정할 수가 없어…!", @@ -96,4 +95,4 @@ "congratulations": "축하합니다!", "beatModeFirstTime": "{{speciesName}}[[가]] {{gameMode}} 모드를 처음으로 클리어했다!\n{{newModifier}}[[를]] 손에 넣었다!", "ppReduced": "{{targetName}}의\n{{moveName}}[[를]] {{reduction}} 깎았다!" -} +} \ No newline at end of file diff --git a/src/locales/ko/battler-tags.json b/src/locales/ko/battler-tags.json index 0993cafa04a..47ddb26c183 100644 --- a/src/locales/ko/battler-tags.json +++ b/src/locales/ko/battler-tags.json @@ -67,7 +67,5 @@ "saltCuredLapse": "{{pokemonNameWithAffix}}[[는]] 소금절이의\n데미지를 입고 있다.", "cursedOnAdd": "{{pokemonNameWithAffix}}[[는]] 자신의 체력을 깎아서\n{{pokemonName}}에게 저주를 걸었다!", "cursedLapse": "{{pokemonNameWithAffix}}[[는]]\n저주받고 있다!", - "stockpilingOnAdd": "{{pokemonNameWithAffix}}[[는]]\n{{stockpiledCount}}개 비축했다!", - "disabledOnAdd": "{{pokemonNameWithAffix}}의 {{moveName}}[[는]]\n사용할 수 없다!", - "disabledLapse": "{{pokemonNameWithAffix}}의 {{moveName}}[[는]]\n이제 사용할 수 있다." -} + "stockpilingOnAdd": "{{pokemonNameWithAffix}}[[는]]\n{{stockpiledCount}}개 비축했다!" +} \ No newline at end of file diff --git a/src/locales/ko/menu.json b/src/locales/ko/menu.json index a9db630f7a1..7976e0bedcf 100644 --- a/src/locales/ko/menu.json +++ b/src/locales/ko/menu.json @@ -51,7 +51,5 @@ "renamePokemon": "포켓몬의 닉네임은?", "rename": "닉네임 바꾸기", "nickname": "닉네임", - "errorServerDown": "서버 연결 중 문제가 발생했습니다.\n\n이 창을 종료하지 않고 두면,\n게임은 자동으로 재접속됩니다.", - "noSaves": "기기에 세이브 파일이 없습니다!", - "tooManySaves": "기기에 세이브 파일이 너무 많습니다!" + "errorServerDown": "서버 연결 중 문제가 발생했습니다.\n\n이 창을 종료하지 않고 두면,\n게임은 자동으로 재접속됩니다." } diff --git a/src/locales/ko/modifier-type.json b/src/locales/ko/modifier-type.json index e957fd0d58a..d94837bb0d2 100644 --- a/src/locales/ko/modifier-type.json +++ b/src/locales/ko/modifier-type.json @@ -47,14 +47,10 @@ "description": "포켓몬의 성격을 {{natureName}}[[로]] 바꾸고 스타팅에도 등록한다." }, "DoubleBattleChanceBoosterModifierType": { - "description": "{{battleCount}}번의 배틀 동안 더블 배틀이 등장할 확률이 4배가 된다." + "description": "{{battleCount}}번의 배틀 동안 더블 배틀이 등장할 확률이 두 배가 된다." }, "TempStatStageBoosterModifierType": { - "description": "자신의 모든 포켓몬이 5번의 배틀 동안 {{stat}}[[가]] {{amount}}단계 증가한다.", - "extra": { - "stage": "1 스테이지", - "percentage": "30%" - } + "description": "자신의 모든 포켓몬이 5번의 배틀 동안 {{stat}}[[가]] 한 단계 증가한다." }, "AttackTypeBoosterModifierType": { "description": "지니게 하면 {{moveType}}타입 기술의 위력이 20% 상승한다." diff --git a/src/locales/pt_BR/battle.json b/src/locales/pt_BR/battle.json index 08eeb99e0cd..b0b2cc9873c 100644 --- a/src/locales/pt_BR/battle.json +++ b/src/locales/pt_BR/battle.json @@ -97,4 +97,4 @@ "unlockedSomething": "{{unlockedThing}}\nfoi desbloqueado.", "congratulations": "Parabéns!", "beatModeFirstTime": "{{speciesName}} venceu o Modo {{gameMode}} pela primeira vez!\nVocê recebeu {{newModifier}}!" -} +} \ No newline at end of file diff --git a/src/locales/pt_BR/modifier-type.json b/src/locales/pt_BR/modifier-type.json index f20a4ef3d0f..823d6b35e16 100644 --- a/src/locales/pt_BR/modifier-type.json +++ b/src/locales/pt_BR/modifier-type.json @@ -47,14 +47,10 @@ "description": "Muda a natureza do Pokémon para {{natureName}} e a desbloqueia permanentemente." }, "DoubleBattleChanceBoosterModifierType": { - "description": "Quadruplica as chances de encontrar uma batalha em dupla por {{battleCount}} batalhas." + "description": "Dobra as chances de encontrar uma batalha em dupla por {{battleCount}} batalhas." }, "TempStatStageBoosterModifierType": { - "description": "Aumenta o atributo de {{stat}} para todos os membros da equipe em {{amount}} por 5 batalhas.", - "extra": { - "stage": "um nível", - "percentage": "30%" - } + "description": "Aumenta o atributo de {{stat}} para todos os membros da equipe por 5 batalhas." }, "AttackTypeBoosterModifierType": { "description": "Aumenta o poder dos ataques do tipo {{moveType}} de um Pokémon em 20%." diff --git a/src/locales/zh_CN/ability-trigger.json b/src/locales/zh_CN/ability-trigger.json index 0bb9c3a56ef..f4289b598a0 100644 --- a/src/locales/zh_CN/ability-trigger.json +++ b/src/locales/zh_CN/ability-trigger.json @@ -12,7 +12,6 @@ "blockItemTheft": "{{pokemonNameWithAffix}}的{{abilityName}}\n阻止了对方夺取道具!", "typeImmunityHeal": "{{pokemonNameWithAffix}}因{{abilityName}}\n回复了少许HP!", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}}因{{abilityName}}\n避免了伤害!", - "fullHpResistType": "{{pokemonNameWithAffix}}\n让甲壳发出光辉,使属性相克发生扭曲!", "moveImmunity": "对{{pokemonNameWithAffix}}没有效果!", "reverseDrain": "{{pokemonNameWithAffix}}\n吸到了污泥浆!", "postDefendTypeChange": "{{pokemonNameWithAffix}}因{{abilityName}}\n变成了{{typeName}}属性!", @@ -52,7 +51,6 @@ "postSummonTeravolt": "{{pokemonNameWithAffix}}\n正在释放溅射气场!", "postSummonDarkAura": "{{pokemonNameWithAffix}}\n正在释放暗黑气场!", "postSummonFairyAura": "{{pokemonNameWithAffix}}\n正在释放妖精气场!", - "postSummonAuraBreak": "{{pokemonNameWithAffix}}\n压制了所有气场!", "postSummonNeutralizingGas": "周围充满了\n{{pokemonNameWithAffix}}的化学变化气体!", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}}\n同时拥有了两种特性!", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}}\n同时拥有了两种特性!", @@ -61,4 +59,4 @@ "postSummonTabletsOfRuin": "{{pokemonNameWithAffix}}的灾祸之简\n令周围的宝可梦的{{statName}}减弱了!", "postSummonBeadsOfRuin": "{{pokemonNameWithAffix}}的灾祸之玉\n令周围的宝可梦的{{statName}}减弱了!", "preventBerryUse": "{{pokemonNameWithAffix}}因太紧张\n而无法食用树果!" -} +} \ No newline at end of file diff --git a/src/locales/zh_CN/battle.json b/src/locales/zh_CN/battle.json index 4197786b7d8..84f468a4a4b 100644 --- a/src/locales/zh_CN/battle.json +++ b/src/locales/zh_CN/battle.json @@ -44,7 +44,6 @@ "moveNotImplemented": "{{moveName}}尚未实装,无法选择。", "moveNoPP": "这个技能的PP用完了", "moveDisabled": "{{moveName}}被禁用!", - "disableInterruptedMove": "{{pokemonNameWithAffix}}的{{moveName}}\n被无效化了!", "noPokeballForce": "一股无形的力量阻止了你使用精灵球。", "noPokeballTrainer": "你不能捕捉其他训练家的宝可梦!", "noPokeballMulti": "只能在剩下一只宝可梦时才能扔出精灵球!", @@ -88,4 +87,4 @@ "unlockedSomething": "{{unlockedThing}}\n已解锁。", "congratulations": "恭喜!", "beatModeFirstTime": "{{speciesName}}首次击败了{{gameMode}}!\n你获得了{{newModifier}}!" -} +} \ No newline at end of file diff --git a/src/locales/zh_CN/battler-tags.json b/src/locales/zh_CN/battler-tags.json index 792551d1ab1..81838b5023a 100644 --- a/src/locales/zh_CN/battler-tags.json +++ b/src/locales/zh_CN/battler-tags.json @@ -67,7 +67,5 @@ "saltCuredLapse": "{{pokemonNameWithAffix}}\n受到了{{moveName}}的伤害!", "cursedOnAdd": "{{pokemonNameWithAffix}}削减了自己的体力,\n并诅咒了{{pokemonName}}!", "cursedLapse": "{{pokemonNameWithAffix}}\n正受到诅咒!", - "stockpilingOnAdd": "{{pokemonNameWithAffix}}蓄力了{{stockpiledCount}}次!", - "disabledOnAdd": "封住了{{pokemonNameWithAffix}}的\n{{moveName}}!", - "disabledLapse": "{{pokemonNameWithAffix}}的\n定身法解除了!" -} + "stockpilingOnAdd": "{{pokemonNameWithAffix}}蓄力了{{stockpiledCount}}次!" +} \ No newline at end of file diff --git a/src/locales/zh_CN/menu.json b/src/locales/zh_CN/menu.json index 8946b5b8df6..59146d30ee9 100644 --- a/src/locales/zh_CN/menu.json +++ b/src/locales/zh_CN/menu.json @@ -51,7 +51,5 @@ "renamePokemon": "给宝可梦起名", "rename": "起名", "nickname": "昵称", - "errorServerDown": "糟糕!访问服务器时发生了错误。\n\n你可以保持页面开启,\n游戏会自动重新连接。", - "noSaves": "你没有任何记录文件!", - "tooManySaves": "你的记录文件太多了!" -} + "errorServerDown": "糟糕!访问服务器时发生了错误。\n\n你可以保持页面开启,\n游戏会自动重新连接。" +} \ No newline at end of file diff --git a/src/locales/zh_CN/modifier-type.json b/src/locales/zh_CN/modifier-type.json index 26e4c2dc110..5d6184640b1 100644 --- a/src/locales/zh_CN/modifier-type.json +++ b/src/locales/zh_CN/modifier-type.json @@ -47,14 +47,10 @@ "description": "将一只宝可梦的性格改为{{natureName}}并为\n该宝可梦永久解锁该性格。" }, "DoubleBattleChanceBoosterModifierType": { - "description": "遭遇双打概率提升四倍,持续{{battleCount}}场战斗。" + "description": "接下来的{{battleCount}}场战斗是双打的概率翻倍。" }, "TempStatStageBoosterModifierType": { - "description": "提升全队的{{stat}}{{amount}}级,持续5场战斗。", - "extra": { - "stage": "1阶", - "percentage": "30%" - } + "description": "为所有成员宝可梦提升一级{{stat}},持续5场战斗。" }, "AttackTypeBoosterModifierType": { "description": "一只宝可梦的{{moveType}}系招式威力提升20%。" diff --git a/src/locales/zh_TW/ability-trigger.json b/src/locales/zh_TW/ability-trigger.json index f31fb12bc35..3286d97b10c 100644 --- a/src/locales/zh_TW/ability-trigger.json +++ b/src/locales/zh_TW/ability-trigger.json @@ -6,8 +6,6 @@ "trace": "{{pokemonName}} 複製了 {{targetName}} 的\n{{abilityName}}!", "windPowerCharged": "受 {{moveName}} 的影響, {{pokemonName}} 提升了能力!", "disguiseAvoidedDamage": "{{pokemonNameWithAffix}}的畫皮脫落了!", - "fullHpResistType": "{{pokemonNameWithAffix}}讓甲殼綻放光輝,扭曲了屬性相剋關係!", "weatherEffectDisappeared": "天氣的影響消失了!", - "postSummonAuraBreak": "{{pokemonNameWithAffix}}壓制了所有氣場!", "preventBerryUse": "{{pokemonNameWithAffix}}因太緊張\n而無法食用樹果!" -} +} \ No newline at end of file diff --git a/src/locales/zh_TW/battle.json b/src/locales/zh_TW/battle.json index 0d44688ff4a..97b85a9cd5a 100644 --- a/src/locales/zh_TW/battle.json +++ b/src/locales/zh_TW/battle.json @@ -40,7 +40,6 @@ "moveNotImplemented": "{{moveName}} 未實裝,無法選擇。", "moveNoPP": "這個技能的PP用完了", "moveDisabled": "{{moveName}} 被禁用!", - "disableInterruptedMove": "{{pokemonNameWithAffix}}的{{moveName}}\n被無效化了!", "noPokeballForce": "一股無形的力量阻止了你使用精靈球。", "noPokeballTrainer": "你不能捕捉其他訓練家的寶可夢!", "noPokeballMulti": "只能在剩下一隻寶可夢時才能扔出精靈球!", @@ -66,4 +65,4 @@ "regainHealth": "{{pokemonName}} 回復了體力!", "fainted": "{{pokemonNameWithAffix}} 倒下了!", "ppReduced": "降低了 {{targetName}} 的\n{{moveName}} 的PP{{reduction}}點!" -} +} \ No newline at end of file diff --git a/src/locales/zh_TW/battler-tags.json b/src/locales/zh_TW/battler-tags.json index b5a2760f7ac..9a35bb0d03f 100644 --- a/src/locales/zh_TW/battler-tags.json +++ b/src/locales/zh_TW/battler-tags.json @@ -66,7 +66,5 @@ "saltCuredOnAdd": "{{pokemonNameWithAffix}} 陷入了鹽腌狀態!", "saltCuredLapse": "{{pokemonNameWithAffix}} 受到了{{moveName}}的傷害!", "cursedOnAdd": "{{pokemonNameWithAffix}}削減了自己的體力,並詛咒了{{pokemonName}}!", - "cursedLapse": "{{pokemonNameWithAffix}}正受到詛咒!", - "disabledOnAdd": "封住了{{pokemonNameWithAffix}}的\n{moveName}}!", - "disabledLapse": "{{pokemonNameWithAffix}}的\n定身法解除了!" -} + "cursedLapse": "{{pokemonNameWithAffix}}正受到詛咒!" +} \ No newline at end of file diff --git a/src/locales/zh_TW/menu.json b/src/locales/zh_TW/menu.json index b56a39bbda2..1ec0b7124d8 100644 --- a/src/locales/zh_TW/menu.json +++ b/src/locales/zh_TW/menu.json @@ -40,7 +40,5 @@ "loading": "加載中…", "playersOnline": "在線玩家", "yes": "是", - "no": "否", - "noSaves": "你沒有任何記錄檔!", - "tooManySaves": "你的記錄檔太多了!" -} + "no": "否" +} \ No newline at end of file diff --git a/src/locales/zh_TW/modifier-type.json b/src/locales/zh_TW/modifier-type.json index ec066277cda..68881a206cb 100644 --- a/src/locales/zh_TW/modifier-type.json +++ b/src/locales/zh_TW/modifier-type.json @@ -47,14 +47,10 @@ "description": "將一隻寶可夢的性格改爲{{natureName}}併爲該寶可\n夢永久解鎖該性格。" }, "DoubleBattleChanceBoosterModifierType": { - "description": "遭遇雙打機率提升四倍,持續{{battleCount}}場戰鬥。" + "description": "接下來的{{battleCount}}場戰鬥是雙打的概率翻倍。" }, "TempStatStageBoosterModifierType": { - "description": "提升全隊的{{stat}}{{amount}}級,持續5場戰鬥。", - "extra": { - "stage": "1階", - "percentage": "30%" - } + "description": "爲所有成員寶可夢提升一級{{stat}},持續5場戰鬥。" }, "AttackTypeBoosterModifierType": { "description": "一隻寶可夢的{{moveType}}系招式威力提升20%。" diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 91bc0d2e981..1413ecf8b69 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -34,6 +34,8 @@ const useMaxWeightForOutput = false; type Modifier = Modifiers.Modifier; +const doModifierLogging: boolean = false; + export enum ModifierPoolType { PLAYER, WILD, @@ -1035,7 +1037,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator { return new AttackTypeBoosterModifierType(pregenArgs[0] as Type, 20); } - console.log("Generating item: Attack Type Booster") + if (doModifierLogging) console.log("Generating item: Attack Type Booster") const attackMoveTypes = party.map(p => p.getMoveset().map(m => m?.getMove()).filter(m => m instanceof AttackMove).map(m => m.type)).flat(); if (!attackMoveTypes.length) { @@ -1063,7 +1065,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator { let type: Type; - const randInt = Utils.randSeedInt(totalWeight); + const randInt = Utils.randSeedInt(totalWeight, undefined, doModifierLogging ? "Generating a move type booster" : "%HIDE"); let weight = 0; var fullweights: integer[] = [] @@ -1104,7 +1106,7 @@ class BaseStatBoosterModifierTypeGenerator extends ModifierTypeGenerator { if (pregenArgs) { return new BaseStatBoosterModifierType(pregenArgs[0]); } - const randStat: PermanentStat = Utils.randSeedInt(Stat.SPD + 1); + const randStat: PermanentStat = Utils.randSeedInt(Stat.SPD + 1, undefined, doModifierLogging ? "Randomly generating a Vitamin" : "%HIDE"); return new BaseStatBoosterModifierType(randStat); }); } @@ -1125,7 +1127,7 @@ class TempStatStageBoosterModifierTypeGenerator extends ModifierTypeGenerator { if (pregenArgs && (pregenArgs.length === 1) && TEMP_BATTLE_STATS.includes(pregenArgs[0])) { return new TempStatStageBoosterModifierType(pregenArgs[0]); } - const randStat: TempBattleStat = Utils.randSeedInt(Stat.ACC, Stat.ATK); + const randStat: TempBattleStat = Utils.randSeedInt(Stat.ACC, Stat.ATK, doModifierLogging ? "Randomly choosing an X item" : "%HIDE"); return new TempStatStageBoosterModifierType(randStat); }); } @@ -1190,7 +1192,7 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator { } if (totalWeight !== 0) { - const randInt = Utils.randSeedInt(totalWeight, 1); + const randInt = Utils.randSeedInt(totalWeight, 1, doModifierLogging ? "Randomly choosing a species booster" : "HIDE"); let weight = 0; var fullweights: integer[] = [] @@ -1225,15 +1227,15 @@ class TmModifierTypeGenerator extends ModifierTypeGenerator { return new TmModifierType(pregenArgs[0] as Moves, tier); } - console.log("Generating item: TM (Tier: " + Utils.getEnumKeys(ModifierTier)[tier].toLowerCase() + ")") + if (doModifierLogging) console.log("Generating item: TM (Tier: " + Utils.getEnumKeys(ModifierTier)[tier].toLowerCase() + ")") const partyMemberCompatibleTms = party.map(p => (p as PlayerPokemon).compatibleTms.filter(tm => !p.moveset.find(m => m?.moveId === tm))); const tierUniqueCompatibleTms = partyMemberCompatibleTms.flat().filter(tm => tmPoolTiers[tm] === tier).filter(tm => !allMoves[tm].name.endsWith(" (N)")).filter((tm, i, array) => array.indexOf(tm) === i); if (!tierUniqueCompatibleTms.length) { return null; } - const randTmIndex = Utils.randSeedInt(tierUniqueCompatibleTms.length); //console.log(tierUniqueCompatibleTms.map((v, i) => i == randTmIndex ? `> ${Utils.getEnumKeys(Moves)[v].toUpperCase() + Utils.getEnumKeys(Moves)[v].substring(1).toLowerCase()} <` : `${Utils.getEnumKeys(Moves)[v].toUpperCase() + Utils.getEnumKeys(Moves)[v].substring(1).toLowerCase()}`)) + const randTmIndex = Utils.randSeedInt(tierUniqueCompatibleTms.length, undefined, doModifierLogging ? "Choosing a TM to give" : "%HIDE"); return new TmModifierType(tierUniqueCompatibleTms[randTmIndex], tier); }); } @@ -1246,7 +1248,7 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator { return new EvolutionItemModifierType(pregenArgs[0] as EvolutionItem); } - console.log("Generating item: Evolution Item") + if (doModifierLogging) console.log("Generating item: Evolution Item") const evolutionItemPool = [ party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => { @@ -1263,9 +1265,7 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator { return null; } - const idx = Utils.randSeedInt(evolutionItemPool.length) - // console.log(evolutionItemPool.map((v, i) => i == idx ? `> ${Utils.getEnumKeys(EvolutionItem)[v!]} <` : Utils.getEnumKeys(EvolutionItem)[v!])) - return new EvolutionItemModifierType(evolutionItemPool[idx]!); // TODO: is the bang correct? + return new EvolutionItemModifierType(evolutionItemPool[Utils.randSeedInt(evolutionItemPool.length, undefined, doModifierLogging ? "Choosing an evolution item" : "%HIDE")]!); // TODO: is the bang correct? }); } } @@ -1277,7 +1277,7 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { return new FormChangeItemModifierType(pregenArgs[0] as FormChangeItem); } - console.log("Generating item: Form Change Item") + if (doModifierLogging) console.log("Generating item: Form Change Item") const formChangeItemPool = [...new Set(party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => { const formChanges = pokemonFormChanges[p.species.speciesId]; @@ -1321,9 +1321,7 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { return null; } - const idx = Utils.randSeedInt(formChangeItemPool.length) - // console.log(formChangeItemPool.map((v, i) => i == idx ? `> ${Utils.getEnumKeys(FormChangeItem)[v!]} <` : Utils.getEnumKeys(FormChangeItem)[v!])) - return new FormChangeItemModifierType(formChangeItemPool[idx]!); + return new FormChangeItemModifierType(formChangeItemPool[Utils.randSeedInt(formChangeItemPool.length, undefined, doModifierLogging ? "Choosing a form change item" : "%HIDE")]); }); } } @@ -1584,7 +1582,7 @@ export const modifierTypes = { if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in Nature)) { return new PokemonNatureChangeModifierType(pregenArgs[0] as Nature); } - return new PokemonNatureChangeModifierType(Utils.randSeedInt(Utils.getEnumValues(Nature).length) as Nature); + return new PokemonNatureChangeModifierType(Utils.randSeedInt(Utils.getEnumValues(Nature).length, undefined, "Choosing a Mint") as Nature); }), TERA_SHARD: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { @@ -1595,11 +1593,11 @@ export const modifierTypes = { return null; } let type: Type; - if (!Utils.randSeedInt(3)) { + if (!Utils.randSeedInt(3, undefined, "Choosing whether to give a type from your party")) { const partyMemberTypes = party.map(p => p.getTypes(false, false, true)).flat(); - type = Utils.randSeedItem(partyMemberTypes); + type = Utils.randSeedItem(partyMemberTypes, "Choosing a Tera Shard type to give"); } else { - type = Utils.randSeedInt(64) ? Utils.randSeedInt(18) as Type : Type.STELLAR; + type = Utils.randSeedInt(64, undefined, "Choosing whether to give a Stellar Shard") ? Utils.randSeedInt(18, undefined, "Choosing a type (man I have no patience)") as Type : Type.STELLAR; } return new TerastallizeModifierType(type); }), @@ -1610,7 +1608,7 @@ export const modifierTypes = { } const berryTypes = Utils.getEnumValues(BerryType); let randBerryType: BerryType; - const rand = Utils.randSeedInt(12); + const rand = Utils.randSeedInt(12, undefined, "Choosing a Berry"); if (rand < 2) { randBerryType = BerryType.SITRUS; } else if (rand < 4) { @@ -1618,7 +1616,7 @@ export const modifierTypes = { } else if (rand < 6) { randBerryType = BerryType.LEPPA; } else { - randBerryType = berryTypes[Utils.randSeedInt(berryTypes.length - 3) + 2]; + randBerryType = berryTypes[Utils.randSeedInt(berryTypes.length - 3, undefined, "Choosing a random berry type") + 2]; } return new BerryModifierType(randBerryType); }), @@ -2584,6 +2582,12 @@ export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemo let r = 0; const aT = candidate?.alternates const aT2 = candidate?.advancedAlternates + const retryPool: string[] = [] + if (candidate) { + retryPool.push(candidate!.type.name) + } else { + retryPool.push("undefined") + } while (options.length && ++r < retryCount && options.filter(o => o.type?.name === candidate?.type?.name || o.type?.group === candidate?.type?.group).length) { //if (options.filter(o => o.type?.name === candidate?.type?.name)) //console.error(options.filter(o => o.type?.name === candidate?.type?.name).map((v, q) => v.type.name + " (" + v.type.group + ") - conflicting name").join("\n")) @@ -2591,17 +2595,23 @@ export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemo //console.error(options.filter(o => o.type?.group === candidate?.type?.group).map((v, q) => v.type.name + " (" + v.type.group + ") - conflicting group").join("\n")) candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate?.type?.tier, candidate?.upgradeCount, undefined, scene, shutUpBro, generateAltTiers, advanced); //console.log(" Retrying - attempt " + r, candidate?.type.name) + if (candidate) { + retryPool.push(candidate!.type.name) + } else { + retryPool.push("undefined") + } } if (options.length && options.filter(o => o.type?.name === candidate?.type?.name || o.type?.group === candidate?.type?.group).length) { - //console.log(" Item " + (i+1) + "/" + count + " (+" + r + ")", candidate?.type.name, "(Out of retries)") + console.log(" Item " + (i+1) + "/" + count + " (" + r + " attempts or more)", candidate?.type.name, retryPool) } else { - //console.log(" Item " + (i+1) + "/" + count + " (+" + r + ")", candidate?.type.name) + console.log(" Item " + (i+1) + "/" + count + " (" + r + " attempt" + (r == 1 ? "" : "s") + ")", candidate?.type.name, retryPool) } if (candidate && candidate.alternates == undefined) { candidate.alternates = aT candidate.advancedAlternates = aT2 } if (candidate) { + candidate.retriesList = retryPool; options.push(candidate); } }); @@ -2708,7 +2718,7 @@ export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: } export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[], poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER, upgradeChance: integer = 0, scene?: BattleScene): PokemonHeldItemModifierType[] { - const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType, undefined, upgradeChance && !Utils.randSeedInt(upgradeChance) ? 1 : 0, undefined, scene)?.type as PokemonHeldItemModifierType); + const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType, undefined, upgradeChance && !Utils.randSeedInt(upgradeChance, undefined, "Chance to upgrade an opponent's item") ? 1 : 0)?.type as PokemonHeldItemModifierType, scene); if (!(waveIndex % 1000)) { ret.push(getModifierType(modifierTypes.MINI_BLACK_HOLE) as PokemonHeldItemModifierType); } @@ -2719,7 +2729,7 @@ export function getDailyRunStarterModifiers(party: PlayerPokemon[], scene?: Batt const ret: Modifiers.PokemonHeldItemModifier[] = []; for (const p of party) { for (let m = 0; m < 3; m++) { - const tierValue = Utils.randSeedInt(64); + const tierValue = Utils.randSeedInt(64, undefined, "Choosing modifier tier for daily items"); let tier: ModifierTier; if (tierValue > 25) { @@ -2769,7 +2779,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, if (generateAltTiers) { for (var luck = 0; luck <= 14; luck++) { var state = Phaser.Math.RND.state() - var tierValueTemp = Utils.randSeedInt(1024); + var tierValueTemp = Utils.randSeedInt(1024, undefined, "%HIDE"); var upgradeCountTemp = 0; var tierTemp: ModifierTier; if (upgradeCount) { @@ -2780,7 +2790,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, const upgradeOddsTemp = Math.floor(128 / ((partyLuckValue + 4) / 4)); let upgraded = false; do { - upgraded = Utils.randSeedInt(upgradeOddsTemp) < 4; + upgraded = Utils.randSeedInt(upgradeOddsTemp, undefined, "%HIDE") < 4; if (upgraded) { upgradeCountTemp++; } @@ -2807,7 +2817,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, Phaser.Math.RND.state(state) } } - const tierValue = Utils.randSeedInt(1024); + const tierValue = Utils.randSeedInt(1024, undefined, "Choosing a modifier tier"); if (!upgradeCount) { upgradeCount = 0; } @@ -2821,7 +2831,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, const upgradeOdds = Math.floor(128 / ((partyLuckValue + 4) / 4)); let upgraded = false; do { - upgraded = Utils.randSeedInt(upgradeOdds) < 4; + upgraded = Utils.randSeedInt(upgradeOdds, undefined, "Upgrade chance") < 4; if (upgraded) { upgradeCount++; } @@ -2862,7 +2872,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, var upgradeOddsTemp = Math.floor(32 / ((luck + 2) / 2)); var upgradeCountTemp = 0; while (modifierPool.hasOwnProperty(tier + upgradeCountTemp + 1) && modifierPool[tier + upgradeCountTemp + 1].length) { - if (!Utils.randSeedInt(upgradeOddsTemp)) { + if (!Utils.randSeedInt(upgradeOddsTemp, undefined, "%HIDE")) { upgradeCountTemp++; } else { break; @@ -2879,7 +2889,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, } const upgradeOdds = Math.floor(32 / ((partyShinyCount + 2) / 2)); while (modifierPool.hasOwnProperty(tier + upgradeCount + 1) && modifierPool[tier + upgradeCount + 1].length) { - if (!Utils.randSeedInt(upgradeOdds)) { + if (!Utils.randSeedInt(upgradeOdds, undefined, "Upgrade chance 2")) { upgradeCount++; } else { break; @@ -2892,7 +2902,17 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier--; } - let index = getItemIndex(thresholds, tier); + const tierThresholds = Object.keys(thresholds[tier]); + const totalWeight = parseInt(tierThresholds[tierThresholds.length - 1]); + const value = Utils.randSeedInt(totalWeight, undefined, doModifierLogging ? "Weighted modifier selection (total " + totalWeight + ")" : "%HIDE"); + let index: integer | undefined; + for (const t of tierThresholds) { + const threshold = parseInt(t); + if (value < threshold) { + index = thresholds[tier][threshold]; + break; + } + } if (index === undefined) { return null; @@ -2900,23 +2920,23 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, if (player) { if (!shutUpBro) { - console.log(index, ignoredPoolIndexes[tier].filter(i => i <= index).length, ignoredPoolIndexes[tier].filter(i => i <= index).length) + //console.log(index, ignoredPoolIndexes[tier].filter(i => i <= index).length, ignoredPoolIndexes[tier].filter(i => i <= index).length) //console.log("Index ", index); //console.log("# of ignored items for this tier", ignoredPoolIndexes[tier].filter(i => i <= index).length) //console.log("Ignored items for this tier", ignoredPoolIndexes[tier].map((v, i) => [ignoredPoolNames[i], v]).flat()) } } - let modifierType: ModifierType = (pool[tier][index]).modifierType; + let modifierType: ModifierType | null = (pool[tier][index]).modifierType; if (modifierType instanceof ModifierTypeGenerator) { - modifierType = (modifierType as ModifierTypeGenerator).generateType(party)!; + modifierType = (modifierType as ModifierTypeGenerator).generateType(party); if (modifierType === null) { if (player) { if (!shutUpBro) console.log(ModifierTier[tier], upgradeCount); } - console.error("Null Modifier - regenerating") + //console.error("Null Modifier - regenerating") return getNewModifierTypeOption(party, poolType, tier, upgradeCount, ++retryCount, scene, shutUpBro, generateAltTiers); } else { - console.log("Generated type", modifierType) + if (doModifierLogging) console.log("Generated type", modifierType) } } @@ -2945,7 +2965,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, function getItemIndex(thresholds, tier) { const tierThresholds = Object.keys(thresholds[tier]); const totalWeight = parseInt(tierThresholds[tierThresholds.length - 1]); - const value = Utils.randSeedInt(totalWeight); + const value = Utils.randSeedInt(totalWeight, undefined, "%HIDE"); let index: integer; for (const t of tierThresholds) { const threshold = parseInt(t); @@ -2992,6 +3012,7 @@ export class ModifierTypeOption { public alternates?: integer[]; public netprice: integer; public advancedAlternates?: string[]; + public retriesList: string[]; constructor(type: ModifierType, upgradeCount: integer, cost: number = 0) { this.type = type; diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 27d090cf11a..5763933cd6d 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -371,6 +371,10 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { return container; } + getIconStackText(_scene: BattleScene, _virtual?: boolean): Phaser.GameObjects.BitmapText | null { + return null; + } + getBattleCount(): number { return this.battleCount; } @@ -388,7 +392,8 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { } getMaxStackCount(_scene: BattleScene, _forThreshold?: boolean): number { - return 1; + // Must be an abitrary number greater than 1 + return 2; } } @@ -1489,7 +1494,7 @@ export class PreserveBerryModifier extends PersistentModifier { apply(args: any[]): boolean { if (!(args[1] as Utils.BooleanHolder).value) { - (args[1] as Utils.BooleanHolder).value = (args[0] as Pokemon).randSeedInt(10, undefined, "Chance to save a berry") < this.getStackCount() * 3; + (args[1] as Utils.BooleanHolder).value = (args[0] as Pokemon).randSeedInt(10, undefined, "Chance to preserve berry") < this.getStackCount() * 3; } return true; @@ -2423,7 +2428,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { return false; } - const targetPokemon = opponents[pokemon.randSeedInt(opponents.length, undefined, "Chance to steal/transfer an item")]; + const targetPokemon = opponents[pokemon.randSeedInt(opponents.length, undefined, "Chance to steal item")]; const transferredItemCount = this.getTransferredItemCount(); if (!transferredItemCount) { diff --git a/src/phases/attempt-capture-phase.ts b/src/phases/attempt-capture-phase.ts index c4ee378d9b5..a4d5514415f 100644 --- a/src/phases/attempt-capture-phase.ts +++ b/src/phases/attempt-capture-phase.ts @@ -1,6 +1,6 @@ import BattleScene from "#app/battle-scene"; import { BattlerIndex } from "#app/battle"; -import { getPokeballCatchMultiplier, getPokeballAtlasKey, getPokeballTintColor, doPokeballBounceAnim } from "#app/data/pokeball"; +import { getPokeballCatchMultiplier, getPokeballAtlasKey, getPokeballTintColor, doPokeballBounceAnim, getPokeballName } from "#app/data/pokeball"; import { getStatusEffectCatchRateMultiplier } from "#app/data/status-effect"; import { PokeballType } from "#app/enums/pokeball"; import { StatusEffect } from "#app/enums/status-effect"; @@ -63,7 +63,7 @@ export class AttemptCapturePhase extends PokemonPhase { const y = Math.round(65536 / Math.sqrt(Math.sqrt(255 / x))); const fpOffset = pokemon.getFieldPositionOffset(); - LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, "Poké Ball Throw") + LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, getPokeballName(this.pokeballType)) const pokeballAtlasKey = getPokeballAtlasKey(this.pokeballType); this.pokeball = this.scene.addFieldSprite(16, 80, "pb", pokeballAtlasKey); @@ -124,7 +124,7 @@ export class AttemptCapturePhase extends PokemonPhase { shakeCounter.stop(); this.failCatch(shakeCount); } else if (shakeCount++ < 3) { - if (pokeballMultiplier === -1 || this.roll(y) < y) { + if (pokeballMultiplier === -1 || pokemon.randSeedInt(65536, undefined, "Capture roll") < y) { this.scene.playSound("se/pb_move"); } else { shakeCounter.stop(); diff --git a/src/phases/attempt-run-phase.ts b/src/phases/attempt-run-phase.ts index 2ef29c56424..ef2c21b74a3 100644 --- a/src/phases/attempt-run-phase.ts +++ b/src/phases/attempt-run-phase.ts @@ -29,7 +29,7 @@ export class AttemptRunPhase extends PokemonPhase { applyAbAttrs(RunSuccessAbAttr, playerPokemon, null, false, escapeChance); - if (playerPokemon.randSeedInt(100, undefined, "Run attempt") < escapeChance.value) { + if (playerPokemon.randSeedInt(100, undefined, "Run away chance") < escapeChance.value) { this.scene.playSound("se/flee"); LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, "Fled") this.scene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500); diff --git a/src/phases/egg-hatch-phase.ts b/src/phases/egg-hatch-phase.ts index 5d7ad82b6c8..2c1a6787cbb 100644 --- a/src/phases/egg-hatch-phase.ts +++ b/src/phases/egg-hatch-phase.ts @@ -391,7 +391,7 @@ export class EggHatchPhase extends Phase { repeat: intensity, duration: Utils.getFrameMs(1), onRepeat: () => { - this.doSprayParticle(Utils.randInt(8), offsetY || 0); + this.doSprayParticle(Utils.randInt(8, undefined, "%HIDE"), offsetY || 0); } }); } @@ -410,8 +410,8 @@ export class EggHatchPhase extends Phase { let f = 0; let yOffset = 0; - const speed = 3 - Utils.randInt(8); - const amp = 24 + Utils.randInt(32); + const speed = 3 - Utils.randInt(8, undefined, "%HIDE"); + const amp = 24 + Utils.randInt(32, undefined, "%HIDE"); const particleTimer = this.scene.tweens.addCounter({ repeat: -1, @@ -449,6 +449,7 @@ export class EggHatchPhase extends Phase { */ generatePokemon(): PlayerPokemon { this.eggHatchData = this.eggLapsePhase.generatePokemon(this.egg); + this.eggMoveIndex = this.eggHatchData.eggMoveIndex; return this.eggHatchData.pokemon; } } diff --git a/src/phases/egg-summary-phase.ts b/src/phases/egg-summary-phase.ts index 190af17c724..1aa432829a1 100644 --- a/src/phases/egg-summary-phase.ts +++ b/src/phases/egg-summary-phase.ts @@ -45,6 +45,7 @@ export class EggSummaryPhase extends Phase { end() { this.eggHatchHandler.clear(); this.scene.ui.setModeForceTransition(Mode.MESSAGE).then(() => {}); + this.scene.time.delayedCall(250, () => this.scene.setModifiersVisible(true)); super.end(); } } diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 5bd9906b52c..9a957882489 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -309,7 +309,7 @@ export class EncounterPhase extends BattlePhase { doSummon(); } else { let message: string; - this.scene.executeWithSeedOffset(() => message = Utils.randSeedItem(encounterMessages), this.scene.currentBattle.waveIndex); + this.scene.executeWithSeedOffset(() => message = Utils.randSeedItem(encounterMessages, "Encounter message"), this.scene.currentBattle.waveIndex); message = message!; // tell TS compiler it's defined now const showDialogueAndSummon = () => { this.scene.ui.showDialogue(message, trainer?.getName(TrainerSlot.NONE, true), null, () => { diff --git a/src/phases/evolution-phase.ts b/src/phases/evolution-phase.ts index d75a7dcea05..13a0cbaf279 100644 --- a/src/phases/evolution-phase.ts +++ b/src/phases/evolution-phase.ts @@ -387,7 +387,7 @@ export class EvolutionPhase extends Phase { this.doSprayParticle(i); } } else if (f < 50) { - this.doSprayParticle(Utils.randInt(8)); + this.doSprayParticle(Utils.randInt(8, undefined, "%HIDE")); } f++; } @@ -503,8 +503,8 @@ export class EvolutionPhase extends Phase { let f = 0; let yOffset = 0; - const speed = 3 - Utils.randInt(8); - const amp = 48 + Utils.randInt(64); + const speed = 3 - Utils.randInt(8, undefined, "%HIDE"); + const amp = 48 + Utils.randInt(64, undefined, "%HIDE"); const particleTimer = this.scene.tweens.addCounter({ repeat: -1, diff --git a/src/phases/field-phase.ts b/src/phases/field-phase.ts index 6448c25ad44..d185b2f2a3f 100644 --- a/src/phases/field-phase.ts +++ b/src/phases/field-phase.ts @@ -8,35 +8,6 @@ import { TrickRoomTag } from "#app/data/arena-tag.js"; type PokemonFunc = (pokemon: Pokemon) => void; export abstract class FieldPhase extends BattlePhase { - getOrder(): BattlerIndex[] { - const playerField = this.scene.getPlayerField().filter(p => p.isActive()) as Pokemon[]; - const enemyField = this.scene.getEnemyField().filter(p => p.isActive()) as Pokemon[]; - - // We shuffle the list before sorting so speed ties produce random results - let orderedTargets: Pokemon[] = playerField.concat(enemyField); - // We seed it with the current turn to prevent an inconsistency where it - // was varying based on how long since you last reloaded - this.scene.executeWithSeedOffset(() => { - orderedTargets = Utils.randSeedShuffle(orderedTargets); - }, this.scene.currentBattle.turn, this.scene.waveSeed); - - orderedTargets.sort((a: Pokemon, b: Pokemon) => { - const aSpeed = a?.getEffectiveStat(Stat.SPD) || 0; - const bSpeed = b?.getEffectiveStat(Stat.SPD) || 0; - - return bSpeed - aSpeed; - }); - - const speedReversed = new Utils.BooleanHolder(false); - this.scene.arena.applyTags(TrickRoomTag, speedReversed); - - if (speedReversed.value) { - orderedTargets = orderedTargets.reverse(); - } - - return orderedTargets.map(t => t.getFieldIndex() + (!t.isPlayer() ? BattlerIndex.ENEMY : 0)); - } - executeForAll(func: PokemonFunc): void { const field = this.scene.getField(true).filter(p => p.summonData); field.forEach(pokemon => func(pokemon)); diff --git a/src/phases/learn-move-phase.ts b/src/phases/learn-move-phase.ts index eb22a05238c..b82574e0bdc 100644 --- a/src/phases/learn-move-phase.ts +++ b/src/phases/learn-move-phase.ts @@ -36,12 +36,153 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase { return this.end(); } - this.messageMode = this.scene.ui.getHandler() instanceof EvolutionSceneHandler ? Mode.EVOLUTION_SCENE : Mode.MESSAGE; - this.scene.ui.setMode(this.messageMode); - // If the Pokemon has less than 4 moves, the new move is added to the largest empty moveset index - // If it has 4 moves, the phase then checks if the player wants to replace the move itself. - if (currentMoveset.length < 4) { - this.learnMove(currentMoveset.length, move, pokemon); + const emptyMoveIndex = pokemon.getMoveset().length < 4 + ? pokemon.getMoveset().length + : pokemon.getMoveset().findIndex(m => m === null); + + const messageMode = this.scene.ui.getHandler() instanceof EvolutionSceneHandler + ? Mode.EVOLUTION_SCENE + : Mode.MESSAGE; + const noHandler = () => { + this.scene.ui.setMode(messageMode).then(() => { + this.scene.ui.showText(i18next.t("battle:learnMoveStopTeaching", { moveName: move.name }), null, () => { + this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => { + this.scene.ui.setMode(messageMode); + var W = LoggerTools.getWave(LoggerTools.getDRPD(this.scene), this.scene.currentBattle.waveIndex, this.scene) + if (W.shop != "") { + LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, W.shop + "; skip learning it") + } else { + var actions = LoggerTools.getActionCount(this.scene, this.scene.currentBattle.waveIndex) + LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, "Skip " + move.name) + } + this.scene.ui.showText(i18next.t("battle:learnMoveNotLearned", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }), null, () => this.end(), null, true); + }, (false ? movesFullHandler : () => { + this.scene.ui.setMode(messageMode); + this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.partyMemberIndex, this.moveId)); + this.end(); + })); + }); + }); + }; + const noHandlerInstant = () => { + this.scene.ui.setMode(messageMode); + var W = LoggerTools.getWave(LoggerTools.getDRPD(this.scene), this.scene.currentBattle.waveIndex, this.scene) + if (W.shop != "") { + LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, W.shop + "; skip learning it") + } else { + var actions = LoggerTools.getActionCount(this.scene, this.scene.currentBattle.waveIndex) + LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, (actions == 0 ? "" : "") + LoggerTools.playerPokeName(this.scene, pokemon) + " | Skip " + move.name) + } + this.scene.ui.showText(i18next.t("battle:learnMoveNotLearned", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }), null, () => this.end(), null, true); + }; + const movesFullHandler = () => { + this.scene.ui.showText(i18next.t("battle:learnMovePrompt", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }), null, () => { + this.scene.ui.showText(i18next.t("battle:learnMoveLimitReached", { pokemonName: getPokemonNameWithAffix(pokemon) }), null, () => { + this.scene.ui.showText(i18next.t("battle:learnMoveReplaceQuestion", { moveName: move.name }), null, () => { + this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => { + this.scene.ui.setMode(messageMode); + this.scene.ui.showText(i18next.t("battle:learnMoveForgetQuestion"), null, () => { + this.scene.ui.setModeWithoutClear(Mode.SUMMARY, this.getPokemon(), SummaryUiMode.LEARN_MOVE, move, (moveIndex: integer) => { + if (moveIndex === 4) { + noHandler(); + return; + } + this.scene.ui.setMode(messageMode).then(() => { + this.scene.ui.showText(i18next.t("battle:countdownPoof"), null, () => { + this.scene.ui.showText(i18next.t("battle:learnMoveForgetSuccess", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: pokemon.moveset[moveIndex]!.getName() }), null, () => { // TODO: is the bang correct? + this.scene.ui.showText(i18next.t("battle:learnMoveAnd"), null, () => { + var W = LoggerTools.getWave(LoggerTools.getDRPD(this.scene), this.scene.currentBattle.waveIndex, this.scene) + if (W.shop != "") { + LoggerTools.logShop(this.scene, this.scene.currentBattle.waveIndex, W.shop + " | " + new PokemonMove(this.moveId).getName() + " → " + pokemon.moveset[moveIndex]!.getName()) + } else { + var actions = LoggerTools.getActionCount(this.scene, this.scene.currentBattle.waveIndex) + LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, (actions == 0 ? "" : "") + LoggerTools.playerPokeName(this.scene, pokemon) + " | " + new PokemonMove(this.moveId).getName() + " → " + pokemon.moveset[moveIndex]!.getName()) + } + pokemon.setMove(moveIndex, Moves.NONE); + this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.partyMemberIndex, this.moveId)); + this.end(); + }, null, true); + }, null, true); + }, null, true); + }); + }); + }, null, true); + }, noHandler); + }); + }, null, true); + }, null, true); + } + if (emptyMoveIndex > -1) { + pokemon.setMove(emptyMoveIndex, this.moveId); + if (this.fromTM) { + if (!pokemon.usedTMs) { + pokemon.usedTMs = []; + } + pokemon.usedTMs.push(this.moveId); + } + initMoveAnim(this.scene, this.moveId).then(() => { + loadMoveAnimAssets(this.scene, [this.moveId], true) + .then(() => { + this.scene.ui.setMode(messageMode).then(() => { + this.scene.playSound("level_up_fanfare"); + this.scene.ui.showText(i18next.t("battle:learnMove", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }), null, () => { + this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeMoveLearnedTrigger, true); + this.end(); + }, messageMode === Mode.EVOLUTION_SCENE ? 1000 : null, true); + }); + }); + }); + } else if (move.isUnimplemented() && false) { + this.scene.ui.setMode(messageMode).then(() => { + this.scene.ui.showText(i18next.t("battle:learnMovePrompt", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }), null, () => { + this.scene.ui.showText(i18next.t("battle:learnMoveLimitReached", { pokemonName: getPokemonNameWithAffix(pokemon) }), null, () => { + this.scene.ui.showText(i18next.t("battle:learnMoveReplaceQuestion", { moveName: move.name }), null, () => { + const noHandler = () => { + this.scene.ui.setMode(messageMode).then(() => { + this.scene.ui.showText(i18next.t("battle:learnMoveStopTeaching", { moveName: move.name }), null, () => { + this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => { + this.scene.ui.setMode(messageMode); + this.scene.ui.showText(i18next.t("battle:learnMoveNotLearned", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }), null, () => this.end(), null, true); + }, () => { + this.scene.ui.setMode(messageMode); + this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.partyMemberIndex, this.moveId)); + this.end(); + }); + }); + }); + }; + this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => { + this.scene.ui.setMode(messageMode); + this.scene.ui.showText(i18next.t("battle:learnMoveForgetQuestion"), null, () => { + this.scene.ui.setModeWithoutClear(Mode.SUMMARY, this.getPokemon(), SummaryUiMode.LEARN_MOVE, move, (moveIndex: integer) => { + if (moveIndex === 4) { + noHandler(); + return; + } + this.scene.ui.setMode(messageMode).then(() => { + this.scene.ui.showText(i18next.t("battle:countdownPoof"), null, () => { + this.scene.ui.showText(i18next.t("battle:learnMoveForgetSuccess", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: pokemon.moveset[moveIndex]!.getName() }), null, () => { // TODO: is the bang correct? + this.scene.ui.showText(i18next.t("battle:learnMoveAnd"), null, () => { + if (this.fromTM) { + if (!pokemon.usedTMs) { + pokemon.usedTMs = []; + } + pokemon.usedTMs.push(this.moveId); + } + pokemon.setMove(moveIndex, Moves.NONE); + this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.partyMemberIndex, this.moveId)); + this.end(); + }, null, true); + }, null, true); + }, null, true); + }); + }); + }, null, true); + }, noHandler); + }); + }, null, true); + }, null, true); + }); } else { this.replaceMoveCheck(move, pokemon); } diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index 25a9b1e91a2..f948377def4 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -205,7 +205,7 @@ export class MovePhase extends BattlePhase { let success = this.move.getMove().applyConditions(this.pokemon, targets[0], this.move.getMove()); const cancelled = new Utils.BooleanHolder(false); let failedText = this.move.getMove().getFailedText(this.pokemon, targets[0], this.move.getMove(), cancelled); - if (success && this.scene.arena.isMoveWeatherCancelled(this.move.getMove())) { + if (success && this.scene.arena.isMoveWeatherCancelled(this.pokemon, this.move.getMove())) { success = false; } else if (success && this.scene.arena.isMoveTerrainCancelled(this.pokemon, this.targets, this.move.getMove())) { success = false; @@ -251,7 +251,7 @@ export class MovePhase extends BattlePhase { switch (this.pokemon.status.effect) { case StatusEffect.PARALYSIS: - if (!this.pokemon.randSeedInt(4, undefined, "Paralysis chance")) { + if (!this.pokemon.randSeedInt(4, undefined, "Chance to be immobilized by Paralysis")) { activated = true; this.cancelled = true; } diff --git a/src/phases/scan-ivs-phase.ts b/src/phases/scan-ivs-phase.ts index d02813dab12..e2320eda9a5 100644 --- a/src/phases/scan-ivs-phase.ts +++ b/src/phases/scan-ivs-phase.ts @@ -52,7 +52,6 @@ export class ScanIvsPhase extends PokemonPhase { if (!this.scene.hideIvs) { this.scene.ui.showText(i18next.t("battle:ivScannerUseQuestion", { pokemonName: getPokemonNameWithAffix(pokemon) }), null, () => { this.scene.ui.setMode(Mode.CONFIRM, () => { - LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, "IV Scanner → " + LoggerTools.enemyPokeName(this.scene, pokemon)) this.scene.ui.setMode(Mode.MESSAGE); this.scene.ui.clearText(); new CommonBattleAnim(CommonAnim.LOCK_ON, pokemon, pokemon).play(this.scene, () => { diff --git a/src/phases/select-biome-phase.ts b/src/phases/select-biome-phase.ts index 5da26ce02f0..2c892131df3 100644 --- a/src/phases/select-biome-phase.ts +++ b/src/phases/select-biome-phase.ts @@ -39,7 +39,7 @@ export class SelectBiomePhase extends BattlePhase { let biomes: Biome[] = []; this.scene.executeWithSeedOffset(() => { biomes = (biomeLinks[currentBiome] as (Biome | [Biome, integer])[]) - .filter(b => !Array.isArray(b) || !Utils.randSeedInt(b[1])) + .filter(b => !Array.isArray(b) || !Utils.randSeedInt(b[1], undefined, "Choosing next biome")) .map(b => !Array.isArray(b) ? b : b[0]); }, this.scene.currentBattle.waveIndex); if (biomes.length > 1 && this.scene.findModifier(m => m instanceof MapModifier)) { @@ -48,7 +48,7 @@ export class SelectBiomePhase extends BattlePhase { biomeChoices = (!Array.isArray(biomeLinks[currentBiome]) ? [biomeLinks[currentBiome] as Biome] : biomeLinks[currentBiome] as (Biome | [Biome, integer])[]) - .filter((b, i) => !Array.isArray(b) || !Utils.randSeedInt(b[1])) + .filter((b, i) => !Array.isArray(b) || !Utils.randSeedInt(b[1], undefined, "Choosing next biome for map")) .map(b => Array.isArray(b) ? b[0] : b); }, this.scene.currentBattle.waveIndex); const biomeSelectItems = biomeChoices.map(b => { @@ -67,7 +67,7 @@ export class SelectBiomePhase extends BattlePhase { delay: 1000 }); } else { - setNextBiome(biomes[Utils.randSeedInt(biomes.length)]); + setNextBiome(biomes[Utils.randSeedInt(biomes.length, undefined, "Choosing biome randomly")]); } } else if (biomeLinks.hasOwnProperty(currentBiome)) { setNextBiome(biomeLinks[currentBiome] as Biome); diff --git a/src/phases/select-modifier-phase.ts b/src/phases/select-modifier-phase.ts index 90ea9eb80a8..5600344d395 100644 --- a/src/phases/select-modifier-phase.ts +++ b/src/phases/select-modifier-phase.ts @@ -327,7 +327,7 @@ export class SelectModifierPhase extends BattlePhase { // costTiers console.log("Rerolls: " + r + (this.costTiers[r] != 0 ? " - ₽" + this.costTiers[r] : "")) mp.forEach((m, i) => { - console.log(" " + m.type!.name + (m.netprice != this.costTiers[r] ? " - ₽" + m.netprice : "")) + console.log(" " + m.type!.name + (m.netprice != this.costTiers[r] ? " - ₽" + m.netprice : "") + " (" + (m.retriesList.length) + " tr" + (m.retriesList.length == 1 ? "y" : "ies") + ")") if (m.eviolite) { console.log(" With Eviolite unlocked: " + m.eviolite.name) } @@ -348,7 +348,7 @@ export class SelectModifierPhase extends BattlePhase { showedLuckFlag = true console.log(" Your luck: " + getPartyLuckValue(party) + " (" + getLuckString(getPartyLuckValue(party)) + ")") } - console.log(" At " + j + " luck (" + getLuckString(j) + "): " + LoggerTools.tierNames[currentTier] + "-tier item (failed to generate item)") + console.log(" At " + j + " luck (" + getLuckString(j) + "): " + LoggerTools.tierNames[currentTier] + "-tier item")// (failed to generate item) } } } diff --git a/src/phases/title-phase.ts b/src/phases/title-phase.ts index dfa180b320a..8288f2aece9 100644 --- a/src/phases/title-phase.ts +++ b/src/phases/title-phase.ts @@ -37,22 +37,6 @@ export class TitlePhase extends Phase { this.loaded = false; } - setBiomeByType(biome: Biome, override?: boolean): void { - if (!this.scene.menuChangesBiome && !override) - return; - this.scene.arenaBg.setTexture(`${getBiomeKey(biome)}_bg`); - } - setBiomeByName(biome: string, override?: boolean): void { - if (!this.scene.menuChangesBiome && !override) - return; - this.scene.arenaBg.setTexture(`${getBiomeKey(Utils.getEnumValues(Biome)[Utils.getEnumKeys(Biome).indexOf(biome)])}_bg`); - } - setBiomeByFile(sessionData: SessionSaveData, override?: boolean): void { - if (!this.scene.menuChangesBiome && !override) - return; - this.scene.arenaBg.setTexture(`${getBiomeKey(sessionData.arena.biome)}_bg`); - } - confirmSlot = (message: string, slotFilter: (i: integer) => boolean, callback: (i: integer) => void) => { const p = this; this.scene.ui.revertMode(); @@ -85,20 +69,18 @@ export class TitlePhase extends Phase { start(): void { super.start(); - //console.log(LoggerTools.importDocument(JSON.stringify(LoggerTools.newDocument()))) this.scene.ui.clearText(); this.scene.ui.fadeIn(250); this.scene.playBgm("title", true); - this.scene.biomeChangeMode = false - this.scene.gameData.getSession(loggedInUser?.lastSessionSlot ?? -1).then(sessionData => { if (sessionData) { this.lastSessionData = sessionData; - this.setBiomeByFile(sessionData, true) - this.setBiomeByType(Biome.END) + const biomeKey = getBiomeKey(sessionData.arena.biome); + const bgTexture = `${biomeKey}_bg`; + this.scene.arenaBg.setTexture(bgTexture); } this.showOptions(); }).catch(err => { @@ -268,7 +250,6 @@ export class TitlePhase extends Phase { } showOptions(): void { - this.scene.biomeChangeMode = true const options: OptionSelectItem[] = []; if (false) if (loggedInUser && loggedInUser!.lastSessionSlot > -1) { @@ -344,8 +325,6 @@ export class TitlePhase extends Phase { options.push({ label: i18next.t("menu:newGame"), handler: () => { - this.scene.biomeChangeMode = false - this.setBiomeByType(Biome.TOWN) const setModeAndEnd = (gameMode: GameModes) => { this.gameMode = gameMode; this.scene.ui.setMode(Mode.MESSAGE); @@ -437,7 +416,6 @@ export class TitlePhase extends Phase { }, { label: "Manage Logs", handler: () => { - this.scene.biomeChangeMode = false //return this.logRenameMenu() this.scene.ui.setOverlayMode(Mode.LOG_HANDLER, (k: string) => { @@ -475,7 +453,6 @@ export class TitlePhase extends Phase { options.push({ label: i18next.t("menu:dailyRun"), handler: () => { - this.scene.biomeChangeMode = false this.setupDaily(); return true; }, @@ -485,7 +462,6 @@ export class TitlePhase extends Phase { options.push({ label: i18next.t("menu:settings"), handler: () => { - this.scene.biomeChangeMode = false this.scene.ui.setOverlayMode(Mode.SETTINGS); return true; }, @@ -634,7 +610,6 @@ export class TitlePhase extends Phase { confirmSlot("Select a slot to replace.", () => true, slotId => this.scene.gameData.importData(GameDataType.SESSION, slotId)); } end(): void { - this.scene.biomeChangeMode = false if (!this.loaded && !this.scene.gameMode.isDaily) { this.scene.arena.preloadBgm(); this.scene.gameMode = getGameMode(this.gameMode); diff --git a/src/phases/trainer-victory-phase.ts b/src/phases/trainer-victory-phase.ts index 1f3de6433c7..04bed55ea0f 100644 --- a/src/phases/trainer-victory-phase.ts +++ b/src/phases/trainer-victory-phase.ts @@ -38,7 +38,7 @@ export class TrainerVictoryPhase extends BattlePhase { this.scene.ui.showText(i18next.t("battle:trainerDefeated", { trainerName: this.scene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) }), null, () => { const victoryMessages = this.scene.currentBattle.trainer?.getVictoryMessages()!; // TODO: is this bang correct? let message: string; - this.scene.executeWithSeedOffset(() => message = Utils.randSeedItem(victoryMessages), this.scene.currentBattle.waveIndex); + this.scene.executeWithSeedOffset(() => message = Utils.randSeedItem(victoryMessages, "Victory message"), this.scene.currentBattle.waveIndex); message = message!; // tell TS compiler it's defined now const showMessage = () => { diff --git a/src/phases/turn-init-phase.ts b/src/phases/turn-init-phase.ts index 0e946042f5c..23e3d1ba684 100644 --- a/src/phases/turn-init-phase.ts +++ b/src/phases/turn-init-phase.ts @@ -124,7 +124,7 @@ export class TurnInitPhase extends FieldPhase { pokemon.getBattleInfo().displayParty((this.scene.currentBattle.double ? Pt1 : Pt)) } } - }) + }); this.scene.pushPhase(new TurnStartPhase(this.scene)); diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index f0bebd0b8ff..52a9b08d5db 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -17,8 +17,9 @@ import { PostTurnStatusEffectPhase } from "./post-turn-status-effect-phase"; import { SwitchSummonPhase } from "./switch-summon-phase"; import { TurnEndPhase } from "./turn-end-phase"; import { WeatherEffectPhase } from "./weather-effect-phase"; +import { BattlerIndex, TurnCommand } from "#app/battle"; +import { TrickRoomTag } from "#app/data/arena-tag"; import * as LoggerTools from "../logger"; -import { TurnCommand } from "#app/battle.js"; export class TurnStartPhase extends FieldPhase { constructor(scene: BattleScene) { @@ -49,19 +50,58 @@ export class TurnStartPhase extends FieldPhase { targIDs[3] = eField[0].name if (eField[1]) targIDs[4] = eField[1].name - //LoggerTools.Actions[pokemon.getBattlerIndex()] += " → " + targets.map(v => targIDs[v+1]) + LoggerTools.Actions[pokemon.getBattlerIndex()] += " → " + targets.map(v => targIDs[v+1]) } console.log(mv.getName(), targets) } } } - start() { - super.start(); + /** + * This orders the active Pokemon on the field by speed into an BattlerIndex array and returns that array. + * It also checks for Trick Room and reverses the array if it is present. + * @returns {@linkcode BattlerIndex[]} the battle indices of all pokemon on the field ordered by speed + */ + getSpeedOrder(): BattlerIndex[] { + const playerField = this.scene.getPlayerField().filter(p => p.isActive()) as Pokemon[]; + const enemyField = this.scene.getEnemyField().filter(p => p.isActive()) as Pokemon[]; - const field = this.scene.getField(); - const order = this.getOrder(); + // We shuffle the list before sorting so speed ties produce random results + let orderedTargets: Pokemon[] = playerField.concat(enemyField); + // We seed it with the current turn to prevent an inconsistency where it + // was varying based on how long since you last reloaded + this.scene.executeWithSeedOffset(() => { + orderedTargets = Utils.randSeedShuffle(orderedTargets); + }, this.scene.currentBattle.turn, this.scene.waveSeed); + orderedTargets.sort((a: Pokemon, b: Pokemon) => { + const aSpeed = a?.getEffectiveStat(Stat.SPD) || 0; + const bSpeed = b?.getEffectiveStat(Stat.SPD) || 0; + + return bSpeed - aSpeed; + }); + + // Next, a check for Trick Room is applied. If Trick Room is present, the order is reversed. + const speedReversed = new Utils.BooleanHolder(false); + this.scene.arena.applyTags(TrickRoomTag, speedReversed); + + if (speedReversed.value) { + orderedTargets = orderedTargets.reverse(); + } + + return orderedTargets.map(t => t.getFieldIndex() + (!t.isPlayer() ? BattlerIndex.ENEMY : BattlerIndex.PLAYER)); + } + + /** + * This takes the result of getSpeedOrder and applies priority / bypass speed attributes to it. + * This also considers the priority levels of various commands and changes the result of getSpeedOrder based on such. + * @returns {@linkcode BattlerIndex[]} the final sequence of commands for this turn + */ + getCommandOrder(): BattlerIndex[] { + let moveOrder = this.getSpeedOrder(); + // The creation of the battlerBypassSpeed object contains checks for the ability Quick Draw and the held item Quick Claw + // The ability Mycelium Might disables Quick Claw's activation when using a status move + // This occurs before the main loop because of battles with more than two Pokemon const battlerBypassSpeed = {}; this.scene.getField(true).filter(p => p.summonData).map(p => { @@ -75,8 +115,9 @@ export class TurnStartPhase extends FieldPhase { battlerBypassSpeed[p.getBattlerIndex()] = bypassSpeed; }); - const moveOrder = order.slice(0); - + // The function begins sorting orderedTargets based on command priority, move priority, and possible speed bypasses. + // Non-FIGHT commands (SWITCH, BALL, RUN) have a higher command priority and will always occur before any FIGHT commands. + moveOrder = moveOrder.slice(0); moveOrder.sort((a, b) => { const aCommand = this.scene.currentBattle.turnCommands[a]; const bCommand = this.scene.currentBattle.turnCommands[b]; @@ -88,37 +129,50 @@ export class TurnStartPhase extends FieldPhase { return -1; } } else if (aCommand?.command === Command.FIGHT) { - const aMove = allMoves[aCommand.move!.move];//TODO: is the bang correct here? - const bMove = allMoves[bCommand!.move!.move];//TODO: is the bang correct here? + const aMove = allMoves[aCommand.move!.move]; + const bMove = allMoves[bCommand!.move!.move]; + // The game now considers priority and applies the relevant move and ability attributes const aPriority = new Utils.IntegerHolder(aMove.priority); const bPriority = new Utils.IntegerHolder(bMove.priority); - applyMoveAttrs(IncrementMovePriorityAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === a)!, null, aMove, aPriority); //TODO: is the bang correct here? - applyMoveAttrs(IncrementMovePriorityAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === b)!, null, bMove, bPriority); //TODO: is the bang correct here? + applyMoveAttrs(IncrementMovePriorityAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === a)!, null, aMove, aPriority); + applyMoveAttrs(IncrementMovePriorityAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === b)!, null, bMove, bPriority); - applyAbAttrs(ChangeMovePriorityAbAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === a)!, null, false, aMove, aPriority); //TODO: is the bang correct here? - applyAbAttrs(ChangeMovePriorityAbAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === b)!, null, false, bMove, bPriority); //TODO: is the bang correct here? + applyAbAttrs(ChangeMovePriorityAbAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === a)!, null, false, aMove, aPriority); + applyAbAttrs(ChangeMovePriorityAbAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === b)!, null, false, bMove, bPriority); + // The game now checks for differences in priority levels. + // If the moves share the same original priority bracket, it can check for differences in battlerBypassSpeed and return the result. + // This conditional is used to ensure that Quick Claw can still activate with abilities like Stall and Mycelium Might (attack moves only) + // Otherwise, the game returns the user of the move with the highest priority. + const isSameBracket = Math.ceil(aPriority.value) - Math.ceil(bPriority.value) === 0; if (aPriority.value !== bPriority.value) { - const bracketDifference = Math.ceil(aPriority.value) - Math.ceil(bPriority.value); - const hasSpeedDifference = battlerBypassSpeed[a].value !== battlerBypassSpeed[b].value; - if (bracketDifference === 0 && hasSpeedDifference) { + if (isSameBracket && battlerBypassSpeed[a].value !== battlerBypassSpeed[b].value) { return battlerBypassSpeed[a].value ? -1 : 1; } return aPriority.value < bPriority.value ? 1 : -1; } } + // If there is no difference between the move's calculated priorities, the game checks for differences in battlerBypassSpeed and returns the result. if (battlerBypassSpeed[a].value !== battlerBypassSpeed[b].value) { return battlerBypassSpeed[a].value ? -1 : 1; } - const aIndex = order.indexOf(a); - const bIndex = order.indexOf(b); + const aIndex = moveOrder.indexOf(a); + const bIndex = moveOrder.indexOf(b); return aIndex < bIndex ? -1 : aIndex > bIndex ? 1 : 0; }); + return moveOrder; + } + + start() { + super.start(); + + const field = this.scene.getField(); + const moveOrder = this.getCommandOrder(); let orderIndex = 0; @@ -138,6 +192,7 @@ export class TurnStartPhase extends FieldPhase { if (!queuedMove) { continue; } + LoggerTools.Actions[pokemon.getBattlerIndex()] = `[[ ${new PokemonMove(queuedMove.move).getName()} unknown target ]]` const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move) || new PokemonMove(queuedMove.move); if (move.getMove().hasAttr(MoveHeaderAttr)) { this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move)); @@ -166,6 +221,7 @@ export class TurnStartPhase extends FieldPhase { } break; case Command.RUN: + LoggerTools.Actions[pokemon.getBattlerIndex()] = "Run from battle" let runningPokemon = pokemon; if (this.scene.currentBattle.double) { const playerActivePokemon = field.filter(pokemon => { @@ -189,167 +245,6 @@ export class TurnStartPhase extends FieldPhase { } } - - this.scene.pushPhase(new WeatherEffectPhase(this.scene)); - - for (const o of order) { - if (field[o].status && field[o].status.isPostTurn()) { - this.scene.pushPhase(new PostTurnStatusEffectPhase(this.scene, o)); - } - } - - this.scene.pushPhase(new BerryPhase(this.scene)); - this.scene.pushPhase(new TurnEndPhase(this.scene)); - - this.scene.arenaFlyout.updateFieldText(); - - if (LoggerTools.Actions.length > 1 && !this.scene.currentBattle.double) { - LoggerTools.Actions.pop() // If this is a single battle, but we somehow have two actions, delete the second - } - if (LoggerTools.Actions.length > 1 && (LoggerTools.Actions[0] == "" || LoggerTools.Actions[0] == undefined || LoggerTools.Actions[0] == null)) - LoggerTools.Actions.shift() // If the left slot isn't doing anything, delete its entry - LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, LoggerTools.Actions.join(" & ")) - - /** - * this.end() will call shiftPhase(), which dumps everything from PrependQueue (aka everything that is unshifted()) to the front - * of the queue and dequeues to start the next phase - * this is important since stuff like SwitchSummon, AttemptRun, AttemptCapture Phases break the "flow" and should take precedence - */ - this.end(); - } - - /* - start() { - super.start(); - - const field = this.scene.getField(); - const order = this.getOrder(); - - let orderIndex = 0; - - for (const o of moveOrder) { - - const pokemon = field[o]; - const turnCommand = this.scene.currentBattle.turnCommands[o]; - - if (turnCommand?.skip) { - continue; - } - - switch (turnCommand?.command) { - case Command.FIGHT: - const queuedMove = turnCommand.move; - pokemon.turnData.order = orderIndex++; - if (!queuedMove) { - continue; - } - const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move) || new PokemonMove(queuedMove.move); - if (move.getMove().hasAttr(MoveHeaderAttr)) { - this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move)); - } - if (pokemon.isPlayer()) { - if (turnCommand.cursor === -1) { - //console.log("turncommand cursor was -1 -- running TOP block") - this.scene.pushPhase(new MovePhase(this.scene, pokemon, turnCommand.targets || turnCommand.move!.targets, move));//TODO: is the bang correct here? - var targets = turnCommand.targets || turnCommand.move!.targets - var mv = move - if (pokemon.isPlayer()) { - console.log(turnCommand.targets, turnCommand.move!.targets) - LoggerTools.Actions[pokemon.getBattlerIndex()] = mv.getName() - if (this.scene.currentBattle.double) { - var targIDs = ["Self", "Self", "Ally", "L", "R"] - if (pokemon.getBattlerIndex() == 1) targIDs = ["Self", "Ally", "Self", "L", "R"] - LoggerTools.Actions[pokemon.getBattlerIndex()] += " → " + targets.map(v => targIDs[v+1]) - } else { - var targIDs = ["Self", "", "", "", ""] - var myField = this.scene.getField() - if (myField[0]) - targIDs[1] = myField[0].name - if (myField[1]) - targIDs[2] = myField[1].name - var eField = this.scene.getEnemyField() - if (eField[0]) - targIDs[3] = eField[0].name - if (eField[1]) - targIDs[4] = eField[1].name - //LoggerTools.Actions[pokemon.getBattlerIndex()] += " → " + targets.map(v => targIDs[v+1]) - } - console.log(mv.getName(), targets) - } - } else { - //console.log("turncommand = ", turnCommand, " -- running BOTTOM block") - const playerPhase = new MovePhase(this.scene, pokemon, turnCommand.targets || turnCommand.move!.targets, move, false, queuedMove.ignorePP);//TODO: is the bang correct here? - var targets = turnCommand.targets || turnCommand.move!.targets - var mv = move - if (pokemon.isPlayer()) { - console.log(turnCommand.targets, turnCommand.move!.targets) - if (turnCommand.args && turnCommand.args[1] && turnCommand.args[1].isContinuing != undefined) { - console.log(mv.getName(), targets) - } else { - LoggerTools.Actions[pokemon.getBattlerIndex()] = mv.getName() - if (this.scene.currentBattle.double) { - var targIDs = ["Self", "Self", "Ally", "L", "R"] - if (pokemon.getBattlerIndex() == 1) targIDs = ["Self", "Ally", "Self", "L", "R"] - LoggerTools.Actions[pokemon.getBattlerIndex()] += " → " + targets.map(v => targIDs[v+1]) - } else { - var targIDs = ["Self", "", "", "", ""] - var myField = this.scene.getField() - if (myField[0]) - targIDs[1] = myField[0].name - if (myField[1]) - targIDs[2] = myField[1].name - var eField = this.scene.getEnemyField() - if (eField[0]) - targIDs[3] = eField[0].name - if (eField[1]) - targIDs[4] = eField[1].name - //LoggerTools.Actions[pokemon.getBattlerIndex()] += " → " + targets.map(v => targIDs[v+1]) - } - console.log(mv.getName(), targets) - } - } - this.scene.pushPhase(playerPhase); - } - } else { - this.scene.pushPhase(new MovePhase(this.scene, pokemon, turnCommand.targets || turnCommand.move!.targets, move, false, queuedMove.ignorePP));//TODO: is the bang correct here? - var targets = turnCommand.targets || turnCommand.move!.targets - var mv = new PokemonMove(queuedMove.move) - } - break; - case Command.BALL: - this.scene.unshiftPhase(new AttemptCapturePhase(this.scene, turnCommand.targets![0] % 2, turnCommand.cursor!));//TODO: is the bang correct here? - break; - case Command.POKEMON: - if (pokemon.isPlayer()) { - // " " + LoggerTools.playerPokeName(this.scene, pokemon) + - LoggerTools.Actions[pokemon.getBattlerIndex()] = ((turnCommand.args![0] as boolean) ? "Baton" : "Switch") + " to " + LoggerTools.playerPokeName(this.scene, turnCommand.cursor!) - } - this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, pokemon.getFieldIndex(), turnCommand.cursor!, true, turnCommand.args![0] as boolean, pokemon.isPlayer()));//TODO: is the bang correct here? - break; - case Command.RUN: - let runningPokemon = pokemon; - if (this.scene.currentBattle.double) { - const playerActivePokemon = field.filter(pokemon => { - if (!!pokemon) { - return pokemon.isPlayer() && pokemon.isActive(); - } else { - return; - } - }); - // if only one pokemon is alive, use that one - if (playerActivePokemon.length > 1) { - // find which active pokemon has faster speed - const fasterPokemon = playerActivePokemon[0].getStat(Stat.SPD) > playerActivePokemon[1].getStat(Stat.SPD) ? playerActivePokemon[0] : playerActivePokemon[1]; - // check if either active pokemon has the ability "Run Away" - const hasRunAway = playerActivePokemon.find(p => p.hasAbility(Abilities.RUN_AWAY)); - runningPokemon = hasRunAway !== undefined ? hasRunAway : fasterPokemon; - } - } - this.scene.unshiftPhase(new AttemptRunPhase(this.scene, runningPokemon.getFieldIndex())); - break; - } - } - this.scene.pushPhase(new WeatherEffectPhase(this.scene)); for (const o of moveOrder) { @@ -371,12 +266,10 @@ export class TurnStartPhase extends FieldPhase { LoggerTools.logActions(this.scene, this.scene.currentBattle.waveIndex, LoggerTools.Actions.join(" & ")) /** - * this.end() will call shiftPhase(), which dumps everything from PrependQueue (aka everything that is unshifted()) to the front - * of the queue and dequeues to start the next phase - * this is important since stuff like SwitchSummon, AttemptRun, AttemptCapture Phases break the "flow" and should take precedence - */ - /* + * this.end() will call shiftPhase(), which dumps everything from PrependQueue (aka everything that is unshifted()) to the front + * of the queue and dequeues to start the next phase + * this is important since stuff like SwitchSummon, AttemptRun, AttemptCapture Phases break the "flow" and should take precedence + */ this.end(); } - */ } diff --git a/src/system/achv.ts b/src/system/achv.ts index 89e5493eb2e..6170fe23e1d 100644 --- a/src/system/achv.ts +++ b/src/system/achv.ts @@ -7,7 +7,7 @@ import * as Utils from "../utils"; import { PlayerGender } from "#enums/player-gender"; import { Challenge, FreshStartChallenge, SingleGenerationChallenge, SingleTypeChallenge, InverseBattleChallenge } from "#app/data/challenge"; import { ConditionFn } from "#app/@types/common"; -import { Stat, getShortenedStatKey } from "#app/enums/stat"; +import { Stat, getShortenedStatKey } from "#app/enums/stat"; import { Challenges } from "#app/enums/challenges"; export enum AchvTier { @@ -197,7 +197,7 @@ export function getAchievementDescription(localizationKey: string): string { case "100_RIBBONS": return i18next.t("achv:RibbonAchv.description", {context: genderStr, "ribbonAmount": achvs._100_RIBBONS.ribbonAmount.toLocaleString("en-US")}); case "TRANSFER_MAX_STAT_STAGE": - return i18next.t("achv:TRANSFER_MAX_BATTLE_STAT.description", { context: genderStr }); + return i18next.t("achv:TRANSFER_MAX_STAT_STAGE.description", { context: genderStr }); case "MAX_FRIENDSHIP": return i18next.t("achv:MAX_FRIENDSHIP.description", { context: genderStr }); case "MEGA_EVOLVE": diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 588d0f4e3fa..4e9ca6155ca 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -31,8 +31,8 @@ import { Variant } from "#app/data/variant"; import {setSettingGamepad, SettingGamepad, settingGamepadDefaults} from "./settings/settings-gamepad"; import {setSettingKeyboard, SettingKeyboard} from "#app/system/settings/settings-keyboard"; import { TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena"; -import * as Modifier from "../modifier/modifier"; import { StatusEffect } from "#app/data/status-effect"; +import { EnemyAttackStatusEffectChanceModifier } from "../modifier/modifier"; import ChallengeData from "./challenge-data"; import { Device } from "#enums/devices"; import { GameDataType } from "#enums/game-data-type"; @@ -327,8 +327,8 @@ export class GameData { this.loadSettings(); this.loadGamepadSettings(); this.loadMappingConfigs(); - this.trainerId = Utils.randInt(65536); - this.secretId = Utils.randInt(65536); + this.trainerId = Utils.randInt(65536, undefined, "Trainer ID"); + this.secretId = Utils.randInt(65536, undefined, "Secret ID"); this.starterData = {}; this.gameStats = new GameStats(); this.runHistory = {}; @@ -1085,8 +1085,10 @@ export class GameData { // TODO //scene.arena.tags = sessionData.arena.tags; + const modifiersModule = await import("../modifier/modifier"); + for (const modifierData of sessionData.modifiers) { - const modifier = modifierData.toModifier(scene, Modifier[modifierData.className]); + const modifier = modifierData.toModifier(scene, modifiersModule[modifierData.className]); if (modifier) { scene.addModifier(modifier, true); } @@ -1095,7 +1097,7 @@ export class GameData { scene.updateModifiers(true); for (const enemyModifierData of sessionData.enemyModifiers) { - const modifier = enemyModifierData.toModifier(scene, Modifier[enemyModifierData.className]); + const modifier = enemyModifierData.toModifier(scene, modifiersModule[enemyModifierData.className]); if (modifier) { scene.addEnemyModifier(modifier, true); } @@ -1251,7 +1253,7 @@ export class GameData { if (md?.className === "ExpBalanceModifier") { // Temporarily limit EXP Balance until it gets reworked md.stackCount = Math.min(md.stackCount, 4); } - if (md instanceof Modifier.EnemyAttackStatusEffectChanceModifier && md.effect === StatusEffect.FREEZE || md.effect === StatusEffect.SLEEP) { + if (md instanceof EnemyAttackStatusEffectChanceModifier && md.effect === StatusEffect.FREEZE || md.effect === StatusEffect.SLEEP) { continue; } ret.push(new PersistentModifierData(md, player)); @@ -1507,7 +1509,7 @@ export class GameData { this.scene.executeWithSeedOffset(() => { const neutralNatures = [ Nature.HARDY, Nature.DOCILE, Nature.SERIOUS, Nature.BASHFUL, Nature.QUIRKY ]; for (let s = 0; s < defaultStarterSpecies.length; s++) { - defaultStarterNatures.push(Utils.randSeedItem(neutralNatures)); + defaultStarterNatures.push(Utils.randSeedItem(neutralNatures, "Random neutral nature")); } }, 0, "default"); @@ -1862,7 +1864,7 @@ export class GameData { entry.hatchedCount = 0; } if (!entry.hasOwnProperty("natureAttr") || (entry.caughtAttr && !entry.natureAttr)) { - entry.natureAttr = this.defaultDexData?.[k].natureAttr || (1 << Utils.randInt(25, 1)); + entry.natureAttr = this.defaultDexData?.[k].natureAttr || (1 << Utils.randInt(25, 1, "Random bit shift")); } } } diff --git a/src/system/version-converter.ts b/src/system/version-converter.ts index ed65fcd99b8..70fe1ee56c3 100644 --- a/src/system/version-converter.ts +++ b/src/system/version-converter.ts @@ -22,16 +22,26 @@ export function applySessionDataPatches(data: SessionSaveData) { } else if (m.className === "PokemonResetNegativeStatStageModifier") { m.className = "ResetNegativeStatStageModifier"; } else if (m.className === "TempBattleStatBoosterModifier") { - m.className = "TempStatStageBoosterModifier"; - m.typeId = "TEMP_STAT_STAGE_BOOSTER"; + // Dire Hit no longer a part of the TempBattleStatBoosterModifierTypeGenerator + if (m.typeId !== "DIRE_HIT") { + m.className = "TempStatStageBoosterModifier"; + m.typeId = "TEMP_STAT_STAGE_BOOSTER"; - // Migration from TempBattleStat to Stat - const newStat = m.typePregenArgs[0] + 1; - m.typePregenArgs[0] = newStat; + // Migration from TempBattleStat to Stat + const newStat = m.typePregenArgs[0] + 1; + m.typePregenArgs[0] = newStat; - // From [ stat, battlesLeft ] to [ stat, maxBattles, battleCount ] - m.args = [ newStat, 5, m.args[1] ]; - } else if (m.className === "DoubleBattleChanceBoosterModifier") { + // From [ stat, battlesLeft ] to [ stat, maxBattles, battleCount ] + m.args = [ newStat, 5, m.args[1] ]; + } else { + m.className = "TempCritBoosterModifier"; + m.typePregenArgs = []; + + // From [ stat, battlesLeft ] to [ maxBattles, battleCount ] + m.args = [ 5, m.args[1] ]; + } + + } else if (m.className === "DoubleBattleChanceBoosterModifier" && m.args.length === 1) { let maxBattles: number; switch (m.typeId) { case "MAX_LURE": @@ -53,6 +63,8 @@ export function applySessionDataPatches(data: SessionSaveData) { data.enemyModifiers.forEach((m) => { if (m.className === "PokemonBaseStatModifier") { m.className = "BaseStatModifier"; + } else if (m.className === "PokemonResetNegativeStatStageModifier") { + m.className = "ResetNegativeStatStageModifier"; } }); } @@ -71,7 +83,7 @@ export function applySystemDataPatches(data: SystemSaveData) { case "1.0.3": case "1.0.4": // --- LEGACY PATCHES --- - if (data.starterData) { + if (data.starterData && data.dexData) { // Migrate ability starter data if empty for caught species Object.keys(data.starterData).forEach(sd => { if (data.dexData[sd].caughtAttr && !data.starterData[sd].abilityAttr) { @@ -102,10 +114,14 @@ export function applySystemDataPatches(data: SystemSaveData) { // --- PATCHES --- // Fix Starter Data - if (data.gameVersion) { + if (data.starterData && data.dexData) { for (const starterId of defaultStarterSpecies) { - data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1; - data.dexData[starterId].caughtAttr |= DexAttr.FEMALE; + if (data.starterData[starterId]?.abilityAttr) { + data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1; + } + if (data.dexData[starterId]?.caughtAttr) { + data.dexData[starterId].caughtAttr |= DexAttr.FEMALE; + } } } } diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index 874bf6a8b46..9bfa3bdf54a 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -25,14 +25,14 @@ interface TimedEvent extends EventBanner { const timedEvents: TimedEvent[] = [ { - name: "September Update", + name: "Egg Skip Update", eventType: EventType.GENERIC, - startDate: new Date(Date.UTC(2024, 7, 28, 0)), - endDate: new Date(Date.UTC(2024, 8, 15, 0)), - bannerKey: "september-update", + startDate: new Date(Date.UTC(2024, 8, 8, 0)), + endDate: new Date(Date.UTC(2024, 8, 12, 0)), + bannerKey: "egg-update", xPosition: 19, - yPosition: 115, - scale: 0.30, + yPosition: 120, + scale: 0.21, availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN"] } ]; @@ -94,9 +94,9 @@ export class TimedEventDisplay extends Phaser.GameObjects.Container { let key = this.event.bannerKey; if (lang && this.event.availableLangs && this.event.availableLangs.length > 0) { if (this.event.availableLangs.includes(lang)) { - key += "-"+lang; + key += "_"+lang; } else { - key += "-en"; + key += "_en"; } } console.log(this.event.bannerKey); diff --git a/src/ui-inputs.ts b/src/ui-inputs.ts index 46f6b100f51..54cbaa34a47 100644 --- a/src/ui-inputs.ts +++ b/src/ui-inputs.ts @@ -133,7 +133,7 @@ export class UiInputs { buttonStats(pressed: boolean = true): void { // allow access to Button.STATS as a toggle for other elements for (const t of this.scene.getInfoToggles(true)) { - t.toggleInfo(pressed,); + t.toggleInfo(pressed); } // handle normal pokemon battle ui for (const p of this.scene.getField().filter(p => p?.isActive(true))) { diff --git a/src/ui/egg-gacha-ui-handler.ts b/src/ui/egg-gacha-ui-handler.ts index c2e5dd77e5e..bd17406bdce 100644 --- a/src/ui/egg-gacha-ui-handler.ts +++ b/src/ui/egg-gacha-ui-handler.ts @@ -571,6 +571,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { this.updateGachaIcon(infoContainer, 2) this.updateGachaIcon(infoContainer, 3) } + break; } } diff --git a/src/ui/form-modal-ui-handler.ts b/src/ui/form-modal-ui-handler.ts index 8c4ea5f6768..331154263ad 100644 --- a/src/ui/form-modal-ui-handler.ts +++ b/src/ui/form-modal-ui-handler.ts @@ -60,7 +60,7 @@ export abstract class FormModalUiHandler extends ModalUiHandler { const inputBg = addWindow(this.scene, 0, 0, 80, 16, false, false, 0, 0, WindowVariant.XTHIN); const isPassword = field.includes(i18next.t("menu:password")) || field.includes(i18next.t("menu:confirmPassword")); - const input = addTextInputObject(this.scene, 4, -2, 440, 116, TextStyle.TOOLTIP_CONTENT, { type: isPassword ? "password" : "text", maxLength: isPassword ? 64 : 18 }); + const input = addTextInputObject(this.scene, 4, -2, 440, 116, TextStyle.TOOLTIP_CONTENT, { type: isPassword ? "password" : "text", maxLength: isPassword ? 64 : 20 }); input.setOrigin(0, 0); inputContainer.add(inputBg); diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index 5dfc4bfc9b6..68ad4565d10 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -41,11 +41,6 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { public options: ModifierOption[]; public shopOptionsRows: ModifierOption[][]; - private rerollUpContainer: Phaser.GameObjects.Container; - private rerollDownContainer: Phaser.GameObjects.Container; - private rerollUpLabel: Phaser.GameObjects.Text; - private rerollDownLabel: Phaser.GameObjects.Text; - private cursorObj: Phaser.GameObjects.Image | null; constructor(scene: BattleScene) { @@ -107,32 +102,6 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.rerollCostText.setPositionRelative(rerollButtonText, rerollButtonText.displayWidth + 5, 1); this.rerollButtonContainer.add(this.rerollCostText); - - - this.rerollUpContainer = this.scene.add.container(100, -78); - this.rerollUpContainer.setName("reroll-brn"); - this.rerollUpContainer.setVisible(false); - ui.add(this.rerollUpContainer); - - this.rerollUpLabel = addTextObject(this.scene, -4, -2, "+1 Reroll", TextStyle.PARTY); - this.rerollUpLabel.setName("text-reroll-btn"); - this.rerollUpLabel.setOrigin(0, 0); - this.rerollUpContainer.add(this.rerollUpLabel); - - - - this.rerollDownContainer = this.scene.add.container(100, -64); - this.rerollDownContainer.setName("reroll-brn"); - this.rerollDownContainer.setVisible(false); - ui.add(this.rerollDownContainer); - - this.rerollDownLabel = addTextObject(this.scene, -4, -2, "-1 Reroll", TextStyle.PARTY); - this.rerollDownLabel.setName("text-reroll-btn"); - this.rerollDownLabel.setOrigin(0, 0); - this.rerollDownContainer.add(this.rerollDownLabel); - - - this.lockRarityButtonContainer = this.scene.add.container(16, -64); this.lockRarityButtonContainer.setVisible(false); ui.add(this.lockRarityButtonContainer); @@ -196,11 +165,6 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.lockRarityButtonContainer.setVisible(false); this.lockRarityButtonContainer.setAlpha(0); - this.rerollUpContainer.setVisible(false) - this.rerollUpContainer.setAlpha(0) - this.rerollDownContainer.setVisible(false) - this.rerollDownContainer.setAlpha(0) - this.rerollButtonContainer.setPositionRelative(this.lockRarityButtonContainer, 0, canLockRarities ? -12 : 0); this.rerollCost = args[3] as integer; @@ -287,15 +251,9 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.rerollButtonContainer.setAlpha(0); this.checkButtonContainer.setAlpha(0); this.lockRarityButtonContainer.setAlpha(0); - this.rerollUpContainer.setAlpha(0) - this.rerollDownContainer.setAlpha(0) this.rerollButtonContainer.setVisible(true); this.checkButtonContainer.setVisible(true); this.lockRarityButtonContainer.setVisible(canLockRarities); - this.rerollUpContainer.setVisible(false) - this.rerollDownContainer.setVisible(false) - - // , this.rerollUpContainer, this.rerollDownContainer this.scene.tweens.add({ targets: [ this.rerollButtonContainer, this.lockRarityButtonContainer, this.checkButtonContainer ], diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 4a7e4bc4303..a4c7f6029fb 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -1073,7 +1073,7 @@ export default class PartyUiHandler extends MessageUiHandler { } getReleaseMessage(pokemonName: string): string { - const rand = Utils.randInt(128); + const rand = Utils.randInt(128, undefined, "Random release message"); if (rand < 20) { return i18next.t("partyUiHandler:goodbye", { pokemonName: pokemonName }); } else if (rand < 40) { diff --git a/src/ui/pokemon-info-container.ts b/src/ui/pokemon-info-container.ts index e9c709a93f0..49bfd4d7293 100644 --- a/src/ui/pokemon-info-container.ts +++ b/src/ui/pokemon-info-container.ts @@ -298,11 +298,6 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { this.pokemonNatureLabelText.setColor(getTextColor(TextStyle.WINDOW, false, this.scene.uiTheme)); this.pokemonNatureLabelText.setShadowColor(getTextColor(TextStyle.WINDOW, true, this.scene.uiTheme)); } - - this.pokemonAbilityText.setVisible(true) - this.pokemonAbilityLabelText.setVisible(true) - this.pokemonNatureText.setVisible(true) - this.pokemonNatureLabelText.setVisible(true) const isFusion = pokemon.isFusion(); const doubleShiny = isFusion && pokemon.shiny && pokemon.fusionShiny; diff --git a/src/ui/run-info-ui-handler.ts b/src/ui/run-info-ui-handler.ts index d6bafb8599e..865a7c1236b 100644 --- a/src/ui/run-info-ui-handler.ts +++ b/src/ui/run-info-ui-handler.ts @@ -18,7 +18,6 @@ import { Type, getTypeRgb } from "../data/type"; import { TypeColor, TypeShadow } from "#app/enums/color"; import { getNatureStatMultiplier, getNatureName } from "../data/nature"; import { getVariantTint } from "#app/data/variant"; -import * as Modifier from "../modifier/modifier"; import { Species } from "#enums/species"; import { PlayerGender } from "#enums/player-gender"; @@ -67,7 +66,7 @@ export default class RunInfoUiHandler extends UiHandler { override async setup() { this.runContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1); // The import of the modifiersModule is loaded here to sidestep async/await issues. - this.modifiersModule = Modifier; + this.modifiersModule = await import("../modifier/modifier"); this.runContainer.setVisible(false); } @@ -302,7 +301,7 @@ export default class RunInfoUiHandler extends UiHandler { const teraPokemon = {}; this.runInfo.enemyModifiers.forEach((m) => { const modifier = m.toModifier(this.scene, this.modifiersModule[m.className]); - if (modifier instanceof Modifier.TerastallizeModifier) { + if (modifier instanceof TerastallizeModifier) { const teraDetails = modifier?.getArgs(); const pkmnId = teraDetails[0]; teraPokemon[pkmnId] = teraDetails[1]; @@ -433,7 +432,7 @@ export default class RunInfoUiHandler extends UiHandler { modifierIconsContainer.setScale(0.45); for (const m of this.runInfo.modifiers) { const modifier = m.toModifier(this.scene, this.modifiersModule[m.className]); - if (modifier instanceof Modifier.PokemonHeldItemModifier) { + if (modifier instanceof PokemonHeldItemModifier) { continue; } const icon = modifier?.getIcon(this.scene, false); @@ -634,17 +633,17 @@ export default class RunInfoUiHandler extends UiHandler { // Endless/Endless Spliced have a different scale because Pokemon tend to accumulate more items in these runs. const heldItemsScale = (this.runInfo.gameMode === GameModes.SPLICED_ENDLESS || this.runInfo.gameMode === GameModes.ENDLESS) ? 0.25 : 0.5; const heldItemsContainer = this.scene.add.container(-82, 2); - const heldItemsList : Modifier.PokemonHeldItemModifier[] = []; + const heldItemsList : PokemonHeldItemModifier[] = []; if (this.runInfo.modifiers.length) { for (const m of this.runInfo.modifiers) { const modifier = m.toModifier(this.scene, this.modifiersModule[m.className]); - if (modifier instanceof Modifier.PokemonHeldItemModifier && modifier.pokemonId === pokemon.id) { + if (modifier instanceof PokemonHeldItemModifier && modifier.pokemonId === pokemon.id) { modifier.stackCount = m["stackCount"]; heldItemsList.push(modifier); } } if (heldItemsList.length > 0) { - (heldItemsList as Modifier.PokemonHeldItemModifier[]).sort(Modifier.modifierSortFunc); + (heldItemsList as PokemonHeldItemModifier[]).sort(modifierSortFunc); let row = 0; for (const [index, item] of heldItemsList.entries()) { if ( index > 36 ) { diff --git a/src/ui/title-ui-handler.ts b/src/ui/title-ui-handler.ts index 67a4f7260e6..c49c039eb8f 100644 --- a/src/ui/title-ui-handler.ts +++ b/src/ui/title-ui-handler.ts @@ -85,7 +85,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler { const ret = super.show(args); if (ret) { - this.splashMessage = Utils.randItem(getSplashMessages()); + this.splashMessage = Utils.randItem(getSplashMessages(), "Splash Message selection"); this.splashMessageText.setText(this.splashMessage.replace("{COUNT}", "?")); const ui = this.getUi(); diff --git a/src/utils.ts b/src/utils.ts index 121d1ae2ae5..036666c7b78 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -13,7 +13,7 @@ export function randomString(length: integer, seeded: boolean = false) { let result = ""; for (let i = 0; i < length; i++) { - const randomIndex = seeded ? randSeedInt(characters.length) : Math.floor(Math.random() * characters.length); + const randomIndex = seeded ? randSeedInt(characters.length, undefined, "%HIDE") : Math.floor(Math.random() * characters.length); result += characters[randomIndex]; } @@ -44,7 +44,7 @@ export function rangemap(value: integer, min: integer, max: integer, outMin: int return ((value - min) / (max - min)) * (outMax - outMin) + outMin } -export function randGauss(stdev: number, mean: number = 0): number { +export function randGauss(stdev: number, mean: number = 0, reason?: string): number { if (!stdev) { return 0; } @@ -54,7 +54,7 @@ export function randGauss(stdev: number, mean: number = 0): number { return z * stdev + mean; } -export function randSeedGauss(stdev: number, mean: number = 0): number { +export function randSeedGauss(stdev: number, mean: number = 0, reason?: string): number { if (!stdev) { return 0; } @@ -85,7 +85,9 @@ export function randInt(range: integer, min: integer = 0, reason?: string): inte return min; } let V = Math.floor(Math.random() * range) + min; - //console.log(reason ? reason : "randInt", V) + if (reason != "%HIDE") { + //console.log("[unseeded] " + (reason ? reason : "randInt"), V) + } return V; } @@ -100,7 +102,13 @@ export function randSeedInt(range: integer, min: integer = 0, reason?: string): return min; } let V = Phaser.Math.RND.integerInRange(min, (range - 1) + min); - //console.log(reason ? reason : "randSeedInt", V) + if (reason != "%HIDE") { + if (reason) { + console.log(reason, V) + } else { + console.error("unlabeled randSeedInt", V) + } + } return V; } @@ -122,7 +130,7 @@ export function randItem(items: T[], reason?: string): T { export function randSeedItem(items: T[], reason?: string): T { function rpick() { let V = Phaser.Math.RND.pick(items) - //console.log(reason ? reason : "randSeedItem") + console.log(reason ? reason : "randSeedItem") return V; } return items.length === 1 @@ -133,7 +141,7 @@ export function randSeedItem(items: T[], reason?: string): T { export function randSeedWeightedItem(items: T[], reason?: string): T { function rpick() { let V = Phaser.Math.RND.weightedPick(items); - //console.log(reason ? reason : "randSeedWeightedItem") + console.log(reason ? reason : "randSeedWeightedItem") return V; } return items.length === 1