Compare commits

...

15 Commits

Author SHA1 Message Date
Dan Albert
4ef2cc26c8 Remove incompatible campaigns.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2558.
2022-11-25 15:29:49 -08:00
Starfire13
a03cfdf305 Updates Khopa's Normandy and Channel campaign to 10.0
Note that Operation Dynamo only requires a yaml file update. The .miz file is fine and is not included here.
2022-11-25 15:29:49 -08:00
Dan Albert
9777e5e432 Remove dead code. 2022-11-25 15:29:49 -08:00
Dan Albert
5f74fd81eb Unfilter the custom waypoint targets.
There doesn't appear to be any reason for us to be poking at
implementation details here aside from changing the name from "unit" to
"building" for that case. Just iterate over the known strike targets.

Making this change uncovered some latent type errors.

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

(cherry picked from commit 5e7e5e2636)
2022-11-25 14:22:11 -08:00
Dan Albert
b57e30a13c Add radios for the MB-339A.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2511.

(cherry picked from commit e208df16b2)
2022-11-25 14:15:23 -08:00
Dan Albert
789c863922 Update RoleplayingPleb's campaigns.
https://github.com/dcs-liberation/dcs_liberation/issues/2558
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2561.

(cherry picked from commit 11632b0ef1)
2022-11-25 13:15:50 -08:00
Dan Albert
3cbd4c7dd4 Make the casualty report scrollable.
Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2567.

(cherry picked from commit b0bc46f539)
2022-11-25 13:15:50 -08:00
SnappyComebacks
9d0c75d199 Add banner for MB-339A.
(cherry picked from commit 627ed45065)
2022-11-25 12:14:52 -07:00
RndName
8e63aa4d72 Remove dcs capture event from state json
With the latest change we added capture zones and corresponding trigger rules for all Airfields as well so we do not need to rely on the dcs capture event S_EVENT_BASE_CAPTURED anymore.

cherry-pick from fc9ad5b519
2022-11-24 11:29:16 +01:00
RndName
06a4dce555 Add Airfield to list of capture zone types
This will create capture zones and the trigger rules to check for a base capture. Will fix an issue where the dcs capture event is not fired and therefore the capture not recognized by liberation

cherry-pick from 40ddad1d9a
2022-11-24 11:29:16 +01:00
RndName
65a232a0c7 Fix carrier group generation
cherry-pick from eb997db703
2022-11-24 11:29:16 +01:00
MetalStormGhost
bde22b52ea Attempt at fixing Carrier killed in state.json but not being removed from game, issue #2405. GenericCarrierGenerator.generate() will now generate the ship group with an array that only contains alive ship units, just like GroundObjectGenerator.generate() has previously done.
Carrier groups will now also show up as destroyed/damaged on the map when the carrier is sunk.

cherry-pick from e53dc5b80b
2022-11-24 11:29:16 +01:00
RndName
bfed69573f Validate primary and secondary nodes for iads network
cherry-pick from ab64655f05
2022-11-21 12:23:40 +01:00
RndName
9ba717fd82 Fix IADS network error caused by dead groups
Fixed an error which would occur when dead units which are non static would be added as secondary node during the skynet lua data generation. This should in general not be possible as connection nodes and power sources are currently most of the time static.

cherry-pick from e1b530e4fc
2022-11-21 12:23:40 +01:00
SnappyComebacks
f2e8a77862 Update pydcs.
Added ice halo generation.

(cherry picked from commit 4414853e45)
2022-11-20 18:03:58 -07:00
39 changed files with 185 additions and 1513 deletions

View File

@@ -16,6 +16,7 @@ Saves from 5.x are not compatible with 6.0.
* **[Mission Generation]** Added performance option to not cull IADS when culling would affect how mission is played at target area.
* **[Mission Generation]** Reworked the ground object generation which now uses a new layout system
* **[Mission Generation]** Added information about the modulation (AM/FM) of the assigned frequencies to the kneeboard and assign AM modulation instead of FM for JTAC.
* **[Mission Generation]** Added ice halos.
* **[Mission Generation]** Adjusted wind speeds. Wind speeds at high altitude are generally higher now.
* **[Mission Generation]** Added turbulence. Higher in Summer and Winter, also higher at day time than at nighttime.
* **[Modding]** Updated UH-60L mod version support to 1.3.1

View File

@@ -1,6 +1,5 @@
from __future__ import annotations
from collections.abc import Sequence
from dataclasses import dataclass, field
from datetime import timedelta
from typing import Literal, TYPE_CHECKING
@@ -12,8 +11,7 @@ from game.theater.theatergroup import TheaterUnit
from game.utils import Distance, meters
if TYPE_CHECKING:
from game.theater import ControlPoint, MissionTarget
from game.theater import ControlPoint
AltitudeReference = Literal["BARO", "RADIO"]
@@ -32,7 +30,7 @@ class FlightWaypoint:
# having three names. A short and long form is enough.
description: str = ""
targets: Sequence[MissionTarget | TheaterUnit] = field(default_factory=list)
targets: list[TheaterUnit] = field(default_factory=list)
obj_name: str = ""
pretty_name: str = ""
only_for_player: bool = False

