Implement some abilities
parent
67f816cff4
commit
552bda9840
|
@ -2785,7 +2785,7 @@ export class PokemonHealPhase extends CommonAnimPhase {
|
|||
this.scene.applyModifiers(HealingBoosterModifier, this.player, hpRestoreMultiplier);
|
||||
const healAmount = new Utils.NumberHolder(this.hpHealed * hpRestoreMultiplier.value);
|
||||
pokemon.heal(healAmount.value);
|
||||
this.scene.validateAchvs(HealAchv, healAmount)
|
||||
this.scene.validateAchvs(HealAchv, healAmount);
|
||||
pokemon.updateInfo().then(() => super.end());
|
||||
} else if (this.showFullHpMessage)
|
||||
this.message = getPokemonMessage(pokemon, `'s\nHP is full!`);
|
||||
|
|
|
@ -291,7 +291,7 @@ export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr {
|
|||
}
|
||||
|
||||
applyPostDefend(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||
if (move.getMove().hasFlag(MoveFlags.MAKES_CONTACT) && Utils.randInt(100) < this.chance && !pokemon.status) {
|
||||
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && Utils.randInt(100) < this.chance && !pokemon.status) {
|
||||
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[Utils.randInt(this.effects.length)];
|
||||
pokemon.scene.unshiftPhase(new ObtainStatusEffectPhase(pokemon.scene, attacker.getBattlerIndex(), effect));
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr {
|
|||
}
|
||||
|
||||
applyPostDefend(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||
if (move.getMove().hasFlag(MoveFlags.MAKES_CONTACT) && Utils.randInt(100) < this.chance)
|
||||
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && Utils.randInt(100) < this.chance)
|
||||
return attacker.addTag(this.tagType, this.turnCount, move.moveId, pokemon.id);
|
||||
|
||||
return false;
|
||||
|
@ -637,6 +637,8 @@ export class BattlerTagImmunityAbAttr extends PreApplyBattlerTagAbAttr {
|
|||
|
||||
export class BlockCritAbAttr extends AbAttr { }
|
||||
|
||||
export class IgnoreContactAbAttr extends AbAttr { }
|
||||
|
||||
export class PreWeatherEffectAbAttr extends AbAttr {
|
||||
applyPreWeatherEffect(pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
return false;
|
||||
|
@ -681,19 +683,6 @@ export class SuppressWeatherEffectAbAttr extends PreWeatherEffectAbAttr {
|
|||
}
|
||||
}
|
||||
|
||||
export class PostTurnAbAttr extends AbAttr {
|
||||
applyPostTurn(pokemon: Pokemon, args: any[]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class PostTurnSpeedBoostAbAttr extends PostTurnAbAttr {
|
||||
applyPostTurn(pokemon: Pokemon, args: any[]): boolean {
|
||||
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.SPD ], 1));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
|
||||
return (pokemon: Pokemon) => {
|
||||
if (pokemon.scene.arena.weather?.isEffectSuppressed(pokemon.scene))
|
||||
|
@ -703,19 +692,6 @@ function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
|
|||
};
|
||||
}
|
||||
|
||||
export class PostTurnHealAbAttr extends PostTurnAbAttr {
|
||||
applyPostTurn(pokemon: Pokemon, args: any[]): boolean {
|
||||
if (pokemon.getHpRatio() < 1) {
|
||||
const scene = pokemon.scene;
|
||||
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.getBattlerIndex(),
|
||||
Math.max(Math.floor(pokemon.getMaxHp() / 16), 1), getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nrestored its HP a little!`), true));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class PostWeatherLapseAbAttr extends AbAttr {
|
||||
protected weatherTypes: WeatherType[];
|
||||
|
||||
|
@ -777,6 +753,32 @@ export class PostWeatherLapseDamageAbAttr extends PostWeatherLapseAbAttr {
|
|||
}
|
||||
}
|
||||
|
||||
export class PostTurnAbAttr extends AbAttr {
|
||||
applyPostTurn(pokemon: Pokemon, args: any[]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class PostTurnSpeedBoostAbAttr extends PostTurnAbAttr {
|
||||
applyPostTurn(pokemon: Pokemon, args: any[]): boolean {
|
||||
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.SPD ], 1));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class PostTurnHealAbAttr extends PostTurnAbAttr {
|
||||
applyPostTurn(pokemon: Pokemon, args: any[]): boolean {
|
||||
if (pokemon.getHpRatio() < 1) {
|
||||
const scene = pokemon.scene;
|
||||
scene.unshiftPhase(new PokemonHealPhase(scene, pokemon.getBattlerIndex(),
|
||||
Math.max(Math.floor(pokemon.getMaxHp() / 16), 1), getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nrestored its HP a little!`), true));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class StatChangeMultiplierAbAttr extends AbAttr {
|
||||
private multiplier: integer;
|
||||
|
||||
|
@ -810,6 +812,22 @@ export class ArenaTrapAbAttr extends CheckTrappedAbAttr {
|
|||
}
|
||||
}
|
||||
|
||||
export class WeightMultiplierAbAttr extends AbAttr {
|
||||
private multiplier: integer;
|
||||
|
||||
constructor(multiplier: integer) {
|
||||
super(true);
|
||||
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
apply(pokemon: Pokemon, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
(args[0] as Utils.NumberHolder).value *= this.multiplier;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export function applyAbAttrs(attrType: { new(...args: any[]): AbAttr }, pokemon: Pokemon, cancelled: Utils.BooleanHolder, ...args: any[]): void {
|
||||
if (!pokemon.canApplyAbility())
|
||||
return;
|
||||
|
@ -1712,8 +1730,10 @@ export function initAbilities() {
|
|||
new Ability(Abilities.HEALER, "Healer (N)", "Sometimes heals an ally's status condition.", 5),
|
||||
new Ability(Abilities.FRIEND_GUARD, "Friend Guard (N)", "Reduces damage done to allies.", 5),
|
||||
new Ability(Abilities.WEAK_ARMOR, "Weak Armor (N)", "Physical attacks to the Pokémon lower its Defense\nstat but sharply raise its Speed stat.", 5),
|
||||
new Ability(Abilities.HEAVY_METAL, "Heavy Metal (N)", "Doubles the Pokémon's weight.", 5),
|
||||
new Ability(Abilities.LIGHT_METAL, "Light Metal (N)", "Halves the Pokémon's weight.", 5),
|
||||
new Ability(Abilities.HEAVY_METAL, "Heavy Metal", "Doubles the Pokémon's weight.", 5)
|
||||
.attr(WeightMultiplierAbAttr, 2),
|
||||
new Ability(Abilities.LIGHT_METAL, "Light Metal", "Halves the Pokémon's weight.", 5)
|
||||
.attr(WeightMultiplierAbAttr, 0.5),
|
||||
new Ability(Abilities.MULTISCALE, "Multiscale (N)", "Reduces the amount of damage the Pokémon takes\nwhile its HP is full.", 5),
|
||||
new Ability(Abilities.TOXIC_BOOST, "Toxic Boost (N)", "Powers up physical attacks when the Pokémon\nis poisoned.", 5),
|
||||
new Ability(Abilities.FLARE_BOOST, "Flare Boost (N)", "Powers up special attacks when the Pokémon\nis burned.", 5),
|
||||
|
@ -1794,7 +1814,8 @@ export function initAbilities() {
|
|||
new Ability(Abilities.SLUSH_RUSH, "Slush Rush (N)", "Boosts the Pokémon's Speed stat in a hailstorm.", 7)
|
||||
.attr(BattleStatMultiplierAbAttr, BattleStat.SPD, 2)
|
||||
.condition(getWeatherCondition(WeatherType.HAIL)),
|
||||
new Ability(Abilities.LONG_REACH, "Long Reach (N)", "The Pokémon uses its moves without making contact\nwith the target.", 7),
|
||||
new Ability(Abilities.LONG_REACH, "Long Reach", "The Pokémon uses its moves without making contact\nwith the target.", 7)
|
||||
.attr(IgnoreContactAbAttr),
|
||||
new Ability(Abilities.LIQUID_VOICE, "Liquid Voice (N)", "All sound-based moves become Water-type moves.", 7),
|
||||
new Ability(Abilities.TRIAGE, "Triage (N)", "Gives priority to a healing move.", 7),
|
||||
new Ability(Abilities.GALVANIZE, "Galvanize (N)", "Normal-type moves become Electric-type moves.\nThe power of those moves is boosted a little.", 7),
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Type } from "./type";
|
|||
import * as Utils from "../utils";
|
||||
import { WeatherType } from "./weather";
|
||||
import { ArenaTagType, ArenaTrapTag } from "./arena-tag";
|
||||
import { Abilities, BlockRecoilDamageAttr, applyAbAttrs } from "./ability";
|
||||
import { Abilities, BlockRecoilDamageAttr, IgnoreContactAbAttr, applyAbAttrs } from "./ability";
|
||||
import { PokemonHeldItemModifier } from "../modifier/modifier";
|
||||
import { BattlerIndex } from "../battle";
|
||||
import { Stat } from "./pokemon-stat";
|
||||
|
@ -172,6 +172,17 @@ export default class Move {
|
|||
return this;
|
||||
}
|
||||
|
||||
checkFlag(flag: MoveFlags, user: Pokemon, target: Pokemon): boolean {
|
||||
switch (flag) {
|
||||
case MoveFlags.MAKES_CONTACT:
|
||||
if (user.getAbility().hasAttr(IgnoreContactAbAttr))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return !!(this.flags & flag);
|
||||
}
|
||||
|
||||
applyConditions(user: Pokemon, target: Pokemon, move: Move): boolean {
|
||||
for (let condition of this.conditions) {
|
||||
if (!condition(user, target, move))
|
||||
|
@ -1933,7 +1944,7 @@ export class WeightPowerAttr extends VariablePowerAttr {
|
|||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const power = args[0] as Utils.NumberHolder;
|
||||
|
||||
const targetWeight = target.species.weight;
|
||||
const targetWeight = target.getWeight();
|
||||
const weightThresholds = [ 10, 25, 50, 100, 200 ];
|
||||
|
||||
let w = 0;
|
||||
|
|
|
@ -22,7 +22,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, IgnoreOpponentStatChangesAbAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from './data/ability';
|
||||
import { Abilities, Ability, BattleStatMultiplierAbAttr, BlockCritAbAttr, IgnoreOpponentStatChangesAbAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from './data/ability';
|
||||
import PokemonData from './system/pokemon-data';
|
||||
import { BattlerIndex } from './battle';
|
||||
import { Mode } from './ui/ui';
|
||||
|
@ -582,6 +582,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
return this.hp && !this.getAbility().conditions.find(condition => !condition(this));
|
||||
}
|
||||
|
||||
getWeight(): number {
|
||||
const weight = new Utils.NumberHolder(this.species.weight);
|
||||
// This will trigger the ability overlay so only call this function when necessary
|
||||
applyAbAttrs(WeightMultiplierAbAttr, this, null, weight);
|
||||
return weight.value;
|
||||
}
|
||||
|
||||
getAttackMoveEffectiveness(moveType: Type): TypeDamageMultiplier {
|
||||
const types = this.getTypes();
|
||||
return getTypeDamageMultiplier(moveType, types[0]) * (types.length > 1 ? getTypeDamageMultiplier(moveType, types[1]) : 1) as TypeDamageMultiplier;
|
||||
|
|
Loading…
Reference in New Issue