mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Add cheats for destroying and repairing runways.
This commit is contained in:
@@ -7,6 +7,7 @@ Saves from 8.x are not compatible with 9.0.0.
|
|||||||
* **[Flight Planning]** Improved IP selection for targets that are near the center of a threat zone.
|
* **[Flight Planning]** Improved IP selection for targets that are near the center of a threat zone.
|
||||||
* **[Modding]** Factions can now specify the ship type to be used for cargo shipping. The Handy Wind will be used by default, but WW2 factions can pick something more appropriate.
|
* **[Modding]** Factions can now specify the ship type to be used for cargo shipping. The Handy Wind will be used by default, but WW2 factions can pick something more appropriate.
|
||||||
* **[UI]** An error will be displayed when invalid fast-forward options are selected rather than beginning a never ending simulation.
|
* **[UI]** An error will be displayed when invalid fast-forward options are selected rather than beginning a never ending simulation.
|
||||||
|
* **[UI]** Added cheats for instantly repairing and destroying runways.
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
|
|||||||
@@ -562,6 +562,7 @@ class Settings:
|
|||||||
show_red_ato: bool = False
|
show_red_ato: bool = False
|
||||||
enable_frontline_cheats: bool = False
|
enable_frontline_cheats: bool = False
|
||||||
enable_base_capture_cheat: bool = False
|
enable_base_capture_cheat: bool = False
|
||||||
|
enable_runway_state_cheat: bool = False
|
||||||
|
|
||||||
only_player_takeoff: bool = True # Legacy parameter do not use
|
only_player_takeoff: bool = True # Legacy parameter do not use
|
||||||
|
|
||||||
|
|||||||
@@ -249,6 +249,10 @@ class RunwayStatus:
|
|||||||
# is reset.
|
# is reset.
|
||||||
self.repair_turns_remaining = None
|
self.repair_turns_remaining = None
|
||||||
|
|
||||||
|
def repair(self) -> None:
|
||||||
|
self.repair_turns_remaining = None
|
||||||
|
self.damaged = False
|
||||||
|
|
||||||
def begin_repair(self) -> None:
|
def begin_repair(self) -> None:
|
||||||
if self.repair_turns_remaining is not None:
|
if self.repair_turns_remaining is not None:
|
||||||
logging.error("Runway already under repair. Restarting.")
|
logging.error("Runway already under repair. Restarting.")
|
||||||
@@ -257,8 +261,7 @@ class RunwayStatus:
|
|||||||
def process_turn(self) -> None:
|
def process_turn(self) -> None:
|
||||||
if self.repair_turns_remaining is not None:
|
if self.repair_turns_remaining is not None:
|
||||||
if self.repair_turns_remaining == 1:
|
if self.repair_turns_remaining == 1:
|
||||||
self.repair_turns_remaining = None
|
self.repair()
|
||||||
self.damaged = False
|
|
||||||
else:
|
else:
|
||||||
self.repair_turns_remaining -= 1
|
self.repair_turns_remaining -= 1
|
||||||
|
|
||||||
@@ -891,6 +894,11 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
|
|||||||
def parking_slots(self) -> Iterator[ParkingSlot]:
|
def parking_slots(self) -> Iterator[ParkingSlot]:
|
||||||
yield from []
|
yield from []
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def runway_is_destroyable(self) -> bool:
|
||||||
|
...
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def runway_status(self) -> RunwayStatus:
|
def runway_status(self) -> RunwayStatus:
|
||||||
@@ -1127,6 +1135,10 @@ class Airfield(ControlPoint):
|
|||||||
def heading(self) -> Heading:
|
def heading(self) -> Heading:
|
||||||
return Heading.from_degrees(self.airport.runways[0].heading)
|
return Heading.from_degrees(self.airport.runways[0].heading)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def runway_is_destroyable(self) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
def runway_is_operational(self) -> bool:
|
def runway_is_operational(self) -> bool:
|
||||||
return not self.runway_status.damaged
|
return not self.runway_status.damaged
|
||||||
|
|
||||||
@@ -1215,6 +1227,10 @@ class NavalControlPoint(ControlPoint, ABC):
|
|||||||
return g
|
return g
|
||||||
raise RuntimeError(f"Found no carrier/LHA group for {self.name}")
|
raise RuntimeError(f"Found no carrier/LHA group for {self.name}")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def runway_is_destroyable(self) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
def runway_is_operational(self) -> bool:
|
def runway_is_operational(self) -> bool:
|
||||||
# Necessary because it's possible for the carrier itself to have sunk
|
# Necessary because it's possible for the carrier itself to have sunk
|
||||||
# while its escorts are still alive.
|
# while its escorts are still alive.
|
||||||
@@ -1392,6 +1408,10 @@ class OffMapSpawn(ControlPoint):
|
|||||||
logging.warning("TODO: Off map spawns have no runways.")
|
logging.warning("TODO: Off map spawns have no runways.")
|
||||||
return self.stub_runway_data()
|
return self.stub_runway_data()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def runway_is_destroyable(self) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def runway_status(self) -> RunwayStatus:
|
def runway_status(self) -> RunwayStatus:
|
||||||
return RunwayStatus()
|
return RunwayStatus()
|
||||||
@@ -1422,6 +1442,10 @@ class Fob(ControlPoint):
|
|||||||
def symbol_set_and_entity(self) -> tuple[SymbolSet, Entity]:
|
def symbol_set_and_entity(self) -> tuple[SymbolSet, Entity]:
|
||||||
return SymbolSet.LAND_INSTALLATIONS, LandInstallationEntity.MILITARY_BASE
|
return SymbolSet.LAND_INSTALLATIONS, LandInstallationEntity.MILITARY_BASE
|
||||||
|
|
||||||
|
@property
|
||||||
|
def runway_is_destroyable(self) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
def runway_is_operational(self) -> bool:
|
def runway_is_operational(self) -> bool:
|
||||||
return self.has_helipads
|
return self.has_helipads
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from PySide6.QtWidgets import (
|
|||||||
from game import Game
|
from game import Game
|
||||||
from game.ato.flighttype import FlightType
|
from game.ato.flighttype import FlightType
|
||||||
from game.config import RUNWAY_REPAIR_COST
|
from game.config import RUNWAY_REPAIR_COST
|
||||||
|
from game.server import EventStream
|
||||||
from game.theater import (
|
from game.theater import (
|
||||||
AMMO_DEPOT_FRONTLINE_UNIT_CONTRIBUTION,
|
AMMO_DEPOT_FRONTLINE_UNIT_CONTRIBUTION,
|
||||||
ControlPoint,
|
ControlPoint,
|
||||||
@@ -69,10 +70,23 @@ class QBaseMenu2(QDialog):
|
|||||||
top_layout.addWidget(self.intel_summary)
|
top_layout.addWidget(self.intel_summary)
|
||||||
top_layout.setAlignment(Qt.AlignTop)
|
top_layout.setAlignment(Qt.AlignTop)
|
||||||
|
|
||||||
|
runway_buttons_layout = QVBoxLayout()
|
||||||
|
top_layout.addLayout(runway_buttons_layout)
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.cp.runway_is_destroyable
|
||||||
|
and self.game_model.game.settings.enable_runway_state_cheat
|
||||||
|
):
|
||||||
|
self.cheat_runway_state = QPushButton()
|
||||||
|
self.update_cheat_runway_state_text()
|
||||||
|
self.cheat_runway_state.clicked.connect(self.on_cheat_runway_state)
|
||||||
|
runway_buttons_layout.addWidget(self.cheat_runway_state)
|
||||||
|
|
||||||
self.repair_button = QPushButton()
|
self.repair_button = QPushButton()
|
||||||
self.repair_button.clicked.connect(self.begin_runway_repair)
|
self.repair_button.clicked.connect(self.begin_runway_repair)
|
||||||
self.update_repair_button()
|
self.update_repair_button()
|
||||||
top_layout.addWidget(self.repair_button)
|
runway_buttons_layout.addWidget(self.repair_button)
|
||||||
|
runway_buttons_layout.addStretch()
|
||||||
|
|
||||||
base_menu_header.setProperty("style", "baseMenuHeader")
|
base_menu_header.setProperty("style", "baseMenuHeader")
|
||||||
base_menu_header.setLayout(top_layout)
|
base_menu_header.setLayout(top_layout)
|
||||||
@@ -129,6 +143,23 @@ class QBaseMenu2(QDialog):
|
|||||||
self.cp.captured
|
self.cp.captured
|
||||||
).has_destinations(self.cp)
|
).has_destinations(self.cp)
|
||||||
|
|
||||||
|
def update_cheat_runway_state_text(self) -> None:
|
||||||
|
if self.cp.runway_can_be_repaired:
|
||||||
|
self.cheat_runway_state.setText("CHEAT: Repair runway")
|
||||||
|
else:
|
||||||
|
self.cheat_runway_state.setText("CHEAT: Destroy runway")
|
||||||
|
|
||||||
|
def on_cheat_runway_state(self) -> None:
|
||||||
|
if self.cp.runway_can_be_repaired:
|
||||||
|
self.cp.runway_status.repair()
|
||||||
|
else:
|
||||||
|
self.cp.runway_status.damage()
|
||||||
|
self.update_cheat_runway_state_text()
|
||||||
|
self.update_repair_button()
|
||||||
|
self.update_intel_summary()
|
||||||
|
with EventStream.event_context() as events:
|
||||||
|
events.update_control_point(self.cp)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def can_repair_runway(self) -> bool:
|
def can_repair_runway(self) -> bool:
|
||||||
return self.cp.captured and self.cp.runway_can_be_repaired
|
return self.cp.captured and self.cp.runway_can_be_repaired
|
||||||
|
|||||||
@@ -69,6 +69,18 @@ class CheatSettingsBox(QGroupBox):
|
|||||||
self.base_capture_cheat = QLabeledWidget(
|
self.base_capture_cheat = QLabeledWidget(
|
||||||
"Enable Base Capture Cheat:", self.base_capture_cheat_checkbox
|
"Enable Base Capture Cheat:", self.base_capture_cheat_checkbox
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.base_runway_state_cheat_checkbox = QCheckBox()
|
||||||
|
self.base_runway_state_cheat_checkbox.setChecked(
|
||||||
|
game.settings.enable_runway_state_cheat
|
||||||
|
)
|
||||||
|
self.base_runway_state_cheat_checkbox.toggled.connect(apply_settings)
|
||||||
|
self.main_layout.addLayout(
|
||||||
|
QLabeledWidget(
|
||||||
|
"Enable runway state cheat:", self.base_runway_state_cheat_checkbox
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.main_layout.addLayout(self.base_capture_cheat)
|
self.main_layout.addLayout(self.base_capture_cheat)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -83,6 +95,10 @@ class CheatSettingsBox(QGroupBox):
|
|||||||
def show_base_capture_cheat(self) -> bool:
|
def show_base_capture_cheat(self) -> bool:
|
||||||
return self.base_capture_cheat_checkbox.isChecked()
|
return self.base_capture_cheat_checkbox.isChecked()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def enable_runway_state_cheat(self) -> bool:
|
||||||
|
return self.base_runway_state_cheat_checkbox.isChecked()
|
||||||
|
|
||||||
|
|
||||||
class AutoSettingsLayout(QGridLayout):
|
class AutoSettingsLayout(QGridLayout):
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -370,6 +386,9 @@ class QSettingsWindow(QDialog):
|
|||||||
self.game.settings.enable_base_capture_cheat = (
|
self.game.settings.enable_base_capture_cheat = (
|
||||||
self.cheat_options.show_base_capture_cheat
|
self.cheat_options.show_base_capture_cheat
|
||||||
)
|
)
|
||||||
|
self.game.settings.enable_runway_state_cheat = (
|
||||||
|
self.cheat_options.enable_runway_state_cheat
|
||||||
|
)
|
||||||
|
|
||||||
events = GameUpdateEvents()
|
events = GameUpdateEvents()
|
||||||
self.game.compute_unculled_zones(events)
|
self.game.compute_unculled_zones(events)
|
||||||
|
|||||||
Reference in New Issue
Block a user