diff --git a/ui/loadout_manager.py b/ui/loadout_manager.py
index edcfc68..845d8d1 100644
--- a/ui/loadout_manager.py
+++ b/ui/loadout_manager.py
@@ -181,6 +181,41 @@ class LoadoutConfig:
return Decimal("0")
return total_damage / total_cost
+ def calculate_dps(self) -> Decimal:
+ """Calculate Damage Per Second (DPS) with all attachments."""
+ # Standard EU fire rate is typically 1 shot per second without attachments
+ # A scope may increase this, but we'll use a base of 1.0 for simplicity
+ shots_per_second = Decimal("1.0")
+ if self.weapon_scope:
+ # Scopes can increase fire rate, but let's be conservative
+ shots_per_second = Decimal("1.2")
+ return self.get_total_damage() * shots_per_second
+
+ def get_armor_decay_per_hit(self) -> Decimal:
+ """Calculate armor decay cost per hit taken (in PED)."""
+ decay_per_hit = Decimal("0")
+ if self.equipped_armor:
+ decay_per_hit = self.equipped_armor.get_total_decay_per_hit()
+ else:
+ # Legacy fallback
+ decay_per_hit = self.armor_decay_pec
+
+ # Add plate decay costs
+ for slot, plate_config in self.armor_plates.items():
+ decay_per_hit += plate_config.decay_pec
+
+ return decay_per_hit / Decimal("100") # Convert PEC to PED
+
+ def get_heal_cost_per_use(self) -> Decimal:
+ """Calculate healing cost per use (in PED)."""
+ return self.heal_cost_pec / Decimal("100")
+
+ def get_hp_per_pec(self) -> Decimal:
+ """Calculate HP healed per PEC spent."""
+ if self.heal_cost_pec == 0:
+ return Decimal("0")
+ return self.heal_amount / self.heal_cost_pec
+
def calculate_weapon_cost_per_hour(self) -> Decimal:
"""Calculate weapon cost per hour."""
cost_per_shot = self.get_total_decay_per_shot() + self.get_total_ammo_per_shot()
@@ -1114,22 +1149,6 @@ class LoadoutManagerDialog(QDialog):
self.loadout_name_edit = QLineEdit()
self.loadout_name_edit.setPlaceholderText("Enter loadout name...")
- # Activity settings
- self.shots_per_hour_spin = QSpinBox()
- self.shots_per_hour_spin.setRange(1, 20000)
- self.shots_per_hour_spin.setValue(3600)
- self.shots_per_hour_spin.setSuffix(" /hr")
-
- self.hits_per_hour_spin = QSpinBox()
- self.hits_per_hour_spin.setRange(0, 5000)
- self.hits_per_hour_spin.setValue(720)
- self.hits_per_hour_spin.setSuffix(" /hr")
-
- self.heals_per_hour_spin = QSpinBox()
- self.heals_per_hour_spin.setRange(0, 500)
- self.heals_per_hour_spin.setValue(60)
- self.heals_per_hour_spin.setSuffix(" /hr")
-
# Weapon section
self.weapon_group = DarkGroupBox("🔫 Weapon Configuration")
self.select_weapon_btn = QPushButton("🔍 Select from Entropia Nexus")
@@ -1185,19 +1204,28 @@ class LoadoutManagerDialog(QDialog):
self.heal_cost_edit = DecimalLineEdit()
self.heal_amount_edit = DecimalLineEdit()
- # Cost summary
- self.summary_group = DarkGroupBox("📊 Cost Summary")
- self.weapon_cost_label = QLabel("0.00 PEC/hr")
- self.armor_cost_label = QLabel("0.00 PEC/hr")
- self.heal_cost_label = QLabel("0.00 PEC/hr")
- self.total_cost_label = QLabel("0.00 PED/hr")
- self.total_cost_label.setStyleSheet("color: #ff9800; font-weight: bold; font-size: 18px;")
- self.total_dpp_label = QLabel("0.0000")
- self.total_dpp_label.setStyleSheet("color: #4caf50; font-weight: bold; font-size: 18px;")
+ # Cost summary - refined metrics (cost per action, not per hour)
+ self.summary_group = DarkGroupBox("📊 Cost Analysis")
- # Protection summary
+ # Weapon metrics
+ self.cost_per_shot_label = QLabel("0.0000 PED")
+ self.dps_label = QLabel("0.00 DPS")
+ self.dpp_label = QLabel("0.0000 DPP")
+ self.dpp_label.setStyleSheet("color: #4caf50; font-weight: bold;")
+
+ # Armor metrics
+ self.cost_per_hit_label = QLabel("0.0000 PED")
self.protection_summary_label = QLabel("No protection")
- self.protection_summary_label.setStyleSheet("color: #4a90d9; font-size: 12px;")
+ self.protection_summary_label.setStyleSheet("color: #4a90d9;")
+
+ # Healing metrics
+ self.cost_per_heal_label = QLabel("0.0000 PED")
+ self.hp_per_pec_label = QLabel("0.00 HP/PEC")
+ self.hp_per_pec_label.setStyleSheet("color: #4caf50;")
+
+ # Total cost display
+ self.total_cost_label = QLabel("0.0000 PED")
+ self.total_cost_label.setStyleSheet("color: #ff9800; font-weight: bold; font-size: 16px;")
# Break-even calculator
self.mob_health_edit = DecimalLineEdit()
@@ -1263,17 +1291,6 @@ class LoadoutManagerDialog(QDialog):
name_layout.addWidget(self.loadout_name_edit, stretch=1)
right_layout.addLayout(name_layout)
- # Activity settings
- activity_group = DarkGroupBox("⚙️ Activity Settings")
- activity_layout = QGridLayout(activity_group)
- activity_layout.addWidget(QLabel("Shots/Hour:"), 0, 0)
- activity_layout.addWidget(self.shots_per_hour_spin, 0, 1)
- activity_layout.addWidget(QLabel("Hits Taken/Hour:"), 0, 2)
- activity_layout.addWidget(self.hits_per_hour_spin, 0, 3)
- activity_layout.addWidget(QLabel("Heals/Hour:"), 0, 4)
- activity_layout.addWidget(self.heals_per_hour_spin, 0, 5)
- right_layout.addWidget(activity_group)
-
# Weapon configuration
weapon_layout = QFormLayout(self.weapon_group)
@@ -1421,23 +1438,41 @@ class LoadoutManagerDialog(QDialog):
right_layout.addWidget(self.accessories_group)
- # Cost summary
+ # Cost summary - refined layout with better metrics
summary_layout = QFormLayout(self.summary_group)
- summary_layout.addRow("Weapon Cost:", self.weapon_cost_label)
- summary_layout.addRow("Armor Cost:", self.armor_cost_label)
- summary_layout.addRow("Healing Cost:", self.heal_cost_label)
- summary_layout.addRow("Total DPP:", self.total_dpp_label)
- summary_layout.addRow("Total Cost:", self.total_cost_label)
- # Protection summary
- summary_layout.addRow("Protection:", self.protection_summary_label)
+ # Weapon section
+ weapon_group = QLabel("⚔️ Weapon")
+ weapon_group.setStyleSheet("color: #e0e0e0; margin-top: 5px;")
+ summary_layout.addRow(weapon_group)
+ summary_layout.addRow(" Cost/Shot:", self.cost_per_shot_label)
+ summary_layout.addRow(" DPS:", self.dps_label)
+ summary_layout.addRow(" DPP:", self.dpp_label)
+ # Armor section
+ armor_group = QLabel("🛡️ Armor")
+ armor_group.setStyleSheet("color: #e0e0e0; margin-top: 5px;")
+ summary_layout.addRow(armor_group)
+ summary_layout.addRow(" Cost/Hit:", self.cost_per_hit_label)
+ summary_layout.addRow(" Protection:", self.protection_summary_label)
+
+ # Healing section
+ heal_group = QLabel("💚 Healing")
+ heal_group.setStyleSheet("color: #e0e0e0; margin-top: 5px;")
+ summary_layout.addRow(heal_group)
+ summary_layout.addRow(" Cost/Heal:", self.cost_per_heal_label)
+ summary_layout.addRow(" HP/PEC:", self.hp_per_pec_label)
+
+ # Break-even calculator
+ break_even_group = QLabel("📈 Break-Even")
+ break_even_group.setStyleSheet("color: #e0e0e0; margin-top: 10px;")
+ summary_layout.addRow(break_even_group)
break_even_layout = QHBoxLayout()
- break_even_layout.addWidget(QLabel("Mob Health:"))
+ break_even_layout.addWidget(QLabel("Mob HP:"))
break_even_layout.addWidget(self.mob_health_edit)
break_even_layout.addWidget(self.calc_break_even_btn)
- summary_layout.addRow("Break-Even:", break_even_layout)
- summary_layout.addRow("", self.break_even_label)
+ summary_layout.addRow(" Calculate:", break_even_layout)
+ summary_layout.addRow(" Break-even:", self.break_even_label)
right_layout.addWidget(self.summary_group)
@@ -1478,11 +1513,6 @@ class LoadoutManagerDialog(QDialog):
# Healing
self.heal_combo.currentTextChanged.connect(self._on_heal_changed)
- # Activity settings
- self.shots_per_hour_spin.valueChanged.connect(self._update_calculations)
- self.hits_per_hour_spin.valueChanged.connect(self._update_calculations)
- self.heals_per_hour_spin.valueChanged.connect(self._update_calculations)
-
# Buttons
self.save_btn.clicked.connect(self._save_loadout)
self.load_btn.clicked.connect(self._load_selected)
@@ -1855,33 +1885,40 @@ class LoadoutManagerDialog(QDialog):
self._update_calculations()
def _update_calculations(self):
- """Update all cost and DPP calculations."""
+ """Update all cost and performance calculations."""
try:
config = self._get_current_config()
- # Update DPP
+ # Weapon metrics (per shot, not per hour)
+ cost_per_shot = config.get_total_decay_per_shot() + config.get_total_ammo_per_shot()
+ self.cost_per_shot_label.setText(f"{cost_per_shot:.4f} PED")
+
+ # DPS calculation
+ dps = config.calculate_dps()
+ self.dps_label.setText(f"{dps:.2f}")
+
+ # DPP (Damage Per Pec)
dpp = config.calculate_dpp()
self.dpp_label.setText(f"{dpp:.4f}")
- self.total_dpp_label.setText(f"{dpp:.4f}")
- # Update cost breakdown
- weapon_cost = config.calculate_weapon_cost_per_hour()
- armor_cost = config.calculate_armor_cost_per_hour()
- heal_cost = config.calculate_heal_cost_per_hour()
- total_cost = config.calculate_total_cost_per_hour()
+ # Armor metrics (cost per hit)
+ cost_per_hit = config.get_armor_decay_per_hit()
+ self.cost_per_hit_label.setText(f"{cost_per_hit:.4f} PED")
- self.weapon_cost_label.setText(f"{weapon_cost:.0f} PEC/hr")
- self.armor_cost_label.setText(f"{armor_cost:.0f} PEC/hr")
- self.heal_cost_label.setText(f"{heal_cost:.0f} PEC/hr")
- self.total_cost_label.setText(f"{total_cost:.2f} PED/hr")
-
- # Update protection summary
+ # Protection summary
protection = config.get_total_protection()
prot_text = format_protection(protection)
if prot_text == "None":
self.protection_summary_label.setText("No protection")
else:
- self.protection_summary_label.setText(f"Total: {protection.get_total()} | {prot_text}")
+ self.protection_summary_label.setText(f"Total: {protection.get_total():.1f} | {prot_text}")
+
+ # Healing metrics
+ cost_per_heal = config.get_heal_cost_per_use()
+ self.cost_per_heal_label.setText(f"{cost_per_heal:.4f} PED")
+
+ hp_per_pec = config.get_hp_per_pec()
+ self.hp_per_pec_label.setText(f"{hp_per_pec:.2f}")
except Exception as e:
logger.error(f"Calculation error: {e}")
@@ -1972,17 +2009,14 @@ class LoadoutManagerDialog(QDialog):
heal_name=self.heal_combo.currentText(),
heal_cost_pec=self.heal_cost_edit.get_decimal(),
heal_amount=self.heal_amount_edit.get_decimal(),
- shots_per_hour=self.shots_per_hour_spin.value(),
- hits_per_hour=self.hits_per_hour_spin.value(),
- heals_per_hour=self.heals_per_hour_spin.value(),
+ shots_per_hour=3600, # Default, no longer in UI
+ hits_per_hour=720, # Default, no longer in UI
+ heals_per_hour=60, # Default, no longer in UI
)
def _set_config(self, config: LoadoutConfig):
"""Set UI fields from configuration."""
self.loadout_name_edit.setText(config.name)
- self.shots_per_hour_spin.setValue(config.shots_per_hour)
- self.hits_per_hour_spin.setValue(config.hits_per_hour)
- self.heals_per_hour_spin.setValue(config.heals_per_hour)
# Weapon
self.weapon_name_label.setText(config.weapon_name)
@@ -2166,9 +2200,6 @@ class LoadoutManagerDialog(QDialog):
self.heal_amount_edit.clear()
# Reset values
- self.shots_per_hour_spin.setValue(3600)
- self.hits_per_hour_spin.setValue(720)
- self.heals_per_hour_spin.setValue(60)
self.mob_health_edit.set_decimal(Decimal("100"))
# Reset combos