Update ranged weapon quickslot text to match stackable items
This commit is contained in:
@@ -9,7 +9,9 @@ export const ITEMS: Record<string, Item> = {
|
|||||||
spriteIndex: 57,
|
spriteIndex: 57,
|
||||||
stats: {
|
stats: {
|
||||||
hp: 5
|
hp: 5
|
||||||
}
|
},
|
||||||
|
stackable: true,
|
||||||
|
quantity: 1
|
||||||
},
|
},
|
||||||
"iron_sword": {
|
"iron_sword": {
|
||||||
id: "iron_sword",
|
id: "iron_sword",
|
||||||
|
|||||||
113
src/engine/__tests__/inventory.test.ts
Normal file
113
src/engine/__tests__/inventory.test.ts
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import { describe, it, expect, beforeEach } from "vitest";
|
||||||
|
import { ItemManager } from "../../scenes/systems/ItemManager";
|
||||||
|
import type { World, CombatantActor, Item } from "../../core/types";
|
||||||
|
import { EntityManager } from "../../engine/EntityManager";
|
||||||
|
|
||||||
|
describe("ItemManager - Stacking Logic", () => {
|
||||||
|
let itemManager: ItemManager;
|
||||||
|
let entityManager: EntityManager;
|
||||||
|
let world: World;
|
||||||
|
let player: CombatantActor;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
world = {
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
tiles: [],
|
||||||
|
actors: new Map(),
|
||||||
|
exit: { x: 9, y: 9 }
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
entityManager = new EntityManager(world);
|
||||||
|
itemManager = new ItemManager(world, entityManager);
|
||||||
|
|
||||||
|
player = {
|
||||||
|
id: 0,
|
||||||
|
pos: { x: 1, y: 1 },
|
||||||
|
category: "combatant",
|
||||||
|
isPlayer: true,
|
||||||
|
type: "player",
|
||||||
|
inventory: { gold: 0, items: [] },
|
||||||
|
stats: {} as any,
|
||||||
|
equipment: {} as any,
|
||||||
|
speed: 1,
|
||||||
|
energy: 0
|
||||||
|
};
|
||||||
|
world.actors.set(0, player);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should stack stackable items when picked up", () => {
|
||||||
|
const potion: Item = {
|
||||||
|
id: "potion",
|
||||||
|
name: "Potion",
|
||||||
|
type: "Consumable",
|
||||||
|
textureKey: "items",
|
||||||
|
spriteIndex: 0,
|
||||||
|
stackable: true,
|
||||||
|
quantity: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// First potion
|
||||||
|
itemManager.spawnItem(potion, { x: 1, y: 1 });
|
||||||
|
itemManager.tryPickup(player);
|
||||||
|
|
||||||
|
expect(player.inventory!.items.length).toBe(1);
|
||||||
|
expect(player.inventory!.items[0].quantity).toBe(1);
|
||||||
|
|
||||||
|
// Second potion
|
||||||
|
itemManager.spawnItem(potion, { x: 1, y: 1 });
|
||||||
|
itemManager.tryPickup(player);
|
||||||
|
|
||||||
|
expect(player.inventory!.items.length).toBe(1);
|
||||||
|
expect(player.inventory!.items[0].quantity).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should NOT stack non-stackable items", () => {
|
||||||
|
const sword: Item = {
|
||||||
|
id: "sword",
|
||||||
|
name: "Sword",
|
||||||
|
type: "Weapon",
|
||||||
|
weaponType: "melee",
|
||||||
|
textureKey: "items",
|
||||||
|
spriteIndex: 1,
|
||||||
|
stackable: false,
|
||||||
|
stats: { attack: 1 }
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
// First sword
|
||||||
|
itemManager.spawnItem(sword, { x: 1, y: 1 });
|
||||||
|
itemManager.tryPickup(player);
|
||||||
|
|
||||||
|
expect(player.inventory!.items.length).toBe(1);
|
||||||
|
|
||||||
|
// Second sword
|
||||||
|
itemManager.spawnItem(sword, { x: 1, y: 1 });
|
||||||
|
itemManager.tryPickup(player);
|
||||||
|
|
||||||
|
expect(player.inventory!.items.length).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should sum quantities of stackable items correctly", () => {
|
||||||
|
const ammo: Item = {
|
||||||
|
id: "ammo",
|
||||||
|
name: "Ammo",
|
||||||
|
type: "Ammo",
|
||||||
|
textureKey: "items",
|
||||||
|
spriteIndex: 2,
|
||||||
|
stackable: true,
|
||||||
|
quantity: 10,
|
||||||
|
ammoType: "9mm"
|
||||||
|
};
|
||||||
|
|
||||||
|
itemManager.spawnItem(ammo, { x: 1, y: 1 });
|
||||||
|
itemManager.tryPickup(player);
|
||||||
|
|
||||||
|
expect(player.inventory!.items[0].quantity).toBe(10);
|
||||||
|
|
||||||
|
const moreAmmo = { ...ammo, quantity: 5 };
|
||||||
|
itemManager.spawnItem(moreAmmo, { x: 1, y: 1 });
|
||||||
|
itemManager.tryPickup(player);
|
||||||
|
|
||||||
|
expect(player.inventory!.items[0].quantity).toBe(15);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -115,28 +115,28 @@ export class QuickSlotComponent {
|
|||||||
sprite.setScale(2.5);
|
sprite.setScale(2.5);
|
||||||
slot.add(sprite);
|
slot.add(sprite);
|
||||||
|
|
||||||
// Add count in bottom-right corner (white with x prefix)
|
// Unified Label (Bottom-Right)
|
||||||
const count = player.inventory.items.filter(it => it.id === desiredId).length;
|
let labelText = "";
|
||||||
if (count > 1) {
|
if (foundItem.stackable) {
|
||||||
const countText = this.scene.add.text(slotSize - 3, slotSize - 3, `x${count}`, {
|
// Sum quantities for stackable items
|
||||||
fontSize: "11px",
|
const totalQuantity = player.inventory.items
|
||||||
color: "#ffffff",
|
.filter(it => it.id === desiredId)
|
||||||
fontStyle: "bold"
|
.reduce((sum, it) => sum + (it.quantity || 1), 0);
|
||||||
}).setOrigin(1, 1);
|
labelText = `x${totalQuantity}`;
|
||||||
slot.add(countText);
|
} else if (foundItem.type === "Weapon" && foundItem.weaponType === "ranged" && foundItem.stats) {
|
||||||
|
// Show ammo for non-stackable ranged weapons
|
||||||
|
labelText = `${foundItem.stats.currentAmmo}/${foundItem.stats.magazineSize}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Ammo Counter for Ranged Weapons (Top-Right)
|
if (labelText) {
|
||||||
if (foundItem.type === "Weapon" && foundItem.weaponType === "ranged" && foundItem.stats) {
|
const display = this.scene.add.text(slotSize - 3, slotSize - 3, labelText, {
|
||||||
const ammoText = `${foundItem.stats.currentAmmo}/${foundItem.stats.magazineSize}`;
|
fontSize: "11px",
|
||||||
const ammoDisplay = this.scene.add.text(slotSize - 2, 2, ammoText, {
|
color: "#ffffff",
|
||||||
fontSize: "10px",
|
|
||||||
color: "#00FF00", // Green text
|
|
||||||
fontStyle: "bold",
|
fontStyle: "bold",
|
||||||
stroke: "#000000",
|
stroke: "#000000",
|
||||||
strokeThickness: 2
|
strokeThickness: 2
|
||||||
}).setOrigin(1, 0); // Top-right anchor
|
}).setOrigin(1, 1);
|
||||||
slot.add(ammoDisplay);
|
slot.add(display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user