diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 1177e938b..4d4d5b1cd 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -352,6 +352,7 @@ export default class BattleScene extends Phaser.Scene { update() { this.checkInput(); + this.ui.update(); } launchBattle() { diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 49401613b..4777be5d0 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -5,7 +5,7 @@ import { getLevelTotalExp } from "../data/exp"; import { PokeballType } from "../data/pokeball"; import Pokemon, { PlayerPokemon } from "../pokemon"; import { Stat } from "../data/pokemon-stat"; -import { addTextObject, TextStyle } from "../ui/text"; +import { addTextObject, getModifierTierTextTint, TextStyle } from "../ui/text"; import { Type } from '../data/type'; import { EvolutionPhase } from '../evolution-phase'; import { pokemonEvolutions } from '../data/pokemon-evolutions'; @@ -30,19 +30,6 @@ export class ModifierBar extends Phaser.GameObjects.Container { this.player = !enemy; this.setScale(0.5); - - this.setInteractive(new Phaser.Geom.Rectangle(enemy ? -320 : 0, 0, 320, 48), Phaser.Geom.Rectangle.Contains); - - const thisArg = this; - - this.on('pointerover', function () { - if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) - thisArg.updateModifierOverflowVisibility(true); - }); - this.on('pointerout', function () { - if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) - thisArg.updateModifierOverflowVisibility(false); - }); } updateModifiers(modifiers: PersistentModifier[]) { @@ -57,12 +44,25 @@ export class ModifierBar extends Phaser.GameObjects.Container { return aId < bId ? 1 : aId > bId ? -1 : 0; }); + const thisArg = this; + visibleIconModifiers.forEach((modifier: PersistentModifier, i: integer) => { const icon = modifier.getIcon(this.scene as BattleScene); if (i >= iconOverflowIndex) icon.setVisible(false); this.add(icon); this.setModifierIconPosition(icon, visibleIconModifiers.length); + icon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 32, 32), Phaser.Geom.Rectangle.Contains); + icon.on('pointerover', () => { + (this.scene as BattleScene).ui.showTooltip(modifier.type.name, modifier.type.description); + if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) + thisArg.updateModifierOverflowVisibility(true); + }); + icon.on('pointerout', () => { + (this.scene as BattleScene).ui.hideTooltip(); + if (this.modifierCache && this.modifierCache.length > iconOverflowIndex) + thisArg.updateModifierOverflowVisibility(false); + }); }); this.modifierCache = modifiers; diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index f9a364cb4..45db56e7a 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -1,7 +1,7 @@ import BattleScene, { Button } from "../battle-scene"; import { ModifierTier, ModifierTypeOption } from "../modifier/modifier-type"; import { getPokeballAtlasKey, PokeballType } from "../data/pokeball"; -import { addTextObject, TextStyle } from "./text"; +import { addTextObject, getModifierTierTextTint, TextStyle } from "./text"; import AwaitableUiHandler from "./awaitable-ui-handler"; import { Mode } from "./ui"; import { PokemonHeldItemModifier } from "../modifier/modifier"; @@ -292,7 +292,7 @@ class ModifierOption extends Phaser.GameObjects.Container { this.itemText = addTextObject(this.scene, 0, 35, this.modifierTypeOption.type.name, TextStyle.PARTY, { align: 'center' }); this.itemText.setOrigin(0.5, 0); this.itemText.setAlpha(0); - this.itemText.setTint(this.getTextTint()); + this.itemText.setTint(getModifierTierTextTint(this.modifierTypeOption.type.tier)); this.add(this.itemText); } @@ -396,19 +396,4 @@ class ModifierOption extends Phaser.GameObjects.Container { getPbAtlasKey(beforeUpgrade: boolean) { return getPokeballAtlasKey((this.modifierTypeOption.type.tier - (beforeUpgrade && this.modifierTypeOption.upgraded ? 1 : 0)) as integer as PokeballType); } - - getTextTint(): integer { - switch (this.modifierTypeOption.type.tier) { - case ModifierTier.COMMON: - return 0xffffff - case ModifierTier.GREAT: - return 0x3890f8; - case ModifierTier.ULTRA: - return 0xf8d038 - case ModifierTier.MASTER: - return 0xe020c0; - case ModifierTier.LUXURY: - return 0xe64a18; - } - } } \ No newline at end of file diff --git a/src/ui/settings-ui-handler.ts b/src/ui/settings-ui-handler.ts index 97f723a9a..f135daf51 100644 --- a/src/ui/settings-ui-handler.ts +++ b/src/ui/settings-ui-handler.ts @@ -25,6 +25,8 @@ export default class SettingsUiHandler extends UiHandler { this.settingsContainer = this.scene.add.container(1, -(this.scene.game.canvas.height / 6) + 1); + this.settingsContainer.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); @@ -94,6 +96,8 @@ export default class SettingsUiHandler extends UiHandler { this.setCursor(0); this.getUi().moveTo(this.settingsContainer, this.getUi().length - 1); + + this.getUi().hideTooltip(); } processInput(button: Button) { diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index c8e461bb2..93e870518 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -412,6 +412,8 @@ export default class SummaryUiHandler extends UiHandler { this.tabSprite.setTexture(`summary_tabs_${this.cursor + 1}`); + this.getUi().hideTooltip(); + if (this.summaryPageContainer.visible) { this.transitioning = true; this.populatePageContainer(this.summaryPageTransitionContainer, forward ? cursor : cursor + 1); @@ -520,6 +522,10 @@ export default class SummaryUiHandler extends UiHandler { icon.setPosition((i % 17) * 12 + 3, 14 * Math.floor(i / 17) + 15); statsContainer.add(icon); + + icon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 32, 32), Phaser.Geom.Rectangle.Contains); + icon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(item.type.name, item.type.description, true)); + icon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip()); }); const totalLvExp = getLevelTotalExp(this.pokemon.level, this.pokemon.species.growthRate); diff --git a/src/ui/text.ts b/src/ui/text.ts index c4778e970..549d7cf9c 100644 --- a/src/ui/text.ts +++ b/src/ui/text.ts @@ -9,7 +9,9 @@ export enum TextStyle { SUMMARY_GOLD, MONEY, SETTINGS_LABEL, - SETTINGS_SELECTED + SETTINGS_SELECTED, + TOOLTIP_TITLE, + TOOLTIP_CONTENT }; export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle) { @@ -37,14 +39,19 @@ export function addTextObject(scene: Phaser.Scene, x: number, y: number, content break; case TextStyle.BATTLE_INFO: case TextStyle.MONEY: + case TextStyle.TOOLTIP_TITLE: styleOptions.fontSize = '72px'; - shadowSize = 4; + shadowSize = 4.5; break; case TextStyle.PARTY: case TextStyle.PARTY_RED: styleOptions.fontFamily = 'pkmnems'; styleOptions.fontSize = '66px'; break; + case TextStyle.TOOLTIP_CONTENT: + styleOptions.fontSize = '64px'; + shadowSize = 4; + break; } shadowColor = getTextColor(style, true); @@ -70,6 +77,7 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean) { case TextStyle.MESSAGE: return !shadow ? '#f8f8f8' : '#6b5a73'; case TextStyle.WINDOW: + case TextStyle.TOOLTIP_CONTENT: return !shadow ? '#484848' : '#d0d0c8'; case TextStyle.BATTLE_INFO: return !shadow ? '#404040' : '#ded6b5'; @@ -80,6 +88,7 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean) { case TextStyle.SUMMARY: return !shadow ? '#ffffff' : '#636363'; case TextStyle.SUMMARY_RED: + case TextStyle.TOOLTIP_TITLE: return !shadow ? '#f89890' : '#984038'; case TextStyle.SUMMARY_GOLD: case TextStyle.MONEY: @@ -89,4 +98,20 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean) { case TextStyle.SETTINGS_SELECTED: return !shadow ? '#f88880' : '#f83018'; } +} + +export function getModifierTierTextTint(tier: integer): integer { + console.log(tier); + switch (tier) { + case 0: // ModifierTier.COMMON: + return 0xffffff; + case 1: // ModifierTier.GREAT: + return 0x3890f8; + case 2: // ModifierTier.ULTRA: + return 0xf8d038 + case 3: // ModifierTier.MASTER: + return 0xe020c0; + case 4: // ModifierTier.LUXURY: + return 0xe64a18; + } } \ No newline at end of file diff --git a/src/ui/ui.ts b/src/ui/ui.ts index e95a2c1f7..7de118a19 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -15,6 +15,8 @@ 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'; export enum Mode { MESSAGE, @@ -51,6 +53,11 @@ export default class UI extends Phaser.GameObjects.Container { private lastMode: Mode; private handlers: UiHandler[]; private overlay: Phaser.GameObjects.Rectangle; + + private tooltipContainer: Phaser.GameObjects.Container; + private tooltipBg: Phaser.GameObjects.NineSlice; + private tooltipTitle: Phaser.GameObjects.Text; + private tooltipContent: Phaser.GameObjects.Text; private overlayActive: boolean; @@ -77,13 +84,33 @@ export default class UI extends Phaser.GameObjects.Container { } setup(): void { - for (let handler of this.handlers) { + for (let handler of this.handlers) handler.setup(); - } this.overlay = this.scene.add.rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6, 0); this.overlay.setOrigin(0, 0); (this.scene as BattleScene).uiContainer.add(this.overlay); this.overlay.setVisible(false); + this.setupTooltip(); + } + + private setupTooltip() { + this.tooltipContainer = this.scene.add.container(0, 0); + this.tooltipContainer.setVisible(false); + + this.tooltipBg = this.scene.add.nineslice(0, 0, 'window', null, 128, 31, 6, 6, 6, 6); + this.tooltipBg.setOrigin(0, 0); + + this.tooltipTitle = addTextObject(this.scene, 64, 4, '', TextStyle.TOOLTIP_TITLE); + this.tooltipTitle.setOrigin(0.5, 0); + + this.tooltipContent = addTextObject(this.scene, 6, 16, '', TextStyle.TOOLTIP_CONTENT); + this.tooltipContent.setWordWrapWidth(696) + + this.tooltipContainer.add(this.tooltipBg); + this.tooltipContainer.add(this.tooltipTitle); + this.tooltipContainer.add(this.tooltipContent); + + (this.scene as BattleScene).uiContainer.add(this.tooltipContainer); } getHandler(): UiHandler { @@ -117,6 +144,30 @@ export default class UI extends Phaser.GameObjects.Container { this.getMessageHandler().showDialogue(text, name, delay, callback, callbackDelay, prompt, promptDelay); } + showTooltip(title: string, content: string, overlap?: boolean): void { + this.tooltipContainer.setVisible(true); + this.tooltipTitle.setText(title); + const wrappedContent = this.tooltipContent.runWordWrap(content); + this.tooltipContent.setText(wrappedContent); + this.tooltipBg.height = 31 + 10.5 * (wrappedContent.split('\n').length - 1); + if (overlap) + (this.scene as BattleScene).uiContainer.moveAbove(this.tooltipContainer, this); + else + (this.scene as BattleScene).uiContainer.moveBelow(this.tooltipContainer, this); + } + + hideTooltip(): void { + this.tooltipContainer.setVisible(false); + this.tooltipTitle.clearTint(); + } + + update(): void { + if (this.tooltipContainer.visible) { + const reverse = this.scene.game.input.mousePointer.x >= this.scene.game.canvas.width - this.tooltipBg.width * 6 - 12; + this.tooltipContainer.setPosition(!reverse ? this.scene.game.input.mousePointer.x / 6 + 2 : this.scene.game.input.mousePointer.x / 6 - this.tooltipBg.width - 2, this.scene.game.input.mousePointer.y / 6 + 2); + } + } + clearText(): void { const handler = this.getHandler(); if (handler instanceof MessageUiHandler)