mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Faction editor update (#434)
Resolves #166 * init faction editor * update persistency * minor fixes * typing smh * small fixes * forgot the changelog -_-
This commit is contained in:
parent
f36526b5de
commit
0d04e0c72e
@ -44,6 +44,7 @@
|
||||
* **[Package Planning]** Ability to plan recovery tanker flights
|
||||
* **[Modding]** Support for Bandit's cloud presets mod (v15)
|
||||
* **[UX]** Reduce size of save-file by loading landmap data on the fly, which also implies no new campaign needs to be started to benefit from an updated landmap
|
||||
* **[New Game Wizard]** Ability to save an edited faction during new game creation
|
||||
|
||||
## Fixes
|
||||
* **[UI/UX]** A-10A flights can be edited again
|
||||
|
||||
@ -321,6 +321,38 @@ class Faction:
|
||||
|
||||
return faction
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return {
|
||||
"country": self.country.name,
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"authors": self.authors,
|
||||
"aircrafts": [ac.variant_id for ac in self.aircraft],
|
||||
"awacs": [ac.variant_id for ac in self.awacs],
|
||||
"tankers": [ac.variant_id for ac in self.tankers],
|
||||
"frontline_units": [unit.variant_id for unit in self.frontline_units],
|
||||
"artillery_units": [unit.variant_id for unit in self.artillery_units],
|
||||
"logistics_units": [unit.variant_id for unit in self.logistics_units],
|
||||
"infantry_units": [unit.variant_id for unit in self.infantry_units],
|
||||
"preset_groups": [group.name for group in self.preset_groups],
|
||||
"air_defense_units": [unit.variant_id for unit in self.air_defense_units],
|
||||
"naval_units": [unit.variant_id for unit in self.naval_units],
|
||||
"missiles": [unit.variant_id for unit in self.missiles],
|
||||
"has_jtac": self.has_jtac,
|
||||
"jtac_unit": self.jtac_unit.variant_id if self.jtac_unit else None,
|
||||
"doctrine": self.doctrine.name,
|
||||
"building_set": list(self.building_set),
|
||||
"liveries_overrides": {
|
||||
ac.variant_id: livery for ac, livery in self.liveries_overrides.items()
|
||||
},
|
||||
"liveries_overrides_ground_forces": self.liveries_overrides_ground_forces,
|
||||
"unrestricted_satnav": self.unrestricted_satnav,
|
||||
"requirements": self.requirements,
|
||||
"carriers": {
|
||||
carrier.variant_id: names for carrier, names in self.carriers.items()
|
||||
},
|
||||
}
|
||||
|
||||
@property
|
||||
def ground_units(self) -> Iterator[GroundUnitType]:
|
||||
yield from self.artillery_units
|
||||
|
||||
@ -37,7 +37,7 @@ class FactionLoader:
|
||||
|
||||
@classmethod
|
||||
def load_factions(cls: Type[FactionLoader]) -> Dict[str, Faction]:
|
||||
user_faction_path = persistency.base_path() / "Retribution/Factions"
|
||||
user_faction_path = persistency.factions_dir()
|
||||
files = cls.find_faction_files_in(
|
||||
FACTION_DIRECTORY
|
||||
) + cls.find_faction_files_in(user_faction_path)
|
||||
|
||||
@ -150,6 +150,10 @@ def debug_dir() -> Path:
|
||||
return _create_dir_if_needed(base_path() / "Retribution" / "Debug")
|
||||
|
||||
|
||||
def factions_dir() -> Path:
|
||||
return _create_dir_if_needed(base_path() / "Retribution" / "Factions")
|
||||
|
||||
|
||||
def groups_dir() -> Path:
|
||||
return _create_dir_if_needed(base_path() / "Retribution" / "Groups")
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from copy import deepcopy
|
||||
from typing import Union, Callable, Set, Optional
|
||||
from typing import Union, Callable, Set, Optional, List
|
||||
|
||||
from PySide6 import QtWidgets, QtGui
|
||||
from PySide6.QtCore import Qt
|
||||
@ -15,14 +17,22 @@ from PySide6.QtWidgets import (
|
||||
QPushButton,
|
||||
QComboBox,
|
||||
QHBoxLayout,
|
||||
QVBoxLayout,
|
||||
QLineEdit,
|
||||
QDialog,
|
||||
QFileDialog,
|
||||
)
|
||||
|
||||
from game import persistency
|
||||
from game.armedforces.forcegroup import ForceGroup
|
||||
from game.ato import FlightType
|
||||
from game.campaignloader import Campaign
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
from game.dcs.groundunittype import GroundUnitType
|
||||
from game.dcs.shipunittype import ShipUnitType
|
||||
from game.dcs.unittype import UnitType
|
||||
from game.factions import Faction, FACTIONS
|
||||
from qt_ui.uiconstants import EVENT_ICONS
|
||||
from qt_ui.windows.newgame.jinja_env import jinja_env
|
||||
|
||||
|
||||
@ -62,69 +72,128 @@ class QFactionUnits(QScrollArea):
|
||||
self.checkboxes: dict[str, QCheckBox] = {}
|
||||
grid = QGridLayout()
|
||||
grid.setColumnStretch(1, 1)
|
||||
if len(self.faction.aircraft) > 0:
|
||||
self.add_ac_combo = QComboBox()
|
||||
hbox = self._create_aircraft_combobox(
|
||||
self.add_ac_combo,
|
||||
lambda: self._on_add_ac(self.faction.aircraft, self.add_ac_combo),
|
||||
self._aircraft_predicate,
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Aircraft:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.aircraft, counter, grid, hbox)
|
||||
if len(self.faction.awacs) > 0:
|
||||
self.add_awacs_combo = QComboBox()
|
||||
hbox = self._create_aircraft_combobox(
|
||||
self.add_awacs_combo,
|
||||
lambda: self._on_add_ac(self.faction.awacs, self.add_awacs_combo),
|
||||
self._awacs_predicate,
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>AWACS:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.awacs, counter, grid, hbox)
|
||||
if len(self.faction.tankers) > 0:
|
||||
self.add_tanker_combo = QComboBox()
|
||||
hbox = self._create_aircraft_combobox(
|
||||
self.add_tanker_combo,
|
||||
lambda: self._on_add_ac(self.faction.tankers, self.add_tanker_combo),
|
||||
self._tanker_predicate,
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Tankers:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.tankers, counter, grid, hbox)
|
||||
if len(self.faction.frontline_units) > 0:
|
||||
self.add_frontline_combo = QComboBox()
|
||||
hbox = self._create_unit_combobox(
|
||||
self.add_frontline_combo,
|
||||
lambda: self._on_add_unit(
|
||||
self.faction.frontline_units, self.add_frontline_combo
|
||||
),
|
||||
self.faction.frontline_units,
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Frontlines vehicles:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(
|
||||
self.faction.frontline_units, counter, grid, hbox
|
||||
)
|
||||
if len(self.faction.artillery_units) > 0:
|
||||
grid.addWidget(QLabel("<strong>Artillery units:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.artillery_units, counter, grid)
|
||||
if len(self.faction.logistics_units) > 0:
|
||||
grid.addWidget(QLabel("<strong>Logistics units:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.logistics_units, counter, grid)
|
||||
if len(self.faction.infantry_units) > 0:
|
||||
grid.addWidget(QLabel("<strong>Infantry units:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.infantry_units, counter, grid)
|
||||
if len(self.faction.preset_groups) > 0:
|
||||
grid.addWidget(QLabel("<strong>Preset groups:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.preset_groups, counter, grid)
|
||||
if len(self.faction.air_defense_units) > 0:
|
||||
grid.addWidget(QLabel("<strong>Air defenses:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(
|
||||
self.faction.air_defense_units, counter, grid
|
||||
)
|
||||
if len(self.faction.naval_units) > 0:
|
||||
grid.addWidget(QLabel("<strong>Naval units:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.naval_units, counter, grid)
|
||||
if len(self.faction.missiles) > 0:
|
||||
grid.addWidget(QLabel("<strong>Missile units:</strong>"), counter, 0)
|
||||
self._add_checkboxes(self.faction.missiles, counter, grid)
|
||||
self.add_ac_combo = QComboBox()
|
||||
hbox = self._create_aircraft_combobox(
|
||||
self.add_ac_combo,
|
||||
lambda: self._on_add_ac(self.faction.aircraft, self.add_ac_combo),
|
||||
self._aircraft_predicate,
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Aircraft:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.aircraft, counter, grid, hbox)
|
||||
|
||||
self.add_awacs_combo = QComboBox()
|
||||
hbox = self._create_aircraft_combobox(
|
||||
self.add_awacs_combo,
|
||||
lambda: self._on_add_ac(self.faction.awacs, self.add_awacs_combo),
|
||||
self._awacs_predicate,
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>AWACS:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.awacs, counter, grid, hbox)
|
||||
|
||||
self.add_tanker_combo = QComboBox()
|
||||
hbox = self._create_aircraft_combobox(
|
||||
self.add_tanker_combo,
|
||||
lambda: self._on_add_ac(self.faction.tankers, self.add_tanker_combo),
|
||||
self._tanker_predicate,
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Tankers:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.tankers, counter, grid, hbox)
|
||||
|
||||
self.add_frontline_combo = QComboBox()
|
||||
hbox = self._create_unit_combobox(
|
||||
self.add_frontline_combo,
|
||||
lambda: self._on_add_unit(
|
||||
self.faction.frontline_units, self.add_frontline_combo
|
||||
),
|
||||
self.faction.frontline_units,
|
||||
["Frontline vehicles"],
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Frontlines vehicles:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(
|
||||
self.faction.frontline_units, counter, grid, hbox
|
||||
)
|
||||
|
||||
self.add_artillery_combo = QComboBox()
|
||||
hbox = self._create_unit_combobox(
|
||||
self.add_artillery_combo,
|
||||
lambda: self._on_add_unit(
|
||||
self.faction.artillery_units, self.add_artillery_combo
|
||||
),
|
||||
self.faction.artillery_units,
|
||||
["Artillery"],
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Artillery units:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(
|
||||
self.faction.artillery_units, counter, grid, hbox
|
||||
)
|
||||
|
||||
self.add_logistics_combo = QComboBox()
|
||||
hbox = self._create_unit_combobox(
|
||||
self.add_logistics_combo,
|
||||
lambda: self._on_add_unit(
|
||||
self.faction.logistics_units, self.add_logistics_combo
|
||||
),
|
||||
self.faction.logistics_units,
|
||||
["Logistics"],
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Logistics units:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(
|
||||
self.faction.logistics_units, counter, grid, hbox
|
||||
)
|
||||
|
||||
self.add_infantry_combo = QComboBox()
|
||||
hbox = self._create_unit_combobox(
|
||||
self.add_infantry_combo,
|
||||
lambda: self._on_add_unit(
|
||||
self.faction.infantry_units, self.add_infantry_combo
|
||||
),
|
||||
self.faction.infantry_units,
|
||||
["Infantry"],
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Infantry units:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.infantry_units, counter, grid, hbox)
|
||||
|
||||
self.add_preset_group_combo = QComboBox()
|
||||
hbox = self._create_preset_group_combobox(
|
||||
self.add_preset_group_combo,
|
||||
lambda: self._on_add_preset_group(
|
||||
self.faction.preset_groups, self.add_preset_group_combo
|
||||
),
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Preset groups:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.preset_groups, counter, grid, hbox)
|
||||
|
||||
self.add_air_defense_combo = QComboBox()
|
||||
hbox = self._create_unit_combobox(
|
||||
self.add_air_defense_combo,
|
||||
lambda: self._on_add_unit(
|
||||
self.faction.air_defense_units, self.add_air_defense_combo
|
||||
),
|
||||
self.faction.air_defense_units,
|
||||
["EarlyWarningRadar", "AAA", "SHORAD"],
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Air defenses:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(
|
||||
self.faction.air_defense_units, counter, grid, hbox
|
||||
)
|
||||
|
||||
self.add_naval_combo = QComboBox()
|
||||
hbox = self._create_naval_combobox(
|
||||
self.add_naval_combo,
|
||||
lambda: self._on_add_unit(self.faction.naval_units, self.add_naval_combo),
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Naval units:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.naval_units, counter, grid, hbox)
|
||||
|
||||
self.add_missile_combo = QComboBox()
|
||||
hbox = self._create_unit_combobox(
|
||||
self.add_missile_combo,
|
||||
lambda: self._on_add_unit(self.faction.missiles, self.add_missile_combo),
|
||||
self.faction.missiles,
|
||||
["Missile"],
|
||||
)
|
||||
grid.addWidget(QLabel("<strong>Missile units:</strong>"), counter, 0)
|
||||
counter = self._add_checkboxes(self.faction.missiles, counter, grid, hbox)
|
||||
|
||||
if show_jtac:
|
||||
grid.addWidget(QLabel("<strong>JTAC</strong>"), counter, 0)
|
||||
@ -166,20 +235,18 @@ class QFactionUnits(QScrollArea):
|
||||
):
|
||||
for ac_dcs in sorted(AircraftType.each_dcs_type(), key=lambda x: x.id):
|
||||
for ac in AircraftType.for_dcs_type(ac_dcs):
|
||||
if ac in self.faction.aircraft:
|
||||
if (
|
||||
ac in self.faction.aircraft
|
||||
or ac in self.faction.awacs
|
||||
or ac in self.faction.tankers
|
||||
):
|
||||
continue
|
||||
predicate(ac)
|
||||
add_ac = QPushButton("+")
|
||||
add_ac.setStyleSheet("QPushButton{ font-weight: bold; }")
|
||||
add_ac.setFixedWidth(50)
|
||||
add_ac.clicked.connect(callback)
|
||||
hbox = QHBoxLayout()
|
||||
hbox.addWidget(cb)
|
||||
hbox.addWidget(add_ac)
|
||||
hbox = self._format(cb, callback)
|
||||
return hbox
|
||||
|
||||
def _create_unit_combobox(
|
||||
self, cb: QComboBox, callback: Callable, units: Set[GroundUnitType]
|
||||
self, cb: QComboBox, callback: Callable, units: Set[GroundUnitType], type: list
|
||||
):
|
||||
for dcs_unit in sorted(GroundUnitType.each_dcs_type(), key=lambda x: x.id):
|
||||
if dcs_unit not in self.faction.country.vehicles:
|
||||
@ -187,14 +254,32 @@ class QFactionUnits(QScrollArea):
|
||||
for unit in GroundUnitType.for_dcs_type(dcs_unit):
|
||||
if unit in units:
|
||||
continue
|
||||
cb.addItem(unit.variant_id, unit)
|
||||
add_unit = QPushButton("+")
|
||||
add_unit.setStyleSheet("QPushButton{ font-weight: bold; }")
|
||||
add_unit.setFixedWidth(50)
|
||||
add_unit.clicked.connect(callback)
|
||||
hbox = QHBoxLayout()
|
||||
hbox.addWidget(cb)
|
||||
hbox.addWidget(add_unit)
|
||||
if "Frontline vehicles" in type:
|
||||
cb.addItem(unit.variant_id, unit)
|
||||
elif unit.unit_class.value in type:
|
||||
cb.addItem(unit.variant_id, unit)
|
||||
else:
|
||||
continue
|
||||
hbox = self._format(cb, callback)
|
||||
return hbox
|
||||
|
||||
def _create_naval_combobox(self, cb: QComboBox, callback: Callable):
|
||||
for ship_dcs in sorted(ShipUnitType.each_dcs_type(), key=lambda x: x.id):
|
||||
for ship in ShipUnitType.for_dcs_type(ship_dcs):
|
||||
if ship in self.faction.naval_units:
|
||||
continue
|
||||
cb.addItem(ship.variant_id, ship)
|
||||
hbox = self._format(cb, callback)
|
||||
return hbox
|
||||
|
||||
def _create_preset_group_combobox(self, cb: QComboBox, callback: Callable):
|
||||
ForceGroup._load_all()
|
||||
preset_group_names = {pg.name for pg in self.faction.preset_groups}
|
||||
for preset_group in ForceGroup._by_name:
|
||||
if preset_group in preset_group_names:
|
||||
continue
|
||||
cb.addItem(preset_group, ForceGroup._by_name[preset_group])
|
||||
hbox = self._format(cb, callback)
|
||||
return hbox
|
||||
|
||||
def _on_add_unit(self, units: Set[UnitType], cb: QComboBox):
|
||||
@ -211,6 +296,13 @@ class QFactionUnits(QScrollArea):
|
||||
del self.faction.__dict__["all_aircrafts"]
|
||||
self.updateFaction(self.faction)
|
||||
|
||||
def _on_add_preset_group(self, groups: List[ForceGroup], cb: QComboBox):
|
||||
groups.append(cb.currentData())
|
||||
if self.faction.__dict__.get("accessible_units"):
|
||||
# invalidate the cached property
|
||||
del self.faction.__dict__["accessible_units"]
|
||||
self.updateFaction(self.faction)
|
||||
|
||||
def updateFaction(self, faction: Faction):
|
||||
self.faction = faction
|
||||
self.content = QWidget()
|
||||
@ -228,6 +320,22 @@ class QFactionUnits(QScrollArea):
|
||||
for d in deletes:
|
||||
units.remove(d)
|
||||
|
||||
def _format(self, cb: QComboBox, callback: Callable):
|
||||
add_button = QPushButton("+")
|
||||
add_button.setStyleSheet("QPushButton{ font-weight: bold; }")
|
||||
add_button.setFixedWidth(50)
|
||||
add_button.clicked.connect(callback)
|
||||
hbox = QHBoxLayout()
|
||||
hbox.addWidget(cb)
|
||||
hbox.addWidget(add_button)
|
||||
if cb.count() == 0:
|
||||
cb.setEnabled(False)
|
||||
add_button.setEnabled(False)
|
||||
else:
|
||||
cb.setEnabled(True)
|
||||
add_button.setEnabled(True)
|
||||
return hbox
|
||||
|
||||
|
||||
class FactionSelection(QtWidgets.QWizardPage):
|
||||
def __init__(self, parent=None):
|
||||
@ -284,6 +392,17 @@ class FactionSelection(QtWidgets.QWizardPage):
|
||||
if r == "USA 2005":
|
||||
self.blueFactionSelect.setCurrentIndex(i)
|
||||
|
||||
self.saveBlueFactionButton = QPushButton("Save as new faction")
|
||||
self.saveRedFactionButton = QPushButton("Save as new faction")
|
||||
self.blueGroupLayout.addWidget(self.saveBlueFactionButton, 3, 0, 1, 2)
|
||||
self.redGroupLayout.addWidget(self.saveRedFactionButton, 3, 0, 1, 2)
|
||||
self.saveBlueFactionButton.clicked.connect(
|
||||
lambda: self.show_save_faction_dialog(self.selected_blue_faction)
|
||||
)
|
||||
self.saveRedFactionButton.clicked.connect(
|
||||
lambda: self.show_save_faction_dialog(self.selected_red_faction)
|
||||
)
|
||||
|
||||
# Faction units
|
||||
self.blueFactionUnits = QFactionUnits(
|
||||
self.blueFactionSelect.currentData(), self.blueGroupLayout, show_jtac=True
|
||||
@ -380,6 +499,15 @@ class FactionSelection(QtWidgets.QWizardPage):
|
||||
qfu.updateFactionUnits(fac.missiles)
|
||||
return fac
|
||||
|
||||
def show_save_faction_dialog(self, faction: Faction):
|
||||
dialog = QFactionSaver(faction)
|
||||
dialog.exec()
|
||||
for r in FACTIONS:
|
||||
if self.blueFactionSelect.findText(r) == -1:
|
||||
self.blueFactionSelect.addItem(r, FACTIONS[r])
|
||||
if self.redFactionSelect.findText(r) == -1:
|
||||
self.redFactionSelect.addItem(r, FACTIONS[r])
|
||||
|
||||
@property
|
||||
def selected_blue_faction(self) -> Faction:
|
||||
return self._filter_selected_units(self.blueFactionUnits)
|
||||
@ -387,3 +515,52 @@ class FactionSelection(QtWidgets.QWizardPage):
|
||||
@property
|
||||
def selected_red_faction(self) -> Faction:
|
||||
return self._filter_selected_units(self.redFactionUnits)
|
||||
|
||||
|
||||
class QFactionSaver(QDialog):
|
||||
def __init__(self, faction: Faction):
|
||||
super().__init__()
|
||||
self.faction = faction
|
||||
|
||||
self.setMinimumWidth(400)
|
||||
self.setWindowTitle("Save new faction")
|
||||
self.setWindowIcon(EVENT_ICONS["strike"])
|
||||
|
||||
layout = QVBoxLayout()
|
||||
|
||||
self.name_label = QLabel("Name:")
|
||||
self.name_text = QLineEdit()
|
||||
layout.addWidget(self.name_label)
|
||||
layout.addWidget(self.name_text)
|
||||
|
||||
self.description_label = QLabel("Description:")
|
||||
self.description_text = QLineEdit()
|
||||
layout.addWidget(self.description_label)
|
||||
layout.addWidget(self.description_text)
|
||||
|
||||
self.authors_label = QLabel("Author(s):")
|
||||
self.authors_text = QLineEdit()
|
||||
layout.addWidget(self.authors_label)
|
||||
layout.addWidget(self.authors_text)
|
||||
|
||||
self.save_button = QPushButton("Save")
|
||||
self.save_button.clicked.connect(self.save_faction)
|
||||
layout.addWidget(self.save_button)
|
||||
self.setLayout(layout)
|
||||
|
||||
def save_faction(self) -> None:
|
||||
self.faction.name = self.name_text.text()
|
||||
self.faction.description = f"<p>{self.description_text.text()}</p>"
|
||||
self.faction.authors = self.authors_text.text()
|
||||
user_faction_path = persistency.factions_dir()
|
||||
|
||||
fd = QFileDialog(
|
||||
caption="Save Faction", directory=str(user_faction_path), filter="*.json"
|
||||
)
|
||||
fd.setAcceptMode(QFileDialog.AcceptMode.AcceptSave)
|
||||
if fd.exec_():
|
||||
json_filename = fd.selectedFiles()[0]
|
||||
with open(json_filename, "w") as file:
|
||||
json.dump(self.faction.to_dict(), file, indent=2)
|
||||
FACTIONS.factions[self.faction.name] = self.faction
|
||||
self.accept()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user