From 8e64eaea3f3e6dc93572f88095e2128f1fe1a3f9 Mon Sep 17 00:00:00 2001 From: NxKarim <43686802+NxKarim@users.noreply.github.com> Date: Tue, 30 Apr 2024 09:47:10 -0600 Subject: [PATCH] Some Fixes (HPRatio, Hustle, Imposter, Sleep Talk) (#353) * Some Fixes - HP ratio related checks (`getHpRatio`): Added rounding to 2 decimals for non-precise option. - Hustle (`BattleStatMultiplierAbAttr`): added optional condition; Hustle now works only for physical attacks. - Imposter (`PostSummonTransformAbAttr`): Switch in a double battle after both foes have been defeated no longer crashes the game. - Sleep Talk (`RandomMovesetMoveAttr`): Single target moves no longer target allies. * Formatting changes for consistency --------- Co-authored-by: Flashfyre --- src/data/ability.ts | 15 +++++++++++---- src/data/move.ts | 22 +++++++++++++++++----- src/field/pokemon.ts | 2 +- src/phases.ts | 2 +- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 281a37cfd0c..2ac7d6be1ac 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -976,16 +976,19 @@ export class FieldMoveTypePowerBoostAbAttr extends FieldMovePowerBoostAbAttr { export class BattleStatMultiplierAbAttr extends AbAttr { private battleStat: BattleStat; private multiplier: number; + private condition: PokemonAttackCondition; - constructor(battleStat: BattleStat, multiplier: number) { + constructor(battleStat: BattleStat, multiplier: number, condition?: PokemonAttackCondition) { super(false); this.battleStat = battleStat; this.multiplier = multiplier; + this.condition = condition; } applyBattleStat(pokemon: Pokemon, passive: boolean, battleStat: BattleStat, statValue: Utils.NumberHolder, args: any[]): boolean | Promise { - if (battleStat === this.battleStat) { + const move = (args[0] as Move); + if (battleStat === this.battleStat && (!this.condition || this.condition(pokemon, null, move))) { statValue.value *= this.multiplier; return true; } @@ -1402,6 +1405,7 @@ export class TraceAbAttr extends PostSummonAbAttr { const targets = pokemon.getOpponents(); if (!targets.length) return false; + let target: Pokemon; if (targets.length > 1) pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); @@ -1427,6 +1431,9 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { const targets = pokemon.getOpponents(); + if (!targets.length) + return false; + let target: Pokemon; if (targets.length > 1) pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); @@ -2642,8 +2649,8 @@ export function initAbilities() { new Ability(Abilities.TRUANT, 3) .attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.TRUANT, 1, false), new Ability(Abilities.HUSTLE, 3) - .attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5) - .attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 0.8), + .attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5, (user, target, move) => move.category == MoveCategory.PHYSICAL) + .attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 0.8, (user, target, move) => move.category == MoveCategory.PHYSICAL), new Ability(Abilities.CUTE_CHARM, 3) .attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED), new Ability(Abilities.PLUS, 3) diff --git a/src/data/move.ts b/src/data/move.ts index 30c97a1ac8d..a95ce9c91f4 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -3099,11 +3099,23 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr { const moveTargets = getMoveTargets(user, move.moveId); if (!moveTargets.targets.length) return false; - const targets = moveTargets.multiple || moveTargets.targets.length === 1 - ? moveTargets.targets - : moveTargets.targets.indexOf(target.getBattlerIndex()) > -1 - ? [ target.getBattlerIndex() ] - : [ moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ]; + let selectTargets: BattlerIndex[]; + switch (true) { + case (moveTargets.multiple || moveTargets.targets.length === 1): { + selectTargets = moveTargets.targets; + break; + } + case (moveTargets.targets.indexOf(target.getBattlerIndex()) > -1): { + selectTargets = [ target.getBattlerIndex() ]; + break; + } + default: { + moveTargets.targets.splice(moveTargets.targets.indexOf(user.getAlly().getBattlerIndex())); + selectTargets = [ moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ]; + break; + } + } + const targets = selectTargets; user.getMoveQueue().push({ move: move.moveId, targets: targets, ignorePP: true }); user.scene.unshiftPhase(new MovePhase(user.scene, user, targets, moveset[moveIndex], true)); return true; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 44573542fe8..9a7bfb48621 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -658,7 +658,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { getHpRatio(precise: boolean = false): number { return precise ? this.hp / this.getMaxHp() - : ((this.hp / this.getMaxHp()) * 100) / 100; + : Math.round((this.hp / this.getMaxHp()) * 100) / 100; } generateGender(): void { diff --git a/src/phases.ts b/src/phases.ts index 8934104ed80..8eda33de20e 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -2548,7 +2548,7 @@ export class MoveEffectPhase extends PokemonPhase { : 3 / (3 + Math.min(targetEvasionLevel.value - userAccuracyLevel.value, 6)); } - applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, user, BattleStat.ACC, accuracyMultiplier); + applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, user, BattleStat.ACC, accuracyMultiplier, this.move.getMove()); const evasionMultiplier = new Utils.NumberHolder(1); applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, this.getTarget(), BattleStat.EVA, evasionMultiplier);