Merge remote-tracking branch 'khopa/develop' into develop

This commit is contained in:
Khopa 2021-01-06 00:54:42 +01:00
commit 1843d23203
12 changed files with 331 additions and 14 deletions

View File

@ -20,6 +20,7 @@ Saves from 2.3 are not compatible with 2.4.
* **[Economy]** Carriers and off-map spawns generate no income (previously $20M like airbases).
* **[Economy]** Sales of aircraft and ground vehicles can now be cancelled before the next turn begins.
* **[UI]** Multi-SAM objectives now show threat and detection rings per group.
* **[UI]** Unit names are now prettier and more accurate, and can now be set per-country for added historical flavour.
* **[Factions]** Added option for date-based loadout restriction. Active radar homing missiles are handled, patches welcome for the other thousand weapons.
* **[Factions]** Added Poland 2010 faction.
* **[Factions]** Added Greece 2005 faction.

View File

@ -1,6 +1,8 @@
from datetime import datetime
from enum import Enum
from typing import Dict, List, Optional, Tuple, Type, Union
import json
from pathlib import Path
from dcs.countries import country_dict
from dcs.helicopters import (
@ -169,6 +171,8 @@ from pydcs_extensions.mb339.mb339 import MB_339PAN
from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M, Rafale_B
from pydcs_extensions.su57.su57 import Su_57
PRETTYNAMES_PATH = Path("./resources/units/pretty_unit_names.json")
plane_map["A-4E-C"] = A_4E_C
plane_map["MB-339PAN"] = MB_339PAN
plane_map["Rafale_M"] = Rafale_M
@ -1321,6 +1325,25 @@ def unit_type_name(unit_type) -> str:
def unit_type_name_2(unit_type) -> str:
return unit_type.name and unit_type.name or unit_type.id
def unit_pretty_name(country_name: str, unit_type) -> str:
original_name = unit_type.name and unit_type.name or unit_type.id
default_name = None
faction_name = None
with PRETTYNAMES_PATH.open("r", encoding="utf-8") as fdata:
data = json.load(fdata, encoding="utf-8")
type_exists = data.get(original_name)
if type_exists is None:
return original_name
for faction in type_exists:
if default_name is None:
default_name = faction.get("default")
if faction_name is None:
faction_name = faction.get(country_name)
if default_name is None:
return original_name
if faction_name is None:
return default_name
return faction_name
def unit_type_from_name(name: str) -> Optional[Type[UnitType]]:
if name in vehicle_map:

View File

@ -262,6 +262,9 @@ class FlightData:
#: The package that the flight belongs to.
package: Package
#: The country that the flight belongs to.
country: str
flight_type: FlightType
#: All units in the flight.
@ -299,7 +302,7 @@ class FlightData:
joker_fuel: Optional[int]
def __init__(self, package: Package, flight_type: FlightType,
def __init__(self, package: Package, country: str, flight_type: FlightType,
units: List[FlyingUnit], size: int, friendly: bool,
departure_delay: timedelta, departure: RunwayData,
arrival: RunwayData, divert: Optional[RunwayData],
@ -308,6 +311,7 @@ class FlightData:
bingo_fuel: Optional[int],
joker_fuel: Optional[int]) -> None:
self.package = package
self.country = country
self.flight_type = flight_type
self.units = units
self.size = size
@ -778,6 +782,7 @@ class AircraftConflictGenerator:
self.flights.append(FlightData(
package=package,
country=faction.country,
flight_type=flight.flight_type,
units=group.units,
size=len(group.units),
@ -984,7 +989,7 @@ class AircraftConflictGenerator:
# Creating a flight even those this isn't a fragged mission lets us
# reuse the existing debriefing code.
# TODO: Special flight type?
flight = Flight(Package(control_point), aircraft, 1,
flight = Flight(Package(control_point), faction.country, aircraft, 1,
FlightType.BARCAP, "Cold", departure=control_point,
arrival=control_point, divert=None)

View File

@ -173,9 +173,11 @@ class PackageBuilder:
closest_airfields: ClosestAirfields,
global_inventory: GlobalAircraftInventory,
is_player: bool,
package_country: str,
start_type: str) -> None:
self.closest_airfields = closest_airfields
self.is_player = is_player
self.package_country = package_country
self.package = Package(location)
self.allocator = AircraftAllocator(closest_airfields, global_inventory,
is_player)
@ -199,7 +201,7 @@ class PackageBuilder:
else:
start_type = self.start_type
flight = Flight(self.package, aircraft, plan.num_aircraft, plan.task,
flight = Flight(self.package, self.package_country, aircraft, plan.num_aircraft, plan.task,
start_type, departure=airfield, arrival=airfield,
divert=self.find_divert_field(aircraft, airfield))
self.package.add_flight(flight)
@ -629,11 +631,17 @@ class CoalitionMissionPlanner:
else:
start_type = "Warm"
if self.is_player:
package_country = self.game.player_country
else:
package_country = self.game.enemy_country
builder = PackageBuilder(
mission.location,
self.objective_finder.closest_airfields_to(mission.location),
self.game.aircraft_inventory,
self.is_player,
package_country,
start_type
)

View File

@ -136,12 +136,13 @@ class FlightWaypoint:
class Flight:
def __init__(self, package: Package, unit_type: Type[FlyingType],
def __init__(self, package: Package, country: str, unit_type: Type[FlyingType],
count: int, flight_type: FlightType, start_type: str,
departure: ControlPoint, arrival: ControlPoint,
divert: Optional[ControlPoint],
custom_name: Optional[str] = None) -> None:
self.package = package
self.country = country
self.unit_type = unit_type
self.count = count
self.departure = departure
@ -179,3 +180,9 @@ class Flight:
if self.custom_name:
return f"{self.custom_name} {self.count} x {name}"
return f"[{self.flight_type}] {self.count} x {name}"
def __str__(self):
name = db.unit_pretty_name(self.country, self.unit_type)
if self.custom_name:
return f"{self.custom_name} {self.count} x {name}"
return f"[{self.flight_type}] {self.count} x {name}"

View File

@ -5,12 +5,13 @@ from PySide2.QtWidgets import QComboBox
from dcs.unittype import FlyingType
from game import Game, db
class QAircraftTypeSelector(QComboBox):
"""Combo box for selecting among the given aircraft types."""
def __init__(self, aircraft_types: Iterable[Type[FlyingType]]) -> None:
def __init__(self, aircraft_types: Iterable[Type[FlyingType]], country: str) -> None:
super().__init__()
for aircraft in aircraft_types:
self.addItem(f"{aircraft.id}", userData=aircraft)
self.addItem(f"{db.unit_pretty_name(country, aircraft)}", userData=aircraft)
self.model().sort(0)

View File

@ -52,7 +52,7 @@ class QDebriefingWindow(QDialog):
for unit_type, count in player_air_losses.items():
try:
lostUnitsLayout.addWidget(
QLabel(db.unit_type_name(unit_type)), row, 0)
QLabel(db.unit_pretty_name(self.debriefing.player_country, unit_type)), row, 0)
lostUnitsLayout.addWidget(QLabel(str(count)), row, 1)
row += 1
except AttributeError:
@ -94,7 +94,7 @@ class QDebriefingWindow(QDialog):
for unit_type, count in enemy_air_losses.items():
try:
enemylostUnitsLayout.addWidget(
QLabel(db.unit_type_name(unit_type)), row, 0)
QLabel(db.unit_pretty_name(self.debriefing.enemy_country, unit_type)), row, 0)
enemylostUnitsLayout.addWidget(QLabel(str(count)), row, 1)
row += 1
except AttributeError:

View File

@ -58,7 +58,7 @@ class QRecruitBehaviour:
existing_units = self.cp.base.total_units_of_type(unit_type)
scheduled_units = self.pending_deliveries.units.get(unit_type, 0)
unitName = QLabel("<b>" + db.unit_type_name_2(unit_type) + "</b>")
unitName = QLabel("<b>" + db.unit_pretty_name(self.game_model.game.player_country, unit_type) + "</b>")
unitName.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
existing_units = QLabel(str(existing_units))

View File

@ -46,7 +46,7 @@ class QIntelInfo(QFrame):
existing_units = self.cp.base.total_units_of_type(unit_type)
if existing_units == 0:
continue
groupLayout.addWidget(QLabel("<b>" + db.unit_type_name(unit_type) + "</b>"), row, 0)
groupLayout.addWidget(QLabel("<b>" + db.unit_pretty_name(self.game.enemy_country, unit_type) + "</b>"), row, 0)
groupLayout.addWidget(QLabel(str(existing_units)), row, 1)
row += 1

View File

@ -14,7 +14,7 @@ from PySide2.QtWidgets import (
QWidget,
)
from game.game import Game
from game.game import Game, db
from qt_ui.uiconstants import ICONS
from qt_ui.windows.finances.QFinancesMenu import FinancesLayout
@ -81,7 +81,7 @@ class AircraftIntelLayout(IntelTableLayout):
for airframe, count in base.aircraft.items():
if not count:
continue
self.add_row(airframe.id, count)
self.add_row(db.unit_pretty_name(game.enemy_country, airframe), count)
self.add_spacer()
self.add_row("<b>Total</b>", total)

View File

@ -34,6 +34,7 @@ class QFlightCreator(QDialog):
self.game = game
self.package = package
self.custom_name_text = None
self.country = self.game.player_country
self.setWindowTitle("Create flight")
self.setWindowIcon(EVENT_ICONS["strike"])
@ -47,7 +48,7 @@ class QFlightCreator(QDialog):
layout.addLayout(QLabeledWidget("Task:", self.task_selector))
self.aircraft_selector = QAircraftTypeSelector(
self.game.aircraft_inventory.available_types_for_player
self.game.aircraft_inventory.available_types_for_player, self.game.player_country
)
self.aircraft_selector.setCurrentIndex(0)
self.aircraft_selector.currentIndexChanged.connect(
@ -154,7 +155,7 @@ class QFlightCreator(QDialog):
start_type = "Cold"
else:
start_type = "Warm"
flight = Flight(self.package, aircraft, size, task, start_type, origin,
flight = Flight(self.package, self.country, aircraft, size, task, start_type, origin,
arrival, divert, custom_name=self.custom_name_text)
flight.client_count = self.client_slots_spinner.value()

View File

@ -0,0 +1,271 @@
{
"A-10A": [{
"default": "A-10A Thunderbolt II"
}],
"A-10C": [{
"default": "A-10C Thunderbolt II (Suite 3)"
}],
"A-10C_2": [{
"default": "A-10C Thunderbolt II (Suite 7)"
}],
"A-20G": [{
"default": "A-20G Havoc",
"UK": "Boston Mk.III"
}],
"A-4E-C": [{
"default": "A-4E Skyhawk"
}],
"AH_1W": [{
"default": "AH-1W SuperCobra"
}],
"AH-64A": [{
"default": "AH-64A Apache"
}],
"AH-64D": [{
"default": "AH-64D Apache Longbow"
}],
"AJS37": [{
"default": "AJS-37 Viggen"
}],
"AV8BNA": [{
"default": "AV-8B Harrier II Night Attack"
}],
"B-1B": [{
"default": "B-1B Lancer"
}],
"B-17G": [{
"default": "B-17G Flying Fortress",
"UK": "Fortress Mk.III"
}],
"B-52H": [{
"default": "B-52H Stratofortress"
}],
"Bf-109K-4": [{
"default": "Bf 109 K-4 Kurfürst"
}],
"C-101CC": [{
"default": "C-101CC Aviojet"
}],
"C-101EB": [{
"default": "C-101EB Aviojet"
}],
"F-4E": [{
"default": "F-4E Phantom II",
"Germany": "F-4F Phantom II",
"Japan": "F-4EJ Kai Phantom II",
"UK": "Phantom F.3"
}],
"F-5E-3": [{
"default": "F-5E Tiger II"
}],
"F-14A-135-GR": [{
"default": "F-14A Tomcat (Block 135-GR Late)"
}],
"F-14B": [{
"default": "F-14B Tomcat"
}],
"F-15C": [{
"default": "F-15C Eagle",
"Japan": "F-15J Eagle"
}],
"F-15E": [{
"default": "F-15E Strike Eagle"
}],
"F-16C_50": [{
"default": "F-16CM Fighting Falcon (Block 50)",
"Japan": "F-2A"
}],
"F-22A":[{
"default": "F-22A Raptor"
}],
"F-86F Sabre": [{
"default": "F-86F Sabre"
}],
"F-111F": [{
"default": "F-111F Aardvark"
}],
"F-117A": [{
"default": "F-117A Nighthawk"
}],
"FA-18C_hornet": [{
"default": "F/A-18C Hornet (Lot 20)",
"Canada": "CF-188 Hornet",
"Spain": "EF-18A+ Hornet"
}],
"FW-190A8": [{
"default": "Fw 190 A-8 Anton"
}],
"FW-190D9": [{
"default": "Fw 190 D-9 Dora"
}],
"Hercules": [{
"default": "C-130J-30 Super Hercules"
}],
"I-16": [{
"default": "I-16 Ishak"
}],
"J-11A": [{
"default": "J-11A Flanker-L"
}],
"JF-17": [{
"default": "JF-17 Thunder",
"China": "FC-1 Fierce Dragon"
}],
"Ju-88A4": [{
"default": "Ju 88 A-4"
}],
"Ka-50": [{
"default": "Ka-50 Hokum"
}],
"L-39ZA": [{
"default": "L-39ZA Albatross"
}],
"M-2000C": [{
"default": "Mirage 2000C"
}],
"MB-339PAN":[{
"default": "MB-339PAN"
}],
"Mirage 2000-5": [{
"default": "Mirage 2000-5"
}],
"Mi-24V": [{
"default": "Mi-24V Hind-E"
}],
"Mi-28N": [{
"default": "Mi-28N Havoc"
}],
"Mi-8MT": [{
"default": "Mi-8MTV2 Hip"
}],
"MiG-15bis": [{
"default": "MiG-15bis Fagot"
}],
"MiG-19P": [{
"default": "MiG-19P Farmer-B",
"China": "J-6A"
}],
"MiG-21Bis": [{
"default": "MiG-21bis Fishbed-N",
"China": "J-7B"
}],
"MiG-23MLD": [{
"default": "MiG-23MLD Flogger-K"
}],
"MiG-25PD": [{
"default": "MiG-25PD Foxbat-E"
}],
"MiG-25RBT": [{
"default": "MiG-25RBT Foxbat-B"
}],
"MiG_27K": [{
"default": "MiG-27K Flogger-J2"
}],
"MiG-29A": [{
"default": "MiG-29A Fulcrum-A"
}],
"MiG-29G": [{
"default": "MiG-29G Fulcrum-A"
}],
"MiG-29S": [{
"default": "MiG-29S Fulcrum-C"
}],
"MiG-31": [{
"default": "MiG-31 Foxhound"
}],
"P-47D-30": [{
"default": "P-47D-30 Thunderbolt (Late)",
"UK": "Thunderbolt Mk.II (Mid)"
}],
"P-47D-30bl1": [{
"default": "P-47D-30 Thunderbolt (Early)",
"UK": "Thunderbolt Mk.II (Early)"
}],
"P-47D-40": [{
"default": "P-47D-40 Thunderbolt",
"UK": "Thunderbolt Mk.II (Late)"
}],
"P-51D": [{
"default": "P-51D-25-NA Mustang",
"UK": "Mustang Mk.IV (Early)"
}],
"P-51D-30-NA": [{
"default": "P-51D-30-NA Mustang",
"UK": "Mustang Mk.IV (Late)"
}],
"Rafale_A_S": [{
"default": "Rafale M (Air-to-Ground)"
}],
"Rafale_B": [{
"default": "Rafale B"
}],
"Rafale_M": [{
"default": "Rafale M (Air-to-Air)"
}],
"S-3B": [{
"default": "S-3B Viking"
}],
"SA342L": [{
"default": "SA 342L Gazelle"
}],
"SA342M": [{
"default": "SA 342M Gazelle",
"UK": "Gazelle AH.1"
}],
"SA342Mistral": [{
"default": "SA 342M Gazelle Mistral"
}],
"SpitfireLFMkIX": [{
"default": "Spitfire LF Mk IX"
}],
"SpitfireLFMkIXCW": [{
"default": "Spitfire LF Mk IX (Clipped Wings)"
}],
"Su-17M4": [{
"default": "Su-17M4 Fitter-K",
"Poland": "Su-22M4 Fitter-K"
}],
"Su-24M": [{
"default": "Su-24M Fencer-D"
}],
"Su-25": [{
"default": "Su-25 Frogfoot"
}],
"Su-25T": [{
"default": "Su-25T Frogfoot"
}],
"Su-27": [{
"default": "Su-27 Flanker-B"
}],
"Su-30": [{
"default": "Su-30 Flanker-C"
}],
"Su-33": [{
"default": "Su-33 Flanker-D"
}],
"Su-34": [{
"default": "Su-34 Fullback"
}],
"Su-57": [{
"default": "Su-57 Felon"
}],
"Tornado GR4": [{
"default": "Tornado GR4"
}],
"Tornado IDS": [{
"default": "Tornado IDS"
}],
"Tu-22M3": [{
"default": "Tu-22M3 Backfire-C"
}],
"Tu-95MS": [{
"default": "Tu-95MS Bear-H"
}],
"Tu-160": [{
"default": "Tu-160 Blackjack"
}],
"UH-1H": [{
"default": "UH-1H Iroquois",
"Germany": "UH-1D Iroquois"
}]
}