feat(api): implement combat loot integration with hybrid static/procedural system

Add CombatLootService that orchestrates loot generation from combat,
supporting both static item drops (consumables, materials) and procedural
equipment generation (weapons, armor with affixes).

Key changes:
- Extend LootEntry model with LootType enum (STATIC/PROCEDURAL)
- Create StaticItemLoader service for consumables/materials from YAML
- Create CombatLootService with full rarity formula incorporating:
  - Party average level
  - Enemy difficulty tier (EASY: +0%, MEDIUM: +5%, HARD: +15%, BOSS: +30%)
  - Character luck stat
  - Per-entry rarity bonus
- Integrate with CombatService._calculate_rewards() for automatic loot gen
- Add boss guaranteed drops via generate_boss_loot()

New enemy variants (goblin family proof-of-concept):
- goblin_scout (Easy) - static drops only
- goblin_warrior (Medium) - static + procedural weapon drops
- goblin_chieftain (Hard) - static + procedural weapon/armor drops

Static items added:
- consumables.yaml: health/mana potions, elixirs, food
- materials.yaml: trophy items, crafting materials

Tests: 59 new tests across 3 test files (all passing)
This commit is contained in:
2025-11-27 00:01:17 -06:00
parent a38906b445
commit fdd48034e4
14 changed files with 2257 additions and 26 deletions

View File

@@ -1757,37 +1757,69 @@ base_damage = attacker_stats.spell_power + ability_base_power # Magical
---
### Future Work: Combat Loot Integration
### Task 2.7: Combat Loot Integration ✅ COMPLETE
**Status:** Planned for future phase
**Status:** Complete
The ItemGenerator is ready for integration with combat loot drops. Future implementation will:
Integrated the ItemGenerator with combat loot drops via a hybrid loot system supporting both static and procedural drops.
**1. Update Enemy Loot Tables** - Add procedural generation options:
**Implementation Summary:**
**1. Extended LootEntry Model** (`app/models/enemy.py`):
```yaml
# Example enhanced enemy loot entry
# New hybrid loot table format
loot_table:
- type: "static"
- loot_type: "static"
item_id: "health_potion_small"
drop_chance: 0.5
- type: "generated"
- loot_type: "procedural"
item_type: "weapon"
rarity_range: ["rare", "epic"]
rarity_bonus: 0.10
drop_chance: 0.1
```
**2. Integrate with CombatService._calculate_rewards()** - Use ItemGenerator for loot rolls
**2. Created CombatLootService** (`app/services/combat_loot_service.py`):
- Orchestrates loot generation from combat encounters
- Combines StaticItemLoader (consumables) + ItemGenerator (equipment)
- Full rarity formula: `effective_luck = base_luck + (entry_bonus + difficulty_bonus + loot_bonus) * 20`
**3. Boss Guaranteed Drops** - Higher-tier enemies guarantee better rarity
**3. Created StaticItemLoader** (`app/services/static_item_loader.py`):
- Loads predefined items from `app/data/static_items/` YAML files
- Supports consumables, materials, and quest items
**4. Luck Stat Integration** - Player luck affects all loot rolls
**4. Integrated with CombatService._calculate_rewards()**:
- Builds `LootContext` from encounter (party level, luck, difficulty)
- Calls `CombatLootService.generate_loot_from_enemy()` for each defeated enemy
- Boss enemies get guaranteed equipment drops via `generate_boss_loot()`
**Implementation Notes:**
- Current enemy loot tables use `item_id` references (static items only)
- ItemGenerator provides `generate_loot_drop(character_level, luck_stat)` method
- Generated items must be stored as full objects (not IDs) in character inventory
- Consider adding `LootService` wrapper for consistent loot generation across all sources
**5. Difficulty Rarity Bonuses:**
- EASY: +0% | MEDIUM: +5% | HARD: +15% | BOSS: +30%
**6. Enemy Variants Created** (proof-of-concept):
- `goblin_scout.yaml` (Easy) - static drops only
- `goblin_warrior.yaml` (Medium) - static + 8% procedural weapon
- `goblin_chieftain.yaml` (Hard) - static + 25% weapon, 15% armor
**Files Created:**
- `app/services/combat_loot_service.py`
- `app/services/static_item_loader.py`
- `app/data/static_items/consumables.yaml`
- `app/data/static_items/materials.yaml`
- `app/data/enemies/goblin_scout.yaml`
- `app/data/enemies/goblin_warrior.yaml`
- `app/data/enemies/goblin_chieftain.yaml`
- `tests/test_loot_entry.py` (16 tests)
- `tests/test_static_item_loader.py` (19 tests)
- `tests/test_combat_loot_service.py` (24 tests)
**Checklist:**
- [x] LootType enum and extended LootEntry (backward compatible)
- [x] StaticItemLoader service for consumables/materials
- [x] CombatLootService with full rarity formula
- [x] CombatService integration with `_build_loot_context()`
- [x] Static items YAML files (consumables, materials)
- [x] Goblin variant YAML files (scout, warrior, chieftain)
- [x] Unit tests (59 new tests passing)
---