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:
@@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user