Added trading and quests, checkpoint push
This commit is contained in:
@@ -819,7 +819,83 @@ async def process_status_effects(manager=None):
|
||||
logger.error(f"❌ Error in status effects task: {e}", exc_info=True)
|
||||
await asyncio.sleep(10)
|
||||
|
||||
# ============================================================================
|
||||
# BACKGROUND TASK: MERCHANT RESTOCK
|
||||
# ============================================================================
|
||||
|
||||
async def restock_merchants(manager=None, npcs_data=None):
|
||||
"""Periodically restocks merchant inventory."""
|
||||
logger.info("💰 Merchant Restock task started")
|
||||
|
||||
# If no data provided, we can't restock effectively without doing I/O which we want to avoid.
|
||||
if not npcs_data:
|
||||
logger.warning("⚠️ No NPC data provided to restock task. Merchants will not restock.")
|
||||
return
|
||||
|
||||
while True:
|
||||
try:
|
||||
# Use injected data
|
||||
static_npcs = npcs_data
|
||||
|
||||
start_time = time.time()
|
||||
restocked_count = 0
|
||||
|
||||
for npc_id, npc_def in static_npcs.items():
|
||||
trade_cfg = npc_def.get('trade', {})
|
||||
if not trade_cfg.get('enabled'):
|
||||
continue
|
||||
|
||||
stock_config = trade_cfg.get('stock', [])
|
||||
|
||||
for item_cfg in stock_config:
|
||||
if item_cfg.get('infinite'):
|
||||
continue
|
||||
|
||||
item_id = item_cfg['item_id']
|
||||
max_stock = item_cfg.get('max_stock', 10)
|
||||
restock_rate = item_cfg.get('restock_rate', 1)
|
||||
|
||||
# Get current stock
|
||||
current_item = await db.get_merchant_stock_item(npc_id, item_id)
|
||||
|
||||
now = time.time()
|
||||
|
||||
if not current_item:
|
||||
# Initialize if missing
|
||||
# If we assume 'restocked' means it should exist.
|
||||
await db.update_merchant_stock(
|
||||
npc_id=npc_id,
|
||||
item_id=item_id,
|
||||
quantity=restock_rate,
|
||||
update_restock_time=True
|
||||
)
|
||||
restocked_count += 1
|
||||
continue
|
||||
|
||||
# Check timer (1 hour default)
|
||||
last_restock = current_item.get('last_restock_at', 0)
|
||||
if now - last_restock > 3600: # 1 hour
|
||||
current_qty = current_item['quantity']
|
||||
if current_qty < max_stock:
|
||||
new_qty = min(max_stock, current_qty + restock_rate)
|
||||
|
||||
await db.update_merchant_stock(
|
||||
npc_id=npc_id,
|
||||
item_id=item_id,
|
||||
quantity=new_qty,
|
||||
update_restock_time=True
|
||||
)
|
||||
restocked_count += 1
|
||||
|
||||
if restocked_count > 0:
|
||||
elapsed = time.time() - start_time
|
||||
logger.info(f"Restocked {restocked_count} items in {elapsed:.2f}s")
|
||||
|
||||
await asyncio.sleep(600) # Check every 10 minutes
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error in merchant restock task: {e}", exc_info=True)
|
||||
await asyncio.sleep(60)
|
||||
# ============================================================================
|
||||
# TASK STARTUP FUNCTION
|
||||
# ============================================================================
|
||||
@@ -868,7 +944,7 @@ def release_background_tasks_lock():
|
||||
_lock_file_handle = None
|
||||
|
||||
|
||||
async def start_background_tasks(manager=None, world_locations=None):
|
||||
async def start_background_tasks(manager=None, world_locations=None, npcs_data=None):
|
||||
"""
|
||||
Start all background tasks.
|
||||
Called when the API starts up.
|
||||
@@ -877,6 +953,7 @@ async def start_background_tasks(manager=None, world_locations=None):
|
||||
Args:
|
||||
manager: WebSocket ConnectionManager for broadcasting events
|
||||
world_locations: Dict of Location objects for interactable mapping
|
||||
npcs_data: Dict of static NPC definitions
|
||||
"""
|
||||
# Try to acquire lock - only one worker will succeed
|
||||
if not acquire_background_tasks_lock():
|
||||
@@ -894,6 +971,7 @@ async def start_background_tasks(manager=None, world_locations=None):
|
||||
asyncio.create_task(check_pvp_combat_timers(manager)),
|
||||
asyncio.create_task(decay_corpses(manager)),
|
||||
asyncio.create_task(process_status_effects(manager)),
|
||||
asyncio.create_task(restock_merchants(manager, npcs_data)),
|
||||
# Note: Interactable cooldowns are handled client-side with server validation
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user