mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
parent
0923add514
commit
4898cdb614
@ -14,6 +14,7 @@
|
||||
* **[Modding]** Support for SW mod v2.55
|
||||
* **[Modding]** Support for Spanish & Australian Naval Assets v3.2.0 by desdemicabina
|
||||
* **[Modding]** Support for Iron Dome v1.2 by IDF Mods Project
|
||||
* **[NewGameWizard]** Re-organized generator options & show the regular settings menu instead of the limited "Difficulty & Automation" page.
|
||||
|
||||
## Fixes
|
||||
* **[New Game Wizard]** Settings would not persist when going back to a previous page.
|
||||
|
||||
5
game/settings/ISettingsContainer.py
Normal file
5
game/settings/ISettingsContainer.py
Normal file
@ -0,0 +1,5 @@
|
||||
from game.settings import Settings
|
||||
|
||||
|
||||
class SettingsContainer:
|
||||
settings: Settings
|
||||
@ -257,7 +257,10 @@ class Settings:
|
||||
CAMPAIGN_MANAGEMENT_PAGE,
|
||||
PILOTS_AND_SQUADRONS_SECTION,
|
||||
default=False,
|
||||
detail="If set, squadrons will be limited to a maximum number of aircraft.",
|
||||
detail=(
|
||||
"If set, squadrons will not be able to exceed a maximum number of aircraft "
|
||||
"(configurable), and the campaign will begin with all squadrons at full strength."
|
||||
),
|
||||
)
|
||||
|
||||
# HQ Automation
|
||||
@ -718,6 +721,9 @@ class Settings:
|
||||
new_state = Settings().__dict__
|
||||
new_state.update(state)
|
||||
self.__dict__.update(new_state)
|
||||
from game.plugins import LuaPluginManager
|
||||
|
||||
LuaPluginManager().load_settings(self)
|
||||
|
||||
@classmethod
|
||||
def _field_description(cls, settings_field: Field[Any]) -> OptionDescription:
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from PySide2 import QtGui, QtWidgets
|
||||
|
||||
from game.campaignloader.campaign import Campaign
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
from game.settings import Settings
|
||||
from game.theater.start_generator import GameGenerator, GeneratorSettings, ModSettings
|
||||
from qt_ui.windows.AirWingConfigurationDialog import AirWingConfigurationDialog
|
||||
from qt_ui.windows.newgame.SettingNames import RUNWAY_REPAIR, FRONTLINE, AIRCRAFT, MISSION_LENGTH, SUPER_CARRIER
|
||||
from qt_ui.windows.newgame.WizardPages.QFactionSelection import FactionSelection
|
||||
from qt_ui.windows.newgame.WizardPages.QGeneratorSettings import GeneratorOptions
|
||||
from qt_ui.windows.newgame.WizardPages.QNewGameSettings import NewGameSettings
|
||||
from qt_ui.windows.newgame.WizardPages.QTheaterConfiguration import TheaterConfiguration, TIME_PERIODS
|
||||
from qt_ui.windows.newgame.WizardPages.QTheaterConfiguration import (
|
||||
TheaterConfiguration,
|
||||
TIME_PERIODS,
|
||||
)
|
||||
|
||||
|
||||
class NewGameWizard(QtWidgets.QWizard):
|
||||
@ -33,8 +33,7 @@ class NewGameWizard(QtWidgets.QWizard):
|
||||
self.addPage(self.faction_selection_page)
|
||||
self.go_page = GeneratorOptions(self.campaigns[0], self)
|
||||
self.addPage(self.go_page)
|
||||
self.settings_page = NewGameSettings(self)
|
||||
self.settings_page.set_campaign_values(self.campaigns[0])
|
||||
self.settings_page = NewGameSettings(self.campaigns[0], self)
|
||||
|
||||
# Update difficulty page on campaign select
|
||||
self.theater_page.campaign_selected.connect(lambda c: self.update_settings(c))
|
||||
@ -70,21 +69,6 @@ class NewGameWizard(QtWidgets.QWizard):
|
||||
start_date = self.theater_page.calendar.selectedDate().toPython()
|
||||
|
||||
logging.info("New campaign start date: %s", start_date.strftime("%m/%d/%Y"))
|
||||
settings = Settings()
|
||||
settings.__setstate__(campaign.settings)
|
||||
settings.player_income_multiplier = self.field("player_income_multiplier") / 10
|
||||
settings.enemy_income_multiplier = self.field("enemy_income_multiplier") / 10
|
||||
settings.automate_runway_repair = self.field(RUNWAY_REPAIR)
|
||||
settings.automate_front_line_reinforcements = self.field(FRONTLINE)
|
||||
settings.desired_player_mission_duration = timedelta(
|
||||
minutes=self.field(MISSION_LENGTH)
|
||||
)
|
||||
settings.enable_squadron_aircraft_limits = self.field("use_new_squadron_rules")
|
||||
settings.automate_aircraft_reinforcements = self.field(AIRCRAFT)
|
||||
settings.supercarrier = self.field(SUPER_CARRIER)
|
||||
settings.perf_culling = (
|
||||
campaign.settings.get("perf_culling_distance") is not None
|
||||
)
|
||||
|
||||
generator_settings = GeneratorSettings(
|
||||
start_date=start_date,
|
||||
@ -138,6 +122,8 @@ class NewGameWizard(QtWidgets.QWizard):
|
||||
|
||||
logging.info("New campaign theater: %s", theater.terrain.name)
|
||||
|
||||
settings = self.settings_page.settings_widget.settings
|
||||
|
||||
generator = GameGenerator(
|
||||
blue_faction,
|
||||
red_faction,
|
||||
|
||||
@ -4,7 +4,14 @@ from copy import deepcopy
|
||||
|
||||
from PySide2 import QtWidgets, QtGui
|
||||
from PySide2.QtCore import Qt
|
||||
from PySide2.QtWidgets import QScrollArea, QWidget, QGridLayout, QCheckBox, QLabel, QTextBrowser
|
||||
from PySide2.QtWidgets import (
|
||||
QScrollArea,
|
||||
QWidget,
|
||||
QGridLayout,
|
||||
QCheckBox,
|
||||
QLabel,
|
||||
QTextBrowser,
|
||||
)
|
||||
|
||||
from game.campaignloader import Campaign
|
||||
from game.factions import Faction, FACTIONS
|
||||
|
||||
@ -8,8 +8,7 @@ from PySide2.QtWidgets import QLabel, QVBoxLayout
|
||||
|
||||
from game.campaignloader import Campaign
|
||||
from game.campaignloader.campaign import DEFAULT_BUDGET
|
||||
from qt_ui.widgets.spinsliders import CurrencySpinner, TimeInputs
|
||||
from qt_ui.windows.newgame.SettingNames import MISSION_LENGTH, SUPER_CARRIER
|
||||
from qt_ui.widgets.spinsliders import CurrencySpinner
|
||||
|
||||
DEFAULT_MISSION_LENGTH: timedelta = timedelta(minutes=60)
|
||||
|
||||
@ -51,38 +50,28 @@ class GeneratorOptions(QtWidgets.QWizardPage):
|
||||
self.registerField("no_carrier", self.no_carrier)
|
||||
self.no_lha = QtWidgets.QCheckBox()
|
||||
self.registerField("no_lha", self.no_lha)
|
||||
self.supercarrier = QtWidgets.QCheckBox()
|
||||
self.registerField(SUPER_CARRIER, self.supercarrier)
|
||||
self.no_player_navy = QtWidgets.QCheckBox()
|
||||
self.registerField("no_player_navy", self.no_player_navy)
|
||||
self.no_enemy_navy = QtWidgets.QCheckBox()
|
||||
self.registerField("no_enemy_navy", self.no_enemy_navy)
|
||||
self.desired_player_mission_duration = TimeInputs(
|
||||
DEFAULT_MISSION_LENGTH, minimum=30, maximum=150
|
||||
)
|
||||
self.registerField(MISSION_LENGTH, self.desired_player_mission_duration.spinner)
|
||||
|
||||
generatorLayout = QtWidgets.QGridLayout()
|
||||
generatorLayout.addWidget(QtWidgets.QLabel("No Aircraft Carriers"), 1, 0)
|
||||
generatorLayout.addWidget(self.no_carrier, 1, 1)
|
||||
generatorLayout.addWidget(QtWidgets.QLabel("No LHA"), 2, 0)
|
||||
generatorLayout.addWidget(self.no_lha, 2, 1)
|
||||
generatorLayout.addWidget(QtWidgets.QLabel("Use Supercarrier module"), 3, 0)
|
||||
generatorLayout.addWidget(self.supercarrier, 3, 1)
|
||||
generatorLayout.addWidget(QtWidgets.QLabel("No Player Navy"), 4, 0)
|
||||
generatorLayout.addWidget(self.no_player_navy, 4, 1)
|
||||
generatorLayout.addWidget(QtWidgets.QLabel("No Enemy Navy"), 5, 0)
|
||||
generatorLayout.addWidget(self.no_enemy_navy, 5, 1)
|
||||
# generatorLayout.addWidget(QtWidgets.QLabel("Desired mission duration"), 6, 0)
|
||||
# generatorLayout.addLayout(self.desired_player_mission_duration, 7, 0)
|
||||
generatorLayout.addWidget(QtWidgets.QLabel("No Player Navy"), 3, 0)
|
||||
generatorLayout.addWidget(self.no_player_navy, 3, 1)
|
||||
generatorLayout.addWidget(QtWidgets.QLabel("No Enemy Navy"), 4, 0)
|
||||
generatorLayout.addWidget(self.no_enemy_navy, 4, 1)
|
||||
|
||||
self.player_budget = BudgetInputs("Player starting budget", DEFAULT_BUDGET)
|
||||
self.registerField("starting_money", self.player_budget.starting_money)
|
||||
generatorLayout.addLayout(self.player_budget, 8, 0)
|
||||
generatorLayout.addLayout(self.player_budget, 5, 0)
|
||||
|
||||
self.enemy_budget = BudgetInputs("Enemy starting budget", DEFAULT_BUDGET)
|
||||
self.registerField("enemy_starting_money", self.enemy_budget.starting_money)
|
||||
generatorLayout.addLayout(self.enemy_budget, 9, 0)
|
||||
generatorLayout.addLayout(self.enemy_budget, 6, 0)
|
||||
|
||||
generatorSettingsGroup.setLayout(generatorLayout)
|
||||
|
||||
@ -204,10 +193,8 @@ class GeneratorOptions(QtWidgets.QWizardPage):
|
||||
|
||||
self.no_carrier.setChecked(s.get("no_carrier", False))
|
||||
self.no_lha.setChecked(s.get("no_lha", False))
|
||||
self.supercarrier.setChecked(s.get(SUPER_CARRIER, False))
|
||||
self.no_player_navy.setChecked(s.get("no_player_navy", False))
|
||||
self.no_enemy_navy.setChecked(s.get("no_enemy_navy", False))
|
||||
# self.desired_player_mission_duration.spinner.setValue(s.get(MISSION_LENGTH, 60))
|
||||
|
||||
self.a4_skyhawk.setChecked(s.get("a4_skyhawk", False))
|
||||
self.a6a_intruder.setChecked(s.get("a6a_intruder", False))
|
||||
|
||||
@ -1,84 +1,37 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from PySide2 import QtWidgets, QtGui
|
||||
from PySide2.QtCore import Qt
|
||||
from PySide2.QtWidgets import QLabel
|
||||
|
||||
from game.campaignloader import Campaign
|
||||
from qt_ui.widgets.spinsliders import FloatSpinSlider
|
||||
from qt_ui.windows.newgame.SettingNames import RUNWAY_REPAIR, FRONTLINE, AIRCRAFT
|
||||
from game.settings import Settings
|
||||
from qt_ui.windows.settings.QSettingsWindow import QSettingsWidget
|
||||
|
||||
|
||||
class NewGameSettings(QtWidgets.QWizardPage):
|
||||
def __init__(self, parent=None) -> None:
|
||||
def __init__(self, campaign: Campaign, parent=None) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
self.setTitle("Campaign options")
|
||||
self.setSubTitle(
|
||||
"\nAll other options unrelated to campaign generation."
|
||||
)
|
||||
self.setSubTitle("\nAll other options unrelated to campaign generation.")
|
||||
self.setPixmap(
|
||||
QtWidgets.QWizard.LogoPixmap,
|
||||
QtGui.QPixmap("./resources/ui/wizard/logo1.png"),
|
||||
)
|
||||
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
|
||||
economy_group = QtWidgets.QGroupBox("Economy options")
|
||||
layout.addWidget(economy_group)
|
||||
economy_layout = QtWidgets.QVBoxLayout()
|
||||
economy_group.setLayout(economy_layout)
|
||||
|
||||
economy_layout.addWidget(QLabel("Player income multiplier"))
|
||||
self.player_income = FloatSpinSlider(0, 5, 1, divisor=10)
|
||||
self.registerField("player_income_multiplier", self.player_income.spinner)
|
||||
economy_layout.addLayout(self.player_income)
|
||||
|
||||
economy_layout.addWidget(QLabel("Enemy income multiplier"))
|
||||
self.enemy_income = FloatSpinSlider(0, 5, 1, divisor=10)
|
||||
self.registerField("enemy_income_multiplier", self.enemy_income.spinner)
|
||||
economy_layout.addLayout(self.enemy_income)
|
||||
|
||||
new_squadron_rules = QtWidgets.QCheckBox("Enable new squadron rules")
|
||||
self.registerField("use_new_squadron_rules", new_squadron_rules)
|
||||
economy_layout.addWidget(new_squadron_rules)
|
||||
economy_layout.addWidget(
|
||||
QLabel(
|
||||
"With new squadron rules enabled, squadrons will not be able to exceed a maximum number of aircraft "
|
||||
"(configurable), and the campaign will begin with all squadrons at full strength."
|
||||
)
|
||||
settings = Settings()
|
||||
settings.__setstate__(campaign.settings)
|
||||
settings.player_income_multiplier = (
|
||||
campaign.recommended_player_income_multiplier
|
||||
)
|
||||
settings.enemy_income_multiplier = campaign.recommended_enemy_income_multiplier
|
||||
settings.__dict__.update(campaign.settings)
|
||||
self.settings_widget = QSettingsWidget(settings)
|
||||
self.setLayout(self.settings_widget.layout)
|
||||
|
||||
assist_group = QtWidgets.QGroupBox("Player assists")
|
||||
layout.addWidget(assist_group)
|
||||
assist_layout = QtWidgets.QGridLayout()
|
||||
assist_group.setLayout(assist_layout)
|
||||
|
||||
assist_layout.addWidget(QtWidgets.QLabel("Automate runway repairs"), 0, 0)
|
||||
self.runway_repairs = QtWidgets.QCheckBox()
|
||||
self.registerField(RUNWAY_REPAIR, self.runway_repairs)
|
||||
assist_layout.addWidget(self.runway_repairs, 0, 1, Qt.AlignRight)
|
||||
|
||||
assist_layout.addWidget(QtWidgets.QLabel("Automate front-line purchases"), 1, 0)
|
||||
self.front_line = QtWidgets.QCheckBox()
|
||||
self.registerField(FRONTLINE, self.front_line)
|
||||
assist_layout.addWidget(self.front_line, 1, 1, Qt.AlignRight)
|
||||
|
||||
assist_layout.addWidget(QtWidgets.QLabel("Automate aircraft purchases"), 2, 0)
|
||||
self.aircraft = QtWidgets.QCheckBox()
|
||||
self.registerField(AIRCRAFT, self.aircraft)
|
||||
assist_layout.addWidget(self.aircraft, 2, 1, Qt.AlignRight)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def set_campaign_values(self, campaign: Campaign) -> None:
|
||||
self.player_income.spinner.setValue(
|
||||
int(campaign.recommended_player_income_multiplier * 10)
|
||||
)
|
||||
self.enemy_income.spinner.setValue(
|
||||
int(campaign.recommended_enemy_income_multiplier * 10)
|
||||
)
|
||||
s = campaign.settings
|
||||
self.runway_repairs.setChecked(s.get(RUNWAY_REPAIR, False))
|
||||
self.front_line.setChecked(s.get(FRONTLINE, False))
|
||||
self.aircraft.setChecked(s.get(AIRCRAFT, False))
|
||||
def set_campaign_values(self, c: Campaign):
|
||||
sw = self.settings_widget
|
||||
sw.settings.player_income_multiplier = c.recommended_player_income_multiplier
|
||||
sw.settings.enemy_income_multiplier = c.recommended_enemy_income_multiplier
|
||||
sw.settings.__dict__.update(c.settings)
|
||||
print(sw.settings.__dict__)
|
||||
sw.update_from_settings()
|
||||
|
||||
@ -6,7 +6,14 @@ from typing import List, Optional
|
||||
from PySide2 import QtWidgets, QtGui
|
||||
from PySide2.QtCore import Signal, QDate, QPoint, QItemSelectionModel, Qt, QModelIndex
|
||||
from PySide2.QtGui import QStandardItem, QPixmap, QStandardItemModel
|
||||
from PySide2.QtWidgets import QCheckBox, QTextBrowser, QTextEdit, QLabel, QListView, QAbstractItemView
|
||||
from PySide2.QtWidgets import (
|
||||
QCheckBox,
|
||||
QTextBrowser,
|
||||
QTextEdit,
|
||||
QLabel,
|
||||
QListView,
|
||||
QAbstractItemView,
|
||||
)
|
||||
|
||||
from game.campaignloader import Campaign
|
||||
from qt_ui.liberation_install import get_dcs_install_directory
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import json
|
||||
import logging
|
||||
import textwrap
|
||||
from typing import Callable
|
||||
import zipfile
|
||||
from typing import Callable, Optional, Dict
|
||||
|
||||
from PySide2 import QtWidgets
|
||||
from PySide2.QtCore import QItemSelectionModel, QPoint, QSize, Qt
|
||||
from PySide2.QtGui import QStandardItem, QStandardItemModel
|
||||
from PySide2.QtWidgets import (
|
||||
@ -37,6 +38,7 @@ from game.settings import (
|
||||
OptionDescription,
|
||||
Settings,
|
||||
)
|
||||
from game.settings.ISettingsContainer import SettingsContainer
|
||||
from game.sim import GameUpdateEvents
|
||||
from qt_ui.widgets.QLabeledWidget import QLabeledWidget
|
||||
from qt_ui.widgets.spinsliders import FloatSpinSlider, TimeInputs
|
||||
@ -45,27 +47,29 @@ from qt_ui.windows.settings.plugins import PluginOptionsPage, PluginsPage
|
||||
|
||||
|
||||
class CheatSettingsBox(QGroupBox):
|
||||
def __init__(self, game: Game, apply_settings: Callable[[], None]) -> None:
|
||||
def __init__(
|
||||
self, sc: SettingsContainer, apply_settings: Callable[[], None]
|
||||
) -> None:
|
||||
super().__init__("Cheat Settings")
|
||||
self.main_layout = QVBoxLayout()
|
||||
self.setLayout(self.main_layout)
|
||||
|
||||
self.red_ato_checkbox = QCheckBox()
|
||||
self.red_ato_checkbox.setChecked(game.settings.show_red_ato)
|
||||
self.red_ato_checkbox.setChecked(sc.settings.show_red_ato)
|
||||
self.red_ato_checkbox.toggled.connect(apply_settings)
|
||||
|
||||
self.frontline_cheat_checkbox = QCheckBox()
|
||||
self.frontline_cheat_checkbox.setChecked(game.settings.enable_frontline_cheats)
|
||||
self.frontline_cheat_checkbox.setChecked(sc.settings.enable_frontline_cheats)
|
||||
self.frontline_cheat_checkbox.toggled.connect(apply_settings)
|
||||
|
||||
self.base_capture_cheat_checkbox = QCheckBox()
|
||||
self.base_capture_cheat_checkbox.setChecked(
|
||||
game.settings.enable_base_capture_cheat
|
||||
sc.settings.enable_base_capture_cheat
|
||||
)
|
||||
self.base_capture_cheat_checkbox.toggled.connect(apply_settings)
|
||||
|
||||
self.transfer_cheat_checkbox = QCheckBox()
|
||||
self.transfer_cheat_checkbox.setChecked(game.settings.enable_transfer_cheat)
|
||||
self.transfer_cheat_checkbox.setChecked(sc.settings.enable_transfer_cheat)
|
||||
self.transfer_cheat_checkbox.toggled.connect(apply_settings)
|
||||
|
||||
self.red_ato = QLabeledWidget("Show Red ATO:", self.red_ato_checkbox)
|
||||
@ -105,14 +109,22 @@ class AutoSettingsLayout(QGridLayout):
|
||||
self,
|
||||
page: str,
|
||||
section: str,
|
||||
settings: Settings,
|
||||
sc: SettingsContainer,
|
||||
write_full_settings: Callable[[], None],
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.settings = settings
|
||||
self.page = page
|
||||
self.section = section
|
||||
self.sc = sc
|
||||
self.write_full_settings = write_full_settings
|
||||
self.settings_map: Dict[str, QWidget] = {}
|
||||
|
||||
for row, (name, description) in enumerate(Settings.fields(page, section)):
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
for row, (name, description) in enumerate(
|
||||
Settings.fields(self.page, self.section)
|
||||
):
|
||||
self.add_label(row, description)
|
||||
if isinstance(description, BooleanOption):
|
||||
self.add_checkbox_for(row, name, description)
|
||||
@ -142,31 +154,33 @@ class AutoSettingsLayout(QGridLayout):
|
||||
def on_toggle(value: bool) -> None:
|
||||
if description.invert:
|
||||
value = not value
|
||||
self.settings.__dict__[name] = value
|
||||
self.sc.settings.__dict__[name] = value
|
||||
if description.causes_expensive_game_update:
|
||||
self.write_full_settings()
|
||||
|
||||
checkbox = QCheckBox()
|
||||
value = self.settings.__dict__[name]
|
||||
value = self.sc.settings.__dict__[name]
|
||||
if description.invert:
|
||||
value = not value
|
||||
checkbox.setChecked(value)
|
||||
checkbox.toggled.connect(on_toggle)
|
||||
self.addWidget(checkbox, row, 1, Qt.AlignRight)
|
||||
self.settings_map[name] = checkbox
|
||||
|
||||
def add_combobox_for(self, row: int, name: str, description: ChoicesOption) -> None:
|
||||
combobox = QComboBox()
|
||||
|
||||
def on_changed(index: int) -> None:
|
||||
self.settings.__dict__[name] = combobox.itemData(index)
|
||||
self.sc.settings.__dict__[name] = combobox.itemData(index)
|
||||
|
||||
for text, value in description.choices.items():
|
||||
combobox.addItem(text, value)
|
||||
combobox.setCurrentText(
|
||||
description.text_for_value(self.settings.__dict__[name])
|
||||
description.text_for_value(self.sc.settings.__dict__[name])
|
||||
)
|
||||
combobox.currentIndexChanged.connect(on_changed)
|
||||
self.addWidget(combobox, row, 1, Qt.AlignRight)
|
||||
self.settings_map[name] = combobox
|
||||
|
||||
def add_float_spin_slider_for(
|
||||
self, row: int, name: str, description: BoundedFloatOption
|
||||
@ -174,44 +188,62 @@ class AutoSettingsLayout(QGridLayout):
|
||||
spinner = FloatSpinSlider(
|
||||
description.min,
|
||||
description.max,
|
||||
self.settings.__dict__[name],
|
||||
self.sc.settings.__dict__[name],
|
||||
divisor=description.divisor,
|
||||
)
|
||||
|
||||
def on_changed() -> None:
|
||||
self.settings.__dict__[name] = spinner.value
|
||||
self.sc.settings.__dict__[name] = spinner.value
|
||||
|
||||
spinner.spinner.valueChanged.connect(on_changed)
|
||||
self.addLayout(spinner, row, 1, Qt.AlignRight)
|
||||
self.settings_map[name] = spinner
|
||||
|
||||
def add_spinner_for(
|
||||
self, row: int, name: str, description: BoundedIntOption
|
||||
) -> None:
|
||||
def on_changed(value: int) -> None:
|
||||
self.settings.__dict__[name] = value
|
||||
self.sc.settings.__dict__[name] = value
|
||||
if description.causes_expensive_game_update:
|
||||
self.write_full_settings()
|
||||
|
||||
spinner = QSpinBox()
|
||||
spinner.setMinimum(description.min)
|
||||
spinner.setMaximum(description.max)
|
||||
spinner.setValue(self.settings.__dict__[name])
|
||||
spinner.setValue(self.sc.settings.__dict__[name])
|
||||
|
||||
spinner.valueChanged.connect(on_changed)
|
||||
self.addWidget(spinner, row, 1, Qt.AlignRight)
|
||||
self.settings_map[name] = spinner
|
||||
|
||||
def add_duration_controls_for(
|
||||
self, row: int, name: str, description: MinutesOption
|
||||
) -> None:
|
||||
inputs = TimeInputs(
|
||||
self.settings.__dict__[name], description.min, description.max
|
||||
self.sc.settings.__dict__[name], description.min, description.max
|
||||
)
|
||||
|
||||
def on_changed() -> None:
|
||||
self.settings.__dict__[name] = inputs.value
|
||||
self.sc.settings.__dict__[name] = inputs.value
|
||||
|
||||
inputs.spinner.valueChanged.connect(on_changed)
|
||||
self.addLayout(inputs, row, 1, Qt.AlignRight)
|
||||
self.settings_map[name] = inputs
|
||||
|
||||
def update_from_settings(self) -> None:
|
||||
for name, description in Settings.fields(self.page, self.section):
|
||||
widget = self.settings_map[name]
|
||||
value = self.sc.settings.__dict__[name]
|
||||
if isinstance(widget, QCheckBox):
|
||||
widget.setChecked(value)
|
||||
elif isinstance(widget, QComboBox):
|
||||
widget.setCurrentText(description.text_for_value(value))
|
||||
elif isinstance(widget, FloatSpinSlider):
|
||||
widget.spinner.setValue(int(value * widget.spinner.divisor))
|
||||
elif isinstance(widget, QSpinBox):
|
||||
widget.setValue(value)
|
||||
elif isinstance(widget, TimeInputs):
|
||||
widget.spinner.setValue(value.seconds // 60)
|
||||
|
||||
|
||||
class AutoSettingsGroup(QGroupBox):
|
||||
@ -219,57 +251,80 @@ class AutoSettingsGroup(QGroupBox):
|
||||
self,
|
||||
page: str,
|
||||
section: str,
|
||||
settings: Settings,
|
||||
sc: SettingsContainer,
|
||||
write_full_settings: Callable[[], None],
|
||||
) -> None:
|
||||
super().__init__(section)
|
||||
self.setLayout(AutoSettingsLayout(page, section, settings, write_full_settings))
|
||||
self.layout = AutoSettingsLayout(page, section, sc, write_full_settings)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def update_from_settings(self) -> None:
|
||||
self.layout.update_from_settings()
|
||||
|
||||
|
||||
class AutoSettingsPageLayout(QVBoxLayout):
|
||||
def __init__(
|
||||
self,
|
||||
page: str,
|
||||
settings: Settings,
|
||||
sc: SettingsContainer,
|
||||
write_full_settings: Callable[[], None],
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.setAlignment(Qt.AlignTop)
|
||||
|
||||
self.widgets = []
|
||||
for section in Settings.sections(page):
|
||||
self.addWidget(
|
||||
AutoSettingsGroup(page, section, settings, write_full_settings)
|
||||
self.widgets.append(
|
||||
AutoSettingsGroup(page, section, sc, write_full_settings)
|
||||
)
|
||||
self.addWidget(self.widgets[-1])
|
||||
|
||||
def update_from_settings(self) -> None:
|
||||
for w in self.widgets:
|
||||
w.update_from_settings()
|
||||
|
||||
|
||||
class AutoSettingsPage(QWidget):
|
||||
def __init__(
|
||||
self,
|
||||
page: str,
|
||||
settings: Settings,
|
||||
sc: SettingsContainer,
|
||||
write_full_settings: Callable[[], None],
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.setLayout(AutoSettingsPageLayout(page, settings, write_full_settings))
|
||||
self.layout = AutoSettingsPageLayout(page, sc, write_full_settings)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def update_from_settings(self) -> None:
|
||||
self.layout.update_from_settings()
|
||||
|
||||
|
||||
class QSettingsWindow(QDialog):
|
||||
def __init__(self, game: Game):
|
||||
super().__init__()
|
||||
|
||||
self.game = game
|
||||
self.pluginsPage = None
|
||||
self.pluginsOptionsPage = None
|
||||
|
||||
self.pages: dict[str, AutoSettingsPage] = {}
|
||||
for page in Settings.pages():
|
||||
self.pages[page] = AutoSettingsPage(page, game.settings, self.applySettings)
|
||||
self.setLayout(QSettingsWidget(game.settings, game).layout)
|
||||
|
||||
self.setModal(True)
|
||||
self.setWindowTitle("Settings")
|
||||
self.setWindowIcon(CONST.ICONS["Settings"])
|
||||
self.setMinimumSize(840, 480)
|
||||
|
||||
|
||||
class QSettingsWidget(QtWidgets.QWizardPage, SettingsContainer):
|
||||
def __init__(self, settings: Settings, game: Optional[Game] = None):
|
||||
super().__init__()
|
||||
|
||||
self.settings = game.settings if game else settings
|
||||
self.game = game
|
||||
|
||||
self.pages: dict[str, AutoSettingsPage] = {}
|
||||
for page in Settings.pages():
|
||||
self.pages[page] = AutoSettingsPage(page, self, self.applySettings)
|
||||
|
||||
self.pluginsPage = PluginsPage(self)
|
||||
self.pluginsOptionsPage = PluginOptionsPage(self)
|
||||
|
||||
self.initUi()
|
||||
|
||||
def initUi(self):
|
||||
@ -306,7 +361,6 @@ class QSettingsWindow(QDialog):
|
||||
self.categoryModel.appendRow(cheat)
|
||||
self.right_layout.addWidget(self.cheatPage)
|
||||
|
||||
self.pluginsPage = PluginsPage()
|
||||
plugins = QStandardItem("LUA Plugins")
|
||||
plugins.setIcon(CONST.ICONS["Plugins"])
|
||||
plugins.setEditable(False)
|
||||
@ -314,7 +368,6 @@ class QSettingsWindow(QDialog):
|
||||
self.categoryModel.appendRow(plugins)
|
||||
self.right_layout.addWidget(self.pluginsPage)
|
||||
|
||||
self.pluginsOptionsPage = PluginOptionsPage()
|
||||
pluginsOptions = QStandardItem("LUA Plugins Options")
|
||||
pluginsOptions.setIcon(CONST.ICONS["PluginsOptions"])
|
||||
pluginsOptions.setEditable(False)
|
||||
@ -351,10 +404,11 @@ class QSettingsWindow(QDialog):
|
||||
self.cheatLayout = QVBoxLayout()
|
||||
self.cheatPage.setLayout(self.cheatLayout)
|
||||
|
||||
self.cheat_options = CheatSettingsBox(self.game, self.applySettings)
|
||||
self.cheat_options = CheatSettingsBox(self, self.applySettings)
|
||||
self.cheatLayout.addWidget(self.cheat_options)
|
||||
|
||||
self.moneyCheatBox = QGroupBox("Money Cheat")
|
||||
self.moneyCheatBox.setDisabled(self.game is None)
|
||||
self.moneyCheatBox.setAlignment(Qt.AlignTop)
|
||||
self.moneyCheatBoxLayout = QGridLayout()
|
||||
self.moneyCheatBox.setLayout(self.moneyCheatBoxLayout)
|
||||
@ -380,26 +434,41 @@ class QSettingsWindow(QDialog):
|
||||
GameUpdateSignal.get_instance().updateGame(self.game)
|
||||
|
||||
def applySettings(self):
|
||||
self.game.settings.show_red_ato = self.cheat_options.show_red_ato
|
||||
self.game.settings.enable_frontline_cheats = (
|
||||
self.cheat_options.show_frontline_cheat
|
||||
)
|
||||
self.game.settings.enable_base_capture_cheat = (
|
||||
self.settings.show_red_ato = self.cheat_options.show_red_ato
|
||||
self.settings.enable_frontline_cheats = self.cheat_options.show_frontline_cheat
|
||||
self.settings.enable_base_capture_cheat = (
|
||||
self.cheat_options.show_base_capture_cheat
|
||||
)
|
||||
self.game.settings.enable_transfer_cheat = (
|
||||
self.cheat_options.show_transfer_cheat
|
||||
)
|
||||
self.settings.enable_transfer_cheat = self.cheat_options.show_transfer_cheat
|
||||
|
||||
if self.game:
|
||||
events = GameUpdateEvents()
|
||||
self.game.compute_unculled_zones(events)
|
||||
EventStream.put_nowait(events)
|
||||
GameUpdateSignal.get_instance().updateGame(self.game)
|
||||
|
||||
def onSelectionChanged(self):
|
||||
def onSelectionChanged(self) -> None:
|
||||
index = self.categoryList.selectionModel().currentIndex().row()
|
||||
self.right_layout.setCurrentIndex(index)
|
||||
|
||||
def update_from_settings(self) -> None:
|
||||
for p in self.pages.values():
|
||||
p.update_from_settings()
|
||||
|
||||
self.cheat_options.red_ato_checkbox.setChecked(self.settings.show_red_ato)
|
||||
self.cheat_options.base_capture_cheat_checkbox.setChecked(
|
||||
self.settings.enable_base_capture_cheat
|
||||
)
|
||||
self.cheat_options.frontline_cheat_checkbox.setChecked(
|
||||
self.settings.enable_frontline_cheats
|
||||
)
|
||||
self.cheat_options.transfer_cheat_checkbox.setChecked(
|
||||
self.settings.enable_transfer_cheat
|
||||
)
|
||||
|
||||
self.pluginsPage.update_from_settings()
|
||||
self.pluginsOptionsPage.update_from_settings()
|
||||
|
||||
def load_settings(self):
|
||||
sd = settings_dir()
|
||||
if not sd.exists():
|
||||
@ -411,12 +480,10 @@ class QSettingsWindow(QDialog):
|
||||
filename = zipfilename.split("/")[-1].replace(".zip", ".json")
|
||||
settings = json.loads(
|
||||
zf.read(filename).decode("utf-8"),
|
||||
object_hook=self.game.settings.obj_hook,
|
||||
object_hook=self.settings.obj_hook,
|
||||
)
|
||||
self.game.settings.__setstate__(settings)
|
||||
self.close()
|
||||
new = QSettingsWindow(self.game)
|
||||
new.exec_()
|
||||
self.settings.__setstate__(settings)
|
||||
self.update_from_settings()
|
||||
|
||||
def save_settings(self):
|
||||
sd = settings_dir()
|
||||
@ -431,9 +498,9 @@ class QSettingsWindow(QDialog):
|
||||
zf.writestr(
|
||||
filename,
|
||||
json.dumps(
|
||||
self.game.settings.__dict__,
|
||||
self.settings.__dict__,
|
||||
indent=2,
|
||||
default=self.game.settings.default_json,
|
||||
default=self.settings.default_json,
|
||||
),
|
||||
zipfile.ZIP_DEFLATED,
|
||||
)
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
from typing import Dict, List
|
||||
|
||||
from PySide2.QtCore import Qt, QLocale
|
||||
from PySide2.QtWidgets import (
|
||||
QCheckBox,
|
||||
@ -11,6 +13,8 @@ from PySide2.QtWidgets import (
|
||||
)
|
||||
|
||||
from game.plugins import LuaPlugin, LuaPluginManager
|
||||
from game.settings import Settings
|
||||
from game.settings.ISettingsContainer import SettingsContainer
|
||||
|
||||
|
||||
class PluginsBox(QGroupBox):
|
||||
@ -21,6 +25,8 @@ class PluginsBox(QGroupBox):
|
||||
layout.setAlignment(Qt.AlignTop)
|
||||
self.setLayout(layout)
|
||||
|
||||
self.plugin_map: Dict[str, QCheckBox] = {}
|
||||
|
||||
for row, plugin in enumerate(LuaPluginManager.plugins()):
|
||||
if not plugin.show_in_ui:
|
||||
continue
|
||||
@ -31,17 +37,29 @@ class PluginsBox(QGroupBox):
|
||||
checkbox.setChecked(plugin.get_value)
|
||||
checkbox.toggled.connect(plugin.set_value)
|
||||
layout.addWidget(checkbox, row, 1)
|
||||
self.plugin_map[plugin.identifier] = checkbox
|
||||
|
||||
def update_from_settings(self, settings: Settings):
|
||||
for identifier, enabled in settings.plugins.items():
|
||||
if identifier in self.plugin_map:
|
||||
self.plugin_map[identifier].setChecked(enabled)
|
||||
|
||||
|
||||
class PluginsPage(QWidget):
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, sc: SettingsContainer) -> None:
|
||||
super().__init__()
|
||||
|
||||
self.sc = sc
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.setAlignment(Qt.AlignTop)
|
||||
self.setLayout(layout)
|
||||
|
||||
layout.addWidget(PluginsBox())
|
||||
self.plugins_box = PluginsBox()
|
||||
layout.addWidget(self.plugins_box)
|
||||
|
||||
def update_from_settings(self):
|
||||
self.plugins_box.update_from_settings(self.sc.settings)
|
||||
|
||||
|
||||
class PluginOptionsBox(QGroupBox):
|
||||
@ -52,6 +70,8 @@ class PluginOptionsBox(QGroupBox):
|
||||
layout.setAlignment(Qt.AlignTop)
|
||||
self.setLayout(layout)
|
||||
|
||||
self.widgets: Dict[str, QWidget] = {}
|
||||
|
||||
for row, option in enumerate(plugin.options):
|
||||
layout.addWidget(QLabel(option.name), row, 0)
|
||||
|
||||
@ -61,6 +81,7 @@ class PluginOptionsBox(QGroupBox):
|
||||
checkbox.setChecked(val)
|
||||
checkbox.toggled.connect(option.set_value)
|
||||
layout.addWidget(checkbox, row, 1)
|
||||
self.widgets[option.identifier] = checkbox
|
||||
elif type(val) == float or type(val) == int:
|
||||
if type(val) == float:
|
||||
spinbox = QDoubleSpinBox()
|
||||
@ -73,16 +94,36 @@ class PluginOptionsBox(QGroupBox):
|
||||
spinbox.setValue(val)
|
||||
spinbox.valueChanged.connect(option.set_value)
|
||||
layout.addWidget(spinbox, row, 1)
|
||||
self.widgets[option.identifier] = spinbox
|
||||
|
||||
def update_from_settings(self, settings: Settings) -> None:
|
||||
for identifier in self.widgets:
|
||||
value = settings.plugin_option(identifier)
|
||||
w = self.widgets[identifier]
|
||||
if isinstance(w, QCheckBox):
|
||||
w.setChecked(value)
|
||||
elif isinstance(w, QDoubleSpinBox) or isinstance(w, QSpinBox):
|
||||
w.setValue(value)
|
||||
|
||||
|
||||
class PluginOptionsPage(QWidget):
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, sc: SettingsContainer) -> None:
|
||||
super().__init__()
|
||||
|
||||
self.sc = sc
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.setAlignment(Qt.AlignTop)
|
||||
self.setLayout(layout)
|
||||
|
||||
self.pobs: List[PluginOptionsBox] = []
|
||||
|
||||
for plugin in LuaPluginManager.plugins():
|
||||
if plugin.options:
|
||||
layout.addWidget(PluginOptionsBox(plugin))
|
||||
pob = PluginOptionsBox(plugin)
|
||||
layout.addWidget(pob)
|
||||
self.pobs.append(pob)
|
||||
|
||||
def update_from_settings(self):
|
||||
for pob in self.pobs:
|
||||
pob.update_from_settings(self.sc.settings)
|
||||
|
||||
@ -17,6 +17,7 @@ recommended_enemy_income_multiplier: 1.0
|
||||
advanced_iads: false
|
||||
settings:
|
||||
max_frontline_length: 30
|
||||
player_income_multiplier: 1.5
|
||||
squadrons:
|
||||
CVN-74 John Stennis:
|
||||
- primary: BARCAP
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user