What a mess
This commit is contained in:
262
docs/PICKUP_AND_CORPSE_ENHANCEMENTS.md
Normal file
262
docs/PICKUP_AND_CORPSE_ENHANCEMENTS.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user