1
0
Fork 0

Aray - record for inventory & equipment

This commit is contained in:
Pabloader 2026-04-30 10:55:24 +00:00
parent 561ffb1d7e
commit cc8f4a562f
2 changed files with 34 additions and 38 deletions

View File

@ -34,7 +34,7 @@ interface SlotRecord {
} }
interface EquipmentState { interface EquipmentState {
slots: SlotRecord[]; slots: Record<string, SlotRecord>;
} }
export type SlotInput = export type SlotInput =
@ -46,17 +46,17 @@ export class Equipment extends Component<EquipmentState> {
#cachedVars: RPGVariables | null = null; #cachedVars: RPGVariables | null = null;
constructor(slots: SlotInput[]) { constructor(slots: SlotInput[]) {
super({ const record: Record<string, SlotRecord> = {};
slots: slots.map(s => { for (const s of slots) {
const slotName = typeof s === 'string' ? s : s.slotName; const slotName = typeof s === 'string' ? s : s.slotName;
const type = typeof s === 'object' && s.type ? s.type : null; const type = typeof s === 'object' && s.type ? s.type : null;
return { slotName, type, itemId: null, appliedEffectKeys: [] }; record[slotName] = { slotName, type, itemId: null, appliedEffectKeys: [] };
}), }
}); super({ slots: record });
} }
#slot(slotName: string): SlotRecord | undefined { #slot(slotName: string): SlotRecord | undefined {
return this.state.slots.find(s => s.slotName === slotName); return this.state.slots[slotName];
} }
/** ItemId in the named slot, or null if empty. */ /** ItemId in the named slot, or null if empty. */
@ -71,7 +71,7 @@ export class Equipment extends Component<EquipmentState> {
*/ */
findCompatibleSlot(slotType: string): string | null { findCompatibleSlot(slotType: string): string | null {
let genericFallback: string | null = null; let genericFallback: string | null = null;
for (const slot of this.state.slots) { for (const slot of Object.values(this.state.slots)) {
if (slot.itemId !== null) continue; if (slot.itemId !== null) continue;
if (slot.type === null) { genericFallback ??= slot.slotName; continue; } if (slot.type === null) { genericFallback ??= slot.slotName; continue; }
if (slot.type === slotType) return slot.slotName; if (slot.type === slotType) return slot.slotName;
@ -81,7 +81,7 @@ export class Equipment extends Component<EquipmentState> {
/** All currently equipped `{ slotName, itemId }` pairs. */ /** All currently equipped `{ slotName, itemId }` pairs. */
getEquipped(): { slotName: string; itemId: string }[] { getEquipped(): { slotName: string; itemId: string }[] {
return this.state.slots return Object.values(this.state.slots)
.filter((s): s is SlotRecord & { itemId: string } => s.itemId !== null) .filter((s): s is SlotRecord & { itemId: string } => s.itemId !== null)
.map(({ slotName, itemId }) => ({ slotName, itemId })); .map(({ slotName, itemId }) => ({ slotName, itemId }));
} }
@ -154,7 +154,7 @@ export class Equipment extends Component<EquipmentState> {
if (this.#cachedVars) return this.#cachedVars; if (this.#cachedVars) return this.#cachedVars;
const result: RPGVariables = {}; const result: RPGVariables = {};
for (const { slotName, itemId } of this.state.slots) { for (const { slotName, itemId } of Object.values(this.state.slots)) {
result[slotName] = itemId ?? ''; result[slotName] = itemId ?? '';
} }
this.#cachedVars = result; this.#cachedVars = result;

View File

@ -15,29 +15,25 @@ interface SlotRecord {
interface InventoryState { interface InventoryState {
infinite: boolean; infinite: boolean;
nextSlotId: number; // auto-increment counter for infinite mode nextSlotId: number; // auto-increment counter for infinite mode
slots: SlotRecord[]; slots: Record<SlotId, SlotRecord>;
} }
function buildInventoryState(input?: number | InventorySlotInput[]): InventoryState { function buildInventoryState(input?: number | InventorySlotInput[]): InventoryState {
if (input === undefined) { if (input === undefined) {
return { infinite: true, nextSlotId: 0, slots: [] }; return { infinite: true, nextSlotId: 0, slots: {} as Record<SlotId, SlotRecord> };
} }
if (typeof input === 'number') { if (typeof input === 'number') {
return { const slots = {} as Record<SlotId, SlotRecord>;
infinite: false, for (let i = 0; i < input; i++) slots[i] = { slotId: i, limit: undefined, contents: null };
nextSlotId: 0, return { infinite: false, nextSlotId: 0, slots };
slots: Array.from({ length: input }, (_, i) => ({ slotId: i, limit: undefined, contents: null })),
};
} }
return { const slots = {} as Record<SlotId, SlotRecord>;
infinite: false, for (const def of input) {
nextSlotId: 0, const slotId = typeof def === 'object' ? def.slotId : def;
slots: input.map(def => ({ const limit = typeof def === 'object' ? def.limit : undefined;
slotId: typeof def === 'object' ? def.slotId : def, slots[slotId] = { slotId, limit, contents: null };
limit: typeof def === 'object' ? def.limit : undefined, }
contents: null, return { infinite: false, nextSlotId: 0, slots };
})),
};
} }
@component @component
@ -55,7 +51,7 @@ export class Inventory extends Component<InventoryState> {
} }
#slot(slotId: SlotId): SlotRecord | undefined { #slot(slotId: SlotId): SlotRecord | undefined {
return this.state.slots.find(s => s.slotId === slotId); return this.state.slots[slotId];
} }
#capFor(slot: SlotRecord, itemId: string): number { #capFor(slot: SlotRecord, itemId: string): number {
@ -94,7 +90,7 @@ export class Inventory extends Component<InventoryState> {
// ── Finite inventory: two-phase (check → apply) ─────────────────────── // ── Finite inventory: two-phase (check → apply) ───────────────────────
if (!this.state.infinite) { if (!this.state.infinite) {
let canFit = 0; let canFit = 0;
for (const slot of this.state.slots) { for (const slot of Object.values(this.state.slots)) {
if (slot.contents === null || slot.contents.itemId === itemId) if (slot.contents === null || slot.contents.itemId === itemId)
canFit += this.#roomFor(slot, itemId); canFit += this.#roomFor(slot, itemId);
} }
@ -102,7 +98,7 @@ export class Inventory extends Component<InventoryState> {
let remaining = amount; let remaining = amount;
const slotIds: SlotId[] = []; const slotIds: SlotId[] = [];
for (const slot of this.state.slots) { for (const slot of Object.values(this.state.slots)) {
if (slot.contents?.itemId === itemId && remaining > 0) { if (slot.contents?.itemId === itemId && remaining > 0) {
const take = Math.min(this.#roomFor(slot, itemId), remaining); const take = Math.min(this.#roomFor(slot, itemId), remaining);
slot.contents!.amount += take; slot.contents!.amount += take;
@ -110,7 +106,7 @@ export class Inventory extends Component<InventoryState> {
slotIds.push(slot.slotId); slotIds.push(slot.slotId);
} }
} }
for (const slot of this.state.slots) { for (const slot of Object.values(this.state.slots)) {
if (slot.contents === null && remaining > 0) { if (slot.contents === null && remaining > 0) {
const take = Math.min(this.#capFor(slot, itemId), remaining); const take = Math.min(this.#capFor(slot, itemId), remaining);
slot.contents = { itemId, amount: take }; slot.contents = { itemId, amount: take };
@ -126,7 +122,7 @@ export class Inventory extends Component<InventoryState> {
let remaining = amount; let remaining = amount;
const slotIds: SlotId[] = []; const slotIds: SlotId[] = [];
for (const slot of this.state.slots) { for (const slot of Object.values(this.state.slots)) {
if (slot.contents?.itemId === itemId && remaining > 0) { if (slot.contents?.itemId === itemId && remaining > 0) {
const take = Math.min(this.#roomFor(slot, itemId), remaining); const take = Math.min(this.#roomFor(slot, itemId), remaining);
if (take > 0) { if (take > 0) {
@ -136,7 +132,7 @@ export class Inventory extends Component<InventoryState> {
} }
} }
} }
for (const slot of this.state.slots) { for (const slot of Object.values(this.state.slots)) {
if (slot.contents === null && remaining > 0) { if (slot.contents === null && remaining > 0) {
const take = Math.min(this.#capFor(slot, itemId), remaining); const take = Math.min(this.#capFor(slot, itemId), remaining);
slot.contents = { itemId, amount: take }; slot.contents = { itemId, amount: take };
@ -146,7 +142,7 @@ export class Inventory extends Component<InventoryState> {
} }
while (remaining > 0) { while (remaining > 0) {
const newSlot: SlotRecord = { slotId: this.state.nextSlotId++, limit: undefined, contents: null }; const newSlot: SlotRecord = { slotId: this.state.nextSlotId++, limit: undefined, contents: null };
this.state.slots.push(newSlot); this.state.slots[newSlot.slotId] = newSlot;
const take = Math.min(this.#capFor(newSlot, itemId), remaining); const take = Math.min(this.#capFor(newSlot, itemId), remaining);
newSlot.contents = { itemId, amount: take }; newSlot.contents = { itemId, amount: take };
remaining -= take; remaining -= take;
@ -177,7 +173,7 @@ export class Inventory extends Component<InventoryState> {
let remaining = amount; let remaining = amount;
const slotIds: SlotId[] = []; const slotIds: SlotId[] = [];
for (const slot of this.state.slots) { for (const slot of Object.values(this.state.slots)) {
if (slot.contents?.itemId === itemId && remaining > 0) { if (slot.contents?.itemId === itemId && remaining > 0) {
const take = Math.min(slot.contents.amount, remaining); const take = Math.min(slot.contents.amount, remaining);
slot.contents.amount -= take; slot.contents.amount -= take;
@ -290,7 +286,7 @@ export class Inventory extends Component<InventoryState> {
return slot?.contents?.itemId === itemId ? slot.contents.amount : 0; return slot?.contents?.itemId === itemId ? slot.contents.amount : 0;
} }
let total = 0; let total = 0;
for (const slot of this.state.slots) { for (const slot of Object.values(this.state.slots)) {
if (slot.contents?.itemId === itemId) total += slot.contents.amount; if (slot.contents?.itemId === itemId) total += slot.contents.amount;
} }
return total; return total;
@ -298,7 +294,7 @@ export class Inventory extends Component<InventoryState> {
getItems(): Map<string, number> { getItems(): Map<string, number> {
const result = new Map<string, number>(); const result = new Map<string, number>();
for (const slot of this.state.slots) { for (const slot of Object.values(this.state.slots)) {
if (slot.contents) { if (slot.contents) {
const { itemId, amount } = slot.contents; const { itemId, amount } = slot.contents;
result.set(itemId, (result.get(itemId) ?? 0) + amount); result.set(itemId, (result.get(itemId) ?? 0) + amount);