mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Remove unused code from AircraftType conversion.
This commit is contained in:
parent
f811ae6c61
commit
8c62a081fe
210
game/db.py
210
game/db.py
@ -6,114 +6,19 @@ from typing import List, Optional, Type, Union
|
|||||||
|
|
||||||
from dcs.countries import country_dict
|
from dcs.countries import country_dict
|
||||||
from dcs.helicopters import (
|
from dcs.helicopters import (
|
||||||
AH_1W,
|
|
||||||
AH_64A,
|
|
||||||
AH_64D,
|
|
||||||
CH_47D,
|
|
||||||
CH_53E,
|
|
||||||
Ka_50,
|
|
||||||
Mi_24V,
|
|
||||||
Mi_26,
|
|
||||||
Mi_28N,
|
|
||||||
Mi_8MT,
|
|
||||||
OH_58D,
|
OH_58D,
|
||||||
SA342L,
|
|
||||||
SA342M,
|
|
||||||
SA342Minigun,
|
|
||||||
SA342Mistral,
|
|
||||||
SH_60B,
|
|
||||||
UH_1H,
|
|
||||||
UH_60A,
|
|
||||||
helicopter_map,
|
helicopter_map,
|
||||||
)
|
)
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
|
|
||||||
# mypy can't resolve these if they're wildcard imports for some reason.
|
# mypy can't resolve these if they're wildcard imports for some reason.
|
||||||
from dcs.planes import (
|
from dcs.planes import (
|
||||||
AJS37,
|
|
||||||
AV8BNA,
|
|
||||||
A_10A,
|
|
||||||
A_10C,
|
|
||||||
A_10C_2,
|
|
||||||
A_20G,
|
|
||||||
A_50,
|
|
||||||
An_26B,
|
|
||||||
An_30M,
|
|
||||||
B_17G,
|
B_17G,
|
||||||
B_1B,
|
|
||||||
B_52H,
|
|
||||||
Bf_109K_4,
|
|
||||||
C_101CC,
|
|
||||||
C_130,
|
|
||||||
C_17A,
|
|
||||||
E_3A,
|
|
||||||
E_2C,
|
|
||||||
FA_18C_hornet,
|
FA_18C_hornet,
|
||||||
FW_190A8,
|
|
||||||
FW_190D9,
|
|
||||||
F_117A,
|
|
||||||
F_14A_135_GR,
|
|
||||||
F_14B,
|
|
||||||
F_15C,
|
|
||||||
F_15E,
|
|
||||||
F_16A,
|
|
||||||
F_16C_50,
|
F_16C_50,
|
||||||
F_4E,
|
|
||||||
F_5E_3,
|
|
||||||
F_86F_Sabre,
|
|
||||||
IL_76MD,
|
|
||||||
IL_78M,
|
|
||||||
JF_17,
|
|
||||||
J_11A,
|
|
||||||
Ju_88A4,
|
Ju_88A4,
|
||||||
KC130,
|
|
||||||
KC_135,
|
|
||||||
KC135MPRS,
|
|
||||||
KJ_2000,
|
|
||||||
L_39ZA,
|
|
||||||
MQ_9_Reaper,
|
|
||||||
M_2000C,
|
|
||||||
MiG_15bis,
|
|
||||||
MiG_19P,
|
|
||||||
MiG_21Bis,
|
|
||||||
MiG_23MLD,
|
|
||||||
MiG_25PD,
|
|
||||||
MiG_27K,
|
|
||||||
MiG_29A,
|
|
||||||
MiG_29G,
|
|
||||||
MiG_29S,
|
|
||||||
MiG_31,
|
|
||||||
Mirage_2000_5,
|
|
||||||
P_47D_30,
|
|
||||||
P_47D_30bl1,
|
|
||||||
P_47D_40,
|
|
||||||
P_51D,
|
|
||||||
P_51D_30_NA,
|
P_51D_30_NA,
|
||||||
RQ_1A_Predator,
|
|
||||||
S_3B,
|
|
||||||
S_3B_Tanker,
|
|
||||||
SpitfireLFMkIX,
|
|
||||||
SpitfireLFMkIXCW,
|
|
||||||
Su_17M4,
|
|
||||||
Su_24M,
|
|
||||||
Su_24MR,
|
|
||||||
Su_25,
|
|
||||||
Su_25T,
|
|
||||||
Su_27,
|
|
||||||
Su_30,
|
|
||||||
Su_33,
|
|
||||||
Su_34,
|
|
||||||
Tornado_GR4,
|
|
||||||
Tornado_IDS,
|
|
||||||
Tu_160,
|
|
||||||
Tu_22M3,
|
|
||||||
Tu_95MS,
|
|
||||||
WingLoong_I,
|
|
||||||
Yak_40,
|
|
||||||
plane_map,
|
plane_map,
|
||||||
I_16,
|
|
||||||
Tu_142,
|
|
||||||
MiG_25RBT,
|
|
||||||
)
|
)
|
||||||
from dcs.ships import (
|
from dcs.ships import (
|
||||||
Boat_Armed_Hi_speed,
|
Boat_Armed_Hi_speed,
|
||||||
@ -351,121 +256,6 @@ This defines both price for the player (although only aircraft listed in CAP/CAS
|
|||||||
and prioritization for the enemy (i.e. less important bases will receive units with lower price)
|
and prioritization for the enemy (i.e. less important bases will receive units with lower price)
|
||||||
"""
|
"""
|
||||||
PRICES = {
|
PRICES = {
|
||||||
# fighter
|
|
||||||
MiG_23MLD: 13,
|
|
||||||
Su_27: 18,
|
|
||||||
Su_33: 22,
|
|
||||||
MiG_29A: 18,
|
|
||||||
MiG_29S: 20,
|
|
||||||
MiG_29G: 18,
|
|
||||||
MiG_25PD: 20,
|
|
||||||
MiG_25RBT: 20,
|
|
||||||
MiG_31: 30,
|
|
||||||
J_11A: 26,
|
|
||||||
JF_17: 20,
|
|
||||||
Su_30: 24,
|
|
||||||
Su_57: 40,
|
|
||||||
SpitfireLFMkIX: 14,
|
|
||||||
SpitfireLFMkIXCW: 14,
|
|
||||||
I_16: 10,
|
|
||||||
Bf_109K_4: 14,
|
|
||||||
FW_190D9: 16,
|
|
||||||
FW_190A8: 14,
|
|
||||||
A_20G: 22,
|
|
||||||
Ju_88A4: 24,
|
|
||||||
F_5E_3: 8,
|
|
||||||
MiG_15bis: 4,
|
|
||||||
MiG_19P: 6,
|
|
||||||
F_86F_Sabre: 4,
|
|
||||||
MiG_21Bis: 8,
|
|
||||||
F_4E: 10,
|
|
||||||
AJS37: 12,
|
|
||||||
C_101CC: 6,
|
|
||||||
A_4E_C: 8,
|
|
||||||
MB_339PAN: 6,
|
|
||||||
AV8BNA: 14,
|
|
||||||
M_2000C: 16,
|
|
||||||
Mirage_2000_5: 20,
|
|
||||||
FA_18C_hornet: 22,
|
|
||||||
F_15C: 22,
|
|
||||||
F_15E: 24,
|
|
||||||
F_16C_50: 20,
|
|
||||||
F_16A: 14,
|
|
||||||
F_14A_135_GR: 20,
|
|
||||||
F_14B: 24,
|
|
||||||
F_22A: 40,
|
|
||||||
Tornado_IDS: 20,
|
|
||||||
Tornado_GR4: 20,
|
|
||||||
JAS39Gripen: 26,
|
|
||||||
# bomber
|
|
||||||
Su_17M4: 10,
|
|
||||||
Su_25: 15,
|
|
||||||
Su_25T: 18,
|
|
||||||
L_39ZA: 10,
|
|
||||||
Su_34: 24,
|
|
||||||
Su_24M: 20,
|
|
||||||
Su_24MR: 24,
|
|
||||||
MiG_27K: 20,
|
|
||||||
A_10A: 16,
|
|
||||||
A_10C: 22,
|
|
||||||
A_10C_2: 24,
|
|
||||||
S_3B: 10,
|
|
||||||
JAS39Gripen_AG: 26,
|
|
||||||
# heli
|
|
||||||
Ka_50: 13,
|
|
||||||
SA342M: 8,
|
|
||||||
SA342L: 5,
|
|
||||||
SA342Minigun: 4,
|
|
||||||
SA342Mistral: 8,
|
|
||||||
UH_1H: 4,
|
|
||||||
Mi_8MT: 5,
|
|
||||||
Mi_24V: 18,
|
|
||||||
Mi_28N: 24,
|
|
||||||
AH_1W: 20,
|
|
||||||
AH_64A: 24,
|
|
||||||
AH_64D: 30,
|
|
||||||
OH_58D: 6,
|
|
||||||
SH_60B: 6,
|
|
||||||
CH_47D: 4,
|
|
||||||
CH_53E: 4,
|
|
||||||
UH_60A: 4,
|
|
||||||
Mi_26: 4,
|
|
||||||
# Bombers
|
|
||||||
B_52H: 35,
|
|
||||||
B_1B: 50,
|
|
||||||
F_117A: 100,
|
|
||||||
Tu_160: 50,
|
|
||||||
Tu_22M3: 40,
|
|
||||||
Tu_95MS: 35,
|
|
||||||
Tu_142: 35,
|
|
||||||
# special
|
|
||||||
IL_76MD: 30,
|
|
||||||
An_26B: 25,
|
|
||||||
An_30M: 25,
|
|
||||||
Yak_40: 25,
|
|
||||||
S_3B_Tanker: 20,
|
|
||||||
IL_78M: 25,
|
|
||||||
KC_135: 25,
|
|
||||||
KC130: 25,
|
|
||||||
KC135MPRS: 25,
|
|
||||||
A_50: 50,
|
|
||||||
KJ_2000: 50,
|
|
||||||
E_3A: 50,
|
|
||||||
E_2C: 50,
|
|
||||||
C_130: 25,
|
|
||||||
Hercules: 25,
|
|
||||||
C_17A: 20,
|
|
||||||
# WW2
|
|
||||||
P_51D_30_NA: 18,
|
|
||||||
P_51D: 16,
|
|
||||||
P_47D_30: 17,
|
|
||||||
P_47D_30bl1: 16,
|
|
||||||
P_47D_40: 18,
|
|
||||||
B_17G: 30,
|
|
||||||
# Drones
|
|
||||||
MQ_9_Reaper: 12,
|
|
||||||
RQ_1A_Predator: 6,
|
|
||||||
WingLoong_I: 6,
|
|
||||||
# armor
|
# armor
|
||||||
Armor.APC_MTLB: 4,
|
Armor.APC_MTLB: 4,
|
||||||
Artillery.Grad_MRL_FDDM__FC: 4,
|
Artillery.Grad_MRL_FDDM__FC: 4,
|
||||||
|
|||||||
@ -1,512 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import json
|
|
||||||
from collections import defaultdict
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any
|
|
||||||
from typing import Optional, Type
|
|
||||||
|
|
||||||
import dcs
|
|
||||||
import yaml
|
|
||||||
from dcs.helicopters import (
|
|
||||||
AH_1W,
|
|
||||||
AH_64A,
|
|
||||||
AH_64D,
|
|
||||||
Ka_50,
|
|
||||||
Mi_24V,
|
|
||||||
Mi_28N,
|
|
||||||
Mi_8MT,
|
|
||||||
OH_58D,
|
|
||||||
SA342L,
|
|
||||||
SA342M,
|
|
||||||
SA342Minigun,
|
|
||||||
SA342Mistral,
|
|
||||||
SH_60B,
|
|
||||||
UH_1H,
|
|
||||||
UH_60A,
|
|
||||||
helicopter_map,
|
|
||||||
)
|
|
||||||
|
|
||||||
from dcs.planes import (
|
|
||||||
AV8BNA,
|
|
||||||
A_10A,
|
|
||||||
A_10C,
|
|
||||||
A_10C_2,
|
|
||||||
A_20G,
|
|
||||||
Bf_109K_4,
|
|
||||||
E_2C,
|
|
||||||
FA_18C_hornet,
|
|
||||||
FW_190A8,
|
|
||||||
FW_190D9,
|
|
||||||
F_14A_135_GR,
|
|
||||||
F_14B,
|
|
||||||
F_86F_Sabre,
|
|
||||||
Ju_88A4,
|
|
||||||
MiG_15bis,
|
|
||||||
MiG_19P,
|
|
||||||
P_47D_30,
|
|
||||||
P_47D_30bl1,
|
|
||||||
P_47D_40,
|
|
||||||
P_51D,
|
|
||||||
P_51D_30_NA,
|
|
||||||
S_3B,
|
|
||||||
S_3B_Tanker,
|
|
||||||
SpitfireLFMkIX,
|
|
||||||
SpitfireLFMkIXCW,
|
|
||||||
Su_25,
|
|
||||||
Su_25T,
|
|
||||||
Su_33,
|
|
||||||
plane_map,
|
|
||||||
)
|
|
||||||
from dcs.unittype import FlyingType
|
|
||||||
|
|
||||||
from game.db import PRICES
|
|
||||||
from game.factions.faction import unit_loader
|
|
||||||
from game.radio.channels import (
|
|
||||||
RadioChannelAllocator,
|
|
||||||
ChannelNamer,
|
|
||||||
NoOpChannelAllocator,
|
|
||||||
ViggenRadioChannelAllocator,
|
|
||||||
ViggenChannelNamer,
|
|
||||||
CommonRadioChannelAllocator,
|
|
||||||
TomcatChannelNamer,
|
|
||||||
ViperChannelNamer,
|
|
||||||
MirageChannelNamer,
|
|
||||||
FarmerRadioChannelAllocator,
|
|
||||||
SingleRadioChannelNamer,
|
|
||||||
SCR522ChannelNamer,
|
|
||||||
HueyChannelNamer,
|
|
||||||
)
|
|
||||||
from gen.radios import get_radio, Radio
|
|
||||||
from pydcs_extensions.a4ec.a4ec import A_4E_C
|
|
||||||
from pydcs_extensions.mod_units import MODDED_AIRPLANES
|
|
||||||
|
|
||||||
THIS_DIR = Path(__file__).resolve().parent
|
|
||||||
SRC_ROOT = THIS_DIR.parent.parent
|
|
||||||
UNIT_DATA_DIR = SRC_ROOT / "resources/units"
|
|
||||||
FACTIONS_DIR = SRC_ROOT / "resources/factions"
|
|
||||||
|
|
||||||
|
|
||||||
# List of airframes that rely on their gun as a primary weapon. We confiscate bullets
|
|
||||||
# from most AI air-to-ground missions since they aren't smart enough to RTB when they're
|
|
||||||
# out of everything other than bullets (DCS does not have an all-but-gun winchester
|
|
||||||
# option) and we don't want to be attacking fully functional Tors with a Vulcan.
|
|
||||||
#
|
|
||||||
# These airframes are the exceptions. They probably should be using their gun regardless
|
|
||||||
# of the mission type.
|
|
||||||
GUN_RELIANT_AIRFRAMES: list[Type[FlyingType]] = [
|
|
||||||
AH_1W,
|
|
||||||
AH_64A,
|
|
||||||
AH_64D,
|
|
||||||
A_10A,
|
|
||||||
A_10C,
|
|
||||||
A_10C_2,
|
|
||||||
A_20G,
|
|
||||||
Bf_109K_4,
|
|
||||||
FW_190A8,
|
|
||||||
FW_190D9,
|
|
||||||
F_86F_Sabre,
|
|
||||||
Ju_88A4,
|
|
||||||
Ka_50,
|
|
||||||
MiG_15bis,
|
|
||||||
MiG_19P,
|
|
||||||
Mi_24V,
|
|
||||||
Mi_28N,
|
|
||||||
P_47D_30,
|
|
||||||
P_47D_30bl1,
|
|
||||||
P_47D_40,
|
|
||||||
P_51D,
|
|
||||||
P_51D_30_NA,
|
|
||||||
SpitfireLFMkIX,
|
|
||||||
SpitfireLFMkIXCW,
|
|
||||||
Su_25,
|
|
||||||
Su_25T,
|
|
||||||
]
|
|
||||||
|
|
||||||
CARRIER_CAPABLE = [
|
|
||||||
FA_18C_hornet,
|
|
||||||
F_14A_135_GR,
|
|
||||||
F_14B,
|
|
||||||
AV8BNA,
|
|
||||||
Su_33,
|
|
||||||
A_4E_C,
|
|
||||||
S_3B,
|
|
||||||
S_3B_Tanker,
|
|
||||||
E_2C,
|
|
||||||
UH_1H,
|
|
||||||
Mi_8MT,
|
|
||||||
Ka_50,
|
|
||||||
AH_1W,
|
|
||||||
OH_58D,
|
|
||||||
UH_60A,
|
|
||||||
SH_60B,
|
|
||||||
SA342L,
|
|
||||||
SA342M,
|
|
||||||
SA342Minigun,
|
|
||||||
SA342Mistral,
|
|
||||||
]
|
|
||||||
|
|
||||||
LHA_CAPABLE = [
|
|
||||||
AV8BNA,
|
|
||||||
UH_1H,
|
|
||||||
Mi_8MT,
|
|
||||||
Ka_50,
|
|
||||||
AH_1W,
|
|
||||||
OH_58D,
|
|
||||||
UH_60A,
|
|
||||||
SH_60B,
|
|
||||||
SA342L,
|
|
||||||
SA342M,
|
|
||||||
SA342Minigun,
|
|
||||||
SA342Mistral,
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class AircraftData:
|
|
||||||
"""Additional aircraft data not exposed by pydcs."""
|
|
||||||
|
|
||||||
#: The type of radio used for inter-flight communications.
|
|
||||||
inter_flight_radio: Radio
|
|
||||||
|
|
||||||
#: The type of radio used for intra-flight communications.
|
|
||||||
intra_flight_radio: Radio
|
|
||||||
|
|
||||||
#: The radio preset channel allocator, if the aircraft supports channel
|
|
||||||
#: presets. If the aircraft does not support preset channels, this will be
|
|
||||||
#: None.
|
|
||||||
channel_allocator: Optional[RadioChannelAllocator]
|
|
||||||
|
|
||||||
#: Defines how channels should be named when printed in the kneeboard.
|
|
||||||
channel_namer: Type[ChannelNamer] = ChannelNamer
|
|
||||||
|
|
||||||
|
|
||||||
# Indexed by the id field of the pydcs PlaneType.
|
|
||||||
AIRCRAFT_DATA: dict[str, AircraftData] = {
|
|
||||||
"A-10C": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("AN/ARC-164"),
|
|
||||||
# VHF for intraflight is not accepted anymore by DCS
|
|
||||||
# (see https://forums.eagle.ru/showthread.php?p=4499738).
|
|
||||||
intra_flight_radio=get_radio("AN/ARC-164"),
|
|
||||||
channel_allocator=NoOpChannelAllocator(),
|
|
||||||
),
|
|
||||||
"AJS37": AircraftData(
|
|
||||||
# The AJS37 has somewhat unique radio configuration. Two backup radio
|
|
||||||
# (FR 24) can only operate simultaneously with the main radio in guard
|
|
||||||
# mode. As such, we only use the main radio for both inter- and intra-
|
|
||||||
# flight communication.
|
|
||||||
inter_flight_radio=get_radio("FR 22"),
|
|
||||||
intra_flight_radio=get_radio("FR 22"),
|
|
||||||
channel_allocator=ViggenRadioChannelAllocator(),
|
|
||||||
channel_namer=ViggenChannelNamer,
|
|
||||||
),
|
|
||||||
"AV8BNA": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("AN/ARC-210"),
|
|
||||||
intra_flight_radio=get_radio("AN/ARC-210"),
|
|
||||||
channel_allocator=CommonRadioChannelAllocator(
|
|
||||||
inter_flight_radio_index=2, intra_flight_radio_index=1
|
|
||||||
),
|
|
||||||
),
|
|
||||||
"F-14B": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("AN/ARC-159"),
|
|
||||||
intra_flight_radio=get_radio("AN/ARC-182"),
|
|
||||||
channel_allocator=CommonRadioChannelAllocator(
|
|
||||||
inter_flight_radio_index=1, intra_flight_radio_index=2
|
|
||||||
),
|
|
||||||
channel_namer=TomcatChannelNamer,
|
|
||||||
),
|
|
||||||
"F-16C_50": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("AN/ARC-164"),
|
|
||||||
intra_flight_radio=get_radio("AN/ARC-222"),
|
|
||||||
# COM2 is the AN/ARC-222, which is the VHF radio we want to use for
|
|
||||||
# intra-flight communication to leave COM1 open for UHF inter-flight.
|
|
||||||
channel_allocator=CommonRadioChannelAllocator(
|
|
||||||
inter_flight_radio_index=1, intra_flight_radio_index=2
|
|
||||||
),
|
|
||||||
channel_namer=ViperChannelNamer,
|
|
||||||
),
|
|
||||||
"JF-17": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("R&S M3AR UHF"),
|
|
||||||
intra_flight_radio=get_radio("R&S M3AR VHF"),
|
|
||||||
channel_allocator=CommonRadioChannelAllocator(
|
|
||||||
inter_flight_radio_index=1, intra_flight_radio_index=1
|
|
||||||
),
|
|
||||||
# Same naming pattern as the Viper, so just reuse that.
|
|
||||||
channel_namer=ViperChannelNamer,
|
|
||||||
),
|
|
||||||
"Ka-50": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("R-800L1"),
|
|
||||||
intra_flight_radio=get_radio("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.
|
|
||||||
channel_allocator=NoOpChannelAllocator(),
|
|
||||||
),
|
|
||||||
"M-2000C": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("TRT ERA 7000 V/UHF"),
|
|
||||||
intra_flight_radio=get_radio("TRT ERA 7200 UHF"),
|
|
||||||
channel_allocator=CommonRadioChannelAllocator(
|
|
||||||
inter_flight_radio_index=1, intra_flight_radio_index=2
|
|
||||||
),
|
|
||||||
channel_namer=MirageChannelNamer,
|
|
||||||
),
|
|
||||||
"MiG-15bis": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("RSI-6K HF"),
|
|
||||||
intra_flight_radio=get_radio("RSI-6K HF"),
|
|
||||||
channel_allocator=NoOpChannelAllocator(),
|
|
||||||
),
|
|
||||||
"MiG-19P": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("RSIU-4V"),
|
|
||||||
intra_flight_radio=get_radio("RSIU-4V"),
|
|
||||||
channel_allocator=FarmerRadioChannelAllocator(),
|
|
||||||
channel_namer=SingleRadioChannelNamer,
|
|
||||||
),
|
|
||||||
"MiG-21Bis": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("RSIU-5V"),
|
|
||||||
intra_flight_radio=get_radio("RSIU-5V"),
|
|
||||||
channel_allocator=CommonRadioChannelAllocator(
|
|
||||||
inter_flight_radio_index=1, intra_flight_radio_index=1
|
|
||||||
),
|
|
||||||
channel_namer=SingleRadioChannelNamer,
|
|
||||||
),
|
|
||||||
"P-51D": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("SCR522"),
|
|
||||||
intra_flight_radio=get_radio("SCR522"),
|
|
||||||
channel_allocator=CommonRadioChannelAllocator(
|
|
||||||
inter_flight_radio_index=1, intra_flight_radio_index=1
|
|
||||||
),
|
|
||||||
channel_namer=SCR522ChannelNamer,
|
|
||||||
),
|
|
||||||
"UH-1H": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("AN/ARC-51BX"),
|
|
||||||
# Ideally this would use the AN/ARC-131 because that radio is supposed
|
|
||||||
# to be used for flight comms, but DCS won't allow it as the flight's
|
|
||||||
# frequency, nor will it allow the AN/ARC-134.
|
|
||||||
intra_flight_radio=get_radio("AN/ARC-51BX"),
|
|
||||||
channel_allocator=CommonRadioChannelAllocator(
|
|
||||||
inter_flight_radio_index=1, intra_flight_radio_index=1
|
|
||||||
),
|
|
||||||
channel_namer=HueyChannelNamer,
|
|
||||||
),
|
|
||||||
"F-22A": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("SCR-522"),
|
|
||||||
intra_flight_radio=get_radio("SCR-522"),
|
|
||||||
channel_allocator=None,
|
|
||||||
channel_namer=SCR522ChannelNamer,
|
|
||||||
),
|
|
||||||
"JAS39Gripen": AircraftData(
|
|
||||||
inter_flight_radio=get_radio("R&S Series 6000"),
|
|
||||||
intra_flight_radio=get_radio("R&S Series 6000"),
|
|
||||||
channel_allocator=None,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
AIRCRAFT_DATA["A-10C_2"] = AIRCRAFT_DATA["A-10C"]
|
|
||||||
AIRCRAFT_DATA["P-51D-30-NA"] = AIRCRAFT_DATA["P-51D"]
|
|
||||||
AIRCRAFT_DATA["P-47D-30"] = AIRCRAFT_DATA["P-51D"]
|
|
||||||
AIRCRAFT_DATA["JAS39Gripen_AG"] = AIRCRAFT_DATA["JAS39Gripen"]
|
|
||||||
|
|
||||||
|
|
||||||
class Converter:
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.all_variants: set[str] = set()
|
|
||||||
self.variant_map: dict[str, dict[str, str]] = {}
|
|
||||||
self.unconverted: set[Type[FlyingType]] = set(
|
|
||||||
k for k in PRICES if issubclass(k, FlyingType)
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def find_unit_id_for_faction_name(name: str) -> str:
|
|
||||||
unit_type = unit_loader(name, [dcs.planes, dcs.helicopters, MODDED_AIRPLANES])
|
|
||||||
if unit_type is None:
|
|
||||||
raise KeyError(f"Found no unit named {name}")
|
|
||||||
return unit_type.id
|
|
||||||
|
|
||||||
def convert(self) -> None:
|
|
||||||
data_path = UNIT_DATA_DIR / "unit_info_text.json"
|
|
||||||
with data_path.open(encoding="utf-8") as unit_data_file:
|
|
||||||
unit_data = json.load(unit_data_file)
|
|
||||||
|
|
||||||
for unit_name, data in dict(unit_data).items():
|
|
||||||
if self.convert_unit(unit_name, data):
|
|
||||||
unit_data.pop(unit_name)
|
|
||||||
|
|
||||||
with data_path.open("w", encoding="utf-8") as unit_data_file:
|
|
||||||
json.dump(unit_data, unit_data_file, indent=2)
|
|
||||||
|
|
||||||
for unconverted in self.unconverted:
|
|
||||||
self.generate_basic_info(unconverted)
|
|
||||||
|
|
||||||
for faction_path in FACTIONS_DIR.glob("*.json"):
|
|
||||||
self.update_faction(faction_path)
|
|
||||||
|
|
||||||
def update_faction(self, faction_path: Path) -> None:
|
|
||||||
with faction_path.open() as faction_file:
|
|
||||||
data = json.load(faction_file)
|
|
||||||
|
|
||||||
self.update_aircraft_list(data, "aircrafts")
|
|
||||||
self.update_aircraft_list(data, "awacs")
|
|
||||||
self.update_aircraft_list(data, "tankers")
|
|
||||||
self.update_aircraft_item(data, "jtac_unit")
|
|
||||||
|
|
||||||
if "liveries_overrides" in data:
|
|
||||||
new_liveries = {}
|
|
||||||
for aircraft, liveries in data["liveries_overrides"].items():
|
|
||||||
name = self.new_name_for(aircraft, data["country"])
|
|
||||||
new_liveries[name] = sorted(liveries)
|
|
||||||
data["liveries_overrides"] = new_liveries
|
|
||||||
|
|
||||||
with faction_path.open("w") as faction_file:
|
|
||||||
json.dump(data, faction_file, indent=2)
|
|
||||||
|
|
||||||
def new_name_for(self, old_name: str, country: str) -> str:
|
|
||||||
if old_name in self.all_variants:
|
|
||||||
return old_name
|
|
||||||
aircraft_id = self.find_unit_id_for_faction_name(old_name)
|
|
||||||
return self.variant_map[aircraft_id][country]
|
|
||||||
|
|
||||||
def update_aircraft_list(self, data: dict[str, Any], field: str) -> None:
|
|
||||||
if field not in data:
|
|
||||||
return
|
|
||||||
|
|
||||||
new_aircraft = []
|
|
||||||
for aircraft in data[field]:
|
|
||||||
new_aircraft.append(self.new_name_for(aircraft, data["country"]))
|
|
||||||
data[field] = sorted(new_aircraft)
|
|
||||||
|
|
||||||
def update_aircraft_item(self, data: dict[str, Any], field: str) -> None:
|
|
||||||
if field in data:
|
|
||||||
aircraft_name = data[field]
|
|
||||||
data[field] = self.new_name_for(aircraft_name, data["country"])
|
|
||||||
|
|
||||||
def generate_basic_info(self, unit_type: Type[FlyingType]) -> None:
|
|
||||||
self.all_variants.add(unit_type.id)
|
|
||||||
output_path = UNIT_DATA_DIR / "aircraft" / f"{unit_type.id}.yaml"
|
|
||||||
if output_path.exists():
|
|
||||||
# Already have data for this, don't clobber it, but do register the
|
|
||||||
# variant names.
|
|
||||||
with output_path.open() as unit_info_file:
|
|
||||||
data = yaml.safe_load(unit_info_file)
|
|
||||||
self.all_variants.update(data["variants"].keys())
|
|
||||||
return
|
|
||||||
with output_path.open("w") as output_file:
|
|
||||||
yaml.safe_dump(
|
|
||||||
{
|
|
||||||
"price": PRICES[unit_type],
|
|
||||||
"variants": {unit_type.id: None},
|
|
||||||
},
|
|
||||||
output_file,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.variant_map[unit_type.id] = defaultdict(lambda: unit_type.id)
|
|
||||||
|
|
||||||
def convert_unit(
|
|
||||||
self, pydcs_name: str, data: list[dict[str, dict[str, str]]]
|
|
||||||
) -> bool:
|
|
||||||
if len(data) != 1:
|
|
||||||
raise ValueError(f"Unexpected data format for {pydcs_name}")
|
|
||||||
|
|
||||||
unit_type: Type[FlyingType]
|
|
||||||
if pydcs_name in plane_map:
|
|
||||||
unit_type = plane_map[pydcs_name]
|
|
||||||
elif pydcs_name in helicopter_map:
|
|
||||||
unit_type = helicopter_map[pydcs_name]
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.unconverted.remove(unit_type)
|
|
||||||
|
|
||||||
variants_dict = data[0]
|
|
||||||
default = variants_dict.pop("default")
|
|
||||||
|
|
||||||
default_name = default["name"]
|
|
||||||
self.all_variants.add(default_name)
|
|
||||||
country_to_variant = defaultdict(lambda: default_name)
|
|
||||||
|
|
||||||
variants = {default_name: {}}
|
|
||||||
for country, variant_dict in variants_dict.items():
|
|
||||||
variant_name = variant_dict["name"]
|
|
||||||
self.all_variants.add(variant_name)
|
|
||||||
country_to_variant[country] = variant_name
|
|
||||||
variants[variant_name] = self.get_variant_data(variant_dict)
|
|
||||||
|
|
||||||
output_dict: dict[str, Any] = {"variants": variants, "price": PRICES[unit_type]}
|
|
||||||
output_dict.update(self.get_variant_data(default))
|
|
||||||
|
|
||||||
if unit_type in CARRIER_CAPABLE:
|
|
||||||
output_dict["carrier_capable"] = True
|
|
||||||
if unit_type in LHA_CAPABLE:
|
|
||||||
output_dict["lha_capable"] = True
|
|
||||||
if unit_type in GUN_RELIANT_AIRFRAMES:
|
|
||||||
output_dict["always_keeps_gun"] = True
|
|
||||||
|
|
||||||
try:
|
|
||||||
aircraft_data = AIRCRAFT_DATA[unit_type.id]
|
|
||||||
radio_dict: dict[str, Any] = {
|
|
||||||
"intra_flight": aircraft_data.intra_flight_radio.name,
|
|
||||||
"inter_flight": aircraft_data.inter_flight_radio.name,
|
|
||||||
}
|
|
||||||
channels_dict: dict[str, Any] = {}
|
|
||||||
if type(aircraft_data.channel_namer) != ChannelNamer:
|
|
||||||
channels_dict["namer"] = aircraft_data.channel_namer.name()
|
|
||||||
if aircraft_data.channel_allocator is not None:
|
|
||||||
alloc = aircraft_data.channel_allocator
|
|
||||||
if alloc.name() != "noop":
|
|
||||||
channels_dict["type"] = alloc.name()
|
|
||||||
if isinstance(alloc, CommonRadioChannelAllocator):
|
|
||||||
channels_dict[
|
|
||||||
"intra_flight_radio_index"
|
|
||||||
] = alloc.intra_flight_radio_index
|
|
||||||
channels_dict[
|
|
||||||
"inter_flight_radio_index"
|
|
||||||
] = alloc.inter_flight_radio_index
|
|
||||||
if channels_dict:
|
|
||||||
radio_dict["channels"] = channels_dict
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
output_path = UNIT_DATA_DIR / "aircraft" / f"{unit_type.id}.yaml"
|
|
||||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
with output_path.open("w") as output_file:
|
|
||||||
yaml.safe_dump(output_dict, output_file)
|
|
||||||
|
|
||||||
self.variant_map[pydcs_name] = country_to_variant
|
|
||||||
return True
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_variant_data(variant: dict[str, Any]) -> dict[str, Any]:
|
|
||||||
result = {}
|
|
||||||
|
|
||||||
try:
|
|
||||||
result["manufacturer"] = variant["manufacturer"]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
result["origin"] = variant["country-of-origin"]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
result["role"] = variant["role"]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
as_str = variant["year-of-variant-introduction"]
|
|
||||||
if as_str == "N/A":
|
|
||||||
result["introduced"] = None
|
|
||||||
else:
|
|
||||||
result["introduced"] = int(as_str)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
result["description"] = variant["text"]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
Converter().convert()
|
|
||||||
Loading…
x
Reference in New Issue
Block a user