From 8e9446a562135c5104644e86a484d1560f7f0d9b Mon Sep 17 00:00:00 2001 From: frutescens Date: Tue, 5 Nov 2024 11:46:54 -0800 Subject: [PATCH] Fixed up move mechanics --- src/data/battler-tags.ts | 21 ++++++++++----------- src/field/pokemon.ts | 7 ++++--- src/phases/faint-phase.ts | 14 ++++++++++++-- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 7de659605f2..270974cf28e 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2798,7 +2798,7 @@ export class PowerTrickTag extends BattlerTag { export class GrudgeTag extends BattlerTag { constructor() { - super(BattlerTagType.GRUDGE, [ BattlerTagLapseType.FAINT, BattlerTagLapseType.TURN_END ], 1); + super(BattlerTagType.GRUDGE, [ BattlerTagLapseType.CUSTOM, BattlerTagLapseType.TURN_END ], 1, Moves.GRUDGE); } onAdd(pokemon: Pokemon) { @@ -2806,17 +2806,14 @@ export class GrudgeTag extends BattlerTag { pokemon.scene.queueMessage(i18next.t("battlerTags:grudgeOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); } - lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { - if (lapseType === BattlerTagLapseType.FAINT) { - if (pokemon.isFainted() && pokemon.turnData.attacksReceived.length > 0) { + override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType, sourcePokemon?: Pokemon): boolean { + if (lapseType === BattlerTagLapseType.CUSTOM && sourcePokemon) { + if (sourcePokemon.isActive()) { const lastMove = pokemon.turnData.attacksReceived[0]; - const lastAttackSource = pokemon.scene.getPokemonById(lastMove.sourceId); - if (lastAttackSource && lastAttackSource?.isOnField()) { - const lastMoveData = lastAttackSource.getMoveset().find(m => m?.moveId === lastMove.move); - if (lastMoveData) { - lastMoveData.ppUsed = lastMoveData.getMovePp(); - pokemon.scene.queueMessage(i18next.t("battlerTags:grudgeOnLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(lastAttackSource), moveName: lastMoveData.getName() })); - } + const lastMoveData = sourcePokemon.getMoveset().find(m => m?.moveId === lastMove.move); + if (lastMoveData) { + lastMoveData.ppUsed = lastMoveData.getMovePp(); + pokemon.scene.queueMessage(i18next.t("battlerTags:grudgeOnLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: lastMoveData.getName() })); } } return false; @@ -3005,6 +3002,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source return new TelekinesisTag(sourceMove); case BattlerTagType.POWER_TRICK: return new PowerTrickTag(sourceMove, sourceId); + case BattlerTagType.GRUDGE: + return new GrudgeTag(); case BattlerTagType.NONE: default: return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 78f82e929de..e4a0734989b 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -19,7 +19,7 @@ import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; import { Status, StatusEffect, getRandomStatus } from "#app/data/status-effect"; import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions"; import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "#app/data/balance/tms"; -import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag, PowerTrickTag } from "../data/battler-tags"; +import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag, PowerTrickTag, GrudgeTag } from "../data/battler-tags"; import { WeatherType } from "#app/data/weather"; import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "#app/data/arena-tag"; import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs, InfiltratorAbAttr, AlliedFieldDamageReductionAbAttr, PostDamageAbAttr, applyPostDamageAbAttrs, PostDamageForceSwitchAbAttr } from "#app/data/ability"; @@ -2836,6 +2836,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // In case of fatal damage, this tag would have gotten cleared before we could lapse it. const destinyTag = this.getTag(BattlerTagType.DESTINY_BOND); + const grudgeTag = this.getTag(BattlerTagType.GRUDGE) as GrudgeTag; const isOneHitKo = result === HitResult.ONE_HIT_KO; @@ -2907,9 +2908,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (this.isFainted()) { // set splice index here, so future scene queues happen before FaintedPhase this.scene.setPhaseQueueSplice(); - if (!isNullOrUndefined(destinyTag) && dmg) { + if ((!isNullOrUndefined(destinyTag) || !isNullOrUndefined(grudgeTag)) && dmg) { // Destiny Bond will activate during FaintPhase - this.scene.unshiftPhase(new FaintPhase(this.scene, this.getBattlerIndex(), isOneHitKo, destinyTag, source)); + this.scene.unshiftPhase(new FaintPhase(this.scene, this.getBattlerIndex(), isOneHitKo, destinyTag ?? undefined, grudgeTag ?? undefined, source)); } else { this.scene.unshiftPhase(new FaintPhase(this.scene, this.getBattlerIndex(), isOneHitKo)); } diff --git a/src/phases/faint-phase.ts b/src/phases/faint-phase.ts index 3e90233a38c..2ce6e1d65df 100644 --- a/src/phases/faint-phase.ts +++ b/src/phases/faint-phase.ts @@ -1,7 +1,7 @@ import { BattlerIndex, BattleType } from "#app/battle"; import BattleScene from "#app/battle-scene"; import { applyPostFaintAbAttrs, applyPostKnockOutAbAttrs, applyPostVictoryAbAttrs, PostFaintAbAttr, PostKnockOutAbAttr, PostVictoryAbAttr } from "#app/data/ability"; -import { BattlerTagLapseType, DestinyBondTag } from "#app/data/battler-tags"; +import { BattlerTagLapseType, DestinyBondTag, GrudgeTag } from "#app/data/battler-tags"; import { battleSpecDialogue } from "#app/data/dialogue"; import { allMoves, PostVictoryStatStageChangeAttr } from "#app/data/move"; import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms"; @@ -33,16 +33,22 @@ export class FaintPhase extends PokemonPhase { */ private destinyTag?: DestinyBondTag; + /** + * Grudge tag belonging to the currently fainting Pokemon, if applicable + */ + private grudgeTag?: GrudgeTag; + /** * The source Pokemon that dealt fatal damage and should get KO'd by Destiny Bond, if applicable */ private source?: Pokemon; - constructor(scene: BattleScene, battlerIndex: BattlerIndex, preventEndure: boolean = false, destinyTag?: DestinyBondTag, source?: Pokemon) { + constructor(scene: BattleScene, battlerIndex: BattlerIndex, preventEndure: boolean = false, destinyTag?: DestinyBondTag, grudgeTag?: GrudgeTag, source?: Pokemon) { super(scene, battlerIndex); this.preventEndure = preventEndure; this.destinyTag = destinyTag; + this.grudgeTag = grudgeTag; this.source = source; } @@ -53,6 +59,10 @@ export class FaintPhase extends PokemonPhase { this.destinyTag.lapse(this.source, BattlerTagLapseType.CUSTOM); } + if (!isNullOrUndefined(this.grudgeTag) && !isNullOrUndefined(this.source)) { + this.grudgeTag.lapse(this.getPokemon(), BattlerTagLapseType.CUSTOM, this.source); + } + if (!this.preventEndure) { const instantReviveModifier = this.scene.applyModifier(PokemonInstantReviveModifier, this.player, this.getPokemon()) as PokemonInstantReviveModifier;