130 lines
4.2 KiB
TypeScript
130 lines
4.2 KiB
TypeScript
|
|
import { describe, it, expect, beforeEach } from "vitest";
|
|
import { ItemManager } from "../../scenes/systems/ItemManager";
|
|
import type { World, CombatantActor, Item, EntityId } from "../../core/types";
|
|
import { EntityAccessor } from "../../engine/EntityAccessor";
|
|
import { ECSWorld } from "../../engine/ecs/World";
|
|
|
|
describe("ItemManager - Stacking Logic", () => {
|
|
let itemManager: ItemManager;
|
|
let accessor: EntityAccessor;
|
|
let world: World;
|
|
let player: CombatantActor;
|
|
let ecsWorld: ECSWorld;
|
|
|
|
beforeEach(() => {
|
|
world = {
|
|
width: 10,
|
|
height: 10,
|
|
tiles: new Array(100).fill(0),
|
|
exit: { x: 9, y: 9 }
|
|
} as any;
|
|
|
|
ecsWorld = new ECSWorld();
|
|
accessor = new EntityAccessor(world, 0 as EntityId, ecsWorld);
|
|
itemManager = new ItemManager(world, accessor, ecsWorld);
|
|
|
|
player = {
|
|
id: 0 as EntityId,
|
|
pos: { x: 1, y: 1 },
|
|
category: "combatant",
|
|
isPlayer: true,
|
|
type: "player",
|
|
inventory: { gold: 0, items: [] },
|
|
stats: { hp: 10, maxHp: 10 } as any,
|
|
equipment: {} as any,
|
|
speed: 100,
|
|
energy: 0
|
|
};
|
|
|
|
// Sync player to ECS
|
|
ecsWorld.addComponent(player.id, "position", player.pos);
|
|
ecsWorld.addComponent(player.id, "player", {});
|
|
ecsWorld.addComponent(player.id, "stats", player.stats);
|
|
ecsWorld.addComponent(player.id, "actorType", { type: "player" });
|
|
ecsWorld.addComponent(player.id, "inventory", player.inventory!);
|
|
ecsWorld.addComponent(player.id, "energy", { current: 0, speed: 100 });
|
|
});
|
|
|
|
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
|
|
};
|
|
|
|
const playerActor = accessor.getPlayer()!;
|
|
|
|
// First potion
|
|
itemManager.spawnItem(potion, { x: 1, y: 1 });
|
|
itemManager.tryPickup(playerActor);
|
|
|
|
expect(playerActor.inventory!.items.length).toBe(1);
|
|
expect(playerActor.inventory!.items[0].quantity).toBe(1);
|
|
|
|
// Second potion
|
|
itemManager.spawnItem(potion, { x: 1, y: 1 });
|
|
itemManager.tryPickup(playerActor);
|
|
|
|
expect(playerActor.inventory!.items.length).toBe(1);
|
|
expect(playerActor.inventory!.items[0].quantity).toBe(2);
|
|
});
|
|
|
|
it("should NOT stack non-stackable items", () => {
|
|
const sword: Item = {
|
|
id: "iron_sword",
|
|
name: "Iron Sword",
|
|
type: "Weapon",
|
|
weaponType: "melee",
|
|
textureKey: "items",
|
|
spriteIndex: 1,
|
|
stackable: false,
|
|
stats: { attack: 1 }
|
|
} as any;
|
|
|
|
const playerActor = accessor.getPlayer()!;
|
|
|
|
// First sword
|
|
itemManager.spawnItem(sword, { x: 1, y: 1 });
|
|
itemManager.tryPickup(playerActor);
|
|
|
|
expect(playerActor.inventory!.items.length).toBe(1);
|
|
|
|
// Second sword
|
|
itemManager.spawnItem(sword, { x: 1, y: 1 });
|
|
itemManager.tryPickup(playerActor);
|
|
|
|
expect(playerActor.inventory!.items.length).toBe(2);
|
|
});
|
|
|
|
it("should sum quantities of stackable items correctly", () => {
|
|
const ammo: Item = {
|
|
id: "9mm_ammo",
|
|
name: "9mm Ammo",
|
|
type: "Ammo",
|
|
textureKey: "items",
|
|
spriteIndex: 2,
|
|
stackable: true,
|
|
quantity: 10,
|
|
ammoType: "9mm"
|
|
} as any;
|
|
|
|
const playerActor = accessor.getPlayer()!;
|
|
|
|
itemManager.spawnItem(ammo, { x: 1, y: 1 });
|
|
itemManager.tryPickup(playerActor);
|
|
|
|
expect(playerActor.inventory!.items[0].quantity).toBe(10);
|
|
|
|
const moreAmmo = { ...ammo, quantity: 5 };
|
|
itemManager.spawnItem(moreAmmo, { x: 1, y: 1 });
|
|
itemManager.tryPickup(playerActor);
|
|
|
|
expect(playerActor.inventory!.items[0].quantity).toBe(15);
|
|
});
|
|
});
|