""" Profile and character stat management handlers. """ import logging from telegram import InlineKeyboardButton, InlineKeyboardMarkup from . import keyboards from data.world_loader import game_world logger = logging.getLogger(__name__) async def handle_profile(query, user_id: int, player: dict, data: list = None): """Display player profile with stats and level info.""" from .utils import format_stat_bar await query.answer() from bot import combat from .utils import format_stat_bar, create_progress_bar # Calculate stats xp_current = player['xp'] xp_needed = combat.xp_for_level(player['level'] + 1) xp_for_current_level = combat.xp_for_level(player['level']) xp_progress = max(0, xp_current - xp_for_current_level) xp_level_requirement = xp_needed - xp_for_current_level progress_percent = int((xp_progress / xp_level_requirement) * 100) if xp_level_requirement > 0 else 0 unspent = player.get('unspent_points', 0) # Build profile with visual bars profile_text = f"👤 {player['name']}\n" profile_text += f"━━━━━━━━━━━━━━━━━━━━\n\n" profile_text += f"Level: {player['level']}\n" # XP bar xp_bar = create_progress_bar(xp_progress, xp_level_requirement, length=10) profile_text += f"⭐ XP: {xp_bar} {progress_percent}% ({xp_current}/{xp_needed})\n" if unspent > 0: profile_text += f"💎 Unspent Points: {unspent}\n" profile_text += f"\n{format_stat_bar('HP', '❤️', player['hp'], player['max_hp'])}\n" profile_text += f"{format_stat_bar('Stamina', '⚡', player['stamina'], player['max_stamina'])}\n\n" profile_text += f"Stats:\n" profile_text += f"💪 Strength: {player['strength']}\n" profile_text += f"🏃 Agility: {player['agility']}\n" profile_text += f"💚 Endurance: {player['endurance']}\n" profile_text += f"🧠 Intellect: {player['intellect']}\n\n" profile_text += f"Combat:\n" profile_text += f"⚔️ Base Damage: {5 + player['strength'] // 2 + player['level']}\n" profile_text += f"🛡️ Flee Chance: {int((0.5 + player['agility'] / 100) * 100)}%\n" profile_text += f"💚 Stamina Regen: {1 + player['endurance'] // 10}/cycle\n\n" # Show status effects if any try: from .api_client import api_client status_effects = await api_client.get_player_status_effects(user_id) if status_effects: from bot.status_utils import get_status_details from .api_client import api_client # Check if player is in combat combat_state = await api_client.get_combat(user_id) in_combat = combat_state is not None profile_text += f"Status Effects:\n" profile_text += get_status_details(status_effects, in_combat=in_combat) + "\n\n" except: pass # Status effects not critical, skip if error location = game_world.get_location(player['location_id']) location_image = location.image_path if location else None # Add spend points button if player has unspent points keyboard_buttons = [] if unspent > 0: keyboard_buttons.append([ InlineKeyboardButton("⭐ Spend Stat Points", callback_data="spend_points_menu") ]) keyboard_buttons.append([InlineKeyboardButton("⬅️ Back", callback_data="main_menu")]) back_keyboard = InlineKeyboardMarkup(keyboard_buttons) from .handlers import send_or_edit_with_image await send_or_edit_with_image( query, text=profile_text, reply_markup=back_keyboard, image_path=location_image ) async def handle_spend_points_menu(query, user_id: int, player: dict, data: list = None): """Show menu for spending attribute points.""" await query.answer() unspent = player.get('unspent_points', 0) if unspent <= 0: await query.answer("You have no points to spend!", show_alert=False) return text = f"⭐ Spend Stat Points\n\n" text += f"Available Points: {unspent}\n\n" text += f"Current Stats:\n" text += f"❤️ Max HP: {player['max_hp']} (+10 per point)\n" text += f"⚡ Max Stamina: {player['max_stamina']} (+5 per point)\n" text += f"💪 Strength: {player['strength']} (+1 per point)\n" text += f"🏃 Agility: {player['agility']} (+1 per point)\n" text += f"💚 Endurance: {player['endurance']} (+1 per point)\n" text += f"🧠 Intellect: {player['intellect']} (+1 per point)\n\n" text += f"💡 Choose wisely! Each point matters." keyboard = keyboards.spend_points_keyboard() from .handlers import send_or_edit_with_image await send_or_edit_with_image(query, text=text, reply_markup=keyboard) async def handle_spend_point(query, user_id: int, player: dict, data: list): """Spend a stat point on a specific attribute.""" stat_name = data[1] unspent = player.get('unspent_points', 0) if unspent <= 0: await query.answer("You have no points to spend!", show_alert=False) return # Map stat names to updates stat_mapping = { 'max_hp': ('max_hp', 10, '❤️ Max HP'), 'max_stamina': ('max_stamina', 5, '⚡ Max Stamina'), 'strength': ('strength', 1, '💪 Strength'), 'agility': ('agility', 1, '🏃 Agility'), 'endurance': ('endurance', 1, '💚 Endurance'), 'intellect': ('intellect', 1, '🧠 Intellect'), } if stat_name not in stat_mapping: await query.answer("Invalid stat!", show_alert=False) return db_field, increase, display_name = stat_mapping[stat_name] new_value = player[db_field] + increase new_unspent = unspent - 1 from .api_client import api_client await api_client.update_player(user_id, { db_field: new_value, 'unspent_points': new_unspent }) # Update local player data player[db_field] = new_value player['unspent_points'] = new_unspent await query.answer(f"+{increase} {display_name}!", show_alert=False) # Refresh the spend points menu text = f"⭐ Spend Stat Points\n\n" text += f"Available Points: {new_unspent}\n\n" text += f"Current Stats:\n" text += f"❤️ Max HP: {player['max_hp']} (+10 per point)\n" text += f"⚡ Max Stamina: {player['max_stamina']} (+5 per point)\n" text += f"💪 Strength: {player['strength']} (+1 per point)\n" text += f"🏃 Agility: {player['agility']} (+1 per point)\n" text += f"💚 Endurance: {player['endurance']} (+1 per point)\n" text += f"🧠 Intellect: {player['intellect']} (+1 per point)\n\n" text += f"💡 Choose wisely! Each point matters." keyboard = keyboards.spend_points_keyboard() from .handlers import send_or_edit_with_image await send_or_edit_with_image(query, text=text, reply_markup=keyboard)