""" EU-Utility - Loot Tracker Plugin Track and analyze hunting loot with statistics and ROI. """ import re from datetime import datetime from collections import defaultdict from pathlib import Path import json from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QTableWidget, QTableWidgetItem, QComboBox, QLineEdit, QTabWidget, QFrame ) from PyQt6.QtCore import Qt from plugins.base_plugin import BasePlugin class LootTrackerPlugin(BasePlugin): """Track hunting loot and calculate ROI.""" name = "Loot Tracker" version = "1.0.0" author = "ImpulsiveFPS" description = "Track hunting loot with stats and ROI analysis" hotkey = "ctrl+shift+l" # L for Loot def initialize(self): """Setup loot tracker.""" self.data_file = Path("data/loot_tracker.json") self.data_file.parent.mkdir(parents=True, exist_ok=True) self.sessions = [] self.current_session = { 'start_time': None, 'kills': 0, 'loot_items': [], 'total_tt': 0.0, 'ammo_cost': 0.0, 'weapon_decay': 0.0, } self._load_data() def _load_data(self): """Load historical data.""" if self.data_file.exists(): try: with open(self.data_file, 'r') as f: self.sessions = json.load(f) except: self.sessions = [] def _save_data(self): """Save data to file.""" with open(self.data_file, 'w') as f: json.dump(self.sessions, f, indent=2) def get_ui(self): """Create plugin UI.""" widget = QWidget() widget.setStyleSheet("background: transparent;") layout = QVBoxLayout(widget) layout.setSpacing(15) layout.setContentsMargins(0, 0, 0, 0) # Title title = QLabel("Loot Tracker") title.setStyleSheet("color: white; font-size: 16px; font-weight: bold;") layout.addWidget(title) # Stats summary stats_frame = QFrame() stats_frame.setStyleSheet(""" QFrame { background-color: rgba(0, 0, 0, 50); border-radius: 10px; border: 1px solid rgba(255, 255, 255, 20); } """) stats_layout = QHBoxLayout(stats_frame) self.kills_label = QLabel("Kills: 0") self.kills_label.setStyleSheet("color: #4caf50; font-size: 14px; font-weight: bold;") stats_layout.addWidget(self.kills_label) self.tt_label = QLabel("TT: 0.00 PED") self.tt_label.setStyleSheet("color: #ffc107; font-size: 14px; font-weight: bold;") stats_layout.addWidget(self.tt_label) self.roi_label = QLabel("ROI: 0%") self.roi_label.setStyleSheet("color: #4a9eff; font-size: 14px; font-weight: bold;") stats_layout.addWidget(self.roi_label) layout.addWidget(stats_frame) # Session controls controls = QHBoxLayout() self.start_btn = QPushButton("▶ Start Session") self.start_btn.setStyleSheet(""" QPushButton { background-color: #4caf50; color: white; padding: 10px 20px; border: none; border-radius: 8px; font-weight: bold; } QPushButton:hover { background-color: #5cbf60; } """) self.start_btn.clicked.connect(self._start_session) controls.addWidget(self.start_btn) self.stop_btn = QPushButton("⏹ Stop Session") self.stop_btn.setStyleSheet(""" QPushButton { background-color: #f44336; color: white; padding: 10px 20px; border: none; border-radius: 8px; font-weight: bold; } QPushButton:hover { background-color: #f55a4e; } """) self.stop_btn.clicked.connect(self._stop_session) self.stop_btn.setEnabled(False) controls.addWidget(self.stop_btn) layout.addLayout(controls) # Loot table self.loot_table = QTableWidget() self.loot_table.setColumnCount(4) self.loot_table.setHorizontalHeaderLabels(["Item", "Qty", "TT Value", "Time"]) self.loot_table.setStyleSheet(""" QTableWidget { background-color: rgba(30, 30, 30, 100); color: white; border: none; border-radius: 6px; } QHeaderView::section { background-color: rgba(74, 158, 255, 100); color: white; padding: 6px; } """) self.loot_table.horizontalHeader().setStretchLastSection(True) layout.addWidget(self.loot_table) layout.addStretch() return widget def _start_session(self): """Start new hunting session.""" self.current_session = { 'start_time': datetime.now().isoformat(), 'kills': 0, 'loot_items': [], 'total_tt': 0.0, 'ammo_cost': 0.0, 'weapon_decay': 0.0, } self.start_btn.setEnabled(False) self.stop_btn.setEnabled(True) def _stop_session(self): """Stop current session and save.""" self.current_session['end_time'] = datetime.now().isoformat() self.sessions.append(self.current_session) self._save_data() self.start_btn.setEnabled(True) self.stop_btn.setEnabled(False) self._update_stats() def _update_stats(self): """Update statistics display.""" kills = self.current_session.get('kills', 0) tt = self.current_session.get('total_tt', 0.0) self.kills_label.setText(f"Kills: {kills}") self.tt_label.setText(f"TT: {tt:.2f} PED") def parse_chat_message(self, message): """Parse loot from chat.""" # Look for loot patterns # Example: "You received Animal Hide (0.03 PED)" loot_pattern = r'You received (.+?) \(([\d.]+) PED\)' match = re.search(loot_pattern, message) if match: item_name = match.group(1) tt_value = float(match.group(2)) self.current_session['loot_items'].append({ 'item': item_name, 'tt': tt_value, 'time': datetime.now().isoformat() }) self.current_session['total_tt'] += tt_value self._update_stats() # Check for new kill # Multiple items in quick succession = one kill # Longer gap = new kill self.current_session['kills'] += 1 def on_hotkey(self): """Toggle session on hotkey.""" if self.start_btn.isEnabled(): self._start_session() else: self._stop_session()