EU-Utility/plugins/mission_tracker/plugin.py

316 lines
10 KiB
Python

"""
EU-Utility - Mission Tracker Plugin
Track active missions and progress.
"""
import json
from datetime import datetime
from pathlib import Path
from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QPushButton, QProgressBar, QFrame, QScrollArea
)
from PyQt6.QtCore import Qt
from plugins.base_plugin import BasePlugin
from core.icon_manager import get_icon_manager
class MissionTrackerPlugin(BasePlugin):
"""Track active missions and daily challenges."""
name = "Mission Tracker"
version = "1.0.0"
author = "ImpulsiveFPS"
description = "Track missions, challenges, and objectives"
hotkey = "ctrl+shift+m"
def initialize(self):
"""Setup mission tracker."""
self.data_file = Path("data/missions.json")
self.data_file.parent.mkdir(parents=True, exist_ok=True)
self.missions = []
self.daily_challenges = []
self._load_data()
def _load_data(self):
"""Load mission data."""
if self.data_file.exists():
try:
with open(self.data_file, 'r') as f:
data = json.load(f)
self.missions = data.get('missions', [])
self.daily_challenges = data.get('daily', [])
except:
pass
def _save_data(self):
"""Save mission data."""
with open(self.data_file, 'w') as f:
json.dump({
'missions': self.missions,
'daily': self.daily_challenges
}, f, indent=2)
def get_ui(self):
"""Create mission tracker UI."""
widget = QWidget()
widget.setStyleSheet("background: transparent;")
layout = QVBoxLayout(widget)
layout.setSpacing(15)
layout.setContentsMargins(0, 0, 0, 0)
# Title
title = QLabel("📜 Mission Tracker")
title.setStyleSheet("""
color: white;
font-size: 16px;
font-weight: bold;
""")
layout.addWidget(title)
# Active missions section
active_label = QLabel("Active Missions")
active_label.setStyleSheet("color: rgba(255,255,255,200); font-size: 12px;")
layout.addWidget(active_label)
# Mission cards
self.missions_container = QWidget()
self.missions_layout = QVBoxLayout(self.missions_container)
self.missions_layout.setSpacing(10)
self.missions_layout.setContentsMargins(0, 0, 0, 0)
self._refresh_missions()
layout.addWidget(self.missions_container)
# Daily challenges
daily_label = QLabel("Daily Challenges")
daily_label.setStyleSheet("color: rgba(255,255,255,200); font-size: 12px; margin-top: 10px;")
layout.addWidget(daily_label)
self.daily_container = QWidget()
self.daily_layout = QVBoxLayout(self.daily_container)
self.daily_layout.setSpacing(8)
self.daily_layout.setContentsMargins(0, 0, 0, 0)
self._refresh_daily()
layout.addWidget(self.daily_container)
# Add mission button
add_btn = QPushButton("+ Add Mission")
add_btn.setStyleSheet("""
QPushButton {
background-color: rgba(255, 140, 66, 200);
color: white;
padding: 10px;
border: none;
border-radius: 4px;
font-weight: bold;
}
QPushButton:hover {
background-color: rgba(255, 160, 80, 230);
}
""")
add_btn.clicked.connect(self._add_mission)
layout.addWidget(add_btn)
layout.addStretch()
return widget
def _create_mission_card(self, mission):
"""Create a mission card widget."""
card = QFrame()
card.setStyleSheet("""
QFrame {
background-color: rgba(30, 35, 45, 200);
border: 1px solid rgba(100, 110, 130, 80);
border-radius: 6px;
}
""")
layout = QVBoxLayout(card)
layout.setContentsMargins(12, 10, 12, 10)
layout.setSpacing(8)
# Header
header = QHBoxLayout()
name = QLabel(mission.get('name', 'Unknown Mission'))
name.setStyleSheet("color: #ff8c42; font-weight: bold; font-size: 12px;")
header.addWidget(name)
header.addStretch()
# Complete button
complete_btn = QPushButton("")
complete_btn.setFixedSize(24, 24)
complete_btn.setStyleSheet("""
QPushButton {
background-color: rgba(76, 175, 80, 150);
color: white;
border: none;
border-radius: 3px;
font-weight: bold;
}
QPushButton:hover {
background-color: rgba(76, 175, 80, 200);
}
""")
complete_btn.clicked.connect(lambda: self._complete_mission(mission))
header.addWidget(complete_btn)
layout.addLayout(header)
# Progress
current = mission.get('current', 0)
total = mission.get('total', 1)
pct = min(100, int(current / total * 100))
progress_layout = QHBoxLayout()
progress = QProgressBar()
progress.setValue(pct)
progress.setTextVisible(False)
progress.setFixedHeight(6)
progress.setStyleSheet("""
QProgressBar {
background-color: rgba(60, 70, 90, 150);
border: none;
border-radius: 3px;
}
QProgressBar::chunk {
background-color: #ff8c42;
border-radius: 3px;
}
""")
progress_layout.addWidget(progress, 1)
progress_text = QLabel(f"{current}/{total}")
progress_text.setStyleSheet("color: rgba(255,255,255,150); font-size: 10px;")
progress_layout.addWidget(progress_text)
layout.addLayout(progress_layout)
return card
def _create_challenge_card(self, challenge):
"""Create a daily challenge card."""
card = QFrame()
card.setStyleSheet("""
QFrame {
background-color: rgba(25, 30, 40, 180);
border: 1px solid rgba(80, 90, 110, 60);
border-radius: 4px;
}
""")
layout = QHBoxLayout(card)
layout.setContentsMargins(10, 8, 10, 8)
layout.setSpacing(10)
# Icon based on type
icon_mgr = get_icon_manager()
icon_label = QLabel()
icon_pixmap = icon_mgr.get_pixmap('sword', size=16)
icon_label.setPixmap(icon_pixmap)
icon_label.setFixedSize(16, 16)
layout.addWidget(icon_label)
# Name
name = QLabel(challenge.get('name', 'Challenge'))
name.setStyleSheet("color: white; font-size: 11px;")
layout.addWidget(name)
layout.addStretch()
# Progress
current = challenge.get('current', 0)
total = challenge.get('total', 1)
pct = min(100, int(current / total * 100))
progress = QProgressBar()
progress.setValue(pct)
progress.setTextVisible(False)
progress.setFixedSize(60, 4)
progress.setStyleSheet("""
QProgressBar {
background-color: rgba(60, 70, 90, 150);
border: none;
border-radius: 2px;
}
QProgressBar::chunk {
background-color: #ffc107;
border-radius: 2px;
}
""")
layout.addWidget(progress)
text = QLabel(f"{current}/{total}")
text.setStyleSheet("color: rgba(255,255,255,120); font-size: 10px;")
layout.addWidget(text)
return card
def _refresh_missions(self):
"""Refresh mission display."""
# Clear existing
while self.missions_layout.count():
item = self.missions_layout.takeAt(0)
if item.widget():
item.widget().deleteLater()
# Add missions
for mission in self.missions:
card = self._create_mission_card(mission)
self.missions_layout.addWidget(card)
def _refresh_daily(self):
"""Refresh daily challenges."""
while self.daily_layout.count():
item = self.daily_layout.takeAt(0)
if item.widget():
item.widget().deleteLater()
for challenge in self.daily_challenges:
card = self._create_challenge_card(challenge)
self.daily_layout.addWidget(card)
def _add_mission(self):
"""Add a new mission."""
# Add sample mission
self.missions.append({
'name': 'Oratan Payback Mission III',
'current': 0,
'total': 100,
'type': 'kill',
'target': 'Oratan Prospector Bandits',
'added': datetime.now().isoformat()
})
self._save_data()
self._refresh_missions()
def _complete_mission(self, mission):
"""Mark mission as complete."""
if mission in self.missions:
self.missions.remove(mission)
self._save_data()
self._refresh_missions()
def parse_chat_message(self, message):
"""Parse mission progress from chat."""
# Look for mission progress
# Example: "Mission updated: 12/100 Oratan Prospector Bandits"
for mission in self.missions:
target = mission.get('target', '')
if target and target in message:
# Extract progress
import re
match = re.search(r'(\d+)/(\d+)', message)
if match:
mission['current'] = int(match.group(1))
mission['total'] = int(match.group(2))
self._save_data()
self._refresh_missions()