View File

@@ -338,9 +338,7 @@ class Debriefing:
seen = set()
captures = []
for capture in reversed(self.state_data.base_capture_events):
# The ID string in the JSON file will be an airport ID for airport captures
# but will be a UUID for all other types, since DCS doesn't know the UUIDs
# for the captured FOBs.
# The ID string in the JSON file will be the UUID generated from liberation
cp_id, new_owner_id_str, _name = capture.split("||")
# Only the most recent capture event matters.
@@ -349,13 +347,8 @@ class Debriefing:
seen.add(cp_id)
try:
control_point = self.game.theater.find_control_point_by_airport_id(
int(cp_id)
)
except ValueError:
# The CP ID could not be converted to an int, so it's a UUID.
control_point = self.game.theater.find_control_point_by_id(UUID(cp_id))
except KeyError:
except (KeyError, ValueError):
# Captured base is not a part of the campaign. This happens when neutral
# bases are near the conflict. Nothing to do.
continue

View File

@@ -1,8 +1,9 @@
import copy
from dcs import Point
from dcs.planes import B_17G, B_52H, Tu_22M3
from dcs.point import MovingPoint
from dcs.task import Bombing, OptFormation, WeaponType, Expend
from dcs.task import Bombing, Expend, OptFormation, WeaponType
from .pydcswaypointbuilder import PydcsWaypointBuilder
@@ -21,7 +22,7 @@ class StrikeIngressBuilder(PydcsWaypointBuilder):
if not targets:
return
center = copy.copy(targets[0].position)
center: Point = copy.copy(targets[0].position)
for target in targets[1:]:
center += target.position
center /= len(targets)

View File

@@ -405,7 +405,17 @@ class GenericCarrierGenerator(GroundObjectGenerator):
logging.warning(f"Found empty carrier group in {self.control_point}")
continue
ship_group = self.create_ship_group(group.group_name, group.units, atc)
ship_units = []
for unit in group.units:
if unit.alive:
# All alive Ships
ship_units.append(unit)
if not ship_units:
# No alive units in this group, continue with next group
continue
ship_group = self.create_ship_group(group.group_name, ship_units, atc)
# Always steam into the wind, even if the carrier is being moved.
# There are multiple unsimulated hours between turns, so we can
@@ -414,7 +424,7 @@ class GenericCarrierGenerator(GroundObjectGenerator):
brc = self.steam_into_wind(ship_group)
# Set Carrier Specific Options
if g_id == 0:
if g_id == 0 and self.control_point.runway_is_operational():
# Get Correct unit type for the carrier.
# This will upgrade to super carrier if option is enabled
carrier_type = self.carrier_type

View File

@@ -44,7 +44,7 @@ class Silence(Option):
class TriggerGenerator:
capture_zone_types = (Fob,)
capture_zone_types = (Fob, Airfield)
capture_zone_flag = 600
def __init__(self, mission: Mission, game: Game) -> None:

View File

@@ -6,6 +6,7 @@ import logging
import re
from dataclasses import dataclass
from typing import Dict, FrozenSet, Iterator, List, Set, Tuple
from dcs.task import Modulation
@@ -246,6 +247,51 @@ RADIOS: List[Radio] = [
),
),
Radio("UHF TRAP 137B", (RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),)),
Radio(
"AN/ARC-150(V) 2",
(
RadioRange(
MHz(225),
MHz(400),
MHz(1),
Modulation.AM,
frozenset((MHz(243),)),
),
),
),
Radio(
"SRT-651/N",
(
RadioRange(
MHz(30),
MHz(88),
MHz(1),
Modulation.FM,
frozenset((MHz(40, 500),)),
),
RadioRange(
MHz(108),
MHz(156),
MHz(1),
Modulation.AM,
frozenset((MHz(121, 500),)),
),
RadioRange(
MHz(156),
MHz(174),
MHz(1),
Modulation.FM,
frozenset((MHz(156, 800),)),
),
RadioRange(
MHz(225),
MHz(400),
MHz(1),
Modulation.AM, # Actually AM/FM, but we can't represent that.
frozenset((MHz(243),)),
),
),
),
]

View File

