feat: add total skill gained tracking to HUD
- Add show_skills config option to HUDConfig - Add total_skill_gained and skill_gains fields to HUDStats - Add skills display section in HUD UI (purple box) - Add update_skill() method to track skill gains - Update on_skill handler in main_window.py to call update_skill() - Add skills checkbox to HUD settings dialog - Fix duplicate code in _refresh_display method - Update to_dict/from_dict for skills config persistence
This commit is contained in:
parent
ecf27a504c
commit
b14888dc97
|
|
@ -48,6 +48,7 @@ class HUDConfig:
|
||||||
show_cost_metrics: bool = True # Cost per shot/hit/heal
|
show_cost_metrics: bool = True # Cost per shot/hit/heal
|
||||||
show_shrapnel: bool = False # Deprecated - now integrated in loot summary
|
show_shrapnel: bool = False # Deprecated - now integrated in loot summary
|
||||||
show_gear_info: bool = True
|
show_gear_info: bool = True
|
||||||
|
show_skills: bool = False # NEW: Total skill gained
|
||||||
|
|
||||||
compact_mode: bool = False
|
compact_mode: bool = False
|
||||||
|
|
||||||
|
|
@ -62,6 +63,7 @@ class HUDConfig:
|
||||||
'show_damage_stats': self.show_damage_stats,
|
'show_damage_stats': self.show_damage_stats,
|
||||||
'show_cost_metrics': self.show_cost_metrics,
|
'show_cost_metrics': self.show_cost_metrics,
|
||||||
'show_gear_info': self.show_gear_info,
|
'show_gear_info': self.show_gear_info,
|
||||||
|
'show_skills': self.show_skills,
|
||||||
'compact_mode': self.compact_mode,
|
'compact_mode': self.compact_mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,6 +79,7 @@ class HUDConfig:
|
||||||
show_damage_stats=data.get('show_damage_stats', False),
|
show_damage_stats=data.get('show_damage_stats', False),
|
||||||
show_cost_metrics=data.get('show_cost_metrics', True),
|
show_cost_metrics=data.get('show_cost_metrics', True),
|
||||||
show_gear_info=data.get('show_gear_info', True),
|
show_gear_info=data.get('show_gear_info', True),
|
||||||
|
show_skills=data.get('show_skills', False),
|
||||||
compact_mode=data.get('compact_mode', False),
|
compact_mode=data.get('compact_mode', False),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -129,6 +132,10 @@ class HUDStats:
|
||||||
current_fap: str = "None"
|
current_fap: str = "None"
|
||||||
current_loadout: str = "None"
|
current_loadout: str = "None"
|
||||||
|
|
||||||
|
# Skills (NEW)
|
||||||
|
total_skill_gained: Decimal = Decimal('0.0') # Total of all skill gains
|
||||||
|
skill_gains: Dict[str, Decimal] = field(default_factory=dict) # Per-skill tracking
|
||||||
|
|
||||||
def recalculate(self):
|
def recalculate(self):
|
||||||
"""Recalculate derived values."""
|
"""Recalculate derived values."""
|
||||||
# Total loot is shrapnel + other loot
|
# Total loot is shrapnel + other loot
|
||||||
|
|
@ -228,6 +235,10 @@ class HUDSettingsDialog(QDialog):
|
||||||
self.cb_damage = QCheckBox("Damage Stats (Dealt/Taken)")
|
self.cb_damage = QCheckBox("Damage Stats (Dealt/Taken)")
|
||||||
self.cb_damage.setChecked(self.config.show_damage_stats)
|
self.cb_damage.setChecked(self.config.show_damage_stats)
|
||||||
form.addRow(self.cb_damage)
|
form.addRow(self.cb_damage)
|
||||||
|
|
||||||
|
self.cb_skills = QCheckBox("Total Skills Gained")
|
||||||
|
self.cb_skills.setChecked(self.config.show_skills)
|
||||||
|
form.addRow(self.cb_skills)
|
||||||
|
|
||||||
# Display mode
|
# Display mode
|
||||||
form.addRow(QLabel("<b>Display Mode</b>"))
|
form.addRow(QLabel("<b>Display Mode</b>"))
|
||||||
|
|
@ -263,6 +274,7 @@ class HUDSettingsDialog(QDialog):
|
||||||
self.config.show_cost_breakdown = self.cb_cost_breakdown.isChecked()
|
self.config.show_cost_breakdown = self.cb_cost_breakdown.isChecked()
|
||||||
self.config.show_combat_stats = self.cb_combat.isChecked()
|
self.config.show_combat_stats = self.cb_combat.isChecked()
|
||||||
self.config.show_damage_stats = self.cb_damage.isChecked()
|
self.config.show_damage_stats = self.cb_damage.isChecked()
|
||||||
|
self.config.show_skills = self.cb_skills.isChecked()
|
||||||
self.config.compact_mode = self.cb_compact.isChecked()
|
self.config.compact_mode = self.cb_compact.isChecked()
|
||||||
self.accept()
|
self.accept()
|
||||||
|
|
||||||
|
|
@ -578,6 +590,20 @@ class HUDOverlay(QWidget):
|
||||||
|
|
||||||
layout.addWidget(damage_box)
|
layout.addWidget(damage_box)
|
||||||
|
|
||||||
|
# === SKILLS (if enabled) ===
|
||||||
|
if self.hud_config.show_skills:
|
||||||
|
skills_box = QFrame()
|
||||||
|
skills_box.setStyleSheet("background-color: rgba(100, 50, 150, 80); border: 1px solid rgba(200, 150, 255, 50); border-radius: 4px;")
|
||||||
|
skills_layout = QHBoxLayout(skills_box)
|
||||||
|
skills_layout.setContentsMargins(8, 4, 8, 4)
|
||||||
|
|
||||||
|
self.skills_label = QLabel("Skills: 0.00")
|
||||||
|
self.skills_label.setStyleSheet("font-size: 11px; color: #DDA0DD;")
|
||||||
|
skills_layout.addWidget(self.skills_label)
|
||||||
|
skills_layout.addStretch()
|
||||||
|
|
||||||
|
layout.addWidget(skills_box)
|
||||||
|
|
||||||
# Separator before footer
|
# Separator before footer
|
||||||
sep_footer = QFrame()
|
sep_footer = QFrame()
|
||||||
sep_footer.setFrameShape(QFrame.Shape.HLine)
|
sep_footer.setFrameShape(QFrame.Shape.HLine)
|
||||||
|
|
@ -641,6 +667,8 @@ class HUDOverlay(QWidget):
|
||||||
height += 25
|
height += 25
|
||||||
if self.hud_config.show_damage_stats:
|
if self.hud_config.show_damage_stats:
|
||||||
height += 25
|
height += 25
|
||||||
|
if self.hud_config.show_skills:
|
||||||
|
height += 25
|
||||||
if self.hud_config.show_session_time:
|
if self.hud_config.show_session_time:
|
||||||
height += 20
|
height += 20
|
||||||
|
|
||||||
|
|
@ -809,31 +837,12 @@ class HUDOverlay(QWidget):
|
||||||
# Damage stats
|
# Damage stats
|
||||||
self._safe_set_text('damage_dealt_label', f"Dealt: {int(self._stats.damage_dealt)}")
|
self._safe_set_text('damage_dealt_label', f"Dealt: {int(self._stats.damage_dealt)}")
|
||||||
self._safe_set_text('damage_taken_label', f"Taken: {int(self._stats.damage_taken)}")
|
self._safe_set_text('damage_taken_label', f"Taken: {int(self._stats.damage_taken)}")
|
||||||
|
|
||||||
|
# Skills
|
||||||
|
if hasattr(self, 'skills_label'):
|
||||||
|
self._safe_set_text('skills_label', f"Skills: {self._stats.total_skill_gained:.2f}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error in _refresh_display: {e}")
|
logger.error(f"Error in _refresh_display: {e}")
|
||||||
self._safe_set_text('cps_label', f"Shot: {self._stats.cost_per_shot:.4f}")
|
|
||||||
self._safe_set_text('cph_label', f"Hit: {self._stats.cost_per_hit:.4f}")
|
|
||||||
self._safe_set_text('cphl_label', f"Heal: {self._stats.cost_per_heal:.4f}")
|
|
||||||
|
|
||||||
# Gear
|
|
||||||
self._safe_set_text('weapon_label', f"W: {self._stats.current_weapon[:20]}")
|
|
||||||
self._safe_set_text('armor_label', f"A: {self._stats.current_armor[:20]}")
|
|
||||||
self._safe_set_text('loadout_label', f"L: {self._stats.current_loadout[:20]}")
|
|
||||||
|
|
||||||
# Cost breakdown
|
|
||||||
self._safe_set_text('wep_cost_label', f"{self._stats.weapon_cost_total:.2f}")
|
|
||||||
self._safe_set_text('arm_cost_label', f"{self._stats.armor_cost_total:.2f}")
|
|
||||||
self._safe_set_text('heal_cost_label', f"{self._stats.healing_cost_total:.2f}")
|
|
||||||
|
|
||||||
# Combat
|
|
||||||
self._safe_set_text('kills_label', f"Kills: {self._stats.kills}")
|
|
||||||
self._safe_set_text('globals_label', f"Globals: {self._stats.globals_count}")
|
|
||||||
|
|
||||||
# Damage stats
|
|
||||||
self._safe_set_text('damage_dealt_label', f"Dealt: {int(self._stats.damage_dealt)}")
|
|
||||||
self._safe_set_text('damage_taken_label', f"Taken: {int(self._stats.damage_taken)}")
|
|
||||||
|
|
||||||
# Shrapnel (in summary section now - already updated above)
|
|
||||||
|
|
||||||
# === Public Update Methods ===
|
# === Public Update Methods ===
|
||||||
|
|
||||||
|
|
@ -909,6 +918,18 @@ class HUDOverlay(QWidget):
|
||||||
self._stats.kills += count
|
self._stats.kills += count
|
||||||
self._refresh_display()
|
self._refresh_display()
|
||||||
|
|
||||||
|
def update_skill(self, skill_name: str, amount: Decimal):
|
||||||
|
"""Update skill gain tracking."""
|
||||||
|
logger.debug(f"[HUD] update_skill called: skill={skill_name}, amount={amount}")
|
||||||
|
if self.session_active:
|
||||||
|
# Track per-skill gains
|
||||||
|
if skill_name not in self._stats.skill_gains:
|
||||||
|
self._stats.skill_gains[skill_name] = Decimal('0.0')
|
||||||
|
self._stats.skill_gains[skill_name] += amount
|
||||||
|
# Update total
|
||||||
|
self._stats.total_skill_gained += amount
|
||||||
|
self._refresh_display()
|
||||||
|
|
||||||
def update_globals(self):
|
def update_globals(self):
|
||||||
"""Update global count."""
|
"""Update global count."""
|
||||||
if self.session_active:
|
if self.session_active:
|
||||||
|
|
|
||||||
|
|
@ -1137,9 +1137,17 @@ class MainWindow(QMainWindow):
|
||||||
|
|
||||||
def on_skill(event):
|
def on_skill(event):
|
||||||
"""Handle skill events."""
|
"""Handle skill events."""
|
||||||
|
from decimal import Decimal
|
||||||
skill_name = event.data.get('skill_name', 'Unknown')
|
skill_name = event.data.get('skill_name', 'Unknown')
|
||||||
gained = event.data.get('gained', 0)
|
gained = event.data.get('gained', 0)
|
||||||
self.log_info("Skill", f"{skill_name} +{gained}")
|
self.log_info("Skill", f"{skill_name} +{gained}")
|
||||||
|
|
||||||
|
# Update HUD skill tracking
|
||||||
|
try:
|
||||||
|
gained_decimal = Decimal(str(gained))
|
||||||
|
self.hud.update_skill(skill_name, gained_decimal)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[ERROR] Error updating HUD skill: {e}")
|
||||||
|
|
||||||
def on_damage_dealt(event):
|
def on_damage_dealt(event):
|
||||||
"""Handle damage dealt - track damage stats and weapon cost."""
|
"""Handle damage dealt - track damage stats and weapon cost."""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue