What a mess
This commit is contained in:
@@ -3,7 +3,7 @@ Inventory-related action handlers.
|
||||
"""
|
||||
import logging
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from . import database, keyboards, logic
|
||||
from . import keyboards, logic
|
||||
from data.world_loader import game_world
|
||||
from data.items import ITEMS
|
||||
|
||||
@@ -13,9 +13,12 @@ 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
|
||||
from .api_client import api_client
|
||||
await query.answer()
|
||||
|
||||
inventory_items = await database.get_inventory(user_id)
|
||||
# Get inventory from API
|
||||
inv_result = await api_client.get_inventory(player['id'])
|
||||
inventory_items = inv_result.get('inventory', [])
|
||||
current_weight, current_volume = logic.calculate_inventory_load(inventory_items)
|
||||
max_weight, max_volume = logic.get_player_capacity(inventory_items, player)
|
||||
|
||||
@@ -41,35 +44,50 @@ async def handle_inventory_menu(query, user_id: int, player: dict, data: list =
|
||||
|
||||
|
||||
async def handle_inventory_item(query, user_id: int, player: dict, data: list):
|
||||
"""Show details for a specific inventory item."""
|
||||
"""Show details for a specific inventory item.
|
||||
|
||||
Note: item_db_id is the inventory row id from the API response.
|
||||
We need to get the full inventory and find the item by id.
|
||||
"""
|
||||
from .api_client import api_client
|
||||
|
||||
await query.answer()
|
||||
item_db_id = int(data[1])
|
||||
item = await database.get_inventory_item(item_db_id)
|
||||
item_def = ITEMS.get(item['item_id'], {})
|
||||
emoji = item_def.get('emoji', '❔')
|
||||
|
||||
# Get inventory from API
|
||||
inv_result = await api_client.get_inventory(user_id)
|
||||
inventory_items = inv_result.get('inventory', [])
|
||||
|
||||
# Find the specific item
|
||||
item = next((i for i in inventory_items if i['id'] == item_db_id), None)
|
||||
if not item:
|
||||
await query.answer("Item not found in inventory", show_alert=True)
|
||||
return
|
||||
|
||||
emoji = item.get('emoji', '❔')
|
||||
|
||||
# Build item details text
|
||||
text = f"{emoji} <b>{item_def.get('name', 'Unknown')}</b>\n"
|
||||
text = f"{emoji} <b>{item.get('name', 'Unknown')}</b>\n"
|
||||
|
||||
description = item_def.get('description')
|
||||
description = item.get('description')
|
||||
if description:
|
||||
text += f"<i>{description}</i>\n\n"
|
||||
else:
|
||||
text += "\n"
|
||||
|
||||
text += f"<b>Weight:</b> {item_def.get('weight', 0)} kg | <b>Volume:</b> {item_def.get('volume', 0)} vol\n"
|
||||
text += f"<b>Weight:</b> {item.get('weight', 0)} kg | <b>Volume:</b> {item.get('volume', 0)} vol\n"
|
||||
|
||||
# Add weapon stats if applicable
|
||||
if item_def.get('type') == 'weapon':
|
||||
text += f"<b>Damage:</b> {item_def.get('damage_min', 0)}-{item_def.get('damage_max', 0)}\n"
|
||||
if item.get('type') == 'weapon':
|
||||
text += f"<b>Damage:</b> {item.get('damage_min', 0)}-{item.get('damage_max', 0)}\n"
|
||||
|
||||
# Add consumable effects if applicable
|
||||
if item_def.get('type') == 'consumable':
|
||||
if item.get('type') == 'consumable':
|
||||
effects = []
|
||||
if item_def.get('hp_restore'):
|
||||
effects.append(f"❤️ +{item_def.get('hp_restore')} HP")
|
||||
if item_def.get('stamina_restore'):
|
||||
effects.append(f"⚡ +{item_def.get('stamina_restore')} Stamina")
|
||||
if item.get('hp_restore'):
|
||||
effects.append(f"❤️ +{item.get('hp_restore')} HP")
|
||||
if item.get('stamina_restore'):
|
||||
effects.append(f"⚡ +{item.get('stamina_restore')} Stamina")
|
||||
if effects:
|
||||
text += f"<b>Effects:</b> {', '.join(effects)}\n"
|
||||
|
||||
@@ -85,7 +103,7 @@ async def handle_inventory_item(query, user_id: int, player: dict, data: list):
|
||||
query,
|
||||
text=text,
|
||||
reply_markup=keyboards.inventory_item_actions_keyboard(
|
||||
item_db_id, item_def, item.get('is_equipped', False), item['quantity']
|
||||
item_db_id, item, item.get('is_equipped', False), item['quantity']
|
||||
),
|
||||
image_path=location_image
|
||||
)
|
||||
@@ -94,60 +112,38 @@ 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
|
||||
from .api_client import api_client
|
||||
|
||||
item_db_id = int(data[1])
|
||||
item = await database.get_inventory_item(item_db_id)
|
||||
|
||||
# Get inventory from API to find the item
|
||||
inv_result = await api_client.get_inventory(user_id)
|
||||
inventory_items = inv_result.get('inventory', [])
|
||||
item = next((i for i in inventory_items if i['id'] == item_db_id), None)
|
||||
|
||||
if not item:
|
||||
await query.answer("Item not found.", show_alert=False)
|
||||
return
|
||||
|
||||
item_def = ITEMS.get(item['item_id'], {})
|
||||
|
||||
if item_def.get('type') != 'consumable':
|
||||
if item.get('type') != 'consumable':
|
||||
await query.answer("This item cannot be used.", show_alert=False)
|
||||
return
|
||||
|
||||
await query.answer()
|
||||
|
||||
# Apply item effects
|
||||
result_parts = []
|
||||
updates = {}
|
||||
# Use the API to use the item
|
||||
result = await api_client.use_item(user_id, item['item_id'])
|
||||
|
||||
if 'hp_restore' in item_def:
|
||||
hp_gain = item_def['hp_restore']
|
||||
new_hp = min(player['max_hp'], player['hp'] + hp_gain)
|
||||
actual_gain = new_hp - player['hp']
|
||||
updates['hp'] = new_hp
|
||||
if actual_gain > 0:
|
||||
result_parts.append(f"❤️ HP: +{actual_gain}")
|
||||
else:
|
||||
result_parts.append(f"❤️ HP: Already at maximum!")
|
||||
|
||||
if 'stamina_restore' in item_def:
|
||||
stamina_gain = item_def['stamina_restore']
|
||||
new_stamina = min(player['max_stamina'], player['stamina'] + stamina_gain)
|
||||
actual_gain = new_stamina - player['stamina']
|
||||
updates['stamina'] = new_stamina
|
||||
if actual_gain > 0:
|
||||
result_parts.append(f"⚡ Stamina: +{actual_gain}")
|
||||
else:
|
||||
result_parts.append(f"⚡ Stamina: Already at maximum!")
|
||||
|
||||
if updates:
|
||||
await database.update_player(user_id, updates)
|
||||
if not result.get('success'):
|
||||
await query.answer(result.get('message', 'Failed to use item'), show_alert=True)
|
||||
return
|
||||
|
||||
# Refresh player data to get updated stats
|
||||
player = await database.get_player(user_id)
|
||||
player = await api_client.get_player_by_id(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'])
|
||||
|
||||
# Show updated inventory
|
||||
inventory_items = await database.get_inventory(user_id)
|
||||
# Get updated inventory
|
||||
inv_result = await api_client.get_inventory(user_id)
|
||||
inventory_items = inv_result.get('inventory', [])
|
||||
current_weight, current_volume = logic.calculate_inventory_load(inventory_items)
|
||||
max_weight, max_volume = logic.get_player_capacity(inventory_items, player)
|
||||
|
||||
@@ -159,13 +155,8 @@ async def handle_inventory_use(query, user_id: int, player: dict, data: list):
|
||||
text += f"📦 Volume: {current_volume}/{max_volume} vol\n"
|
||||
text += "━━━━━━━━━━━━━━━━━━━━\n"
|
||||
|
||||
# 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 += "No effect."
|
||||
# Build result message from API response
|
||||
text += result.get('message', 'Item used.')
|
||||
|
||||
location = game_world.get_location(player['location_id'])
|
||||
location_image = location.image_path if location else None
|
||||
@@ -181,33 +172,38 @@ async def handle_inventory_use(query, user_id: int, player: dict, data: list):
|
||||
|
||||
async def handle_inventory_drop(query, user_id: int, player: dict, data: list):
|
||||
"""Drop an item from inventory to the world."""
|
||||
from .api_client import api_client
|
||||
|
||||
item_db_id = int(data[1])
|
||||
drop_amount_str = data[2] if len(data) > 2 else None
|
||||
|
||||
item = await database.get_inventory_item(item_db_id)
|
||||
# Get inventory to find the item
|
||||
inv_result = await api_client.get_inventory(user_id)
|
||||
inventory_items = inv_result.get('inventory', [])
|
||||
item = next((i for i in inventory_items if i['id'] == item_db_id), None)
|
||||
|
||||
if not item:
|
||||
await query.answer("Item not found.", show_alert=False)
|
||||
return
|
||||
|
||||
item_def = ITEMS.get(item['item_id'], {})
|
||||
|
||||
# Determine how much to drop
|
||||
if drop_amount_str is None or drop_amount_str == "all":
|
||||
await database.drop_item_to_world(item['item_id'], item['quantity'], player['location_id'])
|
||||
await database.remove_item_from_inventory(item['id'], quantity=item['quantity'])
|
||||
await query.answer(f"You dropped all {item['quantity']}x {item_def.get('name')}.", show_alert=False)
|
||||
drop_amount = item['quantity']
|
||||
else:
|
||||
drop_amount = int(drop_amount_str)
|
||||
if drop_amount >= item['quantity']:
|
||||
await database.drop_item_to_world(item['item_id'], item['quantity'], player['location_id'])
|
||||
await database.remove_item_from_inventory(item['id'], quantity=item['quantity'])
|
||||
await query.answer(f"You dropped all {item['quantity']}x {item_def.get('name')}.", show_alert=False)
|
||||
else:
|
||||
await database.drop_item_to_world(item['item_id'], drop_amount, player['location_id'])
|
||||
await database.update_inventory_item(item['id'], quantity=item['quantity'] - drop_amount)
|
||||
await query.answer(f"You dropped {drop_amount}x {item_def.get('name')}.", show_alert=False)
|
||||
drop_amount = min(int(drop_amount_str), item['quantity'])
|
||||
|
||||
inventory_items = await database.get_inventory(user_id)
|
||||
# Use API to drop item
|
||||
result = await api_client.drop_item(user_id, item['item_id'], drop_amount)
|
||||
|
||||
if result.get('success'):
|
||||
await query.answer(result.get('message', f"Dropped {drop_amount}x {item['name']}"), show_alert=False)
|
||||
else:
|
||||
await query.answer(result.get('message', 'Failed to drop item'), show_alert=True)
|
||||
return
|
||||
|
||||
# Get updated inventory
|
||||
inv_result = await api_client.get_inventory(user_id)
|
||||
inventory_items = inv_result.get('inventory', [])
|
||||
current_weight, current_volume = logic.calculate_inventory_load(inventory_items)
|
||||
max_weight, max_volume = logic.get_player_capacity(inventory_items, player)
|
||||
|
||||
@@ -232,54 +228,46 @@ async def handle_inventory_drop(query, user_id: int, player: dict, data: list):
|
||||
|
||||
async def handle_inventory_equip(query, user_id: int, player: dict, data: list):
|
||||
"""Equip an item from inventory."""
|
||||
from .api_client import api_client
|
||||
|
||||
item_db_id = int(data[1])
|
||||
item = await database.get_inventory_item(item_db_id)
|
||||
|
||||
# Get inventory to find the item
|
||||
inv_result = await api_client.get_inventory(user_id)
|
||||
inventory_items = inv_result.get('inventory', [])
|
||||
item = next((i for i in inventory_items if i['id'] == item_db_id), None)
|
||||
|
||||
if not item:
|
||||
await query.answer("Item not found.", show_alert=False)
|
||||
return
|
||||
|
||||
item_def = ITEMS.get(item['item_id'], {})
|
||||
item_slot = item_def.get('slot')
|
||||
|
||||
if not item_slot:
|
||||
if not item.get('equippable'):
|
||||
await query.answer("This item cannot be equipped.", show_alert=False)
|
||||
return
|
||||
|
||||
# Unequip any item in the same slot
|
||||
inventory_items = await database.get_inventory(user_id)
|
||||
for inv_item in inventory_items:
|
||||
if inv_item.get('is_equipped'):
|
||||
inv_item_def = ITEMS.get(inv_item['item_id'], {})
|
||||
if inv_item_def.get('slot') == item_slot:
|
||||
await database.update_inventory_item(inv_item['id'], is_equipped=False)
|
||||
# Use API to equip item
|
||||
result = await api_client.equip_item(user_id, item['item_id'])
|
||||
|
||||
# If equipping from a stack, split the stack
|
||||
if item['quantity'] > 1:
|
||||
await database.update_inventory_item(item_db_id, quantity=item['quantity'] - 1)
|
||||
new_item_id = await database.add_equipped_item_to_inventory(user_id, item['item_id'])
|
||||
await query.answer(f"Equipped {item_def.get('name')}!", show_alert=False)
|
||||
item = await database.get_inventory_item(new_item_id)
|
||||
item_db_id = new_item_id
|
||||
else:
|
||||
await database.update_inventory_item(item_db_id, is_equipped=True)
|
||||
await query.answer(f"Equipped {item_def.get('name')}!", show_alert=False)
|
||||
item = await database.get_inventory_item(item_db_id)
|
||||
if not result.get('success'):
|
||||
await query.answer(result.get('message', 'Failed to equip item'), show_alert=True)
|
||||
return
|
||||
|
||||
await query.answer(result.get('message', f"Equipped {item['name']}!"), show_alert=False)
|
||||
|
||||
# Refresh the item view
|
||||
emoji = item_def.get('emoji', '❔')
|
||||
text = f"{emoji} <b>{item_def.get('name', 'Unknown')}</b>\n"
|
||||
emoji = item.get('emoji', '❔')
|
||||
text = f"{emoji} <b>{item.get('name', 'Unknown')}</b>\n"
|
||||
|
||||
description = item_def.get('description')
|
||||
description = item.get('description')
|
||||
if description:
|
||||
text += f"<i>{description}</i>\n\n"
|
||||
else:
|
||||
text += "\n"
|
||||
|
||||
text += f"<b>Weight:</b> {item_def.get('weight', 0)} kg | <b>Volume:</b> {item_def.get('volume', 0)} vol\n"
|
||||
text += f"<b>Weight:</b> {item.get('weight', 0)} kg | <b>Volume:</b> {item.get('volume', 0)} vol\n"
|
||||
|
||||
if item_def.get('type') == 'weapon':
|
||||
text += f"<b>Damage:</b> {item_def.get('damage_min', 0)}-{item_def.get('damage_max', 0)}\n"
|
||||
if item.get('type') == 'weapon':
|
||||
text += f"<b>Damage:</b> {item.get('damage_min', 0)}-{item.get('damage_max', 0)}\n"
|
||||
|
||||
text += "\n✅ <b>Currently Equipped</b>"
|
||||
|
||||
@@ -291,7 +279,7 @@ async def handle_inventory_equip(query, user_id: int, player: dict, data: list):
|
||||
query,
|
||||
text=text,
|
||||
reply_markup=keyboards.inventory_item_actions_keyboard(
|
||||
item_db_id, item_def, True, item['quantity']
|
||||
item_db_id, item, True, item['quantity']
|
||||
),
|
||||
image_path=location_image
|
||||
)
|
||||
@@ -299,52 +287,42 @@ async def handle_inventory_equip(query, user_id: int, player: dict, data: list):
|
||||
|
||||
async def handle_inventory_unequip(query, user_id: int, player: dict, data: list):
|
||||
"""Unequip an item."""
|
||||
from .api_client import api_client
|
||||
|
||||
item_db_id = int(data[1])
|
||||
item = await database.get_inventory_item(item_db_id)
|
||||
|
||||
# Get inventory to find the item
|
||||
inv_result = await api_client.get_inventory(user_id)
|
||||
inventory_items = inv_result.get('inventory', [])
|
||||
item = next((i for i in inventory_items if i['id'] == item_db_id), None)
|
||||
|
||||
if not item:
|
||||
await query.answer("Item not found.", show_alert=False)
|
||||
return
|
||||
|
||||
item_def = ITEMS.get(item['item_id'], {})
|
||||
# Use API to unequip item
|
||||
result = await api_client.unequip_item(user_id, item['item_id'])
|
||||
|
||||
# Check if there's an existing unequipped stack
|
||||
inventory_items = await database.get_inventory(user_id)
|
||||
existing_stack = None
|
||||
for inv_item in inventory_items:
|
||||
if (inv_item['item_id'] == item['item_id'] and
|
||||
not inv_item.get('is_equipped') and
|
||||
inv_item['id'] != item_db_id):
|
||||
existing_stack = inv_item
|
||||
break
|
||||
if not result.get('success'):
|
||||
await query.answer(result.get('message', 'Failed to unequip item'), show_alert=True)
|
||||
return
|
||||
|
||||
if existing_stack:
|
||||
# Merge into existing stack
|
||||
await database.update_inventory_item(existing_stack['id'], quantity=existing_stack['quantity'] + 1)
|
||||
await database.remove_item_from_inventory(item_db_id)
|
||||
await query.answer(f"Unequipped {item_def.get('name')}.", show_alert=False)
|
||||
item = await database.get_inventory_item(existing_stack['id'])
|
||||
item_db_id = existing_stack['id']
|
||||
else:
|
||||
# Just unequip
|
||||
await database.update_inventory_item(item_db_id, is_equipped=False)
|
||||
await query.answer(f"Unequipped {item_def.get('name')}.", show_alert=False)
|
||||
item = await database.get_inventory_item(item_db_id)
|
||||
await query.answer(result.get('message', f"Unequipped {item['name']}."), show_alert=False)
|
||||
|
||||
# Refresh the item view
|
||||
emoji = item_def.get('emoji', '❔')
|
||||
text = f"{emoji} <b>{item_def.get('name', 'Unknown')}</b>\n"
|
||||
emoji = item.get('emoji', '❔')
|
||||
text = f"{emoji} <b>{item.get('name', 'Unknown')}</b>\n"
|
||||
|
||||
description = item_def.get('description')
|
||||
description = item.get('description')
|
||||
if description:
|
||||
text += f"<i>{description}</i>\n\n"
|
||||
else:
|
||||
text += "\n"
|
||||
|
||||
text += f"<b>Weight:</b> {item_def.get('weight', 0)} kg | <b>Volume:</b> {item_def.get('volume', 0)} vol\n"
|
||||
text += f"<b>Weight:</b> {item.get('weight', 0)} kg | <b>Volume:</b> {item.get('volume', 0)} vol\n"
|
||||
|
||||
if item_def.get('type') == 'weapon':
|
||||
text += f"<b>Damage:</b> {item_def.get('damage_min', 0)}-{item_def.get('damage_max', 0)}\n"
|
||||
if item.get('type') == 'weapon':
|
||||
text += f"<b>Damage:</b> {item.get('damage_min', 0)}-{item.get('damage_max', 0)}\n"
|
||||
|
||||
location = game_world.get_location(player['location_id'])
|
||||
location_image = location.image_path if location else None
|
||||
@@ -354,7 +332,7 @@ async def handle_inventory_unequip(query, user_id: int, player: dict, data: list
|
||||
query,
|
||||
text=text,
|
||||
reply_markup=keyboards.inventory_item_actions_keyboard(
|
||||
item_db_id, item_def, False, item['quantity']
|
||||
item_db_id, item, False, item['quantity']
|
||||
),
|
||||
image_path=location_image
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user