This commit is contained in:
Sirz Benjie 2025-06-18 15:13:10 -06:00 committed by GitHub
commit 27ecb27efb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 146 additions and 140 deletions

View File

@ -885,8 +885,8 @@ export default class BattleScene extends SceneBase {
} }
// store info toggles to be accessible by the ui // store info toggles to be accessible by the ui
addInfoToggle(infoToggle: InfoToggle): void { addInfoToggle(...infoToggles: InfoToggle[]): void {
this.infoToggles.push(infoToggle); this.infoToggles.push(...infoToggles);
} }
// return the stored info toggles; used by ui-inputs // return the stored info toggles; used by ui-inputs

View File

@ -42,62 +42,67 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
super(UiMode.FIGHT); super(UiMode.FIGHT);
} }
/**
* Set the visibility of the objects in the move info container.
*/
private setInfoVis(visibility: boolean): void {
this.moveInfoContainer.iterate((o: Phaser.GameObjects.Components.Visible) => o.setVisible(visibility));
}
setup() { setup() {
const ui = this.getUi(); const ui = this.getUi();
this.movesContainer = globalScene.add.container(18, -38.7); this.movesContainer = globalScene.add.container(18, -38.7).setName(FightUiHandler.MOVES_CONTAINER_NAME);
this.movesContainer.setName(FightUiHandler.MOVES_CONTAINER_NAME);
ui.add(this.movesContainer); ui.add(this.movesContainer);
this.moveInfoContainer = globalScene.add.container(1, 0); this.moveInfoContainer = globalScene.add.container(1, 0).setName("move-info");
this.moveInfoContainer.setName("move-info");
ui.add(this.moveInfoContainer); ui.add(this.moveInfoContainer);
this.typeIcon = globalScene.add.sprite( this.typeIcon = globalScene.add
globalScene.scaledCanvas.width - 57, .sprite(globalScene.scaledCanvas.width - 57, -36, getLocalizedSpriteKey("types"), "unknown")
-36, .setVisible(false);
getLocalizedSpriteKey("types"),
"unknown",
);
this.typeIcon.setVisible(false);
this.moveInfoContainer.add(this.typeIcon);
this.moveCategoryIcon = globalScene.add.sprite(globalScene.scaledCanvas.width - 25, -36, "categories", "physical"); this.moveCategoryIcon = globalScene.add
this.moveCategoryIcon.setVisible(false); .sprite(globalScene.scaledCanvas.width - 25, -36, "categories", "physical")
this.moveInfoContainer.add(this.moveCategoryIcon); .setVisible(false);
this.ppLabel = addTextObject(globalScene.scaledCanvas.width - 70, -26, "PP", TextStyle.MOVE_INFO_CONTENT); this.ppLabel = addTextObject(globalScene.scaledCanvas.width - 70, -26, "PP", TextStyle.MOVE_INFO_CONTENT)
this.ppLabel.setOrigin(0.0, 0.5); .setOrigin(0.0, 0.5)
this.ppLabel.setVisible(false); .setVisible(false)
this.ppLabel.setText(i18next.t("fightUiHandler:pp")); .setText(i18next.t("fightUiHandler:pp"));
this.moveInfoContainer.add(this.ppLabel);
this.ppText = addTextObject(globalScene.scaledCanvas.width - 12, -26, "--/--", TextStyle.MOVE_INFO_CONTENT); this.ppText = addTextObject(globalScene.scaledCanvas.width - 12, -26, "--/--", TextStyle.MOVE_INFO_CONTENT)
this.ppText.setOrigin(1, 0.5); .setOrigin(1, 0.5)
this.ppText.setVisible(false); .setVisible(false);
this.moveInfoContainer.add(this.ppText);
this.powerLabel = addTextObject(globalScene.scaledCanvas.width - 70, -18, "POWER", TextStyle.MOVE_INFO_CONTENT); this.powerLabel = addTextObject(globalScene.scaledCanvas.width - 70, -18, "POWER", TextStyle.MOVE_INFO_CONTENT)
this.powerLabel.setOrigin(0.0, 0.5); .setOrigin(0.0, 0.5)
this.powerLabel.setVisible(false); .setVisible(false)
this.powerLabel.setText(i18next.t("fightUiHandler:power")); .setText(i18next.t("fightUiHandler:power"));
this.moveInfoContainer.add(this.powerLabel);
this.powerText = addTextObject(globalScene.scaledCanvas.width - 12, -18, "---", TextStyle.MOVE_INFO_CONTENT); this.powerText = addTextObject(globalScene.scaledCanvas.width - 12, -18, "---", TextStyle.MOVE_INFO_CONTENT)
this.powerText.setOrigin(1, 0.5); .setOrigin(1, 0.5)
this.powerText.setVisible(false); .setVisible(false);
this.moveInfoContainer.add(this.powerText);
this.accuracyLabel = addTextObject(globalScene.scaledCanvas.width - 70, -10, "ACC", TextStyle.MOVE_INFO_CONTENT); this.accuracyLabel = addTextObject(globalScene.scaledCanvas.width - 70, -10, "ACC", TextStyle.MOVE_INFO_CONTENT)
this.accuracyLabel.setOrigin(0.0, 0.5); .setOrigin(0.0, 0.5)
this.accuracyLabel.setVisible(false); .setVisible(false)
this.accuracyLabel.setText(i18next.t("fightUiHandler:accuracy")); .setText(i18next.t("fightUiHandler:accuracy"));
this.moveInfoContainer.add(this.accuracyLabel);
this.accuracyText = addTextObject(globalScene.scaledCanvas.width - 12, -10, "---", TextStyle.MOVE_INFO_CONTENT); this.accuracyText = addTextObject(globalScene.scaledCanvas.width - 12, -10, "---", TextStyle.MOVE_INFO_CONTENT)
this.accuracyText.setOrigin(1, 0.5); .setOrigin(1, 0.5)
this.accuracyText.setVisible(false); .setVisible(false);
this.moveInfoContainer.add(this.accuracyText);
this.moveInfoContainer.add([
this.typeIcon,
this.moveCategoryIcon,
this.ppLabel,
this.ppText,
this.powerLabel,
this.powerText,
this.accuracyLabel,
this.accuracyText,
]);
// prepare move overlay // prepare move overlay
const overlayScale = 1; const overlayScale = 1;
@ -114,15 +119,14 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
}); });
ui.add(this.moveInfoOverlay); ui.add(this.moveInfoOverlay);
// register the overlay to receive toggle events // register the overlay to receive toggle events
globalScene.addInfoToggle(this.moveInfoOverlay); globalScene.addInfoToggle(this.moveInfoOverlay, this);
globalScene.addInfoToggle(this);
} }
show(args: any[]): boolean { override show(args: [number?, Command?]): boolean {
super.show(args); super.show(args);
this.fieldIndex = args.length ? (args[0] as number) : 0; this.fieldIndex = args[0] ?? 0;
this.fromCommand = args.length > 1 ? (args[1] as Command) : Command.FIGHT; this.fromCommand = args[1] ?? Command.FIGHT;
const messageHandler = this.getUi().getMessageHandler(); const messageHandler = this.getUi().getMessageHandler();
messageHandler.bg.setVisible(false); messageHandler.bg.setVisible(false);
@ -131,8 +135,6 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
const pokemon = (globalScene.phaseManager.getCurrentPhase() as CommandPhase).getPokemon(); const pokemon = (globalScene.phaseManager.getCurrentPhase() as CommandPhase).getPokemon();
if (pokemon.tempSummonData.turnCount <= 1) { if (pokemon.tempSummonData.turnCount <= 1) {
this.setCursor(0); this.setCursor(0);
} else {
this.setCursor(this.getCursor());
} }
this.displayMoves(); this.displayMoves();
this.toggleInfo(false); // in case cancel was pressed while info toggle is active this.toggleInfo(false); // in case cancel was pressed while info toggle is active
@ -147,21 +149,10 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
*/ */
processInput(button: Button): boolean { processInput(button: Button): boolean {
const ui = this.getUi(); const ui = this.getUi();
const cursor = this.getCursor();
let success = false; let success = false;
const cursor = this.getCursor();
switch (button) { switch (button) {
case Button.CANCEL:
{
// Attempts to back out of the move selection pane are blocked in certain MEs
// TODO: Should we allow showing the summary menu at least?
const { battleType, mysteryEncounter } = globalScene.currentBattle;
if (battleType !== BattleType.MYSTERY_ENCOUNTER || !mysteryEncounter?.skipToFightInput) {
ui.setMode(UiMode.COMMAND, this.fieldIndex);
success = true;
}
}
break;
case Button.ACTION: case Button.ACTION:
if ( if (
(globalScene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand( (globalScene.phaseManager.getCurrentPhase() as CommandPhase).handleCommand(
@ -175,6 +166,15 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
ui.playError(); ui.playError();
} }
break; break;
case Button.CANCEL: {
// Cannot back out of fight menu if skipToFightInput is enabled
const { battleType, mysteryEncounter } = globalScene.currentBattle;
if (battleType !== BattleType.MYSTERY_ENCOUNTER || !mysteryEncounter?.skipToFightInput) {
ui.setMode(UiMode.COMMAND, this.fieldIndex);
success = true;
}
break;
}
case Button.UP: case Button.UP:
if (cursor >= 2) { if (cursor >= 2) {
success = this.setCursor(cursor - 2); success = this.setCursor(cursor - 2);
@ -195,8 +195,6 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
success = this.setCursor(cursor + 1); success = this.setCursor(cursor + 1);
} }
break; break;
default:
// other inputs do nothing while in fight menu
} }
if (success) { if (success) {
@ -206,21 +204,26 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
return success; return success;
} }
/**
* Adjust the visibility of move names and the cursor icon when the info overlay is toggled
* @param visible - The visibility of the info overlay; the move names and cursor's visibility will be set to the opposite
*/
toggleInfo(visible: boolean): void { toggleInfo(visible: boolean): void {
// The info overlay will already fade in, so we should hide the move name text and cursor immediately
// rather than adjusting alpha via a tween.
if (visible) { if (visible) {
this.movesContainer.setVisible(false); this.movesContainer.setVisible(false).setAlpha(0);
this.cursorObj?.setVisible(false); this.cursorObj?.setVisible(false).setAlpha(0);
return;
} }
globalScene.tweens.add({ globalScene.tweens.add({
targets: [this.movesContainer, this.cursorObj], targets: [this.movesContainer, this.cursorObj],
duration: fixedInt(125), duration: fixedInt(125),
ease: "Sine.easeInOut", ease: "Sine.easeInOut",
alpha: visible ? 0 : 1, alpha: 1,
}); });
if (!visible) { this.movesContainer.setVisible(true);
this.movesContainer.setVisible(true); this.cursorObj?.setVisible(true);
this.cursorObj?.setVisible(true);
}
} }
isActive(): boolean { isActive(): boolean {
@ -231,6 +234,64 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
return !this.fieldIndex ? this.cursor : this.cursor2; return !this.fieldIndex ? this.cursor : this.cursor2;
} }
/**@returns TextStyle according to percentage of PP remaining */
private static ppRatioToColor(ppRatio: number): TextStyle {
if (ppRatio > 0.25 && ppRatio <= 0.5) {
return TextStyle.MOVE_PP_HALF_FULL;
}
if (ppRatio > 0 && ppRatio <= 0.25) {
return TextStyle.MOVE_PP_NEAR_EMPTY;
}
if (ppRatio === 0) {
return TextStyle.MOVE_PP_EMPTY;
}
return TextStyle.MOVE_PP_FULL; // default to full if ppRatio is invalid
}
/**
* Populate the move info overlay with the information of the move at the given cursor index
* @param cursor - The cursor position to set the move info for
*/
private setMoveInfo(cursor: number): void {
const pokemon = (globalScene.phaseManager.getCurrentPhase() as CommandPhase).getPokemon();
const moveset = pokemon.getMoveset();
const hasMove = cursor < moveset.length;
this.setInfoVis(hasMove);
if (!hasMove) {
return;
}
const pokemonMove = moveset[cursor];
const moveType = pokemon.getMoveType(pokemonMove.getMove());
const textureKey = getLocalizedSpriteKey("types");
this.typeIcon.setTexture(textureKey, PokemonType[moveType].toLowerCase()).setScale(0.8);
const moveCategory = pokemonMove.getMove().category;
this.moveCategoryIcon.setTexture("categories", MoveCategory[moveCategory].toLowerCase()).setScale(1.0);
const power = pokemonMove.getMove().power;
const accuracy = pokemonMove.getMove().accuracy;
const maxPP = pokemonMove.getMovePp();
const pp = maxPP - pokemonMove.ppUsed;
const ppLeftStr = padInt(pp, 2, " ");
const ppMaxStr = padInt(maxPP, 2, " ");
this.ppText.setText(`${ppLeftStr}/${ppMaxStr}`);
this.powerText.setText(`${power >= 0 ? power : "---"}`);
this.accuracyText.setText(`${accuracy >= 0 ? accuracy : "---"}`);
const ppColorStyle = FightUiHandler.ppRatioToColor(pp / maxPP);
//** Changes the text color and shadow according to the determined TextStyle */
this.ppText.setColor(this.getTextColor(ppColorStyle, false)).setShadowColor(this.getTextColor(ppColorStyle, true));
this.moveInfoOverlay.show(pokemonMove.getMove());
pokemon.getOpponents().forEach(opponent => {
(opponent as EnemyPokemon).updateEffectiveness(this.getEffectivenessText(pokemon, opponent, pokemonMove));
});
}
setCursor(cursor: number): boolean { setCursor(cursor: number): boolean {
const ui = this.getUi(); const ui = this.getUi();
@ -244,6 +305,8 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
} }
} }
this.setMoveInfo(cursor);
if (!this.cursorObj) { if (!this.cursorObj) {
const isTera = this.fromCommand === Command.TERA; const isTera = this.fromCommand === Command.TERA;
this.cursorObj = globalScene.add.image(0, 0, isTera ? "cursor_tera" : "cursor"); this.cursorObj = globalScene.add.image(0, 0, isTera ? "cursor_tera" : "cursor");
@ -251,61 +314,6 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
ui.add(this.cursorObj); ui.add(this.cursorObj);
} }
const pokemon = (globalScene.phaseManager.getCurrentPhase() as CommandPhase).getPokemon();
const moveset = pokemon.getMoveset();
const hasMove = cursor < moveset.length;
if (hasMove) {
const pokemonMove = moveset[cursor];
const moveType = pokemon.getMoveType(pokemonMove.getMove());
const textureKey = getLocalizedSpriteKey("types");
this.typeIcon.setTexture(textureKey, PokemonType[moveType].toLowerCase()).setScale(0.8);
const moveCategory = pokemonMove.getMove().category;
this.moveCategoryIcon.setTexture("categories", MoveCategory[moveCategory].toLowerCase()).setScale(1.0);
const power = pokemonMove.getMove().power;
const accuracy = pokemonMove.getMove().accuracy;
const maxPP = pokemonMove.getMovePp();
const pp = maxPP - pokemonMove.ppUsed;
const ppLeftStr = padInt(pp, 2, " ");
const ppMaxStr = padInt(maxPP, 2, " ");
this.ppText.setText(`${ppLeftStr}/${ppMaxStr}`);
this.powerText.setText(`${power >= 0 ? power : "---"}`);
this.accuracyText.setText(`${accuracy >= 0 ? accuracy : "---"}`);
const ppPercentLeft = pp / maxPP;
//** Determines TextStyle according to percentage of PP remaining */
let ppColorStyle = TextStyle.MOVE_PP_FULL;
if (ppPercentLeft > 0.25 && ppPercentLeft <= 0.5) {
ppColorStyle = TextStyle.MOVE_PP_HALF_FULL;
} else if (ppPercentLeft > 0 && ppPercentLeft <= 0.25) {
ppColorStyle = TextStyle.MOVE_PP_NEAR_EMPTY;
} else if (ppPercentLeft === 0) {
ppColorStyle = TextStyle.MOVE_PP_EMPTY;
}
//** Changes the text color and shadow according to the determined TextStyle */
this.ppText.setColor(this.getTextColor(ppColorStyle, false));
this.ppText.setShadowColor(this.getTextColor(ppColorStyle, true));
this.moveInfoOverlay.show(pokemonMove.getMove());
pokemon.getOpponents().forEach(opponent => {
(opponent as EnemyPokemon).updateEffectiveness(this.getEffectivenessText(pokemon, opponent, pokemonMove));
});
}
this.typeIcon.setVisible(hasMove);
this.ppLabel.setVisible(hasMove);
this.ppText.setVisible(hasMove);
this.powerLabel.setVisible(hasMove);
this.powerText.setVisible(hasMove);
this.accuracyLabel.setVisible(hasMove);
this.accuracyText.setVisible(hasMove);
this.moveCategoryIcon.setVisible(hasMove);
this.cursorObj.setPosition(13 + (cursor % 2 === 1 ? 114 : 0), -31 + (cursor >= 2 ? 15 : 0)); this.cursorObj.setPosition(13 + (cursor % 2 === 1 ? 114 : 0), -31 + (cursor >= 2 ? 15 : 0));
return changed; return changed;
@ -336,14 +344,19 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
const moveset = pokemon.getMoveset(); const moveset = pokemon.getMoveset();
for (let moveIndex = 0; moveIndex < 4; moveIndex++) { for (let moveIndex = 0; moveIndex < 4; moveIndex++) {
const moveText = addTextObject(moveIndex % 2 === 0 ? 0 : 114, moveIndex < 2 ? 0 : 16, "-", TextStyle.WINDOW); const moveText = addTextObject(
moveText.setName("text-empty-move"); moveIndex % 2 === 0 ? 0 : 114,
moveIndex < 2 ? 0 : 16,
"-",
TextStyle.WINDOW,
).setName("text-empty-move");
if (moveIndex < moveset.length) { if (moveIndex < moveset.length) {
const pokemonMove = moveset[moveIndex]!; // TODO is the bang correct? const pokemonMove = moveset[moveIndex]!; // TODO is the bang correct?
moveText.setText(pokemonMove.getName()); moveText
moveText.setName(pokemonMove.getName()); .setText(pokemonMove.getName())
moveText.setColor(this.getMoveColor(pokemon, pokemonMove) ?? moveText.style.color); .setName(pokemonMove.getName())
.setColor(this.getMoveColor(pokemon, pokemonMove) ?? moveText.style.color);
} }
this.movesContainer.add(moveText); this.movesContainer.add(moveText);
@ -386,14 +399,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
super.clear(); super.clear();
const messageHandler = this.getUi().getMessageHandler(); const messageHandler = this.getUi().getMessageHandler();
this.clearMoves(); this.clearMoves();
this.typeIcon.setVisible(false); this.setInfoVis(false);
this.ppLabel.setVisible(false);
this.ppText.setVisible(false);
this.powerLabel.setVisible(false);
this.powerText.setVisible(false);
this.accuracyLabel.setVisible(false);
this.accuracyText.setVisible(false);
this.moveCategoryIcon.setVisible(false);
this.moveInfoOverlay.clear(); this.moveInfoOverlay.clear();
messageHandler.bg.setVisible(true); messageHandler.bg.setVisible(true);
this.eraseCursor(); this.eraseCursor();