This commit is contained in:
NxKarim 2024-04-18 15:44:23 -06:00
commit 890a56dfb5
15 changed files with 5978 additions and 41 deletions

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -2053,13 +2053,35 @@ export class SyncEncounterNatureAbAttr extends AbAttr {
}
export class MoveAbilityBypassAbAttr extends AbAttr {
private moveIgnoreFunc: (pokemon: Pokemon, move: Move) => boolean;
constructor(moveIgnoreFunc?: (pokemon: Pokemon, move: Move) => boolean) {
super(false);
this.moveIgnoreFunc = moveIgnoreFunc || ((pokemon, move) => true);
}
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (this.moveIgnoreFunc(pokemon, (args[0] as Move))) {
cancelled.value = true;
return true;
}
return false;
}
}
export class SuppressFieldAbilitiesAbAttr extends AbAttr {
constructor() {
super(false);
}
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
cancelled.value = true;
return true;
const ability = (args[0] as Ability);
if (!ability.hasAttr(UnsuppressableAbilityAbAttr) && !ability.hasAttr(SuppressFieldAbilitiesAbAttr)) {
cancelled.value = true;
return true;
}
return false;
}
}
@ -2931,7 +2953,8 @@ export function initAbilities() {
.attr(PostDefendAbilitySwapAbAttr)
.bypassFaint(),
new Ability(Abilities.GORILLA_TACTICS, "Gorilla Tactics (N)", "Boosts the Pokémon's Attack stat but only allows the use of the first selected move.", 8),
new Ability(Abilities.NEUTRALIZING_GAS, "Neutralizing Gas (N)", "If the Pokémon with Neutralizing Gas is in the battle, the effects of all Pokémon's Abilities will be nullified or will not be triggered.", 8)
new Ability(Abilities.NEUTRALIZING_GAS, "Neutralizing Gas (P)", "If the Pokémon with Neutralizing Gas is in the battle, the effects of all Pokémon's Abilities will be nullified or will not be triggered.", 8)
.attr(SuppressFieldAbilitiesAbAttr)
.attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr)
.attr(NoTransformAbilityAbAttr),
@ -3047,7 +3070,8 @@ export function initAbilities() {
new Ability(Abilities.EARTH_EATER, "Earth Eater", "If hit by a Ground-type move, the Pokémon has its HP restored instead of taking damage.", 9)
.attr(TypeImmunityHealAbAttr, Type.GROUND)
.ignorable(),
new Ability(Abilities.MYCELIUM_MIGHT, "Mycelium Might (N)", "The Pokémon will always act more slowly when using status moves, but these moves will be unimpeded by the Ability of the target.", 9),
new Ability(Abilities.MYCELIUM_MIGHT, "Mycelium Might (P)", "The Pokémon will always act more slowly when using status moves, but these moves will be unimpeded by the Ability of the target.", 9)
.attr(MoveAbilityBypassAbAttr, (pokemon, move: Move) => move.category === MoveCategory.STATUS),
new Ability(Abilities.MINDS_EYE, "Mind's Eye (N)", "The Pokémon ignores changes to opponents' evasiveness, its accuracy can't be lowered, and it can hit Ghost types with Normal- and Fighting-type moves.", 9)
.ignorable(),
new Ability(Abilities.SUPERSWEET_SYRUP, "Supersweet Syrup (N)", "A sickly sweet scent spreads across the field the first time the Pokémon enters a battle, lowering the evasiveness of opposing Pokémon.", 9),

View File

@ -79,6 +79,7 @@ export enum CommonAnim {
MAGMA_STORM,
CLAMP,
THUNDER_CAGE,
INFESTATION,
ORDER_UP_CURLY,
ORDER_UP_DROOPY,
ORDER_UP_STRETCHY,

View File

@ -613,6 +613,16 @@ export class ThunderCageTag extends DamagingTrapTag {
}
}
export class InfestationTag extends DamagingTrapTag {
constructor(turnCount: integer, sourceId: integer) {
super(BattlerTagType.INFESTATION, CommonAnim.INFESTATION, turnCount, Moves.INFESTATION, sourceId);
}
getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ` has been afflicted \nwith an infestation by ${getPokemonPrefix(pokemon.scene.getPokemonById(this.sourceId))}${pokemon.scene.getPokemonById(this.sourceId).name}!`);
}
}
export class ProtectedTag extends BattlerTag {
constructor(sourceMove: Moves, tagType: BattlerTagType = BattlerTagType.PROTECTED) {
@ -1051,6 +1061,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
return new MagmaStormTag(turnCount, sourceId);
case BattlerTagType.THUNDER_CAGE:
return new ThunderCageTag(turnCount, sourceId);
case BattlerTagType.INFESTATION:
return new InfestationTag(turnCount, sourceId);
case BattlerTagType.PROTECTED:
return new ProtectedTag(sourceMove);
case BattlerTagType.SPIKY_SHIELD:

View File

@ -22,6 +22,7 @@ export enum BattlerTagType {
SAND_TOMB = "SAND_TOMB",
MAGMA_STORM = "MAGMA_STORM",
THUNDER_CAGE = "THUNDER_CAGE",
INFESTATION = "INFESTATION",
PROTECTED = "PROTECTED",
SPIKY_SHIELD = "SPIKY_SHIELD",
KINGS_SHIELD = "KINGS_SHIELD",

View File

@ -12,7 +12,7 @@ import * as Utils from "../utils";
import { WeatherType } from "./weather";
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
import { ArenaTagType } from "./enums/arena-tag-type";
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr } from "./ability";
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr } from "./ability";
import { Abilities } from "./enums/abilities";
import { allAbilities } from './ability';
import { PokemonHeldItemModifier } from "../modifier/modifier";
@ -68,7 +68,8 @@ export enum MoveFlags {
POWDER_MOVE = 2048,
DANCE_MOVE = 4096,
WIND_MOVE = 8192,
TRIAGE_MOVE = 16384
TRIAGE_MOVE = 16384,
IGNORE_ABILITIES = 32768
}
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
@ -286,12 +287,24 @@ export default class Move {
return this;
}
ignoresAbilities(ignoresAbilities?: boolean): this {
this.setFlag(MoveFlags.IGNORE_ABILITIES, ignoresAbilities);
return this;
}
checkFlag(flag: MoveFlags, user: Pokemon, target: Pokemon): boolean {
switch (flag) {
case MoveFlags.MAKES_CONTACT:
if (user.hasAbilityWithAttr(IgnoreContactAbAttr))
return false;
break;
case MoveFlags.IGNORE_ABILITIES:
if (user.hasAbilityWithAttr(MoveAbilityBypassAbAttr)) {
const abilityEffectsIgnored = new Utils.BooleanHolder(false);
applyAbAttrs(MoveAbilityBypassAbAttr, user, abilityEffectsIgnored, this);
if (abilityEffectsIgnored.value)
return true;
}
}
return !!(this.flags & flag);
@ -1422,7 +1435,7 @@ export class HalfHpStatMaxAttr extends StatChangeAttr {
user.scene.damageNumberHandler.add(user, damage);
user.updateInfo().then(() => {
const ret = super.apply(user, target, move, args);
user.scene.queueMessage(getPokemonMessage(user, ` cut its own hp\nand maximized its ${getBattleStatName(this.stats[0])}!`));
user.scene.queueMessage(getPokemonMessage(user, ` cut its own HP\nand maximized its ${getBattleStatName(this.stats[0])}!`));
resolve(ret);
});
});
@ -1461,6 +1474,24 @@ export class CutHpStatBoostAttr extends StatChangeAttr {
}
}
export class CopyStatsAttr extends MoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if (!super.apply(user, target, move, args))
return false;
for (let s = 0; s < target.summonData.battleStats.length; s++)
user.summonData.battleStats[s] = target.summonData.battleStats[s];
if (target.getTag(BattlerTagType.CRIT_BOOST))
user.addTag(BattlerTagType.CRIT_BOOST, 0, move.id);
else
user.removeTag(BattlerTagType.CRIT_BOOST);
target.scene.queueMessage(getPokemonMessage(user, 'copied\n') + getPokemonMessage(target, `'s stat changes!`));
return true;
}
}
export class InvertStatsAttr extends MoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if (!super.apply(user, target, move, args))
@ -1475,6 +1506,20 @@ export class InvertStatsAttr extends MoveEffectAttr {
}
}
export class ResetStatsAttr extends MoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if (!super.apply(user, target, move, args))
return false;
for (let s = 0; s < target.summonData.battleStats.length; s++)
target.summonData.battleStats[s] = 0;
target.scene.queueMessage(getPokemonMessage(target, `'s stat changes\nwere eliminated!`));
return true;
}
}
export class HpSplitAttr extends MoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
return new Promise(resolve => {
@ -2414,6 +2459,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
case BattlerTagType.SAND_TOMB:
case BattlerTagType.MAGMA_STORM:
case BattlerTagType.THUNDER_CAGE:
case BattlerTagType.INFESTATION:
return -3;
case BattlerTagType.ENCORE:
return -2;
@ -2883,7 +2929,7 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr {
: moveTargets.targets.indexOf(target.getBattlerIndex()) > -1
? [ target.getBattlerIndex() ]
: [ moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ];
user.getMoveQueue().push({ move: move.moveId, targets: targets, ignorePP: this.enemyMoveset });
user.getMoveQueue().push({ move: move.moveId, targets: targets, ignorePP: true });
user.scene.unshiftPhase(new MovePhase(user.scene, user, targets, moveset[moveIndex], true));
return true;
}
@ -3787,7 +3833,7 @@ export function initMoves() {
.target(MoveTarget.USER_SIDE),
new StatusMove(Moves.HAZE, Type.ICE, -1, 30, -1, 0, 1)
.target(MoveTarget.BOTH_SIDES)
.unimplemented(),
.attr(ResetStatsAttr),
new StatusMove(Moves.REFLECT, Type.PSYCHIC, -1, 20, -1, 0, 1)
.attr(AddArenaTagAttr, ArenaTagType.REFLECT, 5, true)
.target(MoveTarget.USER_SIDE),
@ -4071,7 +4117,8 @@ export function initMoves() {
new SelfStatusMove(Moves.SLEEP_TALK, Type.NORMAL, -1, 10, -1, 0, 2)
.attr(BypassSleepAttr)
.attr(RandomMovesetMoveAttr)
.condition((user, target, move) => user.status?.effect === StatusEffect.SLEEP),
.condition((user, target, move) => user.status?.effect === StatusEffect.SLEEP)
.ignoresVirtual(),
new StatusMove(Moves.HEAL_BELL, Type.NORMAL, -1, 5, -1, 0, 2)
.soundBased()
.target(MoveTarget.USER_AND_ALLIES)
@ -4115,7 +4162,18 @@ export function initMoves() {
.partial(),
new AttackMove(Moves.RAPID_SPIN, Type.NORMAL, MoveCategory.PHYSICAL, 50, 100, 40, 100, 0, 2)
.attr(StatChangeAttr, BattleStat.SPD, 1, true)
.attr(RemoveBattlerTagAttr, [ BattlerTagType.BIND, BattlerTagType.WRAP, BattlerTagType.FIRE_SPIN, BattlerTagType.WHIRLPOOL, BattlerTagType.CLAMP, BattlerTagType.SAND_TOMB, BattlerTagType.MAGMA_STORM, BattlerTagType.THUNDER_CAGE, BattlerTagType.SEEDED ], true)
.attr(RemoveBattlerTagAttr, [
BattlerTagType.BIND,
BattlerTagType.WRAP,
BattlerTagType.FIRE_SPIN,
BattlerTagType.WHIRLPOOL,
BattlerTagType.CLAMP,
BattlerTagType.SAND_TOMB,
BattlerTagType.MAGMA_STORM,
BattlerTagType.THUNDER_CAGE,
BattlerTagType.SEEDED,
BattlerTagType.INFESTATION
], true)
.partial(),
new StatusMove(Moves.SWEET_SCENT, Type.NORMAL, 100, 20, -1, 0, 2)
.attr(StatChangeAttr, BattleStat.EVA, -1)
@ -4156,7 +4214,7 @@ export function initMoves() {
.attr(CounterDamageAttr, (move: Move) => move.category === MoveCategory.SPECIAL, 2)
.target(MoveTarget.ATTACKER),
new StatusMove(Moves.PSYCH_UP, Type.NORMAL, -1, 10, -1, 0, 2)
.unimplemented(),
.attr(CopyStatsAttr),
new AttackMove(Moves.EXTREME_SPEED, Type.NORMAL, MoveCategory.PHYSICAL, 80, 100, 5, -1, 2, 2),
new AttackMove(Moves.ANCIENT_POWER, Type.ROCK, MoveCategory.SPECIAL, 60, 100, 5, 10, 0, 2)
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, true),
@ -4443,7 +4501,7 @@ export function initMoves() {
.attr(ConfuseAttr)
.pulseMove(),
new AttackMove(Moves.DOOM_DESIRE, Type.STEEL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 3)
.attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, 'chose\nDOOM DESIRE as its destiny!'),
.attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, 'chose\nDoom Desire as its destiny!'),
new AttackMove(Moves.PSYCHO_BOOST, Type.PSYCHIC, MoveCategory.SPECIAL, 140, 90, 5, 100, 0, 3)
.attr(StatChangeAttr, BattleStat.SPATK, -2, true),
new SelfStatusMove(Moves.ROOST, Type.FLYING, -1, 5, -1, 0, 4)
@ -4837,7 +4895,7 @@ export function initMoves() {
new AttackMove(Moves.CHIP_AWAY, Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 5)
.attr(IgnoreOpponentStatChangesAttr),
new AttackMove(Moves.CLEAR_SMOG, Type.POISON, MoveCategory.SPECIAL, 50, -1, 15, -1, 0, 5)
.partial(),
.attr(ResetStatsAttr),
new AttackMove(Moves.STORED_POWER, Type.PSYCHIC, MoveCategory.SPECIAL, 20, 100, 10, -1, 0, 5)
.attr(StatChangeCountPowerAttr),
new StatusMove(Moves.QUICK_GUARD, Type.FIGHTING, -1, 15, -1, 3, 5)
@ -5134,7 +5192,7 @@ export function initMoves() {
.attr(SurviveDamageAttr),
new AttackMove(Moves.INFESTATION, Type.BUG, MoveCategory.SPECIAL, 20, 100, 20, 100, 0, 6)
.makesContact()
.partial(),
.attr(TrapAttr, BattlerTagType.INFESTATION),
new AttackMove(Moves.POWER_UP_PUNCH, Type.FIGHTING, MoveCategory.PHYSICAL, 40, 100, 20, 100, 0, 6)
.attr(StatChangeAttr, BattleStat.ATK, 1, true)
.punchingMove(),
@ -5387,8 +5445,10 @@ export function initMoves() {
new AttackMove(Moves.SPECTRAL_THIEF, Type.GHOST, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 7)
.partial(),
new AttackMove(Moves.SUNSTEEL_STRIKE, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 7)
.ignoresAbilities()
.partial(),
new AttackMove(Moves.MOONGEIST_BEAM, Type.GHOST, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7)
.ignoresAbilities()
.partial(),
new StatusMove(Moves.TEARFUL_LOOK, Type.NORMAL, -1, 20, 100, 0, 7)
.attr(StatChangeAttr, BattleStat.ATK, -1)
@ -5411,15 +5471,16 @@ export function initMoves() {
.partial(),
new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7)
.attr(PhotonGeyserCategoryAttr)
.ignoresAbilities()
.partial(),
/* Unused */
new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
.attr(PhotonGeyserCategoryAttr)
.partial(),
.ignoresAbilities(),
new AttackMove(Moves.SEARING_SUNRAZE_SMASH, Type.STEEL, MoveCategory.PHYSICAL, 200, -1, 1, -1, 0, 7)
.partial(),
.ignoresAbilities(),
new AttackMove(Moves.MENACING_MOONRAZE_MAELSTROM, Type.GHOST, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
.partial(),
.ignoresAbilities(),
new AttackMove(Moves.LETS_SNUGGLE_FOREVER, Type.FAIRY, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
.partial(),
new AttackMove(Moves.SPLINTERED_STORMSHARDS, Type.ROCK, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
@ -5453,7 +5514,7 @@ export function initMoves() {
new AttackMove(Moves.SAPPY_SEED, Type.GRASS, MoveCategory.PHYSICAL, 100, 90, 10, 100, 0, 7)
.attr(AddBattlerTagAttr, BattlerTagType.SEEDED),
new AttackMove(Moves.FREEZY_FROST, Type.ICE, MoveCategory.SPECIAL, 100, 90, 10, -1, 0, 7)
.partial(),
.attr(ResetStatsAttr),
new AttackMove(Moves.SPARKLY_SWIRL, Type.FAIRY, MoveCategory.SPECIAL, 120, 85, 5, -1, 0, 7)
.partial(),
new AttackMove(Moves.VEEVEE_VOLLEY, Type.NORMAL, MoveCategory.PHYSICAL, -1, -1, 20, -1, 0, 7)
@ -5929,7 +5990,18 @@ export function initMoves() {
new AttackMove(Moves.TRIPLE_DIVE, Type.WATER, MoveCategory.PHYSICAL, 30, 95, 10, -1, 0, 9)
.attr(MultiHitAttr, MultiHitType._3),
new AttackMove(Moves.MORTAL_SPIN, Type.POISON, MoveCategory.PHYSICAL, 30, 100, 15, 100, 0, 9)
.attr(LapseBattlerTagAttr, [ BattlerTagType.BIND, BattlerTagType.WRAP, BattlerTagType.FIRE_SPIN, BattlerTagType.WHIRLPOOL, BattlerTagType.CLAMP, BattlerTagType.SAND_TOMB, BattlerTagType.MAGMA_STORM, BattlerTagType.THUNDER_CAGE, BattlerTagType.SEEDED ], true)
.attr(LapseBattlerTagAttr, [
BattlerTagType.BIND,
BattlerTagType.WRAP,
BattlerTagType.FIRE_SPIN,
BattlerTagType.WHIRLPOOL,
BattlerTagType.CLAMP,
BattlerTagType.SAND_TOMB,
BattlerTagType.MAGMA_STORM,
BattlerTagType.THUNDER_CAGE,
BattlerTagType.SEEDED,
BattlerTagType.INFESTATION
], true)
.attr(StatusEffectAttr, StatusEffect.POISON)
.target(MoveTarget.ALL_NEAR_ENEMIES),
new StatusMove(Moves.DOODLE, Type.NORMAL, 100, 10, -1, 0, 9)

View File

@ -3234,7 +3234,7 @@ export const starterPassiveAbilities = {
[Species.ZIGZAGOON]: Abilities.PICKPOCKET,
[Species.WURMPLE]: Abilities.TINTED_LENS,
[Species.LOTAD]: Abilities.DRIZZLE,
[Species.SEEDOT]: Abilities.DISGUISE,
[Species.SEEDOT]: Abilities.EARLY_BIRD,
[Species.TAILLOW]: Abilities.KEEN_EYE,
[Species.WINGULL]: Abilities.HYDRATION,
[Species.RALTS]: Abilities.PSYCHIC_SURGE,
@ -3409,7 +3409,7 @@ export const starterPassiveAbilities = {
[Species.AXEW]: Abilities.SHEER_FORCE,
[Species.CUBCHOO]: Abilities.INTIMIDATE,
[Species.CRYOGONAL]: Abilities.DAZZLING,
[Species.SHELMET]: Abilities.DISGUISE,
[Species.SHELMET]: Abilities.TOXIC_DEBRIS,
[Species.STUNFISK]: Abilities.STORM_DRAIN,
[Species.MIENFOO]: Abilities.NO_GUARD,
[Species.DRUDDIGON]: Abilities.INTIMIDATE,
@ -3639,7 +3639,7 @@ export const starterPassiveAbilities = {
[Species.OKIDOGI]: Abilities.INTIMIDATE,
[Species.MUNKIDORI]: Abilities.PRANKSTER,
[Species.FEZANDIPITI]: Abilities.DAZZLING,
[Species.OGERPON]: Abilities.DISGUISE,
[Species.OGERPON]: Abilities.UNNERVE,
[Species.GOUGING_FIRE]: Abilities.BEAST_BOOST,
[Species.RAGING_BOLT]: Abilities.BEAST_BOOST,
[Species.IRON_BOULDER]: Abilities.SHARPNESS,

View File

@ -25,7 +25,7 @@ import { TempBattleStat } from '../data/temp-battle-stat';
import { ArenaTagSide, WeakenMoveScreenTag, WeakenMoveTypeTag } from '../data/arena-tag';
import { ArenaTagType } from "../data/enums/arena-tag-type";
import { Biome } from "../data/enums/biome";
import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, FieldVariableMovePowerAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, VariableMoveTypeAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from '../data/ability';
import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, FieldVariableMovePowerAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, VariableMoveTypeAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr } from '../data/ability';
import { Abilities } from "#app/data/enums/abilities";
import PokemonData from '../system/pokemon-data';
import Battle, { BattlerIndex } from '../battle';
@ -740,8 +740,21 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (passive && !this.hasPassive())
return false;
const ability = (!passive ? this.getAbility() : this.getPassiveAbility());
if (ability.isIgnorable && this.scene.arena.ignoreAbilities)
if (this.scene?.arena.ignoreAbilities && ability.isIgnorable)
return false;
if (this.summonData?.abilitySuppressed && !ability.hasAttr(UnsuppressableAbilityAbAttr))
return false;
if (this.isOnField() && !ability.hasAttr(SuppressFieldAbilitiesAbAttr)) {
const suppressed = new Utils.BooleanHolder(false);
this.scene.getField(true).map(p => {
if (p.getAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility())
p.getAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, false, suppressed, [ability]));
if (p.getPassiveAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility(true))
p.getPassiveAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, true, suppressed, [ability]));
});
if (suppressed.value)
return false;
}
return (this.hp || ability.isBypassFaint) && !ability.conditions.find(condition => !condition(this));
}
@ -2829,6 +2842,7 @@ export class PokemonSummonData {
public disabledMove: Moves = Moves.NONE;
public disabledTurns: integer = 0;
public tags: BattlerTag[] = [];
public abilitySuppressed: boolean = false;
public speciesForm: PokemonSpeciesForm;
public fusionSpeciesForm: PokemonSpeciesForm;

View File

@ -1,11 +1,4 @@
interface MoveTranslationEntry {
name: string,
effect: string
}
interface MoveTranslations {
[key: string]: MoveTranslationEntry
}
import { MoveTranslations } from "#app/plugins/i18n";
export const move: MoveTranslations = {
"pound": {
@ -2549,8 +2542,8 @@ export const move: MoveTranslations = {
effect: "Dummy Data"
},
"neverEndingNightmarePhysical": {
name: "Deep-seated grudges summoned by the user's Z-Power trap the target. The power varies, depending on the original move.",
effect: "Dummy Data"
name: "Never-Ending Nightmare",
effect: "Deep-seated grudges summoned by the user's Z-Power trap the target. The power varies, depending on the original move."
},
"neverEndingNightmareSpecial": {
name: "Never-Ending Nightmare",

39
src/locales/fr/menu.ts Normal file
View File

@ -0,0 +1,39 @@
export const menu = {
"cancel": "Annuler",
"continue": "Continuer",
"dailyRun": "Défi du jour (Bêta)",
"loadGame": "Charger la partie",
"newGame": "Nouvelle partie",
"selectGameMode": "Sélectionnez un mode de jeu.",
"logInOrCreateAccount": "Connectez-vous ou créez un compte pour commencer. Aucun e-mail requis !",
"failedToLoadSaveData": "Échec du chargement des données. Veuillez recharger la page.\nSi cela continue, veuillez contacter 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 ?",
"boy": "Garçon",
"girl": "Fille",
"bossAppeared": "Un {{bossName}} est apparaît.",
"trainerAppeared": "Un combat est lancé\npar {{trainerName}} !",
"singleWildAppeared": "Un {{pokemonName}} sauvage apparaît!",
"multiWildAppeared": "Un {{pokemonName1}} et un {{pokemonName2}}\nsauvages apparaissent !",
"playerComeBack": "{{pokemonName}}, on change!\nReviens !",
"trainerComeBack": "{{trainerName}} retire {{pokemonName}} !",
"playerGo": "{{pokemonName}} ! Go !",
"trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !",
"switchQuestion": "Voulez-vous changer\n{{pokemonName}} ?",
"pokemon": "Pokémon",
"sendOutPokemon": "{{pokemonName}} ! Go !",
"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é.",
"moveDisabled": "{{moveName}} est désactivé !",
"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 !",
"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}} !",
"escapeVerbSwitch": "le changement",
"escapeVerbFlee": "la fuite",
"notDisabled": "{{moveName}} n'est plus désactivé !",
} as const;

File diff suppressed because it is too large Load Diff

View File

@ -2141,10 +2141,8 @@ export class MovePhase extends BattlePhase {
}
if (!this.followUp) {
const abilityEffectsIgnored = new Utils.BooleanHolder(false);
this.scene.getField(true).map(p => applyAbAttrs(MoveAbilityBypassAbAttr, p, abilityEffectsIgnored));
if (abilityEffectsIgnored.value)
this.scene.arena.setIgnoreAbilities(true);
if (this.move.getMove().checkFlag(MoveFlags.IGNORE_ABILITIES, this.pokemon, null))
this.scene.arena.setIgnoreAbilities();
} else {
this.pokemon.turnData.hitsLeft = undefined;
this.pokemon.turnData.hitCount = undefined;

View File

@ -1,10 +1,20 @@
import i18next from 'i18next';
import { menu as enMenu } from '../locales/en/menu';
import { menu as itMenu } from '../locales/it/menu';
import { menu as frMenu } from '../locales/fr/menu';
import { move as enMove } from '../locales/en/move';
import { move as frMove } from '../locales/fr/move';
export interface MoveTranslationEntry {
name: string,
effect: string
}
export interface MoveTranslations {
[key: string]: MoveTranslationEntry
}
const DEFAULT_LANGUAGE_OVERRIDE = '';
/**
@ -35,6 +45,7 @@ i18next.init({
menu: itMenu,
},
fr: {
menu: frMenu,
move: frMove,
}
},