EU-Utility-Plugins-Repo/plugins/tp_runner/plugin.py

220 lines
7.2 KiB
Python

"""
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()