Implement unaware ability

pull/2/head
Flashfyre 2023-11-05 23:27:40 -05:00
parent cc27913728
commit 28f8fdfdc1
4 changed files with 27 additions and 10 deletions

View File

@ -25,7 +25,7 @@ import { Gender } from "./data/gender";
import { Weather, WeatherType, getRandomWeatherType, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather"; import { Weather, WeatherType, getRandomWeatherType, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather";
import { TempBattleStat } from "./data/temp-battle-stat"; import { TempBattleStat } from "./data/temp-battle-stat";
import { ArenaTagType, ArenaTrapTag, TrickRoomTag } from "./data/arena-tag"; import { ArenaTagType, ArenaTrapTag, TrickRoomTag } from "./data/arena-tag";
import { Abilities, CheckTrappedAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreWeatherEffectAbAttrs } from "./data/ability"; import { Abilities, CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreWeatherEffectAbAttrs } from "./data/ability";
import { Unlockables, getUnlockableName } from "./system/unlockables"; import { Unlockables, getUnlockableName } from "./system/unlockables";
import { getBiomeKey } from "./arena"; import { getBiomeKey } from "./arena";
import { BattleType, BattlerIndex, TurnCommand } from "./battle"; import { BattleType, BattlerIndex, TurnCommand } from "./battle";
@ -1644,6 +1644,8 @@ class MoveEffectPhase extends PokemonPhase {
const userAccuracyLevel = new Utils.IntegerHolder(this.getUserPokemon().summonData.battleStats[BattleStat.ACC]); const userAccuracyLevel = new Utils.IntegerHolder(this.getUserPokemon().summonData.battleStats[BattleStat.ACC]);
const targetEvasionLevel = new Utils.IntegerHolder(target.summonData.battleStats[BattleStat.EVA]); const targetEvasionLevel = new Utils.IntegerHolder(target.summonData.battleStats[BattleStat.EVA]);
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, target, null, userAccuracyLevel);
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, this.getUserPokemon(), null, targetEvasionLevel);
this.scene.applyModifiers(TempBattleStatBoosterModifier, this.player, TempBattleStat.ACC, userAccuracyLevel); this.scene.applyModifiers(TempBattleStatBoosterModifier, this.player, TempBattleStat.ACC, userAccuracyLevel);
const rand = Utils.randInt(100, 1); const rand = Utils.randInt(100, 1);
let accuracyMultiplier = 1; let accuracyMultiplier = 1;

View File

