Compare commits

...

8 Commits

Author SHA1 Message Date
Dan Albert
61879aeafa Fix line endings.
These get broken whenever someone uses the GitHub file upload editor,
since that doesn't understand .gitattributes.

(cherry picked from commit 6f4ac1dc39)
2023-05-23 00:50:38 -07:00
Starfire13
f5b9052257 Update Golan Heights and Caen to Evreux campaigns.
I had asked Khopa for permission to edit two of his campaigns to fix
some issues. Only the YAMLs have been edited, .miz files did not need
changes. I have tested both YAMLs to make sure campaigns will generate.
Also tested generating turn 1 .miz and ran it in DCS.

Golan Heights:
1. Removed the 2 problematic squadrons from Marj Ruhayyil that were
causing aircraft losses due to larger aircraft sizes not fitting at that
airfield (which is intended for helicopters).
2. Implemented squadron limits.

Caen to Evreux:
1. Re-arranged squadrons for better force distribution and revised
primary and secondary mission types for better default play experience.
2. Implemented squadron limits.

(cherry picked from commit f831c8efdd)
2023-05-23 00:50:38 -07:00
Starfire13
b27d2be0d1 Update Apache loadouts.
BAI loadout updated to use the new radar guided hellfires. Aux tanks
removed in favour of extra cannon ammo.

(cherry picked from commit e3c6b03603)
2023-05-20 02:34:02 -07:00
Dan Albert
e1a1eca5da Fix syntax error in bluefor_modern.yaml.
(cherry picked from commit 7a2e8279cd)
2023-05-19 18:00:32 -07:00
Dan Albert
c695db0f98 Checkpoint game before sim, auto-revert on abort.
An alternative to
https://github.com/dcs-liberation/dcs_liberation/pull/2891 that I ended
up liking much better (I had assumed some part of the UI would fail or
at least look terrible with this approach, but it seems to work quite
well).

On by default now since it's far less frightening than the previous
thing.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2735.

(cherry picked from commit 24e72475b4)
2023-05-19 17:53:34 -07:00
Starfire13
ff20f16109 Update scenic_inland.yaml
A formatting fix for scenic route 2 that was preventing new campaign start. Fixing at Fuzzle's request as he doesn't have the time for it right now.

(cherry picked from commit f10350dac4)
2023-05-19 17:43:59 -07:00
Dan Albert
8af3dc6965 Fuzzle campaign updates.
https://github.com/dcs-liberation/dcs_liberation/issues/2889
(cherry picked from commit f068976749)
2023-05-19 01:28:08 -07:00
Dan Albert
e6cf253e45 Attempt to reset the simulation on abort.
This is optional because I really don't know if I trust it. I don't see
much wrong with it (aside from the warning about not using it with auto-
resolve, because it won't restore lost aircraft), but it's really not
something I'd built for since it's not going to be possible as the RTS
features grow.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2735.

(cherry picked from commit 4b4c45e90f)
2023-05-19 01:19:49 -07:00
21 changed files with 224 additions and 105 deletions

View File

@@ -16,6 +16,7 @@ Saves from 6.x are not compatible with 7.0.
* **[Mission Generation]** Wind speeds no longer follow a uniform distribution. Median wind speeds are now much lower and the standard deviation has been reduced considerably at altitude but increased somewhat at MSL.
* **[Mission Generation]** Improved task generation for SEAD flights carrying TALDs.
* **[Mission Generation]** Added task timeout for SEAD flights with TALDs to prevent AI from overflying the target.
* **[Mission Generation]** Game state will automatically be checkpointed before fast-forwarding the mission, and restored on mission abort. This means that it's now possible to abort a mission and make changes without needing to manually re-load your game.
* **[Modding]** Updated Community A-4E-C mod version support to 2.1.0 release.
* **[Modding]** Add support for VSN F-4B and F-4C mod.
* **[Modding]** Added support for AI C-47 mod.

View File

@@ -25,6 +25,7 @@ class SaveGameBundle:
MANUAL_SAVE_NAME = "player.liberation"
LAST_TURN_SAVE_NAME = "last_turn.liberation"
START_OF_TURN_SAVE_NAME = "start_of_turn.liberation"
PRE_SIM_CHECKPOINT_SAVE_NAME = "pre_sim_checkpoint.liberation"
def __init__(self, bundle_path: Path) -> None:
self.bundle_path = bundle_path
@@ -58,6 +59,19 @@ class SaveGameBundle:
game, self.START_OF_TURN_SAVE_NAME, copy_from=self
)
def save_pre_sim_checkpoint(self, game: Game) -> None:
"""Writes the save file for the state before beginning simulation.
This save is the state of the game after the player presses "TAKE OFF", but
before the fast-forward simulation begins. It is not practical to rewind, but
players commonly will want to cancel and continue planning after pressing that
button, so we make a checkpoint that we can reload on abort.
"""
with logged_duration("Saving pre-sim checkpoint"):
self._update_bundle_member(
game, self.PRE_SIM_CHECKPOINT_SAVE_NAME, copy_from=self
)
def load_player(self) -> Game:
"""Loads the save manually created by the player via save/save-as."""
return self._load_from(self.MANUAL_SAVE_NAME)
@@ -70,6 +84,10 @@ class SaveGameBundle:
"""Loads the save automatically created at the end of the last turn."""
return self._load_from(self.LAST_TURN_SAVE_NAME)
def load_pre_sim_checkpoint(self) -> Game:
"""Loads the save automatically created before the simulation began."""
return self._load_from(self.PRE_SIM_CHECKPOINT_SAVE_NAME)
def _load_from(self, name: str) -> Game:
with ZipFile(self.bundle_path) as zip_bundle:
with zip_bundle.open(name, "r") as save:

