feat(backend): Integrate Derived Stats into combat, loot, and crafting mechanics

This commit is contained in:
Joan
2026-02-25 10:05:14 +01:00
parent 185781d168
commit fd94387d54
10 changed files with 727 additions and 101 deletions

View File

@@ -24,13 +24,15 @@ logger = logging.getLogger(__name__)
LOCATIONS = None
ITEMS_MANAGER = None
WORLD = None
redis_manager = None
def init_router_dependencies(locations, items_manager, world):
def init_router_dependencies(locations, items_manager, world, redis_mgr=None):
"""Initialize router with game data dependencies"""
global LOCATIONS, ITEMS_MANAGER, WORLD
global LOCATIONS, ITEMS_MANAGER, WORLD, redis_manager
LOCATIONS = locations
ITEMS_MANAGER = items_manager
WORLD = world
redis_manager = redis_mgr
router = APIRouter(tags=["equipment"])
@@ -62,6 +64,25 @@ async def equip_item(
if not item_def.equippable or not item_def.slot:
raise HTTPException(status_code=400, detail="This item cannot be equipped")
# Check equipment requirements (level + stat gates)
if item_def.equip_requirements:
player = await db.get_player_by_id(player_id) if 'level' not in current_user else current_user
req_level = item_def.equip_requirements.get('level', 0)
if player.get('level', 1) < req_level:
raise HTTPException(
status_code=400,
detail=get_game_message('equip_level_required', locale, level=req_level)
)
for stat_name in ['strength', 'agility', 'endurance', 'intellect']:
req_value = item_def.equip_requirements.get(stat_name, 0)
if req_value > 0 and player.get(stat_name, 0) < req_value:
raise HTTPException(
status_code=400,
detail=get_game_message('equip_stat_required', locale, stat=stat_name.capitalize(), value=req_value)
)
# Check if slot is valid
valid_slots = ['head', 'torso', 'legs', 'feet', 'weapon', 'offhand', 'backpack']
if item_def.slot not in valid_slots:
@@ -113,6 +134,10 @@ async def equip_item(
else:
message = get_game_message('equipped', locale, item=get_locale_string(item_def.name, locale))
# Invalidate cached derived stats (equipment changed)
from ..services.stats import invalidate_stats_cache
await invalidate_stats_cache(player_id, redis_manager)
return {
"success": True,
"message": message,
@@ -192,6 +217,10 @@ async def unequip_item(
await db.drop_item(player_id, inv_item['item_id'], 1, current_user['location_id'])
await db.remove_from_inventory(player_id, inv_item['item_id'], 1)
# Invalidate cached derived stats
from ..services.stats import invalidate_stats_cache
await invalidate_stats_cache(player_id, redis_manager)
return {
"success": True,
"message": get_game_message('unequip_dropped', locale, item=get_locale_string(item_def.name, locale)),
@@ -202,6 +231,10 @@ async def unequip_item(
await db.unequip_item(player_id, unequip_req.slot)
await db.update_inventory_item(equipped['item_id'], is_equipped=False)
# Invalidate cached derived stats
from ..services.stats import invalidate_stats_cache
await invalidate_stats_cache(player_id, redis_manager)
return {
"success": True,
"message": get_game_message('unequipped', locale, item=get_locale_string(item_def.name, locale)),