What a mess
This commit is contained in:
@@ -7,7 +7,8 @@ import json
|
||||
import random
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import ContextTypes
|
||||
from . import database, keyboards, logic
|
||||
from . import keyboards, logic
|
||||
from .api_client import api_client
|
||||
from .utils import format_stat_bar
|
||||
from data.world_loader import game_world
|
||||
from data.items import ITEMS
|
||||
@@ -19,9 +20,43 @@ logger = logging.getLogger(__name__)
|
||||
# UTILITY FUNCTIONS
|
||||
# ============================================================================
|
||||
|
||||
async def get_player_status_text(telegram_id: int) -> str:
|
||||
"""Generate player status text with location and stats."""
|
||||
player = await database.get_player(telegram_id)
|
||||
async def check_and_redirect_if_in_combat(query, user_id: int, player: dict) -> bool:
|
||||
"""
|
||||
Check if player is in combat and redirect to combat view if so.
|
||||
Returns True if player is in combat (and was redirected), False otherwise.
|
||||
"""
|
||||
combat_data = await api_client.get_combat(user_id)
|
||||
if combat_data:
|
||||
from data.npcs import NPCS
|
||||
npc_def = NPCS.get(combat_data['npc_id'])
|
||||
|
||||
message = f"⚔️ You're in combat with {npc_def.emoji} {npc_def.name}!\n"
|
||||
message += format_stat_bar("Your HP", "❤️", player['hp'], player['max_hp']) + "\n"
|
||||
message += format_stat_bar("Enemy HP", npc_def.emoji, combat_data['npc_hp'], combat_data['npc_max_hp']) + "\n\n"
|
||||
message += "🎯 Your turn!" if combat_data['turn'] == 'player' else "⏳ Enemy's turn..."
|
||||
|
||||
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
|
||||
)
|
||||
await query.answer("⚔️ You're in combat! Finish or flee first.", show_alert=True)
|
||||
return True
|
||||
return False
|
||||
|
||||
async def get_player_status_text(player_id: int) -> str:
|
||||
"""Generate player status text with location and stats.
|
||||
|
||||
Args:
|
||||
player_id: The unique database ID of the player (not telegram_id)
|
||||
"""
|
||||
from .api_client import api_client
|
||||
|
||||
player = await api_client.get_player_by_id(player_id)
|
||||
if not player:
|
||||
return "Could not find player data."
|
||||
|
||||
@@ -29,7 +64,9 @@ async def get_player_status_text(telegram_id: int) -> str:
|
||||
if not location:
|
||||
return "Error: Player is in an unknown location."
|
||||
|
||||
inventory = await database.get_inventory(telegram_id)
|
||||
# Get inventory from API
|
||||
inv_result = await api_client.get_inventory(player_id)
|
||||
inventory = inv_result.get('inventory', [])
|
||||
weight, volume = logic.calculate_inventory_load(inventory)
|
||||
max_weight, max_volume = logic.get_player_capacity(inventory, player)
|
||||
|
||||
@@ -61,11 +98,15 @@ async def get_player_status_text(telegram_id: int) -> str:
|
||||
|
||||
async def handle_inspect_area(query, user_id: int, player: dict, data: list = None):
|
||||
"""Handle inspect area action - show NPCs and interactables in current location."""
|
||||
# Check if player is in combat and redirect if so
|
||||
if await check_and_redirect_if_in_combat(query, user_id, player):
|
||||
return
|
||||
|
||||
await query.answer()
|
||||
location_id = player['location_id']
|
||||
location = game_world.get_location(location_id)
|
||||
dropped_items = await database.get_dropped_items_in_location(location_id)
|
||||
wandering_enemies = await database.get_wandering_enemies_in_location(location_id)
|
||||
dropped_items = await api_client.get_dropped_items_in_location(location_id)
|
||||
wandering_enemies = await api_client.get_wandering_enemies_in_location(location_id)
|
||||
|
||||
keyboard = await keyboards.inspect_keyboard(location_id, dropped_items, wandering_enemies)
|
||||
image_path = location.image_path if location else None
|
||||
@@ -85,7 +126,7 @@ async def handle_attack_wandering(query, user_id: int, player: dict, data: list)
|
||||
await query.answer()
|
||||
|
||||
# Get the enemy from database
|
||||
wandering_enemies = await database.get_wandering_enemies_in_location(player['location_id'])
|
||||
wandering_enemies = await api_client.get_wandering_enemies_in_location(player['location_id'])
|
||||
enemy_data = next((e for e in wandering_enemies if e['id'] == enemy_db_id), None)
|
||||
|
||||
if not enemy_data:
|
||||
@@ -93,8 +134,8 @@ async def handle_attack_wandering(query, user_id: int, player: dict, data: list)
|
||||
# Refresh inspect menu
|
||||
location_id = player['location_id']
|
||||
location = game_world.get_location(location_id)
|
||||
dropped_items = await database.get_dropped_items_in_location(location_id)
|
||||
wandering_enemies = await database.get_wandering_enemies_in_location(location_id)
|
||||
dropped_items = await api_client.get_dropped_items_in_location(location_id)
|
||||
wandering_enemies = await api_client.get_wandering_enemies_in_location(location_id)
|
||||
keyboard = await keyboards.inspect_keyboard(location_id, dropped_items, wandering_enemies)
|
||||
image_path = location.image_path if location else None
|
||||
|
||||
@@ -110,7 +151,7 @@ async def handle_attack_wandering(query, user_id: int, player: dict, data: list)
|
||||
npc_id = enemy_data['npc_id']
|
||||
|
||||
# Remove enemy from wandering table (they're now in combat)
|
||||
await database.remove_wandering_enemy(enemy_db_id)
|
||||
await api_client.remove_wandering_enemy(enemy_db_id)
|
||||
|
||||
from data.npcs import NPCS
|
||||
from bot import combat
|
||||
@@ -143,6 +184,10 @@ async def handle_attack_wandering(query, user_id: int, player: dict, data: list)
|
||||
|
||||
async def handle_inspect_interactable(query, user_id: int, player: dict, data: list):
|
||||
"""Handle inspecting an interactable object."""
|
||||
# Check if player is in combat and redirect if so
|
||||
if await check_and_redirect_if_in_combat(query, user_id, player):
|
||||
return
|
||||
|
||||
location_id, instance_id = data[1], data[2]
|
||||
|
||||
location = game_world.get_location(location_id)
|
||||
@@ -159,7 +204,7 @@ async def handle_inspect_interactable(query, user_id: int, player: dict, data: l
|
||||
all_on_cooldown = True
|
||||
for action_id in interactable.actions.keys():
|
||||
cooldown_key = f"{instance_id}:{action_id}"
|
||||
if await database.get_cooldown(cooldown_key) == 0:
|
||||
if await api_client.get_cooldown(cooldown_key) == 0:
|
||||
all_on_cooldown = False
|
||||
break
|
||||
|
||||
@@ -185,9 +230,13 @@ async def handle_inspect_interactable(query, user_id: int, player: dict, data: l
|
||||
|
||||
async def handle_action(query, user_id: int, player: dict, data: list):
|
||||
"""Handle performing an action on an interactable object."""
|
||||
# Check if player is in combat and redirect if so
|
||||
if await check_and_redirect_if_in_combat(query, user_id, player):
|
||||
return
|
||||
|
||||
location_id, instance_id, action_id = data[1], data[2], data[3]
|
||||
cooldown_key = f"{instance_id}:{action_id}"
|
||||
cooldown = await database.get_cooldown(cooldown_key)
|
||||
cooldown = await api_client.get_cooldown(cooldown_key)
|
||||
|
||||
if cooldown > 0:
|
||||
await query.answer("Someone got to it just before you!", show_alert=False)
|
||||
@@ -207,13 +256,13 @@ async def handle_action(query, user_id: int, player: dict, data: list):
|
||||
await query.answer()
|
||||
|
||||
# Set cooldown
|
||||
await database.set_cooldown(cooldown_key)
|
||||
await api_client.set_cooldown(cooldown_key)
|
||||
|
||||
# Resolve action
|
||||
outcome = logic.resolve_action(player, action_obj)
|
||||
new_stamina = player['stamina'] - action_obj.stamina_cost
|
||||
new_hp = player['hp'] - outcome.damage_taken
|
||||
await database.update_player(user_id, {"stamina": new_stamina, "hp": new_hp})
|
||||
await api_client.update_player(user_id, {"stamina": new_stamina, "hp": new_hp})
|
||||
|
||||
# Build detailed action result
|
||||
result_details = [f"<i>{outcome.text}</i>"]
|
||||
@@ -232,7 +281,7 @@ async def handle_action(query, user_id: int, player: dict, data: list):
|
||||
can_add, reason = await logic.can_add_item_to_inventory(user_id, item_id, quantity)
|
||||
|
||||
if can_add:
|
||||
await database.add_item_to_inventory(user_id, item_id, quantity)
|
||||
await api_client.add_item_to_inventory(user_id, item_id, quantity)
|
||||
item_def = ITEMS.get(item_id, {})
|
||||
emoji = item_def.get('emoji', '❔')
|
||||
item_name = item_def.get('name', item_id)
|
||||
@@ -285,6 +334,10 @@ async def handle_main_menu(query, user_id: int, player: dict, data: list = None)
|
||||
|
||||
async def handle_move_menu(query, user_id: int, player: dict, data: list = None):
|
||||
"""Show movement options menu."""
|
||||
# Check if player is in combat and redirect if so
|
||||
if await check_and_redirect_if_in_combat(query, user_id, player):
|
||||
return
|
||||
|
||||
await query.answer()
|
||||
location = game_world.get_location(player['location_id'])
|
||||
location_image = location.image_path if location else None
|
||||
@@ -300,31 +353,24 @@ async def handle_move_menu(query, user_id: int, player: dict, data: list = None)
|
||||
|
||||
async def handle_move(query, user_id: int, player: dict, data: list):
|
||||
"""Handle player movement to a new location."""
|
||||
# Check if player is in combat and redirect if so
|
||||
if await check_and_redirect_if_in_combat(query, user_id, player):
|
||||
return
|
||||
|
||||
destination_id = data[1]
|
||||
|
||||
from_location = game_world.get_location(player['location_id'])
|
||||
to_location = game_world.get_location(destination_id)
|
||||
# Use API to move player
|
||||
from .api_client import api_client
|
||||
result = await api_client.move_player(player['id'], destination_id)
|
||||
|
||||
if not from_location or not to_location:
|
||||
await query.answer("Invalid location!", show_alert=True)
|
||||
if not result.get('success'):
|
||||
await query.answer(result.get('message', 'Cannot move there!'), show_alert=True)
|
||||
return
|
||||
|
||||
# Calculate stamina cost
|
||||
inventory = await database.get_inventory(user_id)
|
||||
stamina_cost = logic.calculate_travel_stamina_cost(player, inventory, from_location, to_location)
|
||||
await query.answer(result.get('message', 'Moving...'), show_alert=False)
|
||||
|
||||
if player['stamina'] < stamina_cost:
|
||||
await query.answer(f"Too tired to travel! Need {stamina_cost} stamina.", show_alert=True)
|
||||
return
|
||||
|
||||
# Deduct stamina and update location
|
||||
new_stamina = player['stamina'] - stamina_cost
|
||||
await database.update_player(user_id, {"location_id": destination_id, "stamina": new_stamina})
|
||||
|
||||
await query.answer(f"⚡️ -{stamina_cost} stamina", show_alert=False)
|
||||
|
||||
# Refresh player data
|
||||
player = await database.get_player(user_id)
|
||||
# Refresh player data from API using unique id
|
||||
player = await api_client.get_player_by_id(user_id)
|
||||
|
||||
# Check for random NPC encounter
|
||||
from data.npcs import NPCS, get_random_npc_for_location, get_location_encounter_rate
|
||||
|
||||
Reference in New Issue
Block a user