Implements Merciless (#440)
* Implemented Merciless Attribute CritIfTargetIsPoisonedAbAttr Fix BlockCritAbAttr * Changed CritIfTargetPoisonedAbAttr to ConditionalCritAbAttr Now any condition related to user, target or the move used can be applied to guarantee a critical hit.
This commit is contained in:
parent
e8c1098b91
commit
1ae5847e49
|
@ -1822,6 +1822,36 @@ export class MultCritAbAttr extends AbAttr {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Guarantees a critical hit according to the given condition, except if target prevents critical hits. ie. Merciless
|
||||
* @extends AbAttr
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class ConditionalCritAbAttr extends AbAttr {
|
||||
private condition: PokemonAttackCondition;
|
||||
|
||||
constructor(condition: PokemonAttackCondition, checkUser?: Boolean) {
|
||||
super();
|
||||
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pokemon {@linkcode Pokemon} user.
|
||||
* @param args [0] {@linkcode Utils.BooleanHolder} If true critical hit is guaranteed.
|
||||
* [1] {@linkcode Pokemon} Target.
|
||||
* [2] {@linkcode Move} used by ability user.
|
||||
*/
|
||||
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
const target = (args[1] as Pokemon);
|
||||
const move = (args[2] as Move);
|
||||
if(!this.condition(pokemon,target,move))
|
||||
return false;
|
||||
|
||||
(args[0] as Utils.BooleanHolder).value = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class BlockNonDirectDamageAbAttr extends AbAttr {
|
||||
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
|
@ -3442,7 +3472,7 @@ export function initAbilities() {
|
|||
new Ability(Abilities.WATER_COMPACTION, 7)
|
||||
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.type === Type.WATER && move.category !== MoveCategory.STATUS, BattleStat.DEF, 2),
|
||||
new Ability(Abilities.MERCILESS, 7)
|
||||
.unimplemented(),
|
||||
.attr(ConditionalCritAbAttr, (user, target, move) => target.status?.effect === StatusEffect.TOXIC || target.status?.effect === StatusEffect.POISON),
|
||||
new Ability(Abilities.SHIELDS_DOWN, 7)
|
||||
.attr(PostBattleInitFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
|
||||
.attr(PostSummonFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
|
||||
|
|
|
@ -27,7 +27,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, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr } 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, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr } from '../data/ability';
|
||||
import { Abilities } from "#app/data/enums/abilities";
|
||||
import PokemonData from '../system/pokemon-data';
|
||||
import Battle, { BattlerIndex } from '../battle';
|
||||
|
@ -1523,6 +1523,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
const critOnly = new Utils.BooleanHolder(false);
|
||||
const critAlways = source.getTag(BattlerTagType.ALWAYS_CRIT);
|
||||
applyMoveAttrs(CritOnlyAttr, source, this, move, critOnly);
|
||||
applyAbAttrs(ConditionalCritAbAttr, source, null, critOnly, this, move);
|
||||
if (critOnly.value || critAlways)
|
||||
isCritical = true;
|
||||
else {
|
||||
|
@ -1538,12 +1539,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
critLevel.value += 2;
|
||||
const critChance = [24, 8, 2, 1][Math.max(0, Math.min(critLevel.value, 3))];
|
||||
isCritical = !source.getTag(BattlerTagType.NO_CRIT) && (critChance === 1 || !this.scene.randBattleSeedInt(critChance));
|
||||
if (isCritical) {
|
||||
const blockCrit = new Utils.BooleanHolder(false);
|
||||
applyAbAttrs(BlockCritAbAttr, this, null, blockCrit);
|
||||
if (blockCrit.value)
|
||||
isCritical = false;
|
||||
}
|
||||
}
|
||||
if (isCritical) {
|
||||
const blockCrit = new Utils.BooleanHolder(false);
|
||||
applyAbAttrs(BlockCritAbAttr, this, null, blockCrit);
|
||||
if (blockCrit.value)
|
||||
isCritical = false;
|
||||
}
|
||||
const sourceAtk = new Utils.IntegerHolder(source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this, null, isCritical));
|
||||
const targetDef = new Utils.IntegerHolder(this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source, move, isCritical));
|
||||
|
|
Loading…
Reference in New Issue