fix: add missing UI elements for damage stats and shrapnel
- Add damage_dealt and damage_taken to HUDStats - Add shrapnel_total to HUDStats - Add UI elements for damage stats in _setup_ui - Add UI element for shrapnel in _setup_ui - Update window size calculation for new elements - Update _refresh_display to show damage and shrapnel - Add update_damage() and update_shrapnel() public methods
This commit is contained in:
parent
5c4ce8f307
commit
61d2ad2019
|
|
@ -15,7 +15,7 @@ from typing import Optional, Dict, Any, List, Set
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
import ctypes
|
import ctypes
|
||||||
from ctypes import wintypes
|
from ctypes import wintypes
|
||||||
|
|
||||||
user32 = ctypes.windll.user32
|
user32 = ctypes.windll.user32
|
||||||
GetForegroundWindow = user32.GetForegroundWindow
|
GetForegroundWindow = user32.GetForegroundWindow
|
||||||
GetForegroundWindow.restype = wintypes.HWND
|
GetForegroundWindow.restype = wintypes.HWND
|
||||||
|
|
@ -45,9 +45,9 @@ 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
|
show_shrapnel: bool = False
|
||||||
show_gear_info: bool = True
|
show_gear_info: bool = True
|
||||||
|
|
||||||
compact_mode: bool = False
|
compact_mode: bool = False
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
return {
|
return {
|
||||||
'show_session_time': self.show_session_time,
|
'show_session_time': self.show_session_time,
|
||||||
|
|
@ -62,7 +62,7 @@ class HUDConfig:
|
||||||
'show_gear_info': self.show_gear_info,
|
'show_gear_info': self.show_gear_info,
|
||||||
'compact_mode': self.compact_mode,
|
'compact_mode': self.compact_mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, data: dict) -> "HUDConfig":
|
def from_dict(cls, data: dict) -> "HUDConfig":
|
||||||
return cls(
|
return cls(
|
||||||
|
|
@ -84,34 +84,41 @@ class HUDConfig:
|
||||||
class HUDStats:
|
class HUDStats:
|
||||||
"""Simplified stats for HUD display."""
|
"""Simplified stats for HUD display."""
|
||||||
session_time: timedelta = field(default_factory=lambda: timedelta(0))
|
session_time: timedelta = field(default_factory=lambda: timedelta(0))
|
||||||
|
|
||||||
# Financial (core)
|
# Financial (core)
|
||||||
loot_total: Decimal = Decimal('0.0')
|
loot_total: Decimal = Decimal('0.0')
|
||||||
cost_total: Decimal = Decimal('0.0')
|
cost_total: Decimal = Decimal('0.0')
|
||||||
profit_loss: Decimal = Decimal('0.0')
|
profit_loss: Decimal = Decimal('0.0')
|
||||||
return_percentage: Decimal = Decimal('0.0')
|
return_percentage: Decimal = Decimal('0.0')
|
||||||
|
|
||||||
# Cost breakdown (optional)
|
# Cost breakdown (optional)
|
||||||
weapon_cost_total: Decimal = Decimal('0.0')
|
weapon_cost_total: Decimal = Decimal('0.0')
|
||||||
armor_cost_total: Decimal = Decimal('0.0')
|
armor_cost_total: Decimal = Decimal('0.0')
|
||||||
healing_cost_total: Decimal = Decimal('0.0')
|
healing_cost_total: Decimal = Decimal('0.0')
|
||||||
|
|
||||||
# Combat (optional)
|
# Combat (optional)
|
||||||
kills: int = 0
|
kills: int = 0
|
||||||
globals_count: int = 0
|
globals_count: int = 0
|
||||||
hofs_count: int = 0
|
hofs_count: int = 0
|
||||||
|
|
||||||
|
# Damage stats (optional)
|
||||||
|
damage_dealt: Decimal = Decimal('0.0')
|
||||||
|
damage_taken: Decimal = Decimal('0.0')
|
||||||
|
|
||||||
|
# Shrapnel (optional)
|
||||||
|
shrapnel_total: Decimal = Decimal('0.0')
|
||||||
|
|
||||||
# Cost metrics (core)
|
# Cost metrics (core)
|
||||||
cost_per_shot: Decimal = Decimal('0.0')
|
cost_per_shot: Decimal = Decimal('0.0')
|
||||||
cost_per_hit: Decimal = Decimal('0.0')
|
cost_per_hit: Decimal = Decimal('0.0')
|
||||||
cost_per_heal: Decimal = Decimal('0.0')
|
cost_per_heal: Decimal = Decimal('0.0')
|
||||||
|
|
||||||
# Gear
|
# Gear
|
||||||
current_weapon: str = "None"
|
current_weapon: str = "None"
|
||||||
current_armor: str = "None"
|
current_armor: str = "None"
|
||||||
current_fap: str = "None"
|
current_fap: str = "None"
|
||||||
current_loadout: str = "None"
|
current_loadout: str = "None"
|
||||||
|
|
||||||
def recalculate(self):
|
def recalculate(self):
|
||||||
"""Recalculate derived values."""
|
"""Recalculate derived values."""
|
||||||
self.profit_loss = self.loot_total - self.cost_total
|
self.profit_loss = self.loot_total - self.cost_total
|
||||||
|
|
@ -119,7 +126,7 @@ class HUDStats:
|
||||||
self.return_percentage = (self.loot_total / self.cost_total) * Decimal('100')
|
self.return_percentage = (self.loot_total / self.cost_total) * Decimal('100')
|
||||||
else:
|
else:
|
||||||
self.return_percentage = Decimal('0')
|
self.return_percentage = Decimal('0')
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
return {
|
return {
|
||||||
'session_time': str(self.session_time),
|
'session_time': str(self.session_time),
|
||||||
|
|
@ -145,93 +152,93 @@ class HUDStats:
|
||||||
|
|
||||||
class HUDSettingsDialog(QDialog):
|
class HUDSettingsDialog(QDialog):
|
||||||
"""Dialog to configure which HUD elements to show."""
|
"""Dialog to configure which HUD elements to show."""
|
||||||
|
|
||||||
def __init__(self, config: HUDConfig, parent=None):
|
def __init__(self, config: HUDConfig, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setWindowTitle("HUD Settings")
|
self.setWindowTitle("HUD Settings")
|
||||||
self.setMinimumWidth(300)
|
self.setMinimumWidth(300)
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
self._setup_ui()
|
self._setup_ui()
|
||||||
|
|
||||||
def _setup_ui(self):
|
def _setup_ui(self):
|
||||||
layout = QVBoxLayout(self)
|
layout = QVBoxLayout(self)
|
||||||
|
|
||||||
scroll = QScrollArea()
|
scroll = QScrollArea()
|
||||||
scroll.setWidgetResizable(True)
|
scroll.setWidgetResizable(True)
|
||||||
content = QWidget()
|
content = QWidget()
|
||||||
form = QFormLayout(content)
|
form = QFormLayout(content)
|
||||||
|
|
||||||
# Core stats (always recommended)
|
# Core stats (always recommended)
|
||||||
form.addRow(QLabel("<b>Core Stats (Recommended)</b>"))
|
form.addRow(QLabel("<b>Core Stats (Recommended)</b>"))
|
||||||
|
|
||||||
self.cb_time = QCheckBox("Session Time")
|
self.cb_time = QCheckBox("Session Time")
|
||||||
self.cb_time.setChecked(self.config.show_session_time)
|
self.cb_time.setChecked(self.config.show_session_time)
|
||||||
form.addRow(self.cb_time)
|
form.addRow(self.cb_time)
|
||||||
|
|
||||||
self.cb_profit = QCheckBox("Profit/Loss")
|
self.cb_profit = QCheckBox("Profit/Loss")
|
||||||
self.cb_profit.setChecked(self.config.show_profit_loss)
|
self.cb_profit.setChecked(self.config.show_profit_loss)
|
||||||
form.addRow(self.cb_profit)
|
form.addRow(self.cb_profit)
|
||||||
|
|
||||||
self.cb_return = QCheckBox("Return %")
|
self.cb_return = QCheckBox("Return %")
|
||||||
self.cb_return.setChecked(self.config.show_return_pct)
|
self.cb_return.setChecked(self.config.show_return_pct)
|
||||||
form.addRow(self.cb_return)
|
form.addRow(self.cb_return)
|
||||||
|
|
||||||
self.cb_total_cost = QCheckBox("Total Cost")
|
self.cb_total_cost = QCheckBox("Total Cost")
|
||||||
self.cb_total_cost.setChecked(self.config.show_total_cost)
|
self.cb_total_cost.setChecked(self.config.show_total_cost)
|
||||||
form.addRow(self.cb_total_cost)
|
form.addRow(self.cb_total_cost)
|
||||||
|
|
||||||
self.cb_cost_metrics = QCheckBox("Cost per Shot/Hit/Heal")
|
self.cb_cost_metrics = QCheckBox("Cost per Shot/Hit/Heal")
|
||||||
self.cb_cost_metrics.setChecked(self.config.show_cost_metrics)
|
self.cb_cost_metrics.setChecked(self.config.show_cost_metrics)
|
||||||
form.addRow(self.cb_cost_metrics)
|
form.addRow(self.cb_cost_metrics)
|
||||||
|
|
||||||
self.cb_gear = QCheckBox("Current Gear")
|
self.cb_gear = QCheckBox("Current Gear")
|
||||||
self.cb_gear.setChecked(self.config.show_gear_info)
|
self.cb_gear.setChecked(self.config.show_gear_info)
|
||||||
form.addRow(self.cb_gear)
|
form.addRow(self.cb_gear)
|
||||||
|
|
||||||
# Optional stats
|
# Optional stats
|
||||||
form.addRow(QLabel("<b>Optional Stats</b>"))
|
form.addRow(QLabel("<b>Optional Stats</b>"))
|
||||||
|
|
||||||
self.cb_cost_breakdown = QCheckBox("Cost Breakdown (Weapon/Armor/Heal)")
|
self.cb_cost_breakdown = QCheckBox("Cost Breakdown (Weapon/Armor/Heal)")
|
||||||
self.cb_cost_breakdown.setChecked(self.config.show_cost_breakdown)
|
self.cb_cost_breakdown.setChecked(self.config.show_cost_breakdown)
|
||||||
form.addRow(self.cb_cost_breakdown)
|
form.addRow(self.cb_cost_breakdown)
|
||||||
|
|
||||||
self.cb_combat = QCheckBox("Combat Stats (Kills, Globals)")
|
self.cb_combat = QCheckBox("Combat Stats (Kills, Globals)")
|
||||||
self.cb_combat.setChecked(self.config.show_combat_stats)
|
self.cb_combat.setChecked(self.config.show_combat_stats)
|
||||||
form.addRow(self.cb_combat)
|
form.addRow(self.cb_combat)
|
||||||
|
|
||||||
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_shrapnel = QCheckBox("Shrapnel Amount")
|
self.cb_shrapnel = QCheckBox("Shrapnel Amount")
|
||||||
self.cb_shrapnel.setChecked(self.config.show_shrapnel)
|
self.cb_shrapnel.setChecked(self.config.show_shrapnel)
|
||||||
form.addRow(self.cb_shrapnel)
|
form.addRow(self.cb_shrapnel)
|
||||||
|
|
||||||
# Display mode
|
# Display mode
|
||||||
form.addRow(QLabel("<b>Display Mode</b>"))
|
form.addRow(QLabel("<b>Display Mode</b>"))
|
||||||
|
|
||||||
self.cb_compact = QCheckBox("Compact Mode (smaller font)")
|
self.cb_compact = QCheckBox("Compact Mode (smaller font)")
|
||||||
self.cb_compact.setChecked(self.config.compact_mode)
|
self.cb_compact.setChecked(self.config.compact_mode)
|
||||||
form.addRow(self.cb_compact)
|
form.addRow(self.cb_compact)
|
||||||
|
|
||||||
scroll.setWidget(content)
|
scroll.setWidget(content)
|
||||||
layout.addWidget(scroll)
|
layout.addWidget(scroll)
|
||||||
|
|
||||||
# Buttons
|
# Buttons
|
||||||
btn_layout = QHBoxLayout()
|
btn_layout = QHBoxLayout()
|
||||||
btn_layout.addStretch()
|
btn_layout.addStretch()
|
||||||
|
|
||||||
save_btn = QPushButton("Save")
|
save_btn = QPushButton("Save")
|
||||||
save_btn.clicked.connect(self._on_save)
|
save_btn.clicked.connect(self._on_save)
|
||||||
btn_layout.addWidget(save_btn)
|
btn_layout.addWidget(save_btn)
|
||||||
|
|
||||||
cancel_btn = QPushButton("Cancel")
|
cancel_btn = QPushButton("Cancel")
|
||||||
cancel_btn.clicked.connect(self.reject)
|
cancel_btn.clicked.connect(self.reject)
|
||||||
btn_layout.addWidget(cancel_btn)
|
btn_layout.addWidget(cancel_btn)
|
||||||
|
|
||||||
layout.addLayout(btn_layout)
|
layout.addLayout(btn_layout)
|
||||||
|
|
||||||
def _on_save(self):
|
def _on_save(self):
|
||||||
self.config.show_session_time = self.cb_time.isChecked()
|
self.config.show_session_time = self.cb_time.isChecked()
|
||||||
self.config.show_profit_loss = self.cb_profit.isChecked()
|
self.config.show_profit_loss = self.cb_profit.isChecked()
|
||||||
|
|
@ -245,7 +252,7 @@ class HUDSettingsDialog(QDialog):
|
||||||
self.config.show_shrapnel = self.cb_shrapnel.isChecked()
|
self.config.show_shrapnel = self.cb_shrapnel.isChecked()
|
||||||
self.config.compact_mode = self.cb_compact.isChecked()
|
self.config.compact_mode = self.cb_compact.isChecked()
|
||||||
self.accept()
|
self.accept()
|
||||||
|
|
||||||
def get_config(self) -> HUDConfig:
|
def get_config(self) -> HUDConfig:
|
||||||
return self.config
|
return self.config
|
||||||
|
|
||||||
|
|
@ -253,44 +260,44 @@ class HUDSettingsDialog(QDialog):
|
||||||
class HUDOverlay(QWidget):
|
class HUDOverlay(QWidget):
|
||||||
"""
|
"""
|
||||||
Clean, customizable HUD Overlay for Lemontropia Suite.
|
Clean, customizable HUD Overlay for Lemontropia Suite.
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Collapsible sections
|
- Collapsible sections
|
||||||
- Customizable display elements
|
- Customizable display elements
|
||||||
- Compact mode
|
- Compact mode
|
||||||
- Draggable with Ctrl+click
|
- Draggable with Ctrl+click
|
||||||
"""
|
"""
|
||||||
|
|
||||||
position_changed = pyqtSignal(QPoint)
|
position_changed = pyqtSignal(QPoint)
|
||||||
stats_updated = pyqtSignal(dict)
|
stats_updated = pyqtSignal(dict)
|
||||||
|
|
||||||
def __init__(self, parent=None, config_path: Optional[str] = None):
|
def __init__(self, parent=None, config_path: Optional[str] = None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self.config_path = Path(config_path) if config_path else Path.home() / ".lemontropia" / "hud_config.json"
|
self.config_path = Path(config_path) if config_path else Path.home() / ".lemontropia" / "hud_config.json"
|
||||||
self.config_path.parent.mkdir(parents=True, exist_ok=True)
|
self.config_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
# Load HUD config
|
# Load HUD config
|
||||||
self.hud_config = self._load_hud_config()
|
self.hud_config = self._load_hud_config()
|
||||||
|
|
||||||
# Session state
|
# Session state
|
||||||
self._session_start: Optional[datetime] = None
|
self._session_start: Optional[datetime] = None
|
||||||
self._stats = HUDStats()
|
self._stats = HUDStats()
|
||||||
self.session_active = False
|
self.session_active = False
|
||||||
|
|
||||||
# Drag state
|
# Drag state
|
||||||
self._dragging = False
|
self._dragging = False
|
||||||
self._drag_offset = QPoint()
|
self._drag_offset = QPoint()
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
self._setup_window()
|
self._setup_window()
|
||||||
self._setup_ui()
|
self._setup_ui()
|
||||||
self._load_position()
|
self._load_position()
|
||||||
|
|
||||||
# Timer for session time
|
# Timer for session time
|
||||||
self._timer = QTimer(self)
|
self._timer = QTimer(self)
|
||||||
self._timer.timeout.connect(self._update_session_time)
|
self._timer.timeout.connect(self._update_session_time)
|
||||||
|
|
||||||
def _load_hud_config(self) -> HUDConfig:
|
def _load_hud_config(self) -> HUDConfig:
|
||||||
"""Load HUD configuration."""
|
"""Load HUD configuration."""
|
||||||
try:
|
try:
|
||||||
|
|
@ -301,7 +308,7 @@ class HUDOverlay(QWidget):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
return HUDConfig() # Default config
|
return HUDConfig() # Default config
|
||||||
|
|
||||||
def _save_hud_config(self):
|
def _save_hud_config(self):
|
||||||
"""Save HUD configuration."""
|
"""Save HUD configuration."""
|
||||||
try:
|
try:
|
||||||
|
|
@ -309,7 +316,7 @@ class HUDOverlay(QWidget):
|
||||||
json.dump(self.hud_config.to_dict(), f, indent=2)
|
json.dump(self.hud_config.to_dict(), f, indent=2)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _setup_window(self):
|
def _setup_window(self):
|
||||||
"""Configure window properties."""
|
"""Configure window properties."""
|
||||||
self.setWindowFlags(
|
self.setWindowFlags(
|
||||||
|
|
@ -320,30 +327,30 @@ class HUDOverlay(QWidget):
|
||||||
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
|
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
|
||||||
self.setMouseTracking(True)
|
self.setMouseTracking(True)
|
||||||
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
||||||
|
|
||||||
def _setup_ui(self):
|
def _setup_ui(self):
|
||||||
"""Build the HUD UI."""
|
"""Build the HUD UI."""
|
||||||
# Create container first
|
# Create container first
|
||||||
self.container = QFrame(self)
|
self.container = QFrame(self)
|
||||||
self.container.setObjectName("hudContainer")
|
self.container.setObjectName("hudContainer")
|
||||||
self.container.setStyleSheet(self._get_stylesheet())
|
self.container.setStyleSheet(self._get_stylesheet())
|
||||||
|
|
||||||
# Now calculate and set size
|
# Now calculate and set size
|
||||||
self._update_window_size()
|
self._update_window_size()
|
||||||
|
|
||||||
layout = QVBoxLayout(self.container)
|
layout = QVBoxLayout(self.container)
|
||||||
layout.setContentsMargins(12, 12, 12, 8)
|
layout.setContentsMargins(12, 12, 12, 8)
|
||||||
layout.setSpacing(4)
|
layout.setSpacing(4)
|
||||||
|
|
||||||
# === HEADER: Status + Gear ===
|
# === HEADER: Status + Gear ===
|
||||||
header = QHBoxLayout()
|
header = QHBoxLayout()
|
||||||
|
|
||||||
self.status_label = QLabel("● Ready")
|
self.status_label = QLabel("● Ready")
|
||||||
self.status_label.setStyleSheet("color: #7FFF7F; font-weight: bold;")
|
self.status_label.setStyleSheet("color: #7FFF7F; font-weight: bold;")
|
||||||
header.addWidget(self.status_label)
|
header.addWidget(self.status_label)
|
||||||
|
|
||||||
header.addStretch()
|
header.addStretch()
|
||||||
|
|
||||||
# Settings button
|
# Settings button
|
||||||
self.settings_btn = QPushButton("⚙️")
|
self.settings_btn = QPushButton("⚙️")
|
||||||
self.settings_btn.setFixedSize(24, 24)
|
self.settings_btn.setFixedSize(24, 24)
|
||||||
|
|
@ -360,141 +367,168 @@ class HUDOverlay(QWidget):
|
||||||
""")
|
""")
|
||||||
self.settings_btn.clicked.connect(self._show_settings)
|
self.settings_btn.clicked.connect(self._show_settings)
|
||||||
header.addWidget(self.settings_btn)
|
header.addWidget(self.settings_btn)
|
||||||
|
|
||||||
layout.addLayout(header)
|
layout.addLayout(header)
|
||||||
|
|
||||||
# === GEAR INFO (if enabled) ===
|
# === GEAR INFO (if enabled) ===
|
||||||
if self.hud_config.show_gear_info:
|
if self.hud_config.show_gear_info:
|
||||||
self.gear_frame = QFrame()
|
self.gear_frame = QFrame()
|
||||||
gear_layout = QVBoxLayout(self.gear_frame)
|
gear_layout = QVBoxLayout(self.gear_frame)
|
||||||
gear_layout.setContentsMargins(0, 0, 0, 0)
|
gear_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
gear_layout.setSpacing(2)
|
gear_layout.setSpacing(2)
|
||||||
|
|
||||||
self.weapon_label = QLabel("🔫 None")
|
self.weapon_label = QLabel("🔫 None")
|
||||||
self.armor_label = QLabel("🛡️ None")
|
self.armor_label = QLabel("🛡️ None")
|
||||||
self.loadout_label = QLabel("📋 No Loadout")
|
self.loadout_label = QLabel("📋 No Loadout")
|
||||||
|
|
||||||
gear_layout.addWidget(self.weapon_label)
|
gear_layout.addWidget(self.weapon_label)
|
||||||
gear_layout.addWidget(self.armor_label)
|
gear_layout.addWidget(self.armor_label)
|
||||||
gear_layout.addWidget(self.loadout_label)
|
gear_layout.addWidget(self.loadout_label)
|
||||||
|
|
||||||
layout.addWidget(self.gear_frame)
|
layout.addWidget(self.gear_frame)
|
||||||
|
|
||||||
# Separator
|
# Separator
|
||||||
sep = QFrame()
|
sep = QFrame()
|
||||||
sep.setFrameShape(QFrame.Shape.HLine)
|
sep.setFrameShape(QFrame.Shape.HLine)
|
||||||
sep.setStyleSheet("background-color: rgba(255, 215, 0, 50);")
|
sep.setStyleSheet("background-color: rgba(255, 215, 0, 50);")
|
||||||
sep.setFixedHeight(1)
|
sep.setFixedHeight(1)
|
||||||
layout.addWidget(sep)
|
layout.addWidget(sep)
|
||||||
|
|
||||||
# === CORE: P/L + Return % ===
|
# === CORE: P/L + Return % ===
|
||||||
if self.hud_config.show_profit_loss or self.hud_config.show_return_pct:
|
if self.hud_config.show_profit_loss or self.hud_config.show_return_pct:
|
||||||
core_frame = QFrame()
|
core_frame = QFrame()
|
||||||
core_layout = QHBoxLayout(core_frame)
|
core_layout = QHBoxLayout(core_frame)
|
||||||
core_layout.setContentsMargins(0, 4, 0, 4)
|
core_layout.setContentsMargins(0, 4, 0, 4)
|
||||||
|
|
||||||
if self.hud_config.show_profit_loss:
|
if self.hud_config.show_profit_loss:
|
||||||
self.profit_label = QLabel("P/L: 0.00 PED")
|
self.profit_label = QLabel("P/L: 0.00 PED")
|
||||||
self.profit_label.setStyleSheet("font-size: 18px; font-weight: bold;")
|
self.profit_label.setStyleSheet("font-size: 18px; font-weight: bold;")
|
||||||
core_layout.addWidget(self.profit_label)
|
core_layout.addWidget(self.profit_label)
|
||||||
|
|
||||||
core_layout.addStretch()
|
core_layout.addStretch()
|
||||||
|
|
||||||
if self.hud_config.show_return_pct:
|
if self.hud_config.show_return_pct:
|
||||||
self.return_label = QLabel("0.0%")
|
self.return_label = QLabel("0.0%")
|
||||||
self.return_label.setStyleSheet("font-size: 16px; font-weight: bold;")
|
self.return_label.setStyleSheet("font-size: 16px; font-weight: bold;")
|
||||||
core_layout.addWidget(self.return_label)
|
core_layout.addWidget(self.return_label)
|
||||||
|
|
||||||
layout.addWidget(core_frame)
|
layout.addWidget(core_frame)
|
||||||
|
|
||||||
# === TOTAL COST (if enabled) ===
|
# === TOTAL COST (if enabled) ===
|
||||||
if self.hud_config.show_total_cost:
|
if self.hud_config.show_total_cost:
|
||||||
total_cost_frame = QFrame()
|
total_cost_frame = QFrame()
|
||||||
total_cost_layout = QHBoxLayout(total_cost_frame)
|
total_cost_layout = QHBoxLayout(total_cost_frame)
|
||||||
total_cost_layout.setContentsMargins(0, 0, 0, 0)
|
total_cost_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
self.total_cost_label = QLabel("Cost: 0.00 PED")
|
self.total_cost_label = QLabel("Cost: 0.00 PED")
|
||||||
self.total_cost_label.setStyleSheet("font-size: 14px; color: #FFAAAA;")
|
self.total_cost_label.setStyleSheet("font-size: 14px; color: #FFAAAA;")
|
||||||
total_cost_layout.addWidget(self.total_cost_label)
|
total_cost_layout.addWidget(self.total_cost_label)
|
||||||
total_cost_layout.addStretch()
|
total_cost_layout.addStretch()
|
||||||
|
|
||||||
layout.addWidget(total_cost_frame)
|
layout.addWidget(total_cost_frame)
|
||||||
|
|
||||||
# === COST METRICS (if enabled) ===
|
# === COST METRICS (if enabled) ===
|
||||||
if self.hud_config.show_cost_metrics:
|
if self.hud_config.show_cost_metrics:
|
||||||
metrics_frame = QFrame()
|
metrics_frame = QFrame()
|
||||||
metrics_frame.setStyleSheet("background-color: rgba(0, 0, 0, 100); border-radius: 4px;")
|
metrics_frame.setStyleSheet("background-color: rgba(0, 0, 0, 100); border-radius: 4px;")
|
||||||
metrics_layout = QHBoxLayout(metrics_frame)
|
metrics_layout = QHBoxLayout(metrics_frame)
|
||||||
metrics_layout.setContentsMargins(8, 4, 8, 4)
|
metrics_layout.setContentsMargins(8, 4, 8, 4)
|
||||||
|
|
||||||
self.cps_label = QLabel("Shot: 0.0000")
|
self.cps_label = QLabel("Shot: 0.0000")
|
||||||
self.cph_label = QLabel("Hit: 0.0000")
|
self.cph_label = QLabel("Hit: 0.0000")
|
||||||
self.cphl_label = QLabel("Heal: 0.0000")
|
self.cphl_label = QLabel("Heal: 0.0000")
|
||||||
|
|
||||||
for lbl in [self.cps_label, self.cph_label, self.cphl_label]:
|
for lbl in [self.cps_label, self.cph_label, self.cphl_label]:
|
||||||
lbl.setStyleSheet("font-size: 10px; color: #AAAAAA;")
|
lbl.setStyleSheet("font-size: 10px; color: #AAAAAA;")
|
||||||
metrics_layout.addWidget(lbl)
|
metrics_layout.addWidget(lbl)
|
||||||
|
|
||||||
metrics_layout.addStretch()
|
metrics_layout.addStretch()
|
||||||
layout.addWidget(metrics_frame)
|
layout.addWidget(metrics_frame)
|
||||||
|
|
||||||
# === OPTIONAL: Cost Breakdown ===
|
# === OPTIONAL: Cost Breakdown ===
|
||||||
if self.hud_config.show_cost_breakdown:
|
if self.hud_config.show_cost_breakdown:
|
||||||
breakdown_frame = QFrame()
|
breakdown_frame = QFrame()
|
||||||
breakdown_layout = QFormLayout(breakdown_frame)
|
breakdown_layout = QFormLayout(breakdown_frame)
|
||||||
breakdown_layout.setContentsMargins(0, 0, 0, 0)
|
breakdown_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
breakdown_layout.setSpacing(2)
|
breakdown_layout.setSpacing(2)
|
||||||
|
|
||||||
self.wep_cost_label = QLabel("0.00")
|
self.wep_cost_label = QLabel("0.00")
|
||||||
self.arm_cost_label = QLabel("0.00")
|
self.arm_cost_label = QLabel("0.00")
|
||||||
self.heal_cost_label = QLabel("0.00")
|
self.heal_cost_label = QLabel("0.00")
|
||||||
|
|
||||||
breakdown_layout.addRow("Weapon:", self.wep_cost_label)
|
breakdown_layout.addRow("Weapon:", self.wep_cost_label)
|
||||||
breakdown_layout.addRow("Armor:", self.arm_cost_label)
|
breakdown_layout.addRow("Armor:", self.arm_cost_label)
|
||||||
breakdown_layout.addRow("Healing:", self.heal_cost_label)
|
breakdown_layout.addRow("Healing:", self.heal_cost_label)
|
||||||
|
|
||||||
layout.addWidget(breakdown_frame)
|
layout.addWidget(breakdown_frame)
|
||||||
|
|
||||||
# === OPTIONAL: Combat Stats ===
|
# === OPTIONAL: Combat Stats ===
|
||||||
if self.hud_config.show_combat_stats:
|
if self.hud_config.show_combat_stats:
|
||||||
combat_frame = QFrame()
|
combat_frame = QFrame()
|
||||||
combat_layout = QHBoxLayout(combat_frame)
|
combat_layout = QHBoxLayout(combat_frame)
|
||||||
combat_layout.setContentsMargins(0, 0, 0, 0)
|
combat_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
self.kills_label = QLabel("Kills: 0")
|
self.kills_label = QLabel("Kills: 0")
|
||||||
self.globals_label = QLabel("Globals: 0")
|
self.globals_label = QLabel("Globals: 0")
|
||||||
|
|
||||||
combat_layout.addWidget(self.kills_label)
|
combat_layout.addWidget(self.kills_label)
|
||||||
combat_layout.addStretch()
|
combat_layout.addStretch()
|
||||||
combat_layout.addWidget(self.globals_label)
|
combat_layout.addWidget(self.globals_label)
|
||||||
|
|
||||||
layout.addWidget(combat_frame)
|
layout.addWidget(combat_frame)
|
||||||
|
|
||||||
|
# === OPTIONAL: Damage Stats ===
|
||||||
|
if self.hud_config.show_damage_stats:
|
||||||
|
damage_frame = QFrame()
|
||||||
|
damage_layout = QHBoxLayout(damage_frame)
|
||||||
|
damage_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
|
self.damage_dealt_label = QLabel("Dealt: 0")
|
||||||
|
self.damage_taken_label = QLabel("Taken: 0")
|
||||||
|
|
||||||
|
damage_layout.addWidget(self.damage_dealt_label)
|
||||||
|
damage_layout.addStretch()
|
||||||
|
damage_layout.addWidget(self.damage_taken_label)
|
||||||
|
|
||||||
|
layout.addWidget(damage_frame)
|
||||||
|
|
||||||
|
# === OPTIONAL: Shrapnel ===
|
||||||
|
if self.hud_config.show_shrapnel:
|
||||||
|
shrapnel_frame = QFrame()
|
||||||
|
shrapnel_layout = QHBoxLayout(shrapnel_frame)
|
||||||
|
shrapnel_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
|
self.shrapnel_label = QLabel("💎 Shrapnel: 0.00 PED")
|
||||||
|
shrapnel_layout.addWidget(self.shrapnel_label)
|
||||||
|
shrapnel_layout.addStretch()
|
||||||
|
|
||||||
|
layout.addWidget(shrapnel_frame)
|
||||||
|
|
||||||
# === FOOTER: Session Time + Drag Hint ===
|
# === FOOTER: Session Time + Drag Hint ===
|
||||||
footer = QHBoxLayout()
|
footer = QHBoxLayout()
|
||||||
|
|
||||||
if self.hud_config.show_session_time:
|
if self.hud_config.show_session_time:
|
||||||
self.time_label = QLabel("00:00:00")
|
self.time_label = QLabel("00:00:00")
|
||||||
self.time_label.setStyleSheet("color: #888; font-size: 11px;")
|
self.time_label.setStyleSheet("color: #888; font-size: 11px;")
|
||||||
footer.addWidget(self.time_label)
|
footer.addWidget(self.time_label)
|
||||||
else:
|
else:
|
||||||
footer.addStretch()
|
footer.addStretch()
|
||||||
|
|
||||||
footer.addStretch()
|
footer.addStretch()
|
||||||
|
|
||||||
self.drag_hint = QLabel("Ctrl+drag to move")
|
self.drag_hint = QLabel("Ctrl+drag to move")
|
||||||
self.drag_hint.setStyleSheet("font-size: 9px; color: #666;")
|
self.drag_hint.setStyleSheet("font-size: 9px; color: #666;")
|
||||||
footer.addWidget(self.drag_hint)
|
footer.addWidget(self.drag_hint)
|
||||||
|
|
||||||
layout.addLayout(footer)
|
layout.addLayout(footer)
|
||||||
|
|
||||||
# Ensure container is visible
|
# Ensure container is visible
|
||||||
self.container.show()
|
self.container.show()
|
||||||
|
|
||||||
def _get_stylesheet(self) -> str:
|
def _get_stylesheet(self) -> str:
|
||||||
"""Get stylesheet based on compact mode."""
|
"""Get stylesheet based on compact mode."""
|
||||||
font_size = "11px" if self.hud_config.compact_mode else "12px"
|
font_size = "11px" if self.hud_config.compact_mode else "12px"
|
||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
#hudContainer {{
|
#hudContainer {{
|
||||||
background-color: rgba(0, 0, 0, 180);
|
background-color: rgba(0, 0, 0, 180);
|
||||||
|
|
@ -507,11 +541,11 @@ class HUDOverlay(QWidget):
|
||||||
font-size: {font_size};
|
font-size: {font_size};
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _update_window_size(self):
|
def _update_window_size(self):
|
||||||
"""Calculate window size based on enabled features."""
|
"""Calculate window size based on enabled features."""
|
||||||
height = 80 # Base height
|
height = 80 # Base height
|
||||||
|
|
||||||
if self.hud_config.show_gear_info:
|
if self.hud_config.show_gear_info:
|
||||||
height += 70
|
height += 70
|
||||||
if self.hud_config.show_profit_loss or self.hud_config.show_return_pct:
|
if self.hud_config.show_profit_loss or self.hud_config.show_return_pct:
|
||||||
|
|
@ -524,14 +558,18 @@ class HUDOverlay(QWidget):
|
||||||
height += 70
|
height += 70
|
||||||
if self.hud_config.show_combat_stats:
|
if self.hud_config.show_combat_stats:
|
||||||
height += 25
|
height += 25
|
||||||
|
if self.hud_config.show_damage_stats:
|
||||||
|
height += 25
|
||||||
|
if self.hud_config.show_shrapnel:
|
||||||
|
height += 25
|
||||||
if self.hud_config.show_session_time:
|
if self.hud_config.show_session_time:
|
||||||
height += 20
|
height += 20
|
||||||
|
|
||||||
width = 280 if self.hud_config.compact_mode else 320
|
width = 280 if self.hud_config.compact_mode else 320
|
||||||
|
|
||||||
self.setFixedSize(width, height)
|
self.setFixedSize(width, height)
|
||||||
self.container.setFixedSize(width, height)
|
self.container.setFixedSize(width, height)
|
||||||
|
|
||||||
def _show_settings(self):
|
def _show_settings(self):
|
||||||
"""Show settings dialog."""
|
"""Show settings dialog."""
|
||||||
dialog = HUDSettingsDialog(self.hud_config, self)
|
dialog = HUDSettingsDialog(self.hud_config, self)
|
||||||
|
|
@ -540,21 +578,21 @@ class HUDOverlay(QWidget):
|
||||||
self._save_hud_config()
|
self._save_hud_config()
|
||||||
# Rebuild UI with new settings
|
# Rebuild UI with new settings
|
||||||
self._rebuild_ui()
|
self._rebuild_ui()
|
||||||
|
|
||||||
def _rebuild_ui(self):
|
def _rebuild_ui(self):
|
||||||
"""Rebuild UI with current config."""
|
"""Rebuild UI with current config."""
|
||||||
# Hide first to avoid visual glitch
|
# Hide first to avoid visual glitch
|
||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
# Delete old container
|
# Delete old container
|
||||||
if hasattr(self, 'container') and self.container:
|
if hasattr(self, 'container') and self.container:
|
||||||
self.container.deleteLater()
|
self.container.deleteLater()
|
||||||
self.container = None
|
self.container = None
|
||||||
|
|
||||||
# Small delay to ensure cleanup
|
# Small delay to ensure cleanup
|
||||||
from PyQt6.QtCore import QTimer
|
from PyQt6.QtCore import QTimer
|
||||||
QTimer.singleShot(10, self._do_rebuild)
|
QTimer.singleShot(10, self._do_rebuild)
|
||||||
|
|
||||||
def _do_rebuild(self):
|
def _do_rebuild(self):
|
||||||
"""Actually rebuild the UI."""
|
"""Actually rebuild the UI."""
|
||||||
try:
|
try:
|
||||||
|
|
@ -565,9 +603,9 @@ class HUDOverlay(QWidget):
|
||||||
logger.error(f"Error rebuilding HUD: {e}")
|
logger.error(f"Error rebuilding HUD: {e}")
|
||||||
# Try to recover
|
# Try to recover
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
# === Session Management ===
|
# === Session Management ===
|
||||||
|
|
||||||
def start_session(self, weapon: str = "Unknown", armor: str = "None",
|
def start_session(self, weapon: str = "Unknown", armor: str = "None",
|
||||||
fap: str = "None", loadout: str = "Default",
|
fap: str = "None", loadout: str = "Default",
|
||||||
weapon_dpp: Decimal = Decimal('0.0'),
|
weapon_dpp: Decimal = Decimal('0.0'),
|
||||||
|
|
@ -586,35 +624,35 @@ class HUDOverlay(QWidget):
|
||||||
self._stats.cost_per_hit = cost_per_hit
|
self._stats.cost_per_hit = cost_per_hit
|
||||||
self._stats.cost_per_heal = cost_per_heal
|
self._stats.cost_per_heal = cost_per_heal
|
||||||
self.session_active = True
|
self.session_active = True
|
||||||
|
|
||||||
self._timer.start(1000)
|
self._timer.start(1000)
|
||||||
self._refresh_display()
|
self._refresh_display()
|
||||||
self.status_label.setText("● Live")
|
self.status_label.setText("● Live")
|
||||||
self.status_label.setStyleSheet("color: #7FFF7F; font-weight: bold;")
|
self.status_label.setStyleSheet("color: #7FFF7F; font-weight: bold;")
|
||||||
|
|
||||||
def end_session(self) -> None:
|
def end_session(self) -> None:
|
||||||
"""Alias for stop_session for backward compatibility."""
|
"""Alias for stop_session for backward compatibility."""
|
||||||
self.stop_session()
|
self.stop_session()
|
||||||
|
|
||||||
def stop_session(self) -> None:
|
def stop_session(self) -> None:
|
||||||
"""Stop the current session."""
|
"""Stop the current session."""
|
||||||
self.session_active = False
|
self.session_active = False
|
||||||
self._timer.stop()
|
self._timer.stop()
|
||||||
self.status_label.setText("● Stopped")
|
self.status_label.setText("● Stopped")
|
||||||
self.status_label.setStyleSheet("color: #FF7F7F; font-weight: bold;")
|
self.status_label.setStyleSheet("color: #FF7F7F; font-weight: bold;")
|
||||||
|
|
||||||
# === Event Handlers ===
|
# === Event Handlers ===
|
||||||
|
|
||||||
def _update_session_time(self):
|
def _update_session_time(self):
|
||||||
"""Update session time display."""
|
"""Update session time display."""
|
||||||
if self._session_start and self.session_active:
|
if self._session_start and self.session_active:
|
||||||
elapsed = datetime.now() - self._session_start
|
elapsed = datetime.now() - self._session_start
|
||||||
hours, remainder = divmod(elapsed.seconds, 3600)
|
hours, remainder = divmod(elapsed.seconds, 3600)
|
||||||
minutes, seconds = divmod(remainder, 60)
|
minutes, seconds = divmod(remainder, 60)
|
||||||
|
|
||||||
if hasattr(self, 'time_label'):
|
if hasattr(self, 'time_label'):
|
||||||
self.time_label.setText(f"{hours:02d}:{minutes:02d}:{seconds:02d}")
|
self.time_label.setText(f"{hours:02d}:{minutes:02d}:{seconds:02d}")
|
||||||
|
|
||||||
def _refresh_display(self):
|
def _refresh_display(self):
|
||||||
"""Refresh all display labels."""
|
"""Refresh all display labels."""
|
||||||
# Profit/Loss
|
# Profit/Loss
|
||||||
|
|
@ -623,7 +661,7 @@ class HUDOverlay(QWidget):
|
||||||
color = "#7FFF7F" if profit >= 0 else "#FF7F7F"
|
color = "#7FFF7F" if profit >= 0 else "#FF7F7F"
|
||||||
self.profit_label.setText(f"{profit:+.2f} PED")
|
self.profit_label.setText(f"{profit:+.2f} PED")
|
||||||
self.profit_label.setStyleSheet(f"font-size: 18px; font-weight: bold; color: {color};")
|
self.profit_label.setStyleSheet(f"font-size: 18px; font-weight: bold; color: {color};")
|
||||||
|
|
||||||
# Return %
|
# Return %
|
||||||
if hasattr(self, 'return_label'):
|
if hasattr(self, 'return_label'):
|
||||||
ret = self._stats.return_percentage
|
ret = self._stats.return_percentage
|
||||||
|
|
@ -635,11 +673,11 @@ class HUDOverlay(QWidget):
|
||||||
color = "#FF7F7F"
|
color = "#FF7F7F"
|
||||||
self.return_label.setText(f"{ret:.1f}%")
|
self.return_label.setText(f"{ret:.1f}%")
|
||||||
self.return_label.setStyleSheet(f"font-size: 16px; font-weight: bold; color: {color};")
|
self.return_label.setStyleSheet(f"font-size: 16px; font-weight: bold; color: {color};")
|
||||||
|
|
||||||
# Total Cost
|
# Total Cost
|
||||||
if hasattr(self, 'total_cost_label'):
|
if hasattr(self, 'total_cost_label'):
|
||||||
self.total_cost_label.setText(f"Cost: {self._stats.cost_total:.2f} PED")
|
self.total_cost_label.setText(f"Cost: {self._stats.cost_total:.2f} PED")
|
||||||
|
|
||||||
# Cost metrics
|
# Cost metrics
|
||||||
if hasattr(self, 'cps_label'):
|
if hasattr(self, 'cps_label'):
|
||||||
self.cps_label.setText(f"Shot: {self._stats.cost_per_shot:.4f}")
|
self.cps_label.setText(f"Shot: {self._stats.cost_per_shot:.4f}")
|
||||||
|
|
@ -647,7 +685,7 @@ class HUDOverlay(QWidget):
|
||||||
self.cph_label.setText(f"Hit: {self._stats.cost_per_hit:.4f}")
|
self.cph_label.setText(f"Hit: {self._stats.cost_per_hit:.4f}")
|
||||||
if hasattr(self, 'cphl_label'):
|
if hasattr(self, 'cphl_label'):
|
||||||
self.cphl_label.setText(f"Heal: {self._stats.cost_per_heal:.4f}")
|
self.cphl_label.setText(f"Heal: {self._stats.cost_per_heal:.4f}")
|
||||||
|
|
||||||
# Gear
|
# Gear
|
||||||
if hasattr(self, 'weapon_label'):
|
if hasattr(self, 'weapon_label'):
|
||||||
self.weapon_label.setText(f"🔫 {self._stats.current_weapon[:20]}")
|
self.weapon_label.setText(f"🔫 {self._stats.current_weapon[:20]}")
|
||||||
|
|
@ -655,7 +693,7 @@ class HUDOverlay(QWidget):
|
||||||
self.armor_label.setText(f"🛡️ {self._stats.current_armor[:20]}")
|
self.armor_label.setText(f"🛡️ {self._stats.current_armor[:20]}")
|
||||||
if hasattr(self, 'loadout_label'):
|
if hasattr(self, 'loadout_label'):
|
||||||
self.loadout_label.setText(f"📋 {self._stats.current_loadout[:20]}")
|
self.loadout_label.setText(f"📋 {self._stats.current_loadout[:20]}")
|
||||||
|
|
||||||
# Cost breakdown
|
# Cost breakdown
|
||||||
if hasattr(self, 'wep_cost_label'):
|
if hasattr(self, 'wep_cost_label'):
|
||||||
self.wep_cost_label.setText(f"{self._stats.weapon_cost_total:.2f}")
|
self.wep_cost_label.setText(f"{self._stats.weapon_cost_total:.2f}")
|
||||||
|
|
@ -663,22 +701,32 @@ class HUDOverlay(QWidget):
|
||||||
self.arm_cost_label.setText(f"{self._stats.armor_cost_total:.2f}")
|
self.arm_cost_label.setText(f"{self._stats.armor_cost_total:.2f}")
|
||||||
if hasattr(self, 'heal_cost_label'):
|
if hasattr(self, 'heal_cost_label'):
|
||||||
self.heal_cost_label.setText(f"{self._stats.healing_cost_total:.2f}")
|
self.heal_cost_label.setText(f"{self._stats.healing_cost_total:.2f}")
|
||||||
|
|
||||||
# Combat
|
# Combat
|
||||||
if hasattr(self, 'kills_label'):
|
if hasattr(self, 'kills_label'):
|
||||||
self.kills_label.setText(f"Kills: {self._stats.kills}")
|
self.kills_label.setText(f"Kills: {self._stats.kills}")
|
||||||
if hasattr(self, 'globals_label'):
|
if hasattr(self, 'globals_label'):
|
||||||
self.globals_label.setText(f"Globals: {self._stats.globals_count}")
|
self.globals_label.setText(f"Globals: {self._stats.globals_count}")
|
||||||
|
|
||||||
|
# Damage stats
|
||||||
|
if hasattr(self, 'damage_dealt_label'):
|
||||||
|
self.damage_dealt_label.setText(f"Dealt: {int(self._stats.damage_dealt)}")
|
||||||
|
if hasattr(self, 'damage_taken_label'):
|
||||||
|
self.damage_taken_label.setText(f"Taken: {int(self._stats.damage_taken)}")
|
||||||
|
|
||||||
|
# Shrapnel
|
||||||
|
if hasattr(self, 'shrapnel_label'):
|
||||||
|
self.shrapnel_label.setText(f"💎 Shrapnel: {self._stats.shrapnel_total:.2f} PED")
|
||||||
|
|
||||||
# === Public Update Methods ===
|
# === Public Update Methods ===
|
||||||
|
|
||||||
def update_loot(self, value_ped: Decimal):
|
def update_loot(self, value_ped: Decimal):
|
||||||
"""Update loot value."""
|
"""Update loot value."""
|
||||||
if self.session_active:
|
if self.session_active:
|
||||||
self._stats.loot_total += value_ped
|
self._stats.loot_total += value_ped
|
||||||
self._stats.recalculate()
|
self._stats.recalculate()
|
||||||
self._refresh_display()
|
self._refresh_display()
|
||||||
|
|
||||||
def update_weapon_cost(self, cost_ped: Decimal):
|
def update_weapon_cost(self, cost_ped: Decimal):
|
||||||
"""Update weapon cost."""
|
"""Update weapon cost."""
|
||||||
if self.session_active:
|
if self.session_active:
|
||||||
|
|
@ -686,7 +734,7 @@ class HUDOverlay(QWidget):
|
||||||
self._stats.cost_total += cost_ped
|
self._stats.cost_total += cost_ped
|
||||||
self._stats.recalculate()
|
self._stats.recalculate()
|
||||||
self._refresh_display()
|
self._refresh_display()
|
||||||
|
|
||||||
def update_armor_cost(self, cost_ped: Decimal):
|
def update_armor_cost(self, cost_ped: Decimal):
|
||||||
"""Update armor cost."""
|
"""Update armor cost."""
|
||||||
if self.session_active:
|
if self.session_active:
|
||||||
|
|
@ -694,7 +742,7 @@ class HUDOverlay(QWidget):
|
||||||
self._stats.cost_total += cost_ped
|
self._stats.cost_total += cost_ped
|
||||||
self._stats.recalculate()
|
self._stats.recalculate()
|
||||||
self._refresh_display()
|
self._refresh_display()
|
||||||
|
|
||||||
def update_healing_cost(self, cost_ped: Decimal):
|
def update_healing_cost(self, cost_ped: Decimal):
|
||||||
"""Update healing cost."""
|
"""Update healing cost."""
|
||||||
if self.session_active:
|
if self.session_active:
|
||||||
|
|
@ -702,21 +750,36 @@ class HUDOverlay(QWidget):
|
||||||
self._stats.cost_total += cost_ped
|
self._stats.cost_total += cost_ped
|
||||||
self._stats.recalculate()
|
self._stats.recalculate()
|
||||||
self._refresh_display()
|
self._refresh_display()
|
||||||
|
|
||||||
def update_kills(self, count: int = 1):
|
def update_kills(self, count: int = 1):
|
||||||
"""Update kill count."""
|
"""Update kill count."""
|
||||||
if self.session_active:
|
if self.session_active:
|
||||||
self._stats.kills += count
|
self._stats.kills += count
|
||||||
self._refresh_display()
|
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:
|
||||||
self._stats.globals_count += 1
|
self._stats.globals_count += 1
|
||||||
self._refresh_display()
|
self._refresh_display()
|
||||||
|
|
||||||
|
def update_damage(self, dealt: Decimal = Decimal('0'), taken: Decimal = Decimal('0')):
|
||||||
|
"""Update damage stats."""
|
||||||
|
if self.session_active:
|
||||||
|
if dealt > 0:
|
||||||
|
self._stats.damage_dealt += dealt
|
||||||
|
if taken > 0:
|
||||||
|
self._stats.damage_taken += taken
|
||||||
|
self._refresh_display()
|
||||||
|
|
||||||
|
def update_shrapnel(self, amount: Decimal):
|
||||||
|
"""Update shrapnel amount."""
|
||||||
|
if self.session_active:
|
||||||
|
self._stats.shrapnel_total += amount
|
||||||
|
self._refresh_display()
|
||||||
|
|
||||||
# === Mouse Handling ===
|
# === Mouse Handling ===
|
||||||
|
|
||||||
def mousePressEvent(self, event: QMouseEvent):
|
def mousePressEvent(self, event: QMouseEvent):
|
||||||
if event.button() == Qt.MouseButton.LeftButton:
|
if event.button() == Qt.MouseButton.LeftButton:
|
||||||
if event.modifiers() == Qt.KeyboardModifier.ControlModifier:
|
if event.modifiers() == Qt.KeyboardModifier.ControlModifier:
|
||||||
|
|
@ -724,29 +787,29 @@ class HUDOverlay(QWidget):
|
||||||
self._drag_offset = event.pos()
|
self._drag_offset = event.pos()
|
||||||
self.setCursor(Qt.CursorShape.ClosedHandCursor)
|
self.setCursor(Qt.CursorShape.ClosedHandCursor)
|
||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
def mouseMoveEvent(self, event: QMouseEvent):
|
def mouseMoveEvent(self, event: QMouseEvent):
|
||||||
if self._dragging:
|
if self._dragging:
|
||||||
new_pos = self.mapToGlobal(event.pos()) - self._drag_offset
|
new_pos = self.mapToGlobal(event.pos()) - self._drag_offset
|
||||||
self.move(new_pos)
|
self.move(new_pos)
|
||||||
self.position_changed.emit(new_pos)
|
self.position_changed.emit(new_pos)
|
||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
def mouseReleaseEvent(self, event: QMouseEvent):
|
def mouseReleaseEvent(self, event: QMouseEvent):
|
||||||
if event.button() == Qt.MouseButton.LeftButton and self._dragging:
|
if event.button() == Qt.MouseButton.LeftButton and self._dragging:
|
||||||
self._dragging = False
|
self._dragging = False
|
||||||
self.setCursor(Qt.CursorShape.ArrowCursor)
|
self.setCursor(Qt.CursorShape.ArrowCursor)
|
||||||
self._save_position()
|
self._save_position()
|
||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
def enterEvent(self, event):
|
def enterEvent(self, event):
|
||||||
"""Mouse entered - enable interaction."""
|
"""Mouse entered - enable interaction."""
|
||||||
super().enterEvent(event)
|
super().enterEvent(event)
|
||||||
|
|
||||||
def leaveEvent(self, event):
|
def leaveEvent(self, event):
|
||||||
"""Mouse left - disable interaction."""
|
"""Mouse left - disable interaction."""
|
||||||
super().leaveEvent(event)
|
super().leaveEvent(event)
|
||||||
|
|
||||||
def _save_position(self):
|
def _save_position(self):
|
||||||
"""Save window position."""
|
"""Save window position."""
|
||||||
try:
|
try:
|
||||||
|
|
@ -755,7 +818,7 @@ class HUDOverlay(QWidget):
|
||||||
json.dump({'x': self.x(), 'y': self.y()}, f)
|
json.dump({'x': self.x(), 'y': self.y()}, f)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _load_position(self):
|
def _load_position(self):
|
||||||
"""Load window position."""
|
"""Load window position."""
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue