Compare commits

...

43 Commits

Author SHA1 Message Date
MetalStormGhost
d2eb98bcc5 Added option for only night missions.
- Moved the night mission setting back from the Mission restrictions section to the Mission difficulty section.
- Changed the Night/day mission option into a dropdown menu.

Resolves #1786
2022-01-02 13:23:36 +01:00
RndName
475cb4851a Cleanup the killed map objects recognition
removed the extra array to track killed_map_objects and reuse the existing killed_ground_units routine to remove duplicate code and possible confusion

cherry-pick from 41392585
2022-01-02 12:55:42 +01:00
MetalStormGhost
24e904134e Update multi-part Caucasus campaigns. 2022-01-02 01:52:38 +01:00
RndName
365eaa98f7 Update pydcs 2022-01-02 01:23:49 +01:00
RndName
e070d5bf0d Rework killed map_objects recognition
- removed the map_object_id from the TGO
- add a new TriggerRule with the MapObjectIsDead Condition which adds the map object to the killed_map_objects array in the state.json
- Use the trigger_zone_name as the unique identifier used for the unit_map to recognize the kill
2022-01-02 01:23:48 +01:00
MetalStormGhost
ffd8152b36 Improved the F-104G CAP loadout.
Replace hydra pods with more AIM-9s.
2022-01-02 01:23:06 +01:00
Starfire13
11812f07fc Added missing squadron nickname 2022-01-02 01:23:05 +01:00
RndName
ba4de3dc27 Fix Viggen FR22 group channel id and mention in changelog
cherry-pick from deb7227c
2021-12-30 18:49:00 +01:00
RndName
208382f3c4 Update Viggen radio presets for 2.7.9
the radio presets of the Viggen were changed with the recent dcs update, they will no longer be automatically generated so we have to add them manually
cherry-pick from 0063d8db
2021-12-30 18:19:57 +01:00
RndName
aadb2dd54d Updated changelog
- marked as compat as currently there seems to be no change that the update is not save compat
- mentioned the recent dcs update
2021-12-30 11:13:37 +01:00
RndName
1b2eb1236f Update Fuzzle Campaigns
cherry-pick from 81cbf807
2021-12-30 11:11:42 +01:00
Dan Albert
00bdbf65ce Update pydcs.
cherry-pick from d81c6a0
2021-12-28 17:52:12 +01:00
MetalStormGhost
290646c8ae Updates for WW2 loadouts.
Major changes:
 - FW190A8 ground attack loadout WGr21 rockets (primarily an air-to-air weapon) replaced with SC500J or AB500 bombs.
 - FW190D9 WGr21 rockets replaced with R4M rocket packs and SC500 bombs for CAS.
 - Added droptanks for I-16.
 - Ju-88A4 CAS loadout changed for AB500 cluster bombs.
 - Mosquito now has rockets which were introduced in DCS World 2.7.9.17830 open beta
 - Added more/heavier bombs to P-47
 - P-51 now has a separate OCA/Runway loadout with bombs. Other ground attack loadouts switched to rockets.

Also includes an SA342Minigun loadout which we didn't previously have.

cherry-pick from 5684570
2021-12-28 17:50:56 +01:00
Dan Albert
8f58832527 Add ECM pod to Viper A2G loadouts.
Didn't add to the A2A loadouts since the ECM interferes with radar
operation and is otherwise weight and drag. It does have a radar
priority mode though, so maybe it should be added there too?

cherry-pick from c0dfa77
2021-12-28 17:50:02 +01:00
Dan Albert
f426a16e9d Add weapon data for the AN/ALQ-184.
cherry-pick from 0c7d549
2021-12-28 17:49:38 +01:00
Dan Albert
6f4e436305 Fix misclassification of the HTS as a TGP.
cherry-pick from fc4022a
2021-12-28 17:49:16 +01:00
RndName
08288c9da9 Mention squadron config and f-104 mod in changelog 2021-12-23 13:46:18 +01:00
RndName
9bfac347db Finish implementation of add/remove squadrons from AirWingConfigurationDialog
Users can now add and remove squadrons with specific buttons. this also allows new aircraft types to be added as well.

- rebased existing PR to develop
- reverted observable and changed to signals
- changed the general concept so that changes only affect the ui data model and not the game directly. Game will only be updated on apply
- removed unused code
- adopt to review comments
- allow user to choose a predefined squadron preset (also alow none value to use the random generator)
- Reuse the squadron defs from the default assigner in the AirWing class
- allow user to re-roll the squadron nickname (also added new ui icons for the button)

cherry-pick from d2f7785f
2021-12-23 13:45:13 +01:00
Richard Pump
22a35b0d2e Added squadron configuration gui
- added add/remove buttons to Air Wing Menu, implemented remove

cherry-pick from e4ba9a8b
2021-12-23 13:45:13 +01:00
Starfire13
e56d8de800 Fixed typo in squadrondefgenerator.py
cherry-pick from 4803ae5f
2021-12-23 13:43:49 +01:00
Starfire13
c806980ab8 Fixed typo in naming.py
cherry-pick from d739d830
2021-12-23 13:43:24 +01:00
MetalStormGhost
4750fff114 Re-add From Caen to Evreux campaign.
cherry-pick from 3626fa79
2021-12-23 13:43:04 +01:00
MetalStormGhost
b405b8e7ee F-104 mod support.
cherry-pick from 88bc4fd8
2021-12-23 13:42:49 +01:00
RndName
074ae328ee Revert "Temporary Fix for broken upload action"
This reverts commit 64d273b433.
2021-12-21 09:35:18 +01:00
RndName
5fd6ccb81d Enable / Disable game specific functions if no game is loaded
- Disable Save, Settings, Stats and Notes if game is none

cherry-pick from f9ed61d1
2021-12-20 13:56:20 +01:00
RndName
64d273b433 Temporary Fix for broken upload action
The upload-artifact version 2.3 has problems with 0byte files and prevent the build action from beeing completed.
This temporary fix should be reverted when they fixed the bug.
2021-12-13 20:49:50 +01:00
RndName
d7f833ecfb Fix empty convoy when transfer is not completable
fixes #1553
2021-12-13 20:49:49 +01:00
RndName
5d89b9ac25 Add Easy Communication Setting
allow to enforce the mission setting for easy communication
cherry-pick from 2c21644
2021-12-12 01:24:01 +01:00
RndName
056851765f Update Branch to V5.1.0 2021-12-10 00:14:32 +01:00
MetalStormGhost
54bf9357bf Add option to limit convoy travel distances.
CPU load seems to scale with route length, so add an option to limit
the length of the convoy route. The tradeoff is that the performance
sensitive route won't necessarily be a correct route.
2021-12-10 00:14:32 +01:00
Dan Albert
dfcc458479 Note HTS support in the changelog. 2021-12-10 00:14:31 +01:00
Dan Albert
f3f0e23eff Add weapon data and loadouts for the HTS.
Used in the default Viper DEAD and SEAD loadouts.
2021-12-10 00:14:30 +01:00
Dan Albert
5ce6de6645 Update pydcs.
HTS support.
2021-12-10 00:14:30 +01:00
Dan Albert
50b4d420fe Clarify the role of the faction aircraft list. 2021-12-10 00:14:29 +01:00
MetalStormGhost
224c78ac11 Add a new base banner for FARPs. 2021-12-10 00:14:28 +01:00
Dan Albert
227b054279 Fix incorrect radio range for AN/ARC-222.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1740
2021-12-10 00:14:27 +01:00
Khopa
0093fa0fe1 Fix #1718 : Remove Merkava IV from faction "Israel 1982" 2021-12-10 00:14:02 +01:00
Khopa
3cdfd9d7d2 Fix #1717 : Removed SA5Generator from Iran 1988 faction 2021-12-10 00:14:02 +01:00
Khopa
5e2e07da80 pydcs : Updated to latest pydcs master commit 2021-12-10 00:14:01 +01:00
Khopa
5f3f6f8c9f SA5Generator : Added an ural truck to reload SA-5 sites 2021-12-10 00:13:56 +01:00
RndName
0077b04698 Update UI when buy or sell raises exception
fixes #1562 cherry-pick from 34100d1c
2021-11-26 21:00:44 +01:00
RndName
bb1e314260 Generate unit_id for helipads
fixes mission scripting error (1748)

cherry-picked from 676a256
2021-11-22 15:10:03 +01:00
Dan Albert
d710c2631a Update branch to 5.0.1. 2021-11-13 11:48:25 -08:00
82 changed files with 5958 additions and 659 deletions

View File

@@ -1,3 +1,25 @@
# 5.1.0
Saves from 5.0.0 are compatible with 5.1.0
## Features/Improvements
* **[Engine]** Support for DCS 2.7.9.17830 and newer, including the HTS and ECM pod.
* **[Campaign]** Add option to manually add and remove squadrons and different aircraft type in the new game wizard / air wing configuration dialog.
* **[Mission Generation]** Add Option to enforce the Easy Communication setting for the mission
* **[Mission Generation]** Add Option to select between only night missions, day missions or any time (default).
* **[Modding]** Add F-104 mod support
## Fixes
* **[Campaign]** Fixed some minor issues in campaigns which generated error messages in the log.
* **[Campaign]** Changed the way how map object / scenery kills where tracked. This fixes issues with kill recognition after map updates from ED which change the object ids and therefore prevent correct kill recognition.
* **[Mission Generation]** Fixed incorrect radio specification for the AN/ARC-222.
* **[Mission Generation]** Fixed mission scripting error when using a dedicated server.
* **[Mission Generation]** Fixed an issue where empty convoys lead to an index error when a point capture made a pending transfer of units not completable anymore.
* **[Mission Generation]** Corrected Viggen FR22 & FR24 preset channels for the DCS 2.7.9 update
* **[UI]** Enable / Disable the settings, save and stats actions if no game is loaded to prevent an error as these functions can only be used on a valid game.
# 5.0.0 # 5.0.0
Saves from 4.x are not compatible with 5.0. Saves from 4.x are not compatible with 5.0.
@@ -33,7 +55,7 @@ Saves from 4.x are not compatible with 5.0.
## Fixes ## Fixes
* **[Campaign]** Naval control points will no longer claim ground objectives during campaign generation and prevent them from spawning. * **[Campaign]** Naval control points will no longer claim ground objectives during campaign generation and prevent them from spawning.
* **[Campaign]** Units aboard suck cargo ships will now have their losses tracked properly. * **[Campaign]** Units aboard sunk cargo ships will now have their losses tracked properly.
* **[Mission Generation]** Mission results and other files will now be opened with enforced utf-8 encoding to prevent an issue where destroyed ground units were untracked because of special characters in their names. * **[Mission Generation]** Mission results and other files will now be opened with enforced utf-8 encoding to prevent an issue where destroyed ground units were untracked because of special characters in their names.
* **[Mission Generation]** Fixed generation of landing waypoints so that the AI obeys them. * **[Mission Generation]** Fixed generation of landing waypoints so that the AI obeys them.
* **[Mission Generation]** AI carrier aircraft with a start time of T+0 will now start at T+1s to avoid traffic jams. * **[Mission Generation]** AI carrier aircraft with a start time of T+0 will now start at T+1s to avoid traffic jams.

View File

@@ -5,10 +5,8 @@ from typing import Optional, TYPE_CHECKING
from game.squadrons import Squadron from game.squadrons import Squadron
from game.squadrons.squadrondef import SquadronDef from game.squadrons.squadrondef import SquadronDef
from game.squadrons.squadrondefloader import SquadronDefLoader
from gen.flights.flight import FlightType from gen.flights.flight import FlightType
from .campaignairwingconfig import CampaignAirWingConfig, SquadronConfig from .campaignairwingconfig import CampaignAirWingConfig, SquadronConfig
from .squadrondefgenerator import SquadronDefGenerator
from ..dcs.aircrafttype import AircraftType from ..dcs.aircrafttype import AircraftType
from ..theater import ControlPoint from ..theater import ControlPoint
@@ -25,14 +23,6 @@ class DefaultSquadronAssigner:
self.game = game self.game = game
self.coalition = coalition self.coalition = coalition
self.air_wing = coalition.air_wing self.air_wing = coalition.air_wing
self.squadron_defs = SquadronDefLoader(game, coalition).load()
self.squadron_def_generator = SquadronDefGenerator(self.coalition)
def claim_squadron_def(self, squadron: SquadronDef) -> None:
try:
self.squadron_defs[squadron.aircraft].remove(squadron)
except ValueError:
pass
def assign(self) -> None: def assign(self) -> None:
for control_point in self.game.theater.control_points_for( for control_point in self.game.theater.control_points_for(
@@ -47,7 +37,6 @@ class DefaultSquadronAssigner:
) )
continue continue
self.claim_squadron_def(squadron_def)
squadron = Squadron.create_from( squadron = Squadron.create_from(
squadron_def, control_point, self.coalition, self.game squadron_def, control_point, self.coalition, self.game
) )
@@ -74,7 +63,7 @@ class DefaultSquadronAssigner:
# If we can't find any squadron matching the requirement, we should # If we can't find any squadron matching the requirement, we should
# create one. # create one.
return self.squadron_def_generator.generate_for_task( return self.air_wing.squadron_def_generator.generate_for_task(
config.primary, control_point config.primary, control_point
) )
@@ -105,7 +94,7 @@ class DefaultSquadronAssigner:
# No premade squadron available for this aircraft that meets the requirements, # No premade squadron available for this aircraft that meets the requirements,
# so generate one if possible. # so generate one if possible.
return self.squadron_def_generator.generate_for_aircraft(aircraft) return self.air_wing.squadron_def_generator.generate_for_aircraft(aircraft)
@staticmethod @staticmethod
def squadron_compatible_with( def squadron_compatible_with(
@@ -121,18 +110,24 @@ class DefaultSquadronAssigner:
def find_squadron_for_airframe( def find_squadron_for_airframe(
self, aircraft: AircraftType, task: FlightType, control_point: ControlPoint self, aircraft: AircraftType, task: FlightType, control_point: ControlPoint
) -> Optional[SquadronDef]: ) -> Optional[SquadronDef]:
for squadron in self.squadron_defs[aircraft]: for squadron in self.air_wing.squadron_defs[aircraft]:
if self.squadron_compatible_with(squadron, task, control_point): if not squadron.claimed and self.squadron_compatible_with(
squadron, task, control_point
):
return squadron return squadron
return None return None
def find_squadron_by_name( def find_squadron_by_name(
self, name: str, task: FlightType, control_point: ControlPoint self, name: str, task: FlightType, control_point: ControlPoint
) -> Optional[SquadronDef]: ) -> Optional[SquadronDef]:
for squadrons in self.squadron_defs.values(): for squadrons in self.air_wing.squadron_defs.values():
for squadron in squadrons: for squadron in squadrons:
if squadron.name == name and self.squadron_compatible_with( if (
squadron, task, control_point, ignore_base_preference=True not squadron.claimed
and squadron.name == name
and self.squadron_compatible_with(
squadron, task, control_point, ignore_base_preference=True
)
): ):
return squadron return squadron
return None return None
@@ -140,8 +135,10 @@ class DefaultSquadronAssigner:
def find_squadron_for_task( def find_squadron_for_task(
self, task: FlightType, control_point: ControlPoint self, task: FlightType, control_point: ControlPoint
) -> Optional[SquadronDef]: ) -> Optional[SquadronDef]:
for squadrons in self.squadron_defs.values(): for squadrons in self.air_wing.squadron_defs.values():
for squadron in squadrons: for squadron in squadrons:
if self.squadron_compatible_with(squadron, task, control_point): if not squadron.claimed and self.squadron_compatible_with(
squadron, task, control_point
):
return squadron return squadron
return None return None

View File

@@ -12,12 +12,12 @@ from gen.flights.ai_flight_planner_db import aircraft_for_task, tasks_for_aircra
from gen.flights.flight import FlightType from gen.flights.flight import FlightType
if TYPE_CHECKING: if TYPE_CHECKING:
from game.coalition import Coalition from game.factions.faction import Faction
class SquadronDefGenerator: class SquadronDefGenerator:
def __init__(self, coalition: Coalition) -> None: def __init__(self, faction: Faction) -> None:
self.coalition = coalition self.faction = faction
self.count = itertools.count(1) self.count = itertools.count(1)
self.used_nicknames: set[str] = set() self.used_nicknames: set[str] = set()
@@ -26,7 +26,7 @@ class SquadronDefGenerator:
) -> Optional[SquadronDef]: ) -> Optional[SquadronDef]:
aircraft_choice: Optional[AircraftType] = None aircraft_choice: Optional[AircraftType] = None
for aircraft in aircraft_for_task(task): for aircraft in aircraft_for_task(task):
if aircraft not in self.coalition.faction.aircrafts: if aircraft not in self.faction.aircrafts:
continue continue
if not control_point.can_operate(aircraft): if not control_point.can_operate(aircraft):
continue continue
@@ -44,7 +44,7 @@ class SquadronDefGenerator:
return SquadronDef( return SquadronDef(
name=f"Squadron {next(self.count):03}", name=f"Squadron {next(self.count):03}",
nickname=self.random_nickname(), nickname=self.random_nickname(),
country=self.coalition.country_name, country=self.faction.country,
role="Flying Squadron", role="Flying Squadron",
aircraft=aircraft, aircraft=aircraft,
livery=None, livery=None,
@@ -91,9 +91,9 @@ class SquadronDefGenerator:
"Brass", "Brass",
"Brave", "Brave",
"Brazen", "Brazen",
"Bronze",
"Brown", "Brown",
"Brutal", "Brutal",
"Brzone",
"Burning", "Burning",
"Buzzing", "Buzzing",
"Celestial", "Celestial",

View File

@@ -40,7 +40,7 @@ class Coalition:
self.procurement_requests: OrderedSet[AircraftProcurementRequest] = OrderedSet() self.procurement_requests: OrderedSet[AircraftProcurementRequest] = OrderedSet()
self.bullseye = Bullseye(Point(0, 0)) self.bullseye = Bullseye(Point(0, 0))
self.faker = Faker(self.faction.locales) self.faker = Faker(self.faction.locales)
self.air_wing = AirWing(player) self.air_wing = AirWing(player, game, self.faction)
self.transfers = PendingTransfers(game, player) self.transfers = PendingTransfers(game, player)
# Late initialized because the two coalitions in the game are mutually # Late initialized because the two coalitions in the game are mutually

View File

@@ -42,6 +42,7 @@ import pydcs_extensions.highdigitsams.highdigitsams as highdigitsams
# PATCH pydcs data with MODS # PATCH pydcs data with MODS
from game.factions.faction_loader import FactionLoader from game.factions.faction_loader import FactionLoader
from pydcs_extensions.a4ec.a4ec import A_4E_C from pydcs_extensions.a4ec.a4ec import A_4E_C
from pydcs_extensions.f104.f104 import VSN_F104G, VSN_F104S, VSN_F104S_AG
from pydcs_extensions.f22a.f22a import F_22A from pydcs_extensions.f22a.f22a import F_22A
from pydcs_extensions.hercules.hercules import Hercules from pydcs_extensions.hercules.hercules import Hercules
from pydcs_extensions.jas39.jas39 import JAS39Gripen, JAS39Gripen_AG from pydcs_extensions.jas39.jas39 import JAS39Gripen, JAS39Gripen_AG
@@ -53,6 +54,9 @@ plane_map["Su-57"] = Su_57
plane_map["Hercules"] = Hercules plane_map["Hercules"] = Hercules
plane_map["JAS39Gripen"] = JAS39Gripen plane_map["JAS39Gripen"] = JAS39Gripen
plane_map["JAS39Gripen_AG"] = JAS39Gripen_AG plane_map["JAS39Gripen_AG"] = JAS39Gripen_AG
plane_map["VSN_F104G"] = VSN_F104G
plane_map["VSN_F104S"] = VSN_F104S
plane_map["VSN_F104S_AG"] = VSN_F104S_AG
vehicle_map["FieldHL"] = frenchpack._FIELD_HIDE vehicle_map["FieldHL"] = frenchpack._FIELD_HIDE
vehicle_map["HARRIERH"] = frenchpack._FIELD_HIDE_SMALL vehicle_map["HARRIERH"] = frenchpack._FIELD_HIDE_SMALL

View File

@@ -101,7 +101,7 @@ class StateData:
#: Names of aircraft units that were killed during the mission. #: Names of aircraft units that were killed during the mission.
killed_aircraft: List[str] killed_aircraft: List[str]
#: Names of vehicle (and ship) units that were killed during the mission. #: Names of vehicles, ships or buildings that were killed during the mission.
killed_ground_units: List[str] killed_ground_units: List[str]
#: List of descriptions of destroyed statics. Format of each element is a mapping of #: List of descriptions of destroyed statics. Format of each element is a mapping of

View File

@@ -268,6 +268,10 @@ class Faction:
self.remove_aircraft("Hercules") self.remove_aircraft("Hercules")
if not mod_settings.f22_raptor: if not mod_settings.f22_raptor:
self.remove_aircraft("F-22A") self.remove_aircraft("F-22A")
if not mod_settings.f104_starfighter:
self.remove_aircraft("VSN_F104G")
self.remove_aircraft("VSN_F104S")
self.remove_aircraft("VSN_F104S_AG")
if not mod_settings.jas39_gripen: if not mod_settings.jas39_gripen:
self.remove_aircraft("JAS39Gripen") self.remove_aircraft("JAS39Gripen")
self.remove_aircraft("JAS39Gripen_AG") self.remove_aircraft("JAS39Gripen_AG")

View File

@@ -144,22 +144,35 @@ class ViggenRadioChannelAllocator(RadioChannelAllocator):
self, flight: FlightData, air_support: AirSupport self, flight: FlightData, air_support: AirSupport
) -> None: ) -> None:
# The Viggen's preset channels are handled differently from other # The Viggen's preset channels are handled differently from other
# aircraft. The aircraft automatically configures channels for every # aircraft. Since 2.7.9 the group channels will not be generated automatically
# allied flight in the game (including AWACS) and for every airfield. As # anymore. So we have to set AWACS and JTAC manually. There are also seven
# such, we don't need to allocate any of those. There are seven presets # special channels we can modify. We'll set the first channel of the main radio
# we can modify, however: three channels for the main radio intended for # to the intra-flight channel, and the first three emergency channels to each
# communication with wingmen, and four emergency channels for the backup
# radio. We'll set the first channel of the main radio to the
# intra-flight channel, and the first three emergency channels to each
# of the flight plan's airfields. The fourth emergency channel is always # of the flight plan's airfields. The fourth emergency channel is always
# the guard channel. # the guard channel.
radio_id = 1 radio_id = 1
flight.assign_channel(radio_id, 1, flight.intra_flight_channel)
# Possible Group Channels (100-139)
channel_alloc = iter(range(1, 40))
# Intra-Flight channel on Special 1 and Group 100 (required by module)
flight.assign_channel(radio_id, 41, flight.intra_flight_channel) # Special 1
flight.assign_channel(
radio_id, next(channel_alloc), flight.intra_flight_channel
)
for awacs in air_support.awacs:
flight.assign_channel(radio_id, next(channel_alloc), awacs.freq)
for jtac in air_support.jtacs:
flight.assign_channel(radio_id, next(channel_alloc), jtac.freq)
if flight.departure.atc is not None: if flight.departure.atc is not None:
flight.assign_channel(radio_id, 4, flight.departure.atc) flight.assign_channel(radio_id, 44, flight.departure.atc) # FR24 E
if flight.arrival.atc is not None: if flight.arrival.atc is not None:
flight.assign_channel(radio_id, 5, flight.arrival.atc) flight.assign_channel(radio_id, 45, flight.arrival.atc) # FR24 F
# TODO: Assign divert to 6 when we support divert airfields. if flight.divert is not None and flight.divert.atc is not None:
flight.assign_channel(radio_id, 46, flight.divert.atc) # FR24 G
@classmethod @classmethod
def name(cls) -> str: def name(cls) -> str:
@@ -263,10 +276,18 @@ class ViggenChannelNamer(ChannelNamer):
@staticmethod @staticmethod
def channel_name(radio_id: int, channel_id: int) -> str: def channel_name(radio_id: int, channel_id: int) -> str:
if channel_id >= 4: special_channels = [
channel_letter = "EFGH"[channel_id - 4] "FR 22 Special 1",
return f"FR 24 {channel_letter}" "FR 22 Special 2",
return f"FR 22 Special {channel_id}" "FR 22 Special 3",
"FR 24 E",
"FR 24 F",
"FR 24 G",
"FR 24 H",
]
if channel_id >= 41: # Special channels are 41-47
return special_channels[channel_id - 41]
return f"FR 22 Group {99 + channel_id}"
@classmethod @classmethod
def name(cls) -> str: def name(cls) -> str:

