mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-21 00:52:47 +02:00
https://github.com/pagefaultgames/pokerogue/pull/5962/ * Fixed lint issue; ran biome on entire repository * Fixed biome.jsonc * Trimmed trailing whitespace... again... * Fixed PR template md * Fixed package json * Fixed void return issues + ran biome again * ran biome
396 lines
11 KiB
TypeScript
396 lines
11 KiB
TypeScript
import { globalScene } from "#app/global-scene";
|
|
import { SubstituteTag } from "#app/data/battler-tags";
|
|
import type Pokemon from "#app/field/pokemon";
|
|
import { BattlePhase } from "#app/phases/battle-phase";
|
|
import { isNullOrUndefined } from "#app/utils/common";
|
|
import { PokemonAnimType } from "#enums/pokemon-anim-type";
|
|
import { SpeciesId } from "#enums/species-id";
|
|
|
|
export class PokemonAnimPhase extends BattlePhase {
|
|
public readonly phaseName = "PokemonAnimPhase";
|
|
/** The type of animation to play in this phase */
|
|
protected key: PokemonAnimType;
|
|
/** The Pokemon to which this animation applies */
|
|
protected pokemon: Pokemon;
|
|
/** Any other field sprites affected by this animation */
|
|
protected fieldAssets: Phaser.GameObjects.Sprite[];
|
|
|
|
constructor(key: PokemonAnimType, pokemon: Pokemon, fieldAssets: Phaser.GameObjects.Sprite[] = []) {
|
|
super();
|
|
|
|
this.key = key;
|
|
this.pokemon = pokemon;
|
|
this.fieldAssets = fieldAssets;
|
|
}
|
|
|
|
start(): void {
|
|
super.start();
|
|
|
|
switch (this.key) {
|
|
case PokemonAnimType.SUBSTITUTE_ADD:
|
|
this.doSubstituteAddAnim();
|
|
break;
|
|
case PokemonAnimType.SUBSTITUTE_PRE_MOVE:
|
|
this.doSubstitutePreMoveAnim();
|
|
break;
|
|
case PokemonAnimType.SUBSTITUTE_POST_MOVE:
|
|
this.doSubstitutePostMoveAnim();
|
|
break;
|
|
case PokemonAnimType.SUBSTITUTE_REMOVE:
|
|
this.doSubstituteRemoveAnim();
|
|
break;
|
|
case PokemonAnimType.COMMANDER_APPLY:
|
|
this.doCommanderApplyAnim();
|
|
break;
|
|
case PokemonAnimType.COMMANDER_REMOVE:
|
|
this.doCommanderRemoveAnim();
|
|
break;
|
|
default:
|
|
this.end();
|
|
}
|
|
}
|
|
|
|
private doSubstituteAddAnim(): void {
|
|
const substitute = this.pokemon.getTag(SubstituteTag);
|
|
if (isNullOrUndefined(substitute)) {
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
const getSprite = () => {
|
|
const sprite = globalScene.addFieldSprite(
|
|
this.pokemon.x + this.pokemon.getSprite().x,
|
|
this.pokemon.y + this.pokemon.getSprite().y,
|
|
`pkmn${this.pokemon.isPlayer() ? "__back" : ""}__sub`,
|
|
);
|
|
sprite.setOrigin(0.5, 1);
|
|
globalScene.field.add(sprite);
|
|
return sprite;
|
|
};
|
|
|
|
const [subSprite, subTintSprite] = [getSprite(), getSprite()];
|
|
const subScale = this.pokemon.getSpriteScale() * (this.pokemon.isPlayer() ? 0.5 : 1);
|
|
|
|
subSprite.setVisible(false);
|
|
subSprite.setScale(subScale);
|
|
subTintSprite.setTintFill(0xffffff);
|
|
subTintSprite.setScale(0.01);
|
|
|
|
if (this.pokemon.isPlayer()) {
|
|
globalScene.field.bringToTop(this.pokemon);
|
|
}
|
|
|
|
globalScene.playSound("PRSFX- Transform");
|
|
|
|
globalScene.tweens.add({
|
|
targets: this.pokemon,
|
|
duration: 500,
|
|
x: this.pokemon.x + this.pokemon.getSubstituteOffset()[0],
|
|
y: this.pokemon.y + this.pokemon.getSubstituteOffset()[1],
|
|
alpha: 0.5,
|
|
ease: "Sine.easeIn",
|
|
});
|
|
|
|
globalScene.tweens.add({
|
|
targets: subTintSprite,
|
|
delay: 250,
|
|
scale: subScale,
|
|
ease: "Cubic.easeInOut",
|
|
duration: 500,
|
|
onComplete: () => {
|
|
subSprite.setVisible(true);
|
|
globalScene.tweens.add({
|
|
targets: subTintSprite,
|
|
delay: 250,
|
|
alpha: 0,
|
|
ease: "Cubic.easeOut",
|
|
duration: 1000,
|
|
onComplete: () => {
|
|
subTintSprite.destroy();
|
|
substitute.sprite = subSprite;
|
|
this.end();
|
|
},
|
|
});
|
|
},
|
|
});
|
|
}
|
|
|
|
private doSubstitutePreMoveAnim(): void {
|
|
if (this.fieldAssets.length !== 1) {
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
const subSprite = this.fieldAssets[0];
|
|
if (subSprite === undefined) {
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
globalScene.tweens.add({
|
|
targets: subSprite,
|
|
alpha: 0,
|
|
ease: "Sine.easeInOut",
|
|
duration: 500,
|
|
});
|
|
|
|
globalScene.tweens.add({
|
|
targets: this.pokemon,
|
|
x: subSprite.x,
|
|
y: subSprite.y,
|
|
alpha: 1,
|
|
ease: "Sine.easeInOut",
|
|
delay: 250,
|
|
duration: 500,
|
|
onComplete: () => this.end(),
|
|
});
|
|
}
|
|
|
|
private doSubstitutePostMoveAnim(): void {
|
|
if (this.fieldAssets.length !== 1) {
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
const subSprite = this.fieldAssets[0];
|
|
if (subSprite === undefined) {
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
globalScene.tweens.add({
|
|
targets: this.pokemon,
|
|
x: subSprite.x + this.pokemon.getSubstituteOffset()[0],
|
|
y: subSprite.y + this.pokemon.getSubstituteOffset()[1],
|
|
alpha: 0.5,
|
|
ease: "Sine.easeInOut",
|
|
duration: 500,
|
|
});
|
|
|
|
globalScene.tweens.add({
|
|
targets: subSprite,
|
|
alpha: 1,
|
|
ease: "Sine.easeInOut",
|
|
delay: 250,
|
|
duration: 500,
|
|
onComplete: () => this.end(),
|
|
});
|
|
}
|
|
|
|
private doSubstituteRemoveAnim(): void {
|
|
if (this.fieldAssets.length !== 1) {
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
const subSprite = this.fieldAssets[0];
|
|
if (subSprite === undefined) {
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
const getSprite = () => {
|
|
const sprite = globalScene.addFieldSprite(
|
|
subSprite.x,
|
|
subSprite.y,
|
|
`pkmn${this.pokemon.isPlayer() ? "__back" : ""}__sub`,
|
|
);
|
|
sprite.setOrigin(0.5, 1);
|
|
globalScene.field.add(sprite);
|
|
return sprite;
|
|
};
|
|
|
|
const subTintSprite = getSprite();
|
|
const subScale = this.pokemon.getSpriteScale() * (this.pokemon.isPlayer() ? 0.5 : 1);
|
|
subTintSprite.setAlpha(0);
|
|
subTintSprite.setTintFill(0xffffff);
|
|
subTintSprite.setScale(subScale);
|
|
|
|
globalScene.tweens.add({
|
|
targets: subTintSprite,
|
|
alpha: 1,
|
|
ease: "Sine.easeInOut",
|
|
duration: 500,
|
|
onComplete: () => {
|
|
subSprite.destroy();
|
|
const flashTimer = globalScene.time.addEvent({
|
|
delay: 100,
|
|
repeat: 7,
|
|
startAt: 200,
|
|
callback: () => {
|
|
globalScene.playSound("PRSFX- Substitute2.wav");
|
|
|
|
subTintSprite.setVisible(flashTimer.repeatCount % 2 === 0);
|
|
if (!flashTimer.repeatCount) {
|
|
globalScene.tweens.add({
|
|
targets: subTintSprite,
|
|
scale: 0.01,
|
|
ease: "Sine.cubicEaseIn",
|
|
duration: 500,
|
|
});
|
|
|
|
globalScene.tweens.add({
|
|
targets: this.pokemon,
|
|
x: this.pokemon.x - this.pokemon.getSubstituteOffset()[0],
|
|
y: this.pokemon.y - this.pokemon.getSubstituteOffset()[1],
|
|
alpha: 1,
|
|
ease: "Sine.easeInOut",
|
|
delay: 250,
|
|
duration: 500,
|
|
onComplete: () => {
|
|
subTintSprite.destroy();
|
|
this.end();
|
|
},
|
|
});
|
|
}
|
|
},
|
|
});
|
|
},
|
|
});
|
|
}
|
|
|
|
private doCommanderApplyAnim(): void {
|
|
if (!globalScene.currentBattle?.double) {
|
|
this.end();
|
|
return;
|
|
}
|
|
const dondozo = this.pokemon.getAlly();
|
|
|
|
if (dondozo?.species?.speciesId !== SpeciesId.DONDOZO) {
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
const tatsugiriX = this.pokemon.x + this.pokemon.getSprite().x;
|
|
const tatsugiriY = this.pokemon.y + this.pokemon.getSprite().y;
|
|
|
|
const getSourceSprite = () => {
|
|
const sprite = globalScene.addPokemonSprite(
|
|
this.pokemon,
|
|
tatsugiriX,
|
|
tatsugiriY,
|
|
this.pokemon.getSprite().texture,
|
|
this.pokemon.getSprite()!.frame.name,
|
|
true,
|
|
);
|
|
["spriteColors", "fusionSpriteColors"].map(
|
|
k => (sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k]),
|
|
);
|
|
sprite.setPipelineData("spriteKey", this.pokemon.getBattleSpriteKey());
|
|
sprite.setPipelineData("shiny", this.pokemon.shiny);
|
|
sprite.setPipelineData("variant", this.pokemon.variant);
|
|
sprite.setPipelineData("ignoreFieldPos", true);
|
|
sprite.setOrigin(0.5, 1);
|
|
this.pokemon.getSprite().on("animationupdate", (_anim, frame) => sprite.setFrame(frame.textureFrame));
|
|
globalScene.field.add(sprite);
|
|
return sprite;
|
|
};
|
|
|
|
const sourceSprite = getSourceSprite();
|
|
|
|
this.pokemon.setVisible(false);
|
|
|
|
const sourceFpOffset = this.pokemon.getFieldPositionOffset();
|
|
const dondozoFpOffset = dondozo.getFieldPositionOffset();
|
|
|
|
globalScene.playSound("se/pb_throw");
|
|
|
|
globalScene.tweens.add({
|
|
targets: sourceSprite,
|
|
duration: 375,
|
|
scale: 0.5,
|
|
x: {
|
|
value: tatsugiriX + (dondozoFpOffset[0] - sourceFpOffset[0]) / 2,
|
|
ease: "Linear",
|
|
},
|
|
y: {
|
|
value: (this.pokemon.isPlayer() ? 100 : 65) + sourceFpOffset[1],
|
|
ease: "Sine.easeOut",
|
|
},
|
|
onComplete: () => {
|
|
globalScene.field.bringToTop(dondozo);
|
|
globalScene.tweens.add({
|
|
targets: sourceSprite,
|
|
duration: 375,
|
|
scale: 0.01,
|
|
x: { value: dondozo.x, ease: "Linear" },
|
|
y: { value: dondozo.y + dondozo.height / 2, ease: "Sine.easeIn" },
|
|
onComplete: () => {
|
|
sourceSprite.destroy();
|
|
globalScene.playSound("battle_anims/PRSFX- Liquidation1.wav");
|
|
globalScene.tweens.add({
|
|
targets: dondozo,
|
|
duration: 250,
|
|
ease: "Sine.easeInOut",
|
|
scale: 0.85,
|
|
yoyo: true,
|
|
onComplete: () => this.end(),
|
|
});
|
|
},
|
|
});
|
|
},
|
|
});
|
|
}
|
|
|
|
private doCommanderRemoveAnim(): void {
|
|
// Note: unlike the other Commander animation, this is played through the
|
|
// Dondozo instead of the Tatsugiri.
|
|
const tatsugiri = this.pokemon.getAlly();
|
|
if (isNullOrUndefined(tatsugiri)) {
|
|
console.warn("Aborting COMMANDER_REMOVE anim: Tatsugiri is undefined");
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
const tatsuSprite = globalScene.addPokemonSprite(
|
|
tatsugiri,
|
|
this.pokemon.x + this.pokemon.getSprite().x,
|
|
this.pokemon.y + this.pokemon.getSprite().y + this.pokemon.height / 2,
|
|
tatsugiri.getSprite().texture,
|
|
tatsugiri.getSprite()!.frame.name,
|
|
true,
|
|
);
|
|
["spriteColors", "fusionSpriteColors"].map(
|
|
k => (tatsuSprite.pipelineData[k] = tatsugiri.getSprite().pipelineData[k]),
|
|
);
|
|
tatsuSprite.setPipelineData("spriteKey", tatsugiri.getBattleSpriteKey());
|
|
tatsuSprite.setPipelineData("shiny", tatsugiri.shiny);
|
|
tatsuSprite.setPipelineData("variant", tatsugiri.variant);
|
|
tatsuSprite.setPipelineData("ignoreFieldPos", true);
|
|
this.pokemon.getSprite().on("animationupdate", (_anim, frame) => tatsuSprite.setFrame(frame.textureFrame));
|
|
|
|
tatsuSprite.setOrigin(0.5, 1);
|
|
tatsuSprite.setScale(0.01);
|
|
|
|
globalScene.field.add(tatsuSprite);
|
|
globalScene.field.bringToTop(this.pokemon);
|
|
tatsuSprite.setVisible(true);
|
|
|
|
globalScene.tweens.add({
|
|
targets: this.pokemon,
|
|
duration: 250,
|
|
ease: "Sine.easeInOut",
|
|
scale: 1.15,
|
|
yoyo: true,
|
|
onComplete: () => {
|
|
globalScene.playSound("battle_anims/PRSFX- Liquidation4.wav");
|
|
globalScene.tweens.add({
|
|
targets: tatsuSprite,
|
|
duration: 500,
|
|
scale: 1,
|
|
x: { value: tatsugiri.x + tatsugiri.getSprite().x, ease: "Linear" },
|
|
y: {
|
|
value: tatsugiri.y + tatsugiri.getSprite().y,
|
|
ease: "Sine.easeIn",
|
|
},
|
|
onComplete: () => {
|
|
tatsugiri.setVisible(true);
|
|
tatsuSprite.destroy();
|
|
this.end();
|
|
},
|
|
});
|
|
},
|
|
});
|
|
}
|
|
}
|