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 <flashfireex@gmail.com>
This commit is contained in:
NxKarim 2024-04-30 09:47:10 -06:00 committed by GitHub
parent c7bd99b345
commit 8e64eaea3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 11 deletions

View File

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

View File

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

View File

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

View File

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