fix: loadout selection dialog now reads from both database and JSON files
- Added support for loading JSON-saved loadouts - Dialog now scans ~/.lemontropia/loadouts/ directory - Displays both database and file-based loadouts - Calculates costs from JSON data for preview
This commit is contained in:
parent
c71f6a8647
commit
2c2249f45e
|
|
@ -2,6 +2,8 @@
|
|||
# Allows choosing a loadout when starting a new session
|
||||
# Standards: Python 3.11+, PyQt6, type hints
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from decimal import Decimal
|
||||
from PyQt6.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
|
||||
|
|
@ -39,6 +41,10 @@ class LoadoutSelectionDialog(QDialog):
|
|||
self.db = db_manager or DatabaseManager()
|
||||
self.loadout_db = LoadoutDatabase(self.db)
|
||||
|
||||
# Also check JSON files
|
||||
self.config_dir = Path.home() / ".lemontropia" / "loadouts"
|
||||
self.config_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
self.selected_loadout_id: Optional[int] = None
|
||||
self.selected_loadout_name: Optional[str] = None
|
||||
|
||||
|
|
@ -114,10 +120,40 @@ class LoadoutSelectionDialog(QDialog):
|
|||
layout.addLayout(btn_layout)
|
||||
|
||||
def _load_loadouts(self):
|
||||
"""Load saved loadouts from database."""
|
||||
loadouts = self.loadout_db.list_loadouts()
|
||||
"""Load saved loadouts from database and JSON files."""
|
||||
self.all_loadouts = [] # Store all loadouts for lookup
|
||||
|
||||
if not loadouts:
|
||||
# First try database
|
||||
db_loadouts = self.loadout_db.list_loadouts()
|
||||
for loadout in db_loadouts:
|
||||
self.all_loadouts.append({
|
||||
'id': loadout['id'],
|
||||
'name': loadout['name'],
|
||||
'source': 'db',
|
||||
'data': loadout
|
||||
})
|
||||
|
||||
# Also check JSON files
|
||||
try:
|
||||
for filepath in sorted(self.config_dir.glob("*.json")):
|
||||
try:
|
||||
with open(filepath, 'r') as f:
|
||||
data = json.load(f)
|
||||
# Generate a unique ID based on filename
|
||||
loadout_id = abs(hash(filepath.stem)) % (10 ** 9)
|
||||
self.all_loadouts.append({
|
||||
'id': loadout_id,
|
||||
'name': data.get('name', filepath.stem),
|
||||
'source': 'json',
|
||||
'filepath': str(filepath),
|
||||
'data': data
|
||||
})
|
||||
except Exception as e:
|
||||
print(f"Error loading {filepath}: {e}")
|
||||
except Exception as e:
|
||||
print(f"Error scanning config dir: {e}")
|
||||
|
||||
if not self.all_loadouts:
|
||||
# No loadouts saved
|
||||
item = QListWidgetItem("No loadouts saved yet")
|
||||
item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable)
|
||||
|
|
@ -125,28 +161,33 @@ class LoadoutSelectionDialog(QDialog):
|
|||
self.loadout_list.addItem(item)
|
||||
return
|
||||
|
||||
for loadout in loadouts:
|
||||
# Sort by name
|
||||
self.all_loadouts.sort(key=lambda x: x['name'].lower())
|
||||
|
||||
for loadout_info in self.all_loadouts:
|
||||
item = QListWidgetItem()
|
||||
item.setText(loadout['name'])
|
||||
item.setText(loadout_info['name'])
|
||||
|
||||
data = loadout_info['data']
|
||||
|
||||
# Build tooltip with gear info
|
||||
tooltip = f"Weapon: {loadout['weapon_name'] or 'None'}\n"
|
||||
tooltip += f"Armor: {loadout['armor_name'] or 'None'}\n"
|
||||
tooltip += f"Healing: {loadout['healing_tool_name'] or 'None'}\n"
|
||||
tooltip += f"Cost/Shot: {loadout['cost_per_shot_ped']:.4f} PED\n"
|
||||
tooltip += f"Cost/Hit: {loadout['cost_per_hit_ped']:.4f} PED\n"
|
||||
tooltip += f"Cost/Heal: {loadout['cost_per_heal_ped']:.4f} PED"
|
||||
if loadout_info['source'] == 'db':
|
||||
tooltip = f"Weapon: {data.get('weapon_name') or 'None'}\n"
|
||||
tooltip += f"Armor: {data.get('armor_name') or 'None'}\n"
|
||||
tooltip += f"Healing: {data.get('healing_tool_name') or 'None'}\n"
|
||||
tooltip += f"Cost/Shot: {data.get('cost_per_shot_ped', 0):.4f} PED\n"
|
||||
tooltip += f"Cost/Hit: {data.get('cost_per_hit_ped', 0):.4f} PED\n"
|
||||
tooltip += f"Cost/Heal: {data.get('cost_per_heal_ped', 0):.4f} PED"
|
||||
else:
|
||||
# JSON format
|
||||
tooltip = f"Weapon: {data.get('weapon_name', 'None')}\n"
|
||||
tooltip += f"Armor: {data.get('armor_set_name', 'None')}\n"
|
||||
tooltip += f"Healing: {data.get('heal_name', 'None')}"
|
||||
|
||||
item.setToolTip(tooltip)
|
||||
|
||||
# Store loadout ID
|
||||
item.setData(Qt.ItemDataRole.UserRole, loadout['id'])
|
||||
|
||||
# Highlight active loadout
|
||||
if loadout.get('is_active'):
|
||||
item.setText(f"⭐ {loadout['name']} (Active)")
|
||||
font = item.font()
|
||||
font.setBold(True)
|
||||
item.setFont(font)
|
||||
# Store loadout info
|
||||
item.setData(Qt.ItemDataRole.UserRole, loadout_info['id'])
|
||||
|
||||
self.loadout_list.addItem(item)
|
||||
|
||||
|
|
@ -165,25 +206,53 @@ class LoadoutSelectionDialog(QDialog):
|
|||
self.ok_button.setEnabled(False)
|
||||
return
|
||||
|
||||
# Find the loadout info
|
||||
loadout_info = None
|
||||
for lo in self.all_loadouts:
|
||||
if lo['id'] == loadout_id:
|
||||
loadout_info = lo
|
||||
break
|
||||
|
||||
if not loadout_info:
|
||||
self.ok_button.setEnabled(False)
|
||||
return
|
||||
|
||||
self.selected_loadout_id = loadout_id
|
||||
self.selected_loadout_name = item.text().replace("⭐ ", "").replace(" (Active)", "")
|
||||
self.selected_loadout_name = loadout_info['name']
|
||||
|
||||
# Load and display preview
|
||||
loadout = self.loadout_db.get_loadout(self.selected_loadout_name)
|
||||
if loadout:
|
||||
self._update_preview(loadout)
|
||||
self.ok_button.setEnabled(True)
|
||||
self._update_preview(loadout_info)
|
||||
self.ok_button.setEnabled(True)
|
||||
|
||||
def _update_preview(self, loadout: Dict[str, Any]):
|
||||
def _update_preview(self, loadout_info: Dict[str, Any]):
|
||||
"""Update preview panel with loadout details."""
|
||||
self.preview_weapon.setText(loadout.get('weapon_name') or "None")
|
||||
self.preview_armor.setText(loadout.get('armor_name') or "None")
|
||||
self.preview_healing.setText(loadout.get('healing_tool_name') or "None")
|
||||
data = loadout_info['data']
|
||||
|
||||
# Format costs
|
||||
cost_shot = Decimal(str(loadout.get('cost_per_shot_ped', 0)))
|
||||
cost_hit = Decimal(str(loadout.get('cost_per_hit_ped', 0)))
|
||||
cost_heal = Decimal(str(loadout.get('cost_per_heal_ped', 0)))
|
||||
if loadout_info['source'] == 'db':
|
||||
self.preview_weapon.setText(data.get('weapon_name') or "None")
|
||||
self.preview_armor.setText(data.get('armor_name') or "None")
|
||||
self.preview_healing.setText(data.get('healing_tool_name') or "None")
|
||||
|
||||
# Format costs
|
||||
cost_shot = Decimal(str(data.get('cost_per_shot_ped', 0)))
|
||||
cost_hit = Decimal(str(data.get('cost_per_hit_ped', 0)))
|
||||
cost_heal = Decimal(str(data.get('cost_per_heal_ped', 0)))
|
||||
else:
|
||||
# JSON format
|
||||
self.preview_weapon.setText(data.get('weapon_name', "None"))
|
||||
self.preview_armor.setText(data.get('armor_set_name', "None"))
|
||||
self.preview_healing.setText(data.get('heal_name', "None"))
|
||||
|
||||
# Try to calculate costs from JSON data
|
||||
weapon_decay = Decimal(str(data.get('weapon_decay_pec', 0)))
|
||||
weapon_ammo = Decimal(str(data.get('weapon_ammo_pec', 0)))
|
||||
cost_shot = (weapon_decay + weapon_ammo) / Decimal("100")
|
||||
|
||||
armor_decay = Decimal(str(data.get('armor_decay_pec', 0)))
|
||||
cost_hit = armor_decay / Decimal("100")
|
||||
|
||||
heal_cost = Decimal(str(data.get('heal_cost_pec', 0)))
|
||||
cost_heal = heal_cost / Decimal("100")
|
||||
|
||||
self.preview_cost_shot.setText(f"{cost_shot:.4f} PED")
|
||||
self.preview_cost_hit.setText(f"{cost_hit:.4f} PED")
|
||||
|
|
|
|||
Loading…
Reference in New Issue