From 1ae54de59eb361faa0e77f551fb8fbcb364c169b Mon Sep 17 00:00:00 2001 From: Flashfyre Date: Mon, 30 Oct 2023 12:33:20 -0400 Subject: [PATCH] Fix multi-hit move implementation --- src/battle-phases.ts | 12 ++++++++++-- src/data/move.ts | 4 ++-- src/modifier/modifier-type.ts | 2 +- src/pokemon.ts | 22 ++++++++++++---------- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/battle-phases.ts b/src/battle-phases.ts index 445ca8632..87452fa32 100644 --- a/src/battle-phases.ts +++ b/src/battle-phases.ts @@ -1528,6 +1528,8 @@ class MoveEffectPhase extends PokemonPhase { const targetHitChecks = Object.fromEntries(targets.map(p => [ p.getBattlerIndex(), this.hitCheck(p) ])); if (targets.length === 1 && !targetHitChecks[this.targets[0]]) { + user.turnData.hitCount = 1; + user.turnData.hitsLeft = 1; this.scene.queueMessage(getPokemonMessage(user, '\'s\nattack missed!')); moveHistoryEntry.result = MoveResult.MISS; applyMoveAttrs(MissEffectAttr, user, null, this.move.getMove()); @@ -1539,6 +1541,8 @@ class MoveEffectPhase extends PokemonPhase { new MoveAnim(this.move.getMove().id as Moves, user, this.getTarget()?.getBattlerIndex()).play(this.scene, () => { for (let target of targets) { if (!targetHitChecks[target.getBattlerIndex()]) { + user.turnData.hitCount = 1; + user.turnData.hitsLeft = 1; this.scene.queueMessage(getPokemonMessage(user, '\'s\nattack missed!')); if (moveHistoryEntry.result === MoveResult.PENDING) moveHistoryEntry.result = MoveResult.MISS; @@ -1591,10 +1595,10 @@ class MoveEffectPhase extends PokemonPhase { end() { const user = this.getUserPokemon(); - if (--user.turnData.hitsLeft >= 1 && this.getTarget()) + if (--user.turnData.hitsLeft >= 1 && this.getTarget()?.isActive()) this.scene.unshiftPhase(this.getNewHitPhase()); else { - if (user.turnData.hitCount > 1) + if (user.turnData.hitCount - user.turnData.hitsLeft > 1) this.scene.queueMessage(`Hit ${user.turnData.hitCount} time(s)!`); this.scene.applyModifiers(HitHealModifier, this.player, user); } @@ -1606,6 +1610,10 @@ class MoveEffectPhase extends PokemonPhase { if (this.move.getMove().moveTarget === MoveTarget.USER) return true; + // Hit check only calculated on first hit for multi-hit moves + if (this.getUserPokemon().turnData.hitsLeft < this.getUserPokemon().turnData.hitCount) + return true; + const hiddenTag = target.getTag(HiddenTag); if (hiddenTag && !this.move.getMove().getAttrs(HitsTagAttr).filter(hta => (hta as HitsTagAttr).tagType === hiddenTag.tagType).length) return false; diff --git a/src/data/move.ts b/src/data/move.ts index bba1fe9e7..c03ff8aed 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2694,10 +2694,10 @@ export function initMoves() { new SelfStatusMove(Moves.SKETCH, "Sketch", Type.NORMAL, -1, 1, -1, "Permanently copies the opponent's last move.", -1, 0, 2) .attr(SketchAttr) .ignoresVirtual(), - new AttackMove(Moves.TRIPLE_KICK, "Triple Kick", Type.FIGHTING, MoveCategory.PHYSICAL, 10, 90, 10, -1, "Hits thrice in one turn at increasing power.", -1, 0, 2) + new AttackMove(Moves.TRIPLE_KICK, "Triple Kick (P)", Type.FIGHTING, MoveCategory.PHYSICAL, 10, 90, 10, -1, "Hits thrice in one turn at increasing power.", -1, 0, 2) .attr(MultiHitAttr, MultiHitType._3_INCR) .attr(MissEffectAttr, (user: Pokemon, move: Move) => { - user.turnData.hitsLeft = 0; + user.turnData.hitsLeft = 1; return true; }), new AttackMove(Moves.THIEF, "Thief", Type.DARK, MoveCategory.PHYSICAL, 60, 100, 25, 18, "Steals a held item from the opponent.", -1, 0, 2) diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 0b624834a..a9ddf6e31 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -534,7 +534,7 @@ export class EnemyAttackStatusEffectChanceModifierType extends ModifierType { export class EnemyInstantReviveChanceModifierType extends ModifierType { constructor(name: string, chancePercent: integer, fullHeal: boolean, iconImage?: string) { - super(name, `Adds a ${chancePercent}% chance of reviving with ${fullHeal ? '100' : '50'}% HP`, (type, _args) => new Modifiers.EnemyInstantReviveChanceModifier(type, fullHeal, chancePercent), iconImage, 'enemy_revive'); + super(name, `Adds a ${chancePercent}% chance of reviving with ${fullHeal ? 100 : 50}% HP`, (type, _args) => new Modifiers.EnemyInstantReviveChanceModifier(type, fullHeal, chancePercent), iconImage, 'enemy_revive'); } } diff --git a/src/pokemon.ts b/src/pokemon.ts index 1e5f52c46..aea042916 100644 --- a/src/pokemon.ts +++ b/src/pokemon.ts @@ -754,16 +754,18 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.turnData.attacksReceived.unshift({ move: move.id, result: result as DamageResult, damage: damage.value, critical: isCritical, sourceId: source.id }); } - switch (result) { - case HitResult.SUPER_EFFECTIVE: - this.scene.queueMessage('It\'s super effective!'); - break; - case HitResult.NOT_VERY_EFFECTIVE: - this.scene.queueMessage('It\'s not very effective!'); - break; - case HitResult.NO_EFFECT: - this.scene.queueMessage(`It doesn\'t affect ${this.name}!`); - break; + if (source.turnData.hitsLeft === 1) { + switch (result) { + case HitResult.SUPER_EFFECTIVE: + this.scene.queueMessage('It\'s super effective!'); + break; + case HitResult.NOT_VERY_EFFECTIVE: + this.scene.queueMessage('It\'s not very effective!'); + break; + case HitResult.NO_EFFECT: + this.scene.queueMessage(`It doesn\'t affect ${this.name}!`); + break; + } } if (damage)