View File

@@ -51,6 +51,10 @@ class SaveManager:
with self._save_bundle_context() as bundle:
bundle.save_start_of_turn(self.game)
def save_pre_sim_checkpoint(self) -> None:
with self._save_bundle_context() as bundle:
bundle.save_pre_sim_checkpoint(self.game)
def set_loaded_from(self, bundle: SaveGameBundle) -> None:
"""Reconfigures this save manager based on the loaded game.
@@ -81,6 +85,9 @@ class SaveManager:
self.last_saved_bundle = previous_saved_bundle
raise
def load_pre_sim_checkpoint(self) -> Game:
return self.default_save_bundle.load_pre_sim_checkpoint()
@staticmethod
def load_last_turn(bundle_path: Path) -> Game:
return SaveGameBundle(bundle_path).load_last_turn()

View File

@@ -324,6 +324,17 @@ class Settings:
"modifications."
),
)
reload_pre_sim_checkpoint_on_abort: bool = boolean_option(
"Reset mission to pre-take off conditions on abort",
page=MISSION_GENERATOR_PAGE,
section=GAMEPLAY_SECTION,
default=True,
detail=(
"If enabled, the game will automatically reload a pre-take off save when "
"aborting take off. If this is disabled, you will need to manually re-load "
"your game after aborting take off."
),
)
player_mission_interrupts_sim_at: Optional[StartType] = choices_option(
"Player missions interrupt fast forward",
page=MISSION_GENERATOR_PAGE,

View File

@@ -11,12 +11,12 @@ from game.ato.flightstate import (
Uninitialized,
)
from .combat import CombatInitiator, FrozenCombat
from .gameupdateevents import GameUpdateEvents
from .simulationresults import SimulationResults
if TYPE_CHECKING:
from game import Game
from game.ato import Flight
from .gameupdateevents import GameUpdateEvents
class AircraftSimulation:
@@ -72,6 +72,7 @@ class AircraftSimulation:
def reset(self) -> None:
for flight in self.iter_flights():
flight.set_state(Uninitialized(flight, self.game.settings))
self.combats = []
def iter_flights(self) -> Iterator[Flight]:
packages = itertools.chain(

View File

@@ -39,6 +39,7 @@ class GameLoop:
def start(self) -> None:
if self.started:
raise RuntimeError("Cannot start game loop because it has already started")
self.game.save_manager.save_pre_sim_checkpoint()
self.started = True
self.sim.begin_simulation()

View File

@@ -1,5 +1,5 @@
from datetime import datetime
from typing import List, Optional
from typing import List, Optional, Callable
from PySide6.QtWidgets import (
QDialog,
@@ -33,11 +33,16 @@ from qt_ui.windows.QWaitingForMissionResultWindow import QWaitingForMissionResul
class QTopPanel(QFrame):
def __init__(
self, game_model: GameModel, sim_controller: SimController, ui_flags: UiFlags
self,
game_model: GameModel,
sim_controller: SimController,
ui_flags: UiFlags,
reset_to_pre_sim_checkpoint: Callable[[], None],
) -> None:
super(QTopPanel, self).__init__()
self.game_model = game_model
self.sim_controller = sim_controller
self.reset_to_pre_sim_checkpoint = reset_to_pre_sim_checkpoint
self.dialog: Optional[QDialog] = None
self.setMaximumHeight(70)
@@ -293,7 +298,9 @@ class QTopPanel(QFrame):
persistence.mission_path_for("liberation_nextturn.miz")
)
waiting = QWaitingForMissionResultWindow(self.game, self.sim_controller, self)
waiting = QWaitingForMissionResultWindow(
self.game, self.sim_controller, self.reset_to_pre_sim_checkpoint, self
)
waiting.exec_()
def budget_update(self, game: Game):

View File

@@ -133,7 +133,14 @@ class QLiberationWindow(QMainWindow):
vbox = QVBoxLayout()
vbox.setContentsMargins(0, 0, 0, 0)
vbox.addWidget(QTopPanel(self.game_model, self.sim_controller, ui_flags))
vbox.addWidget(
QTopPanel(
self.game_model,
self.sim_controller,
ui_flags,
self.reset_to_pre_sim_checkpoint,
)
)
vbox.addWidget(hbox)
central_widget = QWidget()
@@ -340,6 +347,23 @@ class QLiberationWindow(QMainWindow):
except Exception:
logging.exception("Error loading save game %s", file[0])
def reset_to_pre_sim_checkpoint(self) -> None:
"""Loads the game that was saved before pressing the take-off button.
A checkpoint will be saved when the player presses take-off to save their state
before the mission simulation begins. If the mission is aborted, we usually want
to reset to the pre-simulation state to allow players to effectively "rewind",
since they probably aborted so that they could make changes. Implementing rewind
for real is impractical, but checkpoints are easy.
"""
if self.game is None:
raise RuntimeError(
"Cannot reset to pre-sim checkpoint when no game is loaded"
)
GameUpdateSignal.get_instance().game_loaded.emit(
self.game.save_manager.load_pre_sim_checkpoint()
)
def saveGame(self):
logging.info("Saving game")

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
import logging
from pathlib import Path
from typing import Optional
from typing import Optional, Callable
from PySide6 import QtCore
from PySide6.QtCore import QObject, Signal
@@ -52,12 +52,14 @@ class QWaitingForMissionResultWindow(QDialog):
self,
game: Game,
sim_controller: SimController,
reset_to_pre_sim_checkpoint: Callable[[], None],
parent: Optional[QWidget] = None,
) -> None:
super(QWaitingForMissionResultWindow, self).__init__(parent=parent)
self.setWindowModality(QtCore.Qt.WindowModal)
self.game = game
self.sim_controller = sim_controller
self.reset_to_pre_sim_checkpoint = reset_to_pre_sim_checkpoint
self.setWindowTitle("Waiting for mission completion.")
self.setWindowIcon(QIcon("./resources/icon.png"))
self.setMinimumHeight(570)
@@ -111,7 +113,7 @@ class QWaitingForMissionResultWindow(QDialog):
self.manually_submit.clicked.connect(self.submit_manually)
self.actions_layout.addWidget(self.manually_submit)
self.cancel = QPushButton("Abort mission")
self.cancel.clicked.connect(self.close)
self.cancel.clicked.connect(self.reject)
self.actions_layout.addWidget(self.cancel)
self.gridLayout.addWidget(self.actions, 2, 0)
@@ -122,7 +124,7 @@ class QWaitingForMissionResultWindow(QDialog):
self.manually_submit2.clicked.connect(self.submit_manually)
self.actions2_layout.addWidget(self.manually_submit2)
self.cancel2 = QPushButton("Abort mission")
self.cancel2.clicked.connect(self.close)
self.cancel2.clicked.connect(self.reject)
self.actions2_layout.addWidget(self.cancel2)
self.proceed = QPushButton("Accept results")
self.proceed.setProperty("style", "btn-success")
@@ -133,6 +135,11 @@ class QWaitingForMissionResultWindow(QDialog):
self.layout.addLayout(self.gridLayout, 1, 0)
self.setLayout(self.layout)
def reject(self) -> None:
if self.game.settings.reload_pre_sim_checkpoint_on_abort:
self.reset_to_pre_sim_checkpoint()
super().reject()
@staticmethod
def add_update_row(description: str, count: int, layout: QGridLayout) -> None:
row = layout.rowCount()
@@ -217,7 +224,7 @@ class QWaitingForMissionResultWindow(QDialog):
GameUpdateSignal.get_instance().sendDebriefing(self.debriefing)
GameUpdateSignal.get_instance().updateGame(self.game)
self.close()
self.accept()
def closeEvent(self, evt):
super(QWaitingForMissionResultWindow, self).closeEvent(evt)

View File

@@ -12,89 +12,61 @@ recommended_enemy_faction: Germany 1944
recommended_start_date: 1944-07-04
miz: caen_to_evreux.miz
performance: 1
version: "10.0"
version: "10.7"
squadrons:
# Evreux
26:
- primary: BARCAP
aircraft:
- Bf 109 K-4 Kurfürst
- primary: BARCAP
aircraft:
- Fw 190 A-8 Anton
- primary: BARCAP
- primary: Escort
aircraft:
- Fw 190 D-9 Dora
size: 12
- primary: Strike
secondary: air-to-ground
aircraft:
- Ju 88 A-4
- primary: AEW&C
- primary: Refueling
- primary: Transport
size: 12
# Conches
40:
- primary: BARCAP
secondary: any
aircraft:
- Bf 109 K-4 Kurfürst
- primary: BARCAP
aircraft:
- Fw 190 A-8 Anton
- primary: BARCAP
aircraft:
- Fw 190 D-9 Dora
- primary: SEAD
secondary: any
- primary: DEAD
secondary: any
size: 4
# Carpiquet
19:
- primary: BARCAP
- primary: CAS
secondary: any
aircraft:
- Thunderbolt Mk.II (Late)
- P-47D-40 Thunderbolt
size: 12
- primary: BARCAP
aircraft:
- Mustang Mk.IV (Late)
- P-51D-30-NA Mustang
- primary: BARCAP
secondary: any
aircraft:
- Spitfire LF Mk IX
- primary: BARCAP
aircraft:
- Spitfire LF Mk IX (Clipped Wings)
- primary: Strike
size: 12
- primary: BAI
secondary: air-to-ground
aircraft:
- MosquitoFBMkVI
- primary: SEAD
secondary: any
- primary: DEAD
secondary: any
size: 12
- primary: OCA/Runway
secondary: air-to-ground
aircraft:
- Boston Mk.III
- A-20G Havoc
size: 10
# Ford_AF
31:
- primary: BARCAP
aircraft:
- Thunderbolt Mk.II (Mid)
- P-47D-30 Thunderbolt (Late)
- primary: BARCAP
aircraft:
- Thunderbolt Mk.II (Early)
- P-47D-30 Thunderbolt (Early)
- primary: BARCAP
- primary: Escort
secondary: air-to-air
aircraft:
- Mustang Mk.IV (Early)
- P-51D-25-NA Mustang
- primary: Strike
secondary: air-to-ground
aircraft:
- Boston Mk.III
- A-20G Havoc
size: 10
- primary: Strike
secondary: air-to-ground
aircraft:
- Fortress Mk.III
- B-17G Flying Fortress
- primary: AEW&C
- primary: Refueling
- primary: Transport
size: 10

View File

@@ -7,7 +7,7 @@ recommended_enemy_faction: Syria 2011
description: <p>In this scenario, you start in Israel and the conflict is focused around the golan heights, an historically disputed territory.<br/><br/>This scenario is designed to be performance and helicopter friendly.</p>
miz: golan_heights_lite.miz
performance: 1
version: "10.5"
version: "10.7"
advanced_iads: true # Campaign has connection_nodes / power_sources / command_centers
iads_config:
- LHA-1 Tarawa # A Naval Group without connections but still participating as EWR
@@ -102,28 +102,31 @@ squadrons:
- primary: AEW&C
aircraft:
- E-3A
size: 1
- primary: Refueling
aircraft:
- KC-135 Stratotanker
- primary: Transport
aircraft:
- C-130
- primary: BARCAP
secondary: any
size: 1
- primary: Escort
secondary: air-to-air
aircraft:
- F-15C Eagle
size: 10
- primary: BARCAP
secondary: any
aircraft:
- F-4E Phantom II
size: 10
- primary: Strike
secondary: air-to-ground
aircraft:
- F-15E Strike Eagle
size: 10
- primary: SEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
size: 10
# Golan South
Golan South:
- primary: CAS
@@ -132,65 +135,67 @@ squadrons:
female_pilot_percentage: 15
aircraft:
- AH-1W SuperCobra
- primary: CAS
size: 4
- primary: BAI
secondary: air-to-ground
nickname: Defenders of Golan
female_pilot_percentage: 25
aircraft:
- AH-64D Apache Longbow
- primary: Transport
size: 6
- primary: Air Assault
secondary: any
aircraft:
- UH-1H Iroquois
size: 2
# Golan North
Golan North:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
size: 4
- primary: CAS
aircraft:
- SA 342M Gazelle
- primary: Transport
secondary: air-to-ground
aircraft:
- SA 342M Gazelle
size: 4
- primary: Air Assault
secondary: any
aircraft:
- Mi-8MTV2 Hip
size: 2
# Marj Ruhayyil
23:
- primary: BARCAP
- primary: BAI
secondary: any
aircraft:
- MiG-21bis Fishbed-N
- primary: BARCAP
size: 12
- primary: Escort
secondary: any
aircraft:
- MiG-23MLD Flogger-K
- primary: SEAD
secondary: air-to-ground
aircraft:
- Su-17M4 Fitter-K
- primary: Strike
secondary: air-to-ground
aircraft:
- Su-17M4 Fitter-K
- MiG-21bis Fishbed-N
size: 12
# Damascus
7:
- primary: BARCAP
secondary: any
aircraft:
- MiG-29S Fulcrum-C
- primary: BARCAP
secondary: any
aircraft:
- MiG-21bis Fishbed-N
- primary: BARCAP
- MiG-23MLD Flogger-K
size: 12
- primary: TARCAP
secondary: any
aircraft:
- MiG-25PD Foxbat-E
size: 12
- primary: SEAD
secondary: air-to-ground
aircraft:
- Su-24M Fencer-D
size: 12
- primary: Strike
secondary: air-to-ground
aircraft:
- Su-17M4 Fitter-K
size: 12

View File

@@ -38,16 +38,20 @@ squadrons:
- primary: AEW&C
aircraft:
- VAW-125
size: 2
- primary: Refueling
aircraft:
- VS-35 (Tanker)
size: 4
- primary: Anti-ship
secondary: air-to-ground
aircraft:
- VS-35
size: 8
- primary: Transport
aircraft:
- HSM-40
size: 2
# BLUFOR LHA
Naval-3:
- primary: BAI
@@ -58,6 +62,7 @@ squadrons:
secondary: air-to-ground
aircraft:
- HMLA-169 (UH-1H)
size: 4
- primary: CAS
secondary: air-to-ground
aircraft:
@@ -109,6 +114,7 @@ squadrons:
- primary: Refueling
aircraft:
- IL-78M
size: 2
# Rio Gallegos
7:
- primary: BARCAP

View File

@@ -198,16 +198,20 @@ squadrons:
- primary: AEW&C
aircraft:
- VAW-125
size: 2
- primary: Refueling
aircraft:
- VS-35 (Tanker)
size: 4
- primary: Anti-ship
secondary: air-to-ground
aircraft:
- VS-35
size: 8
- primary: Transport
aircraft:
- HSM-40
size: 2
#BLUFOR LHA
Naval-3:
- primary: BAI
@@ -218,6 +222,7 @@ squadrons:
secondary: air-to-ground
aircraft:
- HMLA-269 (UH-1H)
size: 4
- primary: CAS
secondary: air-to-ground
aircraft:
@@ -257,6 +262,7 @@ squadrons:
- primary: Refueling
aircraft:
- VMGR-352
size: 2
- primary: Strike
secondary: any
aircraft:
@@ -322,6 +328,7 @@ squadrons:
- primary: Refueling
aircraft:
- IL-78M
size: 2
# Bassel Al-Assad
21:
- primary: TARCAP
@@ -335,12 +342,15 @@ squadrons:
- primary: Refueling
aircraft:
- IL-78M
size: 2
- primary: Transport
aircraft:
- IL-76MD
size: 2
- primary: AEW&C
aircraft:
- A-50
size: 2
- primary: Strike
secondary: air-to-ground
aircraft:
@@ -389,3 +399,4 @@ squadrons:
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
size: 4

View File

@@ -27,16 +27,20 @@ squadrons:
- primary: AEW&C
aircraft:
- VAW-125
size: 2
- primary: Refueling
aircraft:
- VS-35 (Tanker)
size: 4
- primary: Anti-ship
secondary: air-to-ground
aircraft:
- VS-35
size: 8
- primary: Transport
aircraft:
- HSM-40
size: 2
# BLUFOR LHA
Naval-2:
- primary: BAI
@@ -47,6 +51,7 @@ squadrons:
secondary: air-to-ground
aircraft:
- HMLA-269 (UH-1H)
size: 4
- primary: CAS
secondary: air-to-ground
aircraft:
@@ -118,12 +123,15 @@ squadrons:
- primary: AEW&C
aircraft:
- A-50
size: 2
- primary: Refueling
aircraft:
- IL-78M
size: 2
- primary: Transport
aircraft:
- IL-78MD
size: 2
# OPFOR First FOB
FOB Gecitkale:
- primary: CAS
@@ -136,6 +144,7 @@ squadrons:
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
size: 2
- primary: CAS
secondary: air-to-ground
aircraft:

View File

@@ -27,16 +27,20 @@ squadrons:
- primary: AEW&C
aircraft:
- VAW-125
size: 2
- primary: Refueling
aircraft:
- VS-35 (Tanker)
size: 4
- primary: Anti-ship
secondary: air-to-ground
aircraft:
- VS-35
size: 8
- primary: Transport
aircraft:
- HSM-40
size: 2
# BLUFOR LHA
Naval-2:
- primary: BAI
@@ -47,6 +51,7 @@ squadrons:
secondary: air-to-ground
aircraft:
- HMLA-169 (UH-1H)
size: 4
- primary: CAS
secondary: air-to-ground
aircraft:
@@ -92,6 +97,7 @@ squadrons:
- primary: Transport
aircraft:
- IL-76MD
size: 2
- primary: BARCAP
secondary: any
aircraft:
@@ -105,6 +111,7 @@ squadrons:
- primary: Refueling
aircraft:
- IL-78M
size: 2
# Andersen AFB
6:
- primary: TARCAP
@@ -122,6 +129,7 @@ squadrons:
- primary: Transport
aircraft:
- IL-76MD
size: 2
# Antonio B. Won Pat Intl
4:
- primary: TARCAP

View File

@@ -37,6 +37,7 @@ squadrons:
aircraft:
- 101st Combat Aviation Brigade
#US Army UH-60
size: 6
# Havadarya
9:
- primary: BARCAP
@@ -62,9 +63,11 @@ squadrons:
- primary: AEW&C
aircraft:
- VAW-125
size: 2
- primary: Refueling
aircraft:
- VS-35 (Tanker)
size: 4
# BLUFOR LHA
BLUFOR LHA:
- primary: BAI
@@ -75,6 +78,7 @@ squadrons:
secondary: air-to-ground
aircraft:
- HMLA-169 (UH-1H)
size: 4
# BLUFOR Start FOB
FOB Anguran:
- primary: CAS
@@ -87,6 +91,7 @@ squadrons:
aircraft:
- Wolfpack, 1-82 ARB
#US Army Apache AH-64D
size: 2
# OPFOR L1F1
FOB Tang-e Dalan:
- primary: CAS
@@ -140,9 +145,11 @@ squadrons:
- primary: AEW&C
aircraft:
- A-50
size: 2
- primary: Refueling
aircraft:
- IL-78M
size: 2
- primary: BARCAP
secondary: any
aircraft:
@@ -159,6 +166,7 @@ squadrons:
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
size: 4
- primary: SEAD
secondary: air-to-ground
aircraft:
@@ -228,12 +236,15 @@ squadrons:
- primary: AEW&C
aircraft:
- A-50
size: 2
- primary: Refueling
aircraft:
- IL-78M
size: 2
- primary: Transport
aircraft:
- IL-78MD
size: 2
- primary: BARCAP
secondary: any
aircraft:
@@ -249,4 +260,4 @@ squadrons:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- Mi-24P Hind-F

View File

@@ -28,16 +28,20 @@ squadrons:
- primary: AEW&C
aircraft:
- VAW-125
size: 2
- primary: Refueling
aircraft:
- VS-35 (Tanker)
size: 4
- primary: Anti-ship
secondary: air-to-ground
aircraft:
- VS-35
size: 8
- primary: Transport
aircraft:
- HSM-40
size: 2
# BLUFOR LHA
Naval-2:
- primary: BAI
@@ -48,6 +52,7 @@ squadrons:
secondary: air-to-ground
aircraft:
- HMLA-169 (UH-1H)
size: 4
- primary: CAS
secondary: air-to-ground
aircraft:
@@ -72,12 +77,15 @@ squadrons:
- primary: AEW&C
aircraft:
- A-50
size: 2
- primary: Refueling
aircraft:
- IL-78M
size: 2
- primary: Transport
aircraft:
- IL-78MD
size: 2
- primary: BARCAP
secondary: any
aircraft:

View File

@@ -24,6 +24,7 @@ squadrons:
aircraft:
- 960th AAC Squadron
#USAF E-3A
size: 2
# King Hussein Air College, BLUFOR start
19:
- primary: BARCAP
@@ -46,6 +47,7 @@ squadrons:
aircraft:
- 101st Combat Aviation Brigade
#US Army UH-60
size: 4
# FOB Tha'lah, BLUFOR 1st FOB north
FOB Tha'lah:
- primary: CAS

View File

@@ -9,7 +9,7 @@ local unitPayloads = {
["num"] = 3,
},
[2] = {
["CLSID"] = "{M261_M282}",
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[3] = {
@@ -17,7 +17,7 @@ local unitPayloads = {
["num"] = 2,
},
[4] = {
["CLSID"] = "{M261_M282}",
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
},
@@ -30,19 +30,19 @@ local unitPayloads = {
["name"] = "Liberation BAI",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["CLSID"] = "{M299_4xAGM_114L}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["CLSID"] = "{M299_4xAGM_114L}",
["num"] = 4,
},
[3] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["CLSID"] = "{M299_4xAGM_114L}",
["num"] = 2,
},
[4] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["CLSID"] = "{M299_4xAGM_114L}",
["num"] = 1,
},
},
@@ -54,21 +54,21 @@ local unitPayloads = {
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "{M261_M229}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{M261_M229}",
["num"] = 1,
},
[3] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 3,
},
[4] = {
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{M261_M229}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{M261_M229}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 31,

View File

@@ -107,7 +107,7 @@ liveries_overrides:
J-11A Flanker-L:
- USN Aggressor VFC-13 'Ferris' (Fictional)
JF-17 Thunder:
- 'Chips' Camo for Blue Side (Fictional)
- "'Chips' Camo for Blue Side (Fictional)"
Ka-50 Hokum:
- georgia camo
Ka-50 Hokum (Blackshark 3):

View File

@@ -56,6 +56,16 @@ def test_save_start_of_turn(game: Game, tmp_bundle: SaveGameBundle) -> None:
assert zip_file.namelist() == [SaveGameBundle.START_OF_TURN_SAVE_NAME]
def test_save_pre_sim_checkpoint(game: Game, tmp_bundle: SaveGameBundle) -> None:
with ZipFile(tmp_bundle.bundle_path, "r") as zip_file:
with pytest.raises(KeyError):
zip_file.read(SaveGameBundle.PRE_SIM_CHECKPOINT_SAVE_NAME)
tmp_bundle.save_pre_sim_checkpoint(game)
with ZipFile(tmp_bundle.bundle_path, "r") as zip_file:
assert zip_file.namelist() == [SaveGameBundle.PRE_SIM_CHECKPOINT_SAVE_NAME]
def test_failed_save_leaves_original_intact(
game: Game, tmp_bundle: SaveGameBundle
) -> None: