mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-19 06:42:20 +02:00
Rewrite tags for contact protected and check moveFlags.doesFlagEffectApply
This commit is contained in:
parent
99fa9d7516
commit
e6dae1eb91
@ -6701,7 +6701,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.BAD_DREAMS, 4)
|
new Ability(Abilities.BAD_DREAMS, 4)
|
||||||
.attr(PostTurnHurtIfSleepingAbAttr),
|
.attr(PostTurnHurtIfSleepingAbAttr),
|
||||||
new Ability(Abilities.PICKPOCKET, 5)
|
new Ability(Abilities.PICKPOCKET, 5)
|
||||||
.attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT))
|
.attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user, target}))
|
||||||
.condition(getSheerForceHitDisableAbCondition()),
|
.condition(getSheerForceHitDisableAbCondition()),
|
||||||
new Ability(Abilities.SHEER_FORCE, 5)
|
new Ability(Abilities.SHEER_FORCE, 5)
|
||||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 1.3)
|
.attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 1.3)
|
||||||
@ -7051,7 +7051,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.BATTERY, 7)
|
new Ability(Abilities.BATTERY, 7)
|
||||||
.attr(AllyMoveCategoryPowerBoostAbAttr, [ MoveCategory.SPECIAL ], 1.3),
|
.attr(AllyMoveCategoryPowerBoostAbAttr, [ MoveCategory.SPECIAL ], 1.3),
|
||||||
new Ability(Abilities.FLUFFY, 7)
|
new Ability(Abilities.FLUFFY, 7)
|
||||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 0.5)
|
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user, target}), 0.5)
|
||||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => user.getMoveType(move) === PokemonType.FIRE, 2)
|
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => user.getMoveType(move) === PokemonType.FIRE, 2)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.DAZZLING, 7)
|
new Ability(Abilities.DAZZLING, 7)
|
||||||
@ -7060,7 +7060,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.SOUL_HEART, 7)
|
new Ability(Abilities.SOUL_HEART, 7)
|
||||||
.attr(PostKnockOutStatStageChangeAbAttr, Stat.SPATK, 1),
|
.attr(PostKnockOutStatStageChangeAbAttr, Stat.SPATK, 1),
|
||||||
new Ability(Abilities.TANGLING_HAIR, 7)
|
new Ability(Abilities.TANGLING_HAIR, 7)
|
||||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), Stat.SPD, -1, false),
|
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user, target}), Stat.SPD, -1, false),
|
||||||
new Ability(Abilities.RECEIVER, 7)
|
new Ability(Abilities.RECEIVER, 7)
|
||||||
.attr(CopyFaintedAllyAbilityAbAttr)
|
.attr(CopyFaintedAllyAbilityAbAttr)
|
||||||
.uncopiable(),
|
.uncopiable(),
|
||||||
|
@ -52,6 +52,7 @@ export enum BattlerTagLapseType {
|
|||||||
MOVE_EFFECT,
|
MOVE_EFFECT,
|
||||||
TURN_END,
|
TURN_END,
|
||||||
HIT,
|
HIT,
|
||||||
|
/** Tag lapses AFTER_HIT, applying its effects even if the user faints */
|
||||||
AFTER_HIT,
|
AFTER_HIT,
|
||||||
CUSTOM,
|
CUSTOM,
|
||||||
}
|
}
|
||||||
@ -498,7 +499,13 @@ export class BeakBlastChargingTag extends BattlerTag {
|
|||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
if (lapseType === BattlerTagLapseType.AFTER_HIT) {
|
if (lapseType === BattlerTagLapseType.AFTER_HIT) {
|
||||||
const phaseData = getMoveEffectPhaseData(pokemon);
|
const phaseData = getMoveEffectPhaseData(pokemon);
|
||||||
if (phaseData?.move.hasFlag(MoveFlags.MAKES_CONTACT)) {
|
if (
|
||||||
|
phaseData?.move.doesFlagEffectApply({
|
||||||
|
flag: MoveFlags.MAKES_CONTACT,
|
||||||
|
user: phaseData.attacker,
|
||||||
|
target: pokemon,
|
||||||
|
})
|
||||||
|
) {
|
||||||
phaseData.attacker.trySetStatus(StatusEffect.BURN, true, pokemon);
|
phaseData.attacker.trySetStatus(StatusEffect.BURN, true, pokemon);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1614,16 +1621,50 @@ export class ProtectedTag extends BattlerTag {
|
|||||||
/** Base class for `BattlerTag`s that block damaging moves but not status moves */
|
/** Base class for `BattlerTag`s that block damaging moves but not status moves */
|
||||||
export class DamageProtectedTag extends ProtectedTag {}
|
export class DamageProtectedTag extends ProtectedTag {}
|
||||||
|
|
||||||
|
/** Class for `BattlerTag`s that apply some effect when hit by a contact move */
|
||||||
|
export class ContactProtectedTag extends ProtectedTag {
|
||||||
|
/**
|
||||||
|
* Function to call when a contact move hits the pokemon with this tag.
|
||||||
|
* @param _attacker - The pokemon using the contact move
|
||||||
|
* @param _user - The pokemon that is being attacked and has the tag
|
||||||
|
* @param _move - The move used by the attacker
|
||||||
|
*/
|
||||||
|
onContact(_attacker: Pokemon, _user: Pokemon) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lapse the tag and apply `onContact` if the move makes contact and
|
||||||
|
* `lapseType` is custom, respecting the move's flags and the pokemon's
|
||||||
|
* abilities, and whether the lapseType is custom.
|
||||||
|
*
|
||||||
|
* @param pokemon - The pokemon with the tag
|
||||||
|
* @param lapseType - The type of lapse to apply. If this is not {@linkcode BattlerTagLapseType.CUSTOM CUSTOM}, no effect will be applied.
|
||||||
|
* @returns Whether the tag continues to exist after the lapse.
|
||||||
|
*/
|
||||||
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
|
const ret = super.lapse(pokemon, lapseType);
|
||||||
|
|
||||||
|
const moveData = getMoveEffectPhaseData(pokemon);
|
||||||
|
if (
|
||||||
|
lapseType === BattlerTagLapseType.CUSTOM &&
|
||||||
|
moveData &&
|
||||||
|
moveData.move.doesFlagEffectApply({ flag: MoveFlags.MAKES_CONTACT, user: moveData.attacker, target: pokemon })
|
||||||
|
) {
|
||||||
|
this.onContact(moveData.attacker, pokemon);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `BattlerTag` class for moves that block damaging moves damage the enemy if the enemy's move makes contact
|
* `BattlerTag` class for moves that block damaging moves damage the enemy if the enemy's move makes contact
|
||||||
* Used by {@linkcode Moves.SPIKY_SHIELD}
|
* Used by {@linkcode Moves.SPIKY_SHIELD}
|
||||||
*/
|
*/
|
||||||
export class ContactDamageProtectedTag extends ProtectedTag {
|
export class ContactDamageProtectedTag extends ContactProtectedTag {
|
||||||
private damageRatio: number;
|
private damageRatio: number;
|
||||||
|
|
||||||
constructor(sourceMove: Moves, damageRatio: number) {
|
constructor(sourceMove: Moves, damageRatio: number) {
|
||||||
super(sourceMove, BattlerTagType.SPIKY_SHIELD);
|
super(sourceMove, BattlerTagType.SPIKY_SHIELD);
|
||||||
|
|
||||||
this.damageRatio = damageRatio;
|
this.damageRatio = damageRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1636,22 +1677,43 @@ export class ContactDamageProtectedTag extends ProtectedTag {
|
|||||||
this.damageRatio = source.damageRatio;
|
this.damageRatio = source.damageRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
/**
|
||||||
const ret = super.lapse(pokemon, lapseType);
|
* Damage the attacker by `this.damageRatio` of the target's max HP
|
||||||
|
* @param attacker - The pokemon using the contact move
|
||||||
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
* @param user - The pokemon that is being attacked and has the tag
|
||||||
const effectPhase = globalScene.getCurrentPhase();
|
*/
|
||||||
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
|
override onContact(attacker: Pokemon, user: Pokemon): void {
|
||||||
const attacker = effectPhase.getPokemon();
|
const cancelled = new BooleanHolder(false);
|
||||||
if (!attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled);
|
||||||
attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), {
|
if (!cancelled.value) {
|
||||||
result: HitResult.INDIRECT,
|
attacker.damageAndUpdate(toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), {
|
||||||
});
|
result: HitResult.INDIRECT,
|
||||||
}
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
export class ContactSetStatusProtectedTag extends ContactProtectedTag {
|
||||||
|
/**
|
||||||
|
* @param sourceMove The move that caused the tag to be applied
|
||||||
|
* @param tagType The type of the tag
|
||||||
|
* @param statusEffect The status effect to apply to the attacker
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
sourceMove: Moves,
|
||||||
|
tagType: BattlerTagType,
|
||||||
|
private statusEffect: StatusEffect,
|
||||||
|
) {
|
||||||
|
super(sourceMove, tagType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the status effect on the attacker
|
||||||
|
* @param attacker - The pokemon using the contact move
|
||||||
|
* @param user - The pokemon that is being attacked and has the tag
|
||||||
|
*/
|
||||||
|
override onContact(attacker: Pokemon, user: Pokemon): void {
|
||||||
|
attacker.trySetStatus(this.statusEffect, true, user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1659,7 +1721,7 @@ export class ContactDamageProtectedTag extends ProtectedTag {
|
|||||||
* `BattlerTag` class for moves that block damaging moves and lower enemy stats if the enemy's move makes contact
|
* `BattlerTag` class for moves that block damaging moves and lower enemy stats if the enemy's move makes contact
|
||||||
* Used by {@linkcode Moves.KINGS_SHIELD}, {@linkcode Moves.OBSTRUCT}, {@linkcode Moves.SILK_TRAP}
|
* Used by {@linkcode Moves.KINGS_SHIELD}, {@linkcode Moves.OBSTRUCT}, {@linkcode Moves.SILK_TRAP}
|
||||||
*/
|
*/
|
||||||
export class ContactStatStageChangeProtectedTag extends DamageProtectedTag {
|
export class ContactStatStageChangeProtectedTag extends ContactProtectedTag {
|
||||||
private stat: BattleStat;
|
private stat: BattleStat;
|
||||||
private levels: number;
|
private levels: number;
|
||||||
|
|
||||||
@ -1674,68 +1736,19 @@ export class ContactStatStageChangeProtectedTag extends DamageProtectedTag {
|
|||||||
* When given a battler tag or json representing one, load the data for it.
|
* When given a battler tag or json representing one, load the data for it.
|
||||||
* @param {BattlerTag | any} source A battler tag
|
* @param {BattlerTag | any} source A battler tag
|
||||||
*/
|
*/
|
||||||
loadTag(source: BattlerTag | any): void {
|
override loadTag(source: BattlerTag | any): void {
|
||||||
super.loadTag(source);
|
super.loadTag(source);
|
||||||
this.stat = source.stat;
|
this.stat = source.stat;
|
||||||
this.levels = source.levels;
|
this.levels = source.levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
/**
|
||||||
const ret = super.lapse(pokemon, lapseType);
|
* Initiate the stat stage change on the attacker
|
||||||
|
* @param attacker - The pokemon using the contact move
|
||||||
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
* @param user - The pokemon that is being attacked and has the tag
|
||||||
const effectPhase = globalScene.getCurrentPhase();
|
*/
|
||||||
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
|
override onContact(attacker: Pokemon, _user: Pokemon): void {
|
||||||
const attacker = effectPhase.getPokemon();
|
globalScene.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [this.stat], this.levels));
|
||||||
globalScene.unshiftPhase(new StatStageChangePhase(attacker.getBattlerIndex(), false, [this.stat], this.levels));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ContactPoisonProtectedTag extends ProtectedTag {
|
|
||||||
constructor(sourceMove: Moves) {
|
|
||||||
super(sourceMove, BattlerTagType.BANEFUL_BUNKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
|
||||||
const ret = super.lapse(pokemon, lapseType);
|
|
||||||
|
|
||||||
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
|
||||||
const effectPhase = globalScene.getCurrentPhase();
|
|
||||||
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
|
|
||||||
const attacker = effectPhase.getPokemon();
|
|
||||||
attacker.trySetStatus(StatusEffect.POISON, true, pokemon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `BattlerTag` class for moves that block damaging moves and burn the enemy if the enemy's move makes contact
|
|
||||||
* Used by {@linkcode Moves.BURNING_BULWARK}
|
|
||||||
*/
|
|
||||||
export class ContactBurnProtectedTag extends DamageProtectedTag {
|
|
||||||
constructor(sourceMove: Moves) {
|
|
||||||
super(sourceMove, BattlerTagType.BURNING_BULWARK);
|
|
||||||
}
|
|
||||||
|
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
|
||||||
const ret = super.lapse(pokemon, lapseType);
|
|
||||||
|
|
||||||
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
|
||||||
const effectPhase = globalScene.getCurrentPhase();
|
|
||||||
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
|
|
||||||
const attacker = effectPhase.getPokemon();
|
|
||||||
attacker.trySetStatus(StatusEffect.BURN, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3518,9 +3531,9 @@ export function getBattlerTag(
|
|||||||
case BattlerTagType.SILK_TRAP:
|
case BattlerTagType.SILK_TRAP:
|
||||||
return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.SPD, -1);
|
return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.SPD, -1);
|
||||||
case BattlerTagType.BANEFUL_BUNKER:
|
case BattlerTagType.BANEFUL_BUNKER:
|
||||||
return new ContactPoisonProtectedTag(sourceMove);
|
return new ContactSetStatusProtectedTag(sourceMove, tagType, StatusEffect.POISON);
|
||||||
case BattlerTagType.BURNING_BULWARK:
|
case BattlerTagType.BURNING_BULWARK:
|
||||||
return new ContactBurnProtectedTag(sourceMove);
|
return new ContactSetStatusProtectedTag(sourceMove, tagType, StatusEffect.BURN);
|
||||||
case BattlerTagType.ENDURING:
|
case BattlerTagType.ENDURING:
|
||||||
return new EnduringTag(tagType, BattlerTagLapseType.TURN_END, sourceMove);
|
return new EnduringTag(tagType, BattlerTagLapseType.TURN_END, sourceMove);
|
||||||
case BattlerTagType.ENDURE_TOKEN:
|
case BattlerTagType.ENDURE_TOKEN:
|
||||||
|
@ -627,7 +627,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* @param hitResult - The {@linkcode HitResult} of the attempted move
|
* @param hitResult - The {@linkcode HitResult} of the attempted move
|
||||||
* @returns a `Promise` intended to be passed into a `then()` call.
|
* @returns a `Promise` intended to be passed into a `then()` call.
|
||||||
*/
|
*/
|
||||||
protected applyOnGetHitAbEffects(user: Pokemon, target: Pokemon, hitResult: HitResult): void {
|
protected applyOnGetHitAbEffects(user: Pokemon, target: Pokemon, hitResult: HitResult) {
|
||||||
if (!target.isFainted() || target.canApplyAbility()) {
|
if (!target.isFainted() || target.canApplyAbility()) {
|
||||||
applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move.getMove(), hitResult);
|
applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move.getMove(), hitResult);
|
||||||
|
|
||||||
@ -635,10 +635,9 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
if (!user.isPlayer() && this.move.getMove() instanceof AttackMove) {
|
if (!user.isPlayer() && this.move.getMove() instanceof AttackMove) {
|
||||||
globalScene.applyShuffledModifiers(EnemyAttackStatusEffectChanceModifier, false, target);
|
globalScene.applyShuffledModifiers(EnemyAttackStatusEffectChanceModifier, false, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
target.lapseTags(BattlerTagLapseType.AFTER_HIT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
target.lapseTags(BattlerTagLapseType.AFTER_HIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user