View File

@@ -23,6 +23,12 @@ class AutoAtoBehavior(Enum):
Prefer = "Prefer player pilots" Prefer = "Prefer player pilots"
class NightMissions(Enum):
DayAndNight = "nightmissions_nightandday"
OnlyDay = "nightmissions_onlyday"
OnlyNight = "nightmissions_onlynight"
DIFFICULTY_PAGE = "Difficulty" DIFFICULTY_PAGE = "Difficulty"
AI_DIFFICULTY_SECTION = "AI Difficulty" AI_DIFFICULTY_SECTION = "AI Difficulty"
@@ -104,11 +110,16 @@ class Settings:
section=MISSION_DIFFICULTY_SECTION, section=MISSION_DIFFICULTY_SECTION,
default=True, default=True,
) )
night_disabled: bool = boolean_option( night_day_missions: NightMissions = choices_option(
"No night missions", "Night/day mission options",
page=DIFFICULTY_PAGE, page=DIFFICULTY_PAGE,
section=MISSION_DIFFICULTY_SECTION, section=MISSION_DIFFICULTY_SECTION,
default=False, choices={
"Generate night and day missions": NightMissions.DayAndNight,
"Only generate day missions": NightMissions.OnlyDay,
"Only generate night missions": NightMissions.OnlyNight,
},
default=NightMissions.DayAndNight,
) )
# Mission Restrictions # Mission Restrictions
labels: str = choices_option( labels: str = choices_option(
@@ -137,6 +148,15 @@ class Settings:
MISSION_RESTRICTIONS_SECTION, MISSION_RESTRICTIONS_SECTION,
default=True, default=True,
) )
easy_communication: Optional[bool] = choices_option(
"Easy Communication",
page=DIFFICULTY_PAGE,
section=MISSION_RESTRICTIONS_SECTION,
choices={"Player preference": None, "Enforced on": True, "Enforced off": False},
default=None,
)
battle_damage_assessment: Optional[bool] = choices_option( battle_damage_assessment: Optional[bool] = choices_option(
"Battle damage assessment", "Battle damage assessment",
page=DIFFICULTY_PAGE, page=DIFFICULTY_PAGE,
@@ -378,6 +398,12 @@ class Settings:
section=PERFORMANCE_SECTION, section=PERFORMANCE_SECTION,
default=True, default=True,
) )
convoys_travel_full_distance: bool = boolean_option(
"Convoys drive the full distance between control points",
page=MISSION_GENERATOR_PAGE,
section=PERFORMANCE_SECTION,
default=True,
)
perf_infantry: bool = boolean_option( perf_infantry: bool = boolean_option(
"Generate infantry squads alongside vehicles", "Generate infantry squads alongside vehicles",
page=MISSION_GENERATOR_PAGE, page=MISSION_GENERATOR_PAGE,

View File

@@ -7,17 +7,30 @@ from typing import Sequence, Iterator, TYPE_CHECKING, Optional
from game.dcs.aircrafttype import AircraftType from game.dcs.aircrafttype import AircraftType
from gen.flights.ai_flight_planner_db import aircraft_for_task from gen.flights.ai_flight_planner_db import aircraft_for_task
from gen.flights.closestairfields import ObjectiveDistanceCache from gen.flights.closestairfields import ObjectiveDistanceCache
from .squadron import Squadron from .squadrondef import SquadronDef
from .squadrondefloader import SquadronDefLoader
from ..campaignloader.squadrondefgenerator import SquadronDefGenerator
from ..factions.faction import Faction
from ..theater import ControlPoint, MissionTarget from ..theater import ControlPoint, MissionTarget
if TYPE_CHECKING: if TYPE_CHECKING:
from game.game import Game
from gen.flights.flight import FlightType from gen.flights.flight import FlightType
from .squadron import Squadron
class AirWing: class AirWing:
def __init__(self, player: bool) -> None: def __init__(self, player: bool, game: Game, faction: Faction) -> None:
self.player = player self.player = player
self.squadrons: dict[AircraftType, list[Squadron]] = defaultdict(list) self.squadrons: dict[AircraftType, list[Squadron]] = defaultdict(list)
self.squadron_defs = SquadronDefLoader(game, faction).load()
self.squadron_def_generator = SquadronDefGenerator(faction)
def unclaim_squadron_def(self, squadron: Squadron) -> None:
if squadron.aircraft in self.squadron_defs:
for squadron_def in self.squadron_defs[squadron.aircraft]:
if squadron_def.claimed and squadron_def.name == squadron.name:
squadron_def.claimed = False
def add_squadron(self, squadron: Squadron) -> None: def add_squadron(self, squadron: Squadron) -> None:
self.squadrons[squadron.aircraft].append(squadron) self.squadrons[squadron.aircraft].append(squadron)

View File

@@ -419,6 +419,7 @@ class Squadron:
coalition: Coalition, coalition: Coalition,
game: Game, game: Game,
) -> Squadron: ) -> Squadron:
squadron_def.claimed = True
return Squadron( return Squadron(
squadron_def.name, squadron_def.name,
squadron_def.nickname, squadron_def.nickname,

View File

@@ -28,6 +28,7 @@ class SquadronDef:
mission_types: tuple[FlightType, ...] mission_types: tuple[FlightType, ...]
operating_bases: OperatingBases operating_bases: OperatingBases
pilot_pool: list[Pilot] pilot_pool: list[Pilot]
claimed: bool = False
auto_assignable_mission_types: set[FlightType] = field( auto_assignable_mission_types: set[FlightType] = field(
init=False, hash=False, compare=False init=False, hash=False, compare=False

View File

@@ -10,13 +10,13 @@ from .squadrondef import SquadronDef
if TYPE_CHECKING: if TYPE_CHECKING:
from game import Game from game import Game
from game.coalition import Coalition from ..factions.faction import Faction
class SquadronDefLoader: class SquadronDefLoader:
def __init__(self, game: Game, coalition: Coalition) -> None: def __init__(self, game: Game, faction: Faction) -> None:
self.game = game self.game = game
self.coalition = coalition self.faction = faction
@staticmethod @staticmethod
def squadron_directories() -> Iterator[Path]: def squadron_directories() -> Iterator[Path]:
@@ -27,8 +27,8 @@ class SquadronDefLoader:
def load(self) -> dict[AircraftType, list[SquadronDef]]: def load(self) -> dict[AircraftType, list[SquadronDef]]:
squadrons: dict[AircraftType, list[SquadronDef]] = defaultdict(list) squadrons: dict[AircraftType, list[SquadronDef]] = defaultdict(list)
country = self.coalition.country_name country = self.faction.country
faction = self.coalition.faction faction = self.faction
any_country = country.startswith("Combined Joint Task Forces ") any_country = country.startswith("Combined Joint Task Forces ")
for directory in self.squadron_directories(): for directory in self.squadron_directories():
for path, squadron_def in self.load_squadrons_from(directory): for path, squadron_def in self.load_squadrons_from(directory):

View File

@@ -70,6 +70,7 @@ class GeneratorSettings:
class ModSettings: class ModSettings:
a4_skyhawk: bool = False a4_skyhawk: bool = False
f22_raptor: bool = False f22_raptor: bool = False
f104_starfighter: bool = False
hercules: bool = False hercules: bool = False
jas39_gripen: bool = False jas39_gripen: bool = False
su57_felon: bool = False su57_felon: bool = False

View File

@@ -316,16 +316,6 @@ class SceneryGroundObject(BuildingGroundObject):
is_fob_structure=False, is_fob_structure=False,
) )
self.zone = zone self.zone = zone
try:
# In the default TriggerZone using "assign as..." in the DCS Mission Editor,
# property three has the scenery's object ID as its value.
self.map_object_id = self.zone.properties[3]["value"]
except (IndexError, KeyError):
logging.exception(
"Invalid TriggerZone for Scenery definition. The third property must "
"be the map object ID."
)
raise
class FactoryGroundObject(BuildingGroundObject): class FactoryGroundObject(BuildingGroundObject):

View File

@@ -699,6 +699,8 @@ class PendingTransfers:
completable_transfers = [] completable_transfers = []
for transfer in self.pending_transfers: for transfer in self.pending_transfers:
if not transfer.is_completable(self.network_for(transfer.position)): if not transfer.is_completable(self.network_for(transfer.position)):
if transfer.transport:
self.cancel_transport(transfer.transport, transfer)
transfer.disband() transfer.disband()
else: else:
completable_transfers.append(transfer) completable_transfers.append(transfer)

View File

@@ -217,7 +217,7 @@ class UnitMap:
self.buildings[name] = Building(ground_object) self.buildings[name] = Building(ground_object)
def add_scenery(self, ground_object: SceneryGroundObject) -> None: def add_scenery(self, ground_object: SceneryGroundObject) -> None:
name = str(ground_object.map_object_id) name = str(ground_object.zone.name)
if name in self.buildings: if name in self.buildings:
raise RuntimeError( raise RuntimeError(
f"Duplicate TGO unit: {name}. TriggerZone name: " f"Duplicate TGO unit: {name}. TriggerZone name: "

View File

@@ -2,7 +2,7 @@ from pathlib import Path
MAJOR_VERSION = 5 MAJOR_VERSION = 5
MINOR_VERSION = 0 MINOR_VERSION = 1
MICRO_VERSION = 0 MICRO_VERSION = 0

View File

@@ -10,7 +10,7 @@ from typing import Optional, TYPE_CHECKING, Any
from dcs.cloud_presets import Clouds as PydcsClouds from dcs.cloud_presets import Clouds as PydcsClouds
from dcs.weather import CloudPreset, Weather as PydcsWeather, Wind from dcs.weather import CloudPreset, Weather as PydcsWeather, Wind
from game.settings import Settings from game.settings.settings import Settings, NightMissions
from game.utils import Distance, Heading, meters, interpolate, Pressure, inches_hg from game.utils import Distance, Heading, meters, interpolate, Pressure, inches_hg
from game.theater.seasonalconditions import determine_season from game.theater.seasonalconditions import determine_season
@@ -301,7 +301,10 @@ class Conditions:
settings: Settings, settings: Settings,
) -> Conditions: ) -> Conditions:
_start_time = cls.generate_start_time( _start_time = cls.generate_start_time(
theater, day, time_of_day, settings.night_disabled theater,
day,
time_of_day,
settings.night_day_missions,
) )
return cls( return cls(
time_of_day=time_of_day, time_of_day=time_of_day,
@@ -315,9 +318,9 @@ class Conditions:
theater: ConflictTheater, theater: ConflictTheater,
day: datetime.date, day: datetime.date,
time_of_day: TimeOfDay, time_of_day: TimeOfDay,
night_disabled: bool, night_day_missions: NightMissions,
) -> datetime.datetime: ) -> datetime.datetime:
if night_disabled: if night_day_missions == NightMissions.OnlyDay:
logging.info("Skip Night mission due to user settings") logging.info("Skip Night mission due to user settings")
time_range = { time_range = {
TimeOfDay.Dawn: (8, 9), TimeOfDay.Dawn: (8, 9),
@@ -325,6 +328,14 @@ class Conditions:
TimeOfDay.Dusk: (12, 14), TimeOfDay.Dusk: (12, 14),
TimeOfDay.Night: (14, 17), TimeOfDay.Night: (14, 17),
}[time_of_day] }[time_of_day]
elif night_day_missions == NightMissions.OnlyNight:
logging.info("Skip Day mission due to user settings")
time_range = {
TimeOfDay.Dawn: (0, 3),
TimeOfDay.Day: (3, 6),
TimeOfDay.Dusk: (21, 22),
TimeOfDay.Night: (22, 23),
}[time_of_day]
else: else:
time_range = theater.daytime_map[time_of_day.value] time_range = theater.daytime_map[time_of_day.value]

View File

@@ -10,6 +10,7 @@ from dcs.unit import Vehicle
from dcs.unitgroup import VehicleGroup from dcs.unitgroup import VehicleGroup
from game.dcs.groundunittype import GroundUnitType from game.dcs.groundunittype import GroundUnitType
from game.theater import FrontLine
from game.transfers import Convoy from game.transfers import Convoy
from game.unitmap import UnitMap from game.unitmap import UnitMap
from game.utils import kph from game.utils import kph
@@ -38,11 +39,26 @@ class ConvoyGenerator:
convoy.units, convoy.units,
convoy.player_owned, convoy.player_owned,
) )
if self.game.settings.convoys_travel_full_distance:
end_point = convoy.route_end
else:
# convoys_travel_full_distance is disabled, so have the convoy only move the first segment on the route.
# This option aims to remove long routes for ground vehicles between control points,
# since the CPU load for pathfinding long routes on DCS can be pretty heavy.
frontline = FrontLine(convoy.origin, convoy.destination)
# Select the first route segment from the origin towards the destination
# so the convoy spawns at the origin CP. This allows the convoy to be
# targeted by BAI flights and starts it within the protection umbrella of the CP.
end_point = frontline.segments[0].point_b
group.add_waypoint( group.add_waypoint(
convoy.route_end, end_point,
speed=kph(40).kph, speed=kph(40).kph,
move_formation=PointAction.OnRoad, move_formation=PointAction.OnRoad,
) )
self.make_drivable(group) self.make_drivable(group)
self.unit_map.add_convoy_units(group, convoy) self.unit_map.add_convoy_units(group, convoy)
return group return group

View File

