Implement Liquid Ooze (#210)
Co-authored-by: Samuel H <flashfireex@gmail.com>
This commit is contained in:
parent
a214ed6e66
commit
fd8cb07c9b
|
@ -9,7 +9,7 @@ import { BattlerTag } from "./battler-tags";
|
||||||
import { BattlerTagType } from "./enums/battler-tag-type";
|
import { BattlerTagType } from "./enums/battler-tag-type";
|
||||||
import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
|
import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
|
||||||
import { Gender } from "./gender";
|
import { Gender } from "./gender";
|
||||||
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, allMoves } from "./move";
|
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves } from "./move";
|
||||||
import { ArenaTagSide } from "./arena-tag";
|
import { ArenaTagSide } from "./arena-tag";
|
||||||
import { ArenaTagType } from "./enums/arena-tag-type";
|
import { ArenaTagType } from "./enums/arena-tag-type";
|
||||||
import { Stat } from "./pokemon-stat";
|
import { Stat } from "./pokemon-stat";
|
||||||
|
@ -521,6 +521,16 @@ export class MoveImmunityStatChangeAbAttr extends MoveImmunityAbAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ReverseDrainAbAttr extends PostDefendAbAttr {
|
||||||
|
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||||
|
if (!!move.getMove().getAttrs(HitHealAttr).length || !!move.getMove().getAttrs(StrengthSapHealAttr).length ) {
|
||||||
|
pokemon.scene.queueMessage(getPokemonMessage(attacker, ` sucked up the liquid ooze!`));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class PostDefendStatChangeAbAttr extends PostDefendAbAttr {
|
export class PostDefendStatChangeAbAttr extends PostDefendAbAttr {
|
||||||
private condition: PokemonDefendCondition;
|
private condition: PokemonDefendCondition;
|
||||||
private stat: BattleStat;
|
private stat: BattleStat;
|
||||||
|
@ -2549,7 +2559,8 @@ export function initAbilities() {
|
||||||
new Ability(Abilities.MARVEL_SCALE, "Marvel Scale", "The Pokémon's marvelous scales boost the Defense stat if it has a status condition.", 3)
|
new Ability(Abilities.MARVEL_SCALE, "Marvel Scale", "The Pokémon's marvelous scales boost the Defense stat if it has a status condition.", 3)
|
||||||
.conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.DEF, 1.5)
|
.conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.DEF, 1.5)
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.LIQUID_OOZE, "Liquid Ooze (N)", "The oozed liquid has a strong stench, which damages attackers using any draining move.", 3),
|
new Ability(Abilities.LIQUID_OOZE, "Liquid Ooze", "The oozed liquid has a strong stench, which damages attackers using any draining move.", 3)
|
||||||
|
.attr(ReverseDrainAbAttr),
|
||||||
new Ability(Abilities.OVERGROW, "Overgrow", "Powers up Grass-type moves when the Pokémon's HP is low.", 3)
|
new Ability(Abilities.OVERGROW, "Overgrow", "Powers up Grass-type moves when the Pokémon's HP is low.", 3)
|
||||||
.attr(LowHpMoveTypePowerBoostAbAttr, Type.GRASS),
|
.attr(LowHpMoveTypePowerBoostAbAttr, Type.GRASS),
|
||||||
new Ability(Abilities.BLAZE, "Blaze", "Powers up Fire-type moves when the Pokémon's HP is low.", 3)
|
new Ability(Abilities.BLAZE, "Blaze", "Powers up Fire-type moves when the Pokémon's HP is low.", 3)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import * as Utils from "../utils";
|
||||||
import { Moves } from "./enums/moves";
|
import { Moves } from "./enums/moves";
|
||||||
import { ChargeAttr, MoveFlags, allMoves } from "./move";
|
import { ChargeAttr, MoveFlags, allMoves } from "./move";
|
||||||
import { Type } from "./type";
|
import { Type } from "./type";
|
||||||
import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, applyAbAttrs } from "./ability";
|
import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, ReverseDrainAbAttr, applyAbAttrs } from "./ability";
|
||||||
import { Abilities } from "./enums/abilities";
|
import { Abilities } from "./enums/abilities";
|
||||||
import { BattlerTagType } from "./enums/battler-tag-type";
|
import { BattlerTagType } from "./enums/battler-tag-type";
|
||||||
import { TerrainType } from "./terrain";
|
import { TerrainType } from "./terrain";
|
||||||
|
@ -292,7 +292,11 @@ export class SeedTag extends BattlerTag {
|
||||||
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, source.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.LEECH_SEED));
|
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, source.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.LEECH_SEED));
|
||||||
|
|
||||||
const damage = pokemon.damageAndUpdate(Math.max(Math.floor(pokemon.getMaxHp() / 8), 1));
|
const damage = pokemon.damageAndUpdate(Math.max(Math.floor(pokemon.getMaxHp() / 8), 1));
|
||||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(), damage, getPokemonMessage(pokemon, '\'s health is\nsapped by Leech Seed!'), false, true));
|
const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr);
|
||||||
|
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(),
|
||||||
|
!reverseDrain ? damage : damage * -1,
|
||||||
|
!reverseDrain ? getPokemonMessage(pokemon, '\'s health is\nsapped by Leech Seed!') : getPokemonMessage(source, '\'s Leech Seed\nsucked up the liquid ooze!'),
|
||||||
|
false, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import * as Utils from "../utils";
|
||||||
import { WeatherType } from "./weather";
|
import { WeatherType } from "./weather";
|
||||||
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
|
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
|
||||||
import { ArenaTagType } from "./enums/arena-tag-type";
|
import { ArenaTagType } from "./enums/arena-tag-type";
|
||||||
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr } from "./ability";
|
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr } from "./ability";
|
||||||
import { Abilities } from "./enums/abilities";
|
import { Abilities } from "./enums/abilities";
|
||||||
import { allAbilities } from './ability';
|
import { allAbilities } from './ability';
|
||||||
import { PokemonHeldItemModifier } from "../modifier/modifier";
|
import { PokemonHeldItemModifier } from "../modifier/modifier";
|
||||||
|
@ -844,8 +844,12 @@ export class HitHealAttr extends MoveEffectAttr {
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
const healAmount = Math.max(Math.floor(user.turnData.damageDealt * this.healRatio), 1);
|
||||||
|
const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr);
|
||||||
user.scene.unshiftPhase(new PokemonHealPhase(user.scene, user.getBattlerIndex(),
|
user.scene.unshiftPhase(new PokemonHealPhase(user.scene, user.getBattlerIndex(),
|
||||||
Math.max(Math.floor(user.turnData.damageDealt * this.healRatio), 1), getPokemonMessage(target, ` had its\nenergy drained!`), false, true));
|
!reverseDrain ? healAmount : healAmount * -1,
|
||||||
|
!reverseDrain ? getPokemonMessage(target, ` had its\nenergy drained!`) : undefined,
|
||||||
|
false, true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,9 +864,12 @@ export class StrengthSapHealAttr extends MoveEffectAttr {
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
const healAmount = target.stats[Stat.ATK] * (Math.max(2, 2 + target.summonData.battleStats[BattleStat.ATK]) / Math.max(2, 2 - target.summonData.battleStats[BattleStat.ATK]));
|
||||||
|
const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr);
|
||||||
user.scene.unshiftPhase(new PokemonHealPhase(user.scene, user.getBattlerIndex(),
|
user.scene.unshiftPhase(new PokemonHealPhase(user.scene, user.getBattlerIndex(),
|
||||||
target.stats[Stat.ATK] * (Math.max(2, 2 + target.summonData.battleStats[BattleStat.ATK]) / Math.max(2, 2 - target.summonData.battleStats[BattleStat.ATK])),
|
!reverseDrain ? healAmount : healAmount * -1,
|
||||||
getPokemonMessage(user, ` regained\nhealth!`), false, true));
|
!reverseDrain ? getPokemonMessage(user, ` regained\nhealth!`) : undefined,
|
||||||
|
false, true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3796,11 +3796,15 @@ export class PokemonHealPhase extends CommonAnimPhase {
|
||||||
const hasMessage = !!this.message;
|
const hasMessage = !!this.message;
|
||||||
let lastStatusEffect = StatusEffect.NONE;
|
let lastStatusEffect = StatusEffect.NONE;
|
||||||
|
|
||||||
if (!fullHp) {
|
if (!fullHp || this.hpHealed < 0) {
|
||||||
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
|
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
|
||||||
if (!this.revive)
|
if (!this.revive)
|
||||||
this.scene.applyModifiers(HealingBoosterModifier, this.player, hpRestoreMultiplier);
|
this.scene.applyModifiers(HealingBoosterModifier, this.player, hpRestoreMultiplier);
|
||||||
const healAmount = new Utils.NumberHolder(Math.floor(this.hpHealed * hpRestoreMultiplier.value));
|
const healAmount = new Utils.NumberHolder(Math.floor(this.hpHealed * hpRestoreMultiplier.value));
|
||||||
|
if (healAmount.value < 0) {
|
||||||
|
pokemon.damageAndUpdate(healAmount.value * -1, HitResult.HEAL);
|
||||||
|
healAmount.value = 0;
|
||||||
|
}
|
||||||
// Prevent healing to full if specified (in case of healing tokens so Sturdy doesn't cause a softlock)
|
// Prevent healing to full if specified (in case of healing tokens so Sturdy doesn't cause a softlock)
|
||||||
if (this.preventFullHeal && pokemon.hp + healAmount.value >= pokemon.getMaxHp())
|
if (this.preventFullHeal && pokemon.hp + healAmount.value >= pokemon.getMaxHp())
|
||||||
healAmount.value = (pokemon.getMaxHp() - pokemon.hp) - 1;
|
healAmount.value = (pokemon.getMaxHp() - pokemon.hp) - 1;
|
||||||
|
|
Loading…
Reference in New Issue