Add form change animation and additional final boss changes

pull/14/head
Flashfyre 2024-01-13 20:15:55 -05:00
parent 052564f902
commit 40d2c200a4
6 changed files with 105 additions and 15 deletions

View File

@ -286,7 +286,7 @@ export abstract class FieldPhase extends BattlePhase {
}
executeForAll(func: PokemonFunc): void {
const field = this.scene.getField().filter(p => p?.isActive());
const field = this.scene.getField().filter(p => p?.summonData && p.isActive());
field.forEach(pokemon => func(pokemon));
}
}
@ -2389,6 +2389,14 @@ export class DamagePhase extends PokemonPhase {
this.scene.addEnemyModifier(getModifierType(modifierTypes.MINI_BLACK_HOLE).newModifier(pokemon) as PersistentModifier, false, true);
pokemon.generateAndPopulateMoveset(1);
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
this.scene.currentBattle.double = true;
const availablePartyMembers = this.scene.getParty().filter(p => !p.isFainted());
if (availablePartyMembers.length > 1) {
this.scene.pushPhase(new ToggleDoublePositionPhase(this.scene, true));
if (!availablePartyMembers[1].isOnField())
this.scene.pushPhase(new SummonPhase(this.scene, 1));
}
super.end();
}, null, true);
return;

View File

