mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Compare commits
37 Commits
develop-6.
...
6.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
440fe2e019 | ||
|
|
c82bc1c211 | ||
|
|
f855d2956c | ||
|
|
24aebf5ff6 | ||
|
|
8004dccdb2 | ||
|
|
7e7cb4f0bc | ||
|
|
801e3afb98 | ||
|
|
48ea33611d | ||
|
|
7b588c5437 | ||
|
|
e85b1a3195 | ||
|
|
8132b9a080 | ||
|
|
8e0cf2284b | ||
|
|
87405ba58a | ||
|
|
0952cf4c75 | ||
|
|
5bf5b41f2d | ||
|
|
715c60583a | ||
|
|
5dcd1e9360 | ||
|
|
ef7978e887 | ||
|
|
8cfb1790b2 | ||
|
|
41203b9bed | ||
|
|
50fb1f5d97 | ||
|
|
e041fa3c70 | ||
|
|
f358c1c0b2 | ||
|
|
a18dbe0a72 | ||
|
|
00e7a1fe55 | ||
|
|
b664a8cac5 | ||
|
|
2c4678aa48 | ||
|
|
eafc70a5e5 | ||
|
|
7fb1d25887 | ||
|
|
d9491c47b8 | ||
|
|
2c26f366a8 | ||
|
|
c30636b4d2 | ||
|
|
a3a91c5771 | ||
|
|
3d64619481 | ||
|
|
3b97f7a2ba | ||
|
|
6779ee96be | ||
|
|
d9134650dc |
76
.gitattributes
vendored
76
.gitattributes
vendored
@@ -14,3 +14,79 @@
|
||||
*.pyo binary export-ignore
|
||||
*.pyd binary
|
||||
unshipped_data/arcgis_maps/ filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
# https://github.com/alexkaratarakis/gitattributes/blob/master/Common.gitattributes
|
||||
# Documents
|
||||
*.bibtex text diff=bibtex
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
*.md text diff=markdown
|
||||
*.mdx text diff=markdown
|
||||
*.tex text diff=tex
|
||||
*.adoc text
|
||||
*.textile text
|
||||
*.mustache text
|
||||
*.csv text
|
||||
*.tab text
|
||||
*.tsv text
|
||||
*.txt text
|
||||
*.sql text
|
||||
*.epub diff=astextplain
|
||||
|
||||
# Graphics
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.gif binary
|
||||
*.tif binary
|
||||
*.tiff binary
|
||||
*.ico binary
|
||||
# SVG treated as text by default.
|
||||
*.svg text
|
||||
# If you want to treat it as binary,
|
||||
# use the following line instead.
|
||||
# *.svg binary
|
||||
*.eps binary
|
||||
|
||||
# Scripts
|
||||
*.bash text eol=lf
|
||||
*.fish text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.zsh text eol=lf
|
||||
# These are explicitly windows files and should use crlf
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
*.ps1 text eol=crlf
|
||||
|
||||
# Serialisation
|
||||
*.json text
|
||||
*.toml text
|
||||
*.xml text
|
||||
*.yaml text
|
||||
*.yml text
|
||||
|
||||
# Archives
|
||||
*.7z binary
|
||||
*.gz binary
|
||||
*.tar binary
|
||||
*.tgz binary
|
||||
*.zip binary
|
||||
|
||||
# Text files where line endings should be preserved
|
||||
*.patch -text
|
||||
|
||||
#
|
||||
# Exclude files from exporting
|
||||
#
|
||||
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.gitkeep export-ignore
|
||||
25
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
25
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -31,12 +31,13 @@ body:
|
||||
If the bug was found in a development build, select "Development build"
|
||||
and provide a link to the build in the field below.
|
||||
options:
|
||||
- 5.2.0
|
||||
- 6.0.0
|
||||
- Development build
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Build information
|
||||
description: The build information from the Help -> Report an issue window.
|
||||
description:
|
||||
The build information from the Help -> Report an issue window.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
@@ -52,18 +53,17 @@ body:
|
||||
description: >
|
||||
Attach any files needed to reproduce the bug here. **A save game is
|
||||
required.** We typically cannot help without a save game (the
|
||||
`.liberation` file found in
|
||||
`%USERPROFILE%/Saved Games/DCS/Liberation/Saves`), so most bugs filed
|
||||
without saved games will be closed without investigation.
|
||||
`.liberation` file found in `%USERPROFILE%/Saved
|
||||
Games/DCS/Liberation/Saves`), so most bugs filed without saved games
|
||||
will be closed without investigation.
|
||||
|
||||
|
||||
Other useful files to include are:
|
||||
|
||||
|
||||
The Liberation log file. The log file is located at
|
||||
`<Liberation install directory>/logs/liberation.log`. The log often
|
||||
includes data about non-fatal errors that could be the root cause of the
|
||||
problem.
|
||||
The Liberation log file. The log file is located at `<Liberation install
|
||||
directory>/logs/liberation.log`. The log often includes data about
|
||||
non-fatal errors that could be the root cause of the problem.
|
||||
|
||||
|
||||
The `liberation_nextturn.miz` or a track file. This should always be
|
||||
@@ -73,11 +73,12 @@ body:
|
||||
|
||||
The `state.json` file for the most recently completed turn, located at
|
||||
`<Liberation install directory>/state.json`. This file is essential for
|
||||
investigating any issues with end-of-turn results processing.
|
||||
investigating any issues with end-of-turn results processing. **If you
|
||||
include this file, also include `last_turn.liberation`.**
|
||||
|
||||
|
||||
You can attach files to the bug by dragging and dropping the file
|
||||
into this text box. GitHub will not allow uploads of all file types, so
|
||||
You can attach files to the bug by dragging and dropping the file into
|
||||
this text box. GitHub will not allow uploads of all file types, so
|
||||
attach a zip of the files if needed.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
21
.github/ISSUE_TEMPLATE/new-game-bug.yml
vendored
21
.github/ISSUE_TEMPLATE/new-game-bug.yml
vendored
@@ -39,12 +39,13 @@ body:
|
||||
If the bug was found in a development build, select "Development build"
|
||||
and provide a link to the build in the field below.
|
||||
options:
|
||||
- 5.2.0
|
||||
- 6.0.0
|
||||
- Development build
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Build information
|
||||
description: The build information from the Help -> Report an issue window.
|
||||
description:
|
||||
The build information from the Help -> Report an issue window.
|
||||
- type: input
|
||||
attributes:
|
||||
label: Campaign name
|
||||
@@ -59,8 +60,8 @@ body:
|
||||
label: Blue faction
|
||||
description: >
|
||||
The name of the blue faction you selected. If the bug only occurs with a
|
||||
custom faction (or modifications to a stock faction), upload the
|
||||
faction file as an attachment to the bug description field.
|
||||
custom faction (or modifications to a stock faction), upload the faction
|
||||
file as an attachment to the bug description field.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
@@ -68,8 +69,8 @@ body:
|
||||
label: Red faction
|
||||
description: >
|
||||
The name of the red faction you selected. If the bug only occurs with a
|
||||
custom faction (or modifications to a stock faction), upload the
|
||||
faction file as an attachment to the bug description field.
|
||||
custom faction (or modifications to a stock faction), upload the faction
|
||||
file as an attachment to the bug description field.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
@@ -102,11 +103,11 @@ body:
|
||||
attributes:
|
||||
label: Log file
|
||||
description: >
|
||||
Attach the Liberation log file. The log file is located at
|
||||
`<Liberation install directory>/logs/liberation.log`.
|
||||
Attach the Liberation log file. The log file is located at `<Liberation
|
||||
install directory>/logs/liberation.log`.
|
||||
|
||||
|
||||
You can attach files to the bug by dragging and dropping the file
|
||||
into this text box.
|
||||
You can attach files to the bug by dragging and dropping the file into
|
||||
this text box.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
24
changelog.md
24
changelog.md
@@ -1,3 +1,27 @@
|
||||
# 6.1.0
|
||||
|
||||
Saves from 6.0.0 are compatible with 6.1.0
|
||||
|
||||
## Features/Improvements
|
||||
|
||||
* **[Engine]** Support for DCS 2.8.1.34437, including Blackshark 3.
|
||||
* **[Factions]** Defaulted bluefor modern to use Georgian and Ukrainian liveries for Russian aircraft.
|
||||
* **[Factions]** Added Peru.
|
||||
* **[Flight Planning]** AEW&C and Refueling flights are now plannable on LHA carriers.
|
||||
* **[Flight Planning]** Refueling flights planned on aircraft carriers will act as a recovery tanker for the carrier.
|
||||
* **[Loadouts]** Adjusted F-15E loadouts.
|
||||
* **[Mission Generation]** The previous turn will now be saved as last_turn.liberation when submitting mission results. This is often essential for debugging bug reports. **Include this file in the bug report whenever it is available.**
|
||||
* **[Modding]** Added support for the HMS Ariadne, Achilles, and Castle class.
|
||||
* **[Modding]** Added HMS Invincible to the game data as a helicopter carrier.
|
||||
|
||||
## Fixes
|
||||
|
||||
* **[Flight Planning]** Fixes CAS flights not having landing waypoints.
|
||||
* **[Mission Generation]** Airbase and FOB capture is no longer blocked by grounded aircraft / helicopters.
|
||||
* **[Squadrons]** Fixed the livery for the VF-33 F-14A squadron.
|
||||
* **[Theaters]** Fixed Channel campaigns not having data for land/sea/obstacle boundaries, causing front lines to extend into forests and water. Requires a new campaign to get the fix.
|
||||
* **[UI]** Fixed an issue where manual submit of mission results did not end the mission correctly.
|
||||
|
||||
# 6.0.0
|
||||
|
||||
Saves from 5.x are not compatible with 6.0.
|
||||
|
||||
@@ -10,6 +10,7 @@ from dcs.helicopters import (
|
||||
CH_47D,
|
||||
CH_53E,
|
||||
Ka_50,
|
||||
Ka_50_3,
|
||||
Mi_24P,
|
||||
Mi_24V,
|
||||
Mi_26,
|
||||
@@ -237,6 +238,7 @@ CAS_CAPABLE = [
|
||||
OH_58D,
|
||||
SA342M,
|
||||
SA342L,
|
||||
Ka_50_3,
|
||||
Ka_50,
|
||||
Mi_28N,
|
||||
Mi_24P,
|
||||
@@ -308,6 +310,7 @@ SEAD_CAPABLE = [
|
||||
# Aircraft used for DEAD tasks. Must be capable of the CAS DCS task.
|
||||
DEAD_CAPABLE = SEAD_CAPABLE + [
|
||||
AJS37,
|
||||
F_15E,
|
||||
F_14B,
|
||||
F_14A_135_GR,
|
||||
JAS39Gripen_AG,
|
||||
|
||||
@@ -29,7 +29,7 @@ class CasLayout(PatrollingLayout):
|
||||
yield self.target
|
||||
yield self.patrol_end
|
||||
yield from self.nav_from
|
||||
yield self.departure
|
||||
yield self.arrival
|
||||
if self.divert is not None:
|
||||
yield self.divert
|
||||
yield self.bullseye
|
||||
|
||||
@@ -3,6 +3,8 @@ from __future__ import annotations
|
||||
from typing import Any, TYPE_CHECKING, Type
|
||||
|
||||
from game.ato import FlightType
|
||||
from game.theater.controlpoint import NavalControlPoint
|
||||
from game.theater.frontline import FrontLine
|
||||
from .aewc import AewcFlightPlan
|
||||
from .airassault import AirAssaultFlightPlan
|
||||
from .airlift import AirliftFlightPlan
|
||||
@@ -19,6 +21,7 @@ from .ocarunway import OcaRunwayFlightPlan
|
||||
from .packagerefueling import PackageRefuelingFlightPlan
|
||||
from .planningerror import PlanningError
|
||||
from .sead import SeadFlightPlan
|
||||
from .shiprecoverytanker import RecoveryTankerFlightPlan
|
||||
from .strike import StrikeFlightPlan
|
||||
from .sweep import SweepFlightPlan
|
||||
from .tarcap import TarCapFlightPlan
|
||||
@@ -26,15 +29,19 @@ from .theaterrefueling import TheaterRefuelingFlightPlan
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.ato import Flight
|
||||
from game.theater import FrontLine
|
||||
|
||||
|
||||
class FlightPlanBuilderTypes:
|
||||
@staticmethod
|
||||
def for_flight(flight: Flight) -> Type[IBuilder[Any, Any]]:
|
||||
if flight.flight_type is FlightType.REFUELING:
|
||||
if flight.package.target.is_friendly(flight.squadron.player) or isinstance(
|
||||
flight.package.target, FrontLine
|
||||
target = flight.package.target
|
||||
if target.is_friendly(flight.squadron.player) and isinstance(
|
||||
target, NavalControlPoint
|
||||
):
|
||||
return RecoveryTankerFlightPlan.builder_type()
|
||||
if target.is_friendly(flight.squadron.player) or isinstance(
|
||||
target, FrontLine
|
||||
):
|
||||
return TheaterRefuelingFlightPlan.builder_type()
|
||||
return PackageRefuelingFlightPlan.builder_type()
|
||||
|
||||
91
game/ato/flightplans/shiprecoverytanker.py
Normal file
91
game/ato/flightplans/shiprecoverytanker.py
Normal file
@@ -0,0 +1,91 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from typing import Iterator, Type
|
||||
from game.ato.flightplans.standard import StandardFlightPlan, StandardLayout
|
||||
from game.ato.flightplans.ibuilder import IBuilder
|
||||
from game.ato.flightplans.standard import StandardLayout
|
||||
from game.ato.flightplans.waypointbuilder import WaypointBuilder
|
||||
from game.ato.flightwaypoint import FlightWaypoint
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class RecoveryTankerLayout(StandardLayout):
|
||||
nav_to: list[FlightWaypoint]
|
||||
recovery_ship: FlightWaypoint
|
||||
nav_from: list[FlightWaypoint]
|
||||
|
||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||
yield self.departure
|
||||
yield from self.nav_to
|
||||
yield self.recovery_ship
|
||||
yield from self.nav_from
|
||||
yield self.arrival
|
||||
if self.divert is not None:
|
||||
yield self.divert
|
||||
yield self.bullseye
|
||||
|
||||
|
||||
class RecoveryTankerFlightPlan(StandardFlightPlan[RecoveryTankerLayout]):
|
||||
@staticmethod
|
||||
def builder_type() -> Type[Builder]:
|
||||
return Builder
|
||||
|
||||
@property
|
||||
def tot_waypoint(self) -> FlightWaypoint:
|
||||
return self.layout.recovery_ship
|
||||
|
||||
@property
|
||||
def mission_departure_time(self) -> timedelta:
|
||||
return self.patrol_end_time
|
||||
|
||||
@property
|
||||
def patrol_start_time(self) -> timedelta:
|
||||
return self.package.time_over_target
|
||||
|
||||
@property
|
||||
def patrol_end_time(self) -> timedelta:
|
||||
return self.tot + timedelta(hours=2)
|
||||
|
||||
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> timedelta | None:
|
||||
if waypoint == self.tot_waypoint:
|
||||
return self.tot
|
||||
return None
|
||||
|
||||
def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> timedelta | None:
|
||||
if waypoint == self.tot_waypoint:
|
||||
return self.mission_departure_time
|
||||
return None
|
||||
|
||||
|
||||
class Builder(IBuilder[RecoveryTankerFlightPlan, RecoveryTankerLayout]):
|
||||
def layout(self) -> RecoveryTankerLayout:
|
||||
|
||||
builder = WaypointBuilder(self.flight, self.coalition)
|
||||
|
||||
# TODO: Propagate the ship position to the Tanker's TOT,
|
||||
# so that we minimize the tanker's need to catch up to the carrier.
|
||||
recovery_ship = self.package.target.position
|
||||
recovery_tanker = builder.recovery_tanker(recovery_ship)
|
||||
|
||||
# We don't have per aircraft cruise altitudes, so just reuse patrol altitude?
|
||||
tanker_type = self.flight.unit_type
|
||||
nav_cruise_altitude = tanker_type.preferred_patrol_altitude
|
||||
|
||||
return RecoveryTankerLayout(
|
||||
departure=builder.takeoff(self.flight.departure),
|
||||
nav_to=builder.nav_path(
|
||||
self.flight.departure.position, recovery_ship, nav_cruise_altitude
|
||||
),
|
||||
nav_from=builder.nav_path(
|
||||
recovery_ship, self.flight.arrival.position, nav_cruise_altitude
|
||||
),
|
||||
recovery_ship=recovery_tanker,
|
||||
arrival=builder.land(self.flight.arrival),
|
||||
divert=builder.divert(self.flight.divert),
|
||||
bullseye=builder.bullseye(),
|
||||
)
|
||||
|
||||
def build(self) -> RecoveryTankerFlightPlan:
|
||||
return RecoveryTankerFlightPlan(self.flight, self.layout())
|
||||
@@ -23,7 +23,7 @@ from game.theater import (
|
||||
TheaterGroundObject,
|
||||
TheaterUnit,
|
||||
)
|
||||
from game.utils import Distance, meters, nautical_miles
|
||||
from game.utils import Distance, feet, meters, nautical_miles
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.coalition import Coalition
|
||||
@@ -204,6 +204,19 @@ class WaypointBuilder:
|
||||
pretty_name="Refuel",
|
||||
)
|
||||
|
||||
def recovery_tanker(self, position: Point) -> FlightWaypoint:
|
||||
alt_type: AltitudeReference = "BARO"
|
||||
|
||||
return FlightWaypoint(
|
||||
"RECOVERY",
|
||||
FlightWaypointType.RECOVERY_TANKER,
|
||||
position,
|
||||
feet(6000),
|
||||
alt_type,
|
||||
description="Recovery tanker for aircraft carriers",
|
||||
pretty_name="Recovery",
|
||||
)
|
||||
|
||||
def split(self, position: Point) -> FlightWaypoint:
|
||||
alt_type: AltitudeReference = "BARO"
|
||||
if self.is_helo:
|
||||
|
||||
@@ -49,3 +49,4 @@ class FlightWaypointType(IntEnum):
|
||||
REFUEL = 29 # Should look for nearby tanker to refuel from.
|
||||
CARGO_STOP = 30 # Stopover landing point using the LandingReFuAr waypoint type
|
||||
INGRESS_AIR_ASSAULT = 31
|
||||
RECOVERY_TANKER = 32
|
||||
|
||||
@@ -332,6 +332,8 @@ class Game:
|
||||
from .server import EventStream
|
||||
from .sim import GameUpdateEvents
|
||||
|
||||
persistency.save_last_turn_state(self)
|
||||
|
||||
events = GameUpdateEvents()
|
||||
|
||||
logging.info("Pass turn")
|
||||
|
||||
@@ -24,6 +24,7 @@ from dcs.unitgroup import FlyingGroup
|
||||
|
||||
from game.ato import Flight, FlightType
|
||||
from game.ato.flightplans.aewc import AewcFlightPlan
|
||||
from game.ato.flightplans.shiprecoverytanker import RecoveryTankerFlightPlan
|
||||
from game.ato.flightplans.theaterrefueling import TheaterRefuelingFlightPlan
|
||||
|
||||
|
||||
@@ -246,7 +247,10 @@ class AircraftBehavior:
|
||||
def configure_refueling(self, group: FlyingGroup[Any], flight: Flight) -> None:
|
||||
group.task = Refueling.name
|
||||
|
||||
if not isinstance(flight.flight_plan, TheaterRefuelingFlightPlan):
|
||||
if not (
|
||||
isinstance(flight.flight_plan, TheaterRefuelingFlightPlan)
|
||||
or isinstance(flight.flight_plan, RecoveryTankerFlightPlan)
|
||||
):
|
||||
logging.error(
|
||||
f"Cannot configure racetrack refueling tasks for {flight} because it "
|
||||
"does not have an racetrack refueling flight plan."
|
||||
|
||||
@@ -177,6 +177,7 @@ class AircraftGenerator:
|
||||
self.mission_data,
|
||||
dynamic_runways,
|
||||
self.use_client,
|
||||
self.unit_map,
|
||||
).configure()
|
||||
)
|
||||
return group
|
||||
|
||||
@@ -10,6 +10,7 @@ from dcs.unit import Skill
|
||||
from dcs.unitgroup import FlyingGroup
|
||||
|
||||
from game.ato import Flight, FlightType
|
||||
from game.ato.flightplans.shiprecoverytanker import RecoveryTankerFlightPlan
|
||||
from game.callsigns import callsign_for_support_unit
|
||||
from game.data.weapons import Pylon, WeaponType as WeaponTypeEnum
|
||||
from game.missiongenerator.missiondata import MissionData, AwacsInfo, TankerInfo
|
||||
@@ -19,6 +20,7 @@ from game.radio.radios import RadioFrequency, RadioRegistry
|
||||
from game.radio.tacan import TacanBand, TacanRegistry, TacanUsage
|
||||
from game.runways import RunwayData
|
||||
from game.squadrons import Pilot
|
||||
from game.unitmap import UnitMap
|
||||
from .aircraftbehavior import AircraftBehavior
|
||||
from .aircraftpainter import AircraftPainter
|
||||
from .flightdata import FlightData
|
||||
@@ -44,6 +46,7 @@ class FlightGroupConfigurator:
|
||||
mission_data: MissionData,
|
||||
dynamic_runways: dict[str, RunwayData],
|
||||
use_client: bool,
|
||||
unit_map: UnitMap,
|
||||
) -> None:
|
||||
self.flight = flight
|
||||
self.group = group
|
||||
@@ -56,6 +59,7 @@ class FlightGroupConfigurator:
|
||||
self.mission_data = mission_data
|
||||
self.dynamic_runways = dynamic_runways
|
||||
self.use_client = use_client
|
||||
self.unit_map = unit_map
|
||||
|
||||
def configure(self) -> FlightData:
|
||||
AircraftBehavior(self.flight.flight_type).apply_to(self.flight, self.group)
|
||||
@@ -97,6 +101,7 @@ class FlightGroupConfigurator:
|
||||
self.time,
|
||||
self.game.settings,
|
||||
self.mission_data,
|
||||
self.unit_map,
|
||||
).create_waypoints()
|
||||
|
||||
return FlightData(
|
||||
@@ -156,7 +161,9 @@ class FlightGroupConfigurator:
|
||||
blue=self.flight.departure.captured,
|
||||
)
|
||||
)
|
||||
elif isinstance(self.flight.flight_plan, TheaterRefuelingFlightPlan):
|
||||
elif isinstance(
|
||||
self.flight.flight_plan, TheaterRefuelingFlightPlan
|
||||
) or isinstance(self.flight.flight_plan, RecoveryTankerFlightPlan):
|
||||
tacan = self.tacan_registry.alloc_for_band(TacanBand.Y, TacanUsage.AirToAir)
|
||||
self.mission_data.tankers.append(
|
||||
TankerInfo(
|
||||
|
||||
@@ -12,6 +12,7 @@ from game.ato import Flight, FlightWaypoint
|
||||
from game.ato.flightwaypointtype import FlightWaypointType
|
||||
from game.missiongenerator.missiondata import MissionData
|
||||
from game.theater import MissionTarget, TheaterUnit
|
||||
from game.unitmap import UnitMap
|
||||
|
||||
TARGET_WAYPOINTS = (
|
||||
FlightWaypointType.TARGET_GROUP_LOC,
|
||||
@@ -29,6 +30,7 @@ class PydcsWaypointBuilder:
|
||||
mission: Mission,
|
||||
elapsed_mission_time: timedelta,
|
||||
mission_data: MissionData,
|
||||
unit_map: UnitMap,
|
||||
) -> None:
|
||||
self.waypoint = waypoint
|
||||
self.group = group
|
||||
@@ -37,6 +39,7 @@ class PydcsWaypointBuilder:
|
||||
self.mission = mission
|
||||
self.elapsed_mission_time = elapsed_mission_time
|
||||
self.mission_data = mission_data
|
||||
self.unit_map = unit_map
|
||||
|
||||
def build(self) -> MovingPoint:
|
||||
waypoint = self.group.add_waypoint(
|
||||
|
||||
59
game/missiongenerator/aircraft/waypoints/recoverytanker.py
Normal file
59
game/missiongenerator/aircraft/waypoints/recoverytanker.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from dcs.point import MovingPoint
|
||||
from dcs.task import ActivateBeaconCommand, RecoveryTanker
|
||||
|
||||
from game.ato import FlightType
|
||||
from game.utils import feet, knots
|
||||
from .pydcswaypointbuilder import PydcsWaypointBuilder
|
||||
|
||||
|
||||
class RecoveryTankerBuilder(PydcsWaypointBuilder):
|
||||
def add_tasks(self, waypoint: MovingPoint) -> None:
|
||||
|
||||
assert self.flight.flight_type == FlightType.REFUELING
|
||||
group_id = self._get_carrier_group_id()
|
||||
speed = knots(250).meters_per_second
|
||||
altitude = feet(6000).meters
|
||||
|
||||
# Last waypoint has index of 1.
|
||||
# Give the tanker a end condition of the last carrier waypoint.
|
||||
# If the carrier ever gets more than one waypoint this approach needs to change.
|
||||
last_waypoint = 2
|
||||
recovery_tanker = RecoveryTanker(group_id, speed, altitude, last_waypoint)
|
||||
|
||||
waypoint.add_task(recovery_tanker)
|
||||
|
||||
self.configure_tanker_tacan(waypoint)
|
||||
|
||||
def _get_carrier_group_id(self) -> int:
|
||||
name = self.package.target.name
|
||||
carrier_position = self.package.target.position
|
||||
theater_objects = self.unit_map.theater_objects
|
||||
for key, value in theater_objects.items():
|
||||
# Check name and position in case there are multiple of same carrier.
|
||||
if name in key and value.theater_unit.position == carrier_position:
|
||||
theater_mapping = value
|
||||
break
|
||||
assert theater_mapping is not None
|
||||
return theater_mapping.dcs_group_id
|
||||
|
||||
def configure_tanker_tacan(self, waypoint: MovingPoint) -> None:
|
||||
|
||||
if self.flight.unit_type.dcs_unit_type.tacan:
|
||||
tanker_info = self.mission_data.tankers[-1]
|
||||
tacan = tanker_info.tacan
|
||||
tacan_callsign = {
|
||||
"Texaco": "TEX",
|
||||
"Arco": "ARC",
|
||||
"Shell": "SHL",
|
||||
}.get(tanker_info.callsign)
|
||||
|
||||
waypoint.add_task(
|
||||
ActivateBeaconCommand(
|
||||
tacan.number,
|
||||
tacan.band.value,
|
||||
tacan_callsign,
|
||||
bearing=True,
|
||||
unit_id=self.group.units[0].id,
|
||||
aa=True,
|
||||
)
|
||||
)
|
||||
@@ -17,8 +17,12 @@ from game.ato.flightstate import InFlight, WaitingForStart
|
||||
from game.ato.flightwaypointtype import FlightWaypointType
|
||||
from game.ato.starttype import StartType
|
||||
from game.missiongenerator.aircraft.waypoints.cargostop import CargoStopBuilder
|
||||
from game.missiongenerator.aircraft.waypoints.recoverytanker import (
|
||||
RecoveryTankerBuilder,
|
||||
)
|
||||
from game.missiongenerator.missiondata import MissionData
|
||||
from game.settings import Settings
|
||||
from game.unitmap import UnitMap
|
||||
from game.utils import pairwise
|
||||
from .baiingress import BaiIngressBuilder
|
||||
from .landingzone import LandingZoneBuilder
|
||||
@@ -50,6 +54,7 @@ class WaypointGenerator:
|
||||
time: datetime,
|
||||
settings: Settings,
|
||||
mission_data: MissionData,
|
||||
unit_map: UnitMap,
|
||||
) -> None:
|
||||
self.flight = flight
|
||||
self.group = group
|
||||
@@ -58,6 +63,7 @@ class WaypointGenerator:
|
||||
self.time = time
|
||||
self.settings = settings
|
||||
self.mission_data = mission_data
|
||||
self.unit_map = unit_map
|
||||
|
||||
def create_waypoints(self) -> tuple[timedelta, list[FlightWaypoint]]:
|
||||
for waypoint in self.flight.points:
|
||||
@@ -135,6 +141,7 @@ class WaypointGenerator:
|
||||
FlightWaypointType.PICKUP_ZONE: LandingZoneBuilder,
|
||||
FlightWaypointType.DROPOFF_ZONE: LandingZoneBuilder,
|
||||
FlightWaypointType.REFUEL: RefuelPointBuilder,
|
||||
FlightWaypointType.RECOVERY_TANKER: RecoveryTankerBuilder,
|
||||
FlightWaypointType.CARGO_STOP: CargoStopBuilder,
|
||||
}
|
||||
builder = builders.get(waypoint.waypoint_type, DefaultWaypointBuilder)
|
||||
@@ -145,6 +152,7 @@ class WaypointGenerator:
|
||||
self.mission,
|
||||
self.elapsed_mission_time,
|
||||
self.mission_data,
|
||||
self.unit_map,
|
||||
)
|
||||
|
||||
def _estimate_min_fuel_for(self, waypoints: list[FlightWaypoint]) -> None:
|
||||
|
||||
@@ -104,6 +104,7 @@ class GroundObjectGenerator:
|
||||
self.add_trigger_zone_for_scenery(unit)
|
||||
if (
|
||||
self.game.settings.plugin_option("skynetiads")
|
||||
and self.game.theater.iads_network.advanced_iads
|
||||
and isinstance(group, IadsGroundGroup)
|
||||
and group.iads_role.participate
|
||||
):
|
||||
@@ -147,7 +148,7 @@ class GroundObjectGenerator:
|
||||
vehicle_unit.position = unit.position
|
||||
vehicle_unit.heading = unit.position.heading.degrees
|
||||
vehicle_group.add_unit(vehicle_unit)
|
||||
self._register_theater_unit(unit, vehicle_group.units[-1])
|
||||
self._register_theater_unit(vehicle_group.id, unit, vehicle_group.units[-1])
|
||||
if vehicle_group is None:
|
||||
raise RuntimeError(f"Error creating VehicleGroup for {group_name}")
|
||||
return vehicle_group
|
||||
@@ -180,7 +181,7 @@ class GroundObjectGenerator:
|
||||
ship_unit.position = unit.position
|
||||
ship_unit.heading = unit.position.heading.degrees
|
||||
ship_group.add_unit(ship_unit)
|
||||
self._register_theater_unit(unit, ship_group.units[-1])
|
||||
self._register_theater_unit(ship_group.id, unit, ship_group.units[-1])
|
||||
if ship_group is None:
|
||||
raise RuntimeError(f"Error creating ShipGroup for {group_name}")
|
||||
return ship_group
|
||||
@@ -194,7 +195,7 @@ class GroundObjectGenerator:
|
||||
heading=unit.position.heading.degrees,
|
||||
dead=not unit.alive,
|
||||
)
|
||||
self._register_theater_unit(unit, static_group.units[0])
|
||||
self._register_theater_unit(static_group.id, unit, static_group.units[0])
|
||||
|
||||
@staticmethod
|
||||
def enable_eplrs(group: VehicleGroup, unit_type: Type[VehicleType]) -> None:
|
||||
@@ -209,10 +210,11 @@ class GroundObjectGenerator:
|
||||
|
||||
def _register_theater_unit(
|
||||
self,
|
||||
dcs_group_id: int,
|
||||
theater_unit: TheaterUnit,
|
||||
dcs_unit: Unit,
|
||||
) -> None:
|
||||
self.unit_map.add_theater_unit_mapping(theater_unit, dcs_unit)
|
||||
self.unit_map.add_theater_unit_mapping(dcs_group_id, theater_unit, dcs_unit)
|
||||
|
||||
def add_trigger_zone_for_scenery(self, scenery: SceneryUnit) -> None:
|
||||
# Align the trigger zones to the faction color on the DCS briefing/F10 map.
|
||||
@@ -291,13 +293,13 @@ class GroundObjectGenerator:
|
||||
self.m.triggerrules.triggers.append(t)
|
||||
|
||||
def generate_iads_command_unit(self, unit: SceneryUnit) -> None:
|
||||
# Creates a static Infantry Unit next to a scenery object. This is needed
|
||||
# because skynet can not use map objects as Comms, Power or Command and needs a
|
||||
# "real" unit to function correctly
|
||||
# Creates a static Unit (tyre with red flag) next to a scenery object. This is
|
||||
# needed because skynet can not use map objects as Comms, Power or Command and
|
||||
# needs a "real" unit to function correctly
|
||||
self.m.static_group(
|
||||
country=self.country,
|
||||
name=unit.unit_name,
|
||||
_type=dcs.vehicles.Infantry.Soldier_M4,
|
||||
_type=dcs.statics.Fortification.Black_Tyre_RF,
|
||||
position=unit.position,
|
||||
heading=unit.position.heading.degrees,
|
||||
dead=not unit.alive, # Also spawn as dead!
|
||||
|
||||
@@ -159,7 +159,9 @@ class TriggerGenerator:
|
||||
flag = self.get_capture_zone_flag()
|
||||
capture_trigger = TriggerCondition(Event.NoEvent, "Capture Trigger")
|
||||
capture_trigger.add_condition(
|
||||
AllOfCoalitionOutsideZone(defending_coalition, trigger_zone.id)
|
||||
AllOfCoalitionOutsideZone(
|
||||
defending_coalition, trigger_zone.id, unit_type="GROUND"
|
||||
)
|
||||
)
|
||||
capture_trigger.add_condition(
|
||||
PartOfCoalitionInZone(
|
||||
@@ -176,7 +178,9 @@ class TriggerGenerator:
|
||||
|
||||
recapture_trigger = TriggerCondition(Event.NoEvent, "Capture Trigger")
|
||||
recapture_trigger.add_condition(
|
||||
AllOfCoalitionOutsideZone(attacking_coalition, trigger_zone.id)
|
||||
AllOfCoalitionOutsideZone(
|
||||
attacking_coalition, trigger_zone.id, unit_type="GROUND"
|
||||
)
|
||||
)
|
||||
recapture_trigger.add_condition(
|
||||
PartOfCoalitionInZone(
|
||||
|
||||
@@ -31,8 +31,8 @@ def save_dir() -> Path:
|
||||
return Path(base_path()) / "Liberation" / "Saves"
|
||||
|
||||
|
||||
def _temporary_save_file() -> str:
|
||||
return str(save_dir() / "tmpsave.liberation")
|
||||
def _temporary_save_file() -> Path:
|
||||
return save_dir() / "tmpsave.liberation"
|
||||
|
||||
|
||||
def _autosave_path() -> str:
|
||||
@@ -54,16 +54,18 @@ def load_game(path: str) -> Optional[Game]:
|
||||
return None
|
||||
|
||||
|
||||
def save_game(game: Game) -> bool:
|
||||
def save_game(game: Game, destination: Path | None = None) -> None:
|
||||
if destination is None:
|
||||
destination = Path(game.savepath)
|
||||
|
||||
temp_save_file = _temporary_save_file()
|
||||
with logged_duration("Saving game"):
|
||||
try:
|
||||
with open(_temporary_save_file(), "wb") as f:
|
||||
with temp_save_file.open("wb") as f:
|
||||
pickle.dump(game, f)
|
||||
shutil.copy(_temporary_save_file(), game.savepath)
|
||||
return True
|
||||
shutil.copy(temp_save_file, destination)
|
||||
except Exception:
|
||||
logging.exception("Could not save game")
|
||||
return False
|
||||
|
||||
|
||||
def autosave(game: Game) -> bool:
|
||||
@@ -79,3 +81,7 @@ def autosave(game: Game) -> bool:
|
||||
except Exception:
|
||||
logging.exception("Could not save game")
|
||||
return False
|
||||
|
||||
|
||||
def save_last_turn_state(game: Game) -> None:
|
||||
save_game(game, save_dir() / "last_turn.liberation")
|
||||
|
||||
@@ -5,6 +5,7 @@ from datetime import timedelta
|
||||
from pathlib import Path
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from game import persistency
|
||||
from game.debriefing import Debriefing
|
||||
from game.missiongenerator import MissionGenerator
|
||||
from game.unitmap import UnitMap
|
||||
@@ -73,6 +74,7 @@ class MissionSimulation:
|
||||
"was generated."
|
||||
)
|
||||
|
||||
persistency.save_last_turn_state(self.game)
|
||||
MissionResultsProcessor(self.game).commit(debriefing, events)
|
||||
|
||||
def finish(self) -> None:
|
||||
|
||||
@@ -33,6 +33,7 @@ from dcs.ships import (
|
||||
CVN_75,
|
||||
CV_1143_5,
|
||||
Forrestal,
|
||||
Hms_invincible,
|
||||
KUZNECOW,
|
||||
LHA_Tarawa,
|
||||
Stennis,
|
||||
@@ -1176,6 +1177,8 @@ class NavalControlPoint(ControlPoint, ABC):
|
||||
|
||||
if self.is_friendly(for_player):
|
||||
yield from [
|
||||
FlightType.AEWC,
|
||||
FlightType.REFUELING,
|
||||
# TODO: FlightType.INTERCEPTION
|
||||
# TODO: Buddy tanking for the A-4?
|
||||
# TODO: Rescue chopper?
|
||||
@@ -1202,9 +1205,10 @@ class NavalControlPoint(ControlPoint, ABC):
|
||||
for u in group.units:
|
||||
if u.alive and u.type in [
|
||||
Forrestal,
|
||||
Stennis,
|
||||
LHA_Tarawa,
|
||||
Hms_invincible,
|
||||
KUZNECOW,
|
||||
LHA_Tarawa,
|
||||
Stennis,
|
||||
Type_071,
|
||||
]:
|
||||
return True
|
||||
@@ -1270,8 +1274,7 @@ class Carrier(NavalControlPoint):
|
||||
yield from super().mission_types(for_player)
|
||||
if self.is_friendly(for_player):
|
||||
yield from [
|
||||
FlightType.AEWC,
|
||||
FlightType.REFUELING,
|
||||
# Nothing yet.
|
||||
]
|
||||
|
||||
def capture(self, game: Game, events: GameUpdateEvents, for_player: bool) -> None:
|
||||
|
||||
@@ -34,6 +34,7 @@ class FrontLineUnit:
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TheaterUnitMapping:
|
||||
dcs_group_id: int
|
||||
theater_unit: TheaterUnit
|
||||
dcs_unit: Unit
|
||||
|
||||
@@ -104,14 +105,16 @@ class UnitMap:
|
||||
return self.front_line_units.get(name, None)
|
||||
|
||||
def add_theater_unit_mapping(
|
||||
self, theater_unit: TheaterUnit, dcs_unit: Unit
|
||||
self, dcs_group_id: int, theater_unit: TheaterUnit, dcs_unit: Unit
|
||||
) -> None:
|
||||
# Deaths for units at TGOs are recorded in the corresponding GroundUnit within
|
||||
# the GroundGroup, so we have to match the dcs unit with the liberation unit
|
||||
name = str(dcs_unit.name)
|
||||
if name in self.theater_objects:
|
||||
raise RuntimeError(f"Duplicate TGO unit: {name}")
|
||||
self.theater_objects[name] = TheaterUnitMapping(theater_unit, dcs_unit)
|
||||
self.theater_objects[name] = TheaterUnitMapping(
|
||||
dcs_group_id, theater_unit, dcs_unit
|
||||
)
|
||||
|
||||
def theater_units(self, name: str) -> Optional[TheaterUnitMapping]:
|
||||
return self.theater_objects.get(name, None)
|
||||
|
||||
@@ -2,7 +2,7 @@ from pathlib import Path
|
||||
|
||||
|
||||
MAJOR_VERSION = 6
|
||||
MINOR_VERSION = 0
|
||||
MINOR_VERSION = 1
|
||||
MICRO_VERSION = 0
|
||||
VERSION_NUMBER = ".".join(str(v) for v in (MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION))
|
||||
|
||||
|
||||
@@ -238,5 +238,5 @@ class QWaitingForMissionResultWindow(QDialog):
|
||||
# Stop the current waiting thread as we manually submit the results
|
||||
self.wait_thread.stop()
|
||||
self.on_debriefing_update(
|
||||
self.sim_controller.debrief_current_state(Path(file[0], force_end=True))
|
||||
self.sim_controller.debrief_current_state(Path(file[0]), force_end=True)
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ asgiref==3.5.2
|
||||
atomicwrites==1.4.1
|
||||
attrs==21.4.0
|
||||
black==22.6.0
|
||||
certifi==2022.6.15
|
||||
certifi==2022.12.7
|
||||
cfgv==3.3.1
|
||||
click==8.1.3
|
||||
colorama==0.4.5
|
||||
@@ -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@f12d70ea844076f95c74ffab92ec3dc9fdee32e4#egg=pydcs
|
||||
-e git+https://github.com/pydcs/dcs@9c7b47b6c2b4870bf563bf880315dac019f6df1f#egg=pydcs
|
||||
pyinstaller==5.2
|
||||
pyinstaller-hooks-contrib==2022.8
|
||||
pyparsing==3.0.9
|
||||
|
||||
Binary file not shown.
@@ -2,36 +2,36 @@ local unitPayloads = {
|
||||
["name"] = "F-15E",
|
||||
["payloads"] = {
|
||||
[1] = {
|
||||
["displayName"] = "Liberation CAS",
|
||||
["name"] = "Liberation CAS",
|
||||
["displayName"] = "CAS",
|
||||
["name"] = "CAS",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}",
|
||||
["num"] = 18,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[4] = {
|
||||
[2] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 6,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 19,
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{CBU_105}",
|
||||
@@ -39,47 +39,23 @@ local unitPayloads = {
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{CBU_105}",
|
||||
["num"] = 9,
|
||||
["num"] = 12,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{CBU_105}",
|
||||
["num"] = 8,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{CBU_105}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[12] = {
|
||||
["CLSID"] = "{CBU_105}",
|
||||
["num"] = 12,
|
||||
},
|
||||
[13] = {
|
||||
["CLSID"] = "{CBU_105}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[14] = {
|
||||
["CLSID"] = "{Mk82AIR}",
|
||||
["num"] = 6,
|
||||
[11] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 18,
|
||||
},
|
||||
[15] = {
|
||||
["CLSID"] = "{Mk82AIR}",
|
||||
["num"] = 5,
|
||||
[12] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[16] = {
|
||||
["CLSID"] = "{Mk82AIR}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[17] = {
|
||||
["CLSID"] = "{Mk82AIR}",
|
||||
["num"] = 14,
|
||||
},
|
||||
[18] = {
|
||||
["CLSID"] = "{Mk82AIR}",
|
||||
["num"] = 15,
|
||||
},
|
||||
[19] = {
|
||||
["CLSID"] = "{Mk82AIR}",
|
||||
["num"] = 16,
|
||||
[13] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
@@ -90,54 +66,46 @@ local unitPayloads = {
|
||||
["name"] = "STRIKE",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 6,
|
||||
["num"] = 11,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["CLSID"] = "{GBU-31}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 9,
|
||||
["num"] = 13,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
["num"] = 18,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 11,
|
||||
["num"] = 12,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 14,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 16,
|
||||
},
|
||||
[12] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[13] = {
|
||||
[10] = {
|
||||
["CLSID"] = "{GBU-31}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
@@ -150,32 +118,44 @@ local unitPayloads = {
|
||||
["name"] = "CAP",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 19,
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 18,
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 2,
|
||||
["num"] = 18,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
@@ -186,48 +166,44 @@ local unitPayloads = {
|
||||
["name"] = "ANTISHIP",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}",
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 18,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}",
|
||||
["num"] = 2,
|
||||
["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 12,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 8,
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
@@ -235,117 +211,169 @@ local unitPayloads = {
|
||||
},
|
||||
},
|
||||
[5] = {
|
||||
["name"] = "SEAD",
|
||||
["name"] = "DEAD",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 6,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{9BCC2A2B-5708-4860-B1F1-053A18442067}",
|
||||
[6] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 18,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{9BCC2A2B-5708-4860-B1F1-053A18442067}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[10] = {
|
||||
[8] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 12,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 8,
|
||||
},
|
||||
[12] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[13] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 7,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 32,
|
||||
},
|
||||
},
|
||||
[6] = {
|
||||
["name"] = "Liberation OCA/Runway",
|
||||
["name"] = "OCA/Runway",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
|
||||
["num"] = 6,
|
||||
["CLSID"] = "{GBU-31}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
|
||||
["CLSID"] = "{GBU-31}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
|
||||
["num"] = 9,
|
||||
["CLSID"] = "{GBU-31}",
|
||||
["num"] = 10,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
["num"] = 18,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
|
||||
["num"] = 11,
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
|
||||
["num"] = 14,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}",
|
||||
["num"] = 16,
|
||||
},
|
||||
[12] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{GBU-31}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{GBU-31}",
|
||||
["num"] = 13,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 11,
|
||||
},
|
||||
},
|
||||
[7] = {
|
||||
["name"] = "OCA/Aircraft",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 6,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 10,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 14,
|
||||
},
|
||||
[12] = {
|
||||
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
|
||||
["num"] = 16,
|
||||
},
|
||||
[13] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 18,
|
||||
},
|
||||
[14] = {
|
||||
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[15] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
|
||||
107
resources/customized_payloads/Ka-50_3.lua
Normal file
107
resources/customized_payloads/Ka-50_3.lua
Normal file
@@ -0,0 +1,107 @@
|
||||
local unitPayloads = {
|
||||
["name"] = "Ka-50_3",
|
||||
["payloads"] = {
|
||||
[1] = {
|
||||
["name"] = "Liberation CAS",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{9S846_2xIGLA}",
|
||||
["num"] = 6,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{9S846_2xIGLA}",
|
||||
["num"] = 5,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
|
||||
["num"] = 2,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
},
|
||||
},
|
||||
[2] = {
|
||||
["displayName"] = "Liberation BAI",
|
||||
["name"] = "Liberation BAI",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{9S846_2xIGLA}",
|
||||
["num"] = 6,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{9S846_2xIGLA}",
|
||||
["num"] = 5,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 2,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
},
|
||||
},
|
||||
[3] = {
|
||||
["displayName"] = "Liberation OCA/Aircraft",
|
||||
["name"] = "Liberation OCA/Aircraft",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{9S846_2xIGLA}",
|
||||
["num"] = 6,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{9S846_2xIGLA}",
|
||||
["num"] = 5,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "B_8V20A_OFP2",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "B_8V20A_OFP2",
|
||||
["num"] = 1,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "B_8V20A_OFP2",
|
||||
["num"] = 3,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "B_8V20A_OFP2",
|
||||
["num"] = 2,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
},
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
},
|
||||
["unitType"] = "Ka-50_3",
|
||||
}
|
||||
return unitPayloads
|
||||
@@ -24,6 +24,7 @@
|
||||
"F/A-18C Hornet (Lot 20)",
|
||||
"JF-17 Thunder",
|
||||
"Ka-50 Hokum",
|
||||
"Ka-50 Hokum (Blackshark 3)",
|
||||
"Mirage 2000C",
|
||||
"Mirage-F1B",
|
||||
"Mirage-F1BE",
|
||||
@@ -35,6 +36,7 @@
|
||||
"Mirage-F1M-EE",
|
||||
"Mi-24P Hind-F",
|
||||
"Mi-8MTV2 Hip",
|
||||
"MiG-29S Fulcrum-C",
|
||||
"SA 342L Gazelle",
|
||||
"SA 342M Gazelle",
|
||||
"Su-25T Frogfoot",
|
||||
@@ -109,5 +111,13 @@
|
||||
],
|
||||
"has_jtac": true,
|
||||
"jtac_unit": "MQ-9 Reaper",
|
||||
"unrestricted_satnav": true
|
||||
"unrestricted_satnav": true,
|
||||
"liveries_overrides": {
|
||||
"Ka-50 Hokum": ["georgia camo"],
|
||||
"Mi-8MTV2 Hip": ["Ukraine"],
|
||||
"Mi-24P Hind-F": ["Ukrainian Army Aviation"],
|
||||
"MiG-29S Fulcrum-C": ["Air Force Ukraine Standard"],
|
||||
"Su-25T Frogfoot": ["af standard 101"],
|
||||
"Su-27 Flanker-B": ["Air Force Ukraine Standard"]
|
||||
}
|
||||
}
|
||||
62
resources/factions/peru_1995.json
Normal file
62
resources/factions/peru_1995.json
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"country": "Peru",
|
||||
"name": "Peru 1995",
|
||||
"authors": "Dillie",
|
||||
"description": "<p>Peru during the 1995 Cenepa War.</p>",
|
||||
"locales": [
|
||||
"es_ES"
|
||||
],
|
||||
"aircrafts": [
|
||||
"Mirage 2000C",
|
||||
"Mi-24V Hind-E",
|
||||
"Mi-8MTV2 Hip",
|
||||
"MB-339A",
|
||||
"Su-22M4 Fitter-K"
|
||||
],
|
||||
"frontline_units": [
|
||||
"T-55A",
|
||||
"M113",
|
||||
"BRDM-2",
|
||||
"BTR-80",
|
||||
"M1043 HMMWV (M2 HMG)",
|
||||
"ZSU-23-4 Shilka"
|
||||
],
|
||||
"artillery_units": [
|
||||
"BM-21 Grad",
|
||||
"M109A6 Paladin"
|
||||
],
|
||||
"logistics_units": [
|
||||
"Truck Ural-4320T"
|
||||
],
|
||||
"infantry_units": [
|
||||
"Infantry AK-74",
|
||||
"Infantry RPG",
|
||||
"Infantry M249",
|
||||
"MANPADS SA-18 Igla \"Grouse\""
|
||||
],
|
||||
"missiles": [],
|
||||
"preset_groups": [
|
||||
"SA-3/S-125"
|
||||
],
|
||||
"naval_units": [],
|
||||
"air_defense_units": [
|
||||
"AAA ZU-23 Emplacement",
|
||||
"Bofors 40 mm Gun",
|
||||
"SAM P19 \"Flat Face\" SR (SA-2/3)",
|
||||
"ZSU-23-4 Shilka"
|
||||
],
|
||||
"carrier_names": [],
|
||||
"helicopter_carrier_names": [],
|
||||
"cruiser": [],
|
||||
"requirements": {},
|
||||
"has_jtac": false,
|
||||
"doctrine": "modern",
|
||||
"liveries_overrides": {
|
||||
"Mirage 2000C": [
|
||||
"Peru052"
|
||||
],
|
||||
"MB-339A": [
|
||||
"MB339AP 'PERU'"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
],
|
||||
"aircrafts": [
|
||||
"Ka-50 Hokum",
|
||||
"Ka-50 Hokum (Blackshark 3)",
|
||||
"L-39ZA Albatros",
|
||||
"Mi-24V Hind-E",
|
||||
"Mi-24P Hind-F",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"J-15 Flanker X-2",
|
||||
"J-7B",
|
||||
"Ka-50 Hokum",
|
||||
"Ka-50 Hokum (Blackshark 3)",
|
||||
"L-39ZA Albatros",
|
||||
"Mi-24V Hind-E",
|
||||
"Mi-24P Hind-F",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"J-11A Flanker-L",
|
||||
"JF-17 Thunder",
|
||||
"Ka-50 Hokum",
|
||||
"Ka-50 Hokum (Blackshark 3)",
|
||||
"L-39ZA Albatros",
|
||||
"Mi-24V Hind-E",
|
||||
"Mi-24P Hind-F",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"aircrafts": [
|
||||
"IL-76MD",
|
||||
"Ka-50 Hokum",
|
||||
"Ka-50 Hokum (Blackshark 3)",
|
||||
"Mi-24V Hind-E",
|
||||
"Mi-24P Hind-F",
|
||||
"Mi-8MTV2 Hip",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"aircrafts": [
|
||||
"IL-76MD",
|
||||
"Ka-50 Hokum",
|
||||
"Ka-50 Hokum (Blackshark 3)",
|
||||
"L-39ZA Albatros",
|
||||
"Mi-24V Hind-E",
|
||||
"Mi-24P Hind-F",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"aircrafts": [
|
||||
"IL-76MD",
|
||||
"Ka-50 Hokum",
|
||||
"Ka-50 Hokum (Blackshark 3)",
|
||||
"L-39ZA Albatros",
|
||||
"Mi-24V Hind-E",
|
||||
"Mi-24P Hind-F",
|
||||
|
||||
@@ -48,11 +48,15 @@
|
||||
"Rapier"
|
||||
],
|
||||
"naval_units": [
|
||||
"FFG Oliver Hazard Perry",
|
||||
"DDG Arleigh Burke IIa",
|
||||
"CG Ticonderoga",
|
||||
"LHA-1 Tarawa",
|
||||
"CVN-74 John C. Stennis"
|
||||
"CVN-74 John C. Stennis",
|
||||
"Castle Class",
|
||||
"DDG Arleigh Burke IIa",
|
||||
"FFG Oliver Hazard Perry",
|
||||
"HMS Achilles (F12)",
|
||||
"HMS Andromeda (F57)",
|
||||
"HMS Ariadne (F72)",
|
||||
"HMS Invincible (R05)"
|
||||
],
|
||||
"missiles": [],
|
||||
"air_defense_units": [
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"F-16CM Fighting Falcon (Block 50)",
|
||||
"F/A-18C Hornet (Lot 20)",
|
||||
"Ka-50 Hokum",
|
||||
"Ka-50 Hokum (Blackshark 3)",
|
||||
"MB-339A",
|
||||
"Mi-24P Hind-F",
|
||||
"SH-60B Seahawk",
|
||||
|
||||
@@ -5,7 +5,7 @@ female_pilot_percentage: 0
|
||||
country: USA
|
||||
role: Strike Fighter
|
||||
aircraft: F-14A Tomcat (Block 135-GR Late)
|
||||
livery: VF-33 Starfighters 201
|
||||
livery: VF-33 Starfighters AB201(Dale Snodgrass)
|
||||
mission_types:
|
||||
- BAI
|
||||
- BARCAP
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: Escuadrón Aéreo 412
|
||||
nickname: Halcones
|
||||
country: Peru
|
||||
role: Fighter
|
||||
aircraft: Mirage 2000C
|
||||
livery: Peru052
|
||||
mission_types:
|
||||
- BARCAP
|
||||
- Escort
|
||||
- Intercept
|
||||
- Fighter sweep
|
||||
- TARCAP
|
||||
- BAI
|
||||
- CAS
|
||||
- OCA/Aircraft
|
||||
- OCA/Runway
|
||||
- Strike
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 15 KiB |
BIN
resources/ui/units/aircrafts/banners/Ka-50_3_24.jpg
Normal file
BIN
resources/ui/units/aircrafts/banners/Ka-50_3_24.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 276 KiB |
BIN
resources/ui/units/aircrafts/icons/Ka-50_3_24.jpg
Normal file
BIN
resources/ui/units/aircrafts/icons/Ka-50_3_24.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
26
resources/units/aircraft/Ka-50_3.yaml
Normal file
26
resources/units/aircraft/Ka-50_3.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
class: Helicopter
|
||||
always_keeps_gun: true
|
||||
carrier_capable: true
|
||||
description:
|
||||
"The Ka-50 Black Shark (NATO reporting name: Hokum) is a unique and deadly
|
||||
single-seat, Russian attack helicopter that has seen combat in the Northern
|
||||
Caucasus. It combines a high performance dual rotor system with a deadly
|
||||
weapons payload of guided missiles, rockets, bombs, and a 30mm cannon. The
|
||||
Ka-50 is also unique in that it has an ejection seat."
|
||||
introduced: 1995
|
||||
lha_capable: true
|
||||
cabin_size: 0 # Can not transport troops
|
||||
can_carry_crates: true
|
||||
manufacturer: Kamov
|
||||
origin: USSR/Russia
|
||||
price: 20
|
||||
role: Attack
|
||||
variants:
|
||||
Ka-50 Hokum (Blackshark 3): {}
|
||||
radios:
|
||||
intra_flight: R-800L1
|
||||
inter_flight: R-800L1
|
||||
# The R-800L1 doesn't have preset channels, and the other radio is for
|
||||
# communications with FAC and ground units, which don't currently have
|
||||
# radios assigned, so no channels to configure.
|
||||
kneeboard_units: "metric"
|
||||
4
resources/units/ships/CastleClass_01.yaml
Normal file
4
resources/units/ships/CastleClass_01.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
class: Boat
|
||||
price: 0
|
||||
variants:
|
||||
Castle Class: null
|
||||
4
resources/units/ships/hms_invincible.yaml
Normal file
4
resources/units/ships/hms_invincible.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
class: HelicopterCarrier
|
||||
price: 0
|
||||
variants:
|
||||
HMS Invincible (R05): null
|
||||
4
resources/units/ships/leander-gun-achilles.yaml
Normal file
4
resources/units/ships/leander-gun-achilles.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
class: Frigate
|
||||
price: 0
|
||||
variants:
|
||||
HMS Achilles (F12): null
|
||||
4
resources/units/ships/leander-gun-andromeda.yaml
Normal file
4
resources/units/ships/leander-gun-andromeda.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
class: Frigate
|
||||
price: 0
|
||||
variants:
|
||||
HMS Andromeda (F57): null
|
||||
4
resources/units/ships/leander-gun-ariadne.yaml
Normal file
4
resources/units/ships/leander-gun-ariadne.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
class: Frigate
|
||||
price: 0
|
||||
variants:
|
||||
HMS Ariadne (F72): null
|
||||
Reference in New Issue
Block a user