[Bug] Fix Toxic Chain applying for non-damaging moves (#1814)
* Fix Toxic Chain applying for non-damaging moves * Addressing code review to change a boolean to a PokemonAttackCondition * Adding comments to introduced methods * Update src/data/ability.ts --------- Co-authored-by: Tempoanon <163687446+Tempo-anon@users.noreply.github.com>
This commit is contained in:
parent
64ca6dd827
commit
78c3906088
|
@ -1531,23 +1531,50 @@ export class BattleStatMultiplierAbAttr extends AbAttr {
|
|||
}
|
||||
|
||||
export class PostAttackAbAttr extends AbAttr {
|
||||
private attackCondition: PokemonAttackCondition;
|
||||
|
||||
/** The default attackCondition requires that the selected move is a damaging move */
|
||||
constructor(attackCondition: PokemonAttackCondition = (user, target, move) => (move.category !== MoveCategory.STATUS)) {
|
||||
super();
|
||||
|
||||
this.attackCondition = attackCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Please override {@link applyPostAttackAfterMoveTypeCheck} instead of this method. By default, this method checks that the move used is a damaging attack before
|
||||
* applying the effect of any inherited class. This can be changed by providing a different {@link attackCondition} to the constructor. See {@link ConfusionOnStatusEffectAbAttr}
|
||||
* for an example of an effect that does not require a damaging move.
|
||||
*/
|
||||
applyPostAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean | Promise<boolean> {
|
||||
// When attackRequired is true, we require the move to be an attack move and to deal damage before checking secondary requirements.
|
||||
// If attackRequired is false, we always defer to the secondary requirements.
|
||||
if (this.attackCondition(pokemon, defender, move)) {
|
||||
return this.applyPostAttackAfterMoveTypeCheck(pokemon, passive, defender, move, hitResult, args);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only called after {@link applyPostAttack} has already been applied. Use this for handling checks specific to the ability in question.
|
||||
*/
|
||||
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean | Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
||||
private condition: PokemonAttackCondition;
|
||||
private stealCondition: PokemonAttackCondition;
|
||||
|
||||
constructor(condition?: PokemonAttackCondition) {
|
||||
constructor(stealCondition?: PokemonAttackCondition) {
|
||||
super();
|
||||
|
||||
this.condition = condition;
|
||||
this.stealCondition = stealCondition;
|
||||
}
|
||||
|
||||
applyPostAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): Promise<boolean> {
|
||||
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
if (hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, defender, move))) {
|
||||
if (hitResult < HitResult.NO_EFFECT && (!this.stealCondition || this.stealCondition(pokemon, defender, move))) {
|
||||
const heldItems = this.getTargetHeldItems(defender).filter(i => i.isTransferrable);
|
||||
if (heldItems.length) {
|
||||
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
||||
|
@ -1583,7 +1610,7 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
|
|||
this.effects = effects;
|
||||
}
|
||||
|
||||
applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
||||
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: 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) && pokemon !== attacker && (!this.contactRequired || move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) {
|
||||
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
|
||||
|
@ -1614,7 +1641,7 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr {
|
|||
this.effects = effects;
|
||||
}
|
||||
|
||||
applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
||||
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
||||
/**Battler tags inflicted by abilities post attacking are also considered additional effects.*/
|
||||
if (!attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && pokemon !== attacker && (!this.contactRequired || move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance(attacker, pokemon, move) && !pokemon.status) {
|
||||
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
|
||||
|
@ -2414,7 +2441,8 @@ export class ConfusionOnStatusEffectAbAttr extends PostAttackAbAttr {
|
|||
private effects: StatusEffect[];
|
||||
|
||||
constructor(...effects: StatusEffect[]) {
|
||||
super();
|
||||
/** This effect does not require a damaging move */
|
||||
super((user, target, move) => true);
|
||||
this.effects = effects;
|
||||
}
|
||||
/**
|
||||
|
@ -2427,7 +2455,7 @@ export class ConfusionOnStatusEffectAbAttr extends PostAttackAbAttr {
|
|||
* @param args [0] {@linkcode StatusEffect} applied by move
|
||||
* @returns true if defender is confused
|
||||
*/
|
||||
applyPostAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
||||
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
||||
if (this.effects.indexOf(args[0]) > -1 && !defender.isFainted()) {
|
||||
return defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedInt(3,2), move.id, defender.id);
|
||||
}
|
||||
|
@ -4273,7 +4301,7 @@ export const allAbilities = [ new Ability(Abilities.NONE, 3) ];
|
|||
export function initAbilities() {
|
||||
allAbilities.push(
|
||||
new Ability(Abilities.STENCH, 3)
|
||||
.attr(PostAttackApplyBattlerTagAbAttr, false, (user, target, move) => (move.category !== MoveCategory.STATUS && !move.hasAttr(FlinchAttr)) ? 10 : 0, BattlerTagType.FLINCHED),
|
||||
.attr(PostAttackApplyBattlerTagAbAttr, false, (user, target, move) => !move.hasAttr(FlinchAttr) ? 10 : 0, BattlerTagType.FLINCHED),
|
||||
new Ability(Abilities.DRIZZLE, 3)
|
||||
.attr(PostSummonWeatherChangeAbAttr, WeatherType.RAIN)
|
||||
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.RAIN),
|
||||
|
|
Loading…
Reference in New Issue