mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Revert "Use the actual Country type instead of the name."
This reverts commit bd2ec12e0f039c9500ea0dd94e7b2e4f7d168fef. Country is both the data (name, ID, etc) and the container for groups added to the miz, so it can't be used across multiple mission generations. See https://github.com/pydcs/dcs/issues/314 for potential follow up work that would let us do this. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2864.
This commit is contained in:
parent
03671bbfb0
commit
ca96a232f0
@ -37,6 +37,7 @@ class Flight(SidcDescribable):
|
||||
def __init__(
|
||||
self,
|
||||
package: Package,
|
||||
country: str,
|
||||
squadron: Squadron,
|
||||
count: int,
|
||||
flight_type: FlightType,
|
||||
@ -48,6 +49,7 @@ class Flight(SidcDescribable):
|
||||
) -> None:
|
||||
self.id = uuid.uuid4()
|
||||
self.package = package
|
||||
self.country = country
|
||||
self.coalition = squadron.coalition
|
||||
self.squadron = squadron
|
||||
self.squadron.claim_inventory(count)
|
||||
|
||||
@ -71,6 +71,10 @@ class Coalition:
|
||||
return 2
|
||||
return 1
|
||||
|
||||
@property
|
||||
def country_name(self) -> str:
|
||||
return self.faction.country
|
||||
|
||||
@property
|
||||
def opponent(self) -> Coalition:
|
||||
assert self._opponent is not None
|
||||
|
||||
@ -26,11 +26,13 @@ class PackageBuilder:
|
||||
air_wing: AirWing,
|
||||
flight_db: Database[Flight],
|
||||
is_player: bool,
|
||||
package_country: str,
|
||||
start_type: StartType,
|
||||
asap: bool,
|
||||
) -> None:
|
||||
self.closest_airfields = closest_airfields
|
||||
self.is_player = is_player
|
||||
self.package_country = package_country
|
||||
self.package = Package(location, flight_db, auto_asap=asap)
|
||||
self.air_wing = air_wing
|
||||
self.start_type = start_type
|
||||
@ -54,6 +56,7 @@ class PackageBuilder:
|
||||
|
||||
flight = Flight(
|
||||
self.package,
|
||||
self.package_country,
|
||||
squadron,
|
||||
plan.num_aircraft,
|
||||
plan.task,
|
||||
|
||||
@ -143,6 +143,7 @@ class PackageFulfiller:
|
||||
self.air_wing,
|
||||
self.flight_db,
|
||||
self.is_player,
|
||||
self.coalition.country_name,
|
||||
self.default_start_type,
|
||||
mission.asap,
|
||||
)
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
from dcs.countries import country_dict
|
||||
from dcs.country import Country
|
||||
|
||||
|
||||
def country_with_name(name: str) -> Country:
|
||||
for country in country_dict.values():
|
||||
if country.name == name:
|
||||
return country()
|
||||
raise KeyError(f"No country found named {name}")
|
||||
@ -157,8 +157,8 @@ class Debriefing:
|
||||
self.game = game
|
||||
self.unit_map = unit_map
|
||||
|
||||
self.player_country = game.blue.faction.country.name
|
||||
self.enemy_country = game.red.faction.country.name
|
||||
self.player_country = game.blue.country_name
|
||||
self.enemy_country = game.red.country_name
|
||||
|
||||
self.air_losses = self.dead_aircraft()
|
||||
self.ground_losses = self.dead_ground_units()
|
||||
|
||||
@ -7,7 +7,7 @@ from functools import cached_property
|
||||
from typing import Any, Dict, Iterator, List, Optional, TYPE_CHECKING, Type
|
||||
|
||||
import dcs
|
||||
from dcs.country import Country
|
||||
from dcs.countries import country_dict
|
||||
from dcs.unittype import ShipType, StaticType, UnitType as DcsUnitType
|
||||
|
||||
from game.armedforces.forcegroup import ForceGroup
|
||||
@ -28,7 +28,6 @@ from game.data.doctrine import (
|
||||
from game.data.groups import GroupRole
|
||||
from game.data.units import UnitClass
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
from game.dcs.countries import country_with_name
|
||||
from game.dcs.groundunittype import GroundUnitType
|
||||
from game.dcs.shipunittype import ShipUnitType
|
||||
from game.dcs.unittype import UnitType
|
||||
@ -44,7 +43,7 @@ class Faction:
|
||||
locales: Optional[List[str]]
|
||||
|
||||
# Country used by this faction
|
||||
country: Country
|
||||
country: str = field(default="")
|
||||
|
||||
# Nice name of the faction
|
||||
name: str = field(default="")
|
||||
@ -169,15 +168,15 @@ class Faction:
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls: Type[Faction], json: Dict[str, Any]) -> Faction:
|
||||
try:
|
||||
country = country_with_name(json["country"])
|
||||
except KeyError as ex:
|
||||
raise KeyError(
|
||||
f'Faction\'s country ("{json.get("country")}") is not a valid DCS '
|
||||
"country ID"
|
||||
) from ex
|
||||
faction = Faction(locales=json.get("locales"))
|
||||
|
||||
faction = Faction(locales=json.get("locales"), country=country)
|
||||
faction.country = json.get("country", "/")
|
||||
if faction.country not in [c.name for c in country_dict.values()]:
|
||||
raise AssertionError(
|
||||
'Faction\'s country ("{}") is not a valid DCS country ID'.format(
|
||||
faction.country
|
||||
)
|
||||
)
|
||||
|
||||
faction.name = json.get("name", "")
|
||||
if not faction.name:
|
||||
|
||||
18
game/game.py
18
game/game.py
@ -24,7 +24,6 @@ from .ato.flighttype import FlightType
|
||||
from .campaignloader import CampaignAirWingConfig
|
||||
from .coalition import Coalition
|
||||
from .db.gamedb import GameDb
|
||||
from .dcs.countries import country_with_name
|
||||
from .infos.information import Information
|
||||
from .persistence import SaveManager
|
||||
from .profiling import logged_duration
|
||||
@ -180,15 +179,13 @@ class Game:
|
||||
Make sure the opposing factions are using different countries
|
||||
:return:
|
||||
"""
|
||||
# TODO: This should just be rejected and sent back to the user to fix.
|
||||
# This isn't always something that the original faction can support.
|
||||
if player_faction.country == enemy_faction.country:
|
||||
if player_faction.country.name == "USA":
|
||||
enemy_faction.country = country_with_name("USAF Aggressors")
|
||||
elif player_faction.country.name == "Russia":
|
||||
enemy_faction.country = country_with_name("USSR")
|
||||
if player_faction.country == "USA":
|
||||
enemy_faction.country = "USAF Aggressors"
|
||||
elif player_faction.country == "Russia":
|
||||
enemy_faction.country = "USSR"
|
||||
else:
|
||||
enemy_faction.country = country_with_name("Russia")
|
||||
enemy_faction.country = "Russia"
|
||||
|
||||
def faction_for(self, player: bool) -> Faction:
|
||||
return self.coalition_for(player).faction
|
||||
@ -199,10 +196,13 @@ class Game:
|
||||
def air_wing_for(self, player: bool) -> AirWing:
|
||||
return self.coalition_for(player).air_wing
|
||||
|
||||
def country_for(self, player: bool) -> str:
|
||||
return self.coalition_for(player).country_name
|
||||
|
||||
@property
|
||||
def neutral_country(self) -> Type[Country]:
|
||||
"""Return the best fitting country that can be used as neutral faction in the generated mission"""
|
||||
countries_in_use = {self.red.faction.country, self.blue.faction.country}
|
||||
countries_in_use = [self.red.country_name, self.blue.country_name]
|
||||
if UnitedNationsPeacekeepers not in countries_in_use:
|
||||
return UnitedNationsPeacekeepers
|
||||
elif Switzerland.name not in countries_in_use:
|
||||
|
||||
@ -17,8 +17,8 @@ from game.ato.flighttype import FlightType
|
||||
from game.ato.package import Package
|
||||
from game.ato.starttype import StartType
|
||||
from game.factions.faction import Faction
|
||||
from game.missiongenerator.lasercoderegistry import LaserCodeRegistry
|
||||
from game.missiongenerator.missiondata import MissionData
|
||||
from game.missiongenerator.lasercoderegistry import LaserCodeRegistry
|
||||
from game.radio.radios import RadioRegistry
|
||||
from game.radio.tacan import TacanRegistry
|
||||
from game.runways import RunwayData
|
||||
@ -143,6 +143,7 @@ class AircraftGenerator:
|
||||
# TODO: Special flight type?
|
||||
flight = Flight(
|
||||
Package(squadron.location, self.game.db.flights),
|
||||
faction.country,
|
||||
squadron,
|
||||
1,
|
||||
FlightType.BARCAP,
|
||||
|
||||
@ -73,7 +73,7 @@ class AirSupportGenerator:
|
||||
else self.conflict.red_cp
|
||||
)
|
||||
|
||||
country = self.game.blue.faction.country
|
||||
country = self.mission.country(self.game.blue.country_name)
|
||||
|
||||
if not self.game.settings.disable_legacy_tanker:
|
||||
fallback_tanker_number = 0
|
||||
|
||||
@ -29,9 +29,12 @@ class CargoShipGenerator:
|
||||
self.generate_cargo_ship(ship)
|
||||
|
||||
def generate_cargo_ship(self, ship: CargoShip) -> ShipGroup:
|
||||
country = self.mission.country(
|
||||
self.game.coalition_for(ship.player_owned).country_name
|
||||
)
|
||||
waypoints = ship.route
|
||||
group = self.mission.ship_group(
|
||||
self.game.coalition_for(ship.player_owned).faction.country,
|
||||
country,
|
||||
ship.name,
|
||||
HandyWind,
|
||||
position=waypoints[0],
|
||||
|
||||
@ -70,11 +70,13 @@ class ConvoyGenerator:
|
||||
units: dict[GroundUnitType, int],
|
||||
for_player: bool,
|
||||
) -> VehicleGroup:
|
||||
country = self.mission.country(self.game.coalition_for(for_player).country_name)
|
||||
|
||||
unit_types = list(units.items())
|
||||
main_unit_type, main_unit_count = unit_types[0]
|
||||
|
||||
group = self.mission.vehicle_group(
|
||||
self.game.coalition_for(for_player).faction.country,
|
||||
country,
|
||||
name,
|
||||
main_unit_type.dcs_unit_type,
|
||||
position=position,
|
||||
|
||||
@ -151,7 +151,7 @@ class FlotGenerator:
|
||||
utype = AircraftType.named("MQ-9 Reaper")
|
||||
|
||||
jtac = self.mission.flight_group(
|
||||
country=self.game.blue.faction.country,
|
||||
country=self.mission.country(self.game.blue.country_name),
|
||||
name=namegen.next_jtac_name(),
|
||||
aircraft_type=utype.dcs_unit_type,
|
||||
position=position[0],
|
||||
@ -716,7 +716,7 @@ class FlotGenerator:
|
||||
spawn_heading = (
|
||||
self.conflict.heading.left if is_player else self.conflict.heading.right
|
||||
)
|
||||
country = self.game.coalition_for(is_player).faction.country
|
||||
country = self.game.coalition_for(is_player).country_name
|
||||
for group in groups:
|
||||
if group.role == CombatGroupRole.ARTILLERY:
|
||||
distance_from_frontline = (
|
||||
@ -734,7 +734,7 @@ class FlotGenerator:
|
||||
|
||||
g = self._generate_group(
|
||||
is_player,
|
||||
country,
|
||||
self.mission.country(country),
|
||||
group.unit_type,
|
||||
group.size,
|
||||
final_position,
|
||||
@ -750,7 +750,7 @@ class FlotGenerator:
|
||||
self.gen_infantry_group_for_group(
|
||||
g,
|
||||
is_player,
|
||||
country,
|
||||
self.mission.country(country),
|
||||
spawn_heading.opposite,
|
||||
)
|
||||
|
||||
|
||||
@ -93,8 +93,9 @@ class LogisticsGenerator:
|
||||
"ctld", "logisticunit"
|
||||
):
|
||||
# Spawn logisticsunit at pickup zones
|
||||
country = self.mission.country(self.flight.country)
|
||||
logistic_unit = self.mission.static_group(
|
||||
self.flight.squadron.coalition.faction.country,
|
||||
country,
|
||||
f"{self.group.name}logistic",
|
||||
Fortification.FARP_Ammo_Dump_Coating,
|
||||
pickup_point,
|
||||
|
||||
@ -135,12 +135,19 @@ class MissionGenerator:
|
||||
"neutrals", bullseye=Bullseye(Point(0, 0, self.mission.terrain)).to_pydcs()
|
||||
)
|
||||
|
||||
p_country = self.game.blue.faction.country
|
||||
e_country = self.game.red.faction.country
|
||||
self.mission.coalition["blue"].add_country(p_country)
|
||||
self.mission.coalition["red"].add_country(e_country)
|
||||
p_country = self.game.blue.country_name
|
||||
e_country = self.game.red.country_name
|
||||
self.mission.coalition["blue"].add_country(
|
||||
country_dict[country_id_from_name(p_country)]()
|
||||
)
|
||||
self.mission.coalition["red"].add_country(
|
||||
country_dict[country_id_from_name(e_country)]()
|
||||
)
|
||||
|
||||
belligerents = {p_country, e_country}
|
||||
belligerents = [
|
||||
country_id_from_name(p_country),
|
||||
country_id_from_name(e_country),
|
||||
]
|
||||
for country in country_dict.keys():
|
||||
if country not in belligerents:
|
||||
self.mission.coalition["neutrals"].add_country(country_dict[country]())
|
||||
@ -264,18 +271,18 @@ class MissionGenerator:
|
||||
aircraft_generator.clear_parking_slots()
|
||||
|
||||
aircraft_generator.generate_flights(
|
||||
self.game.blue.faction.country,
|
||||
self.mission.country(self.game.blue.country_name),
|
||||
self.game.blue.ato,
|
||||
tgo_generator.runways,
|
||||
)
|
||||
aircraft_generator.generate_flights(
|
||||
self.game.red.faction.country,
|
||||
self.mission.country(self.game.red.country_name),
|
||||
self.game.red.ato,
|
||||
tgo_generator.runways,
|
||||
)
|
||||
aircraft_generator.spawn_unused_aircraft(
|
||||
self.game.blue.faction.country,
|
||||
self.game.red.faction.country,
|
||||
self.mission.country(self.game.blue.country_name),
|
||||
self.mission.country(self.game.red.country_name),
|
||||
)
|
||||
|
||||
for flight in aircraft_generator.flights:
|
||||
@ -307,7 +314,7 @@ class MissionGenerator:
|
||||
pos = Point(cast(float, d["x"]), cast(float, d["z"]), self.mission.terrain)
|
||||
if utype is not None and not self.game.position_culled(pos):
|
||||
self.mission.static_group(
|
||||
country=self.game.blue.faction.country,
|
||||
country=self.mission.country(self.game.blue.country_name),
|
||||
name="",
|
||||
_type=utype,
|
||||
hidden=True,
|
||||
|
||||
@ -599,7 +599,7 @@ class HelipadGenerator:
|
||||
return
|
||||
# Note: Helipad are generated as neutral object in order not to interfer with
|
||||
# capture triggers
|
||||
country = self.game.coalition_for(self.cp.captured).faction.country
|
||||
country = self.m.country(self.game.coalition_for(self.cp.captured).country_name)
|
||||
|
||||
for i, helipad in enumerate(self.cp.helipads):
|
||||
heading = helipad.heading.degrees
|
||||
@ -675,7 +675,7 @@ class TgoGenerator:
|
||||
|
||||
def generate(self) -> None:
|
||||
for cp in self.game.theater.controlpoints:
|
||||
country = self.game.coalition_for(cp.captured).faction.country
|
||||
country = self.m.country(self.game.coalition_for(cp.captured).country_name)
|
||||
|
||||
# Generate helipads
|
||||
helipad_gen = HelipadGenerator(
|
||||
|
||||
@ -99,7 +99,7 @@ class VisualsGenerator:
|
||||
break
|
||||
|
||||
self.mission.static_group(
|
||||
self.game.red.faction.country,
|
||||
self.mission.country(self.game.red.country_name),
|
||||
"",
|
||||
_type=v,
|
||||
position=pos,
|
||||
|
||||
@ -7,7 +7,6 @@ from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import Optional, Sequence, TYPE_CHECKING
|
||||
|
||||
from dcs.country import Country
|
||||
from faker import Faker
|
||||
|
||||
from game.ato import Flight, FlightType, Package
|
||||
@ -29,7 +28,7 @@ if TYPE_CHECKING:
|
||||
class Squadron:
|
||||
name: str
|
||||
nickname: Optional[str]
|
||||
country: Country
|
||||
country: str
|
||||
role: str
|
||||
aircraft: AircraftType
|
||||
max_size: int
|
||||
@ -72,7 +71,7 @@ class Squadron:
|
||||
(
|
||||
self.name,
|
||||
self.nickname,
|
||||
self.country.id,
|
||||
self.country,
|
||||
self.role,
|
||||
self.aircraft,
|
||||
)
|
||||
@ -419,6 +418,7 @@ class Squadron:
|
||||
|
||||
flight = Flight(
|
||||
package,
|
||||
self.coalition.country_name,
|
||||
self,
|
||||
size,
|
||||
FlightType.FERRY,
|
||||
|
||||
@ -5,10 +5,8 @@ from pathlib import Path
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
import yaml
|
||||
from dcs.country import Country
|
||||
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
from game.dcs.countries import country_with_name
|
||||
from game.squadrons.operatingbases import OperatingBases
|
||||
from game.squadrons.pilot import Pilot
|
||||
|
||||
@ -21,7 +19,7 @@ if TYPE_CHECKING:
|
||||
class SquadronDef:
|
||||
name: str
|
||||
nickname: Optional[str]
|
||||
country: Country
|
||||
country: str
|
||||
role: str
|
||||
aircraft: AircraftType
|
||||
livery: Optional[str]
|
||||
@ -73,7 +71,7 @@ class SquadronDef:
|
||||
return SquadronDef(
|
||||
name=data["name"],
|
||||
nickname=data.get("nickname"),
|
||||
country=country_with_name(data["country"]),
|
||||
country=data["country"],
|
||||
role=data["role"],
|
||||
aircraft=unit_type,
|
||||
livery=data.get("livery"),
|
||||
|
||||
@ -29,13 +29,13 @@ class SquadronDefLoader:
|
||||
squadrons: dict[AircraftType, list[SquadronDef]] = defaultdict(list)
|
||||
country = self.faction.country
|
||||
faction = self.faction
|
||||
any_country = country.name.startswith("Combined Joint Task Forces ")
|
||||
any_country = country.startswith("Combined Joint Task Forces ")
|
||||
for directory in self.squadron_directories():
|
||||
for path, squadron_def in self.load_squadrons_from(directory):
|
||||
if not any_country and squadron_def.country != country:
|
||||
logging.debug(
|
||||
"Not using squadron for non-matching country (is "
|
||||
f"{squadron_def.country.name}, need {country.name}: {path}"
|
||||
f"{squadron_def.country}, need {country}: {path}"
|
||||
)
|
||||
continue
|
||||
if squadron_def.aircraft not in faction.aircrafts:
|
||||
|
||||
@ -357,6 +357,7 @@ class AirliftPlanner:
|
||||
|
||||
flight = Flight(
|
||||
self.package,
|
||||
self.game.country_for(squadron.player),
|
||||
squadron,
|
||||
flight_size,
|
||||
FlightType.TRANSPORT,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dcs.countries
|
||||
from PySide6.QtWidgets import QComboBox
|
||||
from dcs.liveries.livery import Livery
|
||||
|
||||
@ -21,7 +22,9 @@ class LiverySelector(QComboBox):
|
||||
self.clear()
|
||||
self.addItem("Default", None)
|
||||
for idx, livery in enumerate(
|
||||
squadron.aircraft.dcs_unit_type.iter_liveries_for_country(squadron.country)
|
||||
squadron.aircraft.dcs_unit_type.iter_liveries_for_country(
|
||||
dcs.countries.get_by_name(squadron.country)
|
||||
)
|
||||
):
|
||||
self.addItem(livery.name, livery)
|
||||
if squadron.livery == livery.id:
|
||||
|
||||
@ -40,6 +40,7 @@ class QFlightCreator(QDialog):
|
||||
self.game = game
|
||||
self.package = package
|
||||
self.custom_name_text = None
|
||||
self.country = self.game.blue.country_name
|
||||
|
||||
# Make dialog modal to prevent background windows to close unexpectedly.
|
||||
self.setModal(True)
|
||||
@ -182,6 +183,7 @@ class QFlightCreator(QDialog):
|
||||
|
||||
flight = Flight(
|
||||
self.package,
|
||||
self.country,
|
||||
squadron,
|
||||
# A bit of a hack to work around the old API. Not actually relevant because
|
||||
# the roster is passed explicitly. Needs a refactor.
|
||||
|
||||
@ -41,7 +41,7 @@ class TestFactionLoader(unittest.TestCase):
|
||||
with (RESOURCES_DIR / "valid_faction.json").open("r") as data:
|
||||
faction = Faction.from_dict(json.load(data))
|
||||
|
||||
self.assertEqual(faction.country.name, "USA")
|
||||
self.assertEqual(faction.country, "USA")
|
||||
self.assertEqual(faction.name, "USA 2005")
|
||||
self.assertEqual(faction.authors, "Khopa")
|
||||
self.assertEqual(faction.description, "This is a test description")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user