import type { ConsumableItem, MeleeWeaponItem, RangedWeaponItem, ArmourItem, AmmoItem, FlamethrowerItem } from "../types"; import { GAME_CONFIG } from "../config/GameConfig"; // ============================================================================= // Per-Type Template Lists (Immutable) // ============================================================================= export const CONSUMABLES = { health_potion: { name: "Health Potion", textureKey: "items", spriteIndex: 57, healAmount: 5, stackable: true, }, throwing_dagger: { name: "Throwing Dagger", textureKey: "items", spriteIndex: 15, attack: 4, throwable: true, stackable: true, }, upgrade_scroll: { name: "Upgrade Scroll", textureKey: "items", spriteIndex: 79, stackable: true, }, } as const; export const RANGED_WEAPONS = { pistol: { name: "Pistol", textureKey: "weapons", spriteIndex: 1, 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, }, } 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 // ============================================================================= import { ALL_VARIANTS, type ArmourVariantId, type WeaponVariantId, type ConsumableVariantId } from "./ItemVariants"; export function createConsumable( id: ConsumableId, quantity = 1, variant?: ConsumableVariantId ): ConsumableItem { const t = CONSUMABLES[id]; const v = variant ? ALL_VARIANTS[variant] : null; // Apply effect multiplier for consumables const effectMult = v?.statModifiers.effectMultiplier ?? 1; const baseHealAmount = "healAmount" in t ? t.healAmount : undefined; const finalHealAmount = baseHealAmount ? Math.floor(baseHealAmount * effectMult) : undefined; const name = v ? `${v.prefix} ${t.name}` : t.name; return { id, name, type: "Consumable", textureKey: t.textureKey, spriteIndex: t.spriteIndex, stackable: t.stackable ?? false, quantity, variant, stats: { hp: finalHealAmount, attack: "attack" in t ? t.attack : undefined, }, throwable: "throwable" in t ? t.throwable : undefined, }; } export function createRangedWeapon( id: RangedWeaponId, variant?: WeaponVariantId ): RangedWeaponItem { const t = RANGED_WEAPONS[id]; const v = variant ? ALL_VARIANTS[variant] : null; const name = v ? `${v.prefix} ${t.name}` : t.name; const attackBonus = (v?.statModifiers as { attack?: number })?.attack ?? 0; return { id, name, type: "Weapon", weaponType: "ranged", textureKey: t.textureKey, spriteIndex: t.spriteIndex, currentAmmo: t.magazineSize, reloadingTurnsLeft: 0, variant, stats: { attack: t.attack + attackBonus, range: t.range, magazineSize: t.magazineSize, ammoType: t.ammoType, projectileSpeed: t.projectileSpeed, fireSound: t.fireSound, }, }; } export function createMeleeWeapon( id: MeleeWeaponId, variant?: WeaponVariantId ): MeleeWeaponItem { const t = MELEE_WEAPONS[id]; const v = variant ? ALL_VARIANTS[variant] : null; const name = v ? `${v.prefix} ${t.name}` : t.name; const attackBonus = (v?.statModifiers as { attack?: number })?.attack ?? 0; return { id, name, type: "Weapon", weaponType: "melee", textureKey: t.textureKey, spriteIndex: t.spriteIndex, variant, stats: { attack: t.attack + attackBonus, }, }; } 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, variant?: ArmourVariantId ): ArmourItem { const t = ARMOUR[id]; const v = variant ? ALL_VARIANTS[variant] : null; const name = v ? `${v.prefix} ${t.name}` : t.name; const defenseBonus = v?.statModifiers.defense ?? 0; return { id, name, type: "BodyArmour", textureKey: t.textureKey, spriteIndex: t.spriteIndex, variant, stats: { defense: t.defense + defenseBonus, }, }; } export function createUpgradeScroll(quantity = 1): ConsumableItem { const t = CONSUMABLES["upgrade_scroll"]; return { id: "upgrade_scroll", name: t.name, type: "Consumable", textureKey: t.textureKey, spriteIndex: t.spriteIndex, stackable: true, quantity, }; } export function createFlamethrower(): FlamethrowerItem { const config = GAME_CONFIG.gameplay.flamethrower; return { id: "flamethrower", name: "Flamethrower", type: "Weapon", weaponType: "flamethrower", textureKey: "weapons", spriteIndex: 5, charges: config.maxCharges, maxCharges: config.maxCharges, lastRechargeTurn: 0, stats: { attack: config.initialDamage, range: config.range, }, }; } // Legacy export for backward compatibility during migration export const ITEMS = ALL_TEMPLATES;