@@ -112,6 +112,7 @@ from game.dcs.aircrafttype import AircraftType
from gen.flights.flight import FlightType from gen.flights.flight import FlightType
from pydcs_extensions.a4ec.a4ec import A_4E_C from pydcs_extensions.a4ec.a4ec import A_4E_C
from pydcs_extensions.f22a.f22a import F_22A from pydcs_extensions.f22a.f22a import F_22A
from pydcs_extensions.f104.f104 import VSN_F104G, VSN_F104S, VSN_F104S_AG
from pydcs_extensions.hercules.hercules import Hercules from pydcs_extensions.hercules.hercules import Hercules
from pydcs_extensions.jas39.jas39 import JAS39Gripen, JAS39Gripen_AG from pydcs_extensions.jas39.jas39 import JAS39Gripen, JAS39Gripen_AG
from pydcs_extensions.su57.su57 import Su_57 from pydcs_extensions.su57.su57 import Su_57
@@ -151,6 +152,8 @@ CAP_CAPABLE = [
F_15E, F_15E,
M_2000C, M_2000C,
F_5E_3, F_5E_3,
VSN_F104S,
VSN_F104G,
MiG_19P, MiG_19P,
A_4E_C, A_4E_C,
F_86F_Sabre, F_86F_Sabre,
@@ -225,6 +228,8 @@ CAS_CAPABLE = [
C_101CC, C_101CC,
L_39ZA, L_39ZA,
UH_1H, UH_1H,
VSN_F104S_AG,
VSN_F104G,
A_20G, A_20G,
Ju_88A4, Ju_88A4,
P_47D_40, P_47D_40,
@@ -281,6 +286,8 @@ DEAD_CAPABLE = [
H_6J, H_6J,
A_20G, A_20G,
Ju_88A4, Ju_88A4,
VSN_F104S_AG,
VSN_F104G,
P_47D_40, P_47D_40,
P_47D_30bl1, P_47D_30bl1,
P_47D_30, P_47D_30,
@@ -344,6 +351,8 @@ STRIKE_CAPABLE = [
B_17G, B_17G,
A_20G, A_20G,
Ju_88A4, Ju_88A4,
VSN_F104S_AG,
VSN_F104G,
P_47D_40, P_47D_40,
P_47D_30bl1, P_47D_30bl1,
P_47D_30, P_47D_30,
@@ -435,6 +444,8 @@ RUNWAY_ATTACK_CAPABLE = [
B_17G, B_17G,
A_20G, A_20G,
Ju_88A4, Ju_88A4,
VSN_F104S_AG,
VSN_F104G,
P_47D_40, P_47D_40,
P_47D_30bl1, P_47D_30bl1,
P_47D_30, P_47D_30,

View File

@@ -25,6 +25,11 @@ class ForcedOptionsGenerator:
self.game.settings.external_views_allowed self.game.settings.external_views_allowed
) )
def _set_easy_communication(self) -> None:
self.mission.forced_options.easy_communication = (
self.game.settings.easy_communication
)
def _set_labels(self) -> None: def _set_labels(self) -> None:
# TODO: Fix settings to use the real type. # TODO: Fix settings to use the real type.
# TODO: Allow forcing "full" and have default do nothing. # TODO: Allow forcing "full" and have default do nothing.
@@ -51,6 +56,7 @@ class ForcedOptionsGenerator:
def generate(self) -> None: def generate(self) -> None:
self._set_options_view() self._set_options_view()
self._set_external_views() self._set_external_views()
self._set_easy_communication()
self._set_labels() self._set_labels()
self._set_unrestricted_satnav() self._set_unrestricted_satnav()
self._set_battle_damage_assessment() self._set_battle_damage_assessment()

View File

@@ -24,7 +24,8 @@ from typing import (
) )
from dcs import Mission, Point, unitgroup from dcs import Mission, Point, unitgroup
from dcs.action import SceneryDestructionZone from dcs.action import SceneryDestructionZone, DoScript
from dcs.condition import MapObjectIsDead
from dcs.country import Country from dcs.country import Country
from dcs.point import StaticPoint from dcs.point import StaticPoint
from dcs.statics import Fortification, fortification_map, warehouse_map from dcs.statics import Fortification, fortification_map, warehouse_map
@@ -35,7 +36,8 @@ from dcs.task import (
OptAlarmState, OptAlarmState,
FireAtPoint, FireAtPoint,
) )
from dcs.triggers import TriggerStart, TriggerZone from dcs.translation import String
from dcs.triggers import TriggerStart, TriggerZone, Event, TriggerOnce
from dcs.unit import Ship, Unit, Vehicle, InvisibleFARP from dcs.unit import Ship, Unit, Vehicle, InvisibleFARP
from dcs.unitgroup import ShipGroup, StaticGroup, VehicleGroup from dcs.unitgroup import ShipGroup, StaticGroup, VehicleGroup
from dcs.unittype import StaticType, ShipType, VehicleType from dcs.unittype import StaticType, ShipType, VehicleType
@@ -297,7 +299,9 @@ class SceneryGenerator(BuildingSiteGenerator):
# this trigger rule is applied. Otherwise you can kill a # this trigger rule is applied. Otherwise you can kill a
# structure twice. # structure twice.
if self.ground_object.is_dead: if self.ground_object.is_dead:
self.generate_dead_trigger_rule(trigger_zone) self.generate_destruction_trigger_rule(trigger_zone)
else:
self.generate_on_dead_trigger_rule(trigger_zone)
# Tell Liberation to manage this groundobjectsgen as part of the campaign. # Tell Liberation to manage this groundobjectsgen as part of the campaign.
self.register_scenery() self.register_scenery()
@@ -325,7 +329,7 @@ class SceneryGenerator(BuildingSiteGenerator):
zone.properties, zone.properties,
) )
def generate_dead_trigger_rule(self, trigger_zone: TriggerZone) -> None: def generate_destruction_trigger_rule(self, trigger_zone: TriggerZone) -> None:
# Add destruction zone trigger # Add destruction zone trigger
t = TriggerStart(comment="Destruction") t = TriggerStart(comment="Destruction")
t.actions.append( t.actions.append(
@@ -333,6 +337,17 @@ class SceneryGenerator(BuildingSiteGenerator):
) )
self.m.triggerrules.triggers.append(t) self.m.triggerrules.triggers.append(t)
def generate_on_dead_trigger_rule(self, trigger_zone: TriggerZone) -> None:
# Add a TriggerRule with the MapObjectIsDead condition to recognize killed
# map objects and add them to the state.json with a DoScript
t = TriggerOnce(Event.NoEvent, f"MapObjectIsDead Trigger {trigger_zone.id}")
t.add_condition(MapObjectIsDead(trigger_zone.id))
script_string = String(
f'killed_ground_units[#killed_ground_units + 1] = "{trigger_zone.name}"'
)
t.actions.append(DoScript(script_string))
self.m.triggerrules.triggers.append(t)
def register_scenery(self) -> None: def register_scenery(self) -> None:
scenery = self.ground_object scenery = self.ground_object
assert isinstance(scenery, SceneryGroundObject) assert isinstance(scenery, SceneryGroundObject)
@@ -600,7 +615,7 @@ class HelipadGenerator:
for i, helipad in enumerate(self.cp.helipads): for i, helipad in enumerate(self.cp.helipads):
name = self.cp.name + "_helipad_" + str(i) name = self.cp.name + "_helipad_" + str(i)
logging.info("Generating helipad static : " + name) logging.info("Generating helipad static : " + name)
pad = InvisibleFARP(name=name) pad = InvisibleFARP(unit_id=self.m.next_unit_id(), name=name)
pad.position = Point(helipad.x, helipad.y) pad.position = Point(helipad.x, helipad.y)
pad.heading = helipad.heading.degrees pad.heading = helipad.heading.degrees
sg = unitgroup.StaticGroup(self.m.next_group_id(), name) sg = unitgroup.StaticGroup(self.m.next_group_id(), name)

View File

@@ -161,10 +161,10 @@ ANIMALS: tuple[str, ...] = (
"FLAMINGO", "FLAMINGO",
"FLEA", "FLEA",
"FLOUNDER", "FLOUNDER",
"FORGMOUTH",
"FOX", "FOX",
"FRINGEHEAD", "FRINGEHEAD",
"FROG", "FROG",
"FROGMOUTH",
"GAR", "GAR",
"GAZELLE", "GAZELLE",
"GECKO", "GECKO",

View File

@@ -2,7 +2,7 @@
import itertools import itertools
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
from typing import Dict, FrozenSet, Iterator, List, Reversible, Set, Tuple from typing import Dict, FrozenSet, Iterator, List, Set, Tuple
@dataclass(frozen=True) @dataclass(frozen=True)
@@ -127,7 +127,7 @@ RADIOS: List[Radio] = [
RadioRange(MHz(30), MHz(88), MHz(1)), RadioRange(MHz(30), MHz(88), MHz(1)),
), ),
), ),
Radio("AN/ARC-222", (RadioRange(MHz(116), MHz(174), step=MHz(1)),)), Radio("AN/ARC-222", (RadioRange(MHz(116), MHz(152), step=MHz(1)),)),
Radio("SCR-522", (RadioRange(MHz(100), MHz(156), step=MHz(1)),)), Radio("SCR-522", (RadioRange(MHz(100), MHz(156), step=MHz(1)),)),
Radio("A.R.I. 1063", (RadioRange(MHz(100), MHz(156), step=MHz(1)),)), Radio("A.R.I. 1063", (RadioRange(MHz(100), MHz(156), step=MHz(1)),)),
Radio("BC-1206", (RadioRange(kHz(200), kHz(400), step=kHz(10)),)), Radio("BC-1206", (RadioRange(kHz(200), kHz(400), step=kHz(10)),)),

View File

