""" EU-Utility - TP Runner Plugin Track teleporter locations and plan routes. """ import json from pathlib import Path from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QComboBox, QTreeWidget, QTreeWidgetItem, QLineEdit, QFrame ) from PyQt6.QtCore import Qt from plugins.base_plugin import BasePlugin class TPRunnerPlugin(BasePlugin): """Track TP locations and plan routes.""" name = "TP Runner" version = "1.0.0" author = "ImpulsiveFPS" description = "Teleporter locations and route planner" hotkey = "ctrl+shift+p" # P for Port # Arkadia TPs ARKADIA_TPS = [ "Arkadia City", "Arkadia City Outskirts", "8 Coins Creek", "Celeste Harbour", "Celeste Outpost North", "Celeste Outpost South", "Celeste Quarry", "Cycadia", "Dauntless Dock", "East Scythe", "Genesis", "Hadesheim", "Hadesheim Ashland", "Hadesheim Pass", "Hadesheim Valley", "Hellfire Hills", "Hero's Landing", "Horror-Filled Hallows", "Jagged Coast", "Jungle Camp", "Khorum Coast", "Khorum Highway", "Kronus", "Lava Camp", "Lighthouse", "Living Graveyard", "Mountaintop", "Neo-Shanghai", "North Scythe", "Nusul Fields", "Oily Business", "Perseus", "Pilgrim's Landing", "Poseidon West", "Red Sands", "Releks Hills", "Rest Stop", "Ripper Snapper", "Sacred Cove", "Sentinel Hill", "Shady Ridge", "Sisyphus", "South Scythe", "Spiral Mountain", "Stormbird Landing", "Sundari", "Tides", "Traveller's Landing", "Victorious", "Vikings", "West Scythe", "Wild Banks", "Wolf's Ridge", ] def initialize(self): """Setup TP runner.""" self.data_file = Path("data/tp_runner.json") self.data_file.parent.mkdir(parents=True, exist_ok=True) self.unlocked_tps = set() self.favorite_routes = [] self._load_data() def _load_data(self): """Load TP data.""" if self.data_file.exists(): try: with open(self.data_file, 'r') as f: data = json.load(f) self.unlocked_tps = set(data.get('unlocked', [])) self.favorite_routes = data.get('routes', []) except: pass def _save_data(self): """Save TP data.""" with open(self.data_file, 'w') as f: json.dump({ 'unlocked': list(self.unlocked_tps), 'routes': self.favorite_routes }, f, indent=2) def get_ui(self): """Create TP runner UI.""" widget = QWidget() widget.setStyleSheet("background: transparent;") layout = QVBoxLayout(widget) layout.setSpacing(15) layout.setContentsMargins(0, 0, 0, 0) # Title title = QLabel("🚀 TP Runner") title.setStyleSheet("color: white; font-size: 16px; font-weight: bold;") layout.addWidget(title) # Progress unlocked = len(self.unlocked_tps) total = len(self.ARKADIA_TPS) progress = QLabel(f"Unlocked: {unlocked}/{total} ({unlocked/total*100:.1f}%)") progress.setStyleSheet("color: #4caf50;") layout.addWidget(progress) # Route planner planner = QFrame() planner.setStyleSheet(""" QFrame { background-color: rgba(30, 35, 45, 200); border: 1px solid rgba(100, 110, 130, 80); border-radius: 6px; } """) planner_layout = QVBoxLayout(planner) # From/To fromto = QHBoxLayout() self.from_combo = QComboBox() self.from_combo.addItems(self.ARKADIA_TPS) self.from_combo.setStyleSheet(""" QComboBox { background-color: rgba(20, 25, 35, 200); color: white; border: 1px solid rgba(100, 110, 130, 80); padding: 5px; } """) fromto.addWidget(QLabel("From:")) fromto.addWidget(self.from_combo) self.to_combo = QComboBox() self.to_combo.addItems(self.ARKADIA_TPS) self.to_combo.setStyleSheet(self.from_combo.styleSheet()) fromto.addWidget(QLabel("To:")) fromto.addWidget(self.to_combo) planner_layout.addLayout(fromto) # Route button route_btn = QPushButton("Find Route") route_btn.setStyleSheet(""" QPushButton { background-color: #ff8c42; color: white; padding: 10px; border: none; border-radius: 4px; font-weight: bold; } """) route_btn.clicked.connect(self._find_route) planner_layout.addWidget(route_btn) layout.addWidget(planner) # TP List self.tp_tree = QTreeWidget() self.tp_tree.setHeaderLabels(["Teleporter", "Status"]) self.tp_tree.setStyleSheet(""" QTreeWidget { background-color: rgba(30, 35, 45, 200); color: white; border: 1px solid rgba(100, 110, 130, 80); border-radius: 6px; } QHeaderView::section { background-color: rgba(35, 40, 55, 200); color: rgba(255,255,255,180); padding: 8px; font-weight: bold; font-size: 11px; } """) # Populate list for tp in sorted(self.ARKADIA_TPS): item = QTreeWidgetItem() item.setText(0, tp) if tp in self.unlocked_tps: item.setText(1, "Unlocked") item.setForeground(1, Qt.GlobalColor.green) else: item.setText(1, "Locked") item.setForeground(1, Qt.GlobalColor.gray) self.tp_tree.addTopLevelItem(item) layout.addWidget(self.tp_tree) # Mark as unlocked button unlock_btn = QPushButton("Mark Unlocked") unlock_btn.setStyleSheet(""" QPushButton { background-color: #4caf50; color: white; padding: 10px; border: none; border-radius: 4px; font-weight: bold; } """) unlock_btn.clicked.connect(self._mark_unlocked) layout.addWidget(unlock_btn) layout.addStretch() return widget def _find_route(self): """Find route between TPs.""" from_tp = self.from_combo.currentText() to_tp = self.to_combo.currentText() if from_tp == to_tp: return # Simple distance estimation (would use actual coordinates) # For now, just show direct route def _mark_unlocked(self): """Mark selected TP as unlocked.""" item = self.tp_tree.currentItem() if item: tp_name = item.text(0) self.unlocked_tps.add(tp_name) item.setText(1, "Unlocked") item.setForeground(1, Qt.GlobalColor.green) self._save_data()