From dd2fce8b62a51f5a55f08b7973078f645789ede4 Mon Sep 17 00:00:00 2001 From: LemonNexus Date: Mon, 9 Feb 2026 10:40:46 +0000 Subject: [PATCH] docs: add comprehensive test hunt guide - Step-by-step instructions for first test hunt - Pre-test checklist - Expected cost calculations - Troubleshooting section - Post-test review steps --- core/armor_system.py | 87 +++++++++++++-------- docs/TEST_HUNT_GUIDE.md | 166 ++++++++++++++++++++++++++++++++++++++++ ui/loadout_manager.py | 15 +++- 3 files changed, 233 insertions(+), 35 deletions(-) create mode 100644 docs/TEST_HUNT_GUIDE.md diff --git a/core/armor_system.py b/core/armor_system.py index 8b815cc..bfc83ca 100644 --- a/core/armor_system.py +++ b/core/armor_system.py @@ -858,13 +858,15 @@ def create_shogun_set() -> ArmorSet: def create_vigilante_set() -> ArmorSet: """Create the Vigilante armor set (light, good all-around).""" + vigilante_economy = Decimal("0.05") + pieces = { ArmorSlot.HEAD: ArmorPiece( name="Vigilante Helmet", item_id="vigilante_helmet", slot=ArmorSlot.HEAD, set_name="Vigilante", - decay_per_hit=Decimal("0.015"), + decay_per_hp=vigilante_economy, protection=ProtectionProfile(impact=Decimal("3"), cut=Decimal("2"), stab=Decimal("2")), weight=Decimal("0.4"), ), @@ -873,7 +875,7 @@ def create_vigilante_set() -> ArmorSet: item_id="vigilante_harness", slot=ArmorSlot.CHEST, set_name="Vigilante", - decay_per_hit=Decimal("0.040"), + decay_per_hp=vigilante_economy, protection=ProtectionProfile(impact=Decimal("6"), cut=Decimal("5"), stab=Decimal("4")), weight=Decimal("1.0"), ), @@ -882,7 +884,7 @@ def create_vigilante_set() -> ArmorSet: item_id="vigilante_arm_l", slot=ArmorSlot.LEFT_ARM, set_name="Vigilante", - decay_per_hit=Decimal("0.015"), + decay_per_hp=vigilante_economy, protection=ProtectionProfile(impact=Decimal("3"), cut=Decimal("2"), stab=Decimal("2")), weight=Decimal("0.4"), ), @@ -891,7 +893,7 @@ def create_vigilante_set() -> ArmorSet: item_id="vigilante_arm_r", slot=ArmorSlot.RIGHT_ARM, set_name="Vigilante", - decay_per_hit=Decimal("0.015"), + decay_per_hp=vigilante_economy, protection=ProtectionProfile(impact=Decimal("3"), cut=Decimal("2"), stab=Decimal("2")), weight=Decimal("0.4"), ), @@ -900,7 +902,7 @@ def create_vigilante_set() -> ArmorSet: item_id="vigilante_gloves_l", slot=ArmorSlot.LEFT_HAND, set_name="Vigilante", - decay_per_hit=Decimal("0.010"), + decay_per_hp=vigilante_economy, protection=ProtectionProfile(impact=Decimal("2"), cut=Decimal("1"), stab=Decimal("1")), weight=Decimal("0.2"), ), @@ -909,7 +911,7 @@ def create_vigilante_set() -> ArmorSet: item_id="vigilante_gloves_r", slot=ArmorSlot.RIGHT_HAND, set_name="Vigilante", - decay_per_hit=Decimal("0.010"), + decay_per_hp=vigilante_economy, protection=ProtectionProfile(impact=Decimal("2"), cut=Decimal("1"), stab=Decimal("1")), weight=Decimal("0.2"), ), @@ -918,7 +920,7 @@ def create_vigilante_set() -> ArmorSet: item_id="vigilante_legs", slot=ArmorSlot.LEGS, set_name="Vigilante", - decay_per_hit=Decimal("0.030"), + decay_per_hp=vigilante_economy, protection=ProtectionProfile(impact=Decimal("5"), cut=Decimal("4"), stab=Decimal("3")), weight=Decimal("0.8"), ), @@ -932,13 +934,15 @@ def create_vigilante_set() -> ArmorSet: def create_hermes_set() -> ArmorSet: """Create the Hermes armor set (medium, good vs penetration).""" + hermes_economy = Decimal("0.05") + pieces = { ArmorSlot.HEAD: ArmorPiece( name="Hermes Helmet", item_id="hermes_helmet", slot=ArmorSlot.HEAD, set_name="Hermes", - decay_per_hit=Decimal("0.020"), + decay_per_hp=hermes_economy, protection=ProtectionProfile(impact=Decimal("3"), cut=Decimal("3"), stab=Decimal("2"), penetration=Decimal("3")), weight=Decimal("0.5"), ), @@ -947,7 +951,7 @@ def create_hermes_set() -> ArmorSet: item_id="hermes_harness", slot=ArmorSlot.CHEST, set_name="Hermes", - decay_per_hit=Decimal("0.050"), + decay_per_hp=hermes_economy, protection=ProtectionProfile(impact=Decimal("10"), cut=Decimal("8"), stab=Decimal("7"), penetration=Decimal("5")), weight=Decimal("1.2"), ), @@ -956,7 +960,7 @@ def create_hermes_set() -> ArmorSet: item_id="hermes_arm_l", slot=ArmorSlot.LEFT_ARM, set_name="Hermes", - decay_per_hit=Decimal("0.020"), + decay_per_hp=hermes_economy, protection=ProtectionProfile(impact=Decimal("4"), cut=Decimal("4"), stab=Decimal("3"), penetration=Decimal("2")), weight=Decimal("0.5"), ), @@ -965,7 +969,7 @@ def create_hermes_set() -> ArmorSet: item_id="hermes_arm_r", slot=ArmorSlot.RIGHT_ARM, set_name="Hermes", - decay_per_hit=Decimal("0.020"), + decay_per_hp=hermes_economy, protection=ProtectionProfile(impact=Decimal("4"), cut=Decimal("4"), stab=Decimal("3"), penetration=Decimal("2")), weight=Decimal("0.5"), ), @@ -974,7 +978,7 @@ def create_hermes_set() -> ArmorSet: item_id="hermes_gloves_l", slot=ArmorSlot.LEFT_HAND, set_name="Hermes", - decay_per_hit=Decimal("0.012"), + decay_per_hp=hermes_economy, protection=ProtectionProfile(impact=Decimal("2"), cut=Decimal("2"), stab=Decimal("1"), penetration=Decimal("1")), weight=Decimal("0.25"), ), @@ -983,7 +987,7 @@ def create_hermes_set() -> ArmorSet: item_id="hermes_gloves_r", slot=ArmorSlot.RIGHT_HAND, set_name="Hermes", - decay_per_hit=Decimal("0.012"), + decay_per_hp=hermes_economy, protection=ProtectionProfile(impact=Decimal("2"), cut=Decimal("2"), stab=Decimal("1"), penetration=Decimal("1")), weight=Decimal("0.25"), ), @@ -992,7 +996,7 @@ def create_hermes_set() -> ArmorSet: item_id="hermes_legs", slot=ArmorSlot.LEGS, set_name="Hermes", - decay_per_hit=Decimal("0.040"), + decay_per_hp=hermes_economy, protection=ProtectionProfile(impact=Decimal("7"), cut=Decimal("6"), stab=Decimal("5"), penetration=Decimal("4")), weight=Decimal("1.0"), ), @@ -1006,13 +1010,16 @@ def create_hermes_set() -> ArmorSet: def create_pixie_set() -> ArmorSet: """Create the Pixie armor set (light starter armor).""" + # Pixie is starter armor, slightly worse economy (18 hp/pec) + pixie_economy = Decimal("0.055") + pieces = { ArmorSlot.HEAD: ArmorPiece( name="Pixie Helmet", item_id="pixie_helmet", slot=ArmorSlot.HEAD, set_name="Pixie", - decay_per_hit=Decimal("0.008"), + decay_per_hp=pixie_economy, protection=ProtectionProfile(impact=Decimal("1"), cut=Decimal("1"), stab=Decimal("1")), weight=Decimal("0.2"), ), @@ -1021,7 +1028,7 @@ def create_pixie_set() -> ArmorSet: item_id="pixie_harness", slot=ArmorSlot.CHEST, set_name="Pixie", - decay_per_hit=Decimal("0.020"), + decay_per_hp=pixie_economy, protection=ProtectionProfile(impact=Decimal("4"), cut=Decimal("3"), stab=Decimal("2")), weight=Decimal("0.5"), ), @@ -1030,7 +1037,7 @@ def create_pixie_set() -> ArmorSet: item_id="pixie_arm_l", slot=ArmorSlot.LEFT_ARM, set_name="Pixie", - decay_per_hit=Decimal("0.008"), + decay_per_hp=pixie_economy, protection=ProtectionProfile(impact=Decimal("1"), cut=Decimal("1"), stab=Decimal("1")), weight=Decimal("0.2"), ), @@ -1039,7 +1046,7 @@ def create_pixie_set() -> ArmorSet: item_id="pixie_arm_r", slot=ArmorSlot.RIGHT_ARM, set_name="Pixie", - decay_per_hit=Decimal("0.008"), + decay_per_hp=pixie_economy, protection=ProtectionProfile(impact=Decimal("1"), cut=Decimal("1"), stab=Decimal("1")), weight=Decimal("0.2"), ), @@ -1048,7 +1055,7 @@ def create_pixie_set() -> ArmorSet: item_id="pixie_gloves_l", slot=ArmorSlot.LEFT_HAND, set_name="Pixie", - decay_per_hit=Decimal("0.005"), + decay_per_hp=pixie_economy, protection=ProtectionProfile(impact=Decimal("1"), cut=Decimal("1")), weight=Decimal("0.1"), ), @@ -1057,7 +1064,7 @@ def create_pixie_set() -> ArmorSet: item_id="pixie_gloves_r", slot=ArmorSlot.RIGHT_HAND, set_name="Pixie", - decay_per_hit=Decimal("0.005"), + decay_per_hp=pixie_economy, protection=ProtectionProfile(impact=Decimal("1"), cut=Decimal("1")), weight=Decimal("0.1"), ), @@ -1066,7 +1073,7 @@ def create_pixie_set() -> ArmorSet: item_id="pixie_legs", slot=ArmorSlot.LEGS, set_name="Pixie", - decay_per_hit=Decimal("0.015"), + decay_per_hp=pixie_economy, protection=ProtectionProfile(impact=Decimal("2"), cut=Decimal("2"), stab=Decimal("1")), weight=Decimal("0.4"), ), @@ -1084,55 +1091,71 @@ def create_pixie_set() -> ArmorSet: def get_mock_plates() -> List[ArmorPlate]: """Get list of available armor plates.""" + # Standard plate economy: 20 hp/pec = 0.05 pec per hp + # Upgraded plates might have better economy (25 hp/pec = 0.04 pec per hp) + standard_economy = Decimal("0.05") + improved_economy = Decimal("0.04") # 25 hp/pec + return [ # General purpose plates ArmorPlate( name="Impact Plating I", item_id="plate_impact_1", - decay_per_hit=Decimal("0.015"), + decay_per_hp=standard_economy, protection=ProtectionProfile(impact=Decimal("3")), ), ArmorPlate( name="Impact Plating II", item_id="plate_impact_2", - decay_per_hit=Decimal("0.030"), + decay_per_hp=improved_economy, protection=ProtectionProfile(impact=Decimal("6")), ), + # 5B Plates (the standard mid-game plate - good all-around) + ArmorPlate( + name="5B Plating Set", + item_id="plate_5b", + decay_per_hp=standard_economy, + protection=ProtectionProfile( + impact=Decimal("5"), cut=Decimal("5"), stab=Decimal("5"), + burn=Decimal("3"), cold=Decimal("3") + ), + block_chance=Decimal("0.01"), # 1% block chance + ), ArmorPlate( name="Cut Plating I", item_id="plate_cut_1", - decay_per_hit=Decimal("0.015"), + decay_per_hp=standard_economy, protection=ProtectionProfile(cut=Decimal("3")), ), ArmorPlate( name="Stab Plating I", item_id="plate_stab_1", - decay_per_hit=Decimal("0.015"), + decay_per_hp=standard_economy, protection=ProtectionProfile(stab=Decimal("3")), ), ArmorPlate( name="Burn Plating I", item_id="plate_burn_1", - decay_per_hit=Decimal("0.015"), + decay_per_hp=standard_economy, protection=ProtectionProfile(burn=Decimal("3")), ), ArmorPlate( name="Cold Plating I", item_id="plate_cold_1", - decay_per_hit=Decimal("0.015"), + decay_per_hp=standard_economy, protection=ProtectionProfile(cold=Decimal("3")), ), ArmorPlate( name="Penetration Plating I", item_id="plate_pen_1", - decay_per_hit=Decimal("0.020"), + decay_per_hp=standard_economy, protection=ProtectionProfile(penetration=Decimal("3")), ), # Composite plates (multi-type) ArmorPlate( name="Composite Plating I", item_id="plate_composite_1", - decay_per_hit=Decimal("0.025"), + decay_per_hp=standard_economy, protection=ProtectionProfile( impact=Decimal("2"), cut=Decimal("2"), stab=Decimal("2") ), @@ -1140,7 +1163,7 @@ def get_mock_plates() -> List[ArmorPlate]: ArmorPlate( name="Elemental Plating I", item_id="plate_elemental_1", - decay_per_hit=Decimal("0.025"), + decay_per_hp=standard_economy, protection=ProtectionProfile( burn=Decimal("2"), cold=Decimal("2"), acid=Decimal("2"), electric=Decimal("2") ), @@ -1149,13 +1172,13 @@ def get_mock_plates() -> List[ArmorPlate]: ArmorPlate( name="Heavy Impact Plating", item_id="plate_heavy_impact", - decay_per_hit=Decimal("0.050"), + decay_per_hp=improved_economy, protection=ProtectionProfile(impact=Decimal("10")), ), ArmorPlate( name="Heavy Universal Plating", item_id="plate_heavy_uni", - decay_per_hit=Decimal("0.060"), + decay_per_hp=improved_economy, protection=ProtectionProfile( impact=Decimal("3"), cut=Decimal("3"), stab=Decimal("3"), burn=Decimal("3"), cold=Decimal("3"), penetration=Decimal("3") diff --git a/docs/TEST_HUNT_GUIDE.md b/docs/TEST_HUNT_GUIDE.md new file mode 100644 index 0000000..e2e086e --- /dev/null +++ b/docs/TEST_HUNT_GUIDE.md @@ -0,0 +1,166 @@ +# Lemontropia Suite - Test Hunt Guide + +**Version:** 0.2.0 +**Date:** 2026-02-09 + +--- + +## Pre-Test Checklist + +### 1. Environment Setup +```powershell +# Pull latest code +git pull origin main + +# Run the application +python gui_main.py +``` + +### 2. Configure Settings +- Open **Settings** → Set your `PLAYER_NAME` (for personal global detection) +- Set **Log Path** (usually `C:/Users/[Username]/Documents/Entropia Universe/chat.log`) +- Enable/disable **Mock Mode** (use mock mode for testing without EU running) + +--- + +## Test Hunt Steps + +### Step 1: Create a Project +1. Click **"New Project"** +2. Name: `Test Hunt - ArMatrix BP-25` +3. Activity Type: `Hunting` +4. Description: `Testing armor, weapon, and healing tracking` + +### Step 2: Configure Loadout +1. Go to **Tools** → **Loadout Manager** (or press `Ctrl+L`) +2. **Weapon Selection:** + - Click "Select Weapon" + - Search: `ArMatrix BP-25` + - Select and confirm + - **NO attachments** for this test + +3. **Armor Selection:** + - Click "Select Armor" + - Choose either: + - **Full Set:** `Ghost` (recommended for test) + - **Individual Pieces:** Mix and match if desired + - **NO plates** for this test (or add if you want to test plates) + +4. **Healing Tool Selection:** + - Select from dropdown: + - `Vivo S10` (starter) + - `Adjusted Restoration Chip` (mid-level) + - `Hedoc MM10` (economical) + +5. **Save Loadout:** + - Name: `Test Loadout` + - Click "Save" + +### Step 3: Start Session +1. Select your project from the list +2. Click **"▶️ Start Session"** +3. The HUD overlay will appear +4. Verify HUD shows: + - Weapon name + - Armor name + - Medical tool name + - All costs at 0.00 + +### Step 4: Hunt in Entropia Universe +1. Go hunt creatures in EU +2. The app will automatically track: + - **Shots fired** (from weapon decay events) + - **Damage dealt** (from chat log) + - **Damage taken** (from chat log) + - **Heals performed** (from chat log) + - **Loot received** (excluding shrapnel/UA) + - **Globals/HOFs** (if any) + +### Step 5: Monitor Real-Time +Watch the HUD for: +- **Session time** (running counter) +- **Loot total** (shrapnel/UA excluded) +- **Cost total** (weapon + armor + healing) +- **Profit/Loss** (green = profit, red = loss) +- **Shots fired** counter +- **Estimated kills** (1 per loot event) +- **Damage dealt/taken** + +### Step 6: Stop Session +1. Click **"⏹️ Stop"** (or close HUD) +2. Review session summary in the main window +3. Check: + - Total loot value + - Total cost breakdown + - Return percentage + - Cost per kill + +--- + +## Expected Behavior + +### Cost Calculations +- **Weapon cost:** ~9.17 PED per 100 shots (ArMatrix BP-25) +- **Armor cost:** ~0.007 PED per 15 damage taken (Ghost) +- **Healing cost:** ~0.017 PED per heal (Vivo S10) + +### Loot Tracking +- **Shrapnel:** Tracked but excluded from profit +- **Universal Ammo:** Tracked but excluded from profit +- **Other loot:** Included in profit calculation + +### Session Metrics +- **Return %:** (Loot / Cost) × 100 +- **Cost/Kill:** Total cost / number of kills +- **Cost/Hour:** Total cost / session hours + +--- + +## Troubleshooting + +### HUD Not Showing +- Press `F9` to show HUD +- Check if session is running + +### Costs Not Updating +- Verify log path is correct +- Check that log file exists and is readable +- Enable mock mode for testing + +### Wrong Player Name +- Update `PLAYER_NAME` in Settings +- Required for personal global detection + +### App Crashes +- Check console for error messages +- Verify Python 3.11+ and PyQt6 installed +- Run `pytest tests/` to check for issues + +--- + +## Post-Test Actions + +### Review Data +1. Check session summary in main window +2. Compare calculated costs with actual PED spent +3. Verify loot values match EU inventory + +### Report Issues +If anything seems wrong: +1. Note the discrepancy +2. Check `chat.log` for relevant lines +3. Share findings for formula refinement + +--- + +## Next Steps After Test + +Once basic hunting works: +1. **Test with attachments:** Add amplifier, scope +2. **Test with plates:** Add armor plating +3. **Test mining:** Switch to mining activity +4. **Test crafting:** Switch to crafting activity + +--- + +**Good luck with the test hunt!** 🍋🎯 \ No newline at end of file diff --git a/ui/loadout_manager.py b/ui/loadout_manager.py index e9a6b78..14ae3b3 100644 --- a/ui/loadout_manager.py +++ b/ui/loadout_manager.py @@ -522,12 +522,21 @@ class ArmorSlotWidget(QWidget): return total def get_total_decay(self) -> Decimal: - """Get total decay per hit for this slot.""" + """Get total decay per hit for this slot (estimated).""" + # Estimate based on typical hit of 10 hp + typical_hit = Decimal("10") decay = Decimal("0") + if self.current_piece: - decay += self.current_piece.decay_per_hit + # Armor only decays for damage it actually absorbs + armor_absorb = min(typical_hit, self.current_piece.protection.get_total()) + decay += self.current_piece.get_decay_for_damage(armor_absorb) + if self.current_plate: - decay += self.current_plate.decay_per_hit + # Plate only decays for damage it actually absorbs + plate_absorb = min(typical_hit, self.current_plate.get_total_protection()) + decay += self.current_plate.get_decay_for_damage(plate_absorb) + return decay