import { EquipmentSlot } from '../../items/equipment-slot.enum'; import { ItemRarity } from '../../items/item-rarity.enum'; import { ItemType } from '../../items/item-type.enum'; import { ASH_RAT_LOOT_TABLE_ID, ITEM_IDS, ItemKey, ROAD_BANDIT_LOOT_TABLE_ID, } from './item.constants'; export interface SeedItemDefinition { id: string; key: ItemKey; name: string; description: string; type: ItemType; equipmentSlot: EquipmentSlot | null; rarity: ItemRarity; tier: number; requiredLevel: number; weaponDamage: number; bonusHp: number; bonusAttack: number; bonusArmor: number; sellPrice: number; iconPath: string; } function item( key: ItemKey, name: string, description: string, type: ItemType, equipmentSlot: EquipmentSlot | null, rarity: ItemRarity, stats: Partial> = {}, ): SeedItemDefinition { return { id: ITEM_IDS[key], key, name, description, type, equipmentSlot, rarity, tier: 1, requiredLevel: 1, weaponDamage: stats.weaponDamage ?? 0, bonusHp: stats.bonusHp ?? 0, bonusAttack: stats.bonusAttack ?? 0, bonusArmor: stats.bonusArmor ?? 0, // Always 0: no merchants exist in Slice 0.4, and the balancing doc's // Grenzmarken table lists purchase prices, not sell prices. sellPrice: 0, iconPath: `/images/items/${key}.png`, }; } // Stats from docs/Ashen_Realms_Balancing_Items_Loot_Design_V1.md §19. export const ITEM_DEFINITIONS: SeedItemDefinition[] = [ item( 'worn-short-sword', 'Abgenutztes Kurzschwert', 'Die Klinge eines Rekruten, öfter geschliffen als geführt.', ItemType.WEAPON, EquipmentSlot.WEAPON, ItemRarity.COMMON, { weaponDamage: 8 }, ), item( 'bandit-blade', 'Räuberklinge', 'Eine grob gezahnte Klinge, geschmiedet für schnelle Überfälle.', ItemType.WEAPON, EquipmentSlot.WEAPON, ItemRarity.COMMON, { weaponDamage: 11, bonusAttack: 1 }, ), item( 'ash-blade', 'Aschenklinge', 'In der Glut der Aschenfelder gehärtet; die Schneide glimmt noch.', ItemType.WEAPON, EquipmentSlot.WEAPON, ItemRarity.RARE, { weaponDamage: 15, bonusAttack: 2 }, ), item( 'bandit-hood', 'Räuberhaube', 'Vernarbtes Leder, das Gesicht und Absicht des Trägers verbirgt.', ItemType.ARMOR, EquipmentSlot.HEAD, ItemRarity.COMMON, { bonusArmor: 3, bonusHp: 5 }, ), item( 'reinforced-leather-jacket', 'Verstärkte Lederjacke', 'Mit Eisenplatten benähtes Leder, schwer und verlässlich.', ItemType.ARMOR, EquipmentSlot.CHEST, ItemRarity.RARE, { bonusArmor: 7, bonusHp: 10 }, ), item( 'raider-gloves', 'Plündererhandschuhe', 'Beschlagene Handschuhe, abgegriffen von fremdem Gut.', ItemType.ARMOR, EquipmentSlot.HANDS, ItemRarity.COMMON, { bonusArmor: 3, bonusAttack: 1 }, ), item( 'guardsman-legs', 'Wachmannsbeinkleid', 'Beinzeug der Grenzwacht, an den Knien geflickt.', ItemType.ARMOR, EquipmentSlot.LEGS, ItemRarity.RARE, { bonusArmor: 5, bonusHp: 5 }, ), item( 'ash-boots', 'Aschenstiefel', 'Stiefel, die durch glimmende Felder getragen wurden und blieben.', ItemType.ARMOR, EquipmentSlot.FEET, ItemRarity.RARE, { bonusArmor: 4, bonusHp: 5 }, ), item( 'borderwatch-sigil', 'Zeichen der Grenzwacht', 'Das Wappen eines Turms, den es nicht mehr gibt.', ItemType.ARMOR, EquipmentSlot.AMULET, ItemRarity.RARE, { bonusAttack: 3, bonusHp: 10 }, ), item( 'burned-captain-pendant', 'Anhänger des verbrannten Hauptmanns', 'Ein Schädel aus Schlacke, in dem die Glut nie erlosch.', ItemType.ARMOR, EquipmentSlot.AMULET, ItemRarity.EPIC, { bonusAttack: 3, bonusHp: 15, bonusArmor: 2 }, ), // Seeded as content only. Slice 0.4 implements no consumable use, and the // Straßenräuber loot entry for it is deliberately deferred (spec §16). item( 'small-healing-potion', 'Kleiner Heiltrank', 'Ein bitterer Sud, der Wunden für einen Atemzug vergessen lässt.', ItemType.CONSUMABLE, null, ItemRarity.COMMON, ), item( 'ash-pelt', 'Aschenfell', 'Versengtes Fell, zäh wie Leder und grau von Ascheflug.', ItemType.MATERIAL, null, ItemRarity.COMMON, ), ]; export const LOOT_TABLES = [ { id: ASH_RAT_LOOT_TABLE_ID, key: 'ash-rat-loot', name: 'Aschenratte Beute' }, { id: ROAD_BANDIT_LOOT_TABLE_ID, key: 'road-bandit-loot', name: 'Straßenräuber Beute' }, ]; export interface SeedLootTableEntry { lootTableId: string; itemDefinitionId: string; position: number; dropChance: string; minQuantity: number; maxQuantity: number; enabled: boolean; } function entry( lootTableId: string, key: ItemKey, position: number, dropChance: string, ): SeedLootTableEntry { return { lootTableId, itemDefinitionId: ITEM_IDS[key], position, dropChance, minQuantity: 1, maxQuantity: 1, enabled: true, }; } /** * Drop chances from docs/Ashen_Realms_Balancing_Items_Loot_Design_V1.md §27–28. * Every entry is an independent roll (spec §17), rolled in `position` order. * * DEFERRED: the Straßenräuber table also lists 10 % Kleiner Heiltrank. It is * omitted here because Slice 0.4 implements no consumables (spec §16). */ export const LOOT_TABLE_ENTRIES: SeedLootTableEntry[] = [ entry(ASH_RAT_LOOT_TABLE_ID, 'ash-pelt', 1, '0.6000'), entry(ASH_RAT_LOOT_TABLE_ID, 'worn-short-sword', 2, '0.0800'), entry(ROAD_BANDIT_LOOT_TABLE_ID, 'bandit-blade', 1, '0.1800'), entry(ROAD_BANDIT_LOOT_TABLE_ID, 'bandit-hood', 2, '0.1200'), entry(ROAD_BANDIT_LOOT_TABLE_ID, 'raider-gloves', 3, '0.0800'), ];