diff --git a/ui/gear_selector.py b/ui/gear_selector.py index ba48b2f..6afd1b1 100644 --- a/ui/gear_selector.py +++ b/ui/gear_selector.py @@ -318,362 +318,3 @@ if __name__ == "__main__": print("Selected:", dialog.selected_gear.name if dialog.selected_gear else None) sys.exit(0) - self.api = EntropiaNexusAPI() - - self.setWindowTitle(f"Select {gear_type.title()} - Entropia Nexus") - self.setMinimumSize(800, 600) - self.setup_ui() - - # Load weapons in background - self.load_weapons_async() - - def setup_ui(self): - layout = QVBoxLayout(self) - layout.setSpacing(10) - - # Status label - self.status_label = QLabel("Loading weapons from Entropia Nexus...") - layout.addWidget(self.status_label) - - # Search box - search_layout = QHBoxLayout() - search_layout.addWidget(QLabel("Search:")) - - self.search_input = QLineEdit() - self.search_input.setPlaceholderText("Search weapons (e.g., 'ArMatrix', 'Opalo')...") - self.search_input.returnPressed.connect(self.on_search) - self.search_input.setEnabled(False) - search_layout.addWidget(self.search_input) - - self.search_btn = QPushButton("Search") - self.search_btn.clicked.connect(self.on_search) - self.search_btn.setEnabled(False) - search_layout.addWidget(self.search_btn) - - layout.addLayout(search_layout) - - # Results list - self.results_tree = QTreeWidget() - self.results_tree.setHeaderLabels(["Name", "Type", "Damage", "DPP", "Cost/h", "Efficiency"]) - self.results_tree.setAlternatingRowColors(True) - self.results_tree.setSelectionMode(QTreeWidget.SelectionMode.SingleSelection) - self.results_tree.itemSelectionChanged.connect(self.on_selection_changed) - self.results_tree.itemDoubleClicked.connect(self.on_item_double_clicked) - - # Adjust columns - header = self.results_tree.header() - header.setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch) - header.setSectionResizeMode(1, QHeaderView.ResizeMode.Fixed) - header.setSectionResizeMode(2, QHeaderView.ResizeMode.Fixed) - header.setSectionResizeMode(3, QHeaderView.ResizeMode.Fixed) - header.setSectionResizeMode(4, QHeaderView.ResizeMode.Fixed) - header.setSectionResizeMode(5, QHeaderView.ResizeMode.Fixed) - header.resizeSection(1, 100) - header.resizeSection(2, 70) - header.resizeSection(3, 60) - header.resizeSection(4, 70) - header.resizeSection(5, 70) - - layout.addWidget(self.results_tree) - - # Stats preview - self.stats_group = QGroupBox("Stats Preview") - self.stats_layout = QFormLayout(self.stats_group) - self.stats_layout.addRow("Select a weapon to view detailed stats", QLabel("")) - layout.addWidget(self.stats_group) - - # Buttons - button_box = QDialogButtonBox( - QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel - ) - button_box.accepted.connect(self.on_accept) - button_box.rejected.connect(self.reject) - self.ok_btn = button_box.button(QDialogButtonBox.StandardButton.Ok) - self.ok_btn.setEnabled(False) - self.ok_btn.setText("Select Weapon") - layout.addWidget(button_box) - - def load_weapons_async(self): - """Load weapons in background thread.""" - self.loader_thread = WeaponLoaderThread(self.api) - self.loader_thread.weapons_loaded.connect(self.on_weapons_loaded) - self.loader_thread.error_occurred.connect(self.on_load_error) - self.loader_thread.start() - - def on_weapons_loaded(self, weapons: List[WeaponStats]): - """Handle loaded weapons.""" - self.weapons = weapons - self.status_label.setText(f"Loaded {len(weapons)} weapons from Entropia Nexus") - self.search_input.setEnabled(True) - self.search_btn.setEnabled(True) - self.populate_tree(weapons[:100]) # Show first 100 initially - - def on_load_error(self, error: str): - """Handle load error.""" - self.status_label.setText(f"Error loading weapons: {error}") - - def populate_tree(self, weapons: List[WeaponStats]): - """Populate tree with weapons.""" - self.results_tree.clear() - for w in weapons: - item = QTreeWidgetItem([ - w.name, - f"{w.type} {w.category}", - str(w.total_damage), - f"{w.dpp:.2f}", - f"{w.cost_per_hour:.0f}", - f"{w.efficiency:.1f}" if w.efficiency else "-" - ]) - item.setData(0, Qt.ItemDataRole.UserRole, w) - self.results_tree.addTopLevelItem(item) - - def on_search(self): - """Search weapons.""" - query = self.search_input.text().strip().lower() - if not query: - self.populate_tree(self.weapons[:100]) - return - - import asyncio - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - results = loop.run_until_complete(self.api.search_weapons(query)) - loop.close() - - self.populate_tree(results) - self.status_label.setText(f"Found {len(results)} weapons matching '{query}'") - - def on_selection_changed(self): - """Handle selection change.""" - selected = self.results_tree.selectedItems() - if selected: - weapon = selected[0].data(0, Qt.ItemDataRole.UserRole) - self.selected_gear = weapon - self.ok_btn.setEnabled(True) - self.update_stats_preview(weapon) - else: - self.selected_gear = None - self.ok_btn.setEnabled(False) - - def update_stats_preview(self, w: WeaponStats): - """Update stats preview.""" - # Clear previous - while self.stats_layout.rowCount() > 0: - self.stats_layout.removeRow(0) - - self.stats_layout.addRow("Name:", QLabel(w.name)) - self.stats_layout.addRow("Type:", QLabel(f"{w.type} {w.category}")) - self.stats_layout.addRow("Class:", QLabel(w.weapon_class)) - self.stats_layout.addRow("Damage:", QLabel(str(w.total_damage))) - self.stats_layout.addRow("DPP:", QLabel(f"{w.dpp:.3f}")) - self.stats_layout.addRow("Decay:", QLabel(f"{w.decay} PEC" if w.decay else "-")) - self.stats_layout.addRow("Ammo:", QLabel(f"{w.ammo_burn} per shot" if w.ammo_burn else "-")) - self.stats_layout.addRow("Uses/min:", QLabel(str(w.uses_per_minute))) - self.stats_layout.addRow("Range:", QLabel(f"{w.range_meters}m" if w.range_meters else "-")) - self.stats_layout.addRow("Efficiency:", QLabel(f"{w.efficiency}%" if w.efficiency else "-")) - self.stats_layout.addRow("Cost/hour:", QLabel(f"{w.cost_per_hour:.2f} PED")) - self.stats_layout.addRow("Max TT:", QLabel(f"{w.max_tt} PED")) - - def on_item_double_clicked(self, item, column): - """Handle double click.""" - self.on_accept() - - def on_accept(self): - """Handle OK button.""" - if self.selected_gear: - w = self.selected_gear - self.gear_selected.emit( - "weapon", - w.name, - { - 'id': w.id, - 'item_id': w.item_id, - 'dpp': float(w.dpp), - 'cost_per_hour': float(w.cost_per_hour), - 'total_damage': float(w.total_damage), - } - ) - self.accept() - - -if __name__ == "__main__": - import sys - from PyQt6.QtWidgets import QApplication - - app = QApplication(sys.argv) - - dialog = GearSelectorDialog("weapon") - if dialog.exec() == QDialog.DialogCode.Accepted: - print("Selected:", dialog.selected_gear.name if dialog.selected_gear else None) - - sys.exit(0) - self.results_tree.itemDoubleClicked.connect(self.on_item_double_clicked) - - # Adjust columns - header = self.results_tree.header() - header.setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch) - header.setSectionResizeMode(1, QHeaderView.ResizeMode.Fixed) - header.setSectionResizeMode(2, QHeaderView.ResizeMode.Fixed) - header.setSectionResizeMode(3, QHeaderView.ResizeMode.Fixed) - header.resizeSection(1, 120) - header.resizeSection(2, 100) - header.resizeSection(3, 100) - - layout.addWidget(self.results_tree) - - # Stats preview - self.stats_group = QGroupBox("Stats Preview") - self.stats_layout = QFormLayout(self.stats_group) - self.stats_layout.addRow("Select an item to view stats", QLabel("")) - layout.addWidget(self.stats_group) - - # Buttons - button_box = QDialogButtonBox( - QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel - ) - button_box.accepted.connect(self.on_accept) - button_box.rejected.connect(self.reject) - self.ok_btn = button_box.button(QDialogButtonBox.StandardButton.Ok) - self.ok_btn.setEnabled(False) - self.ok_btn.setText("Select Gear") - layout.addWidget(button_box) - - def load_mock_data(self): - """Load mock gear data for testing.""" - from core.nexus_api import MOCK_WEAPONS, MOCK_ARMORS, MOCK_TOOLS - - self.results_tree.clear() - - if self.gear_type == "weapon": - for weapon_id, weapon in MOCK_WEAPONS.items(): - item = QTreeWidgetItem([ - weapon.name, - f"{weapon.damage}", - f"{weapon.dpp}", - f"{weapon.range}m" - ]) - item.setData(0, Qt.ItemDataRole.UserRole, { - 'id': weapon_id, - 'type': 'weapon', - 'data': weapon - }) - self.results_tree.addTopLevelItem(item) - - elif self.gear_type == "armor": - for armor_id, armor in MOCK_ARMORS.items(): - total_prot = armor.get_total_protection() - item = QTreeWidgetItem([ - armor.name, - f"{total_prot}", - f"{armor.decay_pec} PEC", - "-" - ]) - item.setData(0, Qt.ItemDataRole.UserRole, { - 'id': armor_id, - 'type': 'armor', - 'data': armor - }) - self.results_tree.addTopLevelItem(item) - - elif self.gear_type == "tool": - for tool_id, tool in MOCK_TOOLS.items(): - item = QTreeWidgetItem([ - tool.name, - f"{tool.depth}m", - f"{tool.decay_pec} PEC", - f"{tool.radius}m" - ]) - item.setData(0, Qt.ItemDataRole.UserRole, { - 'id': tool_id, - 'type': 'tool', - 'data': tool - }) - self.results_tree.addTopLevelItem(item) - - def on_search(self): - """Search for gear.""" - query = self.search_input.text().strip().lower() - if not query: - self.load_mock_data() - return - - # Filter results - for i in range(self.results_tree.topLevelItemCount()): - item = self.results_tree.topLevelItem(i) - name = item.text(0).lower() - item.setHidden(query not in name) - - def on_selection_changed(self): - """Handle selection change.""" - selected = self.results_tree.selectedItems() - if selected: - item_data = selected[0].data(0, Qt.ItemDataRole.UserRole) - self.selected_gear = item_data - self.ok_btn.setEnabled(True) - self.update_stats_preview(item_data) - else: - self.selected_gear = None - self.ok_btn.setEnabled(False) - - def update_stats_preview(self, item_data): - """Update stats preview.""" - # Clear previous - while self.stats_layout.rowCount() > 0: - self.stats_layout.removeRow(0) - - gear = item_data['data'] - - if item_data['type'] == 'weapon': - self.stats_layout.addRow("Damage:", QLabel(f"{gear.damage}")) - self.stats_layout.addRow("DPP:", QLabel(f"{gear.dpp}")) - self.stats_layout.addRow("Decay:", QLabel(f"{gear.decay_pec} PEC")) - self.stats_layout.addRow("Ammo:", QLabel(f"{gear.ammo_pec} PEC")) - self.stats_layout.addRow("Range:", QLabel(f"{gear.range}m")) - self.stats_layout.addRow("Attacks/min:", QLabel(f"{gear.attacks_per_min}")) - self.stats_layout.addRow("Cost/hour:", QLabel(f"{gear.calculate_cost_per_hour():.2f} PED")) - - elif item_data['type'] == 'armor': - self.stats_layout.addRow("Decay:", QLabel(f"{gear.decay_pec} PEC")) - self.stats_layout.addRow("Total Protection:", QLabel(f"{gear.get_total_protection()}")) - for dmg_type, value in gear.protection.items(): - self.stats_layout.addRow(f" {dmg_type.title()}:", QLabel(f"{value}")) - - elif item_data['type'] == 'tool': - self.stats_layout.addRow("Type:", QLabel(f"{gear.tool_type}")) - self.stats_layout.addRow("Depth:", QLabel(f"{gear.depth}m")) - self.stats_layout.addRow("Radius:", QLabel(f"{gear.radius}m")) - self.stats_layout.addRow("Decay:", QLabel(f"{gear.decay_pec} PEC")) - if gear.probe_cost: - self.stats_layout.addRow("Cost/drop:", QLabel(f"{gear.calculate_cost_per_drop():.3f} PED")) - - def on_item_double_clicked(self, item, column): - """Handle double click.""" - self.on_accept() - - def on_accept(self): - """Handle OK button.""" - if self.selected_gear: - gear = self.selected_gear['data'] - self.gear_selected.emit( - self.selected_gear['type'], - gear.name, - { - 'id': self.selected_gear['id'], - 'dpp': getattr(gear, 'dpp', None), - 'cost_per_hour': getattr(gear, 'calculate_cost_per_hour', lambda: 0)() - } - ) - self.accept() - - -if __name__ == "__main__": - import sys - from PyQt6.QtWidgets import QApplication - - app = QApplication(sys.argv) - - dialog = GearSelectorDialog("weapon") - if dialog.exec() == QDialog.DialogCode.Accepted: - print("Selected gear:", dialog.selected_gear) - - sys.exit(0) \ No newline at end of file