RIP phases.ts

This commit is contained in:
innerthunder 2024-08-18 20:29:56 -07:00
parent 85797677a1
commit a372f94348
14 changed files with 58 additions and 5905 deletions

View File

@ -64,7 +64,6 @@ import { PlayerGender } from "#enums/player-gender";
import { Species } from "#enums/species";
import { UiTheme } from "#enums/ui-theme";
import { TimedEventManager } from "#app/timed-event-manager.js";
import { PokemonAnimPhase } from "./pokemon-anim-phase";
import { PokemonAnimType } from "./enums/pokemon-anim-type";
import i18next from "i18next";
import {TrainerType} from "#enums/trainer-type";
@ -76,6 +75,7 @@ import { MessagePhase } from "./phases/message-phase";
import { MovePhase } from "./phases/move-phase";
import { NewBiomeEncounterPhase } from "./phases/new-biome-encounter-phase";
import { NextEncounterPhase } from "./phases/next-encounter-phase";
import { PokemonAnimPhase } from "./phases/pokemon-anim-phase";
import { QuietFormChangePhase } from "./phases/quiet-form-change-phase";
import { ReturnPhase } from "./phases/return-phase";
import { SelectBiomePhase } from "./phases/select-biome-phase";

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ export class CommonAnimPhase extends PokemonPhase {
}
start() {
new CommonBattleAnim(this.anim, this.getPokemon(), this.targetIndex !== undefined ? (this.player ? this.scene.getEnemyField() : this.scene.getPlayerField())[this.targetIndex] : this.getPokemon()).play(this.scene, () => {
new CommonBattleAnim(this.anim, this.getPokemon(), this.targetIndex !== undefined ? (this.player ? this.scene.getEnemyField() : this.scene.getPlayerField())[this.targetIndex] : this.getPokemon()).play(this.scene, false, () => {
this.end();
});
}

View File

@ -57,7 +57,7 @@ export class DamagePhase extends PokemonPhase {
this.scene.damageNumberHandler.add(this.getPokemon(), this.amount, this.damageResult, this.critical);
}
if (this.damageResult !== HitResult.OTHER) {
if (this.damageResult !== HitResult.OTHER && this.amount > 0) {
const flashTimer = this.scene.time.addEvent({
delay: 100,
repeat: 5,

View File

@ -133,7 +133,7 @@ export class FaintPhase extends PokemonPhase {
y: pokemon.y + 150,
ease: "Sine.easeIn",
onComplete: () => {
pokemon.setVisible(false);
pokemon.resetSprite();
pokemon.y -= 150;
pokemon.trySetStatus(StatusEffect.FAINT);
if (pokemon.isPlayer()) {

View File

@ -31,7 +31,9 @@ export class MoveAnimTestPhase extends BattlePhase {
initMoveAnim(this.scene, moveId).then(() => {
loadMoveAnimAssets(this.scene, [moveId], true)
.then(() => {
new MoveAnim(moveId, player ? this.scene.getPlayerPokemon()! : this.scene.getEnemyPokemon()!, (player !== (allMoves[moveId] instanceof SelfStatusMove) ? this.scene.getEnemyPokemon()! : this.scene.getPlayerPokemon()!).getBattlerIndex()).play(this.scene, () => { // TODO: are the bangs correct here?
const user = player ? this.scene.getPlayerPokemon()! : this.scene.getEnemyPokemon()!;
const target = (player !== (allMoves[moveId] instanceof SelfStatusMove)) ? this.scene.getEnemyPokemon()! : this.scene.getPlayerPokemon()!;
new MoveAnim(moveId, user, target.getBattlerIndex()).play(this.scene, !allMoves[moveId].canIgnoreSubstitute(user), () => { // TODO: are the bangs correct here?
if (player) {
this.playMoveAnim(moveQueue, false);
} else {

View File

@ -3,7 +3,7 @@ import { BattlerIndex } from "#app/battle.js";
import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr, applyPostDefendAbAttrs, PostDefendAbAttr, applyPostAttackAbAttrs, PostAttackAbAttr, MaxMultiHitAbAttr, AlwaysHitAbAttr } from "#app/data/ability.js";
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag.js";
import { MoveAnim } from "#app/data/battle-anims.js";
import { BattlerTagLapseType, ProtectedTag, SemiInvulnerableTag } from "#app/data/battler-tags.js";
import { BattlerTagLapseType, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags.js";
import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr } from "#app/data/move.js";
import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms.js";
import { BattlerTagType } from "#app/enums/battler-tag-type.js";
@ -120,7 +120,7 @@ export class MoveEffectPhase extends PokemonPhase {
const applyAttrs: Promise<void>[] = [];
// Move animation only needs one target
new MoveAnim(move.id as Moves, user, this.getTarget()?.getBattlerIndex()!).play(this.scene, () => { // TODO: is the bang correct here?
new MoveAnim(move.id as Moves, user, this.getTarget()?.getBattlerIndex()!).play(this.scene, !move.canIgnoreSubstitute(user), () => { // TODO: is the bang correct here?
/** Has the move successfully hit a target (for damage) yet? */
let hasHit: boolean = false;
for (const target of targets) {
@ -245,7 +245,7 @@ export class MoveEffectPhase extends PokemonPhase {
* If the move hit, and the target doesn't have Shield Dust,
* apply the chance to flinch the target gained from King's Rock
*/
if (dealsDamage && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr)) {
if (dealsDamage && !target.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && (!target.getTag(BattlerTagType.SUBSTITUTE) || move.canIgnoreSubstitute(user))) {
const flinched = new Utils.BooleanHolder(false);
user.scene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched);
if (flinched.value) {
@ -305,7 +305,20 @@ export class MoveEffectPhase extends PokemonPhase {
}
// Wait for all move effects to finish applying, then end this phase
Promise.allSettled(applyAttrs).then(() => this.end());
Promise.allSettled(applyAttrs).then(() => {
/**
* Remove the target's substitute (if it exists and has expired)
* after all targeted effects have applied.
* This prevents blocked effects from applying until after this hit resolves.
*/
targets.forEach(target => {
const substitute = target.getTag(SubstituteTag);
if (!!substitute && substitute.hp <= 0) {
target.lapseTag(BattlerTagType.SUBSTITUTE);
}
});
this.end();
});
});
});
}

View File

@ -170,6 +170,7 @@ export class MovePhase extends BattlePhase {
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); // Remove any tags from moves like Fly/Dive/etc.
this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE);
moveQueue.shift(); // Remove the second turn of charge moves
return this.end();
}
@ -189,6 +190,7 @@ export class MovePhase extends BattlePhase {
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
this.pokemon.lapseTags(BattlerTagLapseType.MOVE_EFFECT); // Remove any tags from moves like Fly/Dive/etc.
this.pokemon.lapseTags(BattlerTagLapseType.AFTER_MOVE);
moveQueue.shift();
return this.end();

View File

@ -31,7 +31,7 @@ export class ObtainStatusEffectPhase extends PokemonPhase {
pokemon.status!.cureTurn = this.cureTurn; // TODO: is this bang correct?
}
pokemon.updateInfo(true);
new CommonBattleAnim(CommonAnim.POISON + (this.statusEffect! - 1), pokemon).play(this.scene, () => {
new CommonBattleAnim(CommonAnim.POISON + (this.statusEffect! - 1), pokemon).play(this.scene, false, () => {
this.scene.queueMessage(getStatusEffectObtainText(this.statusEffect, getPokemonNameWithAffix(pokemon), this.sourceText ?? undefined));
if (pokemon.status?.isPostTurn()) {
this.scene.pushPhase(new PostTurnStatusEffectPhase(this.scene, this.battlerIndex));

View File

@ -1,8 +1,8 @@
import BattleScene from "./battle-scene";
import { SubstituteTag } from "./data/battler-tags";
import { PokemonAnimType } from "./enums/pokemon-anim-type";
import Pokemon from "./field/pokemon";
import { BattlePhase } from "./phases";
import BattleScene from "#app/battle-scene";
import { SubstituteTag } from "#app/data/battler-tags";
import { PokemonAnimType } from "#enums/pokemon-anim-type";
import Pokemon from "#app/field/pokemon";
import { BattlePhase } from "#app/phases/battle-phase";

View File

@ -42,7 +42,7 @@ export class PostTurnStatusEffectPhase extends PokemonPhase {
this.scene.damageNumberHandler.add(this.getPokemon(), pokemon.damage(damage.value, false, true));
pokemon.updateInfo();
}
new CommonBattleAnim(CommonAnim.POISON + (pokemon.status.effect - 1), pokemon).play(this.scene, () => this.end());
new CommonBattleAnim(CommonAnim.POISON + (pokemon.status.effect - 1), pokemon).play(this.scene, false, () => this.end());
} else {
this.end();
}

View File

@ -53,7 +53,7 @@ export class ScanIvsPhase extends PokemonPhase {
this.scene.ui.setMode(Mode.CONFIRM, () => {
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.clearText();
new CommonBattleAnim(CommonAnim.LOCK_ON, pokemon, pokemon).play(this.scene, () => {
new CommonBattleAnim(CommonAnim.LOCK_ON, pokemon, pokemon).play(this.scene, false, () => {
this.scene.ui.getMessageHandler().promptIvs(pokemon.id, pokemon.ivs, this.shownIvs).then(() => this.end());
});
}, () => {

View File

@ -11,6 +11,7 @@ import { Command } from "#app/ui/command-ui-handler.js";
import i18next from "i18next";
import { PostSummonPhase } from "./post-summon-phase";
import { SummonPhase } from "./summon-phase";
import { SubstituteTag } from "#app/data/battler-tags.js";
export class SwitchSummonPhase extends SummonPhase {
private slotIndex: integer;
@ -65,6 +66,16 @@ export class SwitchSummonPhase extends SummonPhase {
if (!this.batonPass) {
(this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.removeTagsBySourceId(pokemon.id));
const substitute = pokemon.getTag(SubstituteTag);
if (!!substitute) {
this.scene.tweens.add({
targets: substitute.sprite,
duration: 250,
scale: substitute.sprite.scale * 0.5,
ease: "Sine.easeIn",
onComplete: () => substitute.sprite.destroy()
});
}
}
this.scene.ui.showText(this.player ?
@ -115,8 +126,18 @@ export class SwitchSummonPhase extends SummonPhase {
pokemonName: this.getPokemon().getNameToRender()
})
);
// Ensure improperly persisted summon data (such as tags) is cleared upon switching
if (!this.batonPass) {
/**
* If this switch is passing a Substitute, make the switched Pokemon match the returned Pokemon's state as it left.
* Otherwise, clear any persisting tags on the returned Pokemon.
*/
if (this.batonPass) {
const substitute = this.lastPokemon.getTag(SubstituteTag);
if (!!substitute) {
switchedInPokemon.x += this.lastPokemon.getSubstituteOffset()[0];
switchedInPokemon.y += this.lastPokemon.getSubstituteOffset()[1];
switchedInPokemon.setAlpha(0.5);
}
} else {
switchedInPokemon.resetBattleData();
switchedInPokemon.resetSummonData();
}

View File

@ -7,6 +7,7 @@ import GameManager from "#test/utils/gameManager";
import { getMovePosition } from "#test/utils/gameManagerUtils";
import { TurnEndPhase } from "#app/phases/turn-end-phase.js";
import { BattlerTagType } from "#app/enums/battler-tag-type.js";
import { BerryPhase } from "#app/phases/berry-phase.js";
const TIMEOUT = 20 * 1000;