feat(api): implement Diablo-style item affix system

Add procedural item generation with affix naming system:
- Items with RARE/EPIC/LEGENDARY rarity get dynamic names
- Prefixes (e.g., "Flaming") add elemental damage, material bonuses
- Suffixes (e.g., "of Strength") add stat bonuses
- Affix count scales with rarity: RARE=1, EPIC=2, LEGENDARY=3

New files:
- models/affixes.py: Affix and BaseItemTemplate dataclasses
- services/affix_loader.py: YAML-based affix pool loading
- services/base_item_loader.py: Base item template loading
- services/item_generator.py: Main procedural generation service
- data/affixes/prefixes.yaml: 14 prefix definitions
- data/affixes/suffixes.yaml: 15 suffix definitions
- data/base_items/weapons.yaml: 12 weapon templates
- data/base_items/armor.yaml: 12 armor templates
- tests/test_item_generator.py: 34 comprehensive tests

Modified:
- enums.py: Added AffixType and AffixTier enums
- items.py: Added affix tracking fields (applied_affixes, generated_name)

Example output: "Frozen Dagger of the Bear" (EPIC with ice damage + STR/CON)
This commit is contained in:
2025-11-26 17:57:34 -06:00
parent f3ac0c8647
commit 185be7fee0
11 changed files with 2658 additions and 0 deletions

View File

@@ -0,0 +1,182 @@
# Base Weapon Templates for Procedural Generation
#
# These templates define the foundation that affixes attach to.
# Example: "Dagger" + "Flaming" prefix = "Flaming Dagger"
#
# Template Structure:
# template_id: Unique identifier
# name: Base item name
# item_type: "weapon"
# description: Flavor text
# base_damage: Weapon damage
# base_value: Gold value
# damage_type: "physical" (default)
# crit_chance: Critical hit chance (0.0-1.0)
# crit_multiplier: Crit damage multiplier
# required_level: Min level to use/drop
# drop_weight: Higher = more common (1.0 = standard)
# min_rarity: Minimum rarity for this template
weapons:
# ==================== ONE-HANDED SWORDS ====================
dagger:
template_id: "dagger"
name: "Dagger"
item_type: "weapon"
description: "A small, quick blade for close combat"
base_damage: 6
base_value: 15
damage_type: "physical"
crit_chance: 0.08
crit_multiplier: 2.0
required_level: 1
drop_weight: 1.5
short_sword:
template_id: "short_sword"
name: "Short Sword"
item_type: "weapon"
description: "A versatile one-handed blade"
base_damage: 10
base_value: 30
damage_type: "physical"
crit_chance: 0.06
crit_multiplier: 2.0
required_level: 1
drop_weight: 1.3
longsword:
template_id: "longsword"
name: "Longsword"
item_type: "weapon"
description: "A standard warrior's blade"
base_damage: 14
base_value: 50
damage_type: "physical"
crit_chance: 0.05
crit_multiplier: 2.0
required_level: 3
drop_weight: 1.0
# ==================== TWO-HANDED WEAPONS ====================
greatsword:
template_id: "greatsword"
name: "Greatsword"
item_type: "weapon"
description: "A massive two-handed blade"
base_damage: 22
base_value: 100
damage_type: "physical"
crit_chance: 0.04
crit_multiplier: 2.5
required_level: 5
drop_weight: 0.7
min_rarity: "uncommon"
# ==================== AXES ====================
hatchet:
template_id: "hatchet"
name: "Hatchet"
item_type: "weapon"
description: "A small throwing axe"
base_damage: 8
base_value: 20
damage_type: "physical"
crit_chance: 0.06
crit_multiplier: 2.2
required_level: 1
drop_weight: 1.2
battle_axe:
template_id: "battle_axe"
name: "Battle Axe"
item_type: "weapon"
description: "A heavy axe designed for combat"
base_damage: 16
base_value: 60
damage_type: "physical"
crit_chance: 0.05
crit_multiplier: 2.3
required_level: 4
drop_weight: 0.9
# ==================== BLUNT WEAPONS ====================
club:
template_id: "club"
name: "Club"
item_type: "weapon"
description: "A simple wooden club"
base_damage: 7
base_value: 10
damage_type: "physical"
crit_chance: 0.04
crit_multiplier: 2.0
required_level: 1
drop_weight: 1.5
mace:
template_id: "mace"
name: "Mace"
item_type: "weapon"
description: "A flanged mace for crushing armor"
base_damage: 12
base_value: 40
damage_type: "physical"
crit_chance: 0.05
crit_multiplier: 2.0
required_level: 2
drop_weight: 1.0
# ==================== STAVES ====================
quarterstaff:
template_id: "quarterstaff"
name: "Quarterstaff"
item_type: "weapon"
description: "A simple wooden staff"
base_damage: 6
base_value: 10
damage_type: "physical"
crit_chance: 0.05
crit_multiplier: 2.0
required_level: 1
drop_weight: 1.2
wizard_staff:
template_id: "wizard_staff"
name: "Wizard Staff"
item_type: "weapon"
description: "A staff attuned to magical energy"
base_damage: 8
base_value: 45
damage_type: "physical"
crit_chance: 0.05
crit_multiplier: 2.0
required_level: 3
drop_weight: 0.8
# ==================== RANGED ====================
shortbow:
template_id: "shortbow"
name: "Shortbow"
item_type: "weapon"
description: "A compact bow for quick shots"
base_damage: 8
base_value: 25
damage_type: "physical"
crit_chance: 0.07
crit_multiplier: 2.0
required_level: 1
drop_weight: 1.1
longbow:
template_id: "longbow"
name: "Longbow"
item_type: "weapon"
description: "A powerful bow with excellent range"
base_damage: 14
base_value: 55
damage_type: "physical"
crit_chance: 0.08
crit_multiplier: 2.2
required_level: 4
drop_weight: 0.9