Pre-menu-integration snapshot: combat, crafting, status effects, gamedata updates
This commit is contained in:
101
api/services/status_effects.py
Normal file
101
api/services/status_effects.py
Normal file
@@ -0,0 +1,101 @@
|
||||
"""
|
||||
Status Effects Manager.
|
||||
Loads status effect definitions from gamedata/status_effects.json.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
|
||||
class StatusEffect:
|
||||
"""Represents a status effect definition."""
|
||||
def __init__(self, effect_id: str, data: Dict[str, Any]):
|
||||
self.id = effect_id
|
||||
self.icon = data.get('icon', '⚡')
|
||||
self.name = data.get('name', effect_id.capitalize())
|
||||
self.description = data.get('description', effect_id.capitalize())
|
||||
self.type = data.get('type', 'debuff')
|
||||
|
||||
|
||||
class StatusEffectsManager:
|
||||
"""Manages status effect definitions loaded from JSON."""
|
||||
|
||||
def __init__(self, gamedata_path: str = "./gamedata"):
|
||||
self.effects: Dict[str, StatusEffect] = {}
|
||||
filepath = os.path.join(gamedata_path, 'status_effects.json')
|
||||
self._load(filepath)
|
||||
|
||||
def _load(self, filepath: str):
|
||||
"""Load status effects from a JSON file."""
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
for effect_id, effect_data in data.get('effects', {}).items():
|
||||
self.effects[effect_id] = StatusEffect(effect_id, effect_data)
|
||||
print(f"✨ Loaded {len(self.effects)} status effects")
|
||||
except FileNotFoundError:
|
||||
print("⚠️ status_effects.json not found")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error loading status_effects.json: {e}")
|
||||
|
||||
def get_effect(self, effect_id: str) -> Optional[StatusEffect]:
|
||||
"""Get a status effect by its ID."""
|
||||
return self.effects.get(effect_id)
|
||||
|
||||
def get_effect_info(self, effect_id: str) -> Dict[str, Any]:
|
||||
"""Get effect info dict for API responses. Returns a fallback if not found."""
|
||||
effect = self.effects.get(effect_id)
|
||||
if effect:
|
||||
return {
|
||||
'name': effect.name,
|
||||
'icon': effect.icon,
|
||||
'description': effect.description,
|
||||
'type': effect.type,
|
||||
}
|
||||
# Fallback for unknown effects
|
||||
return {
|
||||
'name': {'en': effect_id.capitalize(), 'es': effect_id.capitalize()},
|
||||
'icon': '⚡',
|
||||
'description': {'en': effect_id.capitalize(), 'es': effect_id.capitalize()},
|
||||
'type': 'debuff',
|
||||
}
|
||||
|
||||
def resolve_player_effect(self, effect_name: str, effect_icon: str, source: str, skills_manager=None, in_combat: bool = True) -> Dict[str, Any]:
|
||||
"""
|
||||
Resolve translated name and description for a player effect.
|
||||
Tries skill source first, then status_effects.json, then fallback.
|
||||
"""
|
||||
translated_name = effect_name
|
||||
translated_desc = ''
|
||||
|
||||
# 1. Try to get from skill source (e.g., "skill:fortify")
|
||||
if source.startswith('skill:') and skills_manager:
|
||||
skill_id = source.split(':', 1)[1]
|
||||
skill_def = skills_manager.get_skill(skill_id)
|
||||
if skill_def:
|
||||
translated_name = skill_def.name
|
||||
translated_desc = skill_def.description
|
||||
|
||||
# 2. Try to get from status_effects.json by lowercased effect name
|
||||
if not translated_desc:
|
||||
effect_key = effect_name.lower()
|
||||
effect = self.effects.get(effect_key)
|
||||
if effect:
|
||||
translated_name = effect.name
|
||||
translated_desc = effect.description
|
||||
|
||||
# 3. Fallback: wrap the raw name as a translatable dict
|
||||
if not translated_desc:
|
||||
translated_desc = {'en': effect_name, 'es': effect_name}
|
||||
if isinstance(translated_name, str):
|
||||
translated_name = {'en': translated_name, 'es': translated_name}
|
||||
|
||||
return {
|
||||
'name': translated_name,
|
||||
'icon': effect_icon or '⚡',
|
||||
'description': translated_desc,
|
||||
}
|
||||
|
||||
|
||||
# Module-level singleton
|
||||
status_effects_manager = StatusEffectsManager()
|
||||
Reference in New Issue
Block a user