[UI][Misc] Force users to have an active challenge (#3953)
* I hope this is good enough * renamed variable to better name * Remove random newline * When player is ready cool box * Fixed cancel behavior * standardized action/cancel behavior * Added comments --------- Co-authored-by: frutescens <info@laptop> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
This commit is contained in:
parent
84ef7f0683
commit
0cbdaab28e
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"title": "Challenge Modifiers",
|
"title": "Challenge Modifiers",
|
||||||
"illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!",
|
"illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!",
|
||||||
|
"noneSelected": "None Selected",
|
||||||
"singleGeneration": {
|
"singleGeneration": {
|
||||||
"name": "Mono Gen",
|
"name": "Mono Gen",
|
||||||
"desc": "You can only use Pokémon from Generation {{gen}}.",
|
"desc": "You can only use Pokémon from Generation {{gen}}.",
|
||||||
|
|
|
@ -5,13 +5,13 @@ import UiHandler from "./ui-handler";
|
||||||
import { addWindow } from "./ui-theme";
|
import { addWindow } from "./ui-theme";
|
||||||
import {Button} from "#enums/buttons";
|
import {Button} from "#enums/buttons";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { Challenge } from "#app/data/challenge.js";
|
import { Challenge } from "#app/data/challenge";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { Challenges } from "#app/enums/challenges.js";
|
import { Challenges } from "#app/enums/challenges";
|
||||||
import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
|
import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
|
||||||
import { Color, ShadowColor } from "#app/enums/color.js";
|
import { Color, ShadowColor } from "#app/enums/color";
|
||||||
import { SelectStarterPhase } from "#app/phases/select-starter-phase.js";
|
import { SelectStarterPhase } from "#app/phases/select-starter-phase";
|
||||||
import { TitlePhase } from "#app/phases/title-phase.js";
|
import { TitlePhase } from "#app/phases/title-phase";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all the UI for choosing optional challenges.
|
* Handles all the UI for choosing optional challenges.
|
||||||
|
@ -33,7 +33,10 @@ export default class GameChallengesUiHandler extends UiHandler {
|
||||||
|
|
||||||
private cursorObj: Phaser.GameObjects.NineSlice | null;
|
private cursorObj: Phaser.GameObjects.NineSlice | null;
|
||||||
|
|
||||||
|
private startBg: Phaser.GameObjects.NineSlice;
|
||||||
private startCursor: Phaser.GameObjects.NineSlice;
|
private startCursor: Phaser.GameObjects.NineSlice;
|
||||||
|
private startText: Phaser.GameObjects.Text;
|
||||||
|
private hasSelectedChallenge: boolean;
|
||||||
|
|
||||||
private optionsWidth: number;
|
private optionsWidth: number;
|
||||||
|
|
||||||
|
@ -104,20 +107,20 @@ export default class GameChallengesUiHandler extends UiHandler {
|
||||||
this.descriptionText.setShadow(4, 5, ShadowColor.ORANGE);
|
this.descriptionText.setShadow(4, 5, ShadowColor.ORANGE);
|
||||||
this.descriptionText.setOrigin(0, 0);
|
this.descriptionText.setOrigin(0, 0);
|
||||||
|
|
||||||
const startBg = addWindow(this.scene, 0, 0, descriptionBg.width, 24);
|
this.startBg = addWindow(this.scene, 0, 0, descriptionBg.width, 24);
|
||||||
startBg.setName("window-start-bg");
|
this.startBg.setName("window-start-bg");
|
||||||
startBg.setOrigin(0, 0);
|
this.startBg.setOrigin(0, 0);
|
||||||
startBg.setPositionRelative(descriptionBg, 0, descriptionBg.height);
|
this.startBg.setPositionRelative(descriptionBg, 0, descriptionBg.height);
|
||||||
|
|
||||||
const startText = addTextObject(this.scene, 0, 0, i18next.t("common:start"), TextStyle.SETTINGS_LABEL);
|
this.startText = addTextObject(this.scene, 0, 0, i18next.t("challenges:noneSelected"), TextStyle.SETTINGS_LABEL);
|
||||||
startText.setName("text-start");
|
this.startText.setName("text-start");
|
||||||
startText.setOrigin(0, 0);
|
this.startText.setOrigin(0, 0);
|
||||||
startText.setPositionRelative(startBg, (startBg.width - startText.displayWidth) / 2, 4);
|
this.startText.setPositionRelative(this.startBg, (this.startBg.width - this.startText.displayWidth) / 2, 4);
|
||||||
|
|
||||||
this.startCursor = this.scene.add.nineslice(0, 0, "summary_moves_cursor", undefined, descriptionBg.width - 8, 16, 1, 1, 1, 1);
|
this.startCursor = this.scene.add.nineslice(0, 0, "summary_moves_cursor", undefined, descriptionBg.width - 8, 16, 1, 1, 1, 1);
|
||||||
this.startCursor.setName("9s-start-cursor");
|
this.startCursor.setName("9s-start-cursor");
|
||||||
this.startCursor.setOrigin(0, 0);
|
this.startCursor.setOrigin(0, 0);
|
||||||
this.startCursor.setPositionRelative(startBg, 4, 3);
|
this.startCursor.setPositionRelative(this.startBg, 4, 3);
|
||||||
this.startCursor.setVisible(false);
|
this.startCursor.setVisible(false);
|
||||||
|
|
||||||
this.valuesContainer = this.scene.add.container(0, 0);
|
this.valuesContainer = this.scene.add.container(0, 0);
|
||||||
|
@ -157,8 +160,8 @@ export default class GameChallengesUiHandler extends UiHandler {
|
||||||
this.challengesContainer.add(this.optionsBg);
|
this.challengesContainer.add(this.optionsBg);
|
||||||
this.challengesContainer.add(descriptionBg);
|
this.challengesContainer.add(descriptionBg);
|
||||||
this.challengesContainer.add(this.descriptionText);
|
this.challengesContainer.add(this.descriptionText);
|
||||||
this.challengesContainer.add(startBg);
|
this.challengesContainer.add(this.startBg);
|
||||||
this.challengesContainer.add(startText);
|
this.challengesContainer.add(this.startText);
|
||||||
this.challengesContainer.add(this.startCursor);
|
this.challengesContainer.add(this.startCursor);
|
||||||
this.challengesContainer.add(this.valuesContainer);
|
this.challengesContainer.add(this.valuesContainer);
|
||||||
|
|
||||||
|
@ -216,6 +219,21 @@ export default class GameChallengesUiHandler extends UiHandler {
|
||||||
this.monoTypeValue.setVisible(false);
|
this.monoTypeValue.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This checks if a challenge has been selected by the user and updates the text/its opacity accordingly.
|
||||||
|
this.hasSelectedChallenge = this.scene.gameMode.challenges.some(c => c.value !== 0);
|
||||||
|
if (this.hasSelectedChallenge) {
|
||||||
|
|
||||||
|
this.startText.setText(i18next.t("common:start"));
|
||||||
|
this.startText.setAlpha(1);
|
||||||
|
this.startText.setPositionRelative(this.startBg, (this.startBg.width - this.startText.displayWidth) / 2, 4);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
this.startText.setText(i18next.t("challenges:noneSelected"));
|
||||||
|
this.startText.setAlpha(0.5);
|
||||||
|
this.startText.setPositionRelative(this.startBg, (this.startBg.width - this.startText.displayWidth) / 2, 4);
|
||||||
|
}
|
||||||
|
this.challengesContainer.update();
|
||||||
|
|
||||||
// const totalDifficulty = this.scene.gameMode.challenges.reduce((v, c) => v + c.getDifficulty(), 0);
|
// const totalDifficulty = this.scene.gameMode.challenges.reduce((v, c) => v + c.getDifficulty(), 0);
|
||||||
// const totalMinDifficulty = this.scene.gameMode.challenges.reduce((v, c) => v + c.getMinDifficulty(), 0);
|
// const totalMinDifficulty = this.scene.gameMode.challenges.reduce((v, c) => v + c.getMinDifficulty(), 0);
|
||||||
// this.difficultyText.text = `${totalDifficulty}` + (totalMinDifficulty ? `/${totalMinDifficulty}` : "");
|
// this.difficultyText.text = `${totalDifficulty}` + (totalMinDifficulty ? `/${totalMinDifficulty}` : "");
|
||||||
|
@ -227,6 +245,8 @@ export default class GameChallengesUiHandler extends UiHandler {
|
||||||
|
|
||||||
this.startCursor.setVisible(false);
|
this.startCursor.setVisible(false);
|
||||||
this.challengesContainer.setVisible(true);
|
this.challengesContainer.setVisible(true);
|
||||||
|
// Should always be false at the start
|
||||||
|
this.hasSelectedChallenge = this.scene.gameMode.challenges.some(c => c.value !== 0);
|
||||||
this.setCursor(0);
|
this.setCursor(0);
|
||||||
|
|
||||||
this.initLabels();
|
this.initLabels();
|
||||||
|
@ -257,6 +277,7 @@ export default class GameChallengesUiHandler extends UiHandler {
|
||||||
|
|
||||||
if (button === Button.CANCEL) {
|
if (button === Button.CANCEL) {
|
||||||
if (this.startCursor.visible) {
|
if (this.startCursor.visible) {
|
||||||
|
// If the user presses cancel when the start cursor has been activated, the game deactivates the start cursor and allows typical challenge selection behavior
|
||||||
this.startCursor.setVisible(false);
|
this.startCursor.setVisible(false);
|
||||||
this.cursorObj?.setVisible(true);
|
this.cursorObj?.setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -266,83 +287,82 @@ export default class GameChallengesUiHandler extends UiHandler {
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
} else if (button === Button.SUBMIT || button === Button.ACTION) {
|
} else if (button === Button.SUBMIT || button === Button.ACTION) {
|
||||||
if (this.startCursor.visible) {
|
if (this.hasSelectedChallenge) {
|
||||||
const totalDifficulty = this.scene.gameMode.challenges.reduce((v, c) => v + c.getDifficulty(), 0);
|
if (this.startCursor.visible) {
|
||||||
const totalMinDifficulty = this.scene.gameMode.challenges.reduce((v, c) => v + c.getMinDifficulty(), 0);
|
|
||||||
if (totalDifficulty >= totalMinDifficulty) {
|
|
||||||
this.scene.unshiftPhase(new SelectStarterPhase(this.scene));
|
this.scene.unshiftPhase(new SelectStarterPhase(this.scene));
|
||||||
this.scene.getCurrentPhase()?.end();
|
this.scene.getCurrentPhase()?.end();
|
||||||
success = true;
|
|
||||||
} else {
|
} else {
|
||||||
success = false;
|
this.startCursor.setVisible(true);
|
||||||
|
this.cursorObj?.setVisible(false);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.startCursor.setVisible(true);
|
|
||||||
this.cursorObj?.setVisible(false);
|
|
||||||
success = true;
|
success = true;
|
||||||
|
} else {
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (button) {
|
if (this.cursorObj?.visible && !this.startCursor.visible) {
|
||||||
case Button.UP:
|
switch (button) {
|
||||||
if (this.cursor === 0) {
|
case Button.UP:
|
||||||
if (this.scrollCursor === 0) {
|
if (this.cursor === 0) {
|
||||||
// When at the top of the menu and pressing UP, move to the bottommost item.
|
if (this.scrollCursor === 0) {
|
||||||
if (this.scene.gameMode.challenges.length > rowsToDisplay) { // If there are more than 9 challenges, scroll to the bottom
|
// When at the top of the menu and pressing UP, move to the bottommost item.
|
||||||
// First, set the cursor to the last visible element, preparing for the scroll to the end.
|
if (this.scene.gameMode.challenges.length > rowsToDisplay) { // If there are more than 9 challenges, scroll to the bottom
|
||||||
const successA = this.setCursor(rowsToDisplay - 1);
|
// First, set the cursor to the last visible element, preparing for the scroll to the end.
|
||||||
// Then, adjust the scroll to display the bottommost elements of the menu.
|
const successA = this.setCursor(rowsToDisplay - 1);
|
||||||
const successB = this.setScrollCursor(this.scene.gameMode.challenges.length - rowsToDisplay);
|
// Then, adjust the scroll to display the bottommost elements of the menu.
|
||||||
success = successA && successB; // success is just there to play the little validation sound effect
|
const successB = this.setScrollCursor(this.scene.gameMode.challenges.length - rowsToDisplay);
|
||||||
} else { // If there are 9 or less challenges, just move to the bottom one
|
success = successA && successB; // success is just there to play the little validation sound effect
|
||||||
success = this.setCursor(this.scene.gameMode.challenges.length - 1);
|
} else { // If there are 9 or less challenges, just move to the bottom one
|
||||||
|
success = this.setCursor(this.scene.gameMode.challenges.length - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
success = this.setScrollCursor(this.scrollCursor - 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
success = this.setScrollCursor(this.scrollCursor - 1);
|
success = this.setCursor(this.cursor - 1);
|
||||||
}
|
}
|
||||||
} else {
|
if (success) {
|
||||||
success = this.setCursor(this.cursor - 1);
|
this.updateText();
|
||||||
}
|
}
|
||||||
if (success) {
|
break;
|
||||||
this.updateText();
|
case Button.DOWN:
|
||||||
}
|
if (this.cursor === rowsToDisplay - 1) {
|
||||||
break;
|
if (this.scrollCursor < this.scene.gameMode.challenges.length - rowsToDisplay) {
|
||||||
case Button.DOWN:
|
// When at the bottom and pressing DOWN, scroll if possible.
|
||||||
if (this.cursor === rowsToDisplay - 1) {
|
success = this.setScrollCursor(this.scrollCursor + 1);
|
||||||
if (this.scrollCursor < this.scene.gameMode.challenges.length - rowsToDisplay) {
|
} else {
|
||||||
// When at the bottom and pressing DOWN, scroll if possible.
|
// When at the bottom of a scrolling menu and pressing DOWN, move to the topmost item.
|
||||||
success = this.setScrollCursor(this.scrollCursor + 1);
|
// First, set the cursor to the first visible element, preparing for the scroll to the top.
|
||||||
|
const successA = this.setCursor(0);
|
||||||
|
// Then, adjust the scroll to display the topmost elements of the menu.
|
||||||
|
const successB = this.setScrollCursor(0);
|
||||||
|
success = successA && successB; // success is just there to play the little validation sound effect
|
||||||
|
}
|
||||||
|
} else if (this.scene.gameMode.challenges.length < rowsToDisplay && this.cursor === this.scene.gameMode.challenges.length - 1) {
|
||||||
|
// When at the bottom of a non-scrolling menu and pressing DOWN, move to the topmost item.
|
||||||
|
success = this.setCursor(0);
|
||||||
} else {
|
} else {
|
||||||
// When at the bottom of a scrolling menu and pressing DOWN, move to the topmost item.
|
success = this.setCursor(this.cursor + 1);
|
||||||
// First, set the cursor to the first visible element, preparing for the scroll to the top.
|
|
||||||
const successA = this.setCursor(0);
|
|
||||||
// Then, adjust the scroll to display the topmost elements of the menu.
|
|
||||||
const successB = this.setScrollCursor(0);
|
|
||||||
success = successA && successB; // success is just there to play the little validation sound effect
|
|
||||||
}
|
}
|
||||||
} else if (this.scene.gameMode.challenges.length < rowsToDisplay && this.cursor === this.scene.gameMode.challenges.length - 1) {
|
if (success) {
|
||||||
// When at the bottom of a non-scrolling menu and pressing DOWN, move to the topmost item.
|
this.updateText();
|
||||||
success = this.setCursor(0);
|
}
|
||||||
} else {
|
break;
|
||||||
success = this.setCursor(this.cursor + 1);
|
case Button.LEFT:
|
||||||
|
// Moves the option cursor left, if possible.
|
||||||
|
success = this.getActiveChallenge().decreaseValue();
|
||||||
|
if (success) {
|
||||||
|
this.updateText();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Button.RIGHT:
|
||||||
|
// Moves the option cursor right, if possible.
|
||||||
|
success = this.getActiveChallenge().increaseValue();
|
||||||
|
if (success) {
|
||||||
|
this.updateText();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (success) {
|
|
||||||
this.updateText();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Button.LEFT:
|
|
||||||
// Moves the option cursor left, if possible.
|
|
||||||
success = this.getActiveChallenge().decreaseValue();
|
|
||||||
if (success) {
|
|
||||||
this.updateText();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Button.RIGHT:
|
|
||||||
// Moves the option cursor right, if possible.
|
|
||||||
success = this.getActiveChallenge().increaseValue();
|
|
||||||
if (success) {
|
|
||||||
this.updateText();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +370,6 @@ export default class GameChallengesUiHandler extends UiHandler {
|
||||||
if (success) {
|
if (success) {
|
||||||
ui.playSelect();
|
ui.playSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue