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 gemTest() {
for (let i = 0; i < 48; i++) {
for (let i = 0; i < 2; i++) {
this.GameScene.MissionStats.giveGem(new Gem(0));
}
}

View File

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

View File

@ -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++;
}
}

View File

@ -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;

View File

@ -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({

View File

@ -16,7 +16,7 @@ export class Tower extends GameObject {
public row: number;
public column: number;
public definition: TowerDefinition;
public slottedGems: Array<Gem>;
public slottedGems: Array<Gem> = [];
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;

View File

@ -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);
});
}

View File

@ -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);

View File

@ -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();

View File

@ -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) {