Pre-menu-integration snapshot: combat, crafting, status effects, gamedata updates

This commit is contained in:
Joan
2026-03-11 12:43:23 +01:00
parent d5afd28eb9
commit a8dc8211d5
36 changed files with 1724 additions and 404 deletions

View File

@@ -36,7 +36,30 @@ async def calculate_derived_stats(character_id: int, redis_mgr=None) -> Dict[str
if not char:
return _empty_stats()
equipment = await db.get_all_equipment(character_id)
raw_equipment = await db.get_all_equipment(character_id)
enriched_equipment = {}
for slot, item_data in raw_equipment.items():
if not item_data or not item_data.get('item_id'):
continue
inv_item = await db.get_inventory_item_by_id(item_data['item_id'])
if not inv_item:
continue
enriched_item = {
'item_id': inv_item['item_id'], # String ID
'inventory_id': item_data['item_id']
}
unique_item_id = inv_item.get('unique_item_id')
if unique_item_id:
unique_item = await db.get_unique_item(unique_item_id)
if unique_item and unique_item.get('unique_stats'):
enriched_item['unique_stats'] = unique_item['unique_stats']
enriched_equipment[slot] = enriched_item
effects = await db.get_player_effects(character_id)
# 3. Fetch owned perks
@@ -44,7 +67,7 @@ async def calculate_derived_stats(character_id: int, redis_mgr=None) -> Dict[str
owned_perk_ids = [row['perk_id'] for row in owned_perks]
# 4. Compute derived stats
stats = _compute_stats(char, equipment, effects, owned_perk_ids)
stats = _compute_stats(char, enriched_equipment, effects, owned_perk_ids)
# 5. Cache in Redis (5 min TTL)
if redis_mgr and redis_mgr.redis_client:
@@ -95,21 +118,29 @@ def _compute_stats(char: Dict[str, Any], equipment: Dict[str, Any], effects: Lis
if not item_data or not item_data.get('item_id'):
continue
# Get inventory item to find the item definition
inv_item_sync = item_data # equipment dict already has item_id reference
item_def = ITEMS_MANAGER.get_item(inv_item_sync.get('item_id', ''))
item_id_str = item_data.get('item_id', '')
item_def = ITEMS_MANAGER.get_item(item_id_str)
# Try to get item_id from the inventory item if the direct lookup failed
if not item_def:
continue
# Merge base stats and unique stats
merged_stats = {}
if item_def.stats:
total_armor += item_def.stats.get('armor', 0)
weapon_crit += item_def.stats.get('crit_chance', 0)
merged_stats.update(item_def.stats)
if item_data.get('unique_stats'):
merged_stats.update(item_data['unique_stats'])
if merged_stats:
total_armor += merged_stats.get('armor', 0)
weapon_crit += merged_stats.get('crit_chance', 0)
max_hp += merged_stats.get('max_hp', 0)
max_stamina += merged_stats.get('max_stamina', 0)
carry_weight += merged_stats.get('weight_capacity', 0)
if slot == 'weapon':
weapon_damage_min = item_def.stats.get('damage_min', 0)
weapon_damage_max = item_def.stats.get('damage_max', 0)
weapon_damage_min = merged_stats.get('damage_min', 0)
weapon_damage_max = merged_stats.get('damage_max', 0)
if slot == 'offhand':
has_shield = True
@@ -218,6 +249,28 @@ async def invalidate_stats_cache(character_id: int, redis_mgr=None):
await redis_mgr.redis_client.delete(f"stats:{character_id}")
except Exception:
pass
# Sync derived max_hp and max_stamina to the database characters table
try:
derived = await calculate_derived_stats(character_id, redis_mgr)
char = await db.get_player_by_id(character_id)
if char:
new_max_hp = derived.get('max_hp', char['max_hp'])
new_max_stamina = derived.get('max_stamina', char['max_stamina'])
if new_max_hp != char['max_hp'] or new_max_stamina != char['max_stamina']:
new_hp = min(char['hp'], new_max_hp)
new_stamina = min(char['stamina'], new_max_stamina)
await db.update_player(
character_id,
max_hp=new_max_hp,
max_stamina=new_max_stamina,
hp=new_hp,
stamina=new_stamina
)
except Exception as e:
import logging
logging.getLogger(__name__).warning(f"Failed to sync derived stats to DB for {character_id}: {e}")
def get_flee_chance(flee_chance_base: float, enemy_level: int) -> float: