mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Default start type for player flights (#303)
* Implemented a new option in settings: Default start type for Player flights. * Updated changelog. * Removed unnecessary country parameter. * Restore missing parameter * on_pilot_changed should emit pilots_changed in its finally block, otherwise the start-type isn't updated if you have a single client pilot which you switch to a non-client pilot. Also implemented other changes suggested by @Raffson, such as a more streamlined start_type QComboBox handling and moving the pilots_changed Signal to FlightRosterEditor. * Decouple Signal from QFlighStartType --------- Co-authored-by: Raffson <Raffson@users.noreply.github.com>
This commit is contained in:
parent
4c455426e9
commit
a27663e4b6
@ -11,6 +11,7 @@
|
||||
* **[Campaign Design]** Ability to configure specific carrier names & types in campaign's yaml file
|
||||
* **[Mission Generation]** Ability to inject custom kneeboards
|
||||
* **[Options]** Extend option (so it can be disabled when fixed in DCS) to force air-starts (except for the slots that work) at Ramon Airbase, similar to the Nevatim fix in Retribution 1.3.0
|
||||
* **[Options]** New option in Settings: Default start type for Player flights.
|
||||
|
||||
## Fixes
|
||||
* **[UI/UX]** A-10A flights can be edited again.
|
||||
|
||||
@ -22,6 +22,10 @@ class FlightRoster(IFlightRoster):
|
||||
def iter_pilots(self) -> Iterator[Pilot | None]:
|
||||
yield from self.pilots
|
||||
|
||||
@property
|
||||
def player_count(self) -> int:
|
||||
return len([p for p in self.pilots if p is not None and p.player])
|
||||
|
||||
def pilot_at(self, idx: int) -> Pilot | None:
|
||||
return self.pilots[idx]
|
||||
|
||||
|
||||
@ -26,6 +26,11 @@ class IFlightRoster(ABC):
|
||||
def max_size(self) -> int:
|
||||
...
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def player_count(self) -> int:
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def resize(self, new_size: int) -> None:
|
||||
...
|
||||
|
||||
@ -76,6 +76,12 @@ class PackageBuilder:
|
||||
member.assign_tgp_laser_code(
|
||||
self.laser_code_registry.alloc_laser_code()
|
||||
)
|
||||
# If this is a client flight, set the start_type again to match the configured default
|
||||
# https://github.com/dcs-liberation/dcs_liberation/issues/1567
|
||||
if flight.roster is not None and flight.roster.player_count > 0:
|
||||
flight.start_type = (
|
||||
squadron.coalition.game.settings.default_start_type_client
|
||||
)
|
||||
self.package.add_flight(flight)
|
||||
return True
|
||||
|
||||
|
||||
@ -739,6 +739,14 @@ class Settings:
|
||||
"will not be included in automatically planned OCA packages."
|
||||
),
|
||||
)
|
||||
default_start_type_client: StartType = choices_option(
|
||||
"Default start type for Player flights",
|
||||
page=MISSION_GENERATOR_PAGE,
|
||||
section=GAMEPLAY_SECTION,
|
||||
choices={v.value: v for v in StartType},
|
||||
default=StartType.COLD,
|
||||
detail=("Default start type for flights containing Player/Client slots."),
|
||||
)
|
||||
nevatim_parking_fix: bool = boolean_option(
|
||||
"Force air-starts for aircraft at Nevatim and Ramon Airbase inoperable parking slots",
|
||||
page=MISSION_GENERATOR_PAGE,
|
||||
|
||||
@ -89,8 +89,7 @@ class QFlightCreator(QDialog):
|
||||
roster = None
|
||||
else:
|
||||
roster = FlightRoster(
|
||||
squadron,
|
||||
initial_size=self.flight_size_spinner.value(),
|
||||
squadron, initial_size=self.flight_size_spinner.value()
|
||||
)
|
||||
self.roster_editor = FlightRosterEditor(squadron, roster)
|
||||
self.flight_size_spinner.valueChanged.connect(self.roster_editor.resize)
|
||||
@ -100,10 +99,12 @@ class QFlightCreator(QDialog):
|
||||
roster_layout.addWidget(QLabel("Assigned pilots:"))
|
||||
roster_layout.addLayout(self.roster_editor)
|
||||
|
||||
self.roster_editor.pilots_changed.connect(self.on_pilot_selected)
|
||||
|
||||
# When an off-map spawn overrides the start type to in-flight, we save
|
||||
# the selected type into this value. If a non-off-map spawn is selected
|
||||
# we restore the previous choice.
|
||||
self.restore_start_type = self.game.settings.default_start_type
|
||||
self.restore_start_type: Optional[str] = None
|
||||
self.start_type = QComboBox()
|
||||
for start_type in StartType:
|
||||
self.start_type.addItem(start_type.value, start_type)
|
||||
@ -140,6 +141,8 @@ class QFlightCreator(QDialog):
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
self.roster_editor.pilots_changed.emit()
|
||||
|
||||
def reject(self) -> None:
|
||||
super().reject()
|
||||
# Clear the roster to return pilots to the pool.
|
||||
@ -213,6 +216,8 @@ class QFlightCreator(QDialog):
|
||||
)
|
||||
self.divert.change_aircraft(new_aircraft)
|
||||
|
||||
self.roster_editor.pilots_changed.emit()
|
||||
|
||||
def on_departure_changed(self, departure: ControlPoint) -> None:
|
||||
if isinstance(departure, OffMapSpawn):
|
||||
previous_type = self.start_type.currentData()
|
||||
@ -245,6 +250,8 @@ class QFlightCreator(QDialog):
|
||||
)
|
||||
self.on_departure_changed(squadron.location)
|
||||
|
||||
self.roster_editor.pilots_changed.emit()
|
||||
|
||||
def update_max_size(self, available: int) -> None:
|
||||
aircraft = self.aircraft_selector.currentData()
|
||||
if aircraft is None:
|
||||
@ -255,3 +262,23 @@ class QFlightCreator(QDialog):
|
||||
|
||||
default_size = max(2, available, aircraft.max_group_size)
|
||||
self.flight_size_spinner.setValue(default_size)
|
||||
|
||||
try:
|
||||
self.roster_editor.pilots_changed.emit()
|
||||
except AttributeError:
|
||||
return
|
||||
|
||||
def on_pilot_selected(self):
|
||||
# Pilot selection detected. If this is a player flight, set start_type
|
||||
# as configured for players in the settings.
|
||||
# Otherwise, set the start_type as configured for AI.
|
||||
# https://github.com/dcs-liberation/dcs_liberation/issues/1567
|
||||
|
||||
roster = self.roster_editor.roster
|
||||
|
||||
if roster is not None and roster.player_count > 0:
|
||||
start_type = self.game.settings.default_start_type_client
|
||||
else:
|
||||
start_type = self.game.settings.default_start_type
|
||||
|
||||
self.start_type.setCurrentText(start_type.value)
|
||||
|
||||
@ -96,11 +96,16 @@ class PilotControls(QHBoxLayout):
|
||||
player_toggled = Signal()
|
||||
|
||||
def __init__(
|
||||
self, squadron: Optional[Squadron], roster: Optional[FlightRoster], idx: int
|
||||
self,
|
||||
squadron: Optional[Squadron],
|
||||
roster: Optional[FlightRoster],
|
||||
idx: int,
|
||||
pilots_changed: Signal,
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.roster = roster
|
||||
self.pilot_index = idx
|
||||
self.pilots_changed = pilots_changed
|
||||
|
||||
self.selector = PilotSelector(squadron, roster, idx)
|
||||
self.selector.currentIndexChanged.connect(self.on_pilot_changed)
|
||||
@ -131,6 +136,8 @@ class PilotControls(QHBoxLayout):
|
||||
pilot.player = checked
|
||||
self.player_toggled.emit()
|
||||
|
||||
self.pilots_changed.emit()
|
||||
|
||||
def on_pilot_changed(self, index: int) -> None:
|
||||
pilot = self.selector.itemData(index)
|
||||
self.player_checkbox.blockSignals(True)
|
||||
@ -143,6 +150,10 @@ class PilotControls(QHBoxLayout):
|
||||
if self.roster is not None:
|
||||
self.player_checkbox.setEnabled(self.roster.squadron.aircraft.flyable)
|
||||
self.player_checkbox.blockSignals(False)
|
||||
# on_pilot_changed should emit pilots_changed in its finally block,
|
||||
# otherwise the start-type isn't updated if you have a single client
|
||||
# pilot which you switch to a non-client pilot
|
||||
self.pilots_changed.emit()
|
||||
|
||||
def update_available_pilots(self) -> None:
|
||||
self.selector.rebuild()
|
||||
@ -174,9 +185,12 @@ class PilotControls(QHBoxLayout):
|
||||
|
||||
class FlightRosterEditor(QVBoxLayout):
|
||||
MAX_PILOTS = 4
|
||||
pilots_changed = Signal()
|
||||
|
||||
def __init__(
|
||||
self, squadron: Optional[Squadron], roster: Optional[IFlightRoster]
|
||||
self,
|
||||
squadron: Optional[Squadron],
|
||||
roster: Optional[IFlightRoster],
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.roster = roster
|
||||
@ -190,7 +204,7 @@ class FlightRosterEditor(QVBoxLayout):
|
||||
|
||||
return callback
|
||||
|
||||
controls = PilotControls(squadron, roster, pilot_idx)
|
||||
controls = PilotControls(squadron, roster, pilot_idx, self.pilots_changed)
|
||||
controls.selector.available_pilots_changed.connect(
|
||||
make_reset_callback(pilot_idx)
|
||||
)
|
||||
@ -226,7 +240,12 @@ class FlightRosterEditor(QVBoxLayout):
|
||||
class QFlightSlotEditor(QGroupBox):
|
||||
flight_resized = Signal(int)
|
||||
|
||||
def __init__(self, package_model: PackageModel, flight: Flight, game: Game):
|
||||
def __init__(
|
||||
self,
|
||||
package_model: PackageModel,
|
||||
flight: Flight,
|
||||
game: Game,
|
||||
):
|
||||
super().__init__("Slots")
|
||||
self.package_model = package_model
|
||||
self.flight = flight
|
||||
|
||||
@ -43,6 +43,25 @@ class QFlightStartType(QGroupBox):
|
||||
)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def on_pilot_selected(self):
|
||||
# Pilot selection detected. If this is a player flight, set start_type
|
||||
# as configured for players in the settings.
|
||||
# Otherwise, set the start_type as configured for AI.
|
||||
# https://github.com/dcs-liberation/dcs_liberation/issues/1567
|
||||
|
||||
if self.flight.roster.player_count > 0:
|
||||
self.flight.start_type = (
|
||||
self.flight.coalition.game.settings.default_start_type_client
|
||||
)
|
||||
else:
|
||||
self.flight.start_type = (
|
||||
self.flight.coalition.game.settings.default_start_type
|
||||
)
|
||||
|
||||
self.start_type.setCurrentText(self.flight.start_type.value)
|
||||
|
||||
self.package_model.update_tot()
|
||||
|
||||
def _on_start_type_selected(self):
|
||||
selected = self.start_type.currentData()
|
||||
self.flight.start_type = selected
|
||||
|
||||
@ -38,6 +38,17 @@ class QGeneralFlightSettingsTab(QFrame):
|
||||
self.flight_slot_editor.flight_resized.connect(self.flight_size_changed)
|
||||
for pc in self.flight_slot_editor.roster_editor.pilot_controls:
|
||||
pc.player_toggled.connect(self.on_player_toggle)
|
||||
pc.player_toggled.connect(
|
||||
self.flight_slot_editor.roster_editor.pilots_changed
|
||||
)
|
||||
|
||||
start_type = QFlightStartType(
|
||||
package_model,
|
||||
flight,
|
||||
)
|
||||
|
||||
roster = self.flight_slot_editor.roster_editor
|
||||
roster.pilots_changed.connect(start_type.on_pilot_selected)
|
||||
|
||||
widgets = [
|
||||
QFlightTypeTaskInfo(flight),
|
||||
@ -46,7 +57,7 @@ class QGeneralFlightSettingsTab(QFrame):
|
||||
game.game, package_model, flight, flight_wpt_list
|
||||
),
|
||||
self.flight_slot_editor,
|
||||
QFlightStartType(package_model, flight),
|
||||
start_type,
|
||||
QFlightCustomName(flight),
|
||||
]
|
||||
layout = QGridLayout()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user