import Phaser from "phaser"; import type { CombatantActor, Item } from "../../core/types"; export class QuickSlotComponent { private scene: Phaser.Scene; private container!: Phaser.GameObjects.Container; private slots: Phaser.GameObjects.Container[] = []; private itemMap: (Item | null)[] = [null, null, null, null]; // 4 slots private assignedIds: string[] = ["health_potion", "throwing_dagger", "", ""]; // Default slot 1 to HP pot, 2 to Dagger constructor(scene: Phaser.Scene) { this.scene = scene; } create() { const { width, height } = this.scene.scale; // Position bottom center-ish this.container = this.scene.add.container(width / 2 - 100, height - 50); this.container.setScrollFactor(0).setDepth(1500); for (let i = 0; i < 4; i++) { const x = i * 50; const g = this.scene.add.graphics(); // Slot bg g.fillStyle(0x1a1a1a, 0.8); g.fillRect(0, 0, 40, 40); g.lineStyle(1, 0x555555); g.strokeRect(0, 0, 40, 40); // Hotkey label const key = this.scene.add.text(2, 2, `${i + 1}`, { fontSize: "10px", color: "#aaaaaa" }); const slotContainer = this.scene.add.container(x, 0, [g, key]); this.slots.push(slotContainer); this.container.add(slotContainer); // Input const hitArea = new Phaser.Geom.Rectangle(0, 0, 40, 40); slotContainer.setInteractive(hitArea, Phaser.Geom.Rectangle.Contains); slotContainer.on("pointerdown", () => { this.activateSlot(i); }); } // Keyboard inputs this.scene.input.keyboard?.on("keydown-ONE", () => this.activateSlot(0)); this.scene.input.keyboard?.on("keydown-TWO", () => this.activateSlot(1)); this.scene.input.keyboard?.on("keydown-THREE", () => this.activateSlot(2)); this.scene.input.keyboard?.on("keydown-FOUR", () => this.activateSlot(3)); } update(player: CombatantActor, activeItemId?: string | null) { if (!player.inventory) return; // Update slots based on inventory availability for (let i = 0; i < 4; i++) { const desiredId = this.assignedIds[i]; const slot = this.slots[i]; const bgGraphics = slot.list[0] as Phaser.GameObjects.Graphics; // Clear previous item icon if any (children > 2, since 0=bg, 1=text) if (slot.list.length > 2) { slot.removeBetween(2, undefined, true); } if (desiredId) { const foundItem = player.inventory.items.find(it => it.id === desiredId); this.itemMap[i] = foundItem || null; const isActive = foundItem && foundItem.id === activeItemId; // Redraw background based on active state bgGraphics.clear(); bgGraphics.fillStyle(0x1a1a1a, 0.8); bgGraphics.fillRect(0, 0, 40, 40); if (isActive) { bgGraphics.lineStyle(2, 0xffff00); // Gold highlight } else { bgGraphics.lineStyle(1, 0x555555); // Default gray } bgGraphics.strokeRect(0, 0, 40, 40); if (foundItem) { const texture = foundItem.textureKey ?? "items"; const sprite = this.scene.add.sprite(20, 20, texture, foundItem.spriteIndex); // PD items are 16x16, slot is 40x40. Scale it up? sprite.setScale(2); slot.add(sprite); // Add count if stackable (future) const count = player.inventory.items.filter(it => it.id === desiredId).length; const countText = this.scene.add.text(38, 38, `${count}`, { fontSize: "10px", color: "#ffffff" }).setOrigin(1, 1); slot.add(countText); } } else { this.itemMap[i] = null; // Reset bg bgGraphics.clear(); bgGraphics.fillStyle(0x1a1a1a, 0.8); bgGraphics.fillRect(0, 0, 40, 40); bgGraphics.lineStyle(1, 0x555555); bgGraphics.strokeRect(0, 0, 40, 40); } } } private activateSlot(index: number) { const item = this.itemMap[index]; if (item) { console.log(`Activating slot ${index + 1}: ${item.name}`); // Emit event to GameScene to handle item usage const gameScene = this.scene.scene.get("GameScene"); gameScene.events.emit("use-item", { itemId: item.id }); } else { console.log(`Slot ${index + 1} is empty`); } } }