diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 4c3f09cab30..355bbb5a231 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -254,6 +254,25 @@ export class ConfusedTag extends BattlerTag { } } +export class DestinyBondTag extends BattlerTag { + constructor(sourceMove: Moves, sourceId: integer) { + super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId); + } + + lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { + if (lapseType !== BattlerTagLapseType.CUSTOM) { + return super.lapse(pokemon, lapseType); + } + const source = pokemon.scene.getPokemonById(this.sourceId); + if (source.isFainted()) { + const targetMessage = getPokemonMessage(pokemon, ''); + pokemon.scene.queueMessage(`${getPokemonMessage(source, ` took\n${targetMessage} down with it!`)}`) + pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, false, true); + } + return false; + } +} + export class InfatuatedTag extends BattlerTag { constructor(sourceMove: integer, sourceId: integer) { super(BattlerTagType.INFATUATED, BattlerTagLapseType.MOVE, 1, sourceMove, sourceId); @@ -1405,6 +1424,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc return new MagnetRisenTag(tagType, sourceMove); case BattlerTagType.MINIMIZED: return new MinimizeTag(); + case BattlerTagType.DESTINY_BOND: + return new DestinyBondTag(sourceMove, sourceId); case BattlerTagType.NONE: default: return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); diff --git a/src/data/enums/battler-tag-type.ts b/src/data/enums/battler-tag-type.ts index 9411d70a670..6d36cdafab5 100644 --- a/src/data/enums/battler-tag-type.ts +++ b/src/data/enums/battler-tag-type.ts @@ -56,5 +56,6 @@ export enum BattlerTagType { CHARGED = "CHARGED", GROUNDED = "GROUNDED", MAGNET_RISEN = "MAGNET_RISEN", - MINIMIZED = "MINIMIZED" + MINIMIZED = "MINIMIZED", + DESTINY_BOND = "DESTINY_BOND" } diff --git a/src/data/move.ts b/src/data/move.ts index 6849a0fe7ce..9754a29583a 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4250,6 +4250,18 @@ export class MoneyAttr extends MoveEffectAttr { } } +export class DestinyBondAttr extends MoveEffectAttr { + constructor() { + super(true, MoveEffectTrigger.PRE_APPLY); + } + + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + user.scene.queueMessage(`${getPokemonMessage(user, ' is trying\nto take its foe down with it!')}`); + target.addTag(BattlerTagType.DESTINY_BOND, undefined, move.id, user.id); + return true; + } +} + export class LastResortAttr extends MoveAttr { getCondition(): MoveConditionFunc { return (user: Pokemon, target: Pokemon, move: Move) => { @@ -4944,8 +4956,8 @@ export function initMoves() { .unimplemented(), new SelfStatusMove(Moves.DESTINY_BOND, Type.GHOST, -1, 5, -1, 0, 2) .ignoresProtect() - .condition(failOnBossCondition) - .unimplemented(), + .attr(DestinyBondAttr) + .condition(failOnBossCondition), new StatusMove(Moves.PERISH_SONG, Type.NORMAL, -1, 5, -1, 0, 2) .attr(FaintCountdownAttr) .ignoresProtect() diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 0a5e0a6a991..1368c924a16 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1610,6 +1610,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { console.log('damage', damage.value, move.name, power.value, sourceAtk, targetDef); + // In case of fatal damage, this tag would have gotten cleared before we could lapse it. + const destinyTag = this.getTag(BattlerTagType.DESTINY_BOND); + if (damage.value) { if (this.getHpRatio() === 1) applyPreDefendAbAttrs(PreDefendFullHpEndureAbAttr, this, source, battlerMove, cancelled, damage); @@ -1655,8 +1658,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } - if (damage) + if (damage) { this.scene.clearPhaseQueueSplice(); + + const attacker = this.scene.getPokemonById(source.id); + destinyTag?.lapse(attacker, BattlerTagLapseType.CUSTOM); + } } break; case MoveCategory.STATUS: