diff --git a/src/data/move.ts b/src/data/move.ts index e575bf9b5..d16281da6 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -287,16 +287,20 @@ export class AttackMove extends Move { attackScore = Math.pow(effectiveness - 1, 2) * effectiveness < 1 ? -2 : 2; if (attackScore) { if (this.category === MoveCategory.PHYSICAL) { - if (user.getBattleStat(Stat.ATK, target) > user.getBattleStat(Stat.SPATK, target)) { - const statRatio = user.getBattleStat(Stat.SPATK, target) / user.getBattleStat(Stat.ATK, target); + const atk = new Utils.IntegerHolder(user.getBattleStat(Stat.ATK, target)); + applyMoveAttrs(VariableAtkAttr, user, target, move, atk); + if (atk.value > user.getBattleStat(Stat.SPATK, target)) { + const statRatio = user.getBattleStat(Stat.SPATK, target) / atk.value; if (statRatio <= 0.75) attackScore *= 2; else if (statRatio <= 0.875) attackScore *= 1.5; } } else { - if (user.getBattleStat(Stat.SPATK, target) > user.getBattleStat(Stat.ATK, target)) { - const statRatio = user.getBattleStat(Stat.ATK, target) / user.getBattleStat(Stat.SPATK, target); + const spAtk = new Utils.IntegerHolder(user.getBattleStat(Stat.SPATK, target)); + applyMoveAttrs(VariableAtkAttr, user, target, move, spAtk); + if (spAtk.value > user.getBattleStat(Stat.ATK, target)) { + const statRatio = user.getBattleStat(Stat.ATK, target) / spAtk.value; if (statRatio <= 0.75) attackScore *= 2; else if (statRatio <= 0.875) @@ -1504,6 +1508,28 @@ export class HitCountPowerAttr extends VariablePowerAttr { } } +export class VariableAtkAttr extends MoveAttr { + constructor() { + super(); + } + + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { + //const atk = args[0] as Utils.IntegerHolder; + return false; + } +} + +export class DefAtkAttr extends VariableAtkAttr { + constructor() { + super(); + } + + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { + (args[0] as Utils.IntegerHolder).value = user.getBattleStat(Stat.DEF, target); + return true; + } +} + export class VariableAccuracyAttr extends MoveAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { //const accuracy = args[0] as Utils.NumberHolder; @@ -4170,7 +4196,8 @@ export function initMoves() { .attr(CutHpStatBoostAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ]) .soundBased() .danceMove(), - new AttackMove(Moves.BODY_PRESS, "Body Press (P)", Type.FIGHTING, MoveCategory.PHYSICAL, 80, 100, 10, -1, "The user attacks by slamming its body into the target. The higher the user's Defense, the more damage it can inflict on the target.", -1, 0, 8), + new AttackMove(Moves.BODY_PRESS, "Body Press", Type.FIGHTING, MoveCategory.PHYSICAL, 80, 100, 10, -1, "The user attacks by slamming its body into the target. The higher the user's Defense, the more damage it can inflict on the target.", -1, 0, 8) + .attr(DefAtkAttr), new StatusMove(Moves.DECORATE, "Decorate", Type.FAIRY, -1, 15, -1, "The user sharply raises the target's Attack and Sp. Atk stats by decorating the target.", 100, 0, 8) .attr(StatChangeAttr, BattleStat.ATK, 2) .attr(StatChangeAttr, BattleStat.SPATK, 2), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 127ec0683..1a31db0ce 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -2,7 +2,7 @@ import Phaser from 'phaser'; import BattleScene, { AnySound } from '../battle-scene'; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info'; import { Moves } from "../data/enums/moves"; -import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget } from "../data/move"; +import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget } from "../data/move"; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies } from '../data/pokemon-species'; import * as Utils from '../utils'; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type'; @@ -1073,8 +1073,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const critChance = Math.ceil(16 / Math.pow(2, critLevel.value)); isCritical = !source.getTag(BattlerTagType.NO_CRIT) && !(this.getAbility().hasAttr(BlockCritAbAttr)) && (critChance === 1 || !this.scene.currentBattle.randSeedInt(critChance)); } - const sourceAtk = source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this); - const targetDef = this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source); + const sourceAtk = new Utils.IntegerHolder(source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this)); + const targetDef = new Utils.IntegerHolder(this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source)); const criticalMultiplier = isCritical ? 2 : 1; const isTypeImmune = (typeMultiplier.value * arenaAttackTypeMultiplier) === 0; const sourceTypes = source.getTypes(); @@ -1090,8 +1090,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (sourceTeraType !== Type.UNKNOWN && matchesSourceType) stabMultiplier.value = Math.min(stabMultiplier.value + 0.5, 2.25); + applyMoveAttrs(VariableAtkAttr, source, this, move, sourceAtk); + if (!isTypeImmune) { - damage.value = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk / targetDef) / 50) + 2) * stabMultiplier.value * typeMultiplier.value * arenaAttackTypeMultiplier * ((this.scene.currentBattle.randSeedInt(15) + 85) / 100)) * criticalMultiplier; + damage.value = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk.value / targetDef.value) / 50) + 2) * stabMultiplier.value * typeMultiplier.value * arenaAttackTypeMultiplier * ((this.scene.currentBattle.randSeedInt(15) + 85) / 100)) * criticalMultiplier; if (isPhysical && source.status && source.status.effect === StatusEffect.BURN) damage.value = Math.floor(damage.value / 2); move.getAttrs(HitsTagAttr).map(hta => hta as HitsTagAttr).filter(hta => hta.doubleDamage).forEach(hta => {