@@ -1,4 +1,4 @@
from dcs.vehicles import AirDefence from dcs.vehicles import AirDefence, Unarmed
from gen.sam.airdefensegroupgenerator import ( from gen.sam.airdefensegroupgenerator import (
AirDefenseRange, AirDefenseRange,
@@ -14,6 +14,7 @@ class SA5Generator(AirDefenseGroupGenerator):
name = "SA-5/S-200 Site" name = "SA-5/S-200 Site"
def generate(self) -> None: def generate(self) -> None:
self.add_unit( self.add_unit(
AirDefence.RLS_19J6, AirDefence.RLS_19J6,
"SR", "SR",
@@ -28,6 +29,13 @@ class SA5Generator(AirDefenseGroupGenerator):
self.position.y, self.position.y,
self.heading, self.heading,
) )
self.add_unit(
Unarmed.Ural_375,
"LOGI",
self.position.x - 20,
self.position.y,
self.heading,
)
num_launchers = 6 num_launchers = 6
positions = self.get_circular_position( positions = self.get_circular_position(

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
from pydcs_extensions.a4ec.a4ec import A_4E_C from pydcs_extensions.a4ec.a4ec import A_4E_C
from pydcs_extensions.f104.f104 import VSN_F104G, VSN_F104S, VSN_F104S_AG
from pydcs_extensions.f22a.f22a import F_22A from pydcs_extensions.f22a.f22a import F_22A
from pydcs_extensions.hercules.hercules import Hercules from pydcs_extensions.hercules.hercules import Hercules
from pydcs_extensions.highdigitsams import highdigitsams from pydcs_extensions.highdigitsams import highdigitsams
@@ -10,6 +11,9 @@ MODDED_AIRPLANES = [
A_4E_C, A_4E_C,
Su_57, Su_57,
F_22A, F_22A,
VSN_F104G,
VSN_F104S,
VSN_F104S_AG,
Hercules, Hercules,
JAS39Gripen, JAS39Gripen,
JAS39Gripen_AG, JAS39Gripen_AG,

View File

@@ -261,6 +261,7 @@ def create_game(
ModSettings( ModSettings(
a4_skyhawk=False, a4_skyhawk=False,
f22_raptor=False, f22_raptor=False,
f104_starfighter=False,
hercules=False, hercules=False,
jas39_gripen=False, jas39_gripen=False,
su57_felon=False, su57_felon=False,

View File

@@ -111,6 +111,9 @@ def load_icons():
"./resources/ui/misc/" + get_theme_icons() + "/pluginsoptions.png" "./resources/ui/misc/" + get_theme_icons() + "/pluginsoptions.png"
) )
ICONS["Notes"] = QPixmap("./resources/ui/misc/" + get_theme_icons() + "/notes.png") ICONS["Notes"] = QPixmap("./resources/ui/misc/" + get_theme_icons() + "/notes.png")
ICONS["Reload"] = QPixmap(
"./resources/ui/misc/" + get_theme_icons() + "/reload.png"
)
ICONS["TaskCAS"] = QPixmap("./resources/ui/tasks/cas.png") ICONS["TaskCAS"] = QPixmap("./resources/ui/tasks/cas.png")
ICONS["TaskCAP"] = QPixmap("./resources/ui/tasks/cap.png") ICONS["TaskCAP"] = QPixmap("./resources/ui/tasks/cap.png")

View File

@@ -10,28 +10,33 @@ from PySide2.QtCore import (
) )
from PySide2.QtGui import QStandardItemModel, QStandardItem, QIcon from PySide2.QtGui import QStandardItemModel, QStandardItem, QIcon
from PySide2.QtWidgets import ( from PySide2.QtWidgets import (
QComboBox,
QDialog, QDialog,
QListView, QListView,
QVBoxLayout,
QGroupBox, QGroupBox,
QLabel, QLabel,
QWidget,
QScrollArea, QScrollArea,
QLineEdit, QLineEdit,
QTextEdit,
QCheckBox,
QHBoxLayout, QHBoxLayout,
QStackedLayout, QStackedLayout,
QTabWidget, QTabWidget,
QComboBox, QTextEdit,
QVBoxLayout,
QWidget,
QCheckBox,
QPushButton,
QGridLayout,
QToolButton,
) )
from game import Game from game import Game
from gen.flights.flight import FlightType
from game.coalition import Coalition
from game.dcs.aircrafttype import AircraftType from game.dcs.aircrafttype import AircraftType
from game.squadrons import AirWing, Pilot, Squadron from game.squadrons import AirWing, Pilot, Squadron
from game.theater import ControlPoint, ConflictTheater from game.squadrons.squadrondef import SquadronDef
from gen.flights.flight import FlightType from game.theater import ConflictTheater, ControlPoint
from qt_ui.uiconstants import AIRCRAFT_ICONS from qt_ui.uiconstants import AIRCRAFT_ICONS, ICONS
class AllowedMissionTypeControls(QVBoxLayout): class AllowedMissionTypeControls(QVBoxLayout):
@@ -76,25 +81,37 @@ class SquadronBaseSelector(QComboBox):
def __init__( def __init__(
self, self,
bases: Iterable[ControlPoint], bases: Iterable[ControlPoint],
squadron: Squadron, selected_base: Optional[ControlPoint],
aircraft_type: Optional[AircraftType],
) -> None: ) -> None:
super().__init__() super().__init__()
self.bases = list(bases)
self.squadron = squadron
self.setSizeAdjustPolicy(self.AdjustToContents) self.setSizeAdjustPolicy(self.AdjustToContents)
self.bases = list(bases)
self.set_aircraft_type(aircraft_type)
for base in self.bases: if selected_base:
if not base.can_operate(self.squadron.aircraft): self.setCurrentText(selected_base.name)
continue
self.addItem(base.name, base) def set_aircraft_type(self, aircraft_type: Optional[AircraftType]):
self.model().sort(0) self.clear()
self.setCurrentText(self.squadron.location.name) if aircraft_type:
for base in self.bases:
if not base.can_operate(aircraft_type):
continue
self.addItem(base.name, base)
self.model().sort(0)
self.setEnabled(True)
else:
self.addItem("Select aircraft type first", None)
self.setEnabled(False)
self.update()
class SquadronConfigurationBox(QGroupBox): class SquadronConfigurationBox(QGroupBox):
remove_squadron_signal = Signal(Squadron)
def __init__(self, squadron: Squadron, theater: ConflictTheater) -> None: def __init__(self, squadron: Squadron, theater: ConflictTheater) -> None:
super().__init__() super().__init__()
self.setCheckable(True)
self.squadron = squadron self.squadron = squadron
self.reset_title() self.reset_title()
@@ -109,14 +126,24 @@ class SquadronConfigurationBox(QGroupBox):
self.name_edit.textChanged.connect(self.on_name_changed) self.name_edit.textChanged.connect(self.on_name_changed)
left_column.addWidget(self.name_edit) left_column.addWidget(self.name_edit)
left_column.addWidget(QLabel("Nickname:")) nickname_edit_layout = QGridLayout()
left_column.addLayout(nickname_edit_layout)
nickname_edit_layout.addWidget(QLabel("Nickname:"), 0, 0, 1, 2)
self.nickname_edit = QLineEdit(squadron.nickname) self.nickname_edit = QLineEdit(squadron.nickname)
self.nickname_edit.textChanged.connect(self.on_nickname_changed) self.nickname_edit.textChanged.connect(self.on_nickname_changed)
left_column.addWidget(self.nickname_edit) nickname_edit_layout.addWidget(self.nickname_edit, 1, 0, Qt.AlignTop)
reroll_nickname_button = QToolButton()
reroll_nickname_button.setIcon(QIcon(ICONS["Reload"]))
reroll_nickname_button.setToolTip("Re-roll nickname")
reroll_nickname_button.clicked.connect(self.reroll_nickname)
nickname_edit_layout.addWidget(reroll_nickname_button, 1, 1, Qt.AlignTop)
left_column.addWidget(QLabel("Base:")) left_column.addWidget(QLabel("Base:"))
self.base_selector = SquadronBaseSelector( self.base_selector = SquadronBaseSelector(
theater.control_points_for(squadron.player), squadron theater.control_points_for(squadron.player),
squadron.location,
squadron.aircraft,
) )
self.base_selector.currentIndexChanged.connect(self.on_base_changed) self.base_selector.currentIndexChanged.connect(self.on_base_changed)
left_column.addWidget(self.base_selector) left_column.addWidget(self.base_selector)
@@ -138,12 +165,18 @@ class SquadronConfigurationBox(QGroupBox):
self.player_list.setAcceptRichText(False) self.player_list.setAcceptRichText(False)
self.player_list.setEnabled(squadron.player) self.player_list.setEnabled(squadron.player)
left_column.addWidget(self.player_list) left_column.addWidget(self.player_list)
delete_button = QPushButton("Remove Squadron")
delete_button.setMaximumWidth(140)
delete_button.clicked.connect(self.remove_from_squadron_config)
left_column.addWidget(delete_button)
left_column.addStretch() left_column.addStretch()
self.allowed_missions = AllowedMissionTypeControls(squadron) self.allowed_missions = AllowedMissionTypeControls(squadron)
columns.addLayout(self.allowed_missions) columns.addLayout(self.allowed_missions)
def remove_from_squadron_config(self) -> None:
self.remove_squadron_signal.emit(self.squadron)
def on_name_changed(self, text: str) -> None: def on_name_changed(self, text: str) -> None:
self.squadron.name = text self.squadron.name = text
self.reset_title() self.reset_title()
@@ -160,6 +193,11 @@ class SquadronConfigurationBox(QGroupBox):
def reset_title(self) -> None: def reset_title(self) -> None:
self.setTitle(f"{self.squadron.name} - {self.squadron.aircraft}") self.setTitle(f"{self.squadron.name} - {self.squadron.aircraft}")
def reroll_nickname(self) -> None:
self.nickname_edit.setText(
self.squadron.coalition.air_wing.squadron_def_generator.random_nickname()
)
def apply(self) -> Squadron: def apply(self) -> Squadron:
player_names = self.player_list.toPlainText().splitlines() player_names = self.player_list.toPlainText().splitlines()
# Prepend player pilots so they get set active first. # Prepend player pilots so they get set active first.
@@ -173,29 +211,48 @@ class SquadronConfigurationBox(QGroupBox):
class SquadronConfigurationLayout(QVBoxLayout): class SquadronConfigurationLayout(QVBoxLayout):
config_changed = Signal(AircraftType)
def __init__(self, squadrons: list[Squadron], theater: ConflictTheater) -> None: def __init__(self, squadrons: list[Squadron], theater: ConflictTheater) -> None:
super().__init__() super().__init__()
self.squadron_configs = [] self.squadron_configs = []
self.theater = theater
for squadron in squadrons: for squadron in squadrons:
squadron_config = SquadronConfigurationBox(squadron, theater) self.add_squadron(squadron)
self.squadron_configs.append(squadron_config)
self.addWidget(squadron_config)
def apply(self) -> list[Squadron]: def apply(self) -> list[Squadron]:
keep_squadrons = [] keep_squadrons = []
for squadron_config in self.squadron_configs: for squadron_config in self.squadron_configs:
if squadron_config.isChecked(): keep_squadrons.append(squadron_config.apply())
keep_squadrons.append(squadron_config.apply())
return keep_squadrons return keep_squadrons
def remove_squadron(self, squadron: Squadron) -> None:
for squadron_config in self.squadron_configs:
if squadron_config.squadron == squadron:
squadron_config.deleteLater()
self.squadron_configs.remove(squadron_config)
squadron.coalition.air_wing.unclaim_squadron_def(squadron)
self.update()
self.config_changed.emit(squadron.aircraft)
return
def add_squadron(self, squadron: Squadron) -> None:
squadron_config = SquadronConfigurationBox(squadron, self.theater)
squadron_config.remove_squadron_signal.connect(self.remove_squadron)
self.squadron_configs.append(squadron_config)
self.addWidget(squadron_config)
class AircraftSquadronsPage(QWidget): class AircraftSquadronsPage(QWidget):
remove_squadron_page = Signal(AircraftType)
def __init__(self, squadrons: list[Squadron], theater: ConflictTheater) -> None: def __init__(self, squadrons: list[Squadron], theater: ConflictTheater) -> None:
super().__init__() super().__init__()
layout = QVBoxLayout() layout = QVBoxLayout()
self.setLayout(layout) self.setLayout(layout)
self.squadrons_config = SquadronConfigurationLayout(squadrons, theater) self.squadrons_config = SquadronConfigurationLayout(squadrons, theater)
self.squadrons_config.config_changed.connect(self.on_squadron_config_changed)
scrolling_widget = QWidget() scrolling_widget = QWidget()
scrolling_widget.setLayout(self.squadrons_config) scrolling_widget.setLayout(self.squadrons_config)
@@ -208,21 +265,56 @@ class AircraftSquadronsPage(QWidget):
layout.addWidget(scrolling_area) layout.addWidget(scrolling_area)
def on_squadron_config_changed(self, aircraft_type: AircraftType):
if len(self.squadrons_config.squadron_configs) == 0:
self.remove_squadron_page.emit(aircraft_type)
def add_squadron_to_page(self, squadron: Squadron):
self.squadrons_config.add_squadron(squadron)
def apply(self) -> list[Squadron]: def apply(self) -> list[Squadron]:
return self.squadrons_config.apply() return self.squadrons_config.apply()
class AircraftSquadronsPanel(QStackedLayout): class AircraftSquadronsPanel(QStackedLayout):
page_removed = Signal(AircraftType)
def __init__(self, air_wing: AirWing, theater: ConflictTheater) -> None: def __init__(self, air_wing: AirWing, theater: ConflictTheater) -> None:
super().__init__() super().__init__()
self.air_wing = air_wing self.air_wing = air_wing
self.theater = theater
self.squadrons_pages: dict[AircraftType, AircraftSquadronsPage] = {} self.squadrons_pages: dict[AircraftType, AircraftSquadronsPage] = {}
for aircraft, squadrons in self.air_wing.squadrons.items(): for aircraft, squadrons in self.air_wing.squadrons.items():
page = AircraftSquadronsPage(squadrons, theater) self.new_page_for_type(aircraft, squadrons)
self.addWidget(page)
self.squadrons_pages[aircraft] = page def remove_page_for_type(self, aircraft_type: AircraftType):
page = self.squadrons_pages[aircraft_type]
self.removeWidget(page)
page.deleteLater()
self.squadrons_pages.pop(aircraft_type)
self.page_removed.emit(aircraft_type)
self.update()
def new_page_for_type(
self, aircraft_type: AircraftType, squadrons: list[Squadron]
) -> None:
page = AircraftSquadronsPage(squadrons, self.theater)
page.remove_squadron_page.connect(self.remove_page_for_type)
self.addWidget(page)
self.squadrons_pages[aircraft_type] = page
def add_squadron_to_panel(self, squadron: Squadron):
# Find existing page or add new one
if squadron.aircraft in self.squadrons_pages:
page = self.squadrons_pages[squadron.aircraft]
page.add_squadron_to_page(squadron)
else:
self.new_page_for_type(squadron.aircraft, [squadron])
self.update()
def apply(self) -> None: def apply(self) -> None:
self.air_wing.squadrons = {}
for aircraft, page in self.squadrons_pages.items(): for aircraft, page in self.squadrons_pages.items():
self.air_wing.squadrons[aircraft] = page.apply() self.air_wing.squadrons[aircraft] = page.apply()
@@ -235,21 +327,29 @@ class AircraftTypeList(QListView):
self.setIconSize(QSize(91, 24)) self.setIconSize(QSize(91, 24))
self.setMinimumWidth(300) self.setMinimumWidth(300)
model = QStandardItemModel(self) self.item_model = QStandardItemModel(self)
self.setModel(model) self.setModel(self.item_model)
self.selectionModel().setCurrentIndex( self.selectionModel().setCurrentIndex(
model.index(0, 0), QItemSelectionModel.Select self.item_model.index(0, 0), QItemSelectionModel.Select
) )
self.selectionModel().selectionChanged.connect(self.on_selection_changed) self.selectionModel().selectionChanged.connect(self.on_selection_changed)
for aircraft in air_wing.squadrons: for aircraft in air_wing.squadrons:
aircraft_item = QStandardItem(aircraft.name) self.add_aircraft_type(aircraft)
icon = self.icon_for(aircraft)
if icon is not None: def remove_aircraft_type(self, aircraft: AircraftType):
aircraft_item.setIcon(icon) for item in self.item_model.findItems(aircraft.name):
aircraft_item.setEditable(False) self.item_model.removeRow(item.row())
aircraft_item.setSelectable(True) self.page_index_changed.emit(self.selectionModel().currentIndex().row())
model.appendRow(aircraft_item)
def add_aircraft_type(self, aircraft: AircraftType):
aircraft_item = QStandardItem(aircraft.name)
icon = self.icon_for(aircraft)
if icon is not None:
aircraft_item.setIcon(icon)
aircraft_item.setEditable(False)
aircraft_item.setSelectable(True)
self.item_model.appendRow(aircraft_item)
def on_selection_changed( def on_selection_changed(
self, selected: QItemSelection, _deselected: QItemSelection self, selected: QItemSelection, _deselected: QItemSelection
@@ -270,25 +370,70 @@ class AircraftTypeList(QListView):
class AirWingConfigurationTab(QWidget): class AirWingConfigurationTab(QWidget):
def __init__(self, air_wing: AirWing, theater: ConflictTheater) -> None: def __init__(self, coalition: Coalition, game: Game) -> None:
super().__init__() super().__init__()
layout = QHBoxLayout() layout = QGridLayout()
self.setLayout(layout) self.setLayout(layout)
self.game = game
self.coalition = coalition
type_list = AircraftTypeList(air_wing) self.type_list = AircraftTypeList(coalition.air_wing)
type_list.page_index_changed.connect(self.on_aircraft_changed)
layout.addWidget(type_list)
self.squadrons_panel = AircraftSquadronsPanel(air_wing, theater) layout.addWidget(self.type_list, 1, 1, 1, 2)
layout.addLayout(self.squadrons_panel)
add_button = QPushButton("Add Squadron")
add_button.clicked.connect(lambda state: self.add_squadron())
layout.addWidget(add_button, 2, 1, 1, 1)
self.squadrons_panel = AircraftSquadronsPanel(coalition.air_wing, game.theater)
self.squadrons_panel.page_removed.connect(self.type_list.remove_aircraft_type)
layout.addLayout(self.squadrons_panel, 1, 3, 2, 1)
self.type_list.page_index_changed.connect(self.squadrons_panel.setCurrentIndex)
def add_squadron(self) -> None:
selected_aircraft = None
if self.type_list.selectionModel().currentIndex().row() >= 0:
selected_aircraft = self.type_list.item_model.item(
self.type_list.selectionModel().currentIndex().row()
).text()
popup = SquadronConfigPopup(
selected_aircraft,
self.coalition.faction.aircrafts,
list(self.game.theater.control_points_for(self.coalition.player)),
self.coalition.air_wing.squadron_defs,
)
if popup.exec_() != QDialog.Accepted:
return
selected_type = popup.aircraft_type_selector.currentData()
selected_base = popup.squadron_base_selector.currentData()
selected_def = popup.squadron_def_selector.currentData()
# Let user choose the preset or generate one
squadron_def = (
selected_def
or self.coalition.air_wing.squadron_def_generator.generate_for_aircraft(
selected_type
)
)
squadron = Squadron.create_from(
squadron_def, selected_base, self.coalition, self.game
)
# Add Squadron
if not self.type_list.item_model.findItems(selected_type.name):
self.type_list.add_aircraft_type(selected_type)
# TODO Select the newly added type
self.squadrons_panel.add_squadron_to_panel(squadron)
self.update()
def apply(self) -> None: def apply(self) -> None:
self.squadrons_panel.apply() self.squadrons_panel.apply()
def on_aircraft_changed(self, index: QModelIndex) -> None:
self.squadrons_panel.setCurrentIndex(index)
class AirWingConfigurationDialog(QDialog): class AirWingConfigurationDialog(QDialog):
"""Dialog window for air wing configuration.""" """Dialog window for air wing configuration."""
@@ -302,22 +447,13 @@ class AirWingConfigurationDialog(QDialog):
layout = QVBoxLayout() layout = QVBoxLayout()
self.setLayout(layout) self.setLayout(layout)
doc_url = (
"https://github.com/dcs-liberation/dcs_liberation/wiki/Squadrons-and-pilots"
)
doc_label = QLabel( doc_label = QLabel(
"Use this opportunity to customize the squadrons available to your " "Use this opportunity to customize the squadrons available to your "
"coalition. <strong>This is your only opportunity to make changes.</strong>" "coalition. <strong>This is your only opportunity to make changes.</strong>"
"<br /><br />" "<br /><br />"
"To accept your changes and continue, close this window.<br />" "To accept your changes and continue, close this window."
"<br />"
"To remove a squadron from the game, uncheck the box in the title. New "
"squadrons cannot be added via the UI at this time. To add a custom "
"squadron,<br />"
f'see <a style="color:#ffffff" href="{doc_url}">the wiki</a>.'
) )
doc_label.setOpenExternalLinks(True)
layout.addWidget(doc_label) layout.addWidget(doc_label)
tab_widget = QTabWidget() tab_widget = QTabWidget()
@@ -325,7 +461,7 @@ class AirWingConfigurationDialog(QDialog):
self.tabs = [] self.tabs = []
for coalition in game.coalitions: for coalition in game.coalitions:
coalition_tab = AirWingConfigurationTab(coalition.air_wing, game.theater) coalition_tab = AirWingConfigurationTab(coalition, game)
name = "Blue" if coalition.player else "Red" name = "Blue" if coalition.player else "Red"
tab_widget.addTab(coalition_tab, name) tab_widget.addTab(coalition_tab, name)
self.tabs.append(coalition_tab) self.tabs.append(coalition_tab)
@@ -334,3 +470,104 @@ class AirWingConfigurationDialog(QDialog):
for tab in self.tabs: for tab in self.tabs:
tab.apply() tab.apply()
super().reject() super().reject()
class SquadronAircraftTypeSelector(QComboBox):
def __init__(
self, types: list[AircraftType], selected_aircraft: Optional[str]
) -> None:
super().__init__()
self.setSizeAdjustPolicy(self.AdjustToContents)
for type in sorted(types, key=lambda type: type.name):
self.addItem(type.name, type)
if selected_aircraft:
self.setCurrentText(selected_aircraft)
class SquadronDefSelector(QComboBox):
def __init__(
self,
squadron_defs: dict[AircraftType, list[SquadronDef]],
aircraft: Optional[AircraftType],
) -> None:
super().__init__()
self.setSizeAdjustPolicy(self.AdjustToContents)
self.squadron_defs = squadron_defs
self.set_aircraft_type(aircraft)
def set_aircraft_type(self, aircraft: Optional[AircraftType]):
self.clear()
self.addItem("None (Random)", None)
if aircraft and aircraft in self.squadron_defs:
for squadron_def in sorted(
self.squadron_defs[aircraft], key=lambda squadron_def: squadron_def.name
):
if not squadron_def.claimed:
squadron_name = squadron_def.name
if squadron_def.nickname:
squadron_name += " (" + squadron_def.nickname + ")"
self.addItem(squadron_name, squadron_def)
self.setCurrentText("None (Random)")
class SquadronConfigPopup(QDialog):
def __init__(
self,
selected_aircraft: Optional[str],
types: list[AircraftType],
bases: list[ControlPoint],
squadron_defs: dict[AircraftType, list[SquadronDef]],
) -> None:
super().__init__()
self.setWindowTitle(f"Add new Squadron")
self.column = QVBoxLayout()
self.setLayout(self.column)
self.bases = bases
self.column.addWidget(QLabel("Aircraft:"))
self.aircraft_type_selector = SquadronAircraftTypeSelector(
types, selected_aircraft
)
self.aircraft_type_selector.currentIndexChanged.connect(
self.on_aircraft_selection
)
self.column.addWidget(self.aircraft_type_selector)
self.column.addWidget(QLabel("Base:"))
self.squadron_base_selector = SquadronBaseSelector(
bases, None, self.aircraft_type_selector.currentData()
)
self.column.addWidget(self.squadron_base_selector)
self.column.addWidget(QLabel("Preset:"))
self.squadron_def_selector = SquadronDefSelector(
squadron_defs, self.aircraft_type_selector.currentData()
)
self.column.addWidget(self.squadron_def_selector)
self.column.addStretch()
self.button_layout = QHBoxLayout()
self.column.addLayout(self.button_layout)
self.accept_button = QPushButton("Accept")
self.accept_button.clicked.connect(lambda state: self.accept())
self.button_layout.addWidget(self.accept_button)
self.cancel_button = QPushButton("Cancel")
self.cancel_button.clicked.connect(lambda state: self.reject())
self.button_layout.addWidget(self.cancel_button)
def on_aircraft_selection(self) -> None:
self.squadron_base_selector.set_aircraft_type(
self.aircraft_type_selector.currentData()
)
self.squadron_def_selector.set_aircraft_type(
self.aircraft_type_selector.currentData()
)
self.update()

View File

@@ -170,6 +170,19 @@ class QLiberationWindow(QMainWindow):
self.openNotesAction.setIcon(CONST.ICONS["Notes"]) self.openNotesAction.setIcon(CONST.ICONS["Notes"])
self.openNotesAction.triggered.connect(self.showNotesDialog) self.openNotesAction.triggered.connect(self.showNotesDialog)
self.enable_game_actions(False)
def enable_game_actions(self, enabled: bool):
self.openSettingsAction.setVisible(enabled)
self.openStatsAction.setVisible(enabled)
self.openNotesAction.setVisible(enabled)
# Also Disable SaveAction to prevent Keyboard Shortcut
self.saveGameAction.setEnabled(enabled)
self.saveGameAction.setVisible(enabled)
self.saveAsAction.setEnabled(enabled)
self.saveAsAction.setVisible(enabled)
def initToolbar(self): def initToolbar(self):
self.tool_bar = self.addToolBar("File") self.tool_bar = self.addToolBar("File")
self.tool_bar.addAction(self.newGameAction) self.tool_bar.addAction(self.newGameAction)
@@ -328,6 +341,8 @@ class QLiberationWindow(QMainWindow):
QMessageBox.Ok, QMessageBox.Ok,
) )
GameUpdateSignal.get_instance().updateGame(None) GameUpdateSignal.get_instance().updateGame(None)
finally:
self.enable_game_actions(self.game is not None)
def showAboutDialog(self): def showAboutDialog(self):
text = ( text = (

View File

@@ -245,6 +245,8 @@ class QBaseMenu2(QDialog):
return "./resources/ui/carrier.png" return "./resources/ui/carrier.png"
elif self.cp.cptype == ControlPointType.LHA_GROUP: elif self.cp.cptype == ControlPointType.LHA_GROUP:
return "./resources/ui/lha.png" return "./resources/ui/lha.png"
elif self.cp.cptype == ControlPointType.FOB and self.cp.has_helipads:
return "./resources/ui/heliport.png"
elif self.cp.cptype == ControlPointType.FOB: elif self.cp.cptype == ControlPointType.FOB:
return "./resources/ui/fob.png" return "./resources/ui/fob.png"
else: else:

View File

@@ -230,25 +230,23 @@ class UnitTransactionFrame(QFrame, Generic[TransactionItemType]):
self.update_purchase_controls() self.update_purchase_controls()
self.update_available_budget() self.update_available_budget()
def buy(self, item: TransactionItemType, quantity: int) -> bool: def buy(self, item: TransactionItemType, quantity: int) -> None:
try: try:
self.purchase_adapter.buy(item, quantity) self.purchase_adapter.buy(item, quantity)
except TransactionError as ex: except TransactionError as ex:
logging.exception(f"Purchase of {self.display_name_of(item)} failed") logging.exception(f"Purchase of {self.display_name_of(item)} failed")
QMessageBox.warning(self, "Purchase failed", str(ex), QMessageBox.Ok) QMessageBox.warning(self, "Purchase failed", str(ex), QMessageBox.Ok)
return False finally:
self.post_transaction_update() self.post_transaction_update()
return True
def sell(self, item: TransactionItemType, quantity: int) -> bool: def sell(self, item: TransactionItemType, quantity: int) -> None:
try: try:
self.purchase_adapter.sell(item, quantity) self.purchase_adapter.sell(item, quantity)
except TransactionError as ex: except TransactionError as ex:
logging.exception(f"Sale of {self.display_name_of(item)} failed") logging.exception(f"Sale of {self.display_name_of(item)} failed")
QMessageBox.warning(self, "Sale failed", str(ex), QMessageBox.Ok) QMessageBox.warning(self, "Sale failed", str(ex), QMessageBox.Ok)
return False finally:
self.post_transaction_update() self.post_transaction_update()
return True
def update_purchase_controls(self) -> None: def update_purchase_controls(self) -> None:
for group in self.purchase_groups.values(): for group in self.purchase_groups.values():

View File

@@ -105,6 +105,7 @@ class NewGameWizard(QtWidgets.QWizard):
mod_settings = ModSettings( mod_settings = ModSettings(
a4_skyhawk=self.field("a4_skyhawk"), a4_skyhawk=self.field("a4_skyhawk"),
f22_raptor=self.field("f22_raptor"), f22_raptor=self.field("f22_raptor"),
f104_starfighter=self.field("f104_starfighter"),
hercules=self.field("hercules"), hercules=self.field("hercules"),
jas39_gripen=self.field("jas39_gripen"), jas39_gripen=self.field("jas39_gripen"),
su57_felon=self.field("su57_felon"), su57_felon=self.field("su57_felon"),
@@ -564,6 +565,8 @@ class GeneratorOptions(QtWidgets.QWizardPage):
self.registerField("hercules", hercules) self.registerField("hercules", hercules)
f22_raptor = QtWidgets.QCheckBox() f22_raptor = QtWidgets.QCheckBox()
self.registerField("f22_raptor", f22_raptor) self.registerField("f22_raptor", f22_raptor)
f104_starfighter = QtWidgets.QCheckBox()
self.registerField("f104_starfighter", f104_starfighter)
jas39_gripen = QtWidgets.QCheckBox() jas39_gripen = QtWidgets.QCheckBox()
self.registerField("jas39_gripen", jas39_gripen) self.registerField("jas39_gripen", jas39_gripen)
su57_felon = QtWidgets.QCheckBox() su57_felon = QtWidgets.QCheckBox()
@@ -583,16 +586,18 @@ class GeneratorOptions(QtWidgets.QWizardPage):
modLayout.addWidget(a4_skyhawk, 1, 1) modLayout.addWidget(a4_skyhawk, 1, 1)
modLayout.addWidget(QtWidgets.QLabel("F-22A Raptor"), 2, 0) modLayout.addWidget(QtWidgets.QLabel("F-22A Raptor"), 2, 0)
modLayout.addWidget(f22_raptor, 2, 1) modLayout.addWidget(f22_raptor, 2, 1)
modLayout.addWidget(QtWidgets.QLabel("C-130J-30 Super Hercules"), 3, 0) modLayout.addWidget(QtWidgets.QLabel("F-104 Starfighter"), 3, 0)
modLayout.addWidget(hercules, 3, 1) modLayout.addWidget(f104_starfighter, 3, 1)
modLayout.addWidget(QtWidgets.QLabel("JAS 39 Gripen"), 4, 0) modLayout.addWidget(QtWidgets.QLabel("C-130J-30 Super Hercules"), 4, 0)
modLayout.addWidget(jas39_gripen, 4, 1) modLayout.addWidget(hercules, 4, 1)
modLayout.addWidget(QtWidgets.QLabel("Su-57 Felon"), 5, 0) modLayout.addWidget(QtWidgets.QLabel("JAS 39 Gripen"), 5, 0)
modLayout.addWidget(su57_felon, 5, 1) modLayout.addWidget(jas39_gripen, 5, 1)
modLayout.addWidget(QtWidgets.QLabel("Frenchpack"), 6, 0) modLayout.addWidget(QtWidgets.QLabel("Su-57 Felon"), 6, 0)
modLayout.addWidget(frenchpack, 6, 1) modLayout.addWidget(su57_felon, 6, 1)
modLayout.addWidget(QtWidgets.QLabel("High Digit SAMs"), 7, 0) modLayout.addWidget(QtWidgets.QLabel("Frenchpack"), 7, 0)
modLayout.addWidget(high_digit_sams, 7, 1) modLayout.addWidget(frenchpack, 7, 1)
modLayout.addWidget(QtWidgets.QLabel("High Digit SAMs"), 8, 0)
modLayout.addWidget(high_digit_sams, 8, 1)
modSettingsGroup.setLayout(modLayout) modSettingsGroup.setLayout(modLayout)
mlayout = QVBoxLayout() mlayout = QVBoxLayout()

View File

@@ -24,7 +24,7 @@ Pillow==8.3.2
pluggy==0.13.1 pluggy==0.13.1
pre-commit==2.10.1 pre-commit==2.10.1
py==1.10.0 py==1.10.0
-e git://github.com/pydcs/dcs@c06f6bc1a842f890c88e7ccbcb14af5ae32c9cfd#egg=pydcs -e git://github.com/pydcs/dcs@92e3046d476781bd617a6c1abd6853cccf97d57c#egg=pydcs
pyinstaller==4.3 pyinstaller==4.3
pyinstaller-hooks-contrib==2021.1 pyinstaller-hooks-contrib==2021.1
pyparsing==2.4.7 pyparsing==2.4.7

Binary file not shown.

View File

@@ -0,0 +1,323 @@
---
name: Caucasus - Full
theater: Caucasus
authors: Doc_of_Mur
description: <p>This is a complete map of every airbase in the Caucasus Region, all bases are fully defended by Air, Land and/or Sea. The player starts by invading southern Georgia and works their way through Russia. The Strike and SAM targets are limited for performance reasons. If this Scenario is too taxing for your computer you may use the Multi-Part Scenarios. They are copied from this Campaign and are catered toward less powerful machines.</p>
recommended_player_faction: Bluefor Modern
recommended_enemy_faction: Russia 2010
recommended_start_date: 2008-08-01
miz: Caucasus_Multi_Full.miz
performance: 3
version: "9.1"
squadrons:
# Anapa-Vityazevo
12:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: AEW&C
aircraft:
- A-50
- primary: Refueling
aircraft:
- IL-78M
- primary: Transport
aircraft:
- IL-78MD
- primary: Strike
secondary: air-to-ground
aircraft:
- Tu-160 Blackjack
# Krasnodar-Center
13:
- primary: BARCAP
secondary: air-to-air
aircraft:
- MiG-31 Foxhound
- MiG-25PD Foxbat-E
- primary: SEAD
secondary: any
- primary: DEAD
secondary: any
# Novorossiysk
14:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: CAS
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
# Krymsk
15:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: Strike
secondary: air-to-ground
# Maykop-Khanskaya
16:
- primary: CAS
secondary: air-to-ground
aircraft:
- Su-25 Frogfoot
- primary: BAI
secondary: air-to-ground
aircraft:
- Su-34 Fullback
- Su-24M Fencer-D
- primary: DEAD
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- Mi-24V Hind-E
# Gelendzhik
17:
- primary: CAS
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: DEAD
secondary: air-to-ground
- primary: Transport
# Sochi-Adler
18:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: AEW&C
aircraft:
- A-50
- primary: Refueling
aircraft:
- IL-78M
- primary: Transport
aircraft:
- IL-78MD
- primary: Strike
secondary: air-to-ground
- primary: Anti-ship
secondary: air-to-ground
# Sukhumi-Babushara
20:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: CAS
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
# Gudauta
21:
- primary: CAS
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: DEAD
secondary: air-to-ground
# Batumi
22:
- primary: CAS
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
- A-10C Thunderbolt II (Suite 3)
- primary: BAI
secondary: air-to-ground
aircraft:
- F-15E Strike Eagle
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-15C Eagle
- primary: SEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: DEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: Transport
aircraft:
- UH-60A
- primary: AEW&C
aircraft:
- E-2D Advanced Hawkeye
- primary: Refueling
aircraft:
- C-130
# Senaki-Kholki
23:
- primary: CAS
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: DEAD
secondary: air-to-ground
- primary: Transport
# Kobuleti
24:
- primary: CAS
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
- A-10C Thunderbolt II (Suite 3)
- primary: BAI
secondary: air-to-ground
aircraft:
- F-15E Strike Eagle
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-15C Eagle
- primary: SEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: DEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: Transport
aircraft:
- UH-60A
- primary: AEW&C
aircraft:
- E-3A
- primary: Refueling
aircraft:
- KC-135 Stratotanker
# Kutaisi
25:
- primary: BARCAP
- primary: AEW&C
- primary: Refueling
- primary: Transport
- primary: Strike
secondary: air-to-ground
# Mineralnye Vody
26:
- primary: BARCAP
secondary: air-to-air
aircraft:
- MiG-31 Foxhound
- MiG-25PD Foxbat-E
- primary: SEAD
secondary: any
- primary: DEAD
secondary: any
# Nalchik
27:
- primary: CAS
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: DEAD
secondary: air-to-ground
- primary: Transport
# Mozdok
28:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: AEW&C
aircraft:
- A-50
- primary: Refueling
aircraft:
- IL-78M
- primary: Transport
aircraft:
- IL-78MD
- primary: Strike
secondary: air-to-ground
aircraft:
- Tu-160 Blackjack
# Tbilisi-Lochini
29:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: AEW&C
aircraft:
- A-50
- primary: Refueling
aircraft:
- IL-78M
- primary: Transport
aircraft:
- IL-78MD
- primary: Strike
secondary: air-to-ground
aircraft:
- Tu-160 Blackjack
# Beslan
32:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- Mi-24V Hind-E
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- Mi-24V Hind-E
# Blue CV
Naval-5:
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-14B Tomcat
- primary: BARCAP
secondary: any
aircraft:
- F-14B Tomcat
- primary: Strike
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
- primary: BAI
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
- primary: Refueling
aircraft:
- S-3B Tanker
# Blue LHA
Naval-4:
- primary: BAI
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack
- primary: CAS
secondary: air-to-ground
aircraft:
- UH-1H Iroquois
# Red CV
Naval-1:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: any
- primary: Strike
secondary: any
- primary: BAI
secondary: any
- primary: Refueling
# Red LHA
Naval-2:
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground

Binary file not shown.

View File

@@ -0,0 +1,269 @@
---
name: Caucasus - Multi-Part Russia
theater: Caucasus
authors: Doc_of_Mur
description: <p>This is part 2 of the Caucasus Multi-part campaign. After completing Multi-Part Georgia, play this campaign to invade Russia and finish the theater. As this is now Russia the recommended enemy faction has changed. To simulate still owning Georgia the player income has been supplemented through an increased number of blue strike targets at the starting bases. This is a more difficult scenario with a higher concentration of Redfor SAMs and Strike targets than usual.</p>
recommended_player_faction: Bluefor Modern
recommended_enemy_faction: Russia 2010
recommended_start_date: 2008-08-01
miz: Caucasus_Multi_Russia.miz
performance: 2
version: "9.1"
squadrons:
# Anapa-Vityazevo
12:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: AEW&C
aircraft:
- A-50
- primary: Refueling
aircraft:
- IL-78M
- primary: Transport
aircraft:
- IL-78MD
- primary: Strike
secondary: air-to-ground
aircraft:
- Tu-160 Blackjack
# Krasnodar-Center
13:
- primary: BARCAP
secondary: air-to-air
aircraft:
- MiG-31 Foxhound
- MiG-25PD Foxbat-E
- primary: SEAD
secondary: any
- primary: DEAD
secondary: any
# Novorossiysk
14:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: CAS
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
# Krymsk
15:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: Strike
secondary: air-to-ground
# Maykop-Khanskaya
16:
- primary: CAS
secondary: air-to-ground
aircraft:
- Su-25 Frogfoot
- primary: BAI
secondary: air-to-ground
aircraft:
- Su-34 Fullback
- Su-24M Fencer-D
- primary: DEAD
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- Mi-24V Hind-E
# Gelendzhik
17:
- primary: CAS
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: DEAD
secondary: air-to-ground
- primary: Transport
# Sochi-Adler
18:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: AEW&C
aircraft:
- A-50
- primary: Refueling
aircraft:
- IL-78M
- primary: Transport
aircraft:
- IL-78MD
- primary: Strike
secondary: air-to-ground
- primary: Anti-ship
secondary: air-to-ground
# Gudauta
21:
- primary: CAS
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
- A-10C Thunderbolt II (Suite 3)
- primary: BAI
secondary: air-to-ground
aircraft:
- F-15E Strike Eagle
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-15C Eagle
- primary: SEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: DEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: Transport
aircraft:
- UH-60A
- primary: AEW&C
aircraft:
- E-2D Advanced Hawkeye
- primary: Refueling
aircraft:
- C-130
# Mineralnye Vody
26:
- primary: BARCAP
secondary: air-to-air
aircraft:
- MiG-31 Foxhound
- MiG-25PD Foxbat-E
- primary: SEAD
secondary: any
- primary: DEAD
secondary: any
# Nalchik
27:
- primary: CAS
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: DEAD
secondary: air-to-ground
- primary: Transport
# Mozdok
28:
- primary: BARCAP
aircraft:
- Su-30 Flanker-C
- Su-27 Flanker-B
- primary: AEW&C
aircraft:
- A-50
- primary: Refueling
aircraft:
- IL-78M
- primary: Transport
aircraft:
- IL-78MD
- primary: Strike
secondary: air-to-ground
aircraft:
- Tu-160 Blackjack
# Tbilisi-Lochini
29:
- primary: CAS
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
- A-10C Thunderbolt II (Suite 3)
- primary: BAI
secondary: air-to-ground
aircraft:
- F-15E Strike Eagle
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-15C Eagle
- primary: SEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: DEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: Transport
aircraft:
- UH-60A
- primary: AEW&C
aircraft:
- E-3A
- primary: Refueling
aircraft:
- KC-135 Stratotanker
# Beslan
32:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- Mi-24V Hind-E
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- Mi-24V Hind-E
# Blue CV
Naval-5:
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-14B Tomcat
- primary: BARCAP
secondary: any
aircraft:
- F-14B Tomcat
- primary: Strike
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
- primary: BAI
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
- primary: Refueling
aircraft:
- S-3B Tanker
# Blue LHA
Naval-4:
- primary: BAI
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack
- primary: CAS
secondary: air-to-ground
aircraft:
- UH-1H Iroquois
# Red CV
Naval-1:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: any
- primary: Strike
secondary: any
- primary: BAI
secondary: any
- primary: Refueling
# Red LHA
Naval-2:
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground

Binary file not shown.

View File

@@ -0,0 +1,96 @@
---
name: Normandy - From Caen to Evreux
theater: Normandy
authors: Khopa
description: <p>This is a light scenario on the Normandy map.</p><p>August 1944, allied forces are pushing from Caen/Carpiquet to the cities of Lisieux and Evreux.<p>Lisieux is an important logistic hub for the Werhmacht, and Evreux airbase is hosting most of the Luftwaffe forces in the region.</p>
recommended_player_faction: Allies 1944
recommended_enemy_faction: Germany 1944
recommended_start_date: 1944-07-04
miz: caen_to_evreux.miz
performance: 1
version: "9.0"
squadrons:
# Evreux
26:
- primary: BARCAP
aircraft:
- Bf 109 K-4 Kurf\u00fcrst
- primary: BARCAP
aircraft:
- Fw 190 A-8 Anton
- primary: BARCAP
aircraft:
- Fw 190 D-9 Dora
- primary: Strike
secondary: air-to-ground
aircraft:
- Ju 88 A-4
- primary: AEW&C
- primary: Refueling
- primary: Transport
# Conches
40:
- primary: BARCAP
aircraft:
- Bf 109 K-4 Kurf\u00fcrst
- primary: BARCAP
aircraft:
- Fw 190 A-8 Anton
- primary: BARCAP
aircraft:
- Fw 190 D-9 Dora
- primary: SEAD
secondary: any
- primary: DEAD
secondary: any
# Carpiquet
19:
- primary: BARCAP
aircraft:
- Thunderbolt Mk.II (Late)
- P-47D-40 Thunderbolt
- primary: BARCAP
aircraft:
- Mustang Mk.IV (Late)
- P-51D-30-NA Mustang
- primary: BARCAP
aircraft:
- Spitfire LF Mk IX
- primary: BARCAP
aircraft:
- Spitfire LF Mk IX (Clipped Wings)
- primary: Strike
secondary: air-to-ground
aircraft:
- MosquitoFBMkVI
- primary: SEAD
secondary: any
- primary: DEAD
secondary: any
# 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
aircraft:
- Mustang Mk.IV (Early)
- P-51D-25-NA Mustang
- primary: Strike
secondary: air-to-ground
aircraft:
- Boston Mk.III
- A-20G Havoc
- primary: Strike
secondary: air-to-ground
aircraft:
- Fortress Mk.III
- B-17G Flying Fortress
- primary: AEW&C
- primary: Refueling
- primary: Transport

View File

@@ -5,7 +5,7 @@ authors: Fuzzle
recommended_player_faction: Israel-USN 2005 (Allied Sword) recommended_player_faction: Israel-USN 2005 (Allied Sword)
recommended_enemy_faction: Syria-Lebanon 2005 (Allied Sword) recommended_enemy_faction: Syria-Lebanon 2005 (Allied Sword)
description: <p>In this fictional scenario, a US/Israeli coalition must push north from the Israeli border, through Syria and Lebanon to Aleppo.</p><p><strong>Backstory:</strong> A Syrian-Lebanese joint force (with Russian materiel support) has attacked Israel, attmepting to cross the northern border. With the arrival of a US carrier group, Israel prepares its counterattack. The US Navy will handle the Beirut region's coastal arena, while the IAF will push through Damascus and the inland mountain ranges.</p>, description: <p>In this fictional scenario, a US/Israeli coalition must push north from the Israeli border, through Syria and Lebanon to Aleppo.</p><p><strong>Backstory:</strong> A Syrian-Lebanese joint force (with Russian materiel support) has attacked Israel, attmepting to cross the northern border. With the arrival of a US carrier group, Israel prepares its counterattack. The US Navy will handle the Beirut region's coastal arena, while the IAF will push through Damascus and the inland mountain ranges.</p>,
version: 9.1 version: "9.1"
miz: operation_allied_sword.miz miz: operation_allied_sword.miz
performance: 2 performance: 2
recommended_start_date: 2004-07-17 recommended_start_date: 2004-07-17
@@ -135,7 +135,7 @@ squadrons:
aircraft: aircraft:
- SA 342M Gazelle - SA 342M Gazelle
# Palmyra # Palmyra
6: 28:
- primary: BARCAP - primary: BARCAP
secondary: air-to-air secondary: air-to-air
aircraft: aircraft:
@@ -160,7 +160,7 @@ squadrons:
- primary: Refueling - primary: Refueling
aircraft: aircraft:
- IL-78M - IL-78M
- primary: Transport - primary: Transport
aircraft: aircraft:
- IL-76MD - IL-76MD
- primary: AEW&C - primary: AEW&C

View File

@@ -3,7 +3,7 @@ name: Syria - Operation Blackball
theater: Syria theater: Syria
authors: Fuzzle authors: Fuzzle
description: <p>A lightweight fictional showcase of Cyprus for the Syria terrain. A US Navy force must deploy from a FOB and carrier group to push from the north-east down through the island. <strong>Note that the ground units purchased on turn zero must sustain you until you've taken the first hostile FOB. The starting point does not have a factory to simulate a Marine Expeditionary Force deploying from the carrier group.</strong></p><p><strong>Backstory:</strong> The world is at war. With the help of her eastern allies Russia has taken the Suez Canal and deployed a large naval force to the Mediterranean trapping a US carrier group near the Turkish-Syrian border. Now they must break out by taking Cyprus back.</p> description: <p>A lightweight fictional showcase of Cyprus for the Syria terrain. A US Navy force must deploy from a FOB and carrier group to push from the north-east down through the island. <strong>Note that the ground units purchased on turn zero must sustain you until you've taken the first hostile FOB. The starting point does not have a factory to simulate a Marine Expeditionary Force deploying from the carrier group.</strong></p><p><strong>Backstory:</strong> The world is at war. With the help of her eastern allies Russia has taken the Suez Canal and deployed a large naval force to the Mediterranean trapping a US carrier group near the Turkish-Syrian border. Now they must break out by taking Cyprus back.</p>
version: 9.1 version: "9.1"
recommended_player_faction: US Navy 2005 recommended_player_faction: US Navy 2005
recommended_enemy_faction: Russia 2010 recommended_enemy_faction: Russia 2010
miz: operation_blackball.miz miz: operation_blackball.miz

View File

@@ -3,7 +3,7 @@ name: Persian Gulf - Scenic Route
theater: Persian Gulf theater: Persian Gulf
authors: Fuzzle authors: Fuzzle
description: <p>A lightweight naval campaign involving a US Navy carrier group pushing across the coast of Iran. <strong>Note that the ground units purchased on turn zero must sustain you until you've taken the first hostile FOB. The starting point does not have a factory to simulate a Marine Expeditionary Force deploying from the carrier group.</strong></p><p><strong>Backstory:</strong> Iran has declared war on all US forces in the Gulf resulting in all local allies withdrawing their support for American troops. A lone carrier group must pacify the southern coast of Iran and hold out until backup can arrive lest the US and her interests be ejected from the region permanently.</p> description: <p>A lightweight naval campaign involving a US Navy carrier group pushing across the coast of Iran. <strong>Note that the ground units purchased on turn zero must sustain you until you've taken the first hostile FOB. The starting point does not have a factory to simulate a Marine Expeditionary Force deploying from the carrier group.</strong></p><p><strong>Backstory:</strong> Iran has declared war on all US forces in the Gulf resulting in all local allies withdrawing their support for American troops. A lone carrier group must pacify the southern coast of Iran and hold out until backup can arrive lest the US and her interests be ejected from the region permanently.</p>
version: 9.1 version: "9.1"
recommended_player_faction: US Navy 2005 recommended_player_faction: US Navy 2005
recommended_enemy_faction: Iran 2015 recommended_enemy_faction: Iran 2015
miz: scenic_route.miz miz: scenic_route.miz

View File

@@ -2,7 +2,8 @@ local unitPayloads = {
["name"] = "Bf-109K-4", ["name"] = "Bf-109K-4",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "STRIKE", ["displayName"] = "Liberation BAI",
["name"] = "Liberation BAI",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "SC_501_SC500",
@@ -10,37 +11,25 @@ local unitPayloads = {
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 34, [1] = 11,
[2] = 31,
[3] = 30,
[4] = 32,
}, },
}, },
[2] = { [2] = {
["name"] = "CAS", ["displayName"] = "Liberation TARCAP",
["name"] = "Liberation TARCAP",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "SC_501_SC250", ["CLSID"] = "BF109K_4_FUEL_TANK",
["num"] = 1, ["num"] = 1,
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 34, [1] = 11,
[2] = 31,
[3] = 30,
[4] = 32,
}, },
}, },
[3] = { [3] = {
["name"] = "CAP", ["displayName"] = "Liberation DEAD",
["pylons"] = { ["name"] = "Liberation DEAD",
},
["tasks"] = {
[1] = 31,
},
},
[4] = {
["name"] = "ANTISHIP",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "SC_501_SC500",
@@ -48,10 +37,96 @@ local unitPayloads = {
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 34, [1] = 11,
[2] = 31, },
[3] = 30, },
[4] = 32, [4] = {
["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = {
[1] = {
["CLSID"] = "BF109K_4_FUEL_TANK",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[5] = {
["name"] = "Liberation BARCAP",
["pylons"] = {
[1] = {
["CLSID"] = "BF109K_4_FUEL_TANK",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[6] = {
["displayName"] = "Liberation Fighter Sweep",
["name"] = "Liberation Fighter Sweep",
["pylons"] = {
[1] = {
["CLSID"] = "BF109K_4_FUEL_TANK",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[7] = {
["name"] = "Liberation Strike",
["pylons"] = {
[1] = {
["CLSID"] = "SC_501_SC500",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[8] = {
["displayName"] = "Liberation CAS",
["name"] = "Liberation CAS",
["pylons"] = {
[1] = {
["CLSID"] = "SC_501_SC500",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[9] = {
["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "SC_501_SC500",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[10] = {
["displayName"] = "Liberation OCA/Runway",
["name"] = "Liberation OCA/Runway",
["pylons"] = {
[1] = {
["CLSID"] = "SC_501_SC500",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
}, },
}, },
}, },

View File

@@ -5,7 +5,7 @@ local unitPayloads = {
["name"] = "CAS", ["name"] = "CAS",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "<CLEAN>", ["CLSID"] = "ALQ_184",
["num"] = 5, ["num"] = 5,
}, },
[2] = { [2] = {
@@ -80,7 +80,7 @@ local unitPayloads = {
["num"] = 11, ["num"] = 11,
}, },
[8] = { [8] = {
["CLSID"] = "<CLEAN>", ["CLSID"] = "ALQ_184",
["num"] = 5, ["num"] = 5,
}, },
}, },
@@ -166,7 +166,7 @@ local unitPayloads = {
["num"] = 7, ["num"] = 7,
}, },
[9] = { [9] = {
["CLSID"] = "<CLEAN>", ["CLSID"] = "ALQ_184",
["num"] = 5, ["num"] = 5,
}, },
[10] = { [10] = {
@@ -179,46 +179,55 @@ local unitPayloads = {
}, },
}, },
[5] = { [5] = {
["name"] = "SEAD", ["name"] = "Liberation SEAD",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}",
["num"] = 6,
},
[2] = {
["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
["num"] = 7,
},
[3] = {
["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
["num"] = 3,
},
[5] = {
["CLSID"] = "<CLEAN>",
["num"] = 5,
},
[6] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 2,
},
[7] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 8,
},
[9] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 9, ["num"] = 9,
}, },
[2] = {
["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}",
["num"] = 6,
},
[5] = {
["CLSID"] = "ALQ_184",
["num"] = 5,
},
[6] = {
["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}",
["num"] = 11,
},
[7] = {
["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}",
["num"] = 4,
},
[8] = {
["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
["num"] = 3,
},
[9] = {
["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
["num"] = 2,
},
[10] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 1,
},
[11] = {
["CLSID"] = "{AN_ASQ_213}",
["num"] = 10,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 29,
}, },
}, },
[6] = { [6] = {
@@ -262,9 +271,13 @@ local unitPayloads = {
["num"] = 11, ["num"] = 11,
}, },
[10] = { [10] = {
["CLSID"] = "<CLEAN>", ["CLSID"] = "ALQ_184",
["num"] = 5, ["num"] = 5,
}, },
[11] = {
["CLSID"] = "{AN_ASQ_213}",
["num"] = 10,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 31,

View File

@@ -2,67 +2,131 @@ local unitPayloads = {
["name"] = "FW-190A8", ["name"] = "FW-190A8",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "CAS", ["name"] = "Liberation BARCAP",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{WGr21}", ["CLSID"] = "BF109K_4_FUEL_TANK",
["num"] = 3,
},
[2] = {
["CLSID"] = "{WGr21}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{SC_250_T1_L2}",
["num"] = 1, ["num"] = 1,
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 11,
}, },
}, },
[2] = { [2] = {
["name"] = "STRIKE", ["displayName"] = "Liberation TARCAP",
["name"] = "Liberation TARCAP",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{SD_500_A}", ["CLSID"] = "BF109K_4_FUEL_TANK",
["num"] = 1, ["num"] = 1,
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 11,
}, },
}, },
[3] = { [3] = {
["name"] = "CAP", ["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "<CLEAN>", ["CLSID"] = "BF109K_4_FUEL_TANK",
["num"] = 1, ["num"] = 1,
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 11,
}, },
}, },
[4] = { [4] = {
["name"] = "ANTISHIP", ["displayName"] = "Liberation Fighter Sweep",
["name"] = "Liberation Fighter Sweep",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{SD_500_A}", ["CLSID"] = "BF109K_4_FUEL_TANK",
["num"] = 1, ["num"] = 1,
}, },
[2] = {
["CLSID"] = "{WGr21}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{WGr21}",
["num"] = 3,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 11,
},
},
[5] = {
["name"] = "Liberation BAI",
["pylons"] = {
[1] = {
["CLSID"] = "{AB_500_1_SD_10A}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[6] = {
["displayName"] = "Liberation CAS",
["name"] = "Liberation CAS",
["pylons"] = {
[1] = {
["CLSID"] = "{AB_500_1_SD_10A}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[7] = {
["displayName"] = "Liberation Strike",
["name"] = "Liberation Strike",
["pylons"] = {
[1] = {
["CLSID"] = "{SC_500_L2}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[8] = {
["displayName"] = "Liberation DEAD",
["name"] = "Liberation DEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{SC_500_L2}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[9] = {
["displayName"] = "Liberation OCA/Runway",
["name"] = "Liberation OCA/Runway",
["pylons"] = {
[1] = {
["CLSID"] = "{SC_500_L2}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[10] = {
["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "{AB_500_1_SD_10A}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
}, },
}, },
}, },

View File

@@ -2,26 +2,8 @@ local unitPayloads = {
["name"] = "FW-190D9", ["name"] = "FW-190D9",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "ANTISHIP", ["displayName"] = "Liberation Strike",
["pylons"] = { ["name"] = "Liberation Strike",
[1] = {
["CLSID"] = "{WGr21}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{WGr21}",
["num"] = 2,
},
},
["tasks"] = {
[1] = 11,
[2] = 10,
[3] = 32,
[4] = 31,
},
},
[2] = {
["name"] = "STRIKE",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "SC_501_SC500",
@@ -29,37 +11,154 @@ local unitPayloads = {
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 34, [1] = 11,
[2] = 31,
[3] = 30,
[4] = 32,
}, },
}, },
[3] = { [2] = {
["name"] = "CAS", ["displayName"] = "Liberation TARCAP",
["name"] = "Liberation TARCAP",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{WGr21}", ["CLSID"] = "FW109_FUEL_TANK",
["num"] = 3, ["num"] = 1,
}, },
[2] = { [2] = {
["CLSID"] = "{WGr21}", ["CLSID"] = "{FW_190_R4M_RGHT_WING}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{FW_190_R4M_LEFT_WING}",
["num"] = 2, ["num"] = 2,
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
[2] = 10, },
[3] = 32, },
[4] = 31, [3] = {
["displayName"] = "Liberation CAS",
["name"] = "Liberation CAS",
["pylons"] = {
[1] = {
["CLSID"] = "SC_501_SC500",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
}, },
}, },
[4] = { [4] = {
["name"] = "CAP", ["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "FW109_FUEL_TANK",
["num"] = 1,
},
[2] = {
["CLSID"] = "{FW_190_R4M_RGHT_WING}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{FW_190_R4M_LEFT_WING}",
["num"] = 2,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 11,
},
},
[5] = {
["name"] = "Liberation BARCAP",
["pylons"] = {
[1] = {
["CLSID"] = "FW109_FUEL_TANK",
["num"] = 1,
},
[2] = {
["CLSID"] = "{FW_190_R4M_RGHT_WING}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{FW_190_R4M_LEFT_WING}",
["num"] = 2,
},
},
["tasks"] = {
[1] = 11,
},
},
[6] = {
["displayName"] = "Liberation Fighter Sweep",
["name"] = "Liberation Fighter Sweep",
["pylons"] = {
[1] = {
["CLSID"] = "FW109_FUEL_TANK",
["num"] = 1,
},
[2] = {
["CLSID"] = "{FW_190_R4M_RGHT_WING}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{FW_190_R4M_LEFT_WING}",
["num"] = 2,
},
},
["tasks"] = {
[1] = 11,
},
},
[7] = {
["name"] = "Liberation BAI",
["pylons"] = {
[1] = {
["CLSID"] = "SC_501_SC500",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[8] = {
["displayName"] = "Liberation DEAD",
["name"] = "Liberation DEAD",
["pylons"] = {
[1] = {
["CLSID"] = "SC_501_SC500",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[9] = {
["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "ER_4_SC50",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[10] = {
["displayName"] = "Liberation OCA/Runway",
["name"] = "Liberation OCA/Runway",
["pylons"] = {
[1] = {
["CLSID"] = "SC_501_SC500",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
}, },
}, },
}, },

View File

@@ -2,135 +2,74 @@ local unitPayloads = {
["name"] = "I-16", ["name"] = "I-16",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "CAP", ["name"] = "Liberation TARCAP",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "I16_DROP_FUEL_TANK",
["num"] = 5,
},
[2] = {
["CLSID"] = "I16_DROP_FUEL_TANK",
["num"] = 4,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[2] = { [2] = {
["name"] = "CAS", ["displayName"] = "Liberation BARCAP",
["name"] = "Liberation BARCAP",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_DROP_FUEL_TANK",
["num"] = 8,
},
[2] = {
["CLSID"] = "I16_RS_82",
["num"] = 7,
},
[3] = {
["CLSID"] = "I16_RS_82",
["num"] = 6,
},
[4] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 5, ["num"] = 5,
}, },
[5] = { [2] = {
["CLSID"] = "I16_FAB_100SV", ["CLSID"] = "I16_DROP_FUEL_TANK",
["num"] = 4, ["num"] = 4,
}, },
[6] = {
["CLSID"] = "I16_RS_82",
["num"] = 3,
},
[7] = {
["CLSID"] = "I16_RS_82",
["num"] = 2,
},
[8] = {
["CLSID"] = "I16_RS_82",
["num"] = 1,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[3] = { [3] = {
["name"] = "STRIKE", ["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "I16_FAB_100SV", ["CLSID"] = "I16_DROP_FUEL_TANK",
["num"] = 5, ["num"] = 5,
}, },
[2] = { [2] = {
["CLSID"] = "I16_FAB_100SV", ["CLSID"] = "I16_DROP_FUEL_TANK",
["num"] = 4, ["num"] = 4,
}, },
[3] = {
["CLSID"] = "I16_RS_82",
["num"] = 1,
},
[4] = {
["CLSID"] = "I16_RS_82",
["num"] = 2,
},
[5] = {
["CLSID"] = "I16_RS_82",
["num"] = 3,
},
[6] = {
["CLSID"] = "I16_RS_82",
["num"] = 6,
},
[7] = {
["CLSID"] = "I16_RS_82",
["num"] = 7,
},
[8] = {
["CLSID"] = "I16_RS_82",
["num"] = 8,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[4] = { [4] = {
["name"] = "ANTISHIP", ["displayName"] = "Liberation Fighter Sweep",
["name"] = "Liberation Fighter Sweep",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "I16_FAB_100SV", ["CLSID"] = "I16_DROP_FUEL_TANK",
["num"] = 5, ["num"] = 5,
}, },
[2] = { [2] = {
["CLSID"] = "I16_FAB_100SV", ["CLSID"] = "I16_DROP_FUEL_TANK",
["num"] = 4, ["num"] = 4,
}, },
[3] = {
["CLSID"] = "I16_RS_82",
["num"] = 8,
},
[4] = {
["CLSID"] = "I16_RS_82",
["num"] = 7,
},
[5] = {
["CLSID"] = "I16_RS_82",
["num"] = 6,
},
[6] = {
["CLSID"] = "I16_RS_82",
["num"] = 3,
},
[7] = {
["CLSID"] = "I16_RS_82",
["num"] = 2,
},
[8] = {
["CLSID"] = "I16_RS_82",
["num"] = 1,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[5] = { [5] = {
["name"] = "SEAD", ["name"] = "Liberation CAS",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
@@ -145,32 +84,33 @@ local unitPayloads = {
["num"] = 6, ["num"] = 6,
}, },
[4] = { [4] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 5,
},
[5] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 4,
},
[6] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
["num"] = 3, ["num"] = 3,
}, },
[7] = { [5] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
["num"] = 2, ["num"] = 2,
}, },
[8] = { [6] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
["num"] = 1, ["num"] = 1,
}, },
[7] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 5,
},
[8] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 4,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[6] = { [6] = {
["name"] = "DEAD", ["displayName"] = "Liberation BAI",
["name"] = "Liberation BAI",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
@@ -185,32 +125,33 @@ local unitPayloads = {
["num"] = 6, ["num"] = 6,
}, },
[4] = { [4] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 5,
},
[5] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 4,
},
[6] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
["num"] = 3, ["num"] = 3,
}, },
[7] = { [5] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
["num"] = 2, ["num"] = 2,
}, },
[8] = { [6] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
["num"] = 1, ["num"] = 1,
}, },
[7] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 5,
},
[8] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 4,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[7] = { [7] = {
["name"] = "BAI", ["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
@@ -225,25 +166,25 @@ local unitPayloads = {
["num"] = 6, ["num"] = 6,
}, },
[4] = { [4] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 5,
},
[5] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 4,
},
[6] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
["num"] = 3, ["num"] = 3,
}, },
[7] = { [5] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
["num"] = 2, ["num"] = 2,
}, },
[8] = { [6] = {
["CLSID"] = "I16_RS_82", ["CLSID"] = "I16_RS_82",
["num"] = 1, ["num"] = 1,
}, },
[7] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 5,
},
[8] = {
["CLSID"] = "I16_FAB_100SV",
["num"] = 4,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,

View File

@@ -2,15 +2,16 @@ local unitPayloads = {
["name"] = "Ju-88A4", ["name"] = "Ju-88A4",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "ANTISHIP", ["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{LTF_5B}", ["CLSID"] = "{SC_500_L2}",
["num"] = 1, ["num"] = 3,
}, },
[2] = { [2] = {
["CLSID"] = "{LTF_5B}", ["CLSID"] = "{SC_500_L2}",
["num"] = 3, ["num"] = 1,
}, },
}, },
["tasks"] = { ["tasks"] = {
@@ -18,14 +19,14 @@ local unitPayloads = {
}, },
}, },
[2] = { [2] = {
["name"] = "CAS", ["name"] = "Liberation Anti-ship",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{LTF_5B}",
["num"] = 3, ["num"] = 3,
}, },
[2] = { [2] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{LTF_5B}",
["num"] = 1, ["num"] = 1,
}, },
}, },
@@ -34,22 +35,31 @@ local unitPayloads = {
}, },
}, },
[3] = { [3] = {
["name"] = "CAP", ["displayName"] = "Liberation BAI",
["name"] = "Liberation BAI",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "{SC_500_L2}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{SC_500_L2}",
["num"] = 1,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 32, [1] = 32,
}, },
}, },
[4] = { [4] = {
["name"] = "STRIKE", ["name"] = "Liberation Strike",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{SC_500_L2}",
["num"] = 3, ["num"] = 3,
}, },
[2] = { [2] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{SC_500_L2}",
["num"] = 1, ["num"] = 1,
}, },
}, },
@@ -58,15 +68,15 @@ local unitPayloads = {
}, },
}, },
[5] = { [5] = {
["displayName"] = "RUNWAY_ATTACK", ["displayName"] = "Liberation CAS",
["name"] = "RUNWAY_ATTACK", ["name"] = "Liberation CAS",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{AB_500_1_SD_10A}",
["num"] = 3, ["num"] = 3,
}, },
[2] = { [2] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{AB_500_1_SD_10A}",
["num"] = 1, ["num"] = 1,
}, },
}, },
@@ -75,15 +85,15 @@ local unitPayloads = {
}, },
}, },
[6] = { [6] = {
["displayName"] = "SEAD", ["displayName"] = "Liberation DEAD",
["name"] = "SEAD", ["name"] = "Liberation DEAD",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{SC_500_L2}",
["num"] = 3, ["num"] = 3,
}, },
[2] = { [2] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{SC_500_L2}",
["num"] = 1, ["num"] = 1,
}, },
}, },
@@ -92,15 +102,15 @@ local unitPayloads = {
}, },
}, },
[7] = { [7] = {
["displayName"] = "DEAD", ["displayName"] = "Liberation OCA/Runway",
["name"] = "DEAD", ["name"] = "Liberation OCA/Runway",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{SC_500_L2}",
["num"] = 3, ["num"] = 3,
}, },
[2] = { [2] = {
["CLSID"] = "SC_501_SC500", ["CLSID"] = "{SC_500_L2}",
["num"] = 1, ["num"] = 1,
}, },
}, },

