# 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/salvageable` endpoint 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:** ```python # 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:** 1. **Armor absorbs damage** - Up to half the incoming damage is blocked by armor 2. **Durability reduction** - Each armor piece loses durability proportional to damage taken 3. **Higher armor = less durability loss** - Better armor pieces are more durable 4. **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:** ```typescript const salvageableRes = await api.get('/api/game/salvageable') setUncraftableItems(salvageableRes.data.salvageable_items) ``` **2. Calculate adjusted yield:** ```typescript 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:** ```tsx {item.unique_item_data && (
🔧 Durability: {current}/{max} ({percent}%)