mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-05 16:02:20 +02:00
Compare commits
14 Commits
7ed71ceb90
...
31a11e08bb
Author | SHA1 | Date | |
---|---|---|---|
|
31a11e08bb | ||
|
2c4f02098f | ||
|
f6fd091d9b | ||
|
c7184558c2 | ||
|
f6551efc36 | ||
|
9bcbc66db0 | ||
|
1e4b3a45dd | ||
|
872f05d2a7 | ||
|
d15c01378d | ||
|
208aaf11cd | ||
|
0df40893b2 | ||
|
2d0cf54a7f | ||
|
38d4a594a0 | ||
|
0f6170b3f7 |
45
.github/CODEOWNERS
vendored
Normal file
45
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
# Order is important; the last matching pattern takes the most precedence.
|
||||
|
||||
# everything (whole code-base) - Junior Devs
|
||||
* @pagefaultgames/junior-dev-team
|
||||
|
||||
# github actions/templates etc. - Dev Leads
|
||||
/.github @pagefaultgames/dev-leads
|
||||
|
||||
# --- Translations ---
|
||||
|
||||
# all translations - Translation Leads
|
||||
/src/locales @pagefaultgames/translation-leads
|
||||
|
||||
# Catalan (Spain/Spanish)
|
||||
/src/locales/ca_ES @pagefaultgames/catalan-translation-team
|
||||
|
||||
# German
|
||||
/src/locales/de @pagefaultgames/german-translation-team
|
||||
|
||||
# English
|
||||
/src/locales/en @pagefaultgames/english-translation-team
|
||||
|
||||
# Spanish
|
||||
/src/locales/es @pagefaultgames/spanish-translation-team
|
||||
|
||||
# French
|
||||
/src/locales/fr @pagefaultgames/french-translation-team
|
||||
|
||||
# Italian
|
||||
/src/locales/it @pagefaultgames/italian-translation-team
|
||||
|
||||
# Japenese
|
||||
/src/locales/ja @pagefaultgames/japanese-translation-team
|
||||
|
||||
# Korean
|
||||
/src/locales/ko @pagefaultgames/korean-translation-team
|
||||
|
||||
# Brasilian (Brasil/Portuguese)
|
||||
/src/locales/pt_BR @pagefaultgames/portuguese_br-translation-team
|
||||
|
||||
# Chinese (simplified)
|
||||
/src/locales/zh_CN @pagefaultgames/chinese_simplified-translation-team
|
||||
|
||||
# Chinese (traditional)
|
||||
/src/locales/zh_TW @pagefaultgames/chinese_traditional-translation-team
|
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -1,7 +1,7 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for this project
|
||||
title: "[Feature] "
|
||||
labels: ["enhancement"]
|
||||
labels: ["Enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@ -30,7 +30,7 @@
|
||||
- [ ] The PR is self-contained and cannot be split into smaller PRs?
|
||||
- [ ] Have I provided a clear explanation of the changes?
|
||||
- [ ] Have I considered writing automated tests for the issue?
|
||||
- [ ] If I have text, did I add placeholders for them in locales?
|
||||
- [ ] If I have text, did I add make it translatable and added a key in the English language?
|
||||
- [ ] Have I tested the changes (manually)?
|
||||
- [ ] Are all unit tests still passing? (`npm run test`)
|
||||
- [ ] Are the changes visual?
|
||||
|
@ -53,6 +53,7 @@ Check out [Github Issues](https://github.com/pagefaultgames/pokerogue/issues) to
|
||||
- Pokémon Sun/Moon
|
||||
- Pokémon Ultra Sun/Ultra Moon
|
||||
- Pokémon Sword/Shield
|
||||
- Pokémon Legends: Arceus
|
||||
- Pokémon Scarlet/Violet
|
||||
- Firel (Custom Laboratory, Metropolis, Seabed, and Space biome music)
|
||||
- Lmz (Custom Jungle biome music)
|
||||
|
@ -17,6 +17,12 @@ body {
|
||||
background: #484050;
|
||||
}
|
||||
|
||||
@media (display-mode: fullscreen) {
|
||||
body {
|
||||
background: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
#links {
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
|
BIN
public/audio/bgm/battle_legendary_origin_forme.mp3
Normal file
BIN
public/audio/bgm/battle_legendary_origin_forme.mp3
Normal file
Binary file not shown.
BIN
public/audio/bgm/battle_legendary_riders.mp3
Normal file
BIN
public/audio/bgm/battle_legendary_riders.mp3
Normal file
Binary file not shown.
@ -49,8 +49,8 @@ import CandyBar from "./ui/candy-bar";
|
||||
import { Variant, variantData } from "./data/variant";
|
||||
import { Localizable } from "#app/interfaces/locales";
|
||||
import Overrides from "#app/overrides";
|
||||
import {InputsController} from "./inputs-controller";
|
||||
import {UiInputs} from "./ui-inputs";
|
||||
import { InputsController } from "./inputs-controller";
|
||||
import { UiInputs } from "./ui-inputs";
|
||||
import { NewArenaEvent } from "./events/battle-scene";
|
||||
import { ArenaFlyout } from "./ui/arena-flyout";
|
||||
import { EaseType } from "#enums/ease-type";
|
||||
@ -65,7 +65,7 @@ import { Species } from "#enums/species";
|
||||
import { UiTheme } from "#enums/ui-theme";
|
||||
import { TimedEventManager } from "#app/timed-event-manager.js";
|
||||
import i18next from "i18next";
|
||||
import {TrainerType} from "#enums/trainer-type";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { battleSpecDialogue } from "./data/dialogue";
|
||||
import { LoadingScene } from "./loading-scene";
|
||||
import { LevelCapPhase } from "./phases/level-cap-phase";
|
||||
@ -1897,6 +1897,8 @@ export default class BattleScene extends SceneBase {
|
||||
return 22.770;
|
||||
case "battle_legendary_dia_pal": //ORAS Dialga & Palkia Battle
|
||||
return 16.009;
|
||||
case "battle_legendary_origin_forme": //LA Origin Dialga & Palkia Battle
|
||||
return 18.961;
|
||||
case "battle_legendary_giratina": //ORAS Giratina Battle
|
||||
return 10.451;
|
||||
case "battle_legendary_arceus": //HGSS Arceus Battle
|
||||
@ -1925,6 +1927,8 @@ export default class BattleScene extends SceneBase {
|
||||
return 12.503;
|
||||
case "battle_legendary_calyrex": //SWSH Calyrex Battle
|
||||
return 50.641;
|
||||
case "battle_legendary_riders": //SWSH Ice & Shadow Rider Calyrex Battle
|
||||
return 18.155;
|
||||
case "battle_legendary_birds_galar": //SWSH Galarian Legendary Birds Battle
|
||||
return 0.175;
|
||||
case "battle_legendary_ruinous": //SV Treasures of Ruin Battle
|
||||
@ -2668,7 +2672,8 @@ export default class BattleScene extends SceneBase {
|
||||
wave: this.currentBattle?.waveIndex || 0,
|
||||
party: this.party ? this.party.map(p => {
|
||||
return { name: p.name, level: p.level };
|
||||
}) : []
|
||||
}) : [],
|
||||
modeChain: this.ui?.getModeChain() ?? [],
|
||||
};
|
||||
(window as any).gameInfo = gameInfo;
|
||||
}
|
||||
|
@ -275,7 +275,12 @@ export default class Battle {
|
||||
return "battle_legendary_sinnoh";
|
||||
}
|
||||
if (pokemon.species.speciesId === Species.DIALGA || pokemon.species.speciesId === Species.PALKIA) {
|
||||
return "battle_legendary_dia_pal";
|
||||
if (pokemon.getFormKey() === "") {
|
||||
return "battle_legendary_dia_pal";
|
||||
}
|
||||
if (pokemon.getFormKey() === "origin") {
|
||||
return "battle_legendary_origin_forme";
|
||||
}
|
||||
}
|
||||
if (pokemon.species.speciesId === Species.GIRATINA) {
|
||||
return "battle_legendary_giratina";
|
||||
@ -319,7 +324,12 @@ export default class Battle {
|
||||
return "battle_legendary_glas_spec";
|
||||
}
|
||||
if (pokemon.species.speciesId === Species.CALYREX) {
|
||||
return "battle_legendary_calyrex";
|
||||
if (pokemon.getFormKey() === "") {
|
||||
return "battle_legendary_calyrex";
|
||||
}
|
||||
if (pokemon.getFormKey() === "ice" || pokemon.getFormKey() === "shadow") {
|
||||
return "battle_legendary_riders";
|
||||
}
|
||||
}
|
||||
if (pokemon.species.speciesId === Species.GALAR_ARTICUNO || pokemon.species.speciesId === Species.GALAR_ZAPDOS || pokemon.species.speciesId === Species.GALAR_MOLTRES) {
|
||||
return "battle_legendary_birds_galar";
|
||||
@ -504,7 +514,7 @@ export const classicFixedBattles: FixedBattleConfigs = {
|
||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE ])),
|
||||
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
||||
[165]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
||||
[165]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2 ])),
|
||||
[182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])),
|
||||
|
@ -51,21 +51,6 @@ export interface InterfaceConfig {
|
||||
|
||||
const repeatInputDelayMillis = 250;
|
||||
|
||||
// Phaser.Input.Gamepad.GamepadPlugin#refreshPads
|
||||
declare module "phaser" {
|
||||
namespace Input {
|
||||
namespace Gamepad {
|
||||
interface GamepadPlugin {
|
||||
/**
|
||||
* Refreshes the list of connected Gamepads.
|
||||
* This is called automatically when a gamepad is connected or disconnected, and during the update loop.
|
||||
*/
|
||||
refreshPads(): void;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages and handles all input controls for the game, including keyboard and gamepad interactions.
|
||||
*
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "Erfolge",
|
||||
"STATS": "Statistiken",
|
||||
"RUN_HISTORY": "Laufhistorie",
|
||||
"VOUCHERS": "Gutscheine",
|
||||
"EGG_LIST": "Eierliste",
|
||||
"EGG_GACHA": "Eier-Gacha",
|
||||
"MANAGE_DATA": "Daten verwalten",
|
||||
|
@ -45,6 +45,7 @@
|
||||
"battle_legendary_lake_trio": "ORAS Lake Guardians Battle",
|
||||
"battle_legendary_sinnoh": "ORAS Sinnoh Legendary Battle",
|
||||
"battle_legendary_dia_pal": "ORAS Dialga & Palkia Battle",
|
||||
"battle_legendary_origin_forme": "LA Origin Dialga & Palkia Battle",
|
||||
"battle_legendary_giratina": "ORAS Giratina Battle",
|
||||
"battle_legendary_arceus": "HGSS Arceus Battle",
|
||||
"battle_legendary_unova": "BW Unova Legendary Battle",
|
||||
@ -59,6 +60,7 @@
|
||||
"battle_legendary_zac_zam": "SWSH Zacian & Zamazenta Battle",
|
||||
"battle_legendary_glas_spec": "SWSH Glastrier & Spectrier Battle",
|
||||
"battle_legendary_calyrex": "SWSH Calyrex Battle",
|
||||
"battle_legendary_riders": "SWSH Ice & Shadow Rider Calyrex Battle",
|
||||
"battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle",
|
||||
"battle_legendary_ruinous": "SV Treasures of Ruin Battle",
|
||||
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "Achievements",
|
||||
"STATS": "Stats",
|
||||
"RUN_HISTORY": "Run History",
|
||||
"VOUCHERS": "Vouchers",
|
||||
"EGG_LIST": "Egg List",
|
||||
"EGG_GACHA": "Egg Gacha",
|
||||
"MANAGE_DATA": "Manage Data",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "Logros",
|
||||
"STATS": "Estadísticas",
|
||||
"RUN_HISTORY": "Historial de partida",
|
||||
"VOUCHERS": "Vales",
|
||||
"EGG_LIST": "Lista de Huevos",
|
||||
"EGG_GACHA": "Gacha de Huevos",
|
||||
"MANAGE_DATA": "Gestionar Datos",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "Succès",
|
||||
"STATS": "Statistiques",
|
||||
"RUN_HISTORY": "Historique",
|
||||
"VOUCHERS": "Coupons",
|
||||
"EGG_LIST": "Liste des Œufs",
|
||||
"EGG_GACHA": "Gacha-Œufs",
|
||||
"MANAGE_DATA": "Mes données",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "Obiettivi",
|
||||
"STATS": "Statistiche",
|
||||
"RUN_HISTORY": "Run precedenti",
|
||||
"VOUCHERS": "Biglietti",
|
||||
"EGG_LIST": "Lista uova",
|
||||
"EGG_GACHA": "Macchine uova",
|
||||
"MANAGE_DATA": "Gestisci dati",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "じっせき",
|
||||
"STATS": "とうけい",
|
||||
"RUN_HISTORY":"ラン履歴",
|
||||
"VOUCHERS": "クーポン",
|
||||
"EGG_LIST": "タマゴリスト",
|
||||
"EGG_GACHA": "タマゴガチャ",
|
||||
"MANAGE_DATA": "データかんり",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "업적",
|
||||
"STATS": "통계",
|
||||
"RUN_HISTORY": "플레이 이력",
|
||||
"VOUCHERS": "바우처",
|
||||
"EGG_LIST": "알 목록",
|
||||
"EGG_GACHA": "알 뽑기",
|
||||
"MANAGE_DATA": "데이터 관리",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "Conquistas",
|
||||
"STATS": "Estatísticas",
|
||||
"RUN_HISTORY": "Histórico de Jogos",
|
||||
"VOUCHERS": "Vouchers",
|
||||
"EGG_LIST": "Incubadora",
|
||||
"EGG_GACHA": "Gacha de ovos",
|
||||
"MANAGE_DATA": "Gerenciar dados",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "成就",
|
||||
"STATS": "数据统计",
|
||||
"RUN_HISTORY": "历史记录",
|
||||
"VOUCHERS": "兑换券",
|
||||
"EGG_LIST": "蛋列表",
|
||||
"EGG_GACHA": "扭蛋机",
|
||||
"MANAGE_DATA": "管理数据",
|
||||
|
@ -3,7 +3,6 @@
|
||||
"ACHIEVEMENTS": "成就",
|
||||
"STATS": "數據",
|
||||
"RUN_HISTORY": "歷史記錄",
|
||||
"VOUCHERS": "兌換劵",
|
||||
"EGG_LIST": "蛋列表",
|
||||
"EGG_GACHA": "扭蛋機",
|
||||
"MANAGE_DATA": "管理數據",
|
||||
|
64
src/main.ts
64
src/main.ts
@ -73,75 +73,13 @@ const config: Phaser.Types.Core.GameConfig = {
|
||||
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
|
||||
* @param x The relative x position
|
||||
* @param y The relative y position
|
||||
*/
|
||||
const setPositionRelative = function (guideObject: any, x: number, y: number) {
|
||||
const setPositionRelative = function (guideObject: Phaser.GameObjects.GameObject, x: number, y: number) {
|
||||
const offsetX = guideObject.width * (-0.5 + (0.5 - guideObject.originX));
|
||||
const offsetY = guideObject.height * (-0.5 + (0.5 - guideObject.originY));
|
||||
this.setPosition(guideObject.x + offsetX + x, guideObject.y + offsetY + y);
|
||||
};
|
||||
|
||||
declare module "phaser" {
|
||||
namespace GameObjects {
|
||||
interface Container {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
|
||||
* @param x The relative x position
|
||||
* @param y The relative y position
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface Sprite {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
|
||||
* @param x The relative x position
|
||||
* @param y The relative y position
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface Image {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
|
||||
* @param x The relative x position
|
||||
* @param y The relative y position
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface NineSlice {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
|
||||
* @param x The relative x position
|
||||
* @param y The relative y position
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface Text {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
|
||||
* @param x The relative x position
|
||||
* @param y The relative y position
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface Rectangle {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
|
||||
* @param x The relative x position
|
||||
* @param y The relative y position
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Phaser.GameObjects.Container.prototype.setPositionRelative = setPositionRelative;
|
||||
Phaser.GameObjects.Sprite.prototype.setPositionRelative = setPositionRelative;
|
||||
Phaser.GameObjects.Image.prototype.setPositionRelative = setPositionRelative;
|
||||
|
@ -1411,6 +1411,7 @@ export class GameData {
|
||||
case GameDataType.RUN_HISTORY:
|
||||
const data = JSON.parse(dataStr);
|
||||
const keys = Object.keys(data);
|
||||
dataName = i18next.t("menuUiHandler:RUN_HISTORY").toLowerCase();
|
||||
keys.forEach((key) => {
|
||||
const entryKeys = Object.keys(data[key]);
|
||||
valid = ["isFavorite", "isVictory", "entry"].every(v => entryKeys.includes(v)) && entryKeys.length === 3;
|
||||
|
68
src/typings/phaser/index.d.ts
vendored
Normal file
68
src/typings/phaser/index.d.ts
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
import "phaser";
|
||||
|
||||
declare module "phaser" {
|
||||
namespace GameObjects {
|
||||
interface GameObject {
|
||||
width: number;
|
||||
|
||||
height: number;
|
||||
|
||||
originX: number;
|
||||
|
||||
originY: number;
|
||||
|
||||
x: number;
|
||||
|
||||
y: number;
|
||||
}
|
||||
|
||||
interface Container {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface Sprite {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface Image {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface NineSlice {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface Text {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
interface Rectangle {
|
||||
/**
|
||||
* Sets this object's position relative to another object with a given offset
|
||||
*/
|
||||
setPositionRelative(guideObject: any, x: number, y: number): void;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Input {
|
||||
namespace Gamepad {
|
||||
interface GamepadPlugin {
|
||||
/**
|
||||
* Refreshes the list of connected Gamepads.
|
||||
* This is called automatically when a gamepad is connected or disconnected, and during the update loop.
|
||||
*/
|
||||
refreshPads(): void;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ import BattleScene from "../battle-scene";
|
||||
import { Button } from "#enums/buttons";
|
||||
import i18next from "i18next";
|
||||
import { Achv, achvs, getAchievementDescription } from "../system/achv";
|
||||
import { Voucher, getVoucherTypeIcon, getVoucherTypeName, vouchers } from "../system/voucher";
|
||||
import MessageUiHandler from "./message-ui-handler";
|
||||
import { addTextObject, TextStyle } from "./text";
|
||||
import { Mode } from "./ui";
|
||||
@ -9,40 +10,67 @@ import { addWindow } from "./ui-theme";
|
||||
import { ParseKeys } from "i18next";
|
||||
import { PlayerGender } from "#enums/player-gender";
|
||||
|
||||
enum Page {
|
||||
ACHIEVEMENTS,
|
||||
VOUCHERS
|
||||
}
|
||||
|
||||
export default class AchvsUiHandler extends MessageUiHandler {
|
||||
private readonly ACHV_ROWS = 4;
|
||||
private readonly ACHV_COLS = 17;
|
||||
private readonly ROWS = 4;
|
||||
private readonly COLS = 17;
|
||||
|
||||
private achvsContainer: Phaser.GameObjects.Container;
|
||||
private achvIconsContainer: Phaser.GameObjects.Container;
|
||||
private mainContainer: Phaser.GameObjects.Container;
|
||||
private iconsContainer: Phaser.GameObjects.Container;
|
||||
|
||||
private headerBg: Phaser.GameObjects.NineSlice;
|
||||
private headerText: Phaser.GameObjects.Text;
|
||||
private headerActionText: Phaser.GameObjects.Text;
|
||||
private headerActionButton: Phaser.GameObjects.Sprite;
|
||||
private headerBgX: number;
|
||||
private iconsBg: Phaser.GameObjects.NineSlice;
|
||||
private icons: Phaser.GameObjects.Sprite[];
|
||||
|
||||
private achvIconsBg: Phaser.GameObjects.NineSlice;
|
||||
private achvIcons: Phaser.GameObjects.Sprite[];
|
||||
private titleText: Phaser.GameObjects.Text;
|
||||
private scoreText: Phaser.GameObjects.Text;
|
||||
private unlockText: Phaser.GameObjects.Text;
|
||||
|
||||
private achvsName: string;
|
||||
private achvsTotal: number;
|
||||
private scrollCursor: number;
|
||||
private vouchersName: string;
|
||||
private vouchersTotal: number;
|
||||
private currentTotal: number;
|
||||
|
||||
private scrollCursor: number;
|
||||
private cursorObj: Phaser.GameObjects.NineSlice | null;
|
||||
private currentPage: Page;
|
||||
|
||||
constructor(scene: BattleScene, mode: Mode | null = null) {
|
||||
super(scene, mode);
|
||||
|
||||
this.achvsTotal = Object.keys(achvs).length;
|
||||
this.vouchersTotal = Object.keys(vouchers).length;
|
||||
this.scrollCursor = 0;
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
this.achvsContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1);
|
||||
this.mainContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1);
|
||||
|
||||
this.achvsContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains);
|
||||
this.mainContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains);
|
||||
|
||||
const headerBg = addWindow(this.scene, 0, 0, (this.scene.game.canvas.width / 6) - 2, 24);
|
||||
headerBg.setOrigin(0, 0);
|
||||
this.headerBg = addWindow(this.scene, 0, 0, (this.scene.game.canvas.width / 6) - 2, 24);
|
||||
this.headerBg.setOrigin(0, 0);
|
||||
|
||||
this.headerText = addTextObject(this.scene, 0, 0, "", TextStyle.SETTINGS_LABEL);
|
||||
this.headerText.setOrigin(0, 0);
|
||||
this.headerText.setPositionRelative(this.headerBg, 8, 4);
|
||||
this.headerActionButton = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "keyboard", "SPACE.png");
|
||||
this.headerActionButton.setOrigin(0, 0);
|
||||
this.headerActionButton.setPositionRelative(this.headerBg, 236, 6);
|
||||
this.headerActionText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW, {fontSize:"60px"});
|
||||
this.headerActionText.setOrigin(0, 0);
|
||||
this.headerActionText.setPositionRelative(this.headerBg, 264, 8);
|
||||
|
||||
// We need to get the player gender from the game data to add the correct prefix to the achievement name
|
||||
const playerGender = this.scene.gameData.gender;
|
||||
@ -51,30 +79,29 @@ export default class AchvsUiHandler extends MessageUiHandler {
|
||||
genderPrefix = "PGF";
|
||||
}
|
||||
|
||||
const headerText = addTextObject(this.scene, 0, 0, i18next.t(`${genderPrefix}achv:Achievements.name` as ParseKeys), TextStyle.SETTINGS_LABEL);
|
||||
headerText.setOrigin(0, 0);
|
||||
headerText.setPositionRelative(headerBg, 8, 4);
|
||||
this.achvsName = i18next.t(`${genderPrefix}achv:Achievements.name` as ParseKeys);
|
||||
this.vouchersName = i18next.t("voucher:vouchers");
|
||||
|
||||
this.achvIconsBg = addWindow(this.scene, 0, headerBg.height, (this.scene.game.canvas.width / 6) - 2, (this.scene.game.canvas.height / 6) - headerBg.height - 68);
|
||||
this.achvIconsBg.setOrigin(0, 0);
|
||||
this.iconsBg = addWindow(this.scene, 0, this.headerBg.height, (this.scene.game.canvas.width / 6) - 2, (this.scene.game.canvas.height / 6) - this.headerBg.height - 68);
|
||||
this.iconsBg.setOrigin(0, 0);
|
||||
|
||||
this.achvIconsContainer = this.scene.add.container(6, headerBg.height + 6);
|
||||
this.iconsContainer = this.scene.add.container(6, this.headerBg.height + 6);
|
||||
|
||||
this.achvIcons = [];
|
||||
this.icons = [];
|
||||
|
||||
for (let a = 0; a < this.ACHV_ROWS * this.ACHV_COLS; a++) {
|
||||
const x = (a % this.ACHV_COLS) * 18;
|
||||
const y = Math.floor(a / this.ACHV_COLS) * 18;
|
||||
for (let a = 0; a < this.ROWS * this.COLS; a++) {
|
||||
const x = (a % this.COLS) * 18;
|
||||
const y = Math.floor(a / this.COLS) * 18;
|
||||
|
||||
const icon = this.scene.add.sprite(x, y, "items", "unknown");
|
||||
icon.setOrigin(0, 0);
|
||||
icon.setScale(0.5);
|
||||
|
||||
this.achvIcons.push(icon);
|
||||
this.achvIconsContainer.add(icon);
|
||||
this.icons.push(icon);
|
||||
this.iconsContainer.add(icon);
|
||||
}
|
||||
|
||||
const titleBg = addWindow(this.scene, 0, headerBg.height + this.achvIconsBg.height, 174, 24);
|
||||
const titleBg = addWindow(this.scene, 0, this.headerBg.height + this.iconsBg.height, 174, 24);
|
||||
titleBg.setOrigin(0, 0);
|
||||
|
||||
this.titleText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW);
|
||||
@ -105,36 +132,40 @@ export default class AchvsUiHandler extends MessageUiHandler {
|
||||
|
||||
this.message = descriptionText;
|
||||
|
||||
this.achvsContainer.add(headerBg);
|
||||
this.achvsContainer.add(headerText);
|
||||
this.achvsContainer.add(this.achvIconsBg);
|
||||
this.achvsContainer.add(this.achvIconsContainer);
|
||||
this.achvsContainer.add(titleBg);
|
||||
this.achvsContainer.add(this.titleText);
|
||||
this.achvsContainer.add(scoreBg);
|
||||
this.achvsContainer.add(this.scoreText);
|
||||
this.achvsContainer.add(unlockBg);
|
||||
this.achvsContainer.add(this.unlockText);
|
||||
this.achvsContainer.add(descriptionBg);
|
||||
this.achvsContainer.add(descriptionText);
|
||||
this.mainContainer.add(this.headerBg);
|
||||
this.mainContainer.add(this.headerActionButton);
|
||||
this.mainContainer.add(this.headerText);
|
||||
this.mainContainer.add(this.headerActionText);
|
||||
this.mainContainer.add(this.iconsBg);
|
||||
this.mainContainer.add(this.iconsContainer);
|
||||
this.mainContainer.add(titleBg);
|
||||
this.mainContainer.add(this.titleText);
|
||||
this.mainContainer.add(scoreBg);
|
||||
this.mainContainer.add(this.scoreText);
|
||||
this.mainContainer.add(unlockBg);
|
||||
this.mainContainer.add(this.unlockText);
|
||||
this.mainContainer.add(descriptionBg);
|
||||
this.mainContainer.add(descriptionText);
|
||||
|
||||
ui.add(this.achvsContainer);
|
||||
ui.add(this.mainContainer);
|
||||
|
||||
this.currentPage = Page.ACHIEVEMENTS;
|
||||
this.setCursor(0);
|
||||
|
||||
this.achvsContainer.setVisible(false);
|
||||
this.mainContainer.setVisible(false);
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
super.show(args);
|
||||
|
||||
this.headerBgX = this.headerBg.getTopRight().x;
|
||||
this.updateAchvIcons();
|
||||
|
||||
this.achvsContainer.setVisible(true);
|
||||
this.mainContainer.setVisible(true);
|
||||
this.setCursor(0);
|
||||
this.setScrollCursor(0);
|
||||
|
||||
this.getUi().moveTo(this.achvsContainer, this.getUi().length - 1);
|
||||
this.getUi().moveTo(this.mainContainer, this.getUi().length - 1);
|
||||
|
||||
this.getUi().hideTooltip();
|
||||
|
||||
@ -160,48 +191,71 @@ export default class AchvsUiHandler extends MessageUiHandler {
|
||||
this.unlockText.setText(unlocked ? new Date(achvUnlocks[achv.id]).toLocaleDateString() : i18next.t(`${genderPrefix}achv:Locked.name` as ParseKeys));
|
||||
}
|
||||
|
||||
protected showVoucher(voucher: Voucher) {
|
||||
const voucherUnlocks = this.scene.gameData.voucherUnlocks;
|
||||
const unlocked = voucherUnlocks.hasOwnProperty(voucher.id);
|
||||
|
||||
this.titleText.setText(getVoucherTypeName(voucher.voucherType));
|
||||
this.showText(voucher.description);
|
||||
this.unlockText.setText(unlocked ? new Date(voucherUnlocks[voucher.id]).toLocaleDateString() : i18next.t("voucher:locked"));
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
|
||||
if (button === Button.ACTION) {
|
||||
success = true;
|
||||
this.setScrollCursor(0);
|
||||
if (this.currentPage === Page.ACHIEVEMENTS) {
|
||||
this.currentPage = Page.VOUCHERS;
|
||||
this.updateVoucherIcons();
|
||||
this.setCursor(0);
|
||||
} else if (this.currentPage === Page.VOUCHERS) {
|
||||
this.currentPage = Page.ACHIEVEMENTS;
|
||||
this.updateAchvIcons();
|
||||
this.setCursor(0);
|
||||
}
|
||||
this.mainContainer.update();
|
||||
}
|
||||
if (button === Button.CANCEL) {
|
||||
success = true;
|
||||
this.scene.ui.revertMode();
|
||||
} else {
|
||||
const rowIndex = Math.floor(this.cursor / this.ACHV_COLS);
|
||||
const itemOffset = (this.scrollCursor * this.ACHV_COLS);
|
||||
const rowIndex = Math.floor(this.cursor / this.COLS);
|
||||
const itemOffset = (this.scrollCursor * this.COLS);
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
if (this.cursor < this.ACHV_COLS) {
|
||||
if (this.cursor < this.COLS) {
|
||||
if (this.scrollCursor) {
|
||||
success = this.setScrollCursor(this.scrollCursor - 1);
|
||||
}
|
||||
} else {
|
||||
success = this.setCursor(this.cursor - this.ACHV_COLS);
|
||||
success = this.setCursor(this.cursor - this.COLS);
|
||||
}
|
||||
break;
|
||||
case Button.DOWN:
|
||||
const canMoveDown = (this.cursor + itemOffset) + this.ACHV_COLS < this.achvsTotal;
|
||||
if (rowIndex >= this.ACHV_ROWS - 1) {
|
||||
if (this.scrollCursor < Math.ceil(this.achvsTotal / this.ACHV_COLS) - this.ACHV_ROWS && canMoveDown) {
|
||||
const canMoveDown = (this.cursor + itemOffset) + this.COLS < this.currentTotal;
|
||||
if (rowIndex >= this.ROWS - 1) {
|
||||
if (this.scrollCursor < Math.ceil(this.currentTotal / this.COLS) - this.ROWS && canMoveDown) {
|
||||
success = this.setScrollCursor(this.scrollCursor + 1);
|
||||
}
|
||||
} else if (canMoveDown) {
|
||||
success = this.setCursor(this.cursor + this.ACHV_COLS);
|
||||
success = this.setCursor(this.cursor + this.COLS);
|
||||
}
|
||||
break;
|
||||
case Button.LEFT:
|
||||
if (!this.cursor && this.scrollCursor) {
|
||||
success = this.setScrollCursor(this.scrollCursor - 1) && this.setCursor(this.cursor + (this.ACHV_COLS - 1));
|
||||
success = this.setScrollCursor(this.scrollCursor - 1) && this.setCursor(this.cursor + (this.COLS - 1));
|
||||
} else if (this.cursor) {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
}
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
if (this.cursor + 1 === this.ACHV_ROWS * this.ACHV_COLS && this.scrollCursor < Math.ceil(this.achvsTotal / this.ACHV_COLS) - this.ACHV_ROWS) {
|
||||
success = this.setScrollCursor(this.scrollCursor + 1) && this.setCursor(this.cursor - (this.ACHV_COLS - 1));
|
||||
} else if (this.cursor + itemOffset < this.achvsTotal - 1) {
|
||||
if (this.cursor + 1 === this.ROWS * this.COLS && this.scrollCursor < Math.ceil(this.currentTotal / this.COLS) - this.ROWS) {
|
||||
success = this.setScrollCursor(this.scrollCursor + 1) && this.setCursor(this.cursor - (this.COLS - 1));
|
||||
} else if (this.cursor + itemOffset < this.currentTotal - 1) {
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
}
|
||||
break;
|
||||
@ -215,24 +269,30 @@ export default class AchvsUiHandler extends MessageUiHandler {
|
||||
return success;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
setCursor(cursor: integer, pageChange?: boolean): boolean {
|
||||
const ret = super.setCursor(cursor);
|
||||
|
||||
let updateAchv = ret;
|
||||
let update = ret;
|
||||
|
||||
if (!this.cursorObj) {
|
||||
this.cursorObj = this.scene.add.nineslice(0, 0, "select_cursor_highlight", undefined, 16, 16, 1, 1, 1, 1);
|
||||
this.cursorObj.setOrigin(0, 0);
|
||||
this.achvIconsContainer.add(this.cursorObj);
|
||||
updateAchv = true;
|
||||
this.iconsContainer.add(this.cursorObj);
|
||||
update = true;
|
||||
}
|
||||
|
||||
this.cursorObj.setPositionRelative(this.achvIcons[this.cursor], 0, 0);
|
||||
this.cursorObj.setPositionRelative(this.icons[this.cursor], 0, 0);
|
||||
|
||||
if (updateAchv) {
|
||||
this.showAchv(achvs[Object.keys(achvs)[cursor + this.scrollCursor * this.ACHV_COLS]]);
|
||||
if (update || pageChange) {
|
||||
switch (this.currentPage) {
|
||||
case Page.ACHIEVEMENTS:
|
||||
this.showAchv(achvs[Object.keys(achvs)[cursor + this.scrollCursor * this.COLS]]);
|
||||
break;
|
||||
case Page.VOUCHERS:
|
||||
this.showVoucher(vouchers[Object.keys(vouchers)[cursor + this.scrollCursor * this.COLS]]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -249,10 +309,16 @@ export default class AchvsUiHandler extends MessageUiHandler {
|
||||
|
||||
this.scrollCursor = scrollCursor;
|
||||
|
||||
this.updateAchvIcons();
|
||||
|
||||
this.showAchv(achvs[Object.keys(achvs)[Math.min(this.cursor + this.scrollCursor * this.ACHV_COLS, Object.values(achvs).length - 1)]]);
|
||||
|
||||
switch (this.currentPage) {
|
||||
case Page.ACHIEVEMENTS:
|
||||
this.updateAchvIcons();
|
||||
this.showAchv(achvs[Object.keys(achvs)[Math.min(this.cursor + this.scrollCursor * this.COLS, Object.values(achvs).length - 1)]]);
|
||||
break;
|
||||
case Page.VOUCHERS:
|
||||
this.updateVoucherIcons();
|
||||
this.showVoucher(vouchers[Object.keys(vouchers)[Math.min(this.cursor + this.scrollCursor * this.COLS, Object.values(vouchers).length - 1)]]);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -262,15 +328,21 @@ export default class AchvsUiHandler extends MessageUiHandler {
|
||||
* Determines what data is to be displayed on the UI and updates it accordingly based on the current value of this.scrollCursor
|
||||
*/
|
||||
updateAchvIcons(): void {
|
||||
this.headerText.text = this.achvsName;
|
||||
this.headerActionText.text = this.vouchersName;
|
||||
const textPosition = this.headerBgX - this.headerActionText.displayWidth - 8;
|
||||
this.headerActionText.setX(textPosition);
|
||||
this.headerActionButton.setX(textPosition - this.headerActionButton.displayWidth - 4);
|
||||
|
||||
const achvUnlocks = this.scene.gameData.achvUnlocks;
|
||||
|
||||
const itemOffset = this.scrollCursor * this.ACHV_COLS;
|
||||
const itemLimit = this.ACHV_ROWS * this.ACHV_COLS;
|
||||
const itemOffset = this.scrollCursor * this.COLS;
|
||||
const itemLimit = this.ROWS * this.COLS;
|
||||
|
||||
const achvRange = Object.values(achvs).slice(itemOffset, itemLimit + itemOffset);
|
||||
|
||||
achvRange.forEach((achv: Achv, i: integer) => {
|
||||
const icon = this.achvIcons[i];
|
||||
const icon = this.icons[i];
|
||||
const unlocked = achvUnlocks.hasOwnProperty(achv.id);
|
||||
const hidden = !unlocked && achv.secret && (!achv.parentId || !achvUnlocks.hasOwnProperty(achv.parentId));
|
||||
const tinted = !hidden && !unlocked;
|
||||
@ -284,14 +356,54 @@ export default class AchvsUiHandler extends MessageUiHandler {
|
||||
}
|
||||
});
|
||||
|
||||
if (achvRange.length < this.achvIcons.length) {
|
||||
this.achvIcons.slice(achvRange.length).map(i => i.setVisible(false));
|
||||
if (achvRange.length < this.icons.length) {
|
||||
this.icons.slice(achvRange.length).map(i => i.setVisible(false));
|
||||
}
|
||||
|
||||
this.currentTotal = this.achvsTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* updateVoucherIcons(): void
|
||||
* Determines what data is to be displayed on the UI and updates it accordingly based on the current value of this.scrollCursor
|
||||
*/
|
||||
updateVoucherIcons(): void {
|
||||
this.headerText.text = this.vouchersName;
|
||||
this.headerActionText.text = this.achvsName;
|
||||
const textPosition = this.headerBgX - this.headerActionText.displayWidth - 8;
|
||||
this.headerActionText.setX(textPosition);
|
||||
this.headerActionButton.setX(textPosition - this.headerActionButton.displayWidth - 4);
|
||||
|
||||
const voucherUnlocks = this.scene.gameData.voucherUnlocks;
|
||||
|
||||
const itemOffset = this.scrollCursor * this.COLS;
|
||||
const itemLimit = this.ROWS * this.COLS;
|
||||
|
||||
const voucherRange = Object.values(vouchers).slice(itemOffset, itemLimit + itemOffset);
|
||||
|
||||
voucherRange.forEach((voucher: Voucher, i: integer) => {
|
||||
const icon = this.icons[i];
|
||||
const unlocked = voucherUnlocks.hasOwnProperty(voucher.id);
|
||||
|
||||
icon.setFrame(getVoucherTypeIcon(voucher.voucherType));
|
||||
icon.setVisible(true);
|
||||
if (!unlocked) {
|
||||
icon.setTintFill(0);
|
||||
} else {
|
||||
icon.clearTint();
|
||||
}
|
||||
});
|
||||
|
||||
if (voucherRange.length < this.icons.length) {
|
||||
this.icons.slice(voucherRange.length).map(i => i.setVisible(false));
|
||||
}
|
||||
this.currentTotal = this.vouchersTotal;
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.achvsContainer.setVisible(false);
|
||||
this.currentPage = Page.ACHIEVEMENTS;
|
||||
this.mainContainer.setVisible(false);
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import { DexAttr, GameData } from "../system/game-data";
|
||||
import { speciesStarters } from "../data/pokemon-species";
|
||||
import {Button} from "#enums/buttons";
|
||||
import i18next from "i18next";
|
||||
import { UiTheme } from "#app/enums/ui-theme";
|
||||
|
||||
interface DisplayStat {
|
||||
label_key?: string;
|
||||
@ -218,6 +219,9 @@ export default class GameStatsUiHandler extends UiHandler {
|
||||
private statLabels: Phaser.GameObjects.Text[];
|
||||
private statValues: Phaser.GameObjects.Text[];
|
||||
|
||||
private arrowUp: Phaser.GameObjects.Sprite;
|
||||
private arrowDown: Phaser.GameObjects.Sprite;
|
||||
|
||||
constructor(scene: BattleScene, mode: Mode | null = null) {
|
||||
super(scene, mode);
|
||||
|
||||
@ -241,11 +245,9 @@ export default class GameStatsUiHandler extends UiHandler {
|
||||
|
||||
const statsBgWidth = ((this.scene.game.canvas.width / 6) - 2) / 2;
|
||||
const [ statsBgLeft, statsBgRight ] = new Array(2).fill(null).map((_, i) => {
|
||||
let width = statsBgWidth;
|
||||
if (!i) {
|
||||
width += 5;
|
||||
}
|
||||
const statsBg = addWindow(this.scene, statsBgWidth * i, headerBg.height, width, (this.scene.game.canvas.height / 6) - headerBg.height - 2, false, !!i, 2);
|
||||
const width = statsBgWidth + 2;
|
||||
const height = Math.floor((this.scene.game.canvas.height / 6) - headerBg.height - 2);
|
||||
const statsBg = addWindow(this.scene, (statsBgWidth - 2) * i, headerBg.height, width, height, false, false, i>0?-3:0, 1);
|
||||
statsBg.setOrigin(0, 0);
|
||||
return statsBg;
|
||||
});
|
||||
@ -272,6 +274,14 @@ export default class GameStatsUiHandler extends UiHandler {
|
||||
this.gameStatsContainer.add(statsBgRight);
|
||||
this.gameStatsContainer.add(this.statsContainer);
|
||||
|
||||
// arrows to show that we can scroll through the stats
|
||||
const isLegacyTheme = this.scene.uiTheme === UiTheme.LEGACY;
|
||||
this.arrowDown = this.scene.add.sprite(statsBgWidth, this.scene.game.canvas.height / 6 - (isLegacyTheme? 9 : 5), "prompt");
|
||||
this.gameStatsContainer.add(this.arrowDown);
|
||||
this.arrowUp = this.scene.add.sprite(statsBgWidth, headerBg.height + (isLegacyTheme? 7 : 3), "prompt");
|
||||
this.arrowUp.flipY = true;
|
||||
this.gameStatsContainer.add(this.arrowUp);
|
||||
|
||||
ui.add(this.gameStatsContainer);
|
||||
|
||||
this.setCursor(0);
|
||||
@ -286,6 +296,15 @@ export default class GameStatsUiHandler extends UiHandler {
|
||||
|
||||
this.updateStats();
|
||||
|
||||
this.arrowUp.play("prompt");
|
||||
this.arrowDown.play("prompt");
|
||||
if (this.scene.uiTheme === UiTheme.LEGACY) {
|
||||
this.arrowUp.setTint(0x484848);
|
||||
this.arrowDown.setTint(0x484848);
|
||||
}
|
||||
|
||||
this.updateArrows();
|
||||
|
||||
this.gameStatsContainer.setVisible(true);
|
||||
|
||||
this.getUi().moveTo(this.gameStatsContainer, this.getUi().length - 1);
|
||||
@ -311,6 +330,17 @@ export default class GameStatsUiHandler extends UiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show arrows at the top / bottom of the page if it's possible to scroll in that direction
|
||||
*/
|
||||
updateArrows(): void {
|
||||
const showUpArrow = this.cursor > 0;
|
||||
this.arrowUp.setVisible(showUpArrow);
|
||||
|
||||
const showDownArrow = this.cursor < Math.ceil((Object.keys(displayStats).length - 18) / 2);
|
||||
this.arrowDown.setVisible(showDownArrow);
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
@ -346,6 +376,7 @@ export default class GameStatsUiHandler extends UiHandler {
|
||||
|
||||
if (ret) {
|
||||
this.updateStats();
|
||||
this.updateArrows();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -8,7 +8,7 @@ import { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui
|
||||
import { Tutorial, handleTutorial } from "../tutorial";
|
||||
import { loggedInUser, updateUserInfo } from "../account";
|
||||
import i18next from "i18next";
|
||||
import {Button} from "#enums/buttons";
|
||||
import { Button } from "#enums/buttons";
|
||||
import { GameDataType } from "#enums/game-data-type";
|
||||
import BgmBar from "#app/ui/bgm-bar";
|
||||
|
||||
@ -17,7 +17,6 @@ enum MenuOptions {
|
||||
ACHIEVEMENTS,
|
||||
STATS,
|
||||
RUN_HISTORY,
|
||||
VOUCHERS,
|
||||
EGG_LIST,
|
||||
EGG_GACHA,
|
||||
MANAGE_DATA,
|
||||
@ -98,7 +97,6 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
|
||||
render() {
|
||||
const ui = this.getUi();
|
||||
console.log(ui.getModeChain());
|
||||
this.excludedMenus = () => [
|
||||
{ condition: ![Mode.COMMAND, Mode.TITLE].includes(ui.getModeChain()[0]), options: [ MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST] },
|
||||
{ condition: bypassLogin, options: [ MenuOptions.LOG_OUT ] }
|
||||
@ -388,10 +386,6 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
ui.setOverlayMode(Mode.RUN_HISTORY);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.VOUCHERS:
|
||||
ui.setOverlayMode(Mode.VOUCHERS);
|
||||
success = true;
|
||||
break;
|
||||
case MenuOptions.EGG_LIST:
|
||||
if (this.scene.gameData.eggs.length) {
|
||||
ui.revertMode();
|
||||
|
@ -409,10 +409,12 @@ export default class RunInfoUiHandler extends UiHandler {
|
||||
|
||||
// Duration + Money
|
||||
const runInfoTextContainer = this.scene.add.container(0, 0);
|
||||
const runInfoText = addBBCodeTextObject(this.scene, 7, 0, "", TextStyle.WINDOW, {fontSize : "50px", lineSpacing:3});
|
||||
// Japanese is set to a greater line spacing of 35px in addBBCodeTextObject() if lineSpacing < 12.
|
||||
const lineSpacing = (i18next.resolvedLanguage === "ja") ? 12 : 3;
|
||||
const runInfoText = addBBCodeTextObject(this.scene, 7, 0, "", TextStyle.WINDOW, {fontSize: "50px", lineSpacing: lineSpacing});
|
||||
const runTime = Utils.getPlayTimeString(this.runInfo.playTime);
|
||||
runInfoText.appendText(`${i18next.t("runHistory:runLength")}: ${runTime}`, false);
|
||||
const runMoney = Utils.formatMoney(this.runInfo.money, 1000);
|
||||
const runMoney = Utils.formatMoney(this.scene.moneyFormat, this.runInfo.money);
|
||||
runInfoText.appendText(`[color=${getTextColor(TextStyle.MONEY)}]${i18next.t("battleScene:moneyOwned", {formattedMoney : runMoney})}[/color]`);
|
||||
runInfoText.setPosition(7, 70);
|
||||
runInfoTextContainer.add(runInfoText);
|
||||
@ -513,7 +515,9 @@ export default class RunInfoUiHandler extends UiHandler {
|
||||
}
|
||||
const pPassiveInfo = pokemon.passive ? passiveLabel+": "+pokemon.getPassiveAbility().name : "";
|
||||
const pAbilityInfo = abilityLabel + ": " + pokemon.getAbility().name;
|
||||
const pokeInfoText = addBBCodeTextObject(this.scene, 0, 0, pName, TextStyle.SUMMARY, {fontSize: textContainerFontSize, lineSpacing:3});
|
||||
// Japanese is set to a greater line spacing of 35px in addBBCodeTextObject() if lineSpacing < 12.
|
||||
const lineSpacing = (i18next.resolvedLanguage === "ja") ? 12 : 3;
|
||||
const pokeInfoText = addBBCodeTextObject(this.scene, 0, 0, pName, TextStyle.SUMMARY, {fontSize: textContainerFontSize, lineSpacing: lineSpacing});
|
||||
pokeInfoText.appendText(`${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatFancyLargeNumber(pokemon.level, 1)} - ${pNature}`);
|
||||
pokeInfoText.appendText(pAbilityInfo);
|
||||
pokeInfoText.appendText(pPassiveInfo);
|
||||
@ -537,12 +541,12 @@ export default class RunInfoUiHandler extends UiHandler {
|
||||
const speedLabel = (currentLanguage==="es"||currentLanguage==="pt_BR") ? i18next.t("runHistory:SPDshortened") : i18next.t("pokemonInfo:Stat.SPDshortened");
|
||||
const speed = speedLabel+": "+pStats[5];
|
||||
// Column 1: HP Atk Def
|
||||
const pokeStatText1 = addBBCodeTextObject(this.scene, -5, 0, hp, TextStyle.SUMMARY, {fontSize: textContainerFontSize, lineSpacing:3});
|
||||
const pokeStatText1 = addBBCodeTextObject(this.scene, -5, 0, hp, TextStyle.SUMMARY, {fontSize: textContainerFontSize, lineSpacing: lineSpacing});
|
||||
pokeStatText1.appendText(atk);
|
||||
pokeStatText1.appendText(def);
|
||||
pokeStatTextContainer.add(pokeStatText1);
|
||||
// Column 2: SpAtk SpDef Speed
|
||||
const pokeStatText2 = addBBCodeTextObject(this.scene, 25, 0, spatk, TextStyle.SUMMARY, {fontSize: textContainerFontSize, lineSpacing:3});
|
||||
const pokeStatText2 = addBBCodeTextObject(this.scene, 25, 0, spatk, TextStyle.SUMMARY, {fontSize: textContainerFontSize, lineSpacing: lineSpacing});
|
||||
pokeStatText2.appendText(spdef);
|
||||
pokeStatText2.appendText(speed);
|
||||
pokeStatTextContainer.add(pokeStatText2);
|
||||
|
@ -5,7 +5,7 @@ import BBCodeText from "phaser3-rex-plugins/plugins/gameobjects/tagtext/bbcodete
|
||||
import InputText from "phaser3-rex-plugins/plugins/inputtext";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { ModifierTier } from "../modifier/modifier-tier";
|
||||
import i18next from "#app/plugins/i18n.js";
|
||||
import i18next from "#app/plugins/i18n";
|
||||
|
||||
export enum TextStyle {
|
||||
MESSAGE,
|
||||
@ -227,6 +227,7 @@ export function getBBCodeFrag(content: string, textStyle: TextStyle, uiTheme: Ui
|
||||
}
|
||||
|
||||
export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: UiTheme = UiTheme.DEFAULT): string {
|
||||
const isLegacyTheme = uiTheme === UiTheme.LEGACY;
|
||||
switch (textStyle) {
|
||||
case TextStyle.MESSAGE:
|
||||
return !shadow ? "#f8f8f8" : "#6b5a73";
|
||||
@ -235,29 +236,29 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: Ui
|
||||
case TextStyle.MOVE_PP_FULL:
|
||||
case TextStyle.TOOLTIP_CONTENT:
|
||||
case TextStyle.SETTINGS_VALUE:
|
||||
if (uiTheme) {
|
||||
if (isLegacyTheme) {
|
||||
return !shadow ? "#484848" : "#d0d0c8";
|
||||
}
|
||||
return !shadow ? "#f8f8f8" : "#6b5a73";
|
||||
case TextStyle.MOVE_PP_HALF_FULL:
|
||||
if (uiTheme) {
|
||||
if (isLegacyTheme) {
|
||||
return !shadow ? "#a68e17" : "#ebd773";
|
||||
}
|
||||
return !shadow ? "#ccbe00" : "#6e672c";
|
||||
case TextStyle.MOVE_PP_NEAR_EMPTY:
|
||||
if (uiTheme) {
|
||||
if (isLegacyTheme) {
|
||||
return !shadow ? "#d64b00" : "#f7b18b";
|
||||
}
|
||||
return !shadow ? "#d64b00" : "#69402a";
|
||||
case TextStyle.MOVE_PP_EMPTY:
|
||||
if (uiTheme) {
|
||||
if (isLegacyTheme) {
|
||||
return !shadow ? "#e13d3d" : "#fca2a2";
|
||||
}
|
||||
return !shadow ? "#e13d3d" : "#632929";
|
||||
case TextStyle.WINDOW_ALT:
|
||||
return !shadow ? "#484848" : "#d0d0c8";
|
||||
case TextStyle.BATTLE_INFO:
|
||||
if (uiTheme) {
|
||||
if (isLegacyTheme) {
|
||||
return !shadow ? "#404040" : "#ded6b5";
|
||||
}
|
||||
return !shadow ? "#f8f8f8" : "#6b5a73";
|
||||
@ -268,7 +269,7 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: Ui
|
||||
case TextStyle.SUMMARY:
|
||||
return !shadow ? "#f8f8f8" : "#636363";
|
||||
case TextStyle.SUMMARY_ALT:
|
||||
if (uiTheme) {
|
||||
if (isLegacyTheme) {
|
||||
return !shadow ? "#f8f8f8" : "#636363";
|
||||
}
|
||||
return !shadow ? "#484848" : "#d0d0c8";
|
||||
@ -288,6 +289,9 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: Ui
|
||||
case TextStyle.STATS_LABEL:
|
||||
return !shadow ? "#f8b050" : "#c07800";
|
||||
case TextStyle.STATS_VALUE:
|
||||
if (isLegacyTheme) {
|
||||
return !shadow ? "#484848" : "#d0d0c8";
|
||||
}
|
||||
return !shadow ? "#f8f8f8" : "#6b5a73";
|
||||
case TextStyle.SUMMARY_GREEN:
|
||||
return !shadow ? "#78c850" : "#306850";
|
||||
|
13
src/ui/ui.ts
13
src/ui/ui.ts
@ -1,4 +1,4 @@
|
||||
import {default as BattleScene} from "../battle-scene";
|
||||
import { default as BattleScene } from "../battle-scene";
|
||||
import UiHandler from "./ui-handler";
|
||||
import BattleMessageUiHandler from "./battle-message-ui-handler";
|
||||
import CommandUiHandler from "./command-ui-handler";
|
||||
@ -23,7 +23,6 @@ import OptionSelectUiHandler from "./settings/option-select-ui-handler";
|
||||
import EggHatchSceneHandler from "./egg-hatch-scene-handler";
|
||||
import EggListUiHandler from "./egg-list-ui-handler";
|
||||
import EggGachaUiHandler from "./egg-gacha-ui-handler";
|
||||
import VouchersUiHandler from "./vouchers-ui-handler";
|
||||
import {addWindow} from "./ui-theme";
|
||||
import LoginFormUiHandler from "./login-form-ui-handler";
|
||||
import RegistrationFormUiHandler from "./registration-form-ui-handler";
|
||||
@ -37,8 +36,8 @@ import SavingIconHandler from "./saving-icon-handler";
|
||||
import UnavailableModalUiHandler from "./unavailable-modal-ui-handler";
|
||||
import OutdatedModalUiHandler from "./outdated-modal-ui-handler";
|
||||
import SessionReloadModalUiHandler from "./session-reload-modal-ui-handler";
|
||||
import {Button} from "#enums/buttons";
|
||||
import i18next, {ParseKeys} from "i18next";
|
||||
import { Button } from "#enums/buttons";
|
||||
import i18next, { ParseKeys } from "i18next";
|
||||
import GamepadBindingUiHandler from "./settings/gamepad-binding-ui-handler";
|
||||
import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler";
|
||||
import KeyboardBindingUiHandler from "#app/ui/settings/keyboard-binding-ui-handler";
|
||||
@ -77,7 +76,6 @@ export enum Mode {
|
||||
KEYBOARD_BINDING,
|
||||
ACHIEVEMENTS,
|
||||
GAME_STATS,
|
||||
VOUCHERS,
|
||||
EGG_LIST,
|
||||
EGG_GACHA,
|
||||
LOGIN_FORM,
|
||||
@ -120,7 +118,6 @@ const noTransitionModes = [
|
||||
Mode.SETTINGS_KEYBOARD,
|
||||
Mode.ACHIEVEMENTS,
|
||||
Mode.GAME_STATS,
|
||||
Mode.VOUCHERS,
|
||||
Mode.LOGIN_FORM,
|
||||
Mode.REGISTRATION_FORM,
|
||||
Mode.LOADING,
|
||||
@ -179,7 +176,6 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
new KeyboardBindingUiHandler(scene),
|
||||
new AchvsUiHandler(scene),
|
||||
new GameStatsUiHandler(scene),
|
||||
new VouchersUiHandler(scene),
|
||||
new EggListUiHandler(scene),
|
||||
new EggGachaUiHandler(scene),
|
||||
new LoginFormUiHandler(scene),
|
||||
@ -460,6 +456,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
}
|
||||
if (chainMode && this.mode && !clear) {
|
||||
this.modeChain.push(this.mode);
|
||||
(this.scene as BattleScene).updateGameInfo();
|
||||
}
|
||||
this.mode = mode;
|
||||
const touchControls = document?.getElementById("touchControls");
|
||||
@ -507,6 +504,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
|
||||
resetModeChain(): void {
|
||||
this.modeChain = [];
|
||||
(this.scene as BattleScene).updateGameInfo();
|
||||
}
|
||||
|
||||
revertMode(): Promise<boolean> {
|
||||
@ -520,6 +518,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
const doRevertMode = () => {
|
||||
this.getHandler().clear();
|
||||
this.mode = this.modeChain.pop()!; // TODO: is this bang correct?
|
||||
(this.scene as BattleScene).updateGameInfo();
|
||||
const touchControls = document.getElementById("touchControls");
|
||||
if (touchControls) {
|
||||
touchControls.dataset.uiMode = Mode[this.mode];
|
||||
|
@ -1,262 +0,0 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import { Button } from "#enums/buttons";
|
||||
import i18next from "i18next";
|
||||
import { Voucher, getVoucherTypeIcon, getVoucherTypeName, vouchers } from "../system/voucher";
|
||||
import MessageUiHandler from "./message-ui-handler";
|
||||
import { TextStyle, addTextObject } from "./text";
|
||||
import { Mode } from "./ui";
|
||||
import { addWindow } from "./ui-theme";
|
||||
|
||||
const itemRows = 4;
|
||||
const itemCols = 17;
|
||||
|
||||
export default class VouchersUiHandler extends MessageUiHandler {
|
||||
private vouchersContainer: Phaser.GameObjects.Container;
|
||||
private voucherIconsContainer: Phaser.GameObjects.Container;
|
||||
|
||||
private voucherIconsBg: Phaser.GameObjects.NineSlice;
|
||||
private voucherIcons: Phaser.GameObjects.Sprite[];
|
||||
private titleText: Phaser.GameObjects.Text;
|
||||
private unlockText: Phaser.GameObjects.Text;
|
||||
|
||||
private itemsTotal: integer;
|
||||
private scrollCursor: integer;
|
||||
|
||||
private cursorObj: Phaser.GameObjects.NineSlice | null;
|
||||
|
||||
constructor(scene: BattleScene, mode: Mode | null = null) {
|
||||
super(scene, mode);
|
||||
|
||||
this.itemsTotal = Object.keys(vouchers).length;
|
||||
this.scrollCursor = 0;
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
this.vouchersContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1);
|
||||
|
||||
this.vouchersContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains);
|
||||
|
||||
const headerBg = addWindow(this.scene, 0, 0, (this.scene.game.canvas.width / 6) - 2, 24);
|
||||
headerBg.setOrigin(0, 0);
|
||||
|
||||
const headerText = addTextObject(this.scene, 0, 0, i18next.t("voucher:vouchers"), TextStyle.SETTINGS_LABEL);
|
||||
headerText.setOrigin(0, 0);
|
||||
headerText.setPositionRelative(headerBg, 8, 4);
|
||||
|
||||
this.voucherIconsBg = addWindow(this.scene, 0, headerBg.height, (this.scene.game.canvas.width / 6) - 2, (this.scene.game.canvas.height / 6) - headerBg.height - 68);
|
||||
this.voucherIconsBg.setOrigin(0, 0);
|
||||
|
||||
this.voucherIconsContainer = this.scene.add.container(6, headerBg.height + 6);
|
||||
|
||||
this.voucherIcons = [];
|
||||
|
||||
for (let a = 0; a < itemRows * itemCols; a++) {
|
||||
const x = (a % itemCols) * 18;
|
||||
const y = Math.floor(a / itemCols) * 18;
|
||||
|
||||
const icon = this.scene.add.sprite(x, y, "items", "unknown");
|
||||
icon.setOrigin(0, 0);
|
||||
icon.setScale(0.5);
|
||||
|
||||
this.voucherIcons.push(icon);
|
||||
this.voucherIconsContainer.add(icon);
|
||||
}
|
||||
|
||||
const titleBg = addWindow(this.scene, 0, headerBg.height + this.voucherIconsBg.height, 220, 24);
|
||||
titleBg.setOrigin(0, 0);
|
||||
|
||||
this.titleText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW);
|
||||
this.titleText.setOrigin(0, 0);
|
||||
this.titleText.setPositionRelative(titleBg, 8, 4);
|
||||
|
||||
const unlockBg = addWindow(this.scene, titleBg.x + titleBg.width, titleBg.y, 98, 24);
|
||||
unlockBg.setOrigin(0, 0);
|
||||
|
||||
this.unlockText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW);
|
||||
this.unlockText.setOrigin(0, 0);
|
||||
this.unlockText.setPositionRelative(unlockBg, 8, 4);
|
||||
|
||||
const descriptionBg = addWindow(this.scene, 0, titleBg.y + titleBg.height, (this.scene.game.canvas.width / 6) - 2, 42);
|
||||
descriptionBg.setOrigin(0, 0);
|
||||
|
||||
const descriptionText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW, { maxLines: 2 });
|
||||
descriptionText.setWordWrapWidth(1870);
|
||||
descriptionText.setOrigin(0, 0);
|
||||
descriptionText.setPositionRelative(descriptionBg, 8, 4);
|
||||
|
||||
this.message = descriptionText;
|
||||
|
||||
this.vouchersContainer.add(headerBg);
|
||||
this.vouchersContainer.add(headerText);
|
||||
this.vouchersContainer.add(this.voucherIconsBg);
|
||||
this.vouchersContainer.add(this.voucherIconsContainer);
|
||||
this.vouchersContainer.add(titleBg);
|
||||
this.vouchersContainer.add(this.titleText);
|
||||
this.vouchersContainer.add(unlockBg);
|
||||
this.vouchersContainer.add(this.unlockText);
|
||||
this.vouchersContainer.add(descriptionBg);
|
||||
this.vouchersContainer.add(descriptionText);
|
||||
|
||||
ui.add(this.vouchersContainer);
|
||||
|
||||
this.setCursor(0);
|
||||
|
||||
this.vouchersContainer.setVisible(false);
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
super.show(args);
|
||||
|
||||
this.vouchersContainer.setVisible(true);
|
||||
this.setCursor(0);
|
||||
this.setScrollCursor(0);
|
||||
|
||||
this.updateVoucherIcons();
|
||||
|
||||
this.getUi().moveTo(this.vouchersContainer, this.getUi().length - 1);
|
||||
|
||||
this.getUi().hideTooltip();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected showVoucher(voucher: Voucher) {
|
||||
const voucherUnlocks = this.scene.gameData.voucherUnlocks;
|
||||
const unlocked = voucherUnlocks.hasOwnProperty(voucher.id);
|
||||
|
||||
this.titleText.setText(getVoucherTypeName(voucher.voucherType));
|
||||
this.showText(voucher.description);
|
||||
this.unlockText.setText(unlocked ? new Date(voucherUnlocks[voucher.id]).toLocaleDateString() : i18next.t("voucher:locked"));
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
|
||||
if (button === Button.CANCEL) {
|
||||
success = true;
|
||||
this.scene.ui.revertMode();
|
||||
} else {
|
||||
const rowIndex = Math.floor(this.cursor / itemCols);
|
||||
const itemOffset = (this.scrollCursor * itemCols);
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
if (this.cursor < itemCols) {
|
||||
if (this.scrollCursor) {
|
||||
success = this.setScrollCursor(this.scrollCursor - 1);
|
||||
}
|
||||
} else {
|
||||
success = this.setCursor(this.cursor - itemCols);
|
||||
}
|
||||
break;
|
||||
case Button.DOWN:
|
||||
const canMoveDown = (this.cursor + itemOffset) + itemCols < this.itemsTotal;
|
||||
if (rowIndex >= itemRows - 1) {
|
||||
if (this.scrollCursor < Math.ceil(this.itemsTotal / itemCols) - itemRows && canMoveDown) {
|
||||
success = this.setScrollCursor(this.scrollCursor + 1);
|
||||
}
|
||||
} else if (canMoveDown) {
|
||||
success = this.setCursor(this.cursor + itemCols);
|
||||
}
|
||||
break;
|
||||
case Button.LEFT:
|
||||
if (!this.cursor && this.scrollCursor) {
|
||||
success = this.setScrollCursor(this.scrollCursor - 1) && this.setCursor(this.cursor + (itemCols - 1));
|
||||
} else if (this.cursor) {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
}
|
||||
break;
|
||||
case Button.RIGHT:
|
||||
if (this.cursor + 1 === itemRows * itemCols && this.scrollCursor < Math.ceil(this.itemsTotal / itemCols) - itemRows) {
|
||||
success = this.setScrollCursor(this.scrollCursor + 1) && this.setCursor(this.cursor - (itemCols - 1));
|
||||
} else if (this.cursor + itemOffset < Object.keys(vouchers).length - 1) {
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
ui.playSelect();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const ret = super.setCursor(cursor);
|
||||
|
||||
let updateVoucher = ret;
|
||||
|
||||
if (!this.cursorObj) {
|
||||
this.cursorObj = this.scene.add.nineslice(0, 0, "select_cursor_highlight", undefined, 16, 16, 1, 1, 1, 1);
|
||||
this.cursorObj.setOrigin(0, 0);
|
||||
this.voucherIconsContainer.add(this.cursorObj);
|
||||
updateVoucher = true;
|
||||
}
|
||||
|
||||
this.cursorObj.setPositionRelative(this.voucherIcons[this.cursor], 0, 0);
|
||||
|
||||
if (updateVoucher) {
|
||||
this.showVoucher(vouchers[Object.keys(vouchers)[cursor + this.scrollCursor * itemCols]]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
setScrollCursor(scrollCursor: integer): boolean {
|
||||
if (scrollCursor === this.scrollCursor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.scrollCursor = scrollCursor;
|
||||
|
||||
this.updateVoucherIcons();
|
||||
|
||||
this.showVoucher(vouchers[Object.keys(vouchers)[Math.min(this.cursor + this.scrollCursor * itemCols, Object.values(vouchers).length - 1)]]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
updateVoucherIcons(): void {
|
||||
const voucherUnlocks = this.scene.gameData.voucherUnlocks;
|
||||
|
||||
const itemOffset = this.scrollCursor * itemCols;
|
||||
const itemLimit = itemRows * itemCols;
|
||||
|
||||
const voucherRange = Object.values(vouchers).slice(itemOffset, itemLimit + itemOffset);
|
||||
|
||||
voucherRange.forEach((voucher: Voucher, i: integer) => {
|
||||
const icon = this.voucherIcons[i];
|
||||
const unlocked = voucherUnlocks.hasOwnProperty(voucher.id);
|
||||
|
||||
icon.setFrame(getVoucherTypeIcon(voucher.voucherType));
|
||||
icon.setVisible(true);
|
||||
if (!unlocked) {
|
||||
icon.setTintFill(0);
|
||||
} else {
|
||||
icon.clearTint();
|
||||
}
|
||||
});
|
||||
|
||||
if (voucherRange.length < this.voucherIcons.length) {
|
||||
this.voucherIcons.slice(voucherRange.length).map(i => i.setVisible(false));
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.vouchersContainer.setVisible(false);
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
||||
eraseCursor() {
|
||||
if (this.cursorObj) {
|
||||
this.cursorObj.destroy();
|
||||
}
|
||||
this.cursorObj = null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user