View File

@@ -2,133 +2,277 @@ local unitPayloads = {
["name"] = "MosquitoFBMkVI", ["name"] = "MosquitoFBMkVI",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "CAP", ["displayName"] = "500 lb GP Mk.V*2, 500 lb GP Short tail*2",
["pylons"] = { ["name"] = "500 lb GP Mk.V*2, 500 lb GP Short tail*2",
},
["tasks"] = {
[1] = 11,
},
},
[2] = {
["displayName"] = "CAS",
["name"] = "CAS",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{British_MC_250LB_Bomb_Mk2}", ["CLSID"] = "{British_GP_500LB_Bomb_Mk5}",
["num"] = 2, ["num"] = 2,
}, },
[2] = { [2] = {
["CLSID"] = "{British_MC_250LB_Bomb_Mk2}", ["CLSID"] = "{British_GP_500LB_Bomb_Mk5}",
["num"] = 1, ["num"] = 1,
}, },
[3] = { [3] = {
["CLSID"] = "{British_MC_250LB_Bomb_Mk2_on_Handley_Page_Type_B_Cut_Bar}", ["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 4, ["num"] = 4,
}, },
[4] = { [4] = {
["CLSID"] = "{British_MC_250LB_Bomb_Mk2_on_Handley_Page_Type_B_Cut_Bar}", ["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 3, ["num"] = 3,
}, },
}, },
["tasks"] = {
[1] = 11,
[2] = 32,
[3] = 31,
[4] = 34,
},
},
[2] = {
["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = {
},
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[3] = { [3] = {
["displayName"] = "STRIKE", ["displayName"] = "Liberation TARCAP",
["name"] = "STRIKE", ["name"] = "Liberation TARCAP",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk5}",
["num"] = 2,
},
[2] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk5}",
["num"] = 1,
},
[3] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 3,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[4] = { [4] = {
["displayName"] = "DEAD", ["displayName"] = "Liberation OCA/Aircraft",
["name"] = "DEAD", ["name"] = "Liberation OCA/Aircraft",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk5}", ["CLSID"] = "",
["num"] = 2, ["num"] = 2,
}, },
[2] = { [2] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk5}", ["CLSID"] = "",
["num"] = 1, ["num"] = 1,
}, },
[3] = { [3] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}", ["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 4, ["num"] = 4,
}, },
[4] = { [4] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}", ["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 3, ["num"] = 3,
}, },
[5] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_RIGHT_WING_RAILS}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_LEFT_WING_RAILS}",
["num"] = 5,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[5] = { [5] = {
["displayName"] = "SEAD", ["displayName"] = "Liberation Anti-ship",
["name"] = "SEAD", ["name"] = "Liberation Anti-ship",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk5}", ["CLSID"] = "",
["num"] = 2, ["num"] = 2,
}, },
[2] = { [2] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk5}", ["CLSID"] = "",
["num"] = 1, ["num"] = 1,
}, },
[3] = { [3] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}", ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 4, ["num"] = 4,
}, },
[4] = { [4] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}", ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 3, ["num"] = 3,
}, },
[5] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_RIGHT_WING_RAILS}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_LEFT_WING_RAILS}",
["num"] = 5,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[6] = { [6] = {
["displayName"] = "ANTISHIP", ["displayName"] = "Liberation Fighter Sweep",
["name"] = "ANTISHIP", ["name"] = "Liberation Fighter Sweep",
["pylons"] = {
},
["tasks"] = {
[1] = 11,
},
},
[7] = {
["displayName"] = "Liberation CAS",
["name"] = "Liberation CAS",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk5}", ["CLSID"] = "",
["num"] = 2, ["num"] = 2,
}, },
[2] = { [2] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk5}", ["CLSID"] = "",
["num"] = 1, ["num"] = 1,
}, },
[3] = { [3] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}", ["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 4, ["num"] = 4,
}, },
[4] = { [4] = {
["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}", ["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 3, ["num"] = 3,
}, },
[5] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_RIGHT_WING_RAILS}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_LEFT_WING_RAILS}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 11,
},
},
[8] = {
["name"] = "Liberation Strike",
["pylons"] = {
[1] = {
["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short}",
["num"] = 2,
},
[2] = {
["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short}",
["num"] = 1,
},
[3] = {
["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 3,
},
},
["tasks"] = {
[1] = 11,
},
},
[9] = {
["displayName"] = "Liberation BAI",
["name"] = "Liberation BAI",
["pylons"] = {
[1] = {
["CLSID"] = "",
["num"] = 2,
},
[2] = {
["CLSID"] = "",
["num"] = 1,
},
[3] = {
["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 3,
},
[5] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_RIGHT_WING_RAILS}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_LEFT_WING_RAILS}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 11,
},
},
[10] = {
["displayName"] = "Liberation DEAD",
["name"] = "Liberation DEAD",
["pylons"] = {
[1] = {
["CLSID"] = "",
["num"] = 2,
},
[2] = {
["CLSID"] = "",
["num"] = 1,
},
[3] = {
["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 3,
},
[5] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_RIGHT_WING_RAILS}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_LEFT_WING_RAILS}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 11,
},
},
[11] = {
["displayName"] = "Liberation OCA/Runway",
["name"] = "Liberation OCA/Runway",
["pylons"] = {
[1] = {
["CLSID"] = "{British_SAP_500LB_Bomb_Mk5}",
["num"] = 2,
},
[2] = {
["CLSID"] = "{British_SAP_500LB_Bomb_Mk5}",
["num"] = 1,
},
[3] = {
["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}",
["num"] = 3,
},
},
["tasks"] = {
[1] = 11,
},
},
[12] = {
["name"] = "Liberation BARCAP",
["pylons"] = {
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,

View File

@@ -2,27 +2,16 @@ local unitPayloads = {
["name"] = "P-47D-30", ["name"] = "P-47D-30",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "STRIKE", ["name"] = "Liberation TARCAP",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "{AN_M65}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN_M65}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[2] = { [2] = {
["name"] = "ANTISTRIKE", ["displayName"] = "Liberation BARCAP",
["name"] = "Liberation BARCAP",
["pylons"] = { ["pylons"] = {
}, },
["tasks"] = { ["tasks"] = {
@@ -30,27 +19,17 @@ local unitPayloads = {
}, },
}, },
[3] = { [3] = {
["name"] = "CAS", ["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[4] = { [4] = {
["name"] = "CAP", ["displayName"] = "Liberation Fighter Sweep",
["name"] = "Liberation Fighter Sweep",
["pylons"] = { ["pylons"] = {
}, },
["tasks"] = { ["tasks"] = {
@@ -58,18 +37,19 @@ local unitPayloads = {
}, },
}, },
[5] = { [5] = {
["name"] = "SEAD", ["displayName"] = "Liberation CAS",
["name"] = "Liberation CAS",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{AN_M57}", ["CLSID"] = "{AN-M64}",
["num"] = 3, ["num"] = 3,
}, },
[2] = { [2] = {
["CLSID"] = "{AN_M57}", ["CLSID"] = "{AN-M64}",
["num"] = 2, ["num"] = 2,
}, },
[3] = { [3] = {
["CLSID"] = "{AN_M57}", ["CLSID"] = "{AN-M64}",
["num"] = 1, ["num"] = 1,
}, },
}, },
@@ -78,7 +58,8 @@ local unitPayloads = {
}, },
}, },
[6] = { [6] = {
["name"] = "ANTISHIP", ["displayName"] = "Liberation Strike",
["name"] = "Liberation Strike",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{AN-M64}",
@@ -94,6 +75,87 @@ local unitPayloads = {
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 11,
},
},
[7] = {
["displayName"] = "Liberation DEAD",
["name"] = "Liberation DEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[8] = {
["displayName"] = "Liberation BAI",
["name"] = "Liberation BAI",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[9] = {
["displayName"] = "Liberation OCA/Runway",
["name"] = "Liberation OCA/Runway",
["pylons"] = {
[1] = {
["CLSID"] = "{AN_M65}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN_M65}",
["num"] = 2,
},
},
["tasks"] = {
[1] = 11,
},
},
[10] = {
["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
}, },
}, },
}, },

