refactor items logic

This commit is contained in:
Peter Stockings
2026-01-22 22:04:23 +11:00
parent 4129f5390f
commit d2039df8c8
8 changed files with 220 additions and 118 deletions

View File

@@ -1,77 +1,180 @@
import type { Item } from "../types";
import type {
ConsumableItem,
MeleeWeaponItem,
RangedWeaponItem,
ArmourItem,
AmmoItem
} from "../types";
export const ITEMS: Record<string, Item> = {
"health_potion": {
id: "health_potion",
// =============================================================================
// Per-Type Template Lists (Immutable)
// =============================================================================
export const CONSUMABLES = {
health_potion: {
name: "Health Potion",
type: "Consumable",
textureKey: "items",
spriteIndex: 57,
stats: {
hp: 5
},
healAmount: 5,
stackable: true,
quantity: 1
},
"iron_sword": {
id: "iron_sword",
name: "Iron Sword",
type: "Weapon",
weaponType: "melee",
textureKey: "items",
spriteIndex: 2,
stats: {
attack: 2
}
},
"leather_armor": {
id: "leather_armor",
name: "Leather Armor",
type: "BodyArmour",
textureKey: "items",
spriteIndex: 25,
stats: {
defense: 2
}
},
"throwing_dagger": {
id: "throwing_dagger",
throwing_dagger: {
name: "Throwing Dagger",
type: "Consumable",
textureKey: "items",
spriteIndex: 15,
stats: {
attack: 4
},
attack: 4,
throwable: true,
stackable: true,
quantity: 1
},
"pistol": {
id: "pistol",
} as const;
export const RANGED_WEAPONS = {
pistol: {
name: "Pistol",
type: "Weapon",
weaponType: "ranged",
textureKey: "weapons",
spriteIndex: 1,
stats: {
attack: 10,
range: 8,
magazineSize: 6,
currentAmmo: 6,
ammoType: "9mm",
projectileSpeed: 15,
fireSound: "shoot"
}
},
"ammo_9mm": {
id: "ammo_9mm",
name: "9mm Ammo",
type: "Ammo",
attack: 10,
range: 8,
magazineSize: 6,
ammoType: "9mm",
projectileSpeed: 15,
fireSound: "shoot",
},
} as const;
export const MELEE_WEAPONS = {
iron_sword: {
name: "Iron Sword",
textureKey: "items",
spriteIndex: 2,
attack: 2,
},
} as const;
export const AMMO = {
ammo_9mm: {
name: "9mm Ammo",
textureKey: "weapons",
spriteIndex: 23,
ammoType: "9mm",
stackable: true,
quantity: 10 // Finds a pack of 10
}
};
},
} as const;
export const ARMOUR = {
leather_armor: {
name: "Leather Armor",
textureKey: "items",
spriteIndex: 25,
defense: 2,
},
} as const;
// Combined lookup for rendering (e.g., projectile sprites)
export const ALL_TEMPLATES = {
...CONSUMABLES,
...RANGED_WEAPONS,
...MELEE_WEAPONS,
...AMMO,
...ARMOUR,
} as const;
// =============================================================================
// Type-Safe IDs (derived from templates)
// =============================================================================
export type ConsumableId = keyof typeof CONSUMABLES;
export type RangedWeaponId = keyof typeof RANGED_WEAPONS;
export type MeleeWeaponId = keyof typeof MELEE_WEAPONS;
export type AmmoId = keyof typeof AMMO;
export type ArmourId = keyof typeof ARMOUR;
export type ItemTemplateId = keyof typeof ALL_TEMPLATES;
// =============================================================================
// Factory Functions
// =============================================================================
export function createConsumable(id: ConsumableId, quantity = 1): ConsumableItem {
const t = CONSUMABLES[id];
return {
id,
name: t.name,
type: "Consumable",
textureKey: t.textureKey,
spriteIndex: t.spriteIndex,
stackable: t.stackable ?? false,
quantity,
stats: {
hp: "healAmount" in t ? t.healAmount : undefined,
attack: "attack" in t ? t.attack : undefined,
},
throwable: "throwable" in t ? t.throwable : undefined,
};
}
export function createRangedWeapon(id: RangedWeaponId): RangedWeaponItem {
const t = RANGED_WEAPONS[id];
return {
id,
name: t.name,
type: "Weapon",
weaponType: "ranged",
textureKey: t.textureKey,
spriteIndex: t.spriteIndex,
currentAmmo: t.magazineSize,
stats: {
attack: t.attack,
range: t.range,
magazineSize: t.magazineSize,
ammoType: t.ammoType,
projectileSpeed: t.projectileSpeed,
fireSound: t.fireSound,
},
};
}
export function createMeleeWeapon(id: MeleeWeaponId): MeleeWeaponItem {
const t = MELEE_WEAPONS[id];
return {
id,
name: t.name,
type: "Weapon",
weaponType: "melee",
textureKey: t.textureKey,
spriteIndex: t.spriteIndex,
stats: {
attack: t.attack,
},
};
}
export function createAmmo(id: AmmoId, quantity = 10): AmmoItem {
const t = AMMO[id];
return {
id,
name: t.name,
type: "Ammo",
textureKey: t.textureKey,
spriteIndex: t.spriteIndex,
ammoType: t.ammoType,
stackable: true,
quantity,
};
}
export function createArmour(id: ArmourId): ArmourItem {
const t = ARMOUR[id];
return {
id,
name: t.name,
type: "BodyArmour",
textureKey: t.textureKey,
spriteIndex: t.spriteIndex,
stats: {
defense: t.defense,
},
};
}
// Legacy export for backward compatibility during migration
export const ITEMS = ALL_TEMPLATES;