@@ -34,8 +34,13 @@ class IadsConnectionJs(BaseModel):
iads_connections = []
tgo = network_node.group.ground_object
for id, connection in network_node.connections.items():
if connection.ground_object.is_friendly(True) != tgo.is_friendly(True):
continue # Skip connections which are not from same coalition
if (
not connection.iads_role.is_secondary_node
or connection.ground_object.is_friendly(True) != tgo.is_friendly(True)
):
# Skip connections to non secondary nodes (for example PD)
# and connections which are not from same coalition
continue
iads_connections.append(
IadsConnectionJs(
id=id,
@@ -67,10 +72,8 @@ class IadsNetworkJs(BaseModel):
@staticmethod
def from_network(network: IadsNetwork) -> IadsNetworkJs:
iads_connections = []
for connection in network.nodes:
if not connection.group.iads_role.participate:
continue # Skip
iads_connections.extend(IadsConnectionJs.connections_for_node(connection))
for primary_node in network.nodes:
iads_connections.extend(IadsConnectionJs.connections_for_node(primary_node))
return IadsNetworkJs(
advanced=network.advanced_iads, connections=iads_connections
)

View File

@@ -1200,7 +1200,7 @@ class NavalControlPoint(ControlPoint, ABC):
# while its escorts are still alive.
for group in self.find_main_tgo().groups:
for u in group.units:
if u.type in [
if u.alive and u.type in [
Forrestal,
Stennis,
LHA_Tarawa,

View File

@@ -44,15 +44,14 @@ class SkynetNode:
IadsRole.POWER_SOURCE,
]:
# Use UnitName for EWR, CommandCenter, Comms, Power
is_dead = group.alive_units == 0
for unit in group.units:
# Check for alive units in the group
if unit.alive:
if unit.alive or (is_dead and unit.is_static):
# Return first alive unit within the group or otherwise return the
# first static object as these will still be added to the mission
return unit.unit_name
if group.units[0].is_static:
# Statics will be placed as dead unit
return group.units[0].unit_name
# If no alive unit is available and not static raise error
raise IadsNetworkException("Group has no skynet usable units")
# Raise error if there is no skynet capable unit in this group
raise IadsNetworkException(f"Group {group.name} has no skynet usable units")
else:
# Use the GroupName for SAMs, SAMAsEWR and PDs
return group.group_name
@@ -80,10 +79,10 @@ class IadsNetworkNode:
def __str__(self) -> str:
return self.group.group_name
def add_connection_for_tgo(self, tgo: TheaterGroundObject) -> None:
"""Add all possible connections for the given TGO to the node"""
def add_secondary_node(self, tgo: TheaterGroundObject) -> None:
"""Add all possible connections for the given secondary node to this node"""
for group in tgo.groups:
if isinstance(group, IadsGroundGroup) and group.iads_role.participate:
if isinstance(group, IadsGroundGroup) and group.iads_role.is_secondary_node:
self.add_connection_for_group(group)
def add_connection_for_group(self, group: IadsGroundGroup) -> None:
@@ -134,11 +133,11 @@ class IadsNetwork:
# Skip culled ground objects
continue
# HOTFIX! Skip non-static nodes with no alive units left
# Delete this as soon as PRs #2285, #2286 & #2287 are merged
unit_count = len(node.group.units)
is_static = node.group.units[0].is_static if unit_count > 0 else False
if node.group.alive_units == 0 and not is_static:
if node.group.alive_units == 0 and not node.group.has_statics:
# Skip non-static nodes with no alive units left
# Dead static nodes can be added to skynet as these are added to the
# mission as dead unit. Non static will not be added to the mission and
# are therefore not accessible by skynet
continue
# SkynetNode.from_group(node.group) may raise an exception
@@ -146,6 +145,9 @@ class IadsNetwork:
# but if it does, we want to know because it's supposed to be impossible afaict
skynet_node = SkynetNode.from_group(node.group)
for connection in node.connections.values():
if connection.alive_units == 0 and not connection.has_statics:
# Skip non static and dead connection nodes. See comment above
continue
if connection.ground_object.is_friendly(
skynet_node.player
) and not game.iads_considerate_culling(connection.ground_object):
@@ -191,34 +193,27 @@ class IadsNetwork:
for primary_node in primary_nodes:
self.update_tgo(primary_node, events)
def node_for_group(self, group: IadsGroundGroup) -> IadsNetworkNode:
"""Get existing node from the iads network or create a new node"""
for cn in self.nodes:
if cn.group == group:
return cn
node = IadsNetworkNode(group)
self.nodes.append(node)
return node
def node_for_tgo(self, tgo: TheaterGroundObject) -> Optional[IadsNetworkNode]:
"""Get existing node from the iads network or create a new node"""
"""Create Primary node for the TGO or return existing one"""
for cn in self.nodes:
if cn.group.ground_object == tgo:
return cn
return self._new_node_for_tgo(tgo)
def _new_node_for_tgo(self, tgo: TheaterGroundObject) -> Optional[IadsNetworkNode]:
# Create new connection_node if none exists
"""Create a new primary node for the given TGO.
Will return None if the given TGO is not capable of being a primary node.
This will also add any PointDefense of this TGO to the primary node"""
node: Optional[IadsNetworkNode] = None
for group in tgo.groups:
# TODO Cleanup
if isinstance(group, IadsGroundGroup):
# The first IadsGroundGroup is always the primary Group
if not node and group.iads_role.participate:
# Primary Node
node = self.node_for_group(group)
elif node and group.iads_role == IadsRole.POINT_DEFENSE:
if node is None and group.iads_role.is_primary_node:
# Create Primary Node
node = IadsNetworkNode(group)
self.nodes.append(node)
elif node is not None and group.iads_role == IadsRole.POINT_DEFENSE:
# Point Defense Node for this TGO
node.add_connection_for_group(group)
@@ -280,7 +275,13 @@ class IadsNetwork:
connections = self.iads_config[primary_node]
for secondary_node in connections:
try:
node.add_connection_for_tgo(self.ground_objects[secondary_node])
nearby_go = self.ground_objects[secondary_node]
if IadsRole.for_category(nearby_go.category).is_secondary_node:
node.add_secondary_node(nearby_go)
else:
logging.error(
f"IADS: {secondary_node} is not a valid secondary node"
)
except KeyError:
logging.exception(
f"IADS: No ground object found for connection {secondary_node}"
@@ -296,15 +297,11 @@ class IadsNetwork:
continue
nearby_iads_role = IadsRole.for_category(nearby_go.category)
if (
nearby_iads_role
in [
IadsRole.POWER_SOURCE,
IadsRole.CONNECTION_NODE,
]
nearby_iads_role.is_secondary_node
and nearby_go.position.distance_to_point(primary_tgo.position)
<= nearby_iads_role.connection_range.meters
):
node.add_connection_for_tgo(nearby_go)
node.add_secondary_node(nearby_go)
def initialize_network_from_range(self) -> None:
"""Initialize the IADS Network by range"""

View File

@@ -79,3 +79,16 @@ class IadsRole(Enum):
IadsRole.NO_BEHAVIOR,
IadsRole.POINT_DEFENSE,
]
@property
def is_primary_node(self) -> bool:
return self in [
IadsRole.SAM,
IadsRole.SAM_AS_EWR,
IadsRole.EWR,
IadsRole.COMMAND_CENTER,
]
@property
def is_secondary_node(self) -> bool:
return self in [IadsRole.CONNECTION_NODE, IadsRole.POWER_SOURCE]

View File

@@ -185,6 +185,10 @@ class TheaterGroup:
def alive_units(self) -> int:
return sum(unit.alive for unit in self.units)
@property
def has_statics(self) -> bool:
return any(unit.is_static for unit in self.units)
def max_detection_range(self) -> Distance:
"""Calculate the maximum detection range of the TheaterGroup"""
ranges = (u.detection_range for u in self.units if u.is_anti_air)

View File

@@ -7,7 +7,6 @@ from game.missiongenerator.frontlineconflictdescription import (
FrontLineConflictDescription,
)
from game.theater.controlpoint import ControlPointType
from game.theater.theatergroundobject import BuildingGroundObject, IadsGroundObject
from game.utils import Distance
from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox
@@ -81,66 +80,25 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox):
wpt.description = "Frontline"
i = add_model_item(i, model, wpt.pretty_name, wpt)
if self.include_targets:
for cp in self.game.theater.controlpoints:
if (self.include_enemy and not cp.captured) or (
self.include_friendly and cp.captured
):
for ground_object in cp.ground_objects:
if not ground_object.is_dead and isinstance(
ground_object, BuildingGroundObject
):
wpt = FlightWaypoint(
ground_object.waypoint_name,
FlightWaypointType.CUSTOM,
ground_object.position,
Distance.from_meters(0),
)
wpt.alt_type = "RADIO"
wpt.pretty_name = wpt.name
wpt.obj_name = ground_object.obj_name
wpt.targets.append(ground_object)
if cp.captured:
wpt.description = "Friendly Building"
else:
wpt.description = "Enemy Building"
i = add_model_item(i, model, wpt.pretty_name, wpt)
if self.include_units:
for cp in self.game.theater.controlpoints:
if (self.include_enemy and not cp.captured) or (
self.include_friendly and cp.captured
):
for ground_object in cp.ground_objects:
if not ground_object.is_dead and (
isinstance(ground_object, IadsGroundObject)
):
for g in ground_object.groups:
for j, u in enumerate(g.units):
wptname = (
"["
+ str(ground_object.obj_name)
+ "] : "
+ u.name
+ " #"
+ str(j)
)
wpt = FlightWaypoint(
wptname,
FlightWaypointType.CUSTOM,
u.position,
Distance.from_meters(0),
)
wpt.alt_type = "RADIO"
wpt.pretty_name = wptname
wpt.targets.append(u)
wpt.obj_name = ground_object.obj_name
wpt.waypoint_type = FlightWaypointType.CUSTOM
if cp.captured:
wpt.description = "Friendly unit: " + u.name
else:
wpt.description = "Enemy unit: " + u.name
i = add_model_item(i, model, wpt.pretty_name, wpt)
for tgo in self.game.theater.ground_objects:
for target_idx, target in enumerate(tgo.strike_targets):
wptname = f"[{tgo.obj_name}] : {target.name} #{target_idx}"
wpt = FlightWaypoint(
wptname,
FlightWaypointType.CUSTOM,
target.position,
Distance.from_meters(0),
)
wpt.alt_type = "RADIO"
wpt.pretty_name = wptname
wpt.targets.append(target)
wpt.obj_name = tgo.obj_name
wpt.waypoint_type = FlightWaypointType.CUSTOM
if tgo.is_friendly(to_player=True):
wpt.description = f"Friendly unit: {target.name}"
else:
wpt.description = f"Enemy unit: {target.name}"
i = add_model_item(i, model, wpt.pretty_name, wpt)
if self.include_airbases:
for cp in self.game.theater.controlpoints:

View File

@@ -1,71 +0,0 @@
from PySide2.QtGui import QStandardItem, QStandardItemModel
from game import Game
from game.theater import SamGroundObject
from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox
class StrikeTargetInfo:
def __init__(self):
self.name = ""
self.location = None
self.units = []
self.buildings = []
class QStrikeTargetSelectionComboBox(QFilteredComboBox):
def __init__(self, game: Game, parent=None):
super(QStrikeTargetSelectionComboBox, self).__init__(parent)
self.game = game
self.find_possible_strike_targets()
for t in self.targets:
print(t.name + " - " + str(len(t.units)) + " " + str(len(t.buildings)))
def get_selected_target(self) -> StrikeTargetInfo:
n = self.currentText()
for target in self.targets:
if target.name == n:
return target
def find_possible_strike_targets(self):
self.targets = []
i = 0
model = QStandardItemModel()
def add_model_item(i, model, target):
item = QStandardItem(target.name)
model.setItem(i, 0, item)
self.targets.append(target)
return i + 1
for cp in self.game.theater.controlpoints:
if cp.captured:
continue
added_obj_names = []
for g in cp.ground_objects:
if g.obj_name in added_obj_names:
continue
target = StrikeTargetInfo()
target.location = g
target.name = g.obj_name
if isinstance(g, SamGroundObject):
target.name = g.obj_name + " [units]"
for group in g.groups:
for u in group.units:
target.units.append(u)
else:
target.name = g.obj_name + " [" + g.category + "]"
for g2 in cp.ground_objects:
if g2 is not g and g2.obj_name == g.obj_name:
target.buildings.append(g2)
i = add_model_item(i, model, target)
added_obj_names.append(g.obj_name)
self.setModel(model)

View File

@@ -1,73 +0,0 @@
import random
from PySide2.QtGui import QStandardItemModel, QStandardItem
from PySide2.QtWidgets import (
QGroupBox,
QLabel,
QWidget,
QVBoxLayout,
QListView,
QAbstractItemView,
)
from qt_ui.widgets.combos.QStrikeTargetSelectionComboBox import StrikeTargetInfo
class QStrikeTargetInfoView(QGroupBox):
"""
UI Component to display info about a strike target
"""
def __init__(self, strike_target_infos: StrikeTargetInfo):
if strike_target_infos is None:
strike_target_infos = StrikeTargetInfo()
super(QStrikeTargetInfoView, self).__init__(
"Target : " + strike_target_infos.name
)
self.strike_target_infos = strike_target_infos
self.listView = QListView()
self.init_ui()
def init_ui(self):
layout = QVBoxLayout(self)
layout.setSpacing(0)
layout.addWidget(self.listView)
self.setLayout(layout)
def setTarget(self, target):
self.setTitle(target.name)
self.strike_target_infos = target
model = QStandardItemModel()
self.listView.setSelectionMode(QAbstractItemView.NoSelection)
if len(self.strike_target_infos.units) > 0:
dic = {}
for u in self.strike_target_infos.units:
if u.type.id in dic.keys():
dic[u.type.id] = dic[u.type.id] + 1
else:
dic[u.type.id] = 1
for k, v in dic.items():
model.appendRow(QStandardItem(k + " x " + str(v)))
print(k + " x " + str(v))
else:
dic = {}
for b in self.strike_target_infos.buildings:
id = b.dcs_identifier
if b.is_dead:
id = id + "[Destroyed]"
if id in dic.keys():
dic[id] = dic[id] + 1
else:
dic[id] = 1
for k, v in dic.items():
model.appendRow(QStandardItem(k + " x " + str(v)))
print(k + " x " + str(v))
self.listView.setModel(model)

View File

@@ -8,12 +8,13 @@ from PySide2.QtWidgets import (
QGroupBox,
QLabel,
QPushButton,
QScrollArea,
QVBoxLayout,
QWidget,
)
from game.debriefing import Debriefing
T = TypeVar("T")
@@ -52,6 +53,19 @@ class LossGrid(QGridLayout):
self.addWidget(QLabel(str(count)), row, 1)
class ScrollingCasualtyReportContainer(QGroupBox):
def __init__(self, debriefing: Debriefing, player: bool) -> None:
country = debriefing.player_country if player else debriefing.enemy_country
super().__init__(f"{country}'s lost units:")
scroll_content = QWidget()
scroll_content.setLayout(LossGrid(debriefing, player))
scroll_area = QScrollArea()
scroll_area.setWidget(scroll_content)
layout = QVBoxLayout()
layout.addWidget(scroll_area)
self.setLayout(layout)
class QDebriefingWindow(QDialog):
def __init__(self, debriefing: Debriefing):
super(QDebriefingWindow, self).__init__()
@@ -75,12 +89,10 @@ class QDebriefingWindow(QDialog):
title = QLabel("<b>Casualty report</b>")
layout.addWidget(title)
player_lost_units = QGroupBox(f"{self.debriefing.player_country}'s lost units:")
player_lost_units.setLayout(LossGrid(debriefing, player=True))
player_lost_units = ScrollingCasualtyReportContainer(debriefing, player=True)
layout.addWidget(player_lost_units)
enemy_lost_units = QGroupBox(f"{self.debriefing.enemy_country}'s lost units:")
enemy_lost_units.setLayout(LossGrid(debriefing, player=False))
enemy_lost_units = ScrollingCasualtyReportContainer(debriefing, player=False)
layout.addWidget(enemy_lost_units)
okay = QPushButton("Okay")

View File

@@ -32,7 +32,7 @@ pluggy==1.0.0
pre-commit==2.19.0
py==1.11.0
pydantic==1.9.1
-e git+https://github.com/pydcs/dcs@324e4471eb32af69eee8c103ad5260fe1ba13ba9#egg=pydcs
-e git+https://github.com/pydcs/dcs@f12d70ea844076f95c74ffab92ec3dc9fdee32e4#egg=pydcs
pyinstaller==5.2
pyinstaller-hooks-contrib==2022.8
pyparsing==3.0.9

View File

@@ -1,323 +0,0 @@
---
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

View File

@@ -1,185 +0,0 @@
---
name: Caucasus - Muti-Part Georgia
theater: Caucasus
authors: Doc_of_Mur
description: <p><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: Georgia 2008
recommended_start_date: 1995-06-13
miz: Caucasus_Multi_Georgia.miz
performance: 2
version: "9.1"
squadrons:
# Kutaisi
22:
- primary: Refueling
aircraft:
- KC-135 Stratotanker MPRS
- primary: Refueling
aircraft:
- KC-135 Stratotanker
- primary: AEW&C
aircraft:
- E-3A
- primary: Transport
secondary: any
aircraft:
- C-130
- primary: Strike
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: BAI
secondary: air-to-ground
aircraft:
- AH-64D Apache Longbow
- primary: BAI
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
- primary: BAI
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 3)
- primary: BARCAP
secondary: any
aircraft:
- JF-17 Thunder
- primary: BARCAP
aircraft:
- MiG-23MLD Flogger-K
- primary: BAI
secondary: air-to-ground
aircraft:
- Ka-50 Hokum
- primary: Strike
secondary: any
aircraft:
- AJS-37 Viggen
- primary: Strike
secondary: any
aircraft:
- Mirage 2000C
- primary: CAS
secondary: air-to-ground
aircraft:
- UH-1H Iroquois
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
# Kobuleti
24:
- primary: BARCAP
aircraft:
- L-39ZA Albatros
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
# Senaki-Kolkhi
23:
- primary: BARCAP
aircraft:
- L-39ZA Albatros
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- primary: CAS
secondary: air-to-ground
aircraft:
- UH-1H Iroquois
# Kataisi
25:
- primary: BARCAP
aircraft:
- L-39ZA Albatros
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
# Sukhumi-Babushara
20:
- primary: BARCAP
aircraft:
- L-39ZA Albatros
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
# Gudauta
21:
- primary: BARCAP
aircraft:
- L-39ZA Albatros
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
- primary: BAI
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- primary: Strike
secondary: air-to-ground
aircraft:
- Su-25 Frogfoot
- primary: OCA/Runway
secondary: air-to-ground
aircraft:
- Su-25 Frogfoot
Blue CV:
- 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
- primary: AEW&C
aircraft:
- E-2C Hawkeye
Blue LHA:
- primary: BAI
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack

View File

@@ -1,269 +0,0 @@
---
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

View File

@@ -1,162 +0,0 @@
---
name: Syria - Task Force Thunder
theater: Syria
authors: Sith1144
description: <p>A campaign based on the campaign from Combat Mission Shock Force. US forces attempt to bisect the country by advancing towards Homs from Iraq in the east and an amphibious landing near Tartus in the west. Recommended starting budge 3000-4000M for REDFOR, 2000-5000M for BLUFOR. Cannot be inverted. NOTE; the marine landing in the west does NOT have a workshop and cannot produce new units, nor does the first enemy airfield in the area. How many resources you pour into it is up to you.</p>
recommended_player_faction: USA 2005
recommended_enemy_faction: Syria 2011
recommended_start_date: 2009-06-19
miz: Task Force Thunder.miz
performance: 3
version: "9.1"
squadrons:
# Airspawn from Iraq
Al Asad Airbase:
- primary: AEW&C
aircraft:
- E-3A
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-15C Eagle
- primary: Strike
secondary: air-to-ground
aircraft:
- B-1B Lancer
- B-52H Stratofortress
- F-117A Nighthawk
- primary: Refueling
aircraft:
- KC-135 Stratotanker MPRS
#H3 airbase
53:
- primary: SEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: DEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: BAI
secondary: air-to-ground
aircraft:
- F-15E Strike Eagle
#H4 airbase
12:
- primary: CAS
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 3)
- primary: CAS
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
#Northern FOB
Staging Point Alpha:
- primary: CAS
aircraft:
- AH-64D Apache Longbow
#Carrier is called Naval-1
Naval-1:
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-14B Tomcat
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-14B Tomcat
- primary: Strike
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
- primary: SEAD
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
- primary: Refueling
aircraft:
- S-3B Tanker
- primary: AEW&C
aircraft:
- E-2C Hawkeye
#LHA is called Naval-2
Naval-2:
- primary: CAS
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack
- primary: CAS
aircraft:
- AH-1W SuperCobra
- UH-1H Iroquois
# Al Qusayr - opposing the beach landing with old fighters (mig-23), CAS (su-17), helicopters (mi-24)
3:
- primary: BARCAP
secondary: any
aircraft:
- MiG-23MLD Flogger-K
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24V Hind-E
- primary: CAS
secondary: air-to-ground
aircraft:
- Su-17M4 Fitter-K
# Tiyas - secondary base for good fighters (mig-25) and trainers (L-39)
39:
- primary: BARCAP
secondary: air-to-air
aircraft:
- MiG-25PD Foxbat-E
- primary: Strike
secondary: air-to-ground
aircraft:
- L-39ZA Albatros
- primary: BARCAP
secondary: air-to-air
aircraft:
- MiG-29S Fulcrum-C
# Palmyra - forward base, helicopters (mi-24, mi-8), old fighters (mig-21) and cas (su-17)
28:
- primary: BARCAP
secondary: any
aircraft:
- MiG-21bis Fishbed-N
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- Su-17M4 Fitter-K
- primary: CAS
secondary: air-to-ground
aircraft:
- Su-17M4 Fitter-K
- primary: Transport
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
# Shayrat - main base for support planes (A-50, transport, tanker), strike craft (su-24) and modern fighters (mig-29)
36:
- primary: BARCAP
secondary: air-to-air
aircraft:
- MiG-29S Fulcrum-C
- primary: Strike
secondary: air-to-ground
aircraft:
- Su-24M Fencer-D
- primary: Refueling
aircraft:
- IL-78M
- primary: Transport
aircraft:
- IL-76MD
# Defensive Line FARP for gazelles
Defensive Line:
- primary: CAS
aircraft:
- SA 342M Gazelle

