refactor(ui): replace per-hour metrics with per-action cost metrics
Removed confusing per-hour calculations and replaced with practical per-action metrics that players actually need: New Metrics Displayed: - ⚔️ Weapon: Cost/Shot (PED), DPS, DPP - 🛡️ Armor: Cost/Hit (PED), Protection - 💚 Healing: Cost/Heal (PED), HP/PEC Removed: - Activity Settings section (Shots/Hour, Hits/Hour, Heals/Hour) - Per-hour cost calculations The Break-Even calculator remains based on mob HP. These metrics represent actual costs per action taken: - Each shot fired costs X PED - Each hit taken costs Y PED - Each heal used costs Z PED Much more intuitive for tracking hunt profitability.
This commit is contained in:
parent
2183b79ce8
commit
bd6abd60c2
|
|
@ -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
|
||||
# Weapon section
|
||||
weapon_group = QLabel("<b>⚔️ Weapon</b>")
|
||||
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("<b>🛡️ Armor</b>")
|
||||
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("<b>💚 Healing</b>")
|
||||
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("<b>📈 Break-Even</b>")
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue