implement Cheek Pouch ability (#987)
* Partially implement Cheek Pouch ability
* add cheek pouch trigger to EatBerryAttr class
* Partially implement Cheek Pouch ability
* add cheek pouch trigger to EatBerryAttr class
* add cheek pouch trigger to new berry phase, remove partial tag
* run auto formatter because I forgot
* hotfix berries triggering before status effects
* Revert "hotfix berries triggering before status effects"
This reverts commit 3fbbc9a165
.
* add partial tags to abilities that would be blocked by Heal Block
This commit is contained in:
parent
e7cef039c3
commit
9893c21a7e
|
@ -2662,6 +2662,38 @@ export class PreventBerryUseAbAttr extends AbAttr {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Pokemon with this ability heals by a percentage of their maximum hp after eating a berry
|
||||
* @param healPercent - Percent of Max HP to heal
|
||||
* @see {@linkcode apply()} for implementation
|
||||
*/
|
||||
export class HealFromBerryUseAbAttr extends AbAttr {
|
||||
/** Percent of Max HP to heal */
|
||||
private healPercent: number;
|
||||
|
||||
constructor(healPercent: number) {
|
||||
super();
|
||||
|
||||
// Clamp healPercent so its between [0,1].
|
||||
this.healPercent = Math.max(Math.min(healPercent, 1), 0);
|
||||
}
|
||||
|
||||
apply(pokemon: Pokemon, passive: boolean, ...args: [Utils.BooleanHolder, any[]]): boolean {
|
||||
const { name: abilityName } = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
|
||||
pokemon.scene.unshiftPhase(
|
||||
new PokemonHealPhase(
|
||||
pokemon.scene,
|
||||
pokemon.getBattlerIndex(),
|
||||
Math.max(Math.floor(pokemon.getMaxHp() * this.healPercent), 1),
|
||||
getPokemonMessage(pokemon, `'s ${abilityName}\nrestored its HP!`),
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class RunSuccessAbAttr extends AbAttr {
|
||||
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
(args[0] as Utils.IntegerHolder).value = 256;
|
||||
|
@ -3308,9 +3340,11 @@ export function initAbilities() {
|
|||
.bypassFaint(),
|
||||
new Ability(Abilities.VOLT_ABSORB, 3)
|
||||
.attr(TypeImmunityHealAbAttr, Type.ELECTRIC)
|
||||
.partial() // Healing not blocked by Heal Block
|
||||
.ignorable(),
|
||||
new Ability(Abilities.WATER_ABSORB, 3)
|
||||
.attr(TypeImmunityHealAbAttr, Type.WATER)
|
||||
.partial() // Healing not blocked by Heal Block
|
||||
.ignorable(),
|
||||
new Ability(Abilities.OBLIVIOUS, 3)
|
||||
.attr(BattlerTagImmunityAbAttr, BattlerTagType.INFATUATED)
|
||||
|
@ -3409,7 +3443,8 @@ export function initAbilities() {
|
|||
.attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.getMove().hasFlag(MoveFlags.SOUND_BASED))
|
||||
.ignorable(),
|
||||
new Ability(Abilities.RAIN_DISH, 3)
|
||||
.attr(PostWeatherLapseHealAbAttr, 1, WeatherType.RAIN, WeatherType.HEAVY_RAIN),
|
||||
.attr(PostWeatherLapseHealAbAttr, 1, WeatherType.RAIN, WeatherType.HEAVY_RAIN)
|
||||
.partial(), // Healing not blocked by Heal Block
|
||||
new Ability(Abilities.SAND_STREAM, 3)
|
||||
.attr(PostSummonWeatherChangeAbAttr, WeatherType.SANDSTORM)
|
||||
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SANDSTORM),
|
||||
|
@ -3530,6 +3565,7 @@ export function initAbilities() {
|
|||
.attr(PostWeatherLapseHealAbAttr, 2, WeatherType.RAIN, WeatherType.HEAVY_RAIN)
|
||||
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 1.25)
|
||||
.attr(TypeImmunityHealAbAttr, Type.WATER)
|
||||
.partial() // Healing not blocked by Heal Block
|
||||
.ignorable(),
|
||||
new Ability(Abilities.DOWNLOAD, 4)
|
||||
.attr(DownloadAbAttr),
|
||||
|
@ -3607,7 +3643,8 @@ export function initAbilities() {
|
|||
.ignorable(),
|
||||
new Ability(Abilities.ICE_BODY, 4)
|
||||
.attr(BlockWeatherDamageAttr, WeatherType.HAIL)
|
||||
.attr(PostWeatherLapseHealAbAttr, 1, WeatherType.HAIL, WeatherType.SNOW),
|
||||
.attr(PostWeatherLapseHealAbAttr, 1, WeatherType.HAIL, WeatherType.SNOW)
|
||||
.partial(), // Healing not blocked by Heal Block
|
||||
new Ability(Abilities.SOLID_ROCK, 4)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr,(target, user, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 0.75)
|
||||
.ignorable(),
|
||||
|
@ -3768,7 +3805,8 @@ export function initAbilities() {
|
|||
.ignorable()
|
||||
.unimplemented(),
|
||||
new Ability(Abilities.CHEEK_POUCH, 6)
|
||||
.unimplemented(),
|
||||
.attr(HealFromBerryUseAbAttr, 1/3)
|
||||
.partial(), // Healing not blocked by Heal Block
|
||||
new Ability(Abilities.PROTEAN, 6)
|
||||
.unimplemented(),
|
||||
new Ability(Abilities.FUR_COAT, 6)
|
||||
|
@ -4201,6 +4239,7 @@ export function initAbilities() {
|
|||
.ignorable(),
|
||||
new Ability(Abilities.EARTH_EATER, 9)
|
||||
.attr(TypeImmunityHealAbAttr, Type.GROUND)
|
||||
.partial() // Healing not blocked by Heal Block
|
||||
.ignorable(),
|
||||
new Ability(Abilities.MYCELIUM_MIGHT, 9)
|
||||
.attr(MoveAbilityBypassAbAttr, (pokemon, move: Move) => move.category === MoveCategory.STATUS)
|
||||
|
@ -4214,7 +4253,8 @@ export function initAbilities() {
|
|||
.attr(PostSummonStatChangeAbAttr, BattleStat.EVA, -1)
|
||||
.condition(getOncePerBattleCondition(Abilities.SUPERSWEET_SYRUP)),
|
||||
new Ability(Abilities.HOSPITALITY, 9)
|
||||
.attr(PostSummonAllyHealAbAttr, 4, true),
|
||||
.attr(PostSummonAllyHealAbAttr, 4, true)
|
||||
.partial(), // Healing not blocked by Heal Block
|
||||
new Ability(Abilities.TOXIC_CHAIN, 9)
|
||||
.attr(PostAttackApplyStatusEffectAbAttr, false, 30, StatusEffect.TOXIC),
|
||||
new Ability(Abilities.EMBODY_ASPECT_TEAL, 9)
|
||||
|
|
|
@ -12,7 +12,7 @@ import * as Utils from "../utils";
|
|||
import { WeatherType } from "./weather";
|
||||
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
|
||||
import { ArenaTagType } from "./enums/arena-tag-type";
|
||||
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, BlockItemTheftAbAttr, applyPostAttackAbAttrs, ConfusionOnStatusEffectAbAttr } from "./ability";
|
||||
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, BlockItemTheftAbAttr, applyPostAttackAbAttrs, ConfusionOnStatusEffectAbAttr, HealFromBerryUseAbAttr } from "./ability";
|
||||
import { Abilities } from "./enums/abilities";
|
||||
import { allAbilities } from "./ability";
|
||||
import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier } from "../modifier/modifier";
|
||||
|
@ -1577,8 +1577,11 @@ export class EatBerryAttr extends MoveEffectAttr {
|
|||
}
|
||||
target.scene.updateModifiers(target.isPlayer());
|
||||
}
|
||||
|
||||
this.chosenBerry = undefined;
|
||||
|
||||
applyAbAttrs(HealFromBerryUseAbAttr, target, new Utils.BooleanHolder(false));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, get
|
|||
import { TempBattleStat } from "./data/temp-battle-stat";
|
||||
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
|
||||
import { ArenaTagType } from "./data/enums/arena-tag-type";
|
||||
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, IgnoreOpponentEvasionAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr, applyPostMoveUsedAbAttrs, PostMoveUsedAbAttr } from "./data/ability";
|
||||
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, IgnoreOpponentEvasionAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr, applyPostMoveUsedAbAttrs, PostMoveUsedAbAttr, HealFromBerryUseAbAttr } from "./data/ability";
|
||||
import { Unlockables, getUnlockableName } from "./system/unlockables";
|
||||
import { getBiomeKey } from "./field/arena";
|
||||
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
|
||||
|
@ -2221,7 +2221,9 @@ export class BerryPhase extends FieldPhase {
|
|||
if (cancelled.value) {
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is too\nnervous to eat berries!"));
|
||||
} else {
|
||||
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM));
|
||||
this.scene.unshiftPhase(
|
||||
new CommonAnimPhase(this.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM)
|
||||
);
|
||||
|
||||
for (const berryModifier of this.scene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon) as BerryModifier[]) {
|
||||
if (berryModifier.consumed) {
|
||||
|
@ -2234,6 +2236,8 @@ export class BerryPhase extends FieldPhase {
|
|||
}
|
||||
|
||||
this.scene.updateModifiers(pokemon.isPlayer());
|
||||
|
||||
applyAbAttrs(HealFromBerryUseAbAttr, pokemon, new Utils.BooleanHolder(false));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue