mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-06 07:29:30 +02:00
Refactored healing phase + removed preventFullHp
param
This commit is contained in:
parent
cee6e8678a
commit
93c7ab7935
@ -2183,7 +2183,6 @@ export class SacrificialFullRestoreAttr extends SacrificialAttr {
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
this.restorePP),
|
||||
true);
|
||||
|
||||
|
@ -24,11 +24,11 @@ import { NoCritTag, WeakenMoveScreenTag } from "#data/arena-tag";
|
||||
import {
|
||||
AutotomizedTag,
|
||||
BattlerTag,
|
||||
type BattlerTagTypeMap,
|
||||
CritBoostTag,
|
||||
EncoreTag,
|
||||
ExposedTag,
|
||||
GroundedTag,
|
||||
type GrudgeTag,
|
||||
getBattlerTag,
|
||||
HighestStatBoostTag,
|
||||
MoveRestrictionBattlerTag,
|
||||
@ -4240,14 +4240,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**@overload */
|
||||
getTag(tagType: BattlerTagType.GRUDGE): GrudgeTag | undefined;
|
||||
|
||||
/** @overload */
|
||||
getTag(tagType: BattlerTagType.SUBSTITUTE): SubstituteTag | undefined;
|
||||
|
||||
/** @overload */
|
||||
getTag(tagType: BattlerTagType): BattlerTag | undefined;
|
||||
getTag<T extends BattlerTagType>(tagType: T): BattlerTagTypeMap[T] | undefined;
|
||||
|
||||
/** @overload */
|
||||
getTag<T extends BattlerTag>(tagType: Constructor<T>): T | undefined;
|
||||
|
@ -1933,7 +1933,6 @@ export class PokemonInstantReviveModifier extends PokemonHeldItemModifier {
|
||||
* @returns always `true`
|
||||
*/
|
||||
override apply(pokemon: Pokemon): boolean {
|
||||
// Restore the Pokemon to half HP
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"PokemonHealPhase",
|
||||
pokemon.getBattlerIndex(),
|
||||
@ -1948,6 +1947,7 @@ export class PokemonInstantReviveModifier extends PokemonHeldItemModifier {
|
||||
);
|
||||
|
||||
// Remove the Pokemon's FAINT status
|
||||
// TODO: Remove call to `resetStatus` once StatusEffect.FAINT is canned
|
||||
pokemon.resetStatus(true, false, true, false);
|
||||
|
||||
// Reapply Commander on the Pokemon's side of the field, if applicable
|
||||
@ -3549,24 +3549,26 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier {
|
||||
* @returns `true` if the {@linkcode Pokemon} was healed
|
||||
*/
|
||||
override apply(enemyPokemon: Pokemon): boolean {
|
||||
if (!enemyPokemon.isFullHp()) {
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"PokemonHealPhase",
|
||||
enemyPokemon.getBattlerIndex(),
|
||||
Math.max(Math.floor(enemyPokemon.getMaxHp() / (100 / this.healPercent)) * this.stackCount, 1),
|
||||
i18next.t("modifier:enemyTurnHealApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(enemyPokemon),
|
||||
}),
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
return true;
|
||||
if (enemyPokemon.isFullHp()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
// Prevent healing to full from healing tokens
|
||||
const healAmt = Math.min(
|
||||
enemyPokemon.getMaxHp() - 1,
|
||||
toDmgValue((enemyPokemon.getMaxHp() * this.stackCount * this.healPercent) / 100),
|
||||
);
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"PokemonHealPhase",
|
||||
enemyPokemon.getBattlerIndex(),
|
||||
healAmt,
|
||||
i18next.t("modifier:enemyTurnHealApply", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(enemyPokemon),
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
getMaxStackCount(): number {
|
||||
|
@ -1,12 +1,10 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import type { HealBlockTag } from "#data/battler-tags";
|
||||
import { getStatusEffectHealText } from "#data/status-effect";
|
||||
import type { BattlerIndex } from "#enums/battler-index";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { HitResult } from "#enums/hit-result";
|
||||
import { CommonAnim } from "#enums/move-anims-common";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import { HealingBoosterModifier } from "#modifiers/modifier";
|
||||
import { CommonAnimPhase } from "#phases/common-anim-phase";
|
||||
import { HealAchv } from "#system/achv";
|
||||
@ -15,13 +13,16 @@ import i18next from "i18next";
|
||||
|
||||
export class PokemonHealPhase extends CommonAnimPhase {
|
||||
public readonly phaseName = "PokemonHealPhase";
|
||||
|
||||
/** The base amount of HP to heal. */
|
||||
private hpHealed: number;
|
||||
/** The message to display upon healing the target, or `null` to show no message. */
|
||||
private message: string | null;
|
||||
/** Whether to show a message and quit out early upon healing a Pokemon already at full hp. */
|
||||
private showFullHpMessage: boolean;
|
||||
private skipAnim: boolean;
|
||||
private revive: boolean;
|
||||
private healStatus: boolean;
|
||||
private preventFullHeal: boolean;
|
||||
private fullRestorePP: boolean;
|
||||
|
||||
constructor(
|
||||
@ -32,7 +33,6 @@ export class PokemonHealPhase extends CommonAnimPhase {
|
||||
skipAnim = false,
|
||||
revive = false,
|
||||
healStatus = false,
|
||||
preventFullHeal = false,
|
||||
fullRestorePP = false,
|
||||
) {
|
||||
super(battlerIndex, undefined, CommonAnim.HEALTH_UP);
|
||||
@ -43,12 +43,11 @@ export class PokemonHealPhase extends CommonAnimPhase {
|
||||
this.skipAnim = skipAnim;
|
||||
this.revive = revive;
|
||||
this.healStatus = healStatus;
|
||||
this.preventFullHeal = preventFullHeal;
|
||||
this.fullRestorePP = fullRestorePP;
|
||||
}
|
||||
|
||||
start() {
|
||||
if (!this.skipAnim && (this.revive || this.getPokemon().hp) && !this.getPokemon().isFullHp()) {
|
||||
if (!this.skipAnim && !this.getPokemon().isFullHp()) {
|
||||
super.start();
|
||||
} else {
|
||||
this.end();
|
||||
@ -58,78 +57,72 @@ export class PokemonHealPhase extends CommonAnimPhase {
|
||||
end() {
|
||||
const pokemon = this.getPokemon();
|
||||
|
||||
if (!pokemon.isOnField() || (!this.revive && !pokemon.isActive())) {
|
||||
return super.end();
|
||||
// Prevent healing off-field pokemon
|
||||
if (!pokemon.isActive(true)) {
|
||||
super.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const hasMessage = !!this.message;
|
||||
const healOrDamage = !pokemon.isFullHp() || this.hpHealed < 0;
|
||||
const healBlock = pokemon.getTag(BattlerTagType.HEAL_BLOCK) as HealBlockTag;
|
||||
let lastStatusEffect = StatusEffect.NONE;
|
||||
|
||||
// Check for heal block, ending the phase early if healing was prevented
|
||||
const healBlock = pokemon.getTag(BattlerTagType.HEAL_BLOCK);
|
||||
if (healBlock && this.hpHealed > 0) {
|
||||
globalScene.phaseManager.queueMessage(healBlock.onActivation(pokemon));
|
||||
return super.end();
|
||||
super.end();
|
||||
return;
|
||||
}
|
||||
|
||||
if (healOrDamage) {
|
||||
const hpRestoreMultiplier = new NumberHolder(1);
|
||||
if (!this.revive) {
|
||||
globalScene.applyModifiers(HealingBoosterModifier, this.player, hpRestoreMultiplier);
|
||||
}
|
||||
const healAmount = new NumberHolder(Math.floor(this.hpHealed * hpRestoreMultiplier.value));
|
||||
if (healAmount.value < 0) {
|
||||
pokemon.damageAndUpdate(healAmount.value * -1, { result: HitResult.INDIRECT });
|
||||
healAmount.value = 0;
|
||||
}
|
||||
// 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()) {
|
||||
healAmount.value = pokemon.getMaxHp() - pokemon.hp - 1;
|
||||
}
|
||||
healAmount.value = pokemon.heal(healAmount.value);
|
||||
if (healAmount.value) {
|
||||
globalScene.damageNumberHandler.add(pokemon, healAmount.value, HitResult.HEAL);
|
||||
}
|
||||
if (pokemon.isPlayer()) {
|
||||
globalScene.validateAchvs(HealAchv, healAmount);
|
||||
if (healAmount.value > globalScene.gameData.gameStats.highestHeal) {
|
||||
globalScene.gameData.gameStats.highestHeal = healAmount.value;
|
||||
}
|
||||
}
|
||||
if (this.healStatus && !this.revive && pokemon.status) {
|
||||
lastStatusEffect = pokemon.status.effect;
|
||||
pokemon.resetStatus();
|
||||
}
|
||||
if (this.fullRestorePP) {
|
||||
for (const move of this.getPokemon().getMoveset()) {
|
||||
if (move) {
|
||||
move.ppUsed = 0;
|
||||
}
|
||||
}
|
||||
// If we would heal the user past full HP, don't.
|
||||
if (this.hpHealed >= 0 && pokemon.isFullHp()) {
|
||||
if (this.showFullHpMessage) {
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battle:hpIsFull", {
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
}),
|
||||
);
|
||||
}
|
||||
super.end();
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply the effect of healing charms for non-revival items
|
||||
const hpRestoreMultiplier = new NumberHolder(1);
|
||||
globalScene.applyModifiers(HealingBoosterModifier, this.player, hpRestoreMultiplier);
|
||||
let healAmount = Math.floor(this.hpHealed * hpRestoreMultiplier.value);
|
||||
|
||||
// If Liquid Ooze is active, damage the user for the healing amount, then return.
|
||||
// TODO: Refactor liquid ooze to not use a heal phase to do damage
|
||||
if (healAmount < 0) {
|
||||
pokemon.damageAndUpdate(-healAmount, { result: HitResult.INDIRECT });
|
||||
pokemon.updateInfo().then(() => super.end());
|
||||
} else if (this.healStatus && !this.revive && pokemon.status) {
|
||||
lastStatusEffect = pokemon.status.effect;
|
||||
return;
|
||||
}
|
||||
|
||||
// Heal the pokemon (capping at max HP), then show damage numbers and
|
||||
// do achievement validation
|
||||
healAmount = pokemon.heal(healAmount);
|
||||
globalScene.damageNumberHandler.add(pokemon, healAmount, HitResult.HEAL);
|
||||
if (pokemon.isPlayer()) {
|
||||
globalScene.validateAchvs(HealAchv, healAmount);
|
||||
globalScene.gameData.gameStats.highestHeal = Math.max(globalScene.gameData.gameStats.highestHeal, healAmount);
|
||||
}
|
||||
|
||||
// Cure status as applicable
|
||||
// TODO: This should not be the job of the healing phase
|
||||
if (this.healStatus && pokemon.status) {
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon)),
|
||||
);
|
||||
pokemon.resetStatus();
|
||||
pokemon.updateInfo().then(() => super.end());
|
||||
} else if (this.showFullHpMessage) {
|
||||
this.message = i18next.t("battle:hpIsFull", {
|
||||
pokemonName: getPokemonNameWithAffix(pokemon),
|
||||
});
|
||||
}
|
||||
|
||||
this.showMessage();
|
||||
|
||||
pokemon.updateInfo().then(() => super.end());
|
||||
}
|
||||
|
||||
private showMessage(): void {
|
||||
if (this.message) {
|
||||
globalScene.phaseManager.queueMessage(this.message);
|
||||
}
|
||||
|
||||
if (this.healStatus && lastStatusEffect && !hasMessage) {
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectHealText(lastStatusEffect, getPokemonNameWithAffix(pokemon)),
|
||||
);
|
||||
}
|
||||
|
||||
if (!healOrDamage && !lastStatusEffect) {
|
||||
super.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user