6.1 KiB
Salvage UI & Armor Durability Updates
Date: 2025-11-07
Summary
Fixed salvage UI to show item details and durability-based yield, plus implemented armor durability reduction in combat.
Changes Implemented
1. Salvage Item Details Display ✅
Files: pwa/src/components/Game.tsx
Issue: Salvage menu was not showing which specific item you're salvaging (e.g., which knife when you have multiple).
Solution:
- Updated frontend to call
/api/game/salvageableendpoint instead of filtering inventory - Now displays for each salvageable item:
- Current/max durability and percentage
- Tier level
- Unique stats (damage, armor, etc.)
- Expected material yield adjusted for durability
Example Display:
🔪 Knife (Tier 2)
🔧 Durability: 30/100 (30%)
damage: 15
⚠️ Item condition will reduce yield by 70%
⚠️ 30% chance to lose each material
♻️ Expected yield:
🔩 Metal Scrap x4 → x1
📦 Cloth x2 → x0
* Subject to 30% random loss per material
2. Durability-Based Yield Preview ✅
Files: pwa/src/components/Game.tsx
Issue: Salvage menu showed full material yield even when item had low durability.
Solution:
- Calculate
durability_ratio = durability_percent / 100 - Show adjusted yield:
adjusted_quantity = base_quantity * durability_ratio - Cross out original quantity and show reduced amount in orange
- Show warning if durability < 10% (yields nothing)
Visual Indicators:
- Normal durability (100%):
x4 - Reduced durability (30%):
~~x4~~ → x1(strikethrough and arrow) - Too damaged (<10%):
x0(in red)
3. Armor Durability Reduction in Combat ✅
Files: api/main.py
Feature: Equipped armor now loses durability when you take damage in combat.
Function Added: reduce_armor_durability(player_id, damage_taken)
Formula:
# Calculate damage absorbed by armor (up to half the damage)
armor_absorbed = min(damage_taken // 2, total_armor)
# For each armor piece:
proportion = armor_value / total_armor
durability_loss = max(1, int((damage_taken * proportion / armor_value) * 0.5 * 10))
How It Works:
- Armor absorbs damage - Up to half the incoming damage is blocked by armor
- Durability reduction - Each armor piece loses durability proportional to damage taken
- Higher armor = less durability loss - Better armor pieces are more durable
- Armor breaks - When durability reaches 0, the piece breaks and is removed
Combat Message Example:
Zombie attacks for 20 damage! (Armor absorbed 8 damage)
💔 Your 🛡️ Leather Vest broke!
Balance:
- Wearing full armor set (head, chest, legs, feet) can absorb significant damage
- Base reduction rate: 0.5 (configurable)
- Higher tier armor has more max durability and higher armor value
- Encourages repairing armor between fights
Technical Implementation
Frontend Changes (Game.tsx)
1. Fetch salvageable items:
const salvageableRes = await api.get('/api/game/salvageable')
setUncraftableItems(salvageableRes.data.salvageable_items)
2. Calculate adjusted yield:
const durabilityRatio = item.unique_item_data
? item.unique_item_data.durability_percent / 100
: 1.0
const adjustedYield = item.base_yield.map((mat: any) => ({
...mat,
adjusted_quantity: Math.floor(mat.quantity * durability_ratio)
}))
3. Display unique item stats:
{item.unique_item_data && (
<div className="unique-item-details">
<p className="item-durability">
🔧 Durability: {current}/{max} ({percent}%)
</p>
<div className="unique-stats">
{Object.entries(unique_stats).map(([stat, value]) => (
<span className="stat-badge">{stat}: {value}</span>
))}
</div>
</div>
)}
Backend Changes (api/main.py)
1. Armor durability reduction function:
async def reduce_armor_durability(player_id: int, damage_taken: int):
"""Reduce durability of equipped armor when taking damage"""
# Collect all equipped armor pieces
# Calculate total armor value
# Determine damage absorbed
# Reduce durability proportionally per piece
# Break and remove pieces with 0 durability
return armor_absorbed, broken_armor
2. Called during NPC attack:
armor_absorbed, broken_armor = await reduce_armor_durability(player['id'], npc_damage)
actual_damage = max(1, npc_damage - armor_absorbed)
new_player_hp = max(0, player['hp'] - actual_damage)
# Report absorbed damage and broken armor
Configuration
Armor Durability Formula Constants:
base_reduction_rate = 0.5- Base multiplier for durability lossarmor_absorption = damage // 2- Armor blocks up to 50% of damagemin_damage = 1- Always take at least 1 damage even with high armor
To adjust armor durability loss, modify base_reduction_rate in reduce_armor_durability() function.
Benefits
- Informed Salvage Decisions - See which specific item you're salvaging
- Realistic Yield - Damaged items yield fewer materials
- Armor Wear - Armor degrades realistically, encouraging maintenance
- Combat Strategy - Need to repair/replace armor regularly
- Resource Management - Can't salvage broken items for full materials
Testing
Salvage UI:
- ✅ Shows unique item details
- ✅ Shows adjusted yield based on durability
- ✅ Shows warning for low durability items
- ✅ Confirmation dialog shows expected yield
Armor Durability:
- ✅ Armor absorbs damage (up to 50%)
- ✅ Armor loses durability when hit
- ✅ Armor breaks at 0 durability
- ✅ Broken armor message displayed
- ✅ Player takes reduced damage with armor
Future Enhancements
- Armor Repair - Add repair functionality for armor pieces
- Armor Sets - Bonus for wearing complete armor sets
- Armor Tiers - Higher tier armor is more durable
- Repair Kits - Special items to repair armor in the field
- Armor Degradation Visual - Show armor condition in equipment UI
Files Modified
pwa/src/components/Game.tsx- Salvage UI updatesapi/main.py- Armor durability reduction logicapi/main.py- Combat attack function updated
Status
✅ DEPLOYED - All features tested and running in production