Fix multi-hit move implementation

pull/2/head
Flashfyre 2023-10-30 12:33:20 -04:00
parent 179d1bcb13
commit 1ae54de59e
4 changed files with 25 additions and 15 deletions

View File

@ -1528,6 +1528,8 @@ class MoveEffectPhase extends PokemonPhase {
const targetHitChecks = Object.fromEntries(targets.map(p => [ p.getBattlerIndex(), this.hitCheck(p) ])); const targetHitChecks = Object.fromEntries(targets.map(p => [ p.getBattlerIndex(), this.hitCheck(p) ]));
if (targets.length === 1 && !targetHitChecks[this.targets[0]]) { if (targets.length === 1 && !targetHitChecks[this.targets[0]]) {
user.turnData.hitCount = 1;
user.turnData.hitsLeft = 1;
this.scene.queueMessage(getPokemonMessage(user, '\'s\nattack missed!')); this.scene.queueMessage(getPokemonMessage(user, '\'s\nattack missed!'));
moveHistoryEntry.result = MoveResult.MISS; moveHistoryEntry.result = MoveResult.MISS;
applyMoveAttrs(MissEffectAttr, user, null, this.move.getMove()); 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, () => { new MoveAnim(this.move.getMove().id as Moves, user, this.getTarget()?.getBattlerIndex()).play(this.scene, () => {
for (let target of targets) { for (let target of targets) {
if (!targetHitChecks[target.getBattlerIndex()]) { if (!targetHitChecks[target.getBattlerIndex()]) {
user.turnData.hitCount = 1;
user.turnData.hitsLeft = 1;
this.scene.queueMessage(getPokemonMessage(user, '\'s\nattack missed!')); this.scene.queueMessage(getPokemonMessage(user, '\'s\nattack missed!'));
if (moveHistoryEntry.result === MoveResult.PENDING) if (moveHistoryEntry.result === MoveResult.PENDING)
moveHistoryEntry.result = MoveResult.MISS; moveHistoryEntry.result = MoveResult.MISS;
@ -1591,10 +1595,10 @@ class MoveEffectPhase extends PokemonPhase {
end() { end() {
const user = this.getUserPokemon(); const user = this.getUserPokemon();
if (--user.turnData.hitsLeft >= 1 && this.getTarget()) if (--user.turnData.hitsLeft >= 1 && this.getTarget()?.isActive())
this.scene.unshiftPhase(this.getNewHitPhase()); this.scene.unshiftPhase(this.getNewHitPhase());
else { 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.queueMessage(`Hit ${user.turnData.hitCount} time(s)!`);
this.scene.applyModifiers(HitHealModifier, this.player, user); this.scene.applyModifiers(HitHealModifier, this.player, user);
} }
@ -1606,6 +1610,10 @@ class MoveEffectPhase extends PokemonPhase {
if (this.move.getMove().moveTarget === MoveTarget.USER) if (this.move.getMove().moveTarget === MoveTarget.USER)
return true; 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); const hiddenTag = target.getTag(HiddenTag);
if (hiddenTag && !this.move.getMove().getAttrs(HitsTagAttr).filter(hta => (hta as HitsTagAttr).tagType === hiddenTag.tagType).length) if (hiddenTag && !this.move.getMove().getAttrs(HitsTagAttr).filter(hta => (hta as HitsTagAttr).tagType === hiddenTag.tagType).length)
return false; return false;

View File

@ -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) new SelfStatusMove(Moves.SKETCH, "Sketch", Type.NORMAL, -1, 1, -1, "Permanently copies the opponent's last move.", -1, 0, 2)
.attr(SketchAttr) .attr(SketchAttr)
.ignoresVirtual(), .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(MultiHitAttr, MultiHitType._3_INCR)
.attr(MissEffectAttr, (user: Pokemon, move: Move) => { .attr(MissEffectAttr, (user: Pokemon, move: Move) => {
user.turnData.hitsLeft = 0; user.turnData.hitsLeft = 1;
return true; 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) new AttackMove(Moves.THIEF, "Thief", Type.DARK, MoveCategory.PHYSICAL, 60, 100, 25, 18, "Steals a held item from the opponent.", -1, 0, 2)

View File

@ -534,7 +534,7 @@ export class EnemyAttackStatusEffectChanceModifierType extends ModifierType {
export class EnemyInstantReviveChanceModifierType extends ModifierType { export class EnemyInstantReviveChanceModifierType extends ModifierType {
constructor(name: string, chancePercent: integer, fullHeal: boolean, iconImage?: string) { 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');
} }
} }

View File

@ -754,6 +754,7 @@ 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 }); this.turnData.attacksReceived.unshift({ move: move.id, result: result as DamageResult, damage: damage.value, critical: isCritical, sourceId: source.id });
} }
if (source.turnData.hitsLeft === 1) {
switch (result) { switch (result) {
case HitResult.SUPER_EFFECTIVE: case HitResult.SUPER_EFFECTIVE:
this.scene.queueMessage('It\'s super effective!'); this.scene.queueMessage('It\'s super effective!');
@ -765,6 +766,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.scene.queueMessage(`It doesn\'t affect ${this.name}!`); this.scene.queueMessage(`It doesn\'t affect ${this.name}!`);
break; break;
} }
}
if (damage) if (damage)
this.scene.clearPhaseQueueSplice(); this.scene.clearPhaseQueueSplice();