170 lines
6.8 KiB
Python
170 lines
6.8 KiB
Python
"""
|
|
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"👤 <b>{player['name']}</b>\n"
|
|
profile_text += f"━━━━━━━━━━━━━━━━━━━━\n\n"
|
|
profile_text += f"<b>Level:</b> {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"💎 <b>Unspent Points:</b> {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"<b>Stats:</b>\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"<b>Combat:</b>\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"<b>Status Effects:</b>\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"⭐ <b>Spend Stat Points</b>\n\n"
|
|
text += f"Available Points: <b>{unspent}</b>\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"⭐ <b>Spend Stat Points</b>\n\n"
|
|
text += f"Available Points: <b>{new_unspent}</b>\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)
|