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) ]));
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;

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)
.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)

View File

@ -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');
}
}

View File

@ -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)