Add achievement system and UI

Add achievement system and UI; fix counting invalid inputs in UI handlers for input delay
This commit is contained in:
Flashfyre committed 2023-11-12 00:31:40 -05:00
1 parent ff93e6233f
commit cbbb8e972b
49 files changed
+4920 -3764

No files matched your search

+22 -1
View File
@@ -31,6 +31,7 @@ import { getBiomeKey } from "./arena";
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
import { GameMode } from "./game-mode";
import { Species } from "./data/species";
import { HealAchv, LevelAchv, MoneyAchv, achvs } from "./system/achv";
export class CheckLoadPhase extends BattlePhase {
private loaded: boolean;
@@ -329,6 +330,8 @@ export class EncounterPhase extends BattlePhase {
enemyPokemon.untint(100, 'Sine.easeOut');
enemyPokemon.cry();
enemyPokemon.showInfo();
if (enemyPokemon.isShiny())
this.scene.validateAchv(achvs.SEE_SHINY);
});
let text = enemyField.length === 1
? `A wild ${enemyField[0].name} appeared!`
@@ -2259,6 +2262,8 @@ export class MoneyRewardPhase extends BattlePhase {
this.scene.money += moneyAmount.value;
this.scene.updateMoneyText();
this.scene.validateAchvs(MoneyAchv);
this.scene.ui.showText(`You got ₽${moneyAmount.value.toLocaleString('en-US')}\nfor winning!`, null, () => this.end(), null, true);
}
}
@@ -2299,6 +2304,8 @@ export class GameOverPhase extends BattlePhase {
this.scene.gameData.clearSession();
this.scene.time.delayedCall(1000, () => {
if (this.victory)
this.scene.validateAchv(achvs.CLASSIC_VICTORY);
const fadeDuration = this.victory ? 10000 : 5000;
this.scene.fadeOutBgm(fadeDuration, true);
this.scene.ui.fadeOut(fadeDuration).then(() => {
@@ -2464,6 +2471,8 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
start() {
super.start();
this.scene.validateAchvs(LevelAchv, new Utils.IntegerHolder(this.level));
const pokemon = this.getPokemon();
const prevStats = pokemon.stats.slice(0);
pokemon.calculateStats();
@@ -2633,7 +2642,9 @@ export class PokemonHealPhase extends CommonAnimPhase {
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
if (!this.revive)
this.scene.applyModifiers(HealingBoosterModifier, this.player, hpRestoreMultiplier);
pokemon.heal(this.hpHealed * hpRestoreMultiplier.value);
const healAmount = new Utils.NumberHolder(this.hpHealed * hpRestoreMultiplier.value);
pokemon.heal(healAmount.value);
this.scene.validateAchvs(HealAchv, healAmount)
pokemon.updateInfo().then(() => super.end());
} else if (this.showFullHpMessage)
this.message = getPokemonMessage(pokemon, `'s\nHP is full!`);
@@ -2783,6 +2794,16 @@ export class AttemptCapturePhase extends PokemonPhase {
catch() {
const pokemon = this.getPokemon() as EnemyPokemon;
this.scene.unshiftPhase(new VictoryPhase(this.scene, this.battlerIndex));
if (pokemon.getAbility().id === (!pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm()).abilityHidden)
this.scene.validateAchv(achvs.HIDDEN_ABILITY);
if (pokemon.species.pseudoLegendary || pokemon.species.legendary)
this.scene.validateAchv(achvs.CATCH_LEGENDARY);
if (pokemon.species.mythical)
this.scene.validateAchv(achvs.CATCH_MYTHICAL);
this.scene.ui.showText(`${pokemon.name} was caught!`, null, () => {
const end = () => {
this.removePb();
+45 -15
View File
@@ -16,7 +16,7 @@ import { GameData } from './system/game-data';
import StarterSelectUiHandler from './ui/starter-select-ui-handler';
import { TextStyle, addTextObject } from './ui/text';
import { Moves, initMoves } from './data/move';
import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getModifierType, modifierTypes } from './modifier/modifier-type';
import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave } from './modifier/modifier-type';
import AbilityBar from './ui/ability-bar';
import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, applyAbAttrs, initAbilities } from './data/ability';
import Battle, { BattleType, FixedBattleConfig, fixedBattles } from './battle';
@@ -34,6 +34,7 @@ import SettingsUiHandler from './ui/settings-ui-handler';
import MessageUiHandler from './ui/message-ui-handler';
import { Species } from './data/species';
import InvertPostFX from './pipelines/invert';
import { Achv, achvs } from './system/achv';
const enableAuto = true;
const quickStart = false;
@@ -199,6 +200,10 @@ export default class BattleScene extends Phaser.Scene {
this.loadImage('icon_owned', 'ui');
this.loadImage('ability_bar', 'ui');
this.loadImage('party_exp_bar', 'ui');
this.loadImage('achv_bar', 'ui');
this.loadImage('achv_bar_2', 'ui');
this.loadImage('achv_bar_3', 'ui');
this.loadImage('achv_bar_4', 'ui');
this.loadImage('shiny_star', 'ui', 'shiny.png');
this.loadImage('icon_spliced', 'ui');
@@ -306,6 +311,7 @@ export default class BattleScene extends Phaser.Scene {
this.loadSe('beam');
this.loadSe('upgrade');
this.loadSe('buy');
this.loadSe('achv');
this.loadSe('error');
this.loadSe('pb_rel');
@@ -838,6 +844,7 @@ export default class BattleScene extends Phaser.Scene {
this.waveCountText.setY(-(this.game.canvas.height / 6) + (this.enemyModifiers.filter(m => m.isIconVisible(this)).length ? 15 : 0));
this.moneyText.setY(this.waveCountText.y + 10);
this.partyExpBar.setY(this.moneyText.y + 15);
this.ui?.achvBar.setY((this.game.canvas.height / 6 + this.moneyText.y + 15));
}
getMaxExpLevel(ignoreLevelCap?: boolean): integer {
@@ -867,18 +874,19 @@ export default class BattleScene extends Phaser.Scene {
checkInput(): boolean {
if (this.blockInput)
return;
let inputSuccess = false;
if (this.isButtonPressed(Button.UP))
this.ui.processInput(Button.UP);
inputSuccess = this.ui.processInput(Button.UP);
else if (this.isButtonPressed(Button.DOWN))
this.ui.processInput(Button.DOWN);
inputSuccess = this.ui.processInput(Button.DOWN);
else if (this.isButtonPressed(Button.LEFT))
this.ui.processInput(Button.LEFT);
inputSuccess = this.ui.processInput(Button.LEFT);
else if (this.isButtonPressed(Button.RIGHT))
this.ui.processInput(Button.RIGHT);
inputSuccess = this.ui.processInput(Button.RIGHT);
else if (this.isButtonPressed(Button.ACTION))
this.ui.processInput(Button.ACTION);
inputSuccess = this.ui.processInput(Button.ACTION);
else if (this.isButtonPressed(Button.CANCEL))
this.ui.processInput(Button.CANCEL);
inputSuccess = this.ui.processInput(Button.CANCEL);
else if (this.isButtonPressed(Button.MENU)) {
switch (this.ui.getMode()) {
case Mode.MESSAGE:
@@ -894,8 +902,7 @@ export default class BattleScene extends Phaser.Scene {
case Mode.STARTER_SELECT:
case Mode.CONFIRM:
case Mode.GAME_MODE_SELECT:
this.ui.setModeWithoutClear(Mode.SETTINGS);
this.playSound('menu_open');
this.ui.setOverlayMode(Mode.MENU);
break;
case Mode.SETTINGS:
this.ui.revertMode();
@@ -904,16 +911,15 @@ export default class BattleScene extends Phaser.Scene {
default:
return;
}
}
else if (this.ui?.getHandler() instanceof StarterSelectUiHandler) {
} else if (this.ui?.getHandler() instanceof StarterSelectUiHandler) {
if (this.isButtonPressed(Button.CYCLE_SHINY))
this.ui.processInput(Button.CYCLE_SHINY);
inputSuccess = this.ui.processInput(Button.CYCLE_SHINY);
else if (this.isButtonPressed(Button.CYCLE_FORM))
this.ui.processInput(Button.CYCLE_FORM);
inputSuccess = this.ui.processInput(Button.CYCLE_FORM);
else if (this.isButtonPressed(Button.CYCLE_GENDER))
this.ui.processInput(Button.CYCLE_GENDER);
inputSuccess = this.ui.processInput(Button.CYCLE_GENDER);
else if (this.isButtonPressed(Button.CYCLE_ABILITY))
this.ui.processInput(Button.CYCLE_ABILITY);
inputSuccess = this.ui.processInput(Button.CYCLE_ABILITY);
else
return;
}
@@ -1413,4 +1419,28 @@ export default class BattleScene extends Phaser.Scene {
return null;
}
validateAchvs(achvType: { new(...args: any[]): Achv }, ...args: any[]): void {
const filteredAchvs = Object.values(achvs).filter(a => a instanceof achvType);
let newAchv = false;
for (let achv of filteredAchvs) {
if (this.validateAchv(achv, args, false))
newAchv = true;
}
if (newAchv)
this.gameData.saveSystem();
}
validateAchv(achv: Achv, args?: any[], save: boolean = true): boolean {
if (!this.gameData.achvUnlocks.hasOwnProperty(achv.id) && achv.validate(this, args)) {
this.gameData.achvUnlocks[achv.id] = new Date().getTime();
this.ui.achvBar.showAchv(achv);
if (save)
this.gameData.saveSystem();
return true;
}
return false;
}
}
+10 -10
View File
@@ -101,7 +101,7 @@ export default class Move {
return this.attrs.filter(a => a instanceof attrType);
}
attr<T extends new (...args: any[]) => MoveAttr>(AttrType: T, ...args: ConstructorParameters<T>): Move {
attr<T extends new (...args: any[]) => MoveAttr>(AttrType: T, ...args: ConstructorParameters<T>): this {
const attr = new AttrType(...args);
this.attrs.push(attr);
const attrCondition = attr.getCondition();
@@ -111,7 +111,7 @@ export default class Move {
return this;
}
addAttr(attr: MoveAttr): Move {
addAttr(attr: MoveAttr): this {
this.attrs.push(attr);
const attrCondition = attr.getCondition();
if (attrCondition)
@@ -120,7 +120,7 @@ export default class Move {
return this;
}
target(moveTarget: MoveTarget): Move {
target(moveTarget: MoveTarget): this {
this.moveTarget = moveTarget;
return this;
}
@@ -129,7 +129,7 @@ export default class Move {
return !!(this.flags & flag);
}
condition(condition: MoveCondition): Move {
condition(condition: MoveCondition): this {
this.conditions.push(condition);
return this;
@@ -142,32 +142,32 @@ export default class Move {
this.flags ^= flag;
}
makesContact(makesContact?: boolean): Move {
makesContact(makesContact?: boolean): this {
this.setFlag(MoveFlags.MAKES_CONTACT, makesContact);
return this;
}
ignoresProtect(ignoresProtect?: boolean): Move {
ignoresProtect(ignoresProtect?: boolean): this {
this.setFlag(MoveFlags.IGNORE_PROTECT, ignoresProtect);
return this;
}
ignoresVirtual(ignoresVirtual?: boolean): Move {
ignoresVirtual(ignoresVirtual?: boolean): this {
this.setFlag(MoveFlags.IGNORE_VIRTUAL, ignoresVirtual);
return this;
}
soundBased(soundBased?: boolean): Move {
soundBased(soundBased?: boolean): this {
this.setFlag(MoveFlags.SOUND_BASED, soundBased);
return this;
}
hidesUser(hidesUser?: boolean): Move {
hidesUser(hidesUser?: boolean): this {
this.setFlag(MoveFlags.HIDE_USER, hidesUser);
return this;
}
hidesTarget(hidesTarget?: boolean): Move {
hidesTarget(hidesTarget?: boolean): this {
this.setFlag(MoveFlags.HIDE_TARGET, hidesTarget);
return this;
}
+7
View File
@@ -1,3 +1,10 @@
function getData() {
const dataStr = localStorage.getItem('data');
if (!dataStr)
return null;
return JSON.parse(atob(dataStr));
}
function getSession() {
const sessionStr = localStorage.getItem('sessionData');
if (!sessionStr)
+1 -1
View File
@@ -6,7 +6,7 @@ import { EvolutionItem, pokemonEvolutions } from '../data/pokemon-evolutions';
import { Stat, getStatName } from '../data/pokemon-stat';
import { tmPoolTiers, tmSpecies } from '../data/tms';
import { Type } from '../data/type';
import PartyUiHandler, { PokemonMoveSelectFilter, PokemonRememberMoveSelectFilter, PokemonSelectFilter } from '../ui/party-ui-handler';
import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from '../ui/party-ui-handler';
import * as Utils from '../utils';
import { TempBattleStat, getTempBattleStatBoosterItemName, getTempBattleStatName } from '../data/temp-battle-stat';
import { BerryType, getBerryEffectDescription, getBerryName } from '../data/berry';
+3
View File
@@ -15,6 +15,7 @@ import { TempBattleStat } from '../data/temp-battle-stat';
import { BerryType, getBerryEffectFunc, getBerryPredicate } from '../data/berry';
import { Species } from '../data/species';
import { StatusEffect, getStatusEffectDescriptor } from '../data/status-effect';
import { MoneyAchv } from '../system/achv';
type ModifierType = ModifierTypes.ModifierType;
export type ModifierPredicate = (modifier: Modifier) => boolean;
@@ -1171,6 +1172,7 @@ export class DamageMoneyRewardModifier extends PokemonHeldItemModifier {
scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
scene.money += moneyAmount.value;
scene.updateMoneyText();
scene.validateAchvs(MoneyAchv);
return true;
}
@@ -1194,6 +1196,7 @@ export class MoneyInterestModifier extends PersistentModifier {
const interestAmount = Math.floor(scene.money * 0.2 * this.getStackCount());
scene.money += interestAmount;
scene.updateMoneyText();
scene.validateAchvs(MoneyAchv);
scene.queueMessage(`You received interest of ₽${interestAmount.toLocaleString('en-US')}\nfrom the ${this.type.name}!`, null, true);
+5
View File
@@ -30,6 +30,7 @@ import PartyUiHandler, { PartyOption, PartyUiMode } from './ui/party-ui-handler'
import SoundFade from 'phaser3-rex-plugins/plugins/soundfade';
import { GameMode } from './game-mode';
import { LevelMoves } from './data/pokemon-level-moves';
import { DamageAchv, achvs } from './system/achv';
export enum FieldPosition {
CENTER,
@@ -867,6 +868,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.scene.setPhaseQueueSplice();
damage.value = Math.min(damage.value, this.hp);
this.damage(damage.value);
if (source.isPlayer())
this.scene.validateAchvs(DamageAchv, damage);
source.turnData.damageDealt += damage.value;
this.turnData.attacksReceived.unshift({ move: move.id, result: result as DamageResult, damage: damage.value, critical: isCritical, sourceId: source.id });
if (source.isPlayer() && !this.isPlayer())
@@ -1013,6 +1016,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.summonData.battleStats[stat] = source.summonData.battleStats[stat];
for (let tag of source.summonData.tags)
this.summonData.tags.push(tag);
if (battleStats.filter(bs => bs === 6).length)
this.scene.validateAchv(achvs.TRANSFER_MAX_BATTLE_STAT);
}
getMoveHistory(): TurnMove[] {
+126
View File
@@ -0,0 +1,126 @@
import BattleScene from "../battle-scene";
import * as Utils from "../utils";
export enum AchvTier {
COMMON,
GREAT,
ULTRA,
MASTER
}
export class Achv {
public id: string;
public name: string;
public description: string;
public iconImage: string;
public score: integer;
public secret: boolean;
public hasParent: boolean;
public parentId: string;
private conditionFunc: (scene: BattleScene, args: any[]) => boolean;
constructor(name: string, description: string, iconImage: string, score: integer, conditionFunc?: (scene: BattleScene, args: any[]) => boolean) {
this.name = name;
this.description = description;
this.iconImage = iconImage;
this.score = score;
this.conditionFunc = conditionFunc;
}
setSecret(hasParent?: boolean): this {
this.secret = true;
this.hasParent = !!hasParent;
return this;
}
validate(scene: BattleScene, args: any[]): boolean {
return !this.conditionFunc || this.conditionFunc(scene, args);
}
getTier(): AchvTier {
if (this.score >= 250)
return AchvTier.MASTER;
if (this.score >= 100)
return AchvTier.ULTRA;
if (this.score >= 25)
return AchvTier.GREAT;
return AchvTier.COMMON;
}
}
export class MoneyAchv extends Achv {
private moneyAmount: integer;
constructor(name: string, moneyAmount: integer, iconImage: string, score: integer) {
super(name, `Accumulate a total of ₽${moneyAmount.toLocaleString('en-US')}`, iconImage, score, (scene: BattleScene, _args: any[]) => scene.money >= this.moneyAmount);
this.moneyAmount = moneyAmount;
}
}
export class DamageAchv extends Achv {
private damageAmount: integer;
constructor(name: string, damageAmount: integer, iconImage: string, score: integer) {
super(name, `Inflict ${damageAmount.toLocaleString('en-US')} damage in one hit`, iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] as Utils.NumberHolder).value >= this.damageAmount);
this.damageAmount = damageAmount;
}
}
export class HealAchv extends Achv {
private healAmount: integer;
constructor(name: string, healAmount: integer, iconImage: string, score: integer) {
super(name, `Heal ${healAmount.toLocaleString('en-US')} HP at once with a move, ability, or held item`, iconImage, score, (_scene: BattleScene, args: any[]) => (args[0] as Utils.NumberHolder).value >= this.healAmount);
this.healAmount = healAmount;
}
}
export class LevelAchv extends Achv {
private level: integer;
constructor(name: string, level: integer, iconImage: string, score: integer) {
super(name, `Level up a Pokémon to Lv${level}`, iconImage, score, (scene: BattleScene, args: any[]) => (args[0] as Utils.IntegerHolder).value >= this.level);
this.level = level;
}
}
export const achvs = {
_10K_MONEY: new MoneyAchv('Money Haver', 10000, 'nugget', 10),
_100K_MONEY: new MoneyAchv('Rich', 100000, 'big_nugget', 25).setSecret(true),
_1M_MONEY: new MoneyAchv('Millionaire', 1000000, 'relic_gold', 100).setSecret(true),
_10M_MONEY: new MoneyAchv('One Percenter', 10000000, 'coin_case', 250).setSecret(true),
_250_DMG: new DamageAchv('Hard Hitter', 1000, 'lucky_punch', 10),
_1000_DMG: new DamageAchv('Harder Hitter', 1000, 'lucky_punch_great', 25).setSecret(true),
_2500_DMG: new DamageAchv('That\'s a Lotta Damage!', 2500, 'lucky_punch_ultra', 100).setSecret(true),
_10000_DMG: new DamageAchv('One Punch Man', 10000, 'lucky_punch_master', 250).setSecret(true),
_250_HEAL: new HealAchv('Novice Healer', 250, 'potion', 10),
_1000_HEAL: new HealAchv('Big Healer', 1000, 'super_potion', 25).setSecret(true),
_2500_HEAL: new HealAchv('Cleric', 2500, 'hyper_potion', 100).setSecret(true),
_10000_HEAL: new HealAchv('Recovery Master', 10000, 'max_potion', 250).setSecret(true),
LV_100: new LevelAchv('But Wait, There\'s More!', 50, 'rare_candy', 50).setSecret(),
LV_250: new LevelAchv('Elite', 250, 'rarer_candy', 150).setSecret(true),
LV_1000: new LevelAchv('To Go Even Further Beyond', 250, 'candy_jar', 400).setSecret(true),
TRANSFER_MAX_BATTLE_STAT: new Achv('Teamwork', 'Baton pass to another party member with at least one stat maxed out', 'stick', 25),
CATCH_LEGENDARY: new Achv('Legendary', 'Catch a legendary Pokémon', 'mb', 100).setSecret(),
CATCH_MYTHICAL: new Achv('Mythical', 'Catch a mythical Pokémon', 'strange_ball', 100).setSecret(),
SEE_SHINY: new Achv('Shiny', 'Find a shiny Pokémon in the wild', 'pb_gold', 150).setSecret(),
HIDDEN_ABILITY: new Achv('Hidden Potential', 'Catch a Pokémon with a hidden ability', 'ability_charm', 150).setSecret(),
CLASSIC_VICTORY: new Achv('Undefeated', 'Beat the game in classic mode', 'relic_crown', 250)
};
{
(function() {
const achvKeys = Object.keys(achvs);
achvKeys.forEach((a: string, i: integer) => {
achvs[a].id = a;
if (achvs[a].hasParent)
achvs[a].parentId = achvKeys[i - 1];
});
})();
}
+19 -1
View File
@@ -7,7 +7,6 @@ import { Species } from "../data/species";
import * as Utils from "../utils";
import PokemonData from "./pokemon-data";
import PersistentModifierData from "./modifier-data";
import { PokemonHeldItemModifier } from "../modifier/modifier";
import ArenaData from "./arena-data";
import { Unlockables } from "./unlockables";
import { GameMode } from "../game-mode";
@@ -15,12 +14,14 @@ import { BattleType } from "../battle";
import TrainerData from "./trainer-data";
import { trainerConfigs } from "../data/trainer-type";
import { Setting, setSetting, settingDefaults } from "./settings";
import { achvs } from "./achv";
interface SystemSaveData {
trainerId: integer;
secretId: integer;
dexData: DexData;
unlocks: Unlocks;
achvUnlocks: AchvUnlocks;
timestamp: integer;
}
@@ -45,6 +46,10 @@ interface Unlocks {
[key: integer]: boolean;
}
interface AchvUnlocks {
[key: string]: integer
}
export interface DexData {
[key: integer]: DexData | DexEntry
}
@@ -81,6 +86,8 @@ export class GameData {
public unlocks: Unlocks;
public achvUnlocks: AchvUnlocks;
constructor(scene: BattleScene) {
this.scene = scene;
this.loadSettings();
@@ -91,6 +98,7 @@ export class GameData {
[Unlockables.MINI_BLACK_HOLE]: false,
[Unlockables.SPLICED_ENDLESS_MODE]: false
};
this.achvUnlocks = {};
this.initDexData();
this.loadSystem();
}
@@ -98,12 +106,15 @@ export class GameData {
public saveSystem(): boolean {
if (this.scene.quickStart)
return false;
console.log(this.achvUnlocks, "wah")
const data: SystemSaveData = {
trainerId: this.trainerId,
secretId: this.secretId,
dexData: this.dexData,
unlocks: this.unlocks,
achvUnlocks: this.achvUnlocks,
timestamp: new Date().getTime()
};
@@ -129,6 +140,13 @@ export class GameData {
}
}
if (data.achvUnlocks) {
for (let a of Object.keys(data.achvUnlocks)) {
if (achvs.hasOwnProperty(a))
this.achvUnlocks[a] = data.achvUnlocks[a];
}
}
if (data.timestamp === undefined)
this.convertDexData(data.dexData);
+96
View File
@@ -0,0 +1,96 @@
import BattleScene from "../battle-scene";
import { Achv } from "../system/achv";
import { TextStyle, addTextObject } from "./text";
export default class AchvBar extends Phaser.GameObjects.Container {
private bg: Phaser.GameObjects.NineSlice;
private icon: Phaser.GameObjects.Sprite;
private titleText: Phaser.GameObjects.Text;
private scoreText: Phaser.GameObjects.Text;
private descriptionText: Phaser.GameObjects.Text;
private queue: Achv[] = [];
public shown: boolean;
constructor(scene: BattleScene) {
super(scene, scene.game.canvas.width / 6, 0);
}
setup(): void {
this.bg = this.scene.add.nineslice(0, 0, 'achv_bar', null, 160, 40, 41, 6, 16, 4);
this.bg.setOrigin(0, 0);
this.add(this.bg);
this.icon = this.scene.add.sprite(4, 4, 'items');
this.icon.setOrigin(0, 0);
this.add(this.icon);
this.titleText = addTextObject(this.scene, 40, 3, '', TextStyle.MESSAGE, { fontSize: '72px' });
this.titleText.setOrigin(0, 0);
this.add(this.titleText);
this.scoreText = addTextObject(this.scene, 150, 3, '', TextStyle.MESSAGE, { fontSize: '72px' });
this.scoreText.setOrigin(1, 0);
this.add(this.scoreText);
this.descriptionText = addTextObject(this.scene, 43, 16, '', TextStyle.WINDOW, { fontSize: '72px' });
this.descriptionText.setOrigin(0, 0);
this.add(this.descriptionText);
this.descriptionText.setWordWrapWidth(664);
this.descriptionText.setLineSpacing(-5);
this.setScale(0.5);
this.shown = false;
}
showAchv(achv: Achv): void {
if (this.shown) {
this.queue.push(achv);
return;
}
const tier = achv.getTier();
this.bg.setTexture(`achv_bar${tier ? `_${tier + 1}` : ''}`);
this.icon.setFrame(achv.iconImage);
this.titleText.setText(achv.name);
this.descriptionText.setText(achv.description);
this.scoreText.setText(`+${achv.score}pt`);
(this.scene as BattleScene).playSound('achv');
this.scene.tweens.add({
targets: this,
x: (this.scene.game.canvas.width / 6) - 76,
duration: 500,
ease: 'Sine.easeOut'
});
this.scene.time.delayedCall(10000, () => this.hide());
this.setVisible(true);
this.shown = true;
}
protected hide(): void {
if (!this.shown)
return;
this.scene.tweens.add({
targets: this,
x: (this.scene.game.canvas.width / 6),
duration: 500,
ease: 'Sine.easeIn',
onComplete: () => {
this.shown = false;
this.setVisible(false);
if (this.queue.length)
this.showAchv(this.queue.shift());
}
});
}
}
+210
View File
@@ -0,0 +1,210 @@
import BattleScene, { Button } from "../battle-scene";
import { Achv, achvs } from "../system/achv";
import MessageUiHandler from "./message-ui-handler";
import { TextStyle, addTextObject } from "./text";
import { Mode } from "./ui";
export default class AchvsUiHandler extends MessageUiHandler {
private achvsContainer: Phaser.GameObjects.Container;
private achvIconsContainer: Phaser.GameObjects.Container;
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 cursorObj: Phaser.GameObjects.NineSlice;
constructor(scene: BattleScene, mode?: Mode) {
super(scene, mode);
}
setup() {
const ui = this.getUi();
this.achvsContainer = 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);
const headerBg = this.scene.add.nineslice(0, 0, 'window', null, (this.scene.game.canvas.width / 6) - 2, 24, 6, 6, 6, 6);
headerBg.setOrigin(0, 0);
const headerText = addTextObject(this.scene, 0, 0, 'Achievements', TextStyle.SETTINGS_LABEL);
headerText.setOrigin(0, 0);
headerText.setPositionRelative(headerBg, 8, 4);
this.achvIconsBg = this.scene.add.nineslice(0, headerBg.height, 'window', null, (this.scene.game.canvas.width / 6) - 2, (this.scene.game.canvas.height / 6) - headerBg.height - 68, 6, 6, 6, 6);
this.achvIconsBg.setOrigin(0, 0);
this.achvIconsContainer = this.scene.add.container(6, headerBg.height + 6);
this.achvIcons = [];
for (let a = 0; a < Object.keys(achvs).length; a++) {
const x = (a % 17) * 18;
const y = Math.floor(a / 17) * 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);
}
const titleBg = this.scene.add.nineslice(0, headerBg.height + this.achvIconsBg.height, 'window', null, 174, 24, 6, 6, 6, 6);
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 scoreBg = this.scene.add.nineslice(titleBg.x + titleBg.width, titleBg.y, 'window', null, 46, 24, 6, 6, 6, 6);
scoreBg.setOrigin(0, 0);
this.scoreText = addTextObject(this.scene, 0, 0, '', TextStyle.WINDOW);
this.scoreText.setOrigin(0, 0);
this.scoreText.setPositionRelative(scoreBg, 8, 4);
const unlockBg = this.scene.add.nineslice(scoreBg.x + scoreBg.width, scoreBg.y, 'window', null, 98, 24, 6, 6, 6, 6);
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 = this.scene.add.nineslice(0, titleBg.y + titleBg.height, 'window', null, (this.scene.game.canvas.width / 6) - 2, 42, 6, 6, 6, 6);
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.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);
ui.add(this.achvsContainer);
this.setCursor(0);
this.achvsContainer.setVisible(false);
}
show(args: any[]) {
super.show(args);
const achvUnlocks = this.scene.gameData.achvUnlocks;
Object.values(achvs).forEach((achv: Achv, i: integer) => {
const icon = this.achvIcons[i];
const unlocked = achvUnlocks.hasOwnProperty(achv.id);
const hidden = achv.secret && (!achv.parentId || !achvUnlocks.hasOwnProperty(achv.parentId));
const tinted = !hidden && !unlocked;
icon.setFrame(!hidden ? achv.iconImage : 'unknown');
if (tinted)
icon.setTintFill(0);
else
icon.clearTint();
});
this.achvsContainer.setVisible(true);
this.setCursor(0);
this.getUi().moveTo(this.achvsContainer, this.getUi().length - 1);
this.getUi().hideTooltip();
}
protected showAchv(achv: Achv) {
const achvUnlocks = this.scene.gameData.achvUnlocks;
const unlocked = achvUnlocks.hasOwnProperty(achv.id);
const hidden = achv.secret && (!achv.parentId || !achvUnlocks.hasOwnProperty(achv.parentId));
this.titleText.setText(unlocked ? achv.name : '???');
this.showText(!hidden ? achv.description : '');
this.scoreText.setText(`${achv.score}pt`);
this.unlockText.setText(unlocked ? new Date(achvUnlocks[achv.id]).toLocaleDateString() : 'Locked');
}
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
if (button === Button.CANCEL) {
success = true;
this.scene.ui.revertMode();
} else {
switch (button) {
case Button.UP:
if (this.cursor >= 17)
success = this.setCursor(this.cursor - 17);
break;
case Button.DOWN:
if (this.cursor + 17 < Object.keys(achvs).length)
success = this.setCursor(this.cursor + 17);
break;
case Button.LEFT:
if (this.cursor % 17)
success = this.setCursor(this.cursor - 1);
break;
case Button.RIGHT:
if (this.cursor % 17 < 16 && this.cursor < Object.keys(achvs).length - 1)
success = this.setCursor(this.cursor + 1);
break;
}
}
if (success)
ui.playSelect();
return success;
}
setCursor(cursor: integer): boolean {
let ret = super.setCursor(cursor);
let updateAchv = ret;
if (!this.cursorObj) {
this.cursorObj = this.scene.add.nineslice(0, 0, 'starter_select_cursor_highlight', null, 16, 16, 1, 1, 1, 1);
this.cursorObj.setOrigin(0, 0);
this.achvIconsContainer.add(this.cursorObj);
updateAchv = true;
}
this.cursorObj.setPositionRelative(this.achvIcons[this.cursor], 0, 0);
if (updateAchv)
this.showAchv(achvs[Object.keys(achvs)[cursor]]);
return ret;
}
clear() {
super.clear();
this.achvsContainer.setVisible(false);
this.eraseCursor();
}
eraseCursor() {
if (this.cursorObj)
this.cursorObj.destroy();
this.cursorObj = null;
}
}
+3 -1
View File
@@ -55,7 +55,7 @@ export default class BallUiHandler extends UiHandler {
this.setCursor(this.cursor);
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
@@ -91,6 +91,8 @@ export default class BallUiHandler extends UiHandler {
if (success)
ui.playSelect();
return success;
}
updateCounts() {
+2 -1
View File
@@ -102,7 +102,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
this.message.setWordWrapWidth(1780);
}
processInput(button: Button): void {
processInput(button: Button): boolean {
const ui = this.getUi();
if (this.awaitingActionInput) {
if (button === Button.CANCEL || button === Button.ACTION) {
@@ -111,6 +111,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
const originalOnActionInput = this.onActionInput;
this.onActionInput = null;
originalOnActionInput();
return true;
}
}
}
+3 -1
View File
@@ -52,7 +52,7 @@ export default class BiomeSelectUiHandler extends UiHandler {
}
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
@@ -78,6 +78,8 @@ export default class BiomeSelectUiHandler extends UiHandler {
if (success)
ui.playSelect();
return success;
}
setCursor(cursor: integer): boolean {
+3 -1
View File
@@ -51,7 +51,7 @@ export default class CommandUiHandler extends UiHandler {
this.setCursor(this.getCursor());
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
@@ -104,6 +104,8 @@ export default class CommandUiHandler extends UiHandler {
if (success)
ui.playSelect();
return success;
}
getCursor(): integer {
+2 -2
View File
@@ -20,8 +20,8 @@ export default class EvolutionSceneHandler extends UiHandler {
this.scene.fieldUI.bringToTop(this.evolutionContainer);
}
processInput(button: Button) {
this.scene.ui.getMessageHandler().processInput(button);
processInput(button: Button): boolean {
return this.scene.ui.getMessageHandler().processInput(button);
}
setCursor(_cursor: integer): boolean {
+3 -1
View File
@@ -47,7 +47,7 @@ export default class FightUiHandler extends UiHandler {
this.displayMoves();
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
@@ -87,6 +87,8 @@ export default class FightUiHandler extends UiHandler {
if (success)
ui.playSelect();
return success;
}
getCursor(): integer {
+3 -1
View File
@@ -42,7 +42,7 @@ export default class GameModeSelectUiHandler extends OptionSelectUiHandler {
}
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
const options = this.getOptions();
@@ -59,5 +59,7 @@ export default class GameModeSelectUiHandler extends OptionSelectUiHandler {
ui.playSelect();
} else
return super.processInput(button);
return true;
}
}
+124
View File
@@ -0,0 +1,124 @@
import BattleScene, { Button } from "../battle-scene";
import { TextStyle, addTextObject } from "./text";
import { Mode } from "./ui";
import UiHandler from "./uiHandler";
import * as Utils from "../utils";
export enum MenuOptions {
SETTINGS,
ACHIEVEMENTS
}
export default class MenuUiHandler extends UiHandler {
private menuContainer: Phaser.GameObjects.Container;
private menuBg: Phaser.GameObjects.NineSlice;
protected optionSelectText: Phaser.GameObjects.Text;
private cursorObj: Phaser.GameObjects.Image;
constructor(scene: BattleScene, mode?: Mode) {
super(scene, mode);
}
setup() {
const ui = this.getUi();
this.menuContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1);
this.menuContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains);
this.menuBg = this.scene.add.nineslice((this.scene.game.canvas.width / 6) - 92, 0, 'window', null, 90, (this.scene.game.canvas.height / 6) - 2, 6, 6, 6, 6);
this.menuBg.setOrigin(0, 0);
this.menuContainer.add(this.menuBg);
this.optionSelectText = addTextObject(this.scene, 0, 0, Utils.getEnumKeys(MenuOptions).map(o => Utils.toReadableString(o)).join('\n'), TextStyle.WINDOW, { maxLines: Utils.getEnumKeys(MenuOptions).length });
this.optionSelectText.setPositionRelative(this.menuBg, 14, 6);
this.optionSelectText.setLineSpacing(12);
this.menuContainer.add(this.optionSelectText);
ui.add(this.menuContainer);
this.setCursor(0);
this.menuContainer.setVisible(false);
}
show(args: any[]) {
super.show(args);
this.menuContainer.setVisible(true);
this.setCursor(0);
this.getUi().moveTo(this.menuContainer, this.getUi().length - 1);
this.getUi().hideTooltip();
this.scene.playSound('menu_open');
}
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
if (button === Button.ACTION) {
switch (this.cursor as MenuOptions) {
case MenuOptions.SETTINGS:
this.scene.ui.setOverlayMode(Mode.SETTINGS);
success = true;
break;
case MenuOptions.ACHIEVEMENTS:
this.scene.ui.setOverlayMode(Mode.ACHIEVEMENTS);
success = true;
break;
}
} else if (button === Button.CANCEL) {
success = true;
this.scene.ui.revertMode();
} else {
switch (button) {
case Button.UP:
if (this.cursor)
success = this.setCursor(this.cursor - 1);
break;
case Button.DOWN:
if (this.cursor < Utils.getEnumKeys(MenuOptions).length)
success = this.setCursor(this.cursor + 1);
break;
}
}
if (success)
ui.playSelect();
return true;
}
setCursor(cursor: integer): boolean {
const ret = super.setCursor(cursor);
if (!this.cursorObj) {
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
this.cursorObj.setOrigin(0, 0);
this.menuContainer.add(this.cursorObj);
}
this.cursorObj.setPositionRelative(this.menuBg, 7, 9 + this.cursor * 16);
return ret;
}
clear() {
super.clear();
this.menuContainer.setVisible(false);
this.eraseCursor();
}
eraseCursor() {
if (this.cursorObj)
this.cursorObj.destroy();
this.cursorObj = null;
}
}
+4 -2
View File
@@ -137,11 +137,11 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
});
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
if (!this.awaitingActionInput)
return;
return false;
let success = false;
@@ -193,6 +193,8 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
if (success)
ui.playSelect();
return success;
}
setCursor(cursor: integer): boolean {
+3 -1
View File
@@ -65,7 +65,7 @@ export default abstract class OptionSelectUiHandler extends UiHandler {
}
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
@@ -94,6 +94,8 @@ export default abstract class OptionSelectUiHandler extends UiHandler {
if (success)
ui.playSelect();
return success;
}
setCursor(cursor: integer): boolean {
+23 -16
View File
@@ -177,23 +177,22 @@ export default class PartyUiHandler extends MessageUiHandler {
this.setCursor(this.cursor < 6 ? this.cursor : 0);
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
if (this.pendingPrompt)
return;
return false;
if (this.awaitingActionInput) {
if (button === Button.ACTION || button === Button.CANCEL) {
if (this.onActionInput) {
ui.playSelect();
const originalOnActionInput = this.onActionInput;
this.onActionInput = null;
originalOnActionInput();
this.awaitingActionInput = false;
}
if ((button === Button.ACTION || button === Button.CANCEL) && this.onActionInput) {
ui.playSelect();
const originalOnActionInput = this.onActionInput;
this.onActionInput = null;
originalOnActionInput();
this.awaitingActionInput = false;
return true;
}
return;
return false;
}
let success = false;
@@ -206,6 +205,7 @@ export default class PartyUiHandler extends MessageUiHandler {
this.startTransfer();
this.clearOptions();
ui.playSelect();
return true;
} else if (this.partyUiMode === PartyUiMode.REMEMBER_MOVE_MODIFIER && option !== PartyOption.CANCEL) {
let filterResult = (this.selectFilter as PokemonSelectFilter)(pokemon);
if (filterResult === null) {
@@ -216,6 +216,7 @@ export default class PartyUiHandler extends MessageUiHandler {
this.showText(filterResult as string, null, () => this.showText(null, 0), null, true);
}
ui.playSelect();
return true;
} else if ((option !== PartyOption.SUMMARY && option !== PartyOption.RELEASE && option !== PartyOption.CANCEL)
|| (option === PartyOption.RELEASE && this.partyUiMode === PartyUiMode.RELEASE)) {
let filterResult: string;
@@ -254,7 +255,7 @@ export default class PartyUiHandler extends MessageUiHandler {
(this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.POKEMON, this.cursor, option === PartyOption.PASS_BATON);
if (this.partyUiMode !== PartyUiMode.MODIFIER && this.partyUiMode !== PartyUiMode.TM_MODIFIER && this.partyUiMode !== PartyUiMode.MOVE_MODIFIER)
ui.playSelect();
return;
return true;
} else {
this.clearOptions();
this.showText(filterResult as string, null, () => this.showText(null, 0), null, true);
@@ -262,6 +263,7 @@ export default class PartyUiHandler extends MessageUiHandler {
} else if (option === PartyOption.SUMMARY) {
ui.playSelect();
ui.setModeWithoutClear(Mode.SUMMARY, pokemon).then(() => this.clearOptions());
return true;
} else if (option === PartyOption.RELEASE) {
this.clearOptions();
ui.playSelect();
@@ -277,11 +279,13 @@ export default class PartyUiHandler extends MessageUiHandler {
});
} else
this.showText('You can\'t release a Pokémon that\'s in battle!', null, () => this.showText(null, 0), null, true);
return true;
} else if (option === PartyOption.CANCEL)
this.processInput(Button.CANCEL);
return this.processInput(Button.CANCEL);
} else if (button === Button.CANCEL) {
this.clearOptions();
ui.playSelect();
return true;
} else {
switch (button) {
case Button.UP:
@@ -300,8 +304,8 @@ export default class PartyUiHandler extends MessageUiHandler {
} else if (this.partyUiMode === PartyUiMode.FAINT_SWITCH)
ui.playError();
else
this.processInput(Button.CANCEL);
return;
return this.processInput(Button.CANCEL);
return true;
} else if (button === Button.CANCEL) {
if ((this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER || this.partyUiMode === PartyUiMode.SPLICE) && this.transferMode) {
this.clearTransfer();
@@ -317,7 +321,8 @@ export default class PartyUiHandler extends MessageUiHandler {
ui.playSelect();
}
}
return;
return true;
}
const slotCount = this.partySlots.length;
@@ -343,6 +348,8 @@ export default class PartyUiHandler extends MessageUiHandler {
if (success)
ui.playSelect();
return success;
}
populatePartySlots() {
+4 -4
View File
@@ -91,9 +91,7 @@ export default class SettingsUiHandler extends UiHandler {
const settings: object = localStorage.hasOwnProperty('settings') ? JSON.parse(localStorage.getItem('settings')) : {};
Object.keys(settingDefaults).forEach((setting, s) => {
this.setOptionCursor(s, settings.hasOwnProperty(setting) ? settings[setting] : settingDefaults[setting]);
});
Object.keys(settingDefaults).forEach((setting, s) => this.setOptionCursor(s, settings.hasOwnProperty(setting) ? settings[setting] : settingDefaults[setting]));
this.settingsContainer.setVisible(true);
this.setCursor(0);
@@ -103,7 +101,7 @@ export default class SettingsUiHandler extends UiHandler {
this.getUi().hideTooltip();
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
@@ -134,6 +132,8 @@ export default class SettingsUiHandler extends UiHandler {
if (success)
ui.playSelect();
return success;
}
setCursor(cursor: integer): boolean {
+9 -4
View File
@@ -301,10 +301,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.starterSelectMessageBoxContainer.setVisible(true);
}
processInput(button: Button): void {
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
let error = false;
if (this.genMode) {
switch (button) {
@@ -323,7 +324,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
} else {
if (button === Button.ACTION) {
if (!this.speciesStarterDexEntry)
ui.playError();
error = true;
else if (this.starterCursors.length < 3) {
let isDupe = false;
for (let s = 0; s < this.starterCursors.length; s++) {
@@ -380,7 +381,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
success = true;
this.updateInstructions();
} else
ui.playError();
error = true;
}
} else if (button === Button.CANCEL) {
if (this.starterCursors.length) {
@@ -388,7 +389,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
success = true;
this.updateInstructions();
} else
ui.playError();
error = true;
} else {
const genStarters = this.starterSelectGenIconContainers[this.genCursor].getAll().length;
const rows = Math.ceil(genStarters / 9);
@@ -446,6 +447,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
if (success)
ui.playSelect();
else if (error)
ui.playError();
return success || error;
}
updateInstructions(): void {
+9 -4
View File
@@ -241,13 +241,14 @@ export default class SummaryUiHandler extends UiHandler {
this.hideStatus(!fromSummary);
}
processInput(button: Button) {
processInput(button: Button): boolean {
if (this.transitioning)
return;
return false;
const ui = this.getUi();
let success = false;
let error = false;
if (this.moveSelect) {
if (button === Button.ACTION) {
@@ -283,9 +284,9 @@ export default class SummaryUiHandler extends UiHandler {
}
success = true;
} else if (this.moveCursor === 4)
this.processInput(Button.CANCEL);
return this.processInput(Button.CANCEL);
else
ui.playError();
error = true;
} else if (button === Button.CANCEL) {
this.hideMoveSelect();
success = true;
@@ -336,6 +337,10 @@ export default class SummaryUiHandler extends UiHandler {
if (success)
ui.playSelect();
else if (error)
ui.playError();
return success || error;
}
setCursor(cursor: integer): boolean {
+3 -1
View File
@@ -41,7 +41,7 @@ export default class TargetSelectUiHandler extends UiHandler {
this.setCursor(this.targets.indexOf(this.cursor) > -1 ? this.cursor : this.targets[0]);
}
processInput(button: Button) {
processInput(button: Button): boolean {
const ui = this.getUi();
let success = false;
@@ -72,6 +72,8 @@ export default class TargetSelectUiHandler extends UiHandler {
if (success)
ui.playSelect();
return success;
}
setCursor(cursor: integer): boolean {
+1 -1
View File
@@ -107,7 +107,7 @@ export function getModifierTierTextTint(tier: integer): integer {
case 1: // ModifierTier.GREAT:
return 0x3890f8;
case 2: // ModifierTier.ULTRA:
return 0xf8d038
return 0xf8d038;
case 3: // ModifierTier.MASTER:
return 0xe020c0;
case 4: // ModifierTier.LUXURY:
+38 -16
View File
@@ -15,8 +15,10 @@ import BiomeSelectUiHandler from './biome-select-ui-handler';
import TargetSelectUiHandler from './target-select-ui-handler';
import GameModeSelectUiHandler from './game-mode-select-ui-handler';
import SettingsUiHandler from './settings-ui-handler';
import { TextStyle, addTextObject, getTextColor } from './text';
import { getPokeballTintColor } from '../data/pokeball';
import { TextStyle, addTextObject } from './text';
import AchvBar from './achv-bar';
import MenuUiHandler from './menu-ui-handler';
import AchvsUiHandler from './achvs-ui-handler';
export enum Mode {
MESSAGE,
@@ -32,7 +34,9 @@ export enum Mode {
EVOLUTION_SCENE,
CONFIRM,
GAME_MODE_SELECT,
SETTINGS
MENU,
SETTINGS,
ACHIEVEMENTS
};
const transitionModes = [
@@ -45,14 +49,21 @@ const transitionModes = [
const noTransitionModes = [
Mode.CONFIRM,
Mode.GAME_MODE_SELECT,
Mode.MENU,
Mode.SETTINGS
];
const menuModes = [
Mode.MENU,
Mode.SETTINGS
];
export default class UI extends Phaser.GameObjects.Container {
private mode: Mode;
private lastMode: Mode;
private modeChain: Mode[];
private handlers: UiHandler[];
private overlay: Phaser.GameObjects.Rectangle;
public achvBar: AchvBar;
private tooltipContainer: Phaser.GameObjects.Container;
private tooltipBg: Phaser.GameObjects.NineSlice;
@@ -65,6 +76,7 @@ export default class UI extends Phaser.GameObjects.Container {
super(scene, 0, scene.game.canvas.height / 6);
this.mode = Mode.MESSAGE;
this.modeChain = [];
this.handlers = [
new BattleMessageUiHandler(scene),
new CommandUiHandler(scene),
@@ -79,7 +91,9 @@ export default class UI extends Phaser.GameObjects.Container {
new EvolutionSceneHandler(scene),
new ConfirmUiHandler(scene),
new GameModeSelectUiHandler(scene),
new SettingsUiHandler(scene)
new MenuUiHandler(scene),
new SettingsUiHandler(scene),
new AchvsUiHandler(scene)
];
}
@@ -91,6 +105,10 @@ export default class UI extends Phaser.GameObjects.Container {
(this.scene as BattleScene).uiContainer.add(this.overlay);
this.overlay.setVisible(false);
this.setupTooltip();
this.achvBar = new AchvBar(this.scene as BattleScene);
this.achvBar.setup();
(this.scene as BattleScene).uiContainer.add(this.achvBar);
}
private setupTooltip() {
@@ -121,11 +139,11 @@ export default class UI extends Phaser.GameObjects.Container {
return this.handlers[Mode.MESSAGE] as BattleMessageUiHandler;
}
processInput(button: Button): void {
processInput(button: Button): boolean {
if (this.overlayActive)
return;
return false;
this.getHandler().processInput(button);
return this.getHandler().processInput(button);
}
showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer): void {
@@ -229,7 +247,7 @@ export default class UI extends Phaser.GameObjects.Container {
});
}
private setModeInternal(mode: Mode, clear: boolean, forceTransition: boolean, args: any[]): Promise<void> {
private setModeInternal(mode: Mode, clear: boolean, forceTransition: boolean, chainMode: boolean, args: any[]): Promise<void> {
return new Promise(resolve => {
if (this.mode === mode && !forceTransition) {
resolve();
@@ -239,7 +257,8 @@ export default class UI extends Phaser.GameObjects.Container {
if (this.mode !== mode) {
if (clear)
this.getHandler().clear();
this.lastMode = this.mode && !clear ? this.mode : undefined;
if (chainMode && this.mode && !clear)
this.modeChain.push(this.mode);
this.mode = mode;
this.getHandler().show(args);
}
@@ -263,23 +282,26 @@ export default class UI extends Phaser.GameObjects.Container {
}
setMode(mode: Mode, ...args: any[]): Promise<void> {
return this.setModeInternal(mode, true, false, args);
return this.setModeInternal(mode, true, false, false, args);
}
setModeForceTransition(mode: Mode, ...args: any[]): Promise<void> {
return this.setModeInternal(mode, true, true, args);
return this.setModeInternal(mode, true, true, false, args);
}
setModeWithoutClear(mode: Mode, ...args: any[]): Promise<void> {
return this.setModeInternal(mode, false, false, args);
return this.setModeInternal(mode, false, false, false, args);
}
setOverlayMode(mode: Mode, ...args: any[]): Promise<void> {
return this.setModeInternal(mode, false, false, true, args);
}
revertMode(): void {
if (!this.lastMode)
if (!this.modeChain.length)
return;
this.getHandler().clear();
this.mode = this.lastMode;
this.lastMode = undefined;
this.mode = this.modeChain.pop();
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ export default abstract class UiHandler {
this.active = true;
}
abstract processInput(button: Button): void;
abstract processInput(button: Button): boolean;
getUi() {
return this.scene.ui;
+2 -4
View File
@@ -134,11 +134,9 @@ export class NumberHolder {
}
}
export class IntegerHolder {
public value: integer;
export class IntegerHolder extends NumberHolder {
constructor(value: integer) {
this.value = value;
super(value);
}
}