View File

@@ -8,7 +8,7 @@ recommended_enemy_faction: Germany 1944
recommended_start_date: 1944-07-04
miz: caen_to_evreux.miz
performance: 1
version: "9.0"
version: "10.0"
squadrons:
# Evreux
26:

View File

@@ -1,103 +0,0 @@
---
name: Marianas - Guam - Mount Barrigada
theater: MarianaIslands
authors: Ghosti
description: <p>The objective of this campaign is the capture of Guam. Blue side, having landed their forces on the beaches of Agat, controls Antonio B. Won Pat airfield and are pushing towards the enemy stronghold of Mount Barrigada.</p>
miz: marianas_guam_barrigada.miz
performance: 2
version: "9.0"
squadrons:
Blue CV:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: any
- primary: Refueling
- primary: Strike
secondary: any
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
- primary: AEW&C
Blue LHA:
- primary: Strike
secondary: any
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
Red CV:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: any
- primary: Refueling
- primary: Strike
secondary: any
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
- primary: AEW&C
Red LHA:
- primary: Strike
secondary: any
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
# Andersen AFB
6:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: air-to-air
- primary: Strike
secondary: any
- primary: Anti-ship
secondary: any
- primary: BAI
secondary: any
- primary: CAS
secondary: air-to-ground
- primary: AEW&C
- primary: Refueling
- primary: Transport
# Antonio B. Won Pat Intl
4:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: air-to-air
- primary: Strike
secondary: any
- primary: Anti-ship
secondary: any
- primary: BAI
secondary: any
- primary: CAS
secondary: any
- primary: CAS
secondary: air-to-ground
- primary: AEW&C
- primary: Refueling
- primary: Transport
Andersen AFB Northwest Field:
- primary: Strike
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
Orote Point:
- primary: Strike
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground

