9.9 KiB
Pickup and Corpse Looting Enhancements
Date: November 5, 2025
Issues Fixed
1. Pickup Error 500 Fixed
Problem: When trying to pick up items from the ground, the game threw a 500 error.
Root Cause: The game_logic.pickup_item() function was importing from the old data.items.ITEMS dictionary instead of using the new ItemsManager class. The old ITEMS returns dicts, not objects with attributes, causing AttributeError: 'dict' object has no attribute 'weight'.
Solution:
- Modified
api/game_logic.py-pickup_item()function now acceptsitems_manageras a parameter - Updated
api/main.py-pickupendpoint now passesITEMS_MANAGERtogame_logic.pickup_item() - Removed import of old
data.items.ITEMSmodule
Files Changed:
api/game_logic.py(lines 305-346)api/main.py(line 876)
2. Enhanced Corpse Looting System
Problem: Corpse looting was all-or-nothing. Players couldn't see what items were available, which ones required tools, or loot items individually.
Solution: Implemented a comprehensive corpse inspection and individual item looting system.
Backend Changes
New Endpoint: GET /api/game/corpse/{corpse_id}
- Returns detailed information about a corpse's lootable items
- Shows each item with:
- Item name, emoji, and quantity range
- Required tool (if any)
- Whether player has the required tool
- Whether item can be looted
- Works for both NPC and player corpses
Updated Endpoint: POST /api/game/loot_corpse
- Now accepts optional
item_indexparameter - If
item_indexis provided: loots only that specific item - If
item_indexis null: loots all items player has tools for (original behavior) - Returns
remaining_countto show how many items are left - Validates tool requirements before looting
Models Updated:
class LootCorpseRequest(BaseModel):
corpse_id: str
item_index: Optional[int] = None # New field
Frontend Changes
New State Variables:
const [expandedCorpse, setExpandedCorpse] = useState<string | null>(null)
const [corpseDetails, setCorpseDetails] = useState<any>(null)
New Handler Functions:
handleViewCorpseDetails()- Fetches and displays corpse contentshandleLootCorpseItem()- Loots individual items or all available items- Modified
handleLootCorpse()- Now opens detailed view instead of looting immediately
UI Enhancements:
- Corpse card now shows "🔍 Examine" button instead of "🔍 Loot"
- Clicking Examine expands corpse to show all lootable items
- Each item shows:
- Item emoji, name, and quantity range
- Tool requirement with ✓ (has tool) or ✗ (needs tool) indicator
- Color-coded tool status (green = has, red = needs)
- Individual "📦 Loot" button per item
- Disabled/locked state for items requiring tools
- "📦 Loot All Available" button at bottom
- Close button (✕) to collapse corpse details
- Smooth slide-down animation when expanding
CSS Styling Added:
.corpse-card- Purple-themed corpse cards matching danger level 5 color.corpse-container- Flexbox wrapper for card + details.corpse-details- Expansion panel with slide-down animation.corpse-details-header- Header with title and close button.corpse-items-list- List container for loot items.corpse-item- Individual loot item card.corpse-item.locked- Reduced opacity for items requiring tools.corpse-item-tool.has-tool- Green indicator for available tools.corpse-item-tool.needs-tool- Red indicator for missing tools.corpse-item-loot-btn- Individual loot button (green gradient).loot-all-btn- Loot all button (purple gradient)
Files Changed:
api/main.py(lines 893-1189) - New endpoint and updated loot logicpwa/src/components/Game.tsx(lines 72-73, 276-312, 755-828) - State, handlers, and UIpwa/src/components/Game.css(lines 723-919) - Extensive corpse detail styling
User Experience Improvements
Before:
- Click "Loot" on corpse
- Automatically loot all items (if have tools) or get error message
- No visibility into what items are available
- No way to choose which items to take
After:
- Click "🔍 Examine" on corpse
- See detailed list of all lootable items
- Each item shows:
- What it is (emoji + name)
- How many you might get (quantity range)
- If it requires a tool (and whether you have it)
- Choose to loot items individually OR loot all at once
- Items requiring tools show clear indicators
- Can close and come back later for items you don't have tools for yet
Technical Benefits
- Better Error Handling - Clear feedback about missing tools
- Granular Control - Players can pick and choose what to loot
- Tool Visibility - Players know exactly what tools they need
- Inventory Management - Can avoid picking up unwanted items
- Persistent State - Corpses remain with items until fully looted
- Better UX - Smooth animations and clear visual feedback
Testing Checklist
- Pickup items from ground works without errors
- Corpse examination shows all items correctly
- Tool requirements display correctly
- Individual item looting works
- "Loot All" button works
- Items requiring tools can't be looted without tools
- Corpse details refresh after looting individual items
- Corpse disappears when fully looted
- Error messages are clear and helpful
- UI animations work smoothly
- Both NPC and player corpses work correctly
Additional Fixes (Second Iteration)
Issue 1: Messages Disappearing Too Quickly
Problem: Loot success messages were disappearing almost immediately, making it hard to see what was looted.
Solution:
- Removed the "Examining corpse..." message that was flickering
- Added 5-second timer for loot messages to stay visible
- Messages now persist long enough to read
Issue 2: Weight/Volume Validation Not Working
Problem: Players could pick up items even when over weight/volume limits.
Solution:
- Added
calculate_player_capacity()helper function inapi/main.py - Updated
pickup_item()inapi/game_logic.pyto properly calculate capacity - Calculates current weight, max weight, current volume, max volume
- Accounts for equipped bags/containers that increase capacity
- Applied to both pickup and corpse looting
- Better error messages showing current capacity vs. item requirements
Issue 3: Items Lost When Inventory Full
Problem: When looting corpses with full inventory, items would disappear instead of being left behind.
Solution:
- Items that don't fit are now dropped on the ground at player's location
- Loot message shows two sections:
- "Looted: " - items successfully added to inventory
- "⚠️ Backpack full! Dropped on ground: " - items dropped
- Items remain in the world for later pickup
- Corpse is cleared of the item (preventing duplication)
Backend Changes
New Helper Function:
async def calculate_player_capacity(player_id: int):
"""Calculate player's current and max weight/volume capacity"""
# Returns: (current_weight, max_weight, current_volume, max_volume)
Updated loot_corpse Endpoint:
- Calculates player capacity before looting
- Checks each item against weight/volume limits
- If item fits: adds to inventory, updates running weight/volume
- If item doesn't fit: drops on ground at player location
- Works for both NPC and player corpses
- Works for both individual items and "loot all"
Response Format Updated:
{
"success": True,
"message": "Looted: 🥩 Meat x3\n⚠️ Backpack full! Dropped on ground: 🔫 Rifle x1",
"looted_items": [...],
"dropped_items": [...], # NEW
"corpse_empty": True,
"remaining_count": 0
}
Frontend Changes
Updated handleViewCorpseDetails():
- Removed "Examining corpse..." message to prevent flicker
- Directly opens corpse details without transitional message
Updated handleLootCorpseItem():
- Keeps message visible longer (5 seconds)
- Refreshes corpse details without clearing loot message
- Better async handling for corpse refresh
Files Changed:
api/main.py(lines 45-70, 1035-1246)api/game_logic.py(lines 305-385) - Fixed pickup validationpwa/src/components/Game.tsx(lines 276-323)
Deployment
Both API and PWA containers have been rebuilt and deployed successfully.
Deployment Command:
docker compose build echoes_of_the_ashes_api echoes_of_the_ashes_pwa
docker compose up -d echoes_of_the_ashes_api echoes_of_the_ashes_pwa
Status: ✅ All services running successfully
Deployment Date: November 5, 2025 (Second iteration)
Third Iteration - Pickup Validation Fix
Issue: Pickup from Ground Not Validating Weight/Volume
Problem: While corpse looting correctly validated weight/volume and dropped items that didn't fit, picking up items from the ground bypassed these checks entirely.
Root Cause: The pickup_item() function in game_logic.py had weight/volume validation code, but it was using:
- Hardcoded
max_volume = 30 player.get('max_weight', 50)which didn't account for equipped bags- Didn't calculate equipped bag bonuses properly
Solution:
Updated pickup_item() function to match the corpse looting logic:
- Properly calculate base capacity (10kg/10L)
- Loop through inventory to check for equipped bags
- Add bag capacity bonuses from
item_def.stats.get('weight_capacity', 0) - Validate BEFORE removing item from ground
- Better error messages with emoji and current capacity info
Example Error Messages:
⚠️ Item too heavy! 🔫 Rifle x1 (5.0kg) would exceed capacity. Current: 8.5/10.0kg
⚠️ Item too large! 📦 Large Box x1 (15.0L) would exceed capacity. Current: 7.0/10.0L
Success Message Updated:
Picked up 🥩 Meat x3
Files Changed:
api/game_logic.py(lines 305-385) - Complete rewrite of capacity calculation
Status: ✅ Deployed and validated (saw 400 error in logs = validation working)
Deployment Date: November 5, 2025 (Third iteration)