diff --git a/src/classes/Bastion.ts b/src/classes/Bastion.ts index 94e356b..db5ded7 100644 --- a/src/classes/Bastion.ts +++ b/src/classes/Bastion.ts @@ -28,7 +28,7 @@ export class Engine { public static MouseY: number = 0; public static gemTest() { - for (let i = 0; i < 48; i++) { + for (let i = 0; i < 2; i++) { this.GameScene.MissionStats.giveGem(new Gem(0)); } } diff --git a/src/classes/Events.ts b/src/classes/Events.ts index cafe257..67be16b 100644 --- a/src/classes/Events.ts +++ b/src/classes/Events.ts @@ -24,3 +24,7 @@ export enum TowerEvents { export enum StatsEvents { GemGivenEvent = 'gemGivenEvent', } + +export enum GemEvents { + TowerPanelSelectGem = 'towerTabSelectGem', +} diff --git a/src/classes/game/Gem.ts b/src/classes/game/Gem.ts index 5ac0400..185a7ba 100644 --- a/src/classes/game/Gem.ts +++ b/src/classes/game/Gem.ts @@ -1,12 +1,18 @@ import * as PIXI from 'pixi.js'; import { GemType, GemDefinition } from '../Definitions'; import GameAssets from '../Assets'; + +let latestGemId = 0; + export default class Gem { public texture: PIXI.Texture; public level: number = 1; public definition: GemDefinition; + private id; constructor(gemType: GemType) { this.definition = GameAssets.Gems[gemType]; this.texture = this.definition.textures[0]; + this.id = latestGemId + 1; + latestGemId++; } } diff --git a/src/classes/game/MissionStats.ts b/src/classes/game/MissionStats.ts index d7a3347..c1c74e2 100644 --- a/src/classes/game/MissionStats.ts +++ b/src/classes/game/MissionStats.ts @@ -49,20 +49,33 @@ export default class MissionStats extends GameObject { this.goldText.text = this.gold; } - public giveGem(gem: Gem) { + public giveGem(gem: Gem, noNotify?) { if (this.inventory.length >= 48) return Engine.NotificationManager.Notify( "Can't hold more than 48 Gems. Extra Gem was thrown away.", 'danger' ); this.inventory.push(gem); + if (!noNotify) + Engine.NotificationManager.Notify( + `Lv. ${gem.level} ${gem.definition.name}` + ' added to your inventory.', + 'gemaward' + ); Engine.GameScene.events.emit(StatsEvents.GemGivenEvent, gem); } + public takeGem(gem) { + return this.inventory.splice(this.inventory.indexOf(gem), 1)[0]; + } + public getInventory() { return this.inventory; } + public checkIfPlayerHasAnyGems() { + return this.inventory.length > 0; + } + constructor(initialHP: number, initialGold: number) { super(); this.hp = initialHP; diff --git a/src/classes/game/NotificationManager.ts b/src/classes/game/NotificationManager.ts index df86263..04f2792 100644 --- a/src/classes/game/NotificationManager.ts +++ b/src/classes/game/NotificationManager.ts @@ -21,7 +21,7 @@ class Notification { } else if (type == 'reward') { fill = 0xd65afc; } else if (type == 'gemaward') { - fill = 0xffff00; + fill = 0xffffff; } this.ticksToFadeAway = ticksToFadeAway; this.textObj = new PIXI.Text({ diff --git a/src/classes/game/Tower.ts b/src/classes/game/Tower.ts index a8fc19a..95e9448 100644 --- a/src/classes/game/Tower.ts +++ b/src/classes/game/Tower.ts @@ -16,7 +16,7 @@ export class Tower extends GameObject { public row: number; public column: number; public definition: TowerDefinition; - public slottedGems: Array; + public slottedGems: Array = []; public damageDealt: number = 0; private projectiles: Projectile[] = []; private behaviour: string; @@ -55,6 +55,20 @@ export class Tower extends GameObject { private onParentCellLeave = (e) => { this.graphics.clear(); }; + public SlotGem(gem: Gem, index: number) { + console.log('ATTEMPTING TO SLOT ', gem, index); + this.slottedGems[index] = gem; + Engine.GameScene.towerPanel.Hide(); + Engine.GameScene.towerPanel.Show(this); + } + public UnslotGem(index) { + const gem = this.slottedGems.splice(index, 1)[0]; + Engine.GameScene.MissionStats.giveGem(gem, true); + Engine.NotificationManager.Notify( + `Gem Lv. ${gem.level} ${gem.definition.name} unslotted from ${this.name} and placed back in your inventory.`, + 'info' + ); + } public GetCreepsInRange() { let creeps = Engine.Grid.creeps; diff --git a/src/classes/gui/GemTab.ts b/src/classes/gui/GemTab.ts index fcfe7a1..50cbf82 100644 --- a/src/classes/gui/GemTab.ts +++ b/src/classes/gui/GemTab.ts @@ -5,11 +5,15 @@ import { Engine } from '../Bastion'; import { StatsEvents } from '../Events'; import Gem from '../game/Gem'; import { VisualGemSlot } from './TowerPanel'; +import { Tower } from '../game/Tower'; export default class GemTab extends GuiObject { private bounds: PIXI.Rectangle; private gemTabSprite: PIXI.NineSliceSprite; private vGems: VisualGemSlot[] = []; + public isSelectingGem: boolean = false; + public selectingGemSlotIndex: number = -1; + public selectingGemTowerObject: Tower = null; constructor(bounds: PIXI.Rectangle) { super(false); @@ -33,22 +37,65 @@ export default class GemTab extends GuiObject { this.RebuildInventoryVisual(); }); } + public TowerPanelSelectingGem(gem: Gem, index: number, tower: Tower) { + console.log(this); + if (this.isSelectingGem) { + this.isSelectingGem = false; + this.selectingGemSlotIndex = -1; + } else { + this.isSelectingGem = true; + if (gem == null) { + // Want to select gem to slot in, already checked if player has a Gem. + Engine.NotificationManager.Notify( + 'Click on any Gem in your inventory to slot it into this Gem slot.', + 'info' + ); + this.selectingGemSlotIndex = index; + this.selectingGemTowerObject = tower; + } else { + // Already have a gem selected + tower.UnslotGem(index); + this.RebuildInventoryVisual(); + Engine.GameScene.towerPanel.Hide(); + Engine.GameScene.towerPanel.Show(tower); + this.selectingGemSlotIndex = -1; + this.selectingGemTowerObject = null; + } + } + } public RebuildInventoryVisual() { this.vGems.forEach((vGem) => vGem.destroy()); + this.vGems = []; Engine.GameScene.MissionStats.getInventory().forEach((gem, index) => { let vGem = new VisualGemSlot(0, this.container, gem); - let vGemYValue = 5; - let vGemXValue = (index % 4) * 64 + 20; + let vGemYCoord = 5; + let vGemXCoord = (index % 4) * 64 + 20; let vGemYIdx = index; while (true) { if (vGemYIdx <= 3) break; - vGemYValue += 66; + vGemYCoord += 66; vGemYIdx -= 4; } - - vGem.container.x = vGemXValue; - vGem.container.y = vGemYValue; + vGem.container.x = vGemXCoord; + vGem.container.y = vGemYCoord; + vGem.container.onpointermove = () => { + if (gem == null) return; + Engine.GameScene.tooltip.SetContentGem(gem); + Engine.GameScene.tooltip.Show(Engine.MouseX, Engine.MouseY); + }; + vGem.container.onpointerleave = () => { + Engine.GameScene.tooltip.Hide(); + }; + vGem.onClick = () => { + Engine.GameScene.tooltip.Hide(); + if (this.isSelectingGem) { + this.isSelectingGem = false; + let takenGem = Engine.GameScene.MissionStats.takeGem(gem); + this.selectingGemTowerObject.SlotGem(takenGem, this.selectingGemSlotIndex); + this.RebuildInventoryVisual(); + } + }; this.vGems.push(vGem); }); } diff --git a/src/classes/gui/Sidebar.ts b/src/classes/gui/Sidebar.ts index 060a9b5..8389279 100644 --- a/src/classes/gui/Sidebar.ts +++ b/src/classes/gui/Sidebar.ts @@ -6,9 +6,9 @@ import GemTab from './GemTab'; export default class Sidebar extends GuiObject { public towerTab: TowerTab; + public gemTab: GemTab; private bounds: PIXI.Rectangle; private sidebarSprite: PIXI.NineSliceSprite; - private gemTab: GemTab; constructor(bounds: PIXI.Rectangle) { super(false); diff --git a/src/classes/gui/TowerPanel.ts b/src/classes/gui/TowerPanel.ts index 3921902..167b906 100644 --- a/src/classes/gui/TowerPanel.ts +++ b/src/classes/gui/TowerPanel.ts @@ -6,6 +6,7 @@ import GameUIConstants from '../GameUIConstants'; import Button, { ButtonTexture } from './Button'; import { Tower } from '../game/Tower'; import Gem from '../game/Gem'; +import { GemEvents } from '../Events'; export class VisualGemSlot extends GuiObject { public iconSprite: PIXI.Sprite; @@ -55,6 +56,7 @@ export default class TowerPanel extends GuiObject { private bounds: PIXI.Rectangle; private towerPanel: PIXI.NineSliceSprite; private closeBtn: Button; + private vGems: VisualGemSlot[] = []; public isShown: boolean = false; public titleText: PIXI.Text; @@ -110,10 +112,31 @@ export default class TowerPanel extends GuiObject { this.container.addChild(this.titleText); } private MakeSlots(tower: Tower) { + this.vGems.forEach((vGem) => { + vGem.destroy(); + }); + this.vGems = []; let amount = tower.definition.stats.gemSlotsAmount; - amount = 6; + // amount = 6; for (let i = 0; i < amount; i++) { - const element = new VisualGemSlot(i, this.container, null); + let gem = tower.slottedGems[i]; + console.log(gem); + if (!gem) gem = null; + const vGem = new VisualGemSlot(i, this.container, gem); + this.vGems.push(vGem); + vGem.container.onpointermove = () => { + if (!gem) return; + Engine.GameScene.tooltip.SetContentGem(gem); + Engine.GameScene.tooltip.Show(Engine.MouseX, Engine.MouseY); + }; + vGem.container.onpointerleave = () => { + Engine.GameScene.tooltip.Hide(); + }; + vGem.onClick = () => { + Engine.GameScene.tooltip.Hide(); + console.log('MAKESLOTS ', gem); + Engine.GameScene.events.emit(GemEvents.TowerPanelSelectGem, gem, i, tower); + }; } } public Show(tower: Tower) { @@ -121,7 +144,7 @@ export default class TowerPanel extends GuiObject { this.isShown = true; this.SetContent(tower); this.MakeSlots(tower); - if (mouseX < 900) { + if (tower.container.x < 900) { this.ShowRight(); } else { this.ShowLeft(); diff --git a/src/scenes/Game.ts b/src/scenes/Game.ts index ed00434..89a11ff 100644 --- a/src/scenes/Game.ts +++ b/src/scenes/Game.ts @@ -4,7 +4,7 @@ import { MissionDefinition } from '../classes/Definitions'; import Creep from '../classes/game/Creep'; import { Grid } from '../classes/game/Grid'; import WaveManager from '../classes/game/WaveManager'; -import { WaveManagerEvents, CreepEvents } from '../classes/Events'; +import { WaveManagerEvents, CreepEvents, GemEvents } from '../classes/Events'; import Sidebar from '../classes/gui/Sidebar'; import Button, { ButtonTexture } from '../classes/gui/Button'; import Scene from './Scene'; @@ -34,17 +34,17 @@ export class GameScene extends Scene { public sidebar: Sidebar; public tooltip: Tooltip; public towerPanel: TowerPanel; - public dimGraphics: PIXI.Graphics = new PIXI.Graphics({ - x: 0, - y: 0, - zIndex: 120, - }); - private offerGemsSprite: PIXI.NineSliceSprite; private visualGems: VisualGemSlot[] = []; private currentRound: number = 0; private isWaveManagerFinished: boolean = false; private playerWon: boolean = false; private destroyTicker: boolean = false; + private offerGemsSprite: PIXI.NineSliceSprite; + private dimGraphics: PIXI.Graphics = new PIXI.Graphics({ + x: 0, + y: 0, + zIndex: 120, + }); constructor(name: string) { super(); @@ -85,8 +85,6 @@ export class GameScene extends Scene { Engine.GameMaster.currentScene.stage.addChildAt(this.dimGraphics, 0); this.tooltip = new Tooltip(new PIXI.Rectangle(0, 0, 350, 160)); // Added custom button logic to still keep all the regular events for the button, just have an icon instead of text. - // TODO: maybe make this better? add like a seperate class for icon buttons or smth - // nevermind, i can't be bothered to do this, and this works fine. this.changeRoundButton.CustomButtonLogic = () => { this.changeRoundButton.buttonIcon = new PIXI.Sprite({ texture: GameAssets.PlayIconTexture, @@ -109,6 +107,19 @@ export class GameScene extends Scene { this.events.emit(WaveManagerEvents.NewWave, `${this.currentRound + 1}`); }; this.MissionStats = new MissionStats(100, 200); + this.events.on(GemEvents.TowerPanelSelectGem, (gem, index, tower) => { + if (gem == null) { + if (!this.MissionStats.checkIfPlayerHasAnyGems()) + return Engine.NotificationManager.Notify( + 'You require atleast 1 Gem in your inventory to slot it in a Gem slot.', + 'warn' + ); + console.log(gem); + this.sidebar.gemTab.TowerPanelSelectingGem(gem, index, tower); + } else { + this.sidebar.gemTab.TowerPanelSelectingGem(gem, -1, tower); + } + }); this.ticker = new PIXI.Ticker(); this.ticker.maxFPS = 60; this.ticker.minFPS = 30; @@ -225,7 +236,6 @@ export class GameScene extends Scene { this.visualGems.forEach((item) => item.destroy()); Engine.Grid.gridInteractionEnabled = true; this.MissionStats.giveGem(gem); - Engine.NotificationManager.Notify(gem.definition.name + ' added to your inventory.', 'gemaward'); } private ShowScoreScreen(lost) {