Update preAttack and fieldStat

This commit is contained in:
Dean 2025-02-01 16:40:54 -08:00
parent e2249a25a4
commit e958bb5fbd

View File

@ -1160,6 +1160,10 @@ export class PostStatStageChangeStatStageChangeAbAttr extends PostStatStageChang
} }
export class PreAttackAbAttr extends AbAttr { export class PreAttackAbAttr extends AbAttr {
willSucceedPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean {
return true;
}
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean | Promise<boolean> { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean | Promise<boolean> {
return false; return false;
} }
@ -1252,10 +1256,9 @@ export class FieldMultiplyStatAbAttr extends AbAttr {
this.canStack = canStack; this.canStack = canStack;
} }
willSucceed(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { willSucceedFieldStat(pokemon: Pokemon, passive: boolean, simulated: boolean, stat: Stat, statValue: Utils.NumberHolder, checkedPokemon: Pokemon, hasApplied: Utils.BooleanHolder, args: any[]): boolean {
if (!this.canStack && hasApplied.value) { return this.canStack || !hasApplied.value
return false; && this.stat === stat && checkedPokemon.getAbilityAttrs(FieldMultiplyStatAbAttr).every(attr => (attr as FieldMultiplyStatAbAttr).stat !== stat);
}
} }
/** /**
@ -1270,15 +1273,10 @@ export class FieldMultiplyStatAbAttr extends AbAttr {
* @returns true if this changed the checked stat, false otherwise. * @returns true if this changed the checked stat, false otherwise.
*/ */
applyFieldStat(pokemon: Pokemon, passive: boolean, simulated: boolean, stat: Stat, statValue: Utils.NumberHolder, checkedPokemon: Pokemon, hasApplied: Utils.BooleanHolder, args: any[]): boolean { applyFieldStat(pokemon: Pokemon, passive: boolean, simulated: boolean, stat: Stat, statValue: Utils.NumberHolder, checkedPokemon: Pokemon, hasApplied: Utils.BooleanHolder, args: any[]): boolean {
if (this.stat === stat && checkedPokemon.getAbilityAttrs(FieldMultiplyStatAbAttr).every(attr => (attr as FieldMultiplyStatAbAttr).stat !== stat)) {
statValue.value *= this.multiplier; statValue.value *= this.multiplier;
hasApplied.value = true; hasApplied.value = true;
return true; return true;
} }
return false;
}
} }
@ -1291,9 +1289,12 @@ export class MoveTypeChangeAbAttr extends PreAttackAbAttr {
super(true); super(true);
} }
willSucceedPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean {
return (this.condition && this.condition(pokemon, defender, move)) ?? false;
}
// TODO: Decouple this into two attributes (type change / power boost) // TODO: Decouple this into two attributes (type change / power boost)
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean {
if (this.condition && this.condition(pokemon, defender, move)) {
if (args[0] && args[0] instanceof Utils.NumberHolder) { if (args[0] && args[0] instanceof Utils.NumberHolder) {
args[0].value = this.newType; args[0].value = this.newType;
} }
@ -1302,9 +1303,6 @@ export class MoveTypeChangeAbAttr extends PreAttackAbAttr {
} }
return true; return true;
} }
return false;
}
} }
/** Ability attribute for changing a pokemon's type before using a move */ /** Ability attribute for changing a pokemon's type before using a move */
@ -1315,9 +1313,8 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr {
super(true); super(true);
} }
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { willSucceedPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean {
if ( if (!pokemon.isTerastallized() &&
!pokemon.isTerastallized() &&
move.id !== Moves.STRUGGLE && move.id !== Moves.STRUGGLE &&
/** /**
* Skip moves that call other moves because these moves generate a following move that will trigger this ability attribute * Skip moves that call other moves because these moves generate a following move that will trigger this ability attribute
@ -1327,12 +1324,18 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr {
attr instanceof RandomMovesetMoveAttr || attr instanceof RandomMovesetMoveAttr ||
attr instanceof RandomMoveAttr || attr instanceof RandomMoveAttr ||
attr instanceof NaturePowerAttr || attr instanceof NaturePowerAttr ||
attr instanceof CopyMoveAttr attr instanceof CopyMoveAttr)) {
) const moveType = pokemon.getMoveType(move);
) { if (pokemon.getTypes().some((t) => t !== moveType)) {
return true;
}
}
return false;
}
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean {
const moveType = pokemon.getMoveType(move); const moveType = pokemon.getMoveType(move);
if (pokemon.getTypes().some((t) => t !== moveType)) {
if (!simulated) { if (!simulated) {
this.moveType = moveType; this.moveType = moveType;
pokemon.summonData.types = [ moveType ]; pokemon.summonData.types = [ moveType ];
@ -1341,10 +1344,6 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr {
return true; return true;
} }
}
return false;
}
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return i18next.t("abilityTriggers:pokemonTypeChange", { return i18next.t("abilityTriggers:pokemonTypeChange", {
@ -1367,6 +1366,10 @@ export class AddSecondStrikeAbAttr extends PreAttackAbAttr {
this.damageMultiplier = damageMultiplier; this.damageMultiplier = damageMultiplier;
} }
willSucceedPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean {
return move.canBeMultiStrikeEnhanced(pokemon, true);
}
/** /**
* If conditions are met, this doubles the move's hit count (via args[1]) * If conditions are met, this doubles the move's hit count (via args[1])
* or multiplies the damage of secondary strikes (via args[2]) * or multiplies the damage of secondary strikes (via args[2])
@ -1382,8 +1385,6 @@ export class AddSecondStrikeAbAttr extends PreAttackAbAttr {
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean {
const hitCount = args[0] as Utils.NumberHolder; const hitCount = args[0] as Utils.NumberHolder;
const multiplier = args[1] as Utils.NumberHolder; const multiplier = args[1] as Utils.NumberHolder;
if (move.canBeMultiStrikeEnhanced(pokemon, true)) {
this.showAbility = !!hitCount?.value; this.showAbility = !!hitCount?.value;
if (hitCount?.value) { if (hitCount?.value) {
hitCount.value += 1; hitCount.value += 1;
@ -1394,8 +1395,6 @@ export class AddSecondStrikeAbAttr extends PreAttackAbAttr {
} }
return true; return true;
} }
return false;
}
} }
/** /**
@ -1414,6 +1413,10 @@ export class DamageBoostAbAttr extends PreAttackAbAttr {
this.condition = condition; this.condition = condition;
} }
willSucceedPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean {
return this.condition(pokemon, defender, move);
}
/** /**
* *
* @param pokemon the attacker pokemon * @param pokemon the attacker pokemon
@ -1424,14 +1427,10 @@ export class DamageBoostAbAttr extends PreAttackAbAttr {
* @returns true if the function succeeds * @returns true if the function succeeds
*/ */
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean {
if (this.condition(pokemon, defender, move)) {
const power = args[0] as Utils.NumberHolder; const power = args[0] as Utils.NumberHolder;
power.value = Math.floor(power.value * this.damageMultiplier); power.value = Math.floor(power.value * this.damageMultiplier);
return true; return true;
} }
return false;
}
} }
export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr { export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr {
@ -1444,14 +1443,13 @@ export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr {
this.powerMultiplier = powerMultiplier; this.powerMultiplier = powerMultiplier;
} }
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean { willSucceedPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean {
if (this.condition(pokemon, defender, move)) { return this.condition(pokemon, defender, move);
(args[0] as Utils.NumberHolder).value *= this.powerMultiplier;
return true;
} }
return false; applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean {
(args[0] as Utils.NumberHolder).value *= this.powerMultiplier;
return true;
} }
} }
@ -1488,18 +1486,18 @@ export class VariableMovePowerBoostAbAttr extends VariableMovePowerAbAttr {
this.mult = mult; this.mult = mult;
} }
willSucceedPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean {
return this.mult(pokemon, defender, move) !== 1;
}
/** /**
* @override * @override
*/ */
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move, args: any[]): boolean { applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move, args: any[]): boolean {
const multiplier = this.mult(pokemon, defender, move); const multiplier = this.mult(pokemon, defender, move);
if (multiplier !== 1) {
(args[0] as Utils.NumberHolder).value *= multiplier; (args[0] as Utils.NumberHolder).value *= multiplier;
return true; return true;
} }
return false;
}
} }
/** /**
@ -5191,7 +5189,8 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
export function applyAbAttrs(attrType: Constructor<AbAttr>, pokemon: Pokemon, cancelled: Utils.BooleanHolder | null, simulated: boolean = false, ...args: any[]): Promise<void> { export function applyAbAttrs(attrType: Constructor<AbAttr>, pokemon: Pokemon, cancelled: Utils.BooleanHolder | null, simulated: boolean = false, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<AbAttr>(attrType, pokemon, (attr, passive) => attr.apply(pokemon, passive, simulated, cancelled, args), (attr, passive) => attr.willSucceed(pokemon, passive, simulated, args), args, false, simulated); return applyAbAttrsInternal<AbAttr>(attrType, pokemon, (attr, passive) => attr.apply(pokemon, passive, simulated, cancelled, args),
(attr, passive) => attr.willSucceed(pokemon, passive, simulated, args), args, false, simulated);
} }
export function applyPostBattleInitAbAttrs(attrType: Constructor<PostBattleInitAbAttr>, export function applyPostBattleInitAbAttrs(attrType: Constructor<PostBattleInitAbAttr>,
@ -5247,12 +5246,14 @@ export function applyPostDamageAbAttrs(attrType: Constructor<PostDamageAbAttr>,
*/ */
export function applyFieldStatMultiplierAbAttrs(attrType: Constructor<FieldMultiplyStatAbAttr>, export function applyFieldStatMultiplierAbAttrs(attrType: Constructor<FieldMultiplyStatAbAttr>,
pokemon: Pokemon, stat: Stat, statValue: Utils.NumberHolder, checkedPokemon: Pokemon, hasApplied: Utils.BooleanHolder, simulated: boolean = false, ...args: any[]): Promise<void> { pokemon: Pokemon, stat: Stat, statValue: Utils.NumberHolder, checkedPokemon: Pokemon, hasApplied: Utils.BooleanHolder, simulated: boolean = false, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<FieldMultiplyStatAbAttr>(attrType, pokemon, (attr, passive) => attr.applyFieldStat(pokemon, passive, simulated, stat, statValue, checkedPokemon, hasApplied, args), args); return applyAbAttrsInternal<FieldMultiplyStatAbAttr>(attrType, pokemon, (attr, passive) => attr.applyFieldStat(pokemon, passive, simulated, stat, statValue, checkedPokemon, hasApplied, args),
(attr, passive) => attr.willSucceedFieldStat(pokemon, passive, simulated, stat, statValue, checkedPokemon, hasApplied, args), args);
} }
export function applyPreAttackAbAttrs(attrType: Constructor<PreAttackAbAttr>, export function applyPreAttackAbAttrs(attrType: Constructor<PreAttackAbAttr>,
pokemon: Pokemon, defender: Pokemon | null, move: Move, simulated: boolean = false, ...args: any[]): Promise<void> { pokemon: Pokemon, defender: Pokemon | null, move: Move, simulated: boolean = false, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PreAttackAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreAttack(pokemon, passive, simulated, defender, move, args), args, false, simulated); return applyAbAttrsInternal<PreAttackAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreAttack(pokemon, passive, simulated, defender, move, args),
(attr, passive) => attr.willSucceedPreAttack(pokemon, passive, simulated, defender, move, args), args, false, simulated);
} }
export function applyPostAttackAbAttrs(attrType: Constructor<PostAttackAbAttr>, export function applyPostAttackAbAttrs(attrType: Constructor<PostAttackAbAttr>,