263 lines
9.9 KiB
Markdown
263 lines
9.9 KiB
Markdown
# 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 accepts `items_manager` as a parameter
|
|
- Updated `api/main.py` - `pickup` endpoint now passes `ITEMS_MANAGER` to `game_logic.pickup_item()`
|
|
- Removed import of old `data.items.ITEMS` module
|
|
|
|
**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_index` parameter
|
|
- If `item_index` is provided: loots only that specific item
|
|
- If `item_index` is null: loots all items player has tools for (original behavior)
|
|
- Returns `remaining_count` to show how many items are left
|
|
- Validates tool requirements before looting
|
|
|
|
**Models Updated:**
|
|
```python
|
|
class LootCorpseRequest(BaseModel):
|
|
corpse_id: str
|
|
item_index: Optional[int] = None # New field
|
|
```
|
|
|
|
#### Frontend Changes
|
|
|
|
**New State Variables:**
|
|
```typescript
|
|
const [expandedCorpse, setExpandedCorpse] = useState<string | null>(null)
|
|
const [corpseDetails, setCorpseDetails] = useState<any>(null)
|
|
```
|
|
|
|
**New Handler Functions:**
|
|
- `handleViewCorpseDetails()` - Fetches and displays corpse contents
|
|
- `handleLootCorpseItem()` - 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 logic
|
|
- `pwa/src/components/Game.tsx` (lines 72-73, 276-312, 755-828) - State, handlers, and UI
|
|
- `pwa/src/components/Game.css` (lines 723-919) - Extensive corpse detail styling
|
|
|
|
## User Experience Improvements
|
|
|
|
### Before:
|
|
1. Click "Loot" on corpse
|
|
2. Automatically loot all items (if have tools) or get error message
|
|
3. No visibility into what items are available
|
|
4. No way to choose which items to take
|
|
|
|
### After:
|
|
1. Click "🔍 Examine" on corpse
|
|
2. See detailed list of all lootable items
|
|
3. 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)
|
|
4. Choose to loot items individually OR loot all at once
|
|
5. Items requiring tools show clear indicators
|
|
6. Can close and come back later for items you don't have tools for yet
|
|
|
|
## Technical Benefits
|
|
|
|
1. **Better Error Handling** - Clear feedback about missing tools
|
|
2. **Granular Control** - Players can pick and choose what to loot
|
|
3. **Tool Visibility** - Players know exactly what tools they need
|
|
4. **Inventory Management** - Can avoid picking up unwanted items
|
|
5. **Persistent State** - Corpses remain with items until fully looted
|
|
6. **Better UX** - Smooth animations and clear visual feedback
|
|
|
|
## Testing Checklist
|
|
|
|
- [x] Pickup items from ground works without errors
|
|
- [x] Corpse examination shows all items correctly
|
|
- [x] Tool requirements display correctly
|
|
- [x] Individual item looting works
|
|
- [x] "Loot All" button works
|
|
- [x] Items requiring tools can't be looted without tools
|
|
- [x] Corpse details refresh after looting individual items
|
|
- [x] Corpse disappears when fully looted
|
|
- [x] Error messages are clear and helpful
|
|
- [x] UI animations work smoothly
|
|
- [x] 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 in `api/main.py`
|
|
- Updated `pickup_item()` in `api/game_logic.py` to 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:**
|
|
```python
|
|
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:**
|
|
```python
|
|
{
|
|
"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 validation
|
|
- `pwa/src/components/Game.tsx` (lines 276-323)
|
|
|
|
## Deployment
|
|
|
|
Both API and PWA containers have been rebuilt and deployed successfully.
|
|
|
|
**Deployment Command:**
|
|
```bash
|
|
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)
|