pokerogue/src/phases/quiet-form-change-phase.ts
Bertie690 6d90649b92
[Refactor/Bug/Ability] Reworked BattleData, fixed Rage Fist, Harvest, Belch + Implemented Cud Chew (#5655)
* Grabbed reverted changes from stuff

* Added version migrator for rage fist data + deepMergeSpriteData tests

* fixed formattign

* Fied a few

* Fixed constructor (maybe), moved deepCopy and deepMergeSpriteData to own file

`common.ts` is hella bloated so seems legit

* Moved empty moveset verification mapping thing to upgrade script bc i wanted to

* Fixed tests

* test added

* Fixed summondata being cleared inside summonPhase, removed `summonDataPrimer`

like seriously how come no-one checked this

* Fixed test

I forgot that we outsped and oneshot

* Fixed test

* huhjjjjjb

* Hopefully fixed bug

my sanity and homework are paying the price for this lol

* added commented out console.log statement

uncomment to see new berry data

* Fixed migrate script, re-added deprecated attributes out of necessity

* Fixed failing test by not trying to mock rng

* Fixed test

* Fixed tests

* Update ability.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update ability.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update overrides.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update berry-phase.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update encounter-phase.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update game-data.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update move-phase.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Added utility function `randSeedFloat`

basically just `Phaser.math.RND.realInRange(0, 1)`

* Applied review comments, cleaned up code a bit

* Removed unnecessary null checks for turnData and co.

I explicitly made them initialized by default for this very reason

* Added tests for Last Resort regarding moveHistory

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update battle-scene.ts

Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com>

* Update the-winstrate-challenge-encounter.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update ability.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update move.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update move.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update move.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update battle-anims.ts

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Update pokemon.ts comments

* Fixed a few outstanding issues with documentation

* Updated switch summon phase comment

* Re-added BattleSummonData as TempSummonData

* Hppefully fixed -1 sprite scale glitch

* Fixed comment

* Reveted `pokemon-forms.ts`

* Fuxed constructor

* fixed -1 bug

* Revert "Added utility function `randSeedFloat`"

This reverts commit 4c3447c851.

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com>
2025-05-02 00:06:07 -05:00

185 lines
6.3 KiB
TypeScript

import { globalScene } from "#app/global-scene";
import { SemiInvulnerableTag } from "#app/data/battler-tags";
import type { SpeciesFormChange } from "#app/data/pokemon-forms";
import { getSpeciesFormChangeMessage, SpeciesFormChangeTeraTrigger } from "#app/data/pokemon-forms";
import { getTypeRgb } from "#app/data/type";
import { BattleSpec } from "#app/enums/battle-spec";
import { BattlerTagType } from "#app/enums/battler-tag-type";
import type Pokemon from "#app/field/pokemon";
import { EnemyPokemon } from "#app/field/pokemon";
import { getPokemonNameWithAffix } from "#app/messages";
import { BattlePhase } from "./battle-phase";
import { MovePhase } from "./move-phase";
import { PokemonHealPhase } from "./pokemon-heal-phase";
import {
applyAbAttrs,
ClearTerrainAbAttr,
ClearWeatherAbAttr,
PostTeraFormChangeStatChangeAbAttr,
} from "#app/data/abilities/ability";
export class QuietFormChangePhase extends BattlePhase {
protected pokemon: Pokemon;
protected formChange: SpeciesFormChange;
constructor(pokemon: Pokemon, formChange: SpeciesFormChange) {
super();
this.pokemon = pokemon;
this.formChange = formChange;
}
start(): void {
super.start();
if (this.pokemon.formIndex === this.pokemon.species.forms.findIndex(f => f.formKey === this.formChange.formKey)) {
return this.end();
}
const preName = getPokemonNameWithAffix(this.pokemon);
if (!this.pokemon.isOnField() || this.pokemon.getTag(SemiInvulnerableTag) || this.pokemon.isFainted()) {
if (this.pokemon.isPlayer() || this.pokemon.isActive()) {
this.pokemon.changeForm(this.formChange).then(() => {
globalScene.ui.showText(
getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName),
null,
() => this.end(),
1500,
);
});
} else {
this.end();
}
return;
}
const getPokemonSprite = () => {
const sprite = globalScene.addPokemonSprite(
this.pokemon,
this.pokemon.x + this.pokemon.getSprite().x,
this.pokemon.y + this.pokemon.getSprite().y,
"pkmn__sub",
);
sprite.setOrigin(0.5, 1);
const spriteKey = this.pokemon.getBattleSpriteKey();
try {
sprite.play(spriteKey).stop();
} catch (err: unknown) {
console.error(`Failed to play animation for ${spriteKey}`, err);
}
sprite.setPipeline(globalScene.spritePipeline, {
tone: [0.0, 0.0, 0.0, 0.0],
hasShadow: false,
teraColor: getTypeRgb(this.pokemon.getTeraType()),
isTerastallized: this.pokemon.isTerastallized,
});
["spriteColors", "fusionSpriteColors"].map(k => {
if (this.pokemon.summonData.speciesForm) {
k += "Base";
}
sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k];
});
globalScene.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);
globalScene.playSound("battle_anims/PRSFX- Transform");
globalScene.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);
const spriteKey = this.pokemon.getBattleSpriteKey();
try {
pokemonFormTintSprite.play(spriteKey).stop();
} catch (err: unknown) {
console.error(`Failed to play animation for ${spriteKey}`, err);
}
pokemonFormTintSprite.setVisible(true);
globalScene.tweens.add({
targets: pokemonTintSprite,
delay: 250,
scale: 0.01,
ease: "Cubic.easeInOut",
duration: 500,
onComplete: () => pokemonTintSprite.destroy(),
});
globalScene.tweens.add({
targets: pokemonFormTintSprite,
delay: 250,
scale: this.pokemon.getSpriteScale(),
ease: "Cubic.easeInOut",
duration: 500,
onComplete: () => {
this.pokemon.setVisible(true);
globalScene.tweens.add({
targets: pokemonFormTintSprite,
delay: 250,
alpha: 0,
ease: "Cubic.easeOut",
duration: 1000,
onComplete: () => {
pokemonTintSprite.setVisible(false);
globalScene.ui.showText(
getSpeciesFormChangeMessage(this.pokemon, this.formChange, preName),
null,
() => this.end(),
1500,
);
},
});
},
});
});
},
});
}
end(): void {
this.pokemon.findAndRemoveTags(t => t.tagType === BattlerTagType.AUTOTOMIZED);
if (globalScene?.currentBattle.battleSpec === BattleSpec.FINAL_BOSS && this.pokemon instanceof EnemyPokemon) {
globalScene.playBgm();
globalScene.unshiftPhase(
new PokemonHealPhase(this.pokemon.getBattlerIndex(), this.pokemon.getMaxHp(), null, false, false, false, true),
);
this.pokemon.findAndRemoveTags(() => true);
this.pokemon.bossSegments = 5;
this.pokemon.bossSegmentIndex = 4;
this.pokemon.initBattleInfo();
this.pokemon.cry();
const movePhase = globalScene.findPhase(p => p instanceof MovePhase && p.pokemon === this.pokemon) as MovePhase;
if (movePhase) {
movePhase.cancel();
}
}
if (this.formChange.trigger instanceof SpeciesFormChangeTeraTrigger) {
applyAbAttrs(PostTeraFormChangeStatChangeAbAttr, this.pokemon, null);
applyAbAttrs(ClearWeatherAbAttr, this.pokemon, null);
applyAbAttrs(ClearTerrainAbAttr, this.pokemon, null);
}
super.end();
}
}