Aray - record for inventory & equipment
This commit is contained in:
parent
561ffb1d7e
commit
cc8f4a562f
|
|
@ -34,7 +34,7 @@ interface SlotRecord {
|
|||
}
|
||||
|
||||
interface EquipmentState {
|
||||
slots: SlotRecord[];
|
||||
slots: Record<string, SlotRecord>;
|
||||
}
|
||||
|
||||
export type SlotInput =
|
||||
|
|
@ -46,17 +46,17 @@ export class Equipment extends Component<EquipmentState> {
|
|||
#cachedVars: RPGVariables | null = null;
|
||||
|
||||
constructor(slots: SlotInput[]) {
|
||||
super({
|
||||
slots: slots.map(s => {
|
||||
const slotName = typeof s === 'string' ? s : s.slotName;
|
||||
const type = typeof s === 'object' && s.type ? s.type : null;
|
||||
return { slotName, type, itemId: null, appliedEffectKeys: [] };
|
||||
}),
|
||||
});
|
||||
const record: Record<string, SlotRecord> = {};
|
||||
for (const s of slots) {
|
||||
const slotName = typeof s === 'string' ? s : s.slotName;
|
||||
const type = typeof s === 'object' && s.type ? s.type : null;
|
||||
record[slotName] = { slotName, type, itemId: null, appliedEffectKeys: [] };
|
||||
}
|
||||
super({ slots: record });
|
||||
}
|
||||
|
||||
#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. */
|
||||
|
|
@ -71,7 +71,7 @@ export class Equipment extends Component<EquipmentState> {
|
|||
*/
|
||||
findCompatibleSlot(slotType: string): string | 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.type === null) { genericFallback ??= slot.slotName; continue; }
|
||||
if (slot.type === slotType) return slot.slotName;
|
||||
|
|
@ -81,7 +81,7 @@ export class Equipment extends Component<EquipmentState> {
|
|||
|
||||
/** All currently equipped `{ slotName, itemId }` pairs. */
|
||||
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)
|
||||
.map(({ slotName, itemId }) => ({ slotName, itemId }));
|
||||
}
|
||||
|
|
@ -154,7 +154,7 @@ export class Equipment extends Component<EquipmentState> {
|
|||
if (this.#cachedVars) return this.#cachedVars;
|
||||
|
||||
const result: RPGVariables = {};
|
||||
for (const { slotName, itemId } of this.state.slots) {
|
||||
for (const { slotName, itemId } of Object.values(this.state.slots)) {
|
||||
result[slotName] = itemId ?? '';
|
||||
}
|
||||
this.#cachedVars = result;
|
||||
|
|
|
|||
|
|
@ -15,29 +15,25 @@ interface SlotRecord {
|
|||
interface InventoryState {
|
||||
infinite: boolean;
|
||||
nextSlotId: number; // auto-increment counter for infinite mode
|
||||
slots: SlotRecord[];
|
||||
slots: Record<SlotId, SlotRecord>;
|
||||
}
|
||||
|
||||
function buildInventoryState(input?: number | InventorySlotInput[]): InventoryState {
|
||||
if (input === undefined) {
|
||||
return { infinite: true, nextSlotId: 0, slots: [] };
|
||||
return { infinite: true, nextSlotId: 0, slots: {} as Record<SlotId, SlotRecord> };
|
||||
}
|
||||
if (typeof input === 'number') {
|
||||
return {
|
||||
infinite: false,
|
||||
nextSlotId: 0,
|
||||
slots: Array.from({ length: input }, (_, i) => ({ slotId: i, limit: undefined, contents: null })),
|
||||
};
|
||||
const slots = {} as Record<SlotId, SlotRecord>;
|
||||
for (let i = 0; i < input; i++) slots[i] = { slotId: i, limit: undefined, contents: null };
|
||||
return { infinite: false, nextSlotId: 0, slots };
|
||||
}
|
||||
return {
|
||||
infinite: false,
|
||||
nextSlotId: 0,
|
||||
slots: input.map(def => ({
|
||||
slotId: typeof def === 'object' ? def.slotId : def,
|
||||
limit: typeof def === 'object' ? def.limit : undefined,
|
||||
contents: null,
|
||||
})),
|
||||
};
|
||||
const slots = {} as Record<SlotId, SlotRecord>;
|
||||
for (const def of input) {
|
||||
const slotId = typeof def === 'object' ? def.slotId : def;
|
||||
const limit = typeof def === 'object' ? def.limit : undefined;
|
||||
slots[slotId] = { slotId, limit, contents: null };
|
||||
}
|
||||
return { infinite: false, nextSlotId: 0, slots };
|
||||
}
|
||||
|
||||
@component
|
||||
|
|
@ -55,7 +51,7 @@ export class Inventory extends Component<InventoryState> {
|
|||
}
|
||||
|
||||
#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 {
|
||||
|
|
@ -94,7 +90,7 @@ export class Inventory extends Component<InventoryState> {
|
|||
// ── Finite inventory: two-phase (check → apply) ───────────────────────
|
||||
if (!this.state.infinite) {
|
||||
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)
|
||||
canFit += this.#roomFor(slot, itemId);
|
||||
}
|
||||
|
|
@ -102,7 +98,7 @@ export class Inventory extends Component<InventoryState> {
|
|||
|
||||
let remaining = amount;
|
||||
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) {
|
||||
const take = Math.min(this.#roomFor(slot, itemId), remaining);
|
||||
slot.contents!.amount += take;
|
||||
|
|
@ -110,7 +106,7 @@ export class Inventory extends Component<InventoryState> {
|
|||
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) {
|
||||
const take = Math.min(this.#capFor(slot, itemId), remaining);
|
||||
slot.contents = { itemId, amount: take };
|
||||
|
|
@ -126,7 +122,7 @@ export class Inventory extends Component<InventoryState> {
|
|||
let remaining = amount;
|
||||
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) {
|
||||
const take = Math.min(this.#roomFor(slot, itemId), remaining);
|
||||
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) {
|
||||
const take = Math.min(this.#capFor(slot, itemId), remaining);
|
||||
slot.contents = { itemId, amount: take };
|
||||
|
|
@ -146,7 +142,7 @@ export class Inventory extends Component<InventoryState> {
|
|||
}
|
||||
while (remaining > 0) {
|
||||
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);
|
||||
newSlot.contents = { itemId, amount: take };
|
||||
remaining -= take;
|
||||
|
|
@ -177,7 +173,7 @@ export class Inventory extends Component<InventoryState> {
|
|||
|
||||
let remaining = amount;
|
||||
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) {
|
||||
const take = Math.min(slot.contents.amount, remaining);
|
||||
slot.contents.amount -= take;
|
||||
|
|
@ -290,7 +286,7 @@ export class Inventory extends Component<InventoryState> {
|
|||
return slot?.contents?.itemId === itemId ? slot.contents.amount : 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;
|
||||
}
|
||||
return total;
|
||||
|
|
@ -298,7 +294,7 @@ export class Inventory extends Component<InventoryState> {
|
|||
|
||||
getItems(): 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) {
|
||||
const { itemId, amount } = slot.contents;
|
||||
result.set(itemId, (result.get(itemId) ?? 0) + amount);
|
||||
|
|
|
|||
Loading…
Reference in New Issue