propely implement slotting and unslotting gems

This commit is contained in:
koneko 2025-02-01 22:22:41 +01:00
parent d3988447a6
commit 5ecec28870
10 changed files with 141 additions and 24 deletions

View File

@ -28,7 +28,7 @@ export class Engine {
public static MouseY: number = 0; public static MouseY: number = 0;
public static gemTest() { public static gemTest() {
for (let i = 0; i < 48; i++) { for (let i = 0; i < 2; i++) {
this.GameScene.MissionStats.giveGem(new Gem(0)); this.GameScene.MissionStats.giveGem(new Gem(0));
} }
} }

View File

@ -24,3 +24,7 @@ export enum TowerEvents {
export enum StatsEvents { export enum StatsEvents {
GemGivenEvent = 'gemGivenEvent', GemGivenEvent = 'gemGivenEvent',
} }
export enum GemEvents {
TowerPanelSelectGem = 'towerTabSelectGem',
}

View File

@ -1,12 +1,18 @@
import * as PIXI from 'pixi.js'; import * as PIXI from 'pixi.js';
import { GemType, GemDefinition } from '../Definitions'; import { GemType, GemDefinition } from '../Definitions';
import GameAssets from '../Assets'; import GameAssets from '../Assets';
let latestGemId = 0;
export default class Gem { export default class Gem {
public texture: PIXI.Texture; public texture: PIXI.Texture;
public level: number = 1; public level: number = 1;
public definition: GemDefinition; public definition: GemDefinition;
private id;
constructor(gemType: GemType) { constructor(gemType: GemType) {
this.definition = GameAssets.Gems[gemType]; this.definition = GameAssets.Gems[gemType];
this.texture = this.definition.textures[0]; this.texture = this.definition.textures[0];
this.id = latestGemId + 1;
latestGemId++;
} }
} }

View File

@ -49,20 +49,33 @@ export default class MissionStats extends GameObject {
this.goldText.text = this.gold; this.goldText.text = this.gold;
} }
public giveGem(gem: Gem) { public giveGem(gem: Gem, noNotify?) {
if (this.inventory.length >= 48) if (this.inventory.length >= 48)
return Engine.NotificationManager.Notify( return Engine.NotificationManager.Notify(
"Can't hold more than 48 Gems. Extra Gem was thrown away.", "Can't hold more than 48 Gems. Extra Gem was thrown away.",
'danger' 'danger'
); );
this.inventory.push(gem); 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); Engine.GameScene.events.emit(StatsEvents.GemGivenEvent, gem);
} }
public takeGem(gem) {
return this.inventory.splice(this.inventory.indexOf(gem), 1)[0];
}
public getInventory() { public getInventory() {
return this.inventory; return this.inventory;
} }
public checkIfPlayerHasAnyGems() {
return this.inventory.length > 0;
}
constructor(initialHP: number, initialGold: number) { constructor(initialHP: number, initialGold: number) {
super(); super();
this.hp = initialHP; this.hp = initialHP;

View File

@ -21,7 +21,7 @@ class Notification {
} else if (type == 'reward') { } else if (type == 'reward') {
fill = 0xd65afc; fill = 0xd65afc;
} else if (type == 'gemaward') { } else if (type == 'gemaward') {
fill = 0xffff00; fill = 0xffffff;
} }
this.ticksToFadeAway = ticksToFadeAway; this.ticksToFadeAway = ticksToFadeAway;
this.textObj = new PIXI.Text({ this.textObj = new PIXI.Text({

View File

@ -16,7 +16,7 @@ export class Tower extends GameObject {
public row: number; public row: number;
public column: number; public column: number;
public definition: TowerDefinition; public definition: TowerDefinition;
public slottedGems: Array<Gem>; public slottedGems: Array<Gem> = [];
public damageDealt: number = 0; public damageDealt: number = 0;
private projectiles: Projectile[] = []; private projectiles: Projectile[] = [];
private behaviour: string; private behaviour: string;
@ -55,6 +55,20 @@ export class Tower extends GameObject {
private onParentCellLeave = (e) => { private onParentCellLeave = (e) => {
this.graphics.clear(); 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() { public GetCreepsInRange() {
let creeps = Engine.Grid.creeps; let creeps = Engine.Grid.creeps;

View File

@ -5,11 +5,15 @@ import { Engine } from '../Bastion';
import { StatsEvents } from '../Events'; import { StatsEvents } from '../Events';
import Gem from '../game/Gem'; import Gem from '../game/Gem';
import { VisualGemSlot } from './TowerPanel'; import { VisualGemSlot } from './TowerPanel';
import { Tower } from '../game/Tower';
export default class GemTab extends GuiObject { export default class GemTab extends GuiObject {
private bounds: PIXI.Rectangle; private bounds: PIXI.Rectangle;
private gemTabSprite: PIXI.NineSliceSprite; private gemTabSprite: PIXI.NineSliceSprite;
private vGems: VisualGemSlot[] = []; private vGems: VisualGemSlot[] = [];
public isSelectingGem: boolean = false;
public selectingGemSlotIndex: number = -1;
public selectingGemTowerObject: Tower = null;
constructor(bounds: PIXI.Rectangle) { constructor(bounds: PIXI.Rectangle) {
super(false); super(false);
@ -33,22 +37,65 @@ export default class GemTab extends GuiObject {
this.RebuildInventoryVisual(); 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() { public RebuildInventoryVisual() {
this.vGems.forEach((vGem) => vGem.destroy()); this.vGems.forEach((vGem) => vGem.destroy());
this.vGems = [];
Engine.GameScene.MissionStats.getInventory().forEach((gem, index) => { Engine.GameScene.MissionStats.getInventory().forEach((gem, index) => {
let vGem = new VisualGemSlot(0, this.container, gem); let vGem = new VisualGemSlot(0, this.container, gem);
let vGemYValue = 5; let vGemYCoord = 5;
let vGemXValue = (index % 4) * 64 + 20; let vGemXCoord = (index % 4) * 64 + 20;
let vGemYIdx = index; let vGemYIdx = index;
while (true) { while (true) {
if (vGemYIdx <= 3) break; if (vGemYIdx <= 3) break;
vGemYValue += 66; vGemYCoord += 66;
vGemYIdx -= 4; vGemYIdx -= 4;
} }
vGem.container.x = vGemXCoord;
vGem.container.x = vGemXValue; vGem.container.y = vGemYCoord;
vGem.container.y = vGemYValue; 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); this.vGems.push(vGem);
}); });
} }

View File

@ -6,9 +6,9 @@ import GemTab from './GemTab';
export default class Sidebar extends GuiObject { export default class Sidebar extends GuiObject {
public towerTab: TowerTab; public towerTab: TowerTab;
public gemTab: GemTab;
private bounds: PIXI.Rectangle; private bounds: PIXI.Rectangle;
private sidebarSprite: PIXI.NineSliceSprite; private sidebarSprite: PIXI.NineSliceSprite;
private gemTab: GemTab;
constructor(bounds: PIXI.Rectangle) { constructor(bounds: PIXI.Rectangle) {
super(false); super(false);

View File

@ -6,6 +6,7 @@ import GameUIConstants from '../GameUIConstants';
import Button, { ButtonTexture } from './Button'; import Button, { ButtonTexture } from './Button';
import { Tower } from '../game/Tower'; import { Tower } from '../game/Tower';
import Gem from '../game/Gem'; import Gem from '../game/Gem';
import { GemEvents } from '../Events';
export class VisualGemSlot extends GuiObject { export class VisualGemSlot extends GuiObject {
public iconSprite: PIXI.Sprite; public iconSprite: PIXI.Sprite;
@ -55,6 +56,7 @@ export default class TowerPanel extends GuiObject {
private bounds: PIXI.Rectangle; private bounds: PIXI.Rectangle;
private towerPanel: PIXI.NineSliceSprite; private towerPanel: PIXI.NineSliceSprite;
private closeBtn: Button; private closeBtn: Button;
private vGems: VisualGemSlot[] = [];
public isShown: boolean = false; public isShown: boolean = false;
public titleText: PIXI.Text; public titleText: PIXI.Text;
@ -110,10 +112,31 @@ export default class TowerPanel extends GuiObject {
this.container.addChild(this.titleText); this.container.addChild(this.titleText);
} }
private MakeSlots(tower: Tower) { private MakeSlots(tower: Tower) {
this.vGems.forEach((vGem) => {
vGem.destroy();
});
this.vGems = [];
let amount = tower.definition.stats.gemSlotsAmount; let amount = tower.definition.stats.gemSlotsAmount;
amount = 6; // amount = 6;
for (let i = 0; i < amount; i++) { 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) { public Show(tower: Tower) {
@ -121,7 +144,7 @@ export default class TowerPanel extends GuiObject {
this.isShown = true; this.isShown = true;
this.SetContent(tower); this.SetContent(tower);
this.MakeSlots(tower); this.MakeSlots(tower);
if (mouseX < 900) { if (tower.container.x < 900) {
this.ShowRight(); this.ShowRight();
} else { } else {
this.ShowLeft(); this.ShowLeft();

View File

@ -4,7 +4,7 @@ import { MissionDefinition } from '../classes/Definitions';
import Creep from '../classes/game/Creep'; import Creep from '../classes/game/Creep';
import { Grid } from '../classes/game/Grid'; import { Grid } from '../classes/game/Grid';
import WaveManager from '../classes/game/WaveManager'; 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 Sidebar from '../classes/gui/Sidebar';
import Button, { ButtonTexture } from '../classes/gui/Button'; import Button, { ButtonTexture } from '../classes/gui/Button';
import Scene from './Scene'; import Scene from './Scene';
@ -34,17 +34,17 @@ export class GameScene extends Scene {
public sidebar: Sidebar; public sidebar: Sidebar;
public tooltip: Tooltip; public tooltip: Tooltip;
public towerPanel: TowerPanel; public towerPanel: TowerPanel;
public dimGraphics: PIXI.Graphics = new PIXI.Graphics({
x: 0,
y: 0,
zIndex: 120,
});
private offerGemsSprite: PIXI.NineSliceSprite;
private visualGems: VisualGemSlot[] = []; private visualGems: VisualGemSlot[] = [];
private currentRound: number = 0; private currentRound: number = 0;
private isWaveManagerFinished: boolean = false; private isWaveManagerFinished: boolean = false;
private playerWon: boolean = false; private playerWon: boolean = false;
private destroyTicker: 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) { constructor(name: string) {
super(); super();
@ -85,8 +85,6 @@ export class GameScene extends Scene {
Engine.GameMaster.currentScene.stage.addChildAt(this.dimGraphics, 0); Engine.GameMaster.currentScene.stage.addChildAt(this.dimGraphics, 0);
this.tooltip = new Tooltip(new PIXI.Rectangle(0, 0, 350, 160)); 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. // 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.CustomButtonLogic = () => {
this.changeRoundButton.buttonIcon = new PIXI.Sprite({ this.changeRoundButton.buttonIcon = new PIXI.Sprite({
texture: GameAssets.PlayIconTexture, texture: GameAssets.PlayIconTexture,
@ -109,6 +107,19 @@ export class GameScene extends Scene {
this.events.emit(WaveManagerEvents.NewWave, `${this.currentRound + 1}`); this.events.emit(WaveManagerEvents.NewWave, `${this.currentRound + 1}`);
}; };
this.MissionStats = new MissionStats(100, 200); 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 = new PIXI.Ticker();
this.ticker.maxFPS = 60; this.ticker.maxFPS = 60;
this.ticker.minFPS = 30; this.ticker.minFPS = 30;
@ -225,7 +236,6 @@ export class GameScene extends Scene {
this.visualGems.forEach((item) => item.destroy()); this.visualGems.forEach((item) => item.destroy());
Engine.Grid.gridInteractionEnabled = true; Engine.Grid.gridInteractionEnabled = true;
this.MissionStats.giveGem(gem); this.MissionStats.giveGem(gem);
Engine.NotificationManager.Notify(gem.definition.name + ' added to your inventory.', 'gemaward');
} }
private ShowScoreScreen(lost) { private ShowScoreScreen(lost) {