@ -413,6 +413,18 @@ export class BattleStatMultiplierAbAttr extends AbAttr {
} }
} }
export class IgnoreOpponentStatChangesAbAttr extends AbAttr {
constructor() {
super(false);
}
apply(pokemon: Pokemon, cancelled: Utils.BooleanHolder, args: any[]) {
(args[0] as Utils.IntegerHolder).value = 0;
return true;
}
}
export class PostSummonAbAttr extends AbAttr { export class PostSummonAbAttr extends AbAttr {
applyPostSummon(pokemon: Pokemon, args: any[]) { applyPostSummon(pokemon: Pokemon, args: any[]) {
return false; return false;
@ -1486,7 +1498,8 @@ export function initAbilities() {
new Ability(Abilities.TANGLED_FEET, "Tangled Feet (N)", "Raises Evasiveness if the Pokémon is confused.", 4), new Ability(Abilities.TANGLED_FEET, "Tangled Feet (N)", "Raises Evasiveness if the Pokémon is confused.", 4),
new Ability(Abilities.TECHNICIAN, "Technician (N)", "Powers up the Pokémon's weaker moves.", 4), new Ability(Abilities.TECHNICIAN, "Technician (N)", "Powers up the Pokémon's weaker moves.", 4),
new Ability(Abilities.TINTED_LENS, "Tinted Lens (N)", "Powers up \"not very effective\" moves.", 4), new Ability(Abilities.TINTED_LENS, "Tinted Lens (N)", "Powers up \"not very effective\" moves.", 4),
new Ability(Abilities.UNAWARE, "Unaware (N)", "Ignores any stat changes in the Pokémon.", 4), new Ability(Abilities.UNAWARE, "Unaware", "Ignores any stat changes in the Pokémon.", 4)
.attr(IgnoreOpponentStatChangesAbAttr),
new Ability(Abilities.UNBURDEN, "Unburden (N)", "Raises Speed if a held item is used.", 4), new Ability(Abilities.UNBURDEN, "Unburden (N)", "Raises Speed if a held item is used.", 4),
new Ability(Abilities.ANALYTIC, "Analytic (N)", "Boosts move power when the Pokémon moves last.", 5), new Ability(Abilities.ANALYTIC, "Analytic (N)", "Boosts move power when the Pokémon moves last.", 5),
new Ability(Abilities.BIG_PECKS, "Big Pecks", "Protects the Pokémon from Defense-lowering attacks.", 5) new Ability(Abilities.BIG_PECKS, "Big Pecks", "Protects the Pokémon from Defense-lowering attacks.", 5)

View File

@ -214,16 +214,16 @@ export class AttackMove extends Move {
attackScore = Math.pow(effectiveness - 1, 2) * effectiveness < 1 ? -2 : 2; attackScore = Math.pow(effectiveness - 1, 2) * effectiveness < 1 ? -2 : 2;
if (attackScore) { if (attackScore) {
if (this.category === MoveCategory.PHYSICAL) { if (this.category === MoveCategory.PHYSICAL) {
if (user.getBattleStat(Stat.ATK) > user.getBattleStat(Stat.SPATK)) { if (user.getBattleStat(Stat.ATK, target) > user.getBattleStat(Stat.SPATK, target)) {
const statRatio = user.getBattleStat(Stat.SPATK) / user.getBattleStat(Stat.ATK); const statRatio = user.getBattleStat(Stat.SPATK, target) / user.getBattleStat(Stat.ATK, target);
if (statRatio <= 0.75) if (statRatio <= 0.75)
attackScore *= 2; attackScore *= 2;
else if (statRatio <= 0.875) else if (statRatio <= 0.875)
attackScore *= 1.5; attackScore *= 1.5;
} }
} else { } else {
if (user.getBattleStat(Stat.SPATK) > user.getBattleStat(Stat.ATK)) { if (user.getBattleStat(Stat.SPATK, target) > user.getBattleStat(Stat.ATK, target)) {
const statRatio = user.getBattleStat(Stat.ATK) / user.getBattleStat(Stat.SPATK); const statRatio = user.getBattleStat(Stat.ATK, target) / user.getBattleStat(Stat.SPATK, target);
if (statRatio <= 0.75) if (statRatio <= 0.75)
attackScore *= 2; attackScore *= 2;
else if (statRatio <= 0.875) else if (statRatio <= 0.875)

View File

@ -22,7 +22,7 @@ import { WeatherType } from './data/weather';
import { TempBattleStat } from './data/temp-battle-stat'; import { TempBattleStat } from './data/temp-battle-stat';
import { ArenaTagType, WeakenMoveTypeTag } from './data/arena-tag'; import { ArenaTagType, WeakenMoveTypeTag } from './data/arena-tag';
import { Biome } from './data/biome'; import { Biome } from './data/biome';
import { Abilities, Ability, BattleStatMultiplierAbAttr, BlockCritAbAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, abilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from './data/ability'; import { Abilities, Ability, BattleStatMultiplierAbAttr, BlockCritAbAttr, IgnoreOpponentStatChangesAbAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, abilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from './data/ability';
import PokemonData from './system/pokemon-data'; import PokemonData from './system/pokemon-data';
import { BattlerIndex } from './battle'; import { BattlerIndex } from './battle';
import { Mode } from './ui/ui'; import { Mode } from './ui/ui';
@ -392,11 +392,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return this.stats[stat]; return this.stats[stat];
} }
getBattleStat(stat: Stat): integer { getBattleStat(stat: Stat, opponent?: Pokemon): integer {
if (stat === Stat.HP) if (stat === Stat.HP)
return this.getStat(Stat.HP); return this.getStat(Stat.HP);
const battleStat = (stat - 1) as BattleStat; const battleStat = (stat - 1) as BattleStat;
const statLevel = new Utils.IntegerHolder(this.summonData.battleStats[battleStat]); const statLevel = new Utils.IntegerHolder(this.summonData.battleStats[battleStat]);
if (opponent)
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, opponent, null, statLevel);
if (this.isPlayer()) if (this.isPlayer())
this.scene.applyModifiers(TempBattleStatBoosterModifier, this.isPlayer(), battleStat as integer as TempBattleStat, statLevel); this.scene.applyModifiers(TempBattleStatBoosterModifier, this.isPlayer(), battleStat as integer as TempBattleStat, statLevel);
const statValue = new Utils.NumberHolder(this.getStat(stat)); const statValue = new Utils.NumberHolder(this.getStat(stat));
@ -755,8 +757,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const critChance = Math.ceil(16 / Math.pow(2, critLevel.value)); const critChance = Math.ceil(16 / Math.pow(2, critLevel.value));
isCritical = !source.getTag(BattlerTagType.NO_CRIT) && !(this.getAbility().hasAttr(BlockCritAbAttr)) && (critChance === 1 || !Utils.randInt(critChance)); isCritical = !source.getTag(BattlerTagType.NO_CRIT) && !(this.getAbility().hasAttr(BlockCritAbAttr)) && (critChance === 1 || !Utils.randInt(critChance));
} }
const sourceAtk = source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK); const sourceAtk = source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this);
const targetDef = this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF); const targetDef = this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source);
const stabMultiplier = new Utils.IntegerHolder(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 criticalMultiplier = isCritical ? 2 : 1;
const isTypeImmune = (typeMultiplier.value * weatherTypeMultiplier) === 0; const isTypeImmune = (typeMultiplier.value * weatherTypeMultiplier) === 0;