@ -760,8 +760,8 @@ export abstract class BattleAnim {
if (isUser && target === user)
continue;
const sprites = spriteCache[isUser ? AnimFrameTarget.USER : AnimFrameTarget.TARGET];
const spriteSource = isUser ? userSprite : targetSprite;
if ((isUser ? u : t) === sprites.length) {
const spriteSource = isUser ? userSprite : targetSprite;
let sprite: Phaser.GameObjects.Sprite;
sprite = scene.addFieldSprite(0, 0, spriteSource.texture, spriteSource.frame.name);
sprite.setPipeline(scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: true });
@ -772,12 +772,12 @@ export abstract class BattleAnim {
}
const spriteIndex = isUser ? u++ : t++;
const pokemonSprite = sprites[spriteIndex];
const pokemonSprite = sprites[spriteIndex];
const graphicFrameData = frameData.get(frame.target).get(spriteIndex);
pokemonSprite.setPosition(graphicFrameData.x, graphicFrameData.y);
pokemonSprite.setPosition(graphicFrameData.x, graphicFrameData.y - ((spriteSource.height / 2) * (spriteSource.parentContainer.scale - 1)));
pokemonSprite.setAngle(graphicFrameData.angle);
pokemonSprite.setScale(graphicFrameData.scaleX, graphicFrameData.scaleY);
pokemonSprite.setScale(graphicFrameData.scaleX * spriteSource.parentContainer.scale, graphicFrameData.scaleY * spriteSource.parentContainer.scale);
pokemonSprite.setData('locked', frame.locked);

View File

@ -257,7 +257,7 @@ export const battleSpecDialogue = {
$Each cycle your mind reverts to its former state.\nEven so, somehow, remnants of your former selves remain.
$Until now you have yet to succeed, but I sense a different presence in you this time.\n
$You are the only one here, though it is as if there is another.
$Will you finally prove a formidable challenge to me?\nThe challenge I have longed for for millenia?
$Will you finally prove a formidable challenge to me?\nThe challenge I have longed for for millennia?
$We begin.`,
firstStageWin: `I see. The presence I felt was indeed real.\nIt appears I no longer need to hold back.
$Do not disappoint me.`,

View File

@ -182,8 +182,79 @@ export class QuietFormChangePhase extends BattlePhase {
return this.end();
const preName = this.pokemon.name;
this.pokemon.changeForm(this.formChange).then(() => {
this.scene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), Utils.fixedInt(1500));
const getPokemonSprite = () => {
const sprite = this.scene.addFieldSprite(this.pokemon.x + this.pokemon.getSprite().x, this.pokemon.y + this.pokemon.getSprite().y, `pkmn__sub`);
sprite.setOrigin(0.5, 1);
sprite.play(this.pokemon.getSpriteKey()).stop();
sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false });
[ 'spriteColors', 'fusionSpriteColors' ].map(k => {
if (this.pokemon.summonData?.speciesForm)
k += 'Base';
sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k];
});
this.scene.field.add(sprite);
return sprite;
}
const [ pokemonTintSprite, pokemonFormTintSprite ] = [ getPokemonSprite(), getPokemonSprite() ];
this.pokemon.getSprite().on('animationupdate', (_anim, frame) => {
if (frame.textureKey === pokemonTintSprite.texture.key)
pokemonTintSprite.setFrame(frame.textureFrame);
else
pokemonFormTintSprite.setFrame(frame.textureFrame);
});
pokemonTintSprite.setAlpha(0);
pokemonTintSprite.setTintFill(0xFFFFFF);
pokemonFormTintSprite.setVisible(false);
pokemonFormTintSprite.setTintFill(0xFFFFFF);
this.scene.playSound('PRSFX- Transform');
this.scene.tweens.add({
targets: pokemonTintSprite,
alpha: 1,
duration: 1000,
ease: 'Cubic.easeIn',
onComplete: () => {
this.pokemon.setVisible(false);
this.pokemon.changeForm(this.formChange).then(() => {
pokemonFormTintSprite.setScale(0.01);
pokemonFormTintSprite.play(this.pokemon.getSpriteKey()).stop();
pokemonFormTintSprite.setVisible(true);
this.scene.tweens.add({
targets: pokemonTintSprite,
delay: 250,
scale: 0.01,
ease: 'Cubic.easeInOut',
duration: 500,
onComplete: () => pokemonTintSprite.destroy()
});
this.scene.tweens.add({
targets: pokemonFormTintSprite,
delay: 250,
scale: 1,
ease: 'Cubic.easeInOut',
duration: 500,
onComplete: () => {
this.pokemon.setVisible(true);
this.scene.tweens.add({
targets: pokemonFormTintSprite,
delay: 250,
alpha: 0,
ease: 'Cubic.easeOut',
duration: 1000,
onComplete: () => {
pokemonTintSprite.setVisible(false);
this.scene.ui.showText(getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName), null, () => this.end(), Utils.fixedInt(1500));
}
});
}
});
});
}
});
}

View File

@ -212,15 +212,18 @@ export default class SpritePipeline extends FieldSpritePipeline {
const spriteColors = (ignoreOverride && data['spriteColorsBase']) || data['spriteColors'] || [] as number[][];
const fusionSpriteColors = (ignoreOverride && data['fusionSpriteColorsBase']) || data['fusionSpriteColors'] || [] as number[][];
const position = sprite.parentContainer instanceof Pokemon || sprite.parentContainer instanceof Trainer
const isEntityObj = sprite.parentContainer instanceof Pokemon || sprite.parentContainer instanceof Trainer;
const position = isEntityObj
? [ sprite.parentContainer.x, sprite.parentContainer.y ]
: [ sprite.x, sprite.y ];
position[0] += -(sprite.width - sprite.frame.width) / 2 + sprite.frame.x;
if (sprite.originY === 0.5)
position[1] += (sprite.height / 2) * ((isEntityObj ? sprite.parentContainer : sprite).scale - 1);
this.set1i('hasShadow', hasShadow ? 1 : 0);
this.set1i('yCenter', sprite.originY === 0.5 ? 1 : 0);
this.set2f('relPosition', position[0], position[1]);
this.set2f('size', sprite.frame.width, sprite.height);
this.set1f('yOffset', sprite.height - sprite.frame.height);
this.set1f('yOffset', sprite.height - sprite.frame.height * (isEntityObj ? sprite.parentContainer.scale : sprite.scale));
this.set4fv('tone', tone);
const emptyColors = [ 0, 0, 0, 0 ];
const flatSpriteColors: integer[] = [];
@ -243,13 +246,14 @@ export default class SpritePipeline extends FieldSpritePipeline {
const hasShadow = sprite.pipelineData['hasShadow'] as boolean;
if (hasShadow) {
const baseY = (sprite.parentContainer instanceof Pokemon || sprite.parentContainer instanceof Trainer
const isEntityObj = sprite.parentContainer instanceof Pokemon || sprite.parentContainer instanceof Trainer;
const baseY = (isEntityObj
? sprite.parentContainer.y
: sprite.y + sprite.height / 2) * 6;
: sprite.y + sprite.height) * 6;
const bottomPadding = Math.ceil(sprite.height * 0.05) * 6;
const yDelta = (baseY - y1) / 6;
y2 = y1 = baseY + bottomPadding;
const pixelHeight = (v1 - v0) / sprite.frame.height;
const pixelHeight = ((v1 - v0) / (sprite.frame.height * (isEntityObj ? sprite.parentContainer.scale : sprite.scale)));
v1 += (yDelta + bottomPadding / 6) * pixelHeight;
}

View File

@ -208,6 +208,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return ret;
};
this.setScale(this.getSpriteScale());
const sprite = getSprite(true);
const tintSprite = getSprite();
@ -396,6 +398,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
: this.maskSprite;
}
getSpriteScale(): number {
return 1;
}
initShinySparkle(): void {
const shinySparkle = this.scene.addFieldSprite(0, 0, 'shiny');
shinySparkle.setVisible(false);
@ -1250,6 +1256,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.abilityIndex >= abilityCount) // Shouldn't happen
this.abilityIndex = abilityCount - 1;
this.scene.gameData.setPokemonSeen(this, true);
this.setScale(this.getSpriteScale());
this.loadAssets().then(() => {
this.calculateStats();
this.scene.updateModifiers(this.isPlayer(), true);
@ -1559,7 +1566,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.maskSprite = this.getTintSprite();
this.maskSprite.setVisible(true);
this.maskSprite.setPosition(this.x * 6, this.y * 6);
this.maskSprite.setScale(6);
this.maskSprite.setScale(6 * this.getSpriteScale());
this.maskEnabled = true;
}
}
@ -1568,7 +1575,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.maskEnabled) {
this.maskSprite.setVisible(false);
this.maskSprite.setPosition(0, 0);
this.maskSprite.setScale(1);
this.maskSprite.setScale(this.getSpriteScale());
this.maskSprite = null;
this.maskEnabled = false;
}