pokerogue/src/phases/scan-ivs-phase.ts
innerthunder 70295280da
[Move] Implement Substitute (#2559)
* Implement Substitute

Squashed commit from working branch

* Fix integration test imports

* Use Override Helper utils + Fix Baton Pass test

* Update src/test/moves/substitute.test.ts

Co-authored-by: Adrian T. <68144167+torranx@users.noreply.github.com>

* Fix test imports + nits

* Document RemoveAllSubstitutesAttr

* Fix some strict-null issues

* more strict-null fixes

* Fix baton pass test

* Reorganized Substitute translation keys

* Added checks for substitute in contact logic

* Clean up Unseen Fist contact logic

* Remove misleading comment in Download attr

* RIP phases.ts

* Fix imports post-phase migration

* Rewrite `move.canIgnoreSubstitute` to `move.hitsSubstitute`

* Also fixed interactions with Shell Trap and Beak Blast

* Removed some leftover `canIgnoreSubstitute`s

* fix issues after beta merge

* Status move effectiveness now accounts for substitute

* More edge case tests (Counter test failing)

* Fix Counter + Trap edge cases + add Fail messagesd

* Fix leftover nit

* Resolve leftover test issues

* Fix Sub offset carrying over to Trainer fights

* Hide substitute sprite during catch attempts

* Make substitutes baton-passable again

* Remove placeholder locale keys and SPLASH_ONLY

* Fix imports and other nits

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

* ESLint

* Fix imports

* Fix incorrect `resetSprite` timing

* Fix substitute disappearing on hit (maybe?)

* More animation fixes (mostly for Roar)

---------

Co-authored-by: Adrian T. <68144167+torranx@users.noreply.github.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-09-13 12:46:22 -04:00

70 lines
3.0 KiB
TypeScript

import BattleScene from "#app/battle-scene";
import { BattlerIndex } from "#app/battle";
import { CommonBattleAnim, CommonAnim } from "#app/data/battle-anims";
import { Stat } from "#app/enums/stat";
import { getPokemonNameWithAffix } from "#app/messages";
import { getTextColor, TextStyle } from "#app/ui/text";
import { Mode } from "#app/ui/ui";
import i18next from "i18next";
import { PokemonPhase } from "./pokemon-phase";
export class ScanIvsPhase extends PokemonPhase {
private shownIvs: integer;
constructor(scene: BattleScene, battlerIndex: BattlerIndex, shownIvs: integer) {
super(scene, battlerIndex);
this.shownIvs = shownIvs;
}
start() {
super.start();
if (!this.shownIvs) {
return this.end();
}
const pokemon = this.getPokemon();
let enemyIvs: number[] = [];
let statsContainer: Phaser.GameObjects.Sprite[] = [];
let statsContainerLabels: Phaser.GameObjects.Sprite[] = [];
const enemyField = this.scene.getEnemyField();
const uiTheme = (this.scene as BattleScene).uiTheme; // Assuming uiTheme is accessible
for (let e = 0; e < enemyField.length; e++) {
enemyIvs = enemyField[e].ivs;
const currentIvs = this.scene.gameData.dexData[enemyField[e].species.getRootSpeciesId()].ivs; // we are using getRootSpeciesId() here because we want to check against the baby form, not the mid form if it exists
const ivsToShow = this.scene.ui.getMessageHandler().getTopIvs(enemyIvs, this.shownIvs);
statsContainer = enemyField[e].getBattleInfo().getStatsValueContainer().list as Phaser.GameObjects.Sprite[];
statsContainerLabels = statsContainer.filter(m => m.name.indexOf("icon_stat_label") >= 0);
for (let s = 0; s < statsContainerLabels.length; s++) {
const ivStat = Stat[statsContainerLabels[s].frame.name];
if (enemyIvs[ivStat] > currentIvs[ivStat] && ivsToShow.indexOf(Number(ivStat)) >= 0) {
const hexColour = enemyIvs[ivStat] === 31 ? getTextColor(TextStyle.PERFECT_IV, false, uiTheme) : getTextColor(TextStyle.SUMMARY_GREEN, false, uiTheme);
const hexTextColour = Phaser.Display.Color.HexStringToColor(hexColour).color;
statsContainerLabels[s].setTint(hexTextColour);
}
statsContainerLabels[s].setVisible(true);
}
}
if (!this.scene.hideIvs) {
this.scene.ui.showText(i18next.t("battle:ivScannerUseQuestion", { pokemonName: getPokemonNameWithAffix(pokemon) }), null, () => {
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, false, () => {
this.scene.ui.getMessageHandler().promptIvs(pokemon.id, pokemon.ivs, this.shownIvs).then(() => this.end());
});
}, () => {
this.scene.ui.setMode(Mode.MESSAGE);
this.scene.ui.clearText();
this.end();
});
});
} else {
this.end();
}
}
}