View File

@@ -2,7 +2,7 @@ local unitPayloads = {
["name"] = "P-47D-30bl1", ["name"] = "P-47D-30bl1",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "CAP", ["name"] = "Liberation TARCAP",
["pylons"] = { ["pylons"] = {
}, },
["tasks"] = { ["tasks"] = {
@@ -10,47 +10,35 @@ local unitPayloads = {
}, },
}, },
[2] = { [2] = {
["name"] = "CAS", ["displayName"] = "Liberation BARCAP",
["name"] = "Liberation BARCAP",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "{AN_M57}",
["num"] = 1,
},
[2] = {
["CLSID"] = "{AN_M57}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN_M57}",
["num"] = 3,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[3] = { [3] = {
["name"] = "STRIKE", ["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[4] = { [4] = {
["name"] = "SEAD", ["displayName"] = "Liberation Fighter Sweep",
["name"] = "Liberation Fighter Sweep",
["pylons"] = {
},
["tasks"] = {
[1] = 11,
},
},
[5] = {
["displayName"] = "Liberation CAS",
["name"] = "Liberation CAS",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{AN-M64}",
@@ -69,8 +57,9 @@ local unitPayloads = {
[1] = 11, [1] = 11,
}, },
}, },
[5] = { [6] = {
["name"] = "ANTISHIP", ["displayName"] = "Liberation Strike",
["name"] = "Liberation Strike",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{AN-M64}",
@@ -86,6 +75,91 @@ local unitPayloads = {
}, },
}, },
["tasks"] = { ["tasks"] = {
[1] = 11,
},
},
[7] = {
["displayName"] = "Liberation DEAD",
["name"] = "Liberation DEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[8] = {
["displayName"] = "Liberation BAI",
["name"] = "Liberation BAI",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[9] = {
["displayName"] = "Liberation OCA/Runway",
["name"] = "Liberation OCA/Runway",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[10] = {
["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
}, },
}, },
}, },

