Disguise fix and changes
- Added `abilityTriggered` to pokemon battle data to not depend on hit counters. - Ability and form change checks now depend on `abilityTriggered`. - Instead of reducing move damage, damage is now directly modified and set to 1. - All hits but failed and non effective are set as just effective. - Made it so confusion damage also triggers Disguise. - Added both ability's messages. With these changes, for the correct functioning of the ability should be the substute interaction.pull/205/head
parent
77c3a5ad78
commit
f73e915ec7
|
@ -304,19 +304,28 @@ export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PreDefendMovePowerToOneAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
export class PreDefendReceivedMoveNullifierAbAttr extends PreDefendAbAttr {
|
||||||
|
protected condition: PokemonDefendCondition;
|
||||||
|
|
||||||
constructor(condition: PokemonDefendCondition) {
|
constructor(condition: PokemonDefendCondition) {
|
||||||
super(condition, 1);
|
super();
|
||||||
|
|
||||||
|
this.condition = condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move.getMove())) {
|
if (this.condition(pokemon, attacker, move.getMove()) && (args[1] as Utils.NumberHolder).value != HitResult.NO_EFFECT && (args[1] as Utils.NumberHolder).value != HitResult.FAIL) {
|
||||||
(args[0] as Utils.NumberHolder).value = 1;
|
(args[0] as Utils.NumberHolder).value = 1;
|
||||||
|
(args[1] as Utils.NumberHolder).value = HitResult.EFFECTIVE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
||||||
|
return `Its disguise served it as a decoy!`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TypeImmunityAbAttr extends PreDefendAbAttr {
|
export class TypeImmunityAbAttr extends PreDefendAbAttr {
|
||||||
|
@ -445,19 +454,27 @@ export class PostDefendAbAttr extends AbAttr {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PostDefendDisguiseAbAttr extends PostDefendAbAttr {
|
export class PostDefendDisguiseAbAttr extends PostDefendAbAttr {
|
||||||
|
protected condition: PokemonDefendCondition;
|
||||||
|
|
||||||
|
constructor(condition: PokemonDefendCondition) {
|
||||||
|
super(true);
|
||||||
|
this.condition = condition;
|
||||||
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||||
if (pokemon.formIndex == 0 && pokemon.battleData.hitCount != 0 && (move.getMove().category == MoveCategory.SPECIAL || move.getMove().category == MoveCategory.PHYSICAL)) {
|
|
||||||
|
|
||||||
const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt);
|
if (this.condition(pokemon, attacker, move.getMove()) && (hitResult == HitResult.EFFECTIVE)) {
|
||||||
|
const damageDealt = attacker.turnData.damageDealt;
|
||||||
|
let recoilDamage = Math.round(pokemon.getMaxHp() / 8 - damageDealt);
|
||||||
if (!recoilDamage)
|
if (!recoilDamage)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
pokemon.damageAndUpdate(recoilDamage, HitResult.OTHER);
|
pokemon.damageAndUpdate(recoilDamage, HitResult.OTHER);
|
||||||
|
pokemon.battleData.abilityTriggered = true;
|
||||||
pokemon.turnData.damageTaken += recoilDamage;
|
pokemon.turnData.damageTaken += recoilDamage;
|
||||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\'s disguise was busted!'));
|
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\'s disguise was busted!'));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1666,6 +1683,25 @@ export class BlockNonDirectDamageAbAttr extends AbAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class DisguiseConfusionDamageInteractionAbAttr extends AbAttr {
|
||||||
|
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
|
||||||
|
if(pokemon.battleData.abilityTriggered == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
cancelled.value = true;
|
||||||
|
pokemon.damageAndUpdate(Math.round(pokemon.getMaxHp() / 8), HitResult.OTHER);
|
||||||
|
pokemon.battleData.abilityTriggered = true;
|
||||||
|
pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
|
||||||
|
pokemon.scene.queueMessage(`Its disguise served it as a decoy!`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
||||||
|
return `${pokemon.name}\'s disguise was busted!`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class BlockOneHitKOAbAttr extends AbAttr {
|
export class BlockOneHitKOAbAttr extends AbAttr {
|
||||||
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
cancelled.value = true;
|
cancelled.value = true;
|
||||||
|
@ -3143,12 +3179,13 @@ export function initAbilities() {
|
||||||
.attr(UnsuppressableAbilityAbAttr)
|
.attr(UnsuppressableAbilityAbAttr)
|
||||||
.attr(NoFusionAbilityAbAttr),
|
.attr(NoFusionAbilityAbAttr),
|
||||||
new Ability(Abilities.DISGUISE, 7)
|
new Ability(Abilities.DISGUISE, 7)
|
||||||
.attr(PreDefendMovePowerToOneAbAttr, (target, user, move) => target.formIndex == 0 && target.getAttackTypeEffectiveness(move.type) > 0)
|
.attr(DisguiseConfusionDamageInteractionAbAttr)
|
||||||
.attr(PostSummonFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
.attr(PreDefendReceivedMoveNullifierAbAttr, (target, user, move) => target.battleData.abilityTriggered == false)
|
||||||
.attr(PostBattleInitFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
.attr(PostDefendDisguiseAbAttr, (target, user, move) => target.battleData.abilityTriggered == false)
|
||||||
.attr(PostDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
.attr(PreDefendFormChangeAbAttr, p => p.battleData.abilityTriggered == false ? 0 : 1)
|
||||||
.attr(PreDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
.attr(PostSummonFormChangeAbAttr, p => p.battleData.abilityTriggered == false ? 0 : 1)
|
||||||
.attr(PostDefendDisguiseAbAttr)
|
.attr(PostBattleInitFormChangeAbAttr, p => p.battleData.abilityTriggered == false ? 0 : 1)
|
||||||
|
.attr(PostDefendFormChangeAbAttr, p => p.battleData.abilityTriggered == false ? 0 : 1)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(UnsuppressableAbilityAbAttr)
|
.attr(UnsuppressableAbilityAbAttr)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import * as Utils from "../utils";
|
||||||
import { Moves } from "./enums/moves";
|
import { Moves } from "./enums/moves";
|
||||||
import { ChargeAttr, MoveFlags, allMoves } from "./move";
|
import { ChargeAttr, MoveFlags, allMoves } from "./move";
|
||||||
import { Type } from "./type";
|
import { Type } from "./type";
|
||||||
import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, ReverseDrainAbAttr, applyAbAttrs } from "./ability";
|
import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, ReverseDrainAbAttr, applyAbAttrs, DisguiseConfusionDamageInteractionAbAttr } from "./ability";
|
||||||
import { Abilities } from "./enums/abilities";
|
import { Abilities } from "./enums/abilities";
|
||||||
import { BattlerTagType } from "./enums/battler-tag-type";
|
import { BattlerTagType } from "./enums/battler-tag-type";
|
||||||
import { TerrainType } from "./terrain";
|
import { TerrainType } from "./terrain";
|
||||||
|
@ -226,8 +226,15 @@ export class ConfusedTag extends BattlerTag {
|
||||||
const def = pokemon.getBattleStat(Stat.DEF);
|
const def = pokemon.getBattleStat(Stat.DEF);
|
||||||
const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100));
|
const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100));
|
||||||
pokemon.scene.queueMessage('It hurt itself in its\nconfusion!');
|
pokemon.scene.queueMessage('It hurt itself in its\nconfusion!');
|
||||||
pokemon.damageAndUpdate(damage);
|
|
||||||
pokemon.battleData.hitCount++;
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
|
applyAbAttrs(DisguiseConfusionDamageInteractionAbAttr, pokemon, cancelled);
|
||||||
|
|
||||||
|
if (!cancelled.value) {
|
||||||
|
pokemon.damageAndUpdate(damage);
|
||||||
|
pokemon.battleData.hitCount++;
|
||||||
|
}
|
||||||
|
|
||||||
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
|
(pokemon.scene.getCurrentPhase() as MovePhase).cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 } from '../data/ability';
|
import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, FieldVariableMovePowerAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, PreDefendReceivedMoveNullifierAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, VariableMoveTypeAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr } 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';
|
||||||
|
@ -1412,6 +1412,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
damage.value = 0;
|
damage.value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let preResult = new Utils.NumberHolder(result);
|
||||||
|
applyPreDefendAbAttrs(PreDefendReceivedMoveNullifierAbAttr, this, source, battlerMove, cancelled, damage , preResult);
|
||||||
|
result = (preResult as Utils.NumberHolder).value;
|
||||||
|
|
||||||
console.log('damage', damage.value, move.name, power.value, sourceAtk, targetDef);
|
console.log('damage', damage.value, move.name, power.value, sourceAtk, targetDef);
|
||||||
|
|
||||||
if (damage.value) {
|
if (damage.value) {
|
||||||
|
@ -3054,6 +3058,7 @@ export class PokemonBattleData {
|
||||||
public hitCount: integer = 0;
|
public hitCount: integer = 0;
|
||||||
public endured: boolean = false;
|
public endured: boolean = false;
|
||||||
public berriesEaten: BerryType[] = [];
|
public berriesEaten: BerryType[] = [];
|
||||||
|
public abilityTriggered: boolean = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PokemonBattleSummonData {
|
export class PokemonBattleSummonData {
|
||||||
|
|
Loading…
Reference in New Issue