- Standardize all handlers to signature: (query, user_id, player, data=None) - Replace 125-line if/elif chain with HANDLER_MAP dictionary - Reduce router code by 90 lines (72% reduction) - Add HANDLER_MAP registry for cleaner organization - Enable future auto-discovery and decorator patterns - Maintain full backward compatibility - Document changes in HANDLER_REFACTORING_V2.md Benefits: - O(1) handler lookup vs O(n) if/elif chain - Add new handlers by just updating the map - Consistent signature makes code easier to understand - Opens doors for middleware and hooks
165 lines
6.0 KiB
Python
165 lines
6.0 KiB
Python
"""
|
|
Combat-related action handlers.
|
|
"""
|
|
import logging
|
|
from . import database, keyboards
|
|
from .utils import format_stat_bar
|
|
from data.world_loader import game_world
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def handle_combat_attack(query, user_id: int, player: dict, data: list = None):
|
|
"""Handle player attack action in combat."""
|
|
from bot import combat
|
|
await query.answer()
|
|
|
|
message, npc_died, turn_ended = await combat.player_attack(user_id)
|
|
|
|
if npc_died:
|
|
# Combat ended - return to main menu
|
|
location = game_world.get_location(player['location_id'])
|
|
location_image = location.image_path if location else None
|
|
|
|
from .handlers import send_or_edit_with_image
|
|
await send_or_edit_with_image(
|
|
query,
|
|
text=message,
|
|
reply_markup=keyboards.main_menu_keyboard(),
|
|
image_path=location_image
|
|
)
|
|
elif turn_ended:
|
|
# NPC's turn - auto-attack
|
|
npc_message, player_died = await combat.npc_attack(user_id)
|
|
message += "\n\n" + npc_message
|
|
|
|
if player_died:
|
|
from .handlers import send_or_edit_with_image
|
|
await send_or_edit_with_image(query, text=message, reply_markup=None)
|
|
else:
|
|
combat_data = await database.get_combat(user_id)
|
|
if combat_data:
|
|
from data.npcs import NPCS
|
|
npc_def = NPCS.get(combat_data['npc_id'])
|
|
keyboard = await keyboards.combat_keyboard(user_id)
|
|
|
|
from .handlers import send_or_edit_with_image
|
|
await send_or_edit_with_image(
|
|
query,
|
|
text=message,
|
|
reply_markup=keyboard,
|
|
image_path=npc_def.image_url if npc_def else None
|
|
)
|
|
else:
|
|
await query.answer(message, show_alert=False)
|
|
|
|
|
|
async def handle_combat_flee(query, user_id: int, player: dict, data: list = None):
|
|
"""Handle flee attempt from combat."""
|
|
from bot import combat
|
|
await query.answer()
|
|
|
|
message, fled, turn_ended = await combat.flee_attempt(user_id)
|
|
|
|
if fled:
|
|
# Successfully fled - return to main menu
|
|
location = game_world.get_location(player['location_id'])
|
|
location_image = location.image_path if location else None
|
|
|
|
from .handlers import send_or_edit_with_image
|
|
await send_or_edit_with_image(
|
|
query,
|
|
text=message,
|
|
reply_markup=keyboards.main_menu_keyboard(),
|
|
image_path=location_image
|
|
)
|
|
elif turn_ended:
|
|
# Failed to flee - NPC attacks
|
|
npc_message, player_died = await combat.npc_attack(user_id)
|
|
message += "\n\n" + npc_message
|
|
|
|
if player_died:
|
|
from .handlers import send_or_edit_with_image
|
|
await send_or_edit_with_image(query, text=message, reply_markup=None)
|
|
else:
|
|
combat_data = await database.get_combat(user_id)
|
|
if combat_data:
|
|
from data.npcs import NPCS
|
|
npc_def = NPCS.get(combat_data['npc_id'])
|
|
keyboard = await keyboards.combat_keyboard(user_id)
|
|
|
|
from .handlers import send_or_edit_with_image
|
|
await send_or_edit_with_image(
|
|
query,
|
|
text=message,
|
|
reply_markup=keyboard,
|
|
image_path=npc_def.image_url if npc_def else None
|
|
)
|
|
else:
|
|
await query.answer(message, show_alert=False)
|
|
|
|
|
|
async def handle_combat_use_item_menu(query, user_id: int, player: dict, data: list = None):
|
|
"""Show menu of usable items during combat."""
|
|
await query.answer()
|
|
|
|
|
|
async def handle_combat_use_item(query, user_id: int, player: dict, data: list):
|
|
"""Use an item during combat."""
|
|
from bot import combat
|
|
item_db_id = int(data[1])
|
|
|
|
message, turn_ended = await combat.use_item_in_combat(user_id, item_db_id)
|
|
await query.answer(message, show_alert=False)
|
|
|
|
if turn_ended:
|
|
# NPC's turn
|
|
npc_message, player_died = await combat.npc_attack(user_id)
|
|
|
|
if player_died:
|
|
from .handlers import send_or_edit_with_image
|
|
await send_or_edit_with_image(
|
|
query,
|
|
text=message + "\n\n" + npc_message,
|
|
reply_markup=None
|
|
)
|
|
else:
|
|
combat_data = await database.get_combat(user_id)
|
|
if combat_data:
|
|
from data.npcs import NPCS
|
|
npc_def = NPCS.get(combat_data['npc_id'])
|
|
keyboard = await keyboards.combat_keyboard(user_id)
|
|
full_message = message + "\n\n" + npc_message + "\n\n🎯 Your turn!"
|
|
|
|
from .handlers import send_or_edit_with_image
|
|
await send_or_edit_with_image(
|
|
query,
|
|
text=full_message,
|
|
reply_markup=keyboard,
|
|
image_path=npc_def.image_url if npc_def else None
|
|
)
|
|
|
|
|
|
async def handle_combat_back(query, user_id: int, player: dict, data: list = None):
|
|
"""Return to combat menu from item selection."""
|
|
await query.answer()
|
|
combat_data = await database.get_combat(user_id)
|
|
|
|
if combat_data:
|
|
from data.npcs import NPCS
|
|
npc_def = NPCS.get(combat_data['npc_id'])
|
|
keyboard = await keyboards.combat_keyboard(user_id)
|
|
|
|
message = f"⚔️ Combat with {npc_def.emoji} {npc_def.name}!\n"
|
|
message += format_stat_bar(f"{npc_def.emoji} Enemy HP", "", combat_data['npc_hp'], combat_data['npc_max_hp']) + "\n"
|
|
message += format_stat_bar("Your HP", "❤️", player['hp'], player['max_hp']) + "\n\n"
|
|
message += "🎯 Your turn!" if combat_data['turn'] == 'player' else "⏳ Enemy's turn..."
|
|
|
|
from .handlers import send_or_edit_with_image
|
|
await send_or_edit_with_image(
|
|
query,
|
|
text=message,
|
|
reply_markup=keyboard,
|
|
image_path=npc_def.image_url if npc_def else None
|
|
)
|