From d54a4be7b4bcd2e95bc935f855d062c55d169d1a Mon Sep 17 00:00:00 2001 From: Flashfyre Date: Thu, 26 Oct 2023 20:02:30 -0400 Subject: [PATCH] Implement Adaptability ability --- src/data/ability.ts | 14 ++++++++++++-- src/pokemon.ts | 8 +++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 85f3e35d3..60d8f08f5 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -103,7 +103,7 @@ export class PreDefendAbAttr extends AbAttr { export class BlockItemTheftAbAttr extends AbAttr { apply(pokemon: Pokemon, cancelled: Utils.BooleanHolder, args: any[]): boolean { - cancelled.value = true;; + cancelled.value = true; return true; } @@ -113,6 +113,15 @@ export class BlockItemTheftAbAttr extends AbAttr { } } +export class StabBoostAbAttr extends AbAttr { + apply(pokemon: Pokemon, cancelled: Utils.BooleanHolder, args: any[]): boolean { + if ((args[0] as Utils.IntegerHolder).value > 1) + (args[0] as Utils.IntegerHolder).value += 0.5; + + return true; + } +} + export class ReceivedTypeDamageMultiplierAbAttr extends PreDefendAbAttr { private moveType: Type; private powerMultiplier: number; @@ -1330,7 +1339,8 @@ export function initAbilities() { .attr(ProtectStatAbAttr), new Ability(Abilities.WONDER_GUARD, "Wonder Guard", "Only super effective moves will hit.", 3) .attr(NonSuperEffectiveImmunityAbAttr), - new Ability(Abilities.ADAPTABILITY, "Adaptability (N)", "Powers up moves of the same type.", 4), + new Ability(Abilities.ADAPTABILITY, "Adaptability", "Powers up moves of the same type.", 4) + .attr(StabBoostAbAttr), new Ability(Abilities.AFTERMATH, "Aftermath (N)", "Damages the attacker landing the finishing hit.", 4), new Ability(Abilities.ANGER_POINT, "Anger Point (N)", "Maxes Attack after taking a critical hit.", 4), new Ability(Abilities.ANTICIPATION, "Anticipation (N)", "Senses a foe's dangerous moves.", 4), diff --git a/src/pokemon.ts b/src/pokemon.ts index 780ced83f..a4214886d 100644 --- a/src/pokemon.ts +++ b/src/pokemon.ts @@ -23,7 +23,7 @@ import { WeatherType } from './data/weather'; import { TempBattleStat } from './data/temp-battle-stat'; import { ArenaTagType, WeakenMoveTypeTag } from './data/arena-tag'; import { Biome } from './data/biome'; -import { Abilities, Ability, BattleStatMultiplierAbAttr, BlockCritAbAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, abilities, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from './data/ability'; +import { Abilities, Ability, BattleStatMultiplierAbAttr, BlockCritAbAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, abilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from './data/ability'; import PokemonData from './system/pokemon-data'; import { BattlerIndex } from './battle'; @@ -676,12 +676,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } const sourceAtk = source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK); const targetDef = this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF); - const stabMultiplier = source.species.type1 === move.type || (source.species.type2 !== null && source.species.type2 === move.type) ? 1.5 : 1; + const stabMultiplier = new Utils.IntegerHolder(source.species.type1 === move.type || (source.species.type2 !== null && source.species.type2 === move.type) ? 1.5 : 1); const criticalMultiplier = isCritical ? 2 : 1; const isTypeImmune = (typeMultiplier.value * weatherTypeMultiplier) === 0; + applyAbAttrs(StabBoostAbAttr, source, null, stabMultiplier); + if (!isTypeImmune) { - damage = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk / targetDef) / 50) + 2) * stabMultiplier * typeMultiplier.value * weatherTypeMultiplier * ((Utils.randInt(15) + 85) / 100)) * criticalMultiplier; + damage = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk / targetDef) / 50) + 2) * stabMultiplier.value * typeMultiplier.value * weatherTypeMultiplier * ((Utils.randInt(15) + 85) / 100)) * criticalMultiplier; if (isPhysical && source.status && source.status.effect === StatusEffect.BURN) damage = Math.floor(damage / 2); move.getAttrs(HitsTagAttr).map(hta => hta as HitsTagAttr).filter(hta => hta.doubleDamage).forEach(hta => {