View File

@@ -1,103 +0,0 @@
---
name: Marianas - Guam - Landing at Agat
theater: MarianaIslands
authors: Ghosti
description: <p>The objective of this campaign is the capture of Guam. Blue side, having landed their forces on the beaches of Agat, are pushing inland. <strong>Note:</strong> This campaign requires a carrier-capable (or LHA-capable) BLUFOR faction to be able to field aircraft.</p>
miz: marianas_guam_landing_at_agat.miz
performance: 2
version: "9.0"
squadrons:
Blue CV:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: any
- primary: Refueling
- primary: Strike
secondary: any
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
- primary: AEW&C
Blue LHA:
- primary: Strike
secondary: any
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
Red CV:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: any
- primary: Refueling
- primary: Strike
secondary: any
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
- primary: AEW&C
Red LHA:
- primary: Strike
secondary: any
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
# Andersen AFB
6:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: air-to-air
- primary: Strike
secondary: any
- primary: Anti-ship
secondary: any
- primary: BAI
secondary: any
- primary: CAS
secondary: air-to-ground
- primary: AEW&C
- primary: Refueling
- primary: Transport
# Antonio B. Won Pat Intl
4:
- primary: BARCAP
secondary: air-to-air
- primary: BARCAP
secondary: air-to-air
- primary: Strike
secondary: any
- primary: Anti-ship
secondary: any
- primary: BAI
secondary: any
- primary: CAS
secondary: any
- primary: CAS
secondary: air-to-ground
- primary: AEW&C
- primary: Refueling
- primary: Transport
Andersen AFB Northwest Field:
- primary: Strike
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground
Orote Point:
- primary: Strike
secondary: air-to-ground
- primary: BAI
secondary: air-to-ground
- primary: CAS
secondary: air-to-ground