View File

@@ -2,31 +2,34 @@ local unitPayloads = {
["name"] = "P-47D-40", ["name"] = "P-47D-40",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "CAP", ["displayName"] = "Liberation OCA/Runway",
["name"] = "Liberation OCA/Runway",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "{AN_M65}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN_M65}",
["num"] = 2,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[2] = { [2] = {
["name"] = "CAS", ["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "{P47_5_HVARS_ON_LEFT_WING_RAILS}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{P47_5_HVARS_ON_RIGHT_WING_RAILS}",
["num"] = 5,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[3] = { [3] = {
["name"] = "SEAD", ["displayName"] = "Liberation DEAD",
["name"] = "Liberation DEAD",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{P47_5_HVARS_ON_LEFT_WING_RAILS}", ["CLSID"] = "{P47_5_HVARS_ON_LEFT_WING_RAILS}",
@@ -36,13 +39,35 @@ local unitPayloads = {
["CLSID"] = "{P47_5_HVARS_ON_RIGHT_WING_RAILS}", ["CLSID"] = "{P47_5_HVARS_ON_RIGHT_WING_RAILS}",
["num"] = 5, ["num"] = 5,
}, },
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[5] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 11, [1] = 11,
}, },
}, },
[4] = { [4] = {
["name"] = "STRIKE", ["displayName"] = "Liberation BARCAP",
["name"] = "Liberation BARCAP",
["pylons"] = {
},
["tasks"] = {
[1] = 11,
},
},
[5] = {
["displayName"] = "Liberation Strike",
["name"] = "Liberation Strike",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{AN-M64}",
@@ -53,6 +78,14 @@ local unitPayloads = {
["num"] = 2, ["num"] = 2,
}, },
[3] = { [3] = {
["CLSID"] = "{P47_5_HVARS_ON_RIGHT_WING_RAILS}",
["num"] = 5,
},
[4] = {
["CLSID"] = "{P47_5_HVARS_ON_LEFT_WING_RAILS}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{AN-M64}",
["num"] = 1, ["num"] = 1,
}, },
@@ -61,7 +94,45 @@ local unitPayloads = {
[1] = 11, [1] = 11,
}, },
}, },
[5] = { [6] = {
["displayName"] = "Liberation Fighter Sweep",
["name"] = "Liberation Fighter Sweep",
["pylons"] = {
},
["tasks"] = {
[1] = 11,
},
},
[7] = {
["displayName"] = "Liberation SEAD",
["name"] = "Liberation SEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{P47_5_HVARS_ON_RIGHT_WING_RAILS}",
["num"] = 5,
},
[4] = {
["CLSID"] = "{P47_5_HVARS_ON_LEFT_WING_RAILS}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[8] = {
["name"] = "ANTISHIP", ["name"] = "ANTISHIP",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
@@ -76,10 +147,143 @@ local unitPayloads = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{AN-M64}",
["num"] = 1, ["num"] = 1,
}, },
[4] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[5] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
}, },
["tasks"] = { ["tasks"] = {
}, },
}, },
[9] = {
["displayName"] = "Liberation SEAD Escort",
["name"] = "Liberation SEAD Escort",
["pylons"] = {
[1] = {
["CLSID"] = "{P47_5_HVARS_ON_LEFT_WING_RAILS}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{P47_5_HVARS_ON_RIGHT_WING_RAILS}",
["num"] = 5,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[5] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[10] = {
["displayName"] = "Liberation CAS",
["name"] = "Liberation CAS",
["pylons"] = {
[1] = {
["CLSID"] = "{P47_5_HVARS_ON_LEFT_WING_RAILS}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{P47_5_HVARS_ON_RIGHT_WING_RAILS}",
["num"] = 5,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[5] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[11] = {
["displayName"] = "Liberation TARCAP",
["name"] = "Liberation TARCAP",
["pylons"] = {
},
["tasks"] = {
[1] = 11,
},
},
[12] = {
["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "{P47_5_HVARS_ON_LEFT_WING_RAILS}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{P47_5_HVARS_ON_RIGHT_WING_RAILS}",
["num"] = 5,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[5] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
[13] = {
["displayName"] = "Liberation BAI",
["name"] = "Liberation BAI",
["pylons"] = {
[1] = {
["CLSID"] = "{P47_5_HVARS_ON_LEFT_WING_RAILS}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{P47_5_HVARS_ON_RIGHT_WING_RAILS}",
["num"] = 5,
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{AN-M64}",
["num"] = 2,
},
[5] = {
["CLSID"] = "{AN-M64}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 11,
},
},
}, },
["tasks"] = { ["tasks"] = {
}, },

View File

@@ -2,40 +2,17 @@ local unitPayloads = {
["name"] = "P-51D-30-NA", ["name"] = "P-51D-30-NA",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "CAS", ["displayName"] = "Liberation OCA/Runway",
["name"] = "Liberation OCA/Runway",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{AN-M64}",
["num"] = 7, ["num"] = 7,
}, },
[5] = { [2] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{AN-M64}",
["num"] = 4, ["num"] = 4,
}, },
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 31,
@@ -44,7 +21,17 @@ local unitPayloads = {
}, },
}, },
[2] = { [2] = {
["name"] = "STRIKE", ["displayName"] = "Liberation Fighter Sweep",
["name"] = "Liberation Fighter Sweep",
["pylons"] = {
},
["tasks"] = {
[1] = 31,
},
},
[3] = {
["displayName"] = "Liberation CAS",
["name"] = "Liberation CAS",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
@@ -59,11 +46,11 @@ local unitPayloads = {
["num"] = 8, ["num"] = 8,
}, },
[4] = { [4] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{HVAR}",
["num"] = 7, ["num"] = 7,
}, },
[5] = { [5] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{HVAR}",
["num"] = 4, ["num"] = 4,
}, },
[6] = { [6] = {
@@ -78,6 +65,14 @@ local unitPayloads = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
["num"] = 1, ["num"] = 1,
}, },
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 31,
@@ -85,16 +80,9 @@ local unitPayloads = {
[3] = 30, [3] = 30,
}, },
}, },
[3] = {
["name"] = "CAP",
["pylons"] = {
},
["tasks"] = {
[1] = 31,
},
},
[4] = { [4] = {
["name"] = "ANTISHIP", ["displayName"] = "Liberation Strike",
["name"] = "Liberation Strike",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
@@ -109,11 +97,11 @@ local unitPayloads = {
["num"] = 8, ["num"] = 8,
}, },
[4] = { [4] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{HVAR}",
["num"] = 7, ["num"] = 7,
}, },
[5] = { [5] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{HVAR}",
["num"] = 4, ["num"] = 4,
}, },
[6] = { [6] = {
@@ -128,6 +116,245 @@ local unitPayloads = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
["num"] = 1, ["num"] = 1,
}, },
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 31,
[2] = 32,
[3] = 30,
},
},
[5] = {
["displayName"] = "Liberation Anti-ship",
["name"] = "Liberation Anti-ship",
["pylons"] = {
[1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{HVAR}",
["num"] = 7,
},
[5] = {
["CLSID"] = "{HVAR}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 31,
[2] = 32,
[3] = 30,
},
},
[6] = {
["displayName"] = "Liberation BAI",
["name"] = "Liberation BAI",
["pylons"] = {
[1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{HVAR}",
["num"] = 7,
},
[5] = {
["CLSID"] = "{HVAR}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 31,
[2] = 32,
[3] = 30,
},
},
[7] = {
["displayName"] = "Liberation DEAD",
["name"] = "Liberation DEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{HVAR}",
["num"] = 7,
},
[5] = {
["CLSID"] = "{HVAR}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 31,
[2] = 32,
[3] = 30,
},
},
[8] = {
["displayName"] = "Liberation TARCAP",
["name"] = "Liberation TARCAP",
["pylons"] = {
},
["tasks"] = {
[1] = 31,
},
},
[9] = {
["displayName"] = "Liberation BARCAP",
["name"] = "Liberation BARCAP",
["pylons"] = {
},
["tasks"] = {
[1] = 31,
},
},
[10] = {
["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = {
},
["tasks"] = {
[1] = 31,
},
},
[11] = {
["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{HVAR}",
["num"] = 7,
},
[5] = {
["CLSID"] = "{HVAR}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 31,

View File

@@ -2,7 +2,8 @@ local unitPayloads = {
["name"] = "P-51D", ["name"] = "P-51D",
["payloads"] = { ["payloads"] = {
[1] = { [1] = {
["name"] = "CAS", ["displayName"] = "Liberation CAS",
["name"] = "Liberation CAS",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
@@ -17,22 +18,30 @@ local unitPayloads = {
["num"] = 8, ["num"] = 8,
}, },
[4] = { [4] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{HVAR}",
["num"] = 7, ["num"] = 7,
}, },
[5] = { [5] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{HVAR}",
["num"] = 4, ["num"] = 6,
}, },
[6] = { [6] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
["num"] = 3, ["num"] = 5,
}, },
[7] = { [7] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
["num"] = 2, ["num"] = 4,
}, },
[8] = { [8] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[10] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
["num"] = 1, ["num"] = 1,
}, },
@@ -40,53 +49,48 @@ local unitPayloads = {
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 31,
[2] = 32, [2] = 32,
[3] = 30, [3] = 34,
[4] = 30,
}, },
}, },
[2] = { [2] = {
["name"] = "STRIKE", ["name"] = "Liberation TARCAP",
["pylons"] = { ["pylons"] = {
[1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{AN-M64}",
["num"] = 7,
},
[5] = {
["CLSID"] = "{AN-M64}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
}, },
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 31,
[2] = 32,
[3] = 30,
}, },
}, },
[3] = { [3] = {
["name"] = "ANTISHIP", ["displayName"] = "Liberation BARCAP",
["name"] = "Liberation BARCAP",
["pylons"] = {
},
["tasks"] = {
[1] = 31,
},
},
[4] = {
["displayName"] = "Liberation Escort",
["name"] = "Liberation Escort",
["pylons"] = {
},
["tasks"] = {
[1] = 31,
},
},
[5] = {
["displayName"] = "Liberation Fighter Sweep",
["name"] = "Liberation Fighter Sweep",
["pylons"] = {
},
["tasks"] = {
[1] = 31,
},
},
[6] = {
["displayName"] = "Liberation Strike",
["name"] = "Liberation Strike",
["pylons"] = { ["pylons"] = {
[1] = { [1] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
@@ -101,22 +105,30 @@ local unitPayloads = {
["num"] = 8, ["num"] = 8,
}, },
[4] = { [4] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{HVAR}",
["num"] = 7, ["num"] = 7,
}, },
[5] = { [5] = {
["CLSID"] = "{AN-M64}", ["CLSID"] = "{HVAR}",
["num"] = 4, ["num"] = 6,
}, },
[6] = { [6] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
["num"] = 3, ["num"] = 5,
}, },
[7] = { [7] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
["num"] = 2, ["num"] = 4,
}, },
[8] = { [8] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[10] = {
["CLSID"] = "{HVAR}", ["CLSID"] = "{HVAR}",
["num"] = 1, ["num"] = 1,
}, },
@@ -124,7 +136,236 @@ local unitPayloads = {
["tasks"] = { ["tasks"] = {
[1] = 31, [1] = 31,
[2] = 32, [2] = 32,
[3] = 30, [3] = 34,
[4] = 30,
},
},
[7] = {
["displayName"] = "Liberation Anti-ship",
["name"] = "Liberation Anti-ship",
["pylons"] = {
[1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{HVAR}",
["num"] = 7,
},
[5] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 4,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 31,
[2] = 32,
[3] = 34,
[4] = 30,
},
},
[8] = {
["displayName"] = "Liberation DEAD",
["name"] = "Liberation DEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{HVAR}",
["num"] = 7,
},
[5] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 4,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 31,
[2] = 32,
[3] = 34,
[4] = 30,
},
},
[9] = {
["displayName"] = "Liberation BAI",
["name"] = "Liberation BAI",
["pylons"] = {
[1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{HVAR}",
["num"] = 7,
},
[5] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 4,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 31,
[2] = 32,
[3] = 34,
[4] = 30,
},
},
[10] = {
["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "{HVAR}",
["num"] = 10,
},
[2] = {
["CLSID"] = "{HVAR}",
["num"] = 9,
},
[3] = {
["CLSID"] = "{HVAR}",
["num"] = 8,
},
[4] = {
["CLSID"] = "{HVAR}",
["num"] = 7,
},
[5] = {
["CLSID"] = "{HVAR}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{HVAR}",
["num"] = 5,
},
[7] = {
["CLSID"] = "{HVAR}",
["num"] = 4,
},
[8] = {
["CLSID"] = "{HVAR}",
["num"] = 3,
},
[9] = {
["CLSID"] = "{HVAR}",
["num"] = 2,
},
[10] = {
["CLSID"] = "{HVAR}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 31,
[2] = 32,
[3] = 34,
[4] = 30,
},
},
[11] = {
["displayName"] = "Liberation OCA/Runway",
["name"] = "Liberation OCA/Runway",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 7,
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 4,
},
},
["tasks"] = {
[1] = 31,
[2] = 32,
[3] = 34,
[4] = 30,
}, },
}, },
}, },

