UI/UX: Improve visual clarity and consistency
- Align status bars with label padding (HP, Stamina, XP) - Add clear combat turn indicators (YOUR TURN / ENEMY TURN) - Display HP/Stamina bars in inventory menu and usage - Add consistent separators between sections - Improve feedback for item usage with visible stat changes Files modified: - bot/utils.py: Added label_width parameter to format_stat_bar() - bot/combat.py: Turn headers and separators - bot/inventory_handlers.py: HP/Stamina display - bot/action_handlers.py: Separator placement fix See docs/development/UI_UX_IMPROVEMENTS.md for details
This commit is contained in:
@@ -12,21 +12,22 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
async def handle_inventory_menu(query, user_id: int, player: dict, data: list = None):
|
||||
"""Display player inventory with item management options."""
|
||||
from .utils import format_stat_bar
|
||||
await query.answer()
|
||||
inventory_items = await database.get_inventory(user_id)
|
||||
|
||||
# Calculate inventory summary
|
||||
inventory_items = await database.get_inventory(user_id)
|
||||
current_weight, current_volume = logic.calculate_inventory_load(inventory_items)
|
||||
max_weight, max_volume = logic.get_player_capacity(inventory_items, player)
|
||||
|
||||
text = "<b>🎒 Your Inventory:</b>\n"
|
||||
text += f"{format_stat_bar('HP', '❤️', player['hp'], player['max_hp'])}\n"
|
||||
text += f"{format_stat_bar('Stamina', '⚡', player['stamina'], player['max_stamina'])}\n"
|
||||
text += f"📊 Weight: {current_weight}/{max_weight} kg\n"
|
||||
text += f"📦 Volume: {current_volume}/{max_volume} vol\n\n"
|
||||
text += f"📦 Volume: {current_volume}/{max_volume} vol\n"
|
||||
|
||||
if not inventory_items:
|
||||
text += "It's empty."
|
||||
text += "\n<i>Your inventory is empty.</i>"
|
||||
|
||||
# Keep current location image for context
|
||||
location = game_world.get_location(player['location_id'])
|
||||
location_image = location.image_path if location else None
|
||||
|
||||
@@ -92,6 +93,8 @@ async def handle_inventory_item(query, user_id: int, player: dict, data: list):
|
||||
|
||||
async def handle_inventory_use(query, user_id: int, player: dict, data: list):
|
||||
"""Use a consumable item from inventory."""
|
||||
from .utils import format_stat_bar
|
||||
|
||||
item_db_id = int(data[1])
|
||||
item = await database.get_inventory_item(item_db_id)
|
||||
|
||||
@@ -127,40 +130,42 @@ async def handle_inventory_use(query, user_id: int, player: dict, data: list):
|
||||
actual_gain = new_stamina - player['stamina']
|
||||
updates['stamina'] = new_stamina
|
||||
if actual_gain > 0:
|
||||
result_parts.append(f"⚡️ Stamina: +{actual_gain}")
|
||||
result_parts.append(f"⚡ Stamina: +{actual_gain}")
|
||||
else:
|
||||
result_parts.append(f"⚡️ Stamina: Already at maximum!")
|
||||
result_parts.append(f"⚡ Stamina: Already at maximum!")
|
||||
|
||||
if updates:
|
||||
await database.update_player(user_id, updates)
|
||||
|
||||
# Refresh player data to get updated stats
|
||||
player = await database.get_player(user_id)
|
||||
|
||||
# Remove one item from inventory
|
||||
if item['quantity'] > 1:
|
||||
await database.update_inventory_item(item['id'], quantity=item['quantity'] - 1)
|
||||
else:
|
||||
await database.remove_item_from_inventory(item['id'])
|
||||
|
||||
# Build result message
|
||||
emoji = item_def.get('emoji', '❔')
|
||||
result_text = f"<b>Used {emoji} {item_def.get('name')}</b>\n\n"
|
||||
if result_parts:
|
||||
result_text += "\n".join(result_parts)
|
||||
else:
|
||||
result_text += "No effect."
|
||||
|
||||
# Show updated inventory
|
||||
inventory_items = await database.get_inventory(user_id)
|
||||
current_weight, current_volume = logic.calculate_inventory_load(inventory_items)
|
||||
max_weight, max_volume = logic.get_player_capacity(inventory_items, player)
|
||||
|
||||
# Build status section with HP/Stamina bars
|
||||
text = "<b>🎒 Your Inventory:</b>\n"
|
||||
text += f"{format_stat_bar('HP', '❤️', player['hp'], player['max_hp'])}\n"
|
||||
text += f"{format_stat_bar('Stamina', '⚡', player['stamina'], player['max_stamina'])}\n"
|
||||
text += f"📊 Weight: {current_weight}/{max_weight} kg\n"
|
||||
text += f"📦 Volume: {current_volume}/{max_volume} vol\n\n"
|
||||
text += f"📦 Volume: {current_volume}/{max_volume} vol\n"
|
||||
text += "━━━━━━━━━━━━━━━━━━━━\n"
|
||||
|
||||
if not inventory_items:
|
||||
text += "It's empty."
|
||||
# Build result message
|
||||
emoji = item_def.get('emoji', '❔')
|
||||
text += f"<b>✨ Used {emoji} {item_def.get('name')}</b>\n"
|
||||
if result_parts:
|
||||
text += "\n".join(result_parts)
|
||||
else:
|
||||
text += f"{result_text}"
|
||||
text += "No effect."
|
||||
|
||||
location = game_world.get_location(player['location_id'])
|
||||
location_image = location.image_path if location else None
|
||||
|
||||
Reference in New Issue
Block a user