diff --git a/src/data/move.ts b/src/data/move.ts index c6d69c5c003..717a9094c08 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1297,9 +1297,38 @@ export class StatChangeAttr extends MoveEffectAttr { } getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { - // TODO: Add awareness of level limits - const levels = this.getLevels(user); - return (levels * 4) + (levels > 0 ? -2 : 2); + let ret = 0; + let moveLevels = this.getLevels(user); + for (let stat of this.stats) { + let levels = moveLevels; + if (levels > 0) + levels = Math.min(target.summonData.battleStats[stat] + levels, 6) - target.summonData.battleStats[stat]; + else + levels = Math.max(target.summonData.battleStats[stat] + levels, -6) - target.summonData.battleStats[stat]; + let noEffect = false; + switch (stat) { + case BattleStat.ATK: + if (this.selfTarget) + noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.PHYSICAL); + break; + case BattleStat.DEF: + if (!this.selfTarget) + noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.PHYSICAL); + break; + case BattleStat.SPATK: + if (this.selfTarget) + noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.SPECIAL); + break; + case BattleStat.SPDEF: + if (!this.selfTarget) + noEffect = !user.getMoveset().find(m => m instanceof AttackMove && m.category === MoveCategory.SPECIAL); + break; + } + if (noEffect) + continue; + ret += (levels * 4) + (levels > 0 ? -2 : 2); + } + return ret; } } @@ -1325,7 +1354,7 @@ export class HalfHpStatMaxAttr extends StatChangeAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise { return new Promise(resolve => { - const damage = user.damage(Math.floor(user.getMaxHp() / 2), true); + const damage = user.damageAndUpdate(Math.floor(user.getMaxHp() / 2), HitResult.OTHER, false, true); if (damage) user.scene.damageNumberHandler.add(user, damage); user.updateInfo().then(() => { @@ -1339,6 +1368,8 @@ export class HalfHpStatMaxAttr extends StatChangeAttr { getCondition(): MoveConditionFunc { return (user, target, move) => user.getHpRatio() > 0.5 && user.summonData.battleStats[this.stats[0]] < 6; } + + // TODO: Add benefit score that considers HP cut } export class CutHpStatBoostAttr extends StatChangeAttr { diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index ddb05ff625e..60c0b4abc9c 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -2363,7 +2363,7 @@ export class EnemyPokemon extends Pokemon { } } - this.aiType = AiType.SMART_RANDOM; + this.aiType = boss || this.hasTrainer() ? AiType.SMART : AiType.SMART_RANDOM; } initBattleInfo(): void { @@ -2461,17 +2461,21 @@ export class EnemyPokemon extends Pokemon { for (let mt of moveTargets[move.id]) { const target = this.scene.getField()[mt]; let targetScore = move.getUserBenefitScore(this, target, move) + move.getTargetBenefitScore(this, target, move) * (mt < BattlerIndex.ENEMY === this.isPlayer() ? 1 : -1); - if (move instanceof AttackMove) { + if (move.name.endsWith(' (N)')) + targetScore = -20; + else if (move instanceof AttackMove) { const effectiveness = target.getAttackMoveEffectiveness(this, pokemonMove); if (target.isPlayer() !== this.isPlayer()) { targetScore *= effectiveness; if (this.isOfType(moveType)) targetScore *= 1.5; - } else { + } else if (effectiveness) { targetScore /= effectiveness; if (this.isOfType(moveType)) targetScore /= 1.5; } + if (!targetScore) + targetScore = -20; } targetScores.push(targetScore); } @@ -2494,6 +2498,10 @@ export class EnemyPokemon extends Pokemon { if (this.aiType === AiType.SMART_RANDOM) { while (r < sortedMovePool.length - 1 && this.scene.randBattleSeedInt(8) >= 5) r++; + } else if (this.aiType === AiType.SMART) { + while (r < sortedMovePool.length - 1 && (moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) >= 0 + && this.scene.randBattleSeedInt(100) < Math.round((moveScores[movePool.indexOf(sortedMovePool[r + 1])] / moveScores[movePool.indexOf(sortedMovePool[r])]) * 50)) + r++; } console.log(movePool.map(m => m.getName()), moveScores, r, sortedMovePool.map(m => m.getName())); return { move: sortedMovePool[r].moveId, targets: moveTargets[sortedMovePool[r].moveId] };