View File

@@ -0,0 +1,34 @@
local unitPayloads = {
["name"] = "SA342Minigun",
["payloads"] = {
[1] = {
["name"] = "Liberation CAS",
["pylons"] = {
[1] = {
["CLSID"] = "{IR_Deflector}",
["num"] = 6,
},
},
["tasks"] = {
[1] = 31,
},
},
[2] = {
["displayName"] = "Liberation OCA/Aircraft",
["name"] = "Liberation OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "{IR_Deflector}",
["num"] = 6,
},
},
["tasks"] = {
[1] = 31,
},
},
},
["tasks"] = {
},
["unitType"] = "SA342Minigun",
}
return unitPayloads

View File

@@ -0,0 +1,166 @@
local unitPayloads = {
["name"] = "VSN_F104G",
["payloads"] = {
[1] = {
["displayName"] = "CAP",
["name"] = "CAP",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-9L}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{AIM-9L}",
["num"] = 5,
},
[3] = {
["CLSID"] = "{AIM-9L}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-9L}",
["num"] = 8,
},
[5] = {
["CLSID"] = "VSN_F104G_R_PTB",
["num"] = 10,
},
[6] = {
["CLSID"] = "VSN_F104G_L_PTB",
["num"] = 2,
},
},
["tasks"] = {
[1] = 11,
},
},
[2] = {
["displayName"] = "DEAD",
["name"] = "DEAD",
["pylons"] = {
[1] = {
["CLSID"] = "VSN_F104G_L_PTB",
["num"] = 2,
},
[2] = {
["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}",
["num"] = 8,
},
[3] = {
["CLSID"] = "VSN_F104G_R_PTB",
["num"] = 10,
},
[4] = {
["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{AIM-9L}",
["num"] = 5,
},
[6] = {
["CLSID"] = "{AIM-9L}",
["num"] = 7,
},
},
["tasks"] = {
[1] = 19,
},
},
[3] = {
["displayName"] = "CAS",
["name"] = "CAS",
["pylons"] = {
[1] = {
["CLSID"] = "VSN_F104G_L_PTB",
["num"] = 2,
},
[2] = {
["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}",
["num"] = 8,
},
[3] = {
["CLSID"] = "VSN_F104G_R_PTB",
["num"] = 10,
},
[4] = {
["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{AIM-9L}",
["num"] = 5,
},
[6] = {
["CLSID"] = "{AIM-9L}",
["num"] = 7,
},
},
["tasks"] = {
[1] = 19,
},
},
[4] = {
["displayName"] = "STRIKE",
["name"] = "STRIKE",
["pylons"] = {
[1] = {
["CLSID"] = "VSN_F104G_L_PTB",
["num"] = 2,
},
[2] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 8,
},
[3] = {
["CLSID"] = "VSN_F104G_R_PTB",
["num"] = 10,
},
[4] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 6,
},
},
["tasks"] = {
[1] = 19,
},
},
[5] = {
["displayName"] = "OCA",
["name"] = "OCA",
["pylons"] = {
[1] = {
["CLSID"] = "VSN_F104G_L_PTB",
["num"] = 2,
},
[2] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 8,
},
[3] = {
["CLSID"] = "VSN_F104G_R_PTB",
["num"] = 10,
},
[4] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 6,
},
},
["tasks"] = {
[1] = 19,
},
},
},
["tasks"] = {
},
["unitType"] = "VSN_F104G",
}
return unitPayloads

View File

@@ -0,0 +1,50 @@
local unitPayloads = {
["name"] = "VSN_F104S",
["payloads"] = {
[1] = {
["displayName"] = "CAP",
["name"] = "CAP",
["pylons"] = {
[1] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 2,
},
[2] = {
["CLSID"] = "{AIM-7F}",
["num"] = 3,
},
[3] = {
["CLSID"] = "VSN_F104G_PTB",
["num"] = 4,
},
[4] = {
["CLSID"] = "{AIM-9L}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-9L}",
["num"] = 7,
},
[6] = {
["CLSID"] = "VSN_F104G_PTB",
["num"] = 8,
},
[7] = {
["CLSID"] = "{AIM-7F}",
["num"] = 9,
},
[8] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 10,
},
},
["tasks"] = {
[1] = 11,
},
},
},
["tasks"] = {
},
["unitType"] = "VSN_F104S",
}
return unitPayloads

View File

@@ -0,0 +1,189 @@
local unitPayloads = {
["name"] = "VSN_F104S_AG",
["payloads"] = {
[1] = {
["displayName"] = "DEAD",
["name"] = "DEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 2,
},
[2] = {
["CLSID"] = "{08164777-5E9C-4B08-B48E-5AA7AFB246E2}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{08164777-5E9C-4B08-B48E-5AA7AFB246E2}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{AIM-9L}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{AIM-9L}",
["num"] = 7,
},
[7] = {
["CLSID"] = "{08164777-5E9C-4B08-B48E-5AA7AFB246E2}",
["num"] = 8,
},
[8] = {
["CLSID"] = "{08164777-5E9C-4B08-B48E-5AA7AFB246E2}",
["num"] = 9,
},
[9] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 10,
},
},
["tasks"] = {
[1] = 19,
},
},
[2] = {
["displayName"] = "CAS",
["name"] = "CAS",
["pylons"] = {
[1] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 2,
},
[2] = {
["CLSID"] = "{08164777-5E9C-4B08-B48E-5AA7AFB246E2}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{08164777-5E9C-4B08-B48E-5AA7AFB246E2}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{AIM-9L}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{AIM-9L}",
["num"] = 7,
},
[7] = {
["CLSID"] = "{08164777-5E9C-4B08-B48E-5AA7AFB246E2}",
["num"] = 8,
},
[8] = {
["CLSID"] = "{08164777-5E9C-4B08-B48E-5AA7AFB246E2}",
["num"] = 9,
},
[9] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 10,
},
},
["tasks"] = {
[1] = 19,
},
},
[3] = {
["displayName"] = "STRIKE",
["name"] = "STRIKE",
["pylons"] = {
[1] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 2,
},
[2] = {
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{AIM-9L}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{AIM-9L}",
["num"] = 7,
},
[7] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 8,
},
[8] = {
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
["num"] = 9,
},
[9] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 10,
},
},
["tasks"] = {
[1] = 19,
},
},
[4] = {
["displayName"] = "OCA",
["name"] = "OCA",
["pylons"] = {
[1] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 2,
},
[2] = {
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{AIM-9L}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{AIM-9L}",
["num"] = 7,
},
[7] = {
["CLSID"] = "{7A44FF09-527C-4B7E-B42B-3F111CFE50FB}",
["num"] = 8,
},
[8] = {
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
["num"] = 9,
},
[9] = {
["CLSID"] = "{LAU-138 wtip - AIM-9L}",
["num"] = 10,
},
},
["tasks"] = {
[1] = 19,
},
},
},
["tasks"] = {
},
["unitType"] = "VSN_F104S_AG",
}
return unitPayloads

View File

@@ -47,7 +47,6 @@
"HawkGenerator", "HawkGenerator",
"RapierGenerator", "RapierGenerator",
"SA2Generator", "SA2Generator",
"SA5Generator",
"ZSU57Generator", "ZSU57Generator",
"ZSU23Generator", "ZSU23Generator",
"ZU23Generator", "ZU23Generator",

View File

@@ -25,8 +25,7 @@
"frontline_units": [ "frontline_units": [
"M113", "M113",
"M163 Vulcan Air Defense System", "M163 Vulcan Air Defense System",
"M60A3 \"Patton\"", "M60A3 \"Patton\""
"Merkava Mk IV"
], ],
"artillery_units": [], "artillery_units": [],
"logistics_units": [ "logistics_units": [
@@ -56,4 +55,4 @@
"navy_generators": [], "navy_generators": [],
"has_jtac": true, "has_jtac": true,
"jtac_unit": "MQ-9 Reaper" "jtac_unit": "MQ-9 Reaper"
} }

View File

@@ -9,6 +9,8 @@
"aircrafts": [ "aircrafts": [
"AH-1W SuperCobra", "AH-1W SuperCobra",
"AV-8B Harrier II Night Attack", "AV-8B Harrier II Night Attack",
"F-104S Starfighter",
"F-104S Starfighter A/G",
"C-130", "C-130",
"Tornado IDS", "Tornado IDS",
"UH-1H Iroquois" "UH-1H Iroquois"

View File

@@ -4,10 +4,10 @@ local WRITESTATE_SCHEDULE_IN_SECONDS = 60
logger = mist.Logger:new("DCSLiberation", "info") logger = mist.Logger:new("DCSLiberation", "info")
logger:info("Check that json.lua is loaded : json = "..tostring(json)) logger:info("Check that json.lua is loaded : json = "..tostring(json))
killed_aircrafts = {} killed_aircrafts = {} -- killed aircraft will be added via S_EVENT_CRASH event
killed_ground_units = {} killed_ground_units = {} -- killed units will be added via S_EVENT_DEAD event
base_capture_events = {} base_capture_events = {}
destroyed_objects_positions = {} destroyed_objects_positions = {} -- will be added via S_EVENT_DEAD event
mission_ended = false mission_ended = false
local function ends_with(str, ending) local function ends_with(str, ending)

View File

@@ -1,8 +1,8 @@
--- ---
name: 18th Air Refueling Squadron name: 18th Air Refueling Squadron
nickname: nickname: Kanza
country: USA country: USA
role: Air-to-Air Refueling role: Air-to-Air Refueling
aircraft: KC-135 Stratotanker aircraft: KC-135 Stratotanker
mission_types: mission_types:
- Refueling - Refueling

BIN
resources/ui/heliport.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -5,7 +5,19 @@
<br/><br/> <br/><br/>
<strong>Available aircrafts:</strong> <strong>Potential aircraft:</strong>
<p>
The aircraft that will be present in the game are specified by the campaign.
Only aircraft in this list will be allowed, but not all aircraft in this
list will necessarily be available.
</p>
<p>
If the campaign you chose doesn't include the aircraft you want to fly, you
can mod the campaign by following the squadron section of the
<a style="color: #ffffff"
href="https://github.com/dcs-liberation/dcs_liberation/wiki/Custom-Campaigns#squadron-configuration">
custom campaigns guide</a>.
</p>
<ul> <ul>
{% for aircraft in faction.aircrafts %} {% for aircraft in faction.aircrafts %}
<li>{{aircraft.name}}</li> <li>{{aircraft.name}}</li>

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,18 @@
description:
"The Lockheed F-104 Starfighter is a single-engine, supersonic interceptor aircraft\
\ which was extensively deployed as a fighter-bomber during the Cold War. Created \
\ as a day fighter by Lockheed as one of the Century Series of fighter aircraft \
\ for the United States Air Force (USAF), it was developed into an all-weather \
\ multirole aircraft in the early 1960s and produced by several other nations, \
\ seeing widespread service outside the United States. \
\ The F-104G variant was used by West German Luftwaffe and Bundesmarine \
\ as well as other NATO countries."
introduced: 1958
manufacturer: Lockheed
origin: USA
price: 9
role: Fighter-Bomber
max_range: 100
gunfighter: true
variants:
F-104G Starfighter: {}

View File

@@ -0,0 +1,17 @@
description:
"The Lockheed F-104 Starfighter is a single-engine, supersonic interceptor aircraft\
\ which was extensively deployed as a fighter-bomber during the Cold War. Created \
\ as a day fighter by Lockheed as one of the Century Series of fighter aircraft \
\ for the United States Air Force (USAF), it was developed into an all-weather \
\ multirole aircraft in the early 1960s and produced by several other nations, \
\ seeing widespread service outside the United States. \
\ The Aeritalia F-104S is a licensed production Italian version."
introduced: 1966
manufacturer: Lockheed
origin: USA
price: 9
role: Light Fighter
max_range: 100
gunfighter: true
variants:
F-104S Starfighter: {}

View File

@@ -0,0 +1,17 @@
description:
"The Lockheed F-104 Starfighter is a single-engine, supersonic interceptor aircraft\
\ which was extensively deployed as a fighter-bomber during the Cold War. Created \
\ as a day fighter by Lockheed as one of the Century Series of fighter aircraft \
\ for the United States Air Force (USAF), it was developed into an all-weather \
\ multirole aircraft in the early 1960s and produced by several other nations, \
\ seeing widespread service outside the United States. \
\ The Aeritalia F-104S is a licensed production Italian version."
introduced: 1966
manufacturer: Lockheed
origin: USA
price: 9
role: Fighter-Bomber
max_range: 100
gunfighter: true
variants:
F-104S Starfighter A/G: {}

View File

@@ -0,0 +1,5 @@
name: AN/ALQ-184 ECM
# https://www.deagel.com/Protection%20Systems/ANALQ-184/a001666
year: 1987
clsids:
- "ALQ_184"

View File

@@ -0,0 +1,7 @@
name: AN/ASQ-213 HARM Targeting System
# https://www.af.mil/About-Us/Fact-Sheets/Display/Article/104602/high-speed-anti-radiation-missile-targeting-system/
# We have the R7 pod, but since we never get older variants of things in DCS
# just pretend it's as old as the initial revision.
year: 1994
clsids:
- "{AN_ASQ_213}"