204 lines
6.8 KiB
Python
204 lines
6.8 KiB
Python
"""
|
|
Lemontropia Suite - Simple Armor Selector
|
|
Quick armor selection for cost configuration.
|
|
"""
|
|
|
|
import logging
|
|
from decimal import Decimal
|
|
|
|
from PyQt6.QtWidgets import (
|
|
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
|
|
QPushButton, QLineEdit, QListWidget, QListWidgetItem,
|
|
QMessageBox, QFormLayout, QGroupBox
|
|
)
|
|
from PyQt6.QtCore import Qt, pyqtSignal
|
|
|
|
from core.nexus_full_api import get_nexus_api
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ArmorSelectorDialog(QDialog):
|
|
"""Simple dialog to select armor for cost tracking."""
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.setWindowTitle("Select Armor")
|
|
self.setMinimumSize(500, 400)
|
|
|
|
self.selected_armor = None
|
|
self._armors = []
|
|
|
|
self._setup_ui()
|
|
self._load_armors()
|
|
|
|
def _setup_ui(self):
|
|
"""Setup simple UI."""
|
|
layout = QVBoxLayout(self)
|
|
layout.setSpacing(10)
|
|
|
|
# Search
|
|
search_layout = QHBoxLayout()
|
|
search_layout.addWidget(QLabel("Search:"))
|
|
self.search_edit = QLineEdit()
|
|
self.search_edit.setPlaceholderText("Type armor name...")
|
|
self.search_edit.textChanged.connect(self._on_search)
|
|
search_layout.addWidget(self.search_edit)
|
|
layout.addLayout(search_layout)
|
|
|
|
# Armor list
|
|
self.armor_list = QListWidget()
|
|
self.armor_list.itemClicked.connect(self._on_select)
|
|
self.armor_list.itemDoubleClicked.connect(self._on_double_click)
|
|
layout.addWidget(self.armor_list)
|
|
|
|
# Preview
|
|
preview_group = QGroupBox("Selected Armor")
|
|
preview_layout = QFormLayout(preview_group)
|
|
|
|
self.preview_name = QLabel("None")
|
|
preview_layout.addRow("Name:", self.preview_name)
|
|
|
|
self.preview_protection = QLabel("-")
|
|
preview_layout.addRow("Protection:", self.preview_protection)
|
|
|
|
self.preview_decay = QLabel("-")
|
|
preview_layout.addRow("Decay/Hit:", self.preview_decay)
|
|
|
|
self.preview_cost = QLabel("-")
|
|
self.preview_cost.setStyleSheet("font-weight: bold; color: #7FFF7F;")
|
|
preview_layout.addRow("Cost/Hit:", self.preview_cost)
|
|
|
|
layout.addWidget(preview_group)
|
|
|
|
# Buttons
|
|
button_layout = QHBoxLayout()
|
|
button_layout.addStretch()
|
|
|
|
self.ok_btn = QPushButton("Select")
|
|
self.ok_btn.clicked.connect(self.accept)
|
|
self.ok_btn.setEnabled(False)
|
|
self.ok_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: #2E7D32;
|
|
color: white;
|
|
padding: 8px 16px;
|
|
font-weight: bold;
|
|
}
|
|
QPushButton:disabled {
|
|
background-color: #333;
|
|
color: #666;
|
|
}
|
|
""")
|
|
button_layout.addWidget(self.ok_btn)
|
|
|
|
cancel_btn = QPushButton("Cancel")
|
|
cancel_btn.clicked.connect(self.reject)
|
|
button_layout.addWidget(cancel_btn)
|
|
|
|
layout.addLayout(button_layout)
|
|
|
|
def _load_armors(self):
|
|
"""Load armors from API."""
|
|
try:
|
|
nexus = get_nexus_api()
|
|
# Get armor sets from API
|
|
self._armors = nexus.get_all_armor_sets()
|
|
|
|
# Sort by name
|
|
self._armors.sort(key=lambda a: a.name.lower())
|
|
|
|
self._populate_list(self._armors)
|
|
except Exception as e:
|
|
logger.error(f"Failed to load armors: {e}")
|
|
QMessageBox.warning(self, "Error", f"Failed to load armors: {e}")
|
|
|
|
def _populate_list(self, armors):
|
|
"""Populate list with armors."""
|
|
self.armor_list.clear()
|
|
|
|
for armor in armors:
|
|
# Get decay from Defense field if available
|
|
decay_pec = Decimal("0")
|
|
if hasattr(armor, 'defense') and armor.defense:
|
|
# Estimate decay based on protection level
|
|
# Higher protection = higher decay
|
|
decay_pec = Decimal("15") # Default estimate
|
|
|
|
cost_per_hit = decay_pec / Decimal("100")
|
|
|
|
item = QListWidgetItem(f"{armor.name}")
|
|
item.setData(Qt.ItemDataRole.UserRole, armor)
|
|
|
|
# Tooltip with protection info
|
|
tooltip_parts = [f"Set ID: {armor.id}"]
|
|
if hasattr(armor, 'defense') and armor.defense:
|
|
tooltip_parts.append(f"Defense: {armor.defense}")
|
|
tooltip_parts.append(f"Est. Decay: {decay_pec} PEC")
|
|
tooltip_parts.append(f"Est. Cost/Hit: {cost_per_hit:.4f} PED")
|
|
|
|
item.setToolTip("\n".join(tooltip_parts))
|
|
|
|
self.armor_list.addItem(item)
|
|
|
|
def _on_search(self, text):
|
|
"""Filter armors by search text."""
|
|
if not text:
|
|
self._populate_list(self._armors)
|
|
return
|
|
|
|
text_lower = text.lower()
|
|
filtered = [a for a in self._armors if text_lower in a.name.lower()]
|
|
self._populate_list(filtered)
|
|
|
|
def _on_select(self, item):
|
|
"""Update preview when armor selected."""
|
|
armor = item.data(Qt.ItemDataRole.UserRole)
|
|
if not armor:
|
|
return
|
|
|
|
self.selected_armor = armor
|
|
|
|
# Estimate decay (we'll need to calculate this properly)
|
|
decay_pec = self._estimate_decay(armor)
|
|
cost_per_hit = decay_pec / Decimal("100")
|
|
|
|
# Update preview
|
|
self.preview_name.setText(armor.name)
|
|
|
|
protection_text = "See tooltip"
|
|
if hasattr(armor, 'defense') and armor.defense:
|
|
protection_text = str(armor.defense)[:50]
|
|
self.preview_protection.setText(protection_text)
|
|
|
|
self.preview_decay.setText(f"{decay_pec} PEC (estimated)")
|
|
self.preview_cost.setText(f"{cost_per_hit:.4f} PED")
|
|
|
|
self.ok_btn.setEnabled(True)
|
|
|
|
def _estimate_decay(self, armor):
|
|
"""Estimate decay based on armor protection."""
|
|
# This is a simplified estimate - real decay comes from API data
|
|
# For now, return a default value
|
|
# TODO: Get real decay from armor pieces or set data
|
|
return Decimal("15")
|
|
|
|
def _on_double_click(self, item):
|
|
"""Double-click to select immediately."""
|
|
self._on_select(item)
|
|
self.accept()
|
|
|
|
def get_selected_armor(self):
|
|
"""Get the selected armor as a dict for the simplified system."""
|
|
if not self.selected_armor:
|
|
return None
|
|
|
|
decay_pec = self._estimate_decay(self.selected_armor)
|
|
|
|
return {
|
|
'name': self.selected_armor.name,
|
|
'api_id': getattr(self.selected_armor, 'id', None),
|
|
'decay_pec': decay_pec,
|
|
'protection_summary': str(getattr(self.selected_armor, 'defense', 'Unknown')),
|
|
}
|