View File

@@ -1,84 +0,0 @@
name: Caucasus - Mozdok to Maykop
theater: Caucasus
authors: Khopa
recommended_player_faction: Russia 2010
recommended_enemy_faction: USA 1990
description: <p>A small theater in Russia, progress from Mozdok to Maykop.</p><p>This scenario is pretty simple, and is ideal if you want to run a short campaign to try liberation. If your PC is not powerful, this is also the less performance heavy scenario.</p>
miz: mozdok_to_maykop.miz
performance: 0
version: 9.0
squadrons:
# Mozdok
28:
- primary: BARCAP
secondary: air-to-air
aircraft:
- Su-27 Flanker-B
- primary: BARCAP
secondary: any
aircraft:
- MiG-29S Fulcrum-C
- primary: SEAD
secondary: air-to-ground
aircraft:
- Su-25T Frogfoot
- primary: Strike
aircraft:
- Tu-160 Blackjack
- primary: AEW&C
aircraft:
- A-50
- primary: Refueling
aircraft:
- IL-78M
- primary: Transport
aircraft:
- IL-76MD
# Cherkessk FARP
Zarechnoe FARP:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
- Mi-24V Hind-E
- primary: CAS
secondary: air-to-ground
aircraft:
- Ka-50 Hokum
# Mineralvodye
26:
- primary: BARCAP
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
- primary: CAS
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack
# Cherkessk FARP
Cherkessk FARP:
- primary: CAS
secondary: air-to-ground
aircraft:
- AH-64A Apache
# Maykop
16:
- primary: BARCAP
secondary: any
aircraft:
- F-15C Eagle
- primary: BARCAP
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
- primary: Strike
aircraft:
- B-52H Stratofortress
- primary: CAS
secondary: air-to-ground
aircraft:
- A-10A Thunderbolt II
- primary: AEW&C
aircraft:
- E-2C Hawkeye

