Implemented Merciless
Attribute CritIfTargetIsPoisonedAbAttr Fix BlockCritAbAttrpull/440/head
parent
58ec2ebd89
commit
a03d7ac9ef
|
@ -1822,6 +1822,29 @@ export class MultCritAbAttr extends AbAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute used by Merciless
|
||||||
|
* Guarantees a critical hit if the target is poisoned, except if target prevents critical hits.
|
||||||
|
*/
|
||||||
|
export class CritIfTargetPoisonedAbAttr extends AbAttr {
|
||||||
|
/**
|
||||||
|
* Multiplies the base additional effect chance by the given multiplier.
|
||||||
|
* @param {Pokemon} pokemon N/A
|
||||||
|
* @param {boolean} passive N/A
|
||||||
|
* @param {cancelled} cancelled N/A
|
||||||
|
* @param {any[]} args args[0]: BooleanHolder, If true critical hit is guaranteed. args[1]: Target Pokémon.
|
||||||
|
* @returns {boolean} true if function succeeds.
|
||||||
|
*/
|
||||||
|
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
const target = (args[1] as Pokemon);
|
||||||
|
if(target.status)
|
||||||
|
if(!(target.status.effect === StatusEffect.TOXIC || target.status.effect === StatusEffect.POISON))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
(args[0] as Utils.BooleanHolder).value = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class BlockNonDirectDamageAbAttr extends AbAttr {
|
export class BlockNonDirectDamageAbAttr extends AbAttr {
|
||||||
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
@ -3442,7 +3465,7 @@ export function initAbilities() {
|
||||||
new Ability(Abilities.WATER_COMPACTION, 7)
|
new Ability(Abilities.WATER_COMPACTION, 7)
|
||||||
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.type === Type.WATER && move.category !== MoveCategory.STATUS, BattleStat.DEF, 2),
|
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.type === Type.WATER && move.category !== MoveCategory.STATUS, BattleStat.DEF, 2),
|
||||||
new Ability(Abilities.MERCILESS, 7)
|
new Ability(Abilities.MERCILESS, 7)
|
||||||
.unimplemented(),
|
.attr(CritIfTargetPoisonedAbAttr),
|
||||||
new Ability(Abilities.SHIELDS_DOWN, 7)
|
new Ability(Abilities.SHIELDS_DOWN, 7)
|
||||||
.attr(PostBattleInitFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
|
.attr(PostBattleInitFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
|
||||||
.attr(PostSummonFormChangeAbAttr, 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 { ArenaTagSide, WeakenMoveScreenTag, WeakenMoveTypeTag } from '../data/arena-tag';
|
||||||
import { ArenaTagType } from "../data/enums/arena-tag-type";
|
import { ArenaTagType } from "../data/enums/arena-tag-type";
|
||||||
import { Biome } from "../data/enums/biome";
|
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, CritIfTargetPoisonedAbAttr } from '../data/ability';
|
||||||
import { Abilities } from "#app/data/enums/abilities";
|
import { Abilities } from "#app/data/enums/abilities";
|
||||||
import PokemonData from '../system/pokemon-data';
|
import PokemonData from '../system/pokemon-data';
|
||||||
import Battle, { BattlerIndex } from '../battle';
|
import Battle, { BattlerIndex } from '../battle';
|
||||||
|
@ -1484,6 +1484,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
const critOnly = new Utils.BooleanHolder(false);
|
const critOnly = new Utils.BooleanHolder(false);
|
||||||
const critAlways = source.getTag(BattlerTagType.ALWAYS_CRIT);
|
const critAlways = source.getTag(BattlerTagType.ALWAYS_CRIT);
|
||||||
applyMoveAttrs(CritOnlyAttr, source, this, move, critOnly);
|
applyMoveAttrs(CritOnlyAttr, source, this, move, critOnly);
|
||||||
|
applyAbAttrs(CritIfTargetPoisonedAbAttr, source, null, critOnly, this);
|
||||||
if (critOnly.value || critAlways)
|
if (critOnly.value || critAlways)
|
||||||
isCritical = true;
|
isCritical = true;
|
||||||
else {
|
else {
|
||||||
|
@ -1499,12 +1500,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
critLevel.value += 2;
|
critLevel.value += 2;
|
||||||
const critChance = [24, 8, 2, 1][Math.max(0, Math.min(critLevel.value, 3))];
|
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));
|
isCritical = !source.getTag(BattlerTagType.NO_CRIT) && (critChance === 1 || !this.scene.randBattleSeedInt(critChance));
|
||||||
if (isCritical) {
|
}
|
||||||
const blockCrit = new Utils.BooleanHolder(false);
|
if (isCritical) {
|
||||||
applyAbAttrs(BlockCritAbAttr, this, null, blockCrit);
|
const blockCrit = new Utils.BooleanHolder(false);
|
||||||
if (blockCrit.value)
|
applyAbAttrs(BlockCritAbAttr, this, null, blockCrit);
|
||||||
isCritical = false;
|
if (blockCrit.value)
|
||||||
}
|
isCritical = false;
|
||||||
}
|
}
|
||||||
const sourceAtk = new Utils.IntegerHolder(source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this, null, isCritical));
|
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));
|
const targetDef = new Utils.IntegerHolder(this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source, move, isCritical));
|
||||||
|
|
Loading…
Reference in New Issue