Files
echoes-of-the-ash/bot/corpse_handlers.py
Joan 861f3b8a36 Add visual progress bars and refactor handler modules
- Implement visual HP/Stamina/XP bars using Unicode characters (██░)
- Refactor handlers.py (1308 → 377 lines) into specialized modules:
  * action_handlers.py - World interaction and status display
  * inventory_handlers.py - Inventory management
  * combat_handlers.py - Combat actions
  * profile_handlers.py - Character stats with visual bars
  * corpse_handlers.py - Looting system
  * pickup_handlers.py - Item collection
- Add utility functions: create_progress_bar(), format_stat_bar()
- Organize all documentation into docs/ structure
- Create comprehensive documentation index with navigation
- Add UI examples showing before/after visual improvements
2025-10-19 00:23:44 +02:00

235 lines
8.0 KiB
Python

"""
Corpse looting handlers (player and NPC corpses).
"""
import logging
import json
import random
from . import database, keyboards, logic
from data.world_loader import game_world
from data.items import ITEMS
logger = logging.getLogger(__name__)
async def handle_loot_player_corpse(query, user_id: int, player: dict, data: list):
"""Show player corpse loot menu."""
corpse_id = int(data[1])
corpse = await database.get_player_corpse(corpse_id)
if not corpse:
await query.answer("Corpse not found.", show_alert=False)
return
items = json.loads(corpse['items'])
keyboard = keyboards.player_corpse_loot_keyboard(corpse_id, items)
location = game_world.get_location(player['location_id'])
image_path = location.image_path if location else None
await query.answer()
text = f"🎒 {corpse['player_name']}'s bag\n\nYou find the remains of another survivor..."
from .handlers import send_or_edit_with_image
await send_or_edit_with_image(
query,
text=text,
reply_markup=keyboard,
image_path=image_path
)
async def handle_take_corpse_item(query, user_id: int, player: dict, data: list):
"""Take an item from a player corpse."""
corpse_id = int(data[1])
item_index = int(data[2])
corpse = await database.get_player_corpse(corpse_id)
if not corpse:
await query.answer("Corpse not found.", show_alert=False)
return
items = json.loads(corpse['items'])
if item_index >= len(items):
await query.answer("Item not found.", show_alert=False)
return
item_data = items[item_index]
item_def = ITEMS.get(item_data['item_id'], {})
# Check inventory capacity
can_add, reason = await logic.can_add_item_to_inventory(
user_id, item_data['item_id'], item_data['quantity']
)
if not can_add:
await query.answer(reason, show_alert=False)
return
# Add to inventory
await database.add_item_to_inventory(user_id, item_data['item_id'], item_data['quantity'])
# Remove from corpse
items.pop(item_index)
if items:
await database.update_player_corpse(corpse_id, json.dumps(items))
keyboard = keyboards.player_corpse_loot_keyboard(corpse_id, items)
location = game_world.get_location(player['location_id'])
image_path = location.image_path if location else None
await query.answer(f"Took {item_def.get('name', 'Unknown')}.", show_alert=False)
text = f"🎒 {corpse['player_name']}'s bag"
from .handlers import send_or_edit_with_image
await send_or_edit_with_image(
query,
text=text,
reply_markup=keyboard,
image_path=image_path
)
else:
# Bag is empty, remove it
await database.remove_player_corpse(corpse_id)
await query.answer(
f"Took {item_def.get('name', 'Unknown')}. The bag is now empty.",
show_alert=False
)
location = game_world.get_location(player['location_id'])
dropped_items = await database.get_dropped_items_in_location(player['location_id'])
wandering_enemies = await database.get_wandering_enemies_in_location(player['location_id'])
keyboard = await keyboards.inspect_keyboard(player['location_id'], dropped_items, wandering_enemies)
from .handlers import send_or_edit_with_image
await send_or_edit_with_image(
query,
text="You scan the area. You notice...",
reply_markup=keyboard,
image_path=location.image_path if location else None
)
async def handle_scavenge_npc_corpse(query, user_id: int, player: dict, data: list):
"""Show NPC corpse scavenging menu."""
corpse_id = int(data[1])
corpse = await database.get_npc_corpse(corpse_id)
if not corpse:
await query.answer("Corpse not found.", show_alert=False)
return
from data.npcs import NPCS
npc_def = NPCS.get(corpse['npc_id'])
loot_items = json.loads(corpse['loot_remaining'])
keyboard = keyboards.npc_corpse_scavenge_keyboard(corpse_id, loot_items)
location = game_world.get_location(player['location_id'])
image_path = location.image_path if location else None
await query.answer()
text = f"🔪 {npc_def.emoji} {npc_def.name} Corpse\n\n{npc_def.description}"
from .handlers import send_or_edit_with_image
await send_or_edit_with_image(
query,
text=text,
reply_markup=keyboard,
image_path=image_path
)
async def handle_scavenge_corpse_item(query, user_id: int, player: dict, data: list):
"""Scavenge a specific item from an NPC corpse."""
corpse_id = int(data[1])
loot_index = int(data[2])
corpse = await database.get_npc_corpse(corpse_id)
if not corpse:
await query.answer("Corpse not found.", show_alert=False)
return
loot_items = json.loads(corpse['loot_remaining'])
if loot_index >= len(loot_items):
await query.answer("Nothing to scavenge here.", show_alert=False)
return
loot_data = loot_items[loot_index]
required_tool = loot_data.get('required_tool')
# Check if player has required tool
if required_tool:
inventory_items = await database.get_inventory(user_id)
has_tool = any(item['item_id'] == required_tool for item in inventory_items)
if not has_tool:
tool_def = ITEMS.get(required_tool, {})
await query.answer(
f"You need a {tool_def.get('name', 'tool')} to scavenge this.",
show_alert=False
)
return
# Determine quantity
quantity = random.randint(loot_data['quantity_min'], loot_data['quantity_max'])
item_def = ITEMS.get(loot_data['item_id'], {})
# Check inventory capacity
can_add, reason = await logic.can_add_item_to_inventory(
user_id, loot_data['item_id'], quantity
)
if not can_add:
await query.answer(reason, show_alert=False)
return
# Add to inventory
await database.add_item_to_inventory(user_id, loot_data['item_id'], quantity)
# Remove from corpse
loot_items.pop(loot_index)
if loot_items:
await database.update_npc_corpse(corpse_id, json.dumps(loot_items))
keyboard = keyboards.npc_corpse_scavenge_keyboard(corpse_id, loot_items)
location = game_world.get_location(player['location_id'])
image_path = location.image_path if location else None
await query.answer(
f"Scavenged {quantity}x {item_def.get('name', 'Unknown')}.",
show_alert=False
)
from data.npcs import NPCS
npc_def = NPCS.get(corpse['npc_id'])
text = f"🔪 {npc_def.emoji} {npc_def.name} Corpse"
from .handlers import send_or_edit_with_image
await send_or_edit_with_image(
query,
text=text,
reply_markup=keyboard,
image_path=image_path
)
else:
# Nothing left, remove corpse
await database.remove_npc_corpse(corpse_id)
await query.answer(
f"Scavenged {quantity}x {item_def.get('name', 'Unknown')}. Nothing left on the corpse.",
show_alert=False
)
location = game_world.get_location(player['location_id'])
dropped_items = await database.get_dropped_items_in_location(player['location_id'])
wandering_enemies = await database.get_wandering_enemies_in_location(player['location_id'])
keyboard = await keyboards.inspect_keyboard(player['location_id'], dropped_items, wandering_enemies)
from .handlers import send_or_edit_with_image
await send_or_edit_with_image(
query,
text="You scan the area. You notice...",
reply_markup=keyboard,
image_path=location.image_path if location else None
)