diff --git a/src/ui/components/InventoryOverlay.ts b/src/ui/components/InventoryOverlay.ts index bdc6681..7246b7d 100644 --- a/src/ui/components/InventoryOverlay.ts +++ b/src/ui/components/InventoryOverlay.ts @@ -7,72 +7,224 @@ export class InventoryOverlay extends OverlayComponent { private backpackSlots: Phaser.GameObjects.Container[] = []; protected setupContent() { - const panelH = 500; + // Base overlay is 700x500, so we need to fit within those bounds + const panelW = 680; + const panelH = 480; - const title = this.scene.add.text(0, -panelH / 2 + 25, "INVENTORY", { - fontSize: "28px", + // Main title + const title = this.scene.add.text(0, -panelH / 2 + 25, "EQUIPMENT & INVENTORY", { + fontSize: "26px", color: "#d4af37", - fontStyle: "bold" + fontStyle: "bold", + fontFamily: "serif" }).setOrigin(0.5); this.container.add(title); - this.createEquipmentSection(); - this.createBackpackSection(); + // Draw ornate border around entire panel + this.drawOrnateBorder(panelW, panelH); + + // Create two distinct panels + this.createEquipmentPanel(); + this.createBackpackPanel(); } - private createEquipmentSection() { - const eqX = -180; - const eqY = 10; + private drawOrnateBorder(w: number, h: number) { + const g = this.scene.add.graphics(); - const createSlot = (x: number, y: number, w: number, h: number, label: string, key: string) => { - const g = this.scene.add.graphics(); - g.lineStyle(2, 0x444444, 1); - g.strokeRect(-w / 2, -h / 2, w, h); - g.fillStyle(0x1a1a1a, 1); - g.fillRect(-w / 2 + 1, -h / 2 + 1, w - 2, h - 2); + // Main outer border - golden + g.lineStyle(3, 0xd4af37, 1); + g.strokeRect(-w / 2 + 10, -h / 2 + 50, w - 20, h - 60); + + // Inner accent line + g.lineStyle(2, 0x8b7355, 0.8); + g.strokeRect(-w / 2 + 14, -h / 2 + 54, w - 28, h - 68); - const txt = this.scene.add.text(0, 0, label, { fontSize: "11px", color: "#666666", fontStyle: "bold" }).setOrigin(0.5); - const container = this.scene.add.container(x, y, [g, txt]); + // Corner flourishes + const cornerSize = 20; + const corners = [ + { x: -w / 2 + 10, y: -h / 2 + 50 }, // top-left + { x: w / 2 - 10, y: -h / 2 + 50 }, // top-right + { x: -w / 2 + 10, y: h / 2 - 10 }, // bottom-left + { x: w / 2 - 10, y: h / 2 - 10 }, // bottom-right + ]; + + g.lineStyle(3, 0xd4af37, 1); + corners.forEach((corner, idx) => { + const flipX = idx % 2 === 1 ? -1 : 1; + const flipY = idx >= 2 ? -1 : 1; + // Outer corner lines + g.beginPath(); + g.moveTo(corner.x, corner.y + flipY * cornerSize); + g.lineTo(corner.x, corner.y); + g.lineTo(corner.x + flipX * cornerSize, corner.y); + g.strokePath(); + + // Inner decorative corner accent + g.lineStyle(2, 0xffd700, 0.6); + g.beginPath(); + g.moveTo(corner.x + flipX * 5, corner.y + flipY * 10); + g.lineTo(corner.x + flipX * 5, corner.y + flipY * 5); + g.lineTo(corner.x + flipX * 10, corner.y + flipY * 5); + g.strokePath(); + g.lineStyle(3, 0xd4af37, 1); + }); + + this.container.add(g); + } + + private createEquipmentPanel() { + const panelX = -165; + const panelY = 40; + const panelW = 260; + const panelH = 360; + + // Panel background + const bg = this.scene.add.graphics(); + bg.fillStyle(0x2a1f2a, 0.9); + bg.fillRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH); + + // Panel border + bg.lineStyle(2, 0x8b7355, 1); + bg.strokeRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH); + this.container.add(bg); + + // Draw connecting lines for paper doll + this.drawPaperDollLines(panelX, panelY); + + // Create equipment slots + this.createEquipmentSlots(panelX, panelY); + } + + private drawPaperDollLines(centerX: number, centerY: number) { + const g = this.scene.add.graphics(); + g.lineStyle(2, 0x5a4a3a, 1); + + // Body center point + const bodyX = centerX; + const bodyY = centerY - 10; + + // Connect helmet to body + g.lineBetween(bodyX, bodyY - 60, bodyX, bodyY - 35); + + // Connect body to belt + g.lineBetween(bodyX, bodyY + 35, bodyX, bodyY + 65); + + // Connect body to main hand (left side) + g.lineBetween(bodyX - 35, bodyY - 5, bodyX - 70, bodyY - 5); + + // Connect body to off hand (right side) + g.lineBetween(bodyX + 35, bodyY - 5, bodyX + 70, bodyY - 5); + + // Connect body to rings + g.lineBetween(bodyX - 20, bodyY + 10, bodyX - 35, bodyY + 25); + g.lineBetween(bodyX + 20, bodyY + 10, bodyX + 35, bodyY + 25); + + // Connect belt to boots + g.lineBetween(bodyX, bodyY + 78, bodyX, bodyY + 110); + + this.container.add(g); + } + + private createEquipmentSlots(centerX: number, centerY: number) { + const slotBorder = 0xd4af37; + const slotBg = 0x3a2a2a; + + const createSlot = (x: number, y: number, size: number, key: string) => { + const g = this.scene.add.graphics(); + + // Outer golden border + g.lineStyle(2, slotBorder, 1); + g.strokeRect(-size / 2, -size / 2, size, size); + + // Inner darker border + g.lineStyle(1, 0x8b7355, 1); + g.strokeRect(-size / 2 + 2, -size / 2 + 2, size - 4, size - 4); + + // Background + g.fillStyle(slotBg, 1); + g.fillRect(-size / 2 + 3, -size / 2 + 3, size - 6, size - 6); + + const container = this.scene.add.container(x, y, [g]); this.equipmentSlots.set(key, container); this.container.add(container); }; - createSlot(eqX, eqY - 140, 70, 70, "Head", "helmet"); - createSlot(eqX, eqY - 20, 90, 130, "Body", "bodyArmour"); - createSlot(eqX, eqY + 80, 100, 36, "Belt", "belt"); - createSlot(eqX - 140, eqY - 50, 90, 160, "Main Hand", "mainHand"); - createSlot(eqX + 140, eqY - 50, 90, 160, "Off Hand", "offHand"); - createSlot(eqX - 80, eqY - 30, 54, 54, "Ring", "ringLeft"); - createSlot(eqX + 80, eqY - 30, 54, 54, "Ring", "ringRight"); - createSlot(eqX - 100, eqY + 70, 70, 70, "Hands", "gloves"); - createSlot(eqX + 100, eqY + 70, 70, 70, "Boots", "boots"); + // Helmet (top center) + createSlot(centerX, centerY - 75, 46, "helmet"); + + // Body armor (center) + createSlot(centerX, centerY - 10, 58, "bodyArmour"); + + // Main hand (left) + createSlot(centerX - 92, centerY - 5, 46, "mainHand"); + + // Off hand (right) + createSlot(centerX + 92, centerY - 5, 46, "offHand"); + + // Rings + createSlot(centerX - 46, centerY + 28, 38, "ringLeft"); + createSlot(centerX + 46, centerY + 28, 38, "ringRight"); + + // Belt + createSlot(centerX, centerY + 52, 32, "belt"); + + // Boots (bottom) + createSlot(centerX, centerY + 125, 46, "boots"); } - private createBackpackSection() { - const bpX = 100; - const bpY = -150; - const rows = 8; - const cols = 5; - const bpSlotSize = 40; + private createBackpackPanel() { + const panelX = 175; + const panelY = 40; + const panelW = 240; + const panelH = 360; - const bpTitle = this.scene.add.text(bpX + (cols * 44) / 2 - 20, bpY - 40, "BACKPACK", { - fontSize: "18px", - color: "#d4af37", - fontStyle: "bold" + // Panel background + const bg = this.scene.add.graphics(); + bg.fillStyle(0x2a1f2a, 0.9); + bg.fillRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH); + + // Panel border + bg.lineStyle(2, 0x8b7355, 1); + bg.strokeRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH); + this.container.add(bg); + + // Backpack title + const bpTitle = this.scene.add.text(panelX, panelY - panelH / 2 + 25, "BACKPACK", { + fontSize: "20px", + color: "#d4af37", + fontStyle: "bold", + fontFamily: "serif" }).setOrigin(0.5); this.container.add(bpTitle); + // Create backpack grid (4 columns x 6 rows) + const rows = 6; + const cols = 4; + const slotSize = 44; + const spacing = 6; + const gridW = cols * (slotSize + spacing) - spacing; + const startX = panelX - gridW / 2; + const startY = panelY - panelH / 2 + 55; + for (let r = 0; r < rows; r++) { for (let c = 0; c < cols; c++) { - const x = bpX + c * 44; - const y = bpY + r * 44; + const x = startX + c * (slotSize + spacing) + slotSize / 2; + const y = startY + r * (slotSize + spacing) + slotSize / 2; const g = this.scene.add.graphics(); - g.lineStyle(1, 0x333333, 1); - g.strokeRect(-bpSlotSize / 2, -bpSlotSize / 2, bpSlotSize, bpSlotSize); - g.fillStyle(0x0c0c0c, 1); - g.fillRect(-bpSlotSize / 2 + 0.5, -bpSlotSize / 2 + 0.5, bpSlotSize - 1, bpSlotSize - 1); + + // Golden border + g.lineStyle(2, 0xd4af37, 1); + g.strokeRect(-slotSize / 2, -slotSize / 2, slotSize, slotSize); + + // Inner border + g.lineStyle(1, 0x8b7355, 1); + g.strokeRect(-slotSize / 2 + 2, -slotSize / 2 + 2, slotSize - 4, slotSize - 4); + + // Background + g.fillStyle(0x1a0f1a, 1); + g.fillRect(-slotSize / 2 + 3, -slotSize / 2 + 3, slotSize - 6, slotSize - 6); const container = this.scene.add.container(x, y, [g]); this.container.add(container); @@ -86,31 +238,30 @@ export class InventoryOverlay extends OverlayComponent { // Clear existing items from slots this.backpackSlots.forEach(slot => { - if (slot.list.length > 1) { // 0 is bg - // Remove all children after bg - slot.removeBetween(1, undefined, true); - } + if (slot.list.length > 1) { + slot.removeBetween(1, undefined, true); + } }); // Populate items player.inventory.items.forEach((item, index) => { - if (index >= this.backpackSlots.length) return; + if (index >= this.backpackSlots.length) return; - const slot = this.backpackSlots[index]; - - const texture = item.textureKey; - const frame = item.spriteIndex; - - const sprite = this.scene.add.sprite(0, 0, texture, frame); - sprite.setScale(2); // 16x16 -> 32x32, fits in 40x40 slot - - slot.add(sprite); - - // Add simple tooltip on hover (console log for now) or click - slot.setInteractive(new Phaser.Geom.Rectangle(-20, -20, 40, 40), Phaser.Geom.Rectangle.Contains); - slot.on("pointerdown", () => { - console.log("Clicked item:", item); - }); + const slot = this.backpackSlots[index]; + + const texture = item.textureKey; + const frame = item.spriteIndex; + + const sprite = this.scene.add.sprite(0, 0, texture, frame); + sprite.setScale(2.2); // Scale to fit nicely in 44px slots + + slot.add(sprite); + + // Add interactivity + slot.setInteractive(new Phaser.Geom.Rectangle(-22, -22, 44, 44), Phaser.Geom.Rectangle.Contains); + slot.on("pointerdown", () => { + console.log("Clicked item:", item); + }); }); } }