87 lines
2.6 KiB
TypeScript
87 lines
2.6 KiB
TypeScript
export type Condition = 'new' | 'complete' | 'no_manual' | 'loose';
|
|
|
|
export interface ItemRef {
|
|
gameId: string;
|
|
condition: Condition;
|
|
}
|
|
|
|
export interface ShelfSlot {
|
|
id: string;
|
|
item: ItemRef | null;
|
|
qty: number;
|
|
}
|
|
|
|
export interface Inventory {
|
|
backroom: Record<string, number>;
|
|
slots: ShelfSlot[];
|
|
}
|
|
|
|
export const SLOT_CAPACITY = 5;
|
|
|
|
export function itemKey(item: ItemRef): string {
|
|
return `${item.gameId}|${item.condition}`;
|
|
}
|
|
|
|
export function parseItemKey(key: string): ItemRef {
|
|
const [gameId, condition] = key.split('|');
|
|
return { gameId, condition: condition as Condition };
|
|
}
|
|
|
|
export function createInventory(slotCount: number): Inventory {
|
|
const slots: ShelfSlot[] = [];
|
|
for (let i = 0; i < slotCount; i++) slots.push({ id: `slot-${i}`, item: null, qty: 0 });
|
|
return { backroom: {}, slots };
|
|
}
|
|
|
|
export function addToBackroom(inv: Inventory, item: ItemRef, qty: number): void {
|
|
const key = itemKey(item);
|
|
inv.backroom[key] = (inv.backroom[key] ?? 0) + qty;
|
|
}
|
|
|
|
export function backroomQty(inv: Inventory, item: ItemRef): number {
|
|
return inv.backroom[itemKey(item)] ?? 0;
|
|
}
|
|
|
|
export function getSlot(inv: Inventory, slotId: string): ShelfSlot {
|
|
const slot = inv.slots.find((s) => s.id === slotId);
|
|
if (!slot) throw new Error(`Unknown slot: ${slotId}`);
|
|
return slot;
|
|
}
|
|
|
|
/** Moves up to `qty` items from the backroom into the slot. Returns the quantity moved. */
|
|
export function stockSlot(inv: Inventory, slotId: string, item: ItemRef, qty: number): number {
|
|
const slot = getSlot(inv, slotId);
|
|
if (slot.item && itemKey(slot.item) !== itemKey(item)) {
|
|
throw new Error(`Slot ${slotId} holds another item`);
|
|
}
|
|
const key = itemKey(item);
|
|
const moved = Math.min(qty, SLOT_CAPACITY - slot.qty, inv.backroom[key] ?? 0);
|
|
if (moved <= 0) return 0;
|
|
slot.item = item;
|
|
slot.qty += moved;
|
|
inv.backroom[key] -= moved;
|
|
if (inv.backroom[key] === 0) delete inv.backroom[key];
|
|
return moved;
|
|
}
|
|
|
|
export function takeFromSlot(inv: Inventory, slotId: string): ItemRef {
|
|
const slot = getSlot(inv, slotId);
|
|
if (!slot.item || slot.qty === 0) throw new Error(`Slot ${slotId} is empty`);
|
|
const item = slot.item;
|
|
slot.qty -= 1;
|
|
if (slot.qty === 0) slot.item = null;
|
|
return item;
|
|
}
|
|
|
|
export function shelfItems(inv: Inventory): ShelfSlot[] {
|
|
return inv.slots.filter((s) => s.item !== null && s.qty > 0);
|
|
}
|
|
|
|
export function totalQty(inv: Inventory, item: ItemRef): number {
|
|
const key = itemKey(item);
|
|
const onShelves = inv.slots
|
|
.filter((s) => s.item && itemKey(s.item) === key)
|
|
.reduce((sum, s) => sum + s.qty, 0);
|
|
return backroomQty(inv, item) + onShelves;
|
|
}
|