View File

@@ -8,7 +8,7 @@ recommended_enemy_faction: Russia 1975
recommended_start_date: 1995-06-13
miz: northern_russia.miz
performance: 2
version: "9.1"
version: "10.5"
squadrons:
# Kutaisi
25:

View File

@@ -6,7 +6,7 @@ recommended_enemy_faction: "Germany 1940"
description: "<p>The Battle of Dunkirk (French: Bataille de Dunkerque) was fought around the French port of Dunkirk (Dunkerque) during the Second World War, between the Allies and Nazi Germany. As the Allies were losing the Battle of France on the Western Front, the Battle of Dunkirk was the defence and evacuation of British and other Allied forces to Britain from 26 May to 4 June 1940..</p>"
miz: "operation_dynamo.miz"
performance: 1
version: "9.0"
version: "10.0"
squadrons:
# Manston
5:

View File

@@ -8,7 +8,7 @@ recommended_enemy_faction: Syria 2012'ish
recommended_start_date: 2012-06-05
miz: syria_full_map.miz
performance: 3
version: "9.1"
version: "10.5"
squadrons:
# Incirlik
16:

View File

@@ -160,11 +160,6 @@ local function onEvent(event)
write_state()
end
if event.id == world.event.S_EVENT_BASE_CAPTURED and event.place then
base_capture_events[#base_capture_events + 1] = event.place.getID(event.place) .. "||" .. event.place.getCoalition(event.place) .. "||" .. event.place.getName(event.place)
write_state()
end
if event.id == world.event.S_EVENT_MISSION_END then
mission_ended = true
write_state()

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -6,3 +6,17 @@ role: Light Attack
max_range: 200
variants:
MB-339A: {}
radios:
intra_flight: SRT-651/N
inter_flight: AN/ARC-150(V) 2
channels:
# The common allocator is sufficient for Liberation's purposes. There are
# more than 20 channels available on COMM2 (manual says 100, ME says 30,
# presumably only 30 can be truly *pre* set, and the other 70 can be set in
# the cockpit). We never need that many though, so no sense customizing
# further.
type: common
# COMM1 us UHF only. COMM2 is V/UHF. We prefer allocating intra-flight on
# VHF because it's less contested, so intra-flight goes to COMM2.
intra_flight_radio_index: 2
inter_flight_radio_index: 1