From c2f112e3a64b3b2cdfd3053f58d7b3efda279365 Mon Sep 17 00:00:00 2001 From: Simon Clark Date: Mon, 21 Jun 2021 01:14:07 +0100 Subject: [PATCH] Refactor the mod select changes, re-add accidentally deleted factions. --- game/event/event.py | 2 +- game/factions/faction.py | 70 +++++++++++++++ game/game.py | 110 +++--------------------- game/operation/operation.py | 12 +-- game/settings.py | 13 --- game/theater/start_generator.py | 26 ++++-- qt_ui/main.py | 4 +- qt_ui/widgets/QFactionsInfos.py | 4 +- qt_ui/widgets/QTopPanel.py | 4 +- qt_ui/windows/newgame/QNewGameWizard.py | 17 +++- resources/factions/france_1985.json | 79 +++++++++++++++++ resources/factions/france_2005.json | 86 ++++++++++++++++++ resources/factions/sweden_2002.json | 52 +++++++++++ 13 files changed, 341 insertions(+), 138 deletions(-) create mode 100644 resources/factions/france_1985.json create mode 100644 resources/factions/france_2005.json create mode 100644 resources/factions/sweden_2002.json diff --git a/game/event/event.py b/game/event/event.py index 1fb0230f..1d554fca 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -54,7 +54,7 @@ class Event: @property def is_player_attacking(self) -> bool: - return self.attacker_name == self.game.player_name + return self.attacker_name == self.game.player_faction.name @property def tasks(self) -> List[Type[Task]]: diff --git a/game/factions/faction.py b/game/factions/faction.py index 0a4b2548..452fb9a7 100644 --- a/game/factions/faction.py +++ b/game/factions/faction.py @@ -257,6 +257,76 @@ class Faction: if unit.unit_class is unit_class: yield unit + def apply_mod_settings(self, mod_settings) -> Faction: + # aircraft + if not mod_settings.a4_skyhawk: + self.remove_aircraft("A-4E-C") + if not mod_settings.hercules: + self.remove_aircraft("Hercules") + if not mod_settings.f22_raptor: + self.remove_aircraft("F-22A") + if not mod_settings.jas39_gripen: + self.remove_aircraft("JAS39Gripen") + self.remove_aircraft("JAS39Gripen_AG") + if not mod_settings.su57_felon: + self.remove_aircraft("Su-57") + # frenchpack + if not mod_settings.frenchpack: + self.remove_vehicle("AMX10RCR") + self.remove_vehicle("SEPAR") + self.remove_vehicle("ERC") + self.remove_vehicle("M120") + self.remove_vehicle("AA20") + self.remove_vehicle("TRM2000") + self.remove_vehicle("TRM2000_Citerne") + self.remove_vehicle("TRM2000_AA20") + self.remove_vehicle("TRMMISTRAL") + self.remove_vehicle("VABH") + self.remove_vehicle("VAB_RADIO") + self.remove_vehicle("VAB_50") + self.remove_vehicle("VIB_VBR") + self.remove_vehicle("VAB_HOT") + self.remove_vehicle("VAB_MORTIER") + self.remove_vehicle("VBL50") + self.remove_vehicle("VBLANF1") + self.remove_vehicle("VBL-radio") + self.remove_vehicle("VBAE") + self.remove_vehicle("VBAE_MMP") + self.remove_vehicle("AMX-30B2") + self.remove_vehicle("Tracma") + self.remove_vehicle("JTACFP") + self.remove_vehicle("SHERIDAN") + self.remove_vehicle("Leclerc_XXI") + self.remove_vehicle("Toyota_bleu") + self.remove_vehicle("Toyota_vert") + self.remove_vehicle("Toyota_desert") + self.remove_vehicle("Kamikaze") + # high digit sams + if not mod_settings.high_digit_sams: + self.remove_air_defenses("SA10BGenerator") + self.remove_air_defenses("SA12Generator") + self.remove_air_defenses("SA20Generator") + self.remove_air_defenses("SA20BGenerator") + self.remove_air_defenses("SA23Generator") + self.remove_air_defenses("SA17Generator") + self.remove_air_defenses("KS19Generator") + return self + + def remove_aircraft(self, name): + for i in self.aircrafts: + if i.dcs_unit_type.id == name: + self.aircrafts.remove(i) + + def remove_air_defenses(self, name): + for i in self.air_defenses: + if i == name: + self.air_defenses.remove(i) + + def remove_vehicle(self, name): + for i in self.frontline_units: + if i.dcs_unit_type.id == name: + self.frontline_units.remove(i) + def load_ship(name: str) -> Optional[Type[ShipType]]: if (ship := getattr(dcs.ships, name, None)) is not None: diff --git a/game/game.py b/game/game.py index f854de1f..e6fbd972 100644 --- a/game/game.py +++ b/game/game.py @@ -35,7 +35,7 @@ from .infos.information import Information from .navmesh import NavMesh from .procurement import AircraftProcurementRequest, ProcurementAi from .profiling import logged_duration -from .settings import ModSettings, Settings, AutoAtoBehavior +from .settings import Settings, AutoAtoBehavior from .squadrons import AirWing from .theater import ConflictTheater from .theater.bullseye import Bullseye @@ -88,23 +88,21 @@ class TurnState(Enum): class Game: def __init__( self, - player_name: str, - enemy_name: str, + player_faction: Faction, + enemy_faction: Faction, theater: ConflictTheater, start_date: datetime, settings: Settings, player_budget: float, enemy_budget: float, - mod_settings: ModSettings, ) -> None: self.settings = settings - self.mod_settings = mod_settings self.events: List[Event] = [] self.theater = theater - self.player_name = player_name - self.player_country = db.FACTIONS[player_name].country - self.enemy_name = enemy_name - self.enemy_country = db.FACTIONS[enemy_name].country + self.player_faction = player_faction + self.player_country = player_faction.country + self.enemy_faction = enemy_faction + self.enemy_country = enemy_faction.country # pass_turn() will be called when initialization is complete which will # increment this to turn 0 before it reaches the player. self.turn = -1 @@ -127,8 +125,6 @@ class Game: self.conditions = self.generate_conditions() - self.apply_mods() - self.blue_transit_network = TransitNetwork() self.red_transit_network = TransitNetwork() @@ -207,92 +203,6 @@ class Game: else: self.enemy_country = "Russia" - def apply_mods(self): - # aircraft - if not self.mod_settings.a4_skyhawk: - self.remove_aircraft("A-4E-C") - if not self.mod_settings.hercules: - self.remove_aircraft("Hercules") - if not self.mod_settings.f22_raptor: - self.remove_aircraft("F-22A") - if not self.mod_settings.jas39_gripen: - self.remove_aircraft("JAS39Gripen") - self.remove_aircraft("JAS39Gripen_AG") - if not self.mod_settings.su57_felon: - self.remove_aircraft("Su-57") - # frenchpack - if not self.mod_settings.frenchpack: - self.remove_vehicle("AMX10RCR") - self.remove_vehicle("SEPAR") - self.remove_vehicle("ERC") - self.remove_vehicle("M120") - self.remove_vehicle("AA20") - self.remove_vehicle("TRM2000") - self.remove_vehicle("TRM2000_Citerne") - self.remove_vehicle("TRM2000_AA20") - self.remove_vehicle("TRMMISTRAL") - self.remove_vehicle("VABH") - self.remove_vehicle("VAB_RADIO") - self.remove_vehicle("VAB_50") - self.remove_vehicle("VIB_VBR") - self.remove_vehicle("VAB_HOT") - self.remove_vehicle("VAB_MORTIER") - self.remove_vehicle("VBL50") - self.remove_vehicle("VBLANF1") - self.remove_vehicle("VBL-radio") - self.remove_vehicle("VBAE") - self.remove_vehicle("VBAE_MMP") - self.remove_vehicle("AMX-30B2") - self.remove_vehicle("Tracma") - self.remove_vehicle("JTACFP") - self.remove_vehicle("SHERIDAN") - self.remove_vehicle("Leclerc_XXI") - self.remove_vehicle("Toyota_bleu") - self.remove_vehicle("Toyota_vert") - self.remove_vehicle("Toyota_desert") - self.remove_vehicle("Kamikaze") - # high digit sams - if not self.mod_settings.high_digit_sams: - self.remove_air_defenses("SA10BGenerator") - self.remove_air_defenses("SA12Generator") - self.remove_air_defenses("SA20Generator") - self.remove_air_defenses("SA20BGenerator") - self.remove_air_defenses("SA23Generator") - self.remove_air_defenses("SA17Generator") - self.remove_air_defenses("KS19Generator") - - def remove_aircraft(self, name): - for i in self.player_faction.aircrafts: - if i.dcs_unit_type.id == name: - self.player_faction.aircrafts.remove(i) - for i in self.enemy_faction.aircrafts: - if i.dcs_unit_type.id == name: - self.enemy_faction.aircrafts.remove(i) - - def remove_air_defenses(self, name): - for i in self.player_faction.air_defenses: - if i == name: - self.player_faction.air_defenses.remove(i) - for i in self.enemy_faction.air_defenses: - if i == name: - self.enemy_faction.air_defenses.remove(i) - - def remove_vehicle(self, name): - for i in self.player_faction.frontline_units: - if i.dcs_unit_type.id == name: - self.player_faction.frontline_units.remove(i) - for i in self.enemy_faction.frontline_units: - if i.dcs_unit_type.id == name: - self.enemy_faction.frontline_units.remove(i) - - @property - def player_faction(self) -> Faction: - return db.FACTIONS[self.player_name] - - @property - def enemy_faction(self) -> Faction: - return db.FACTIONS[self.enemy_name] - def faction_for(self, player: bool) -> Faction: if player: return self.player_faction @@ -332,8 +242,8 @@ class Game: player_cp, enemy_cp, enemy_cp.position, - self.player_name, - self.enemy_name, + self.player_faction.name, + self.enemy_faction.name, ) ) @@ -379,7 +289,7 @@ class Game: return ( event and event.attacker_name - and event.attacker_name == self.player_name + and event.attacker_name == self.player_faction.name ) else: raise RuntimeError(f"{event} was passed when an Event type was expected") diff --git a/game/operation/operation.py b/game/operation/operation.py index 9dff4d51..da5239cb 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -77,8 +77,8 @@ class Operation: yield Conflict( cls.game.theater, frontline, - cls.game.player_name, - cls.game.enemy_name, + cls.game.player_faction.name, + cls.game.enemy_faction.name, cls.game.player_country, cls.game.enemy_country, frontline.position, @@ -95,8 +95,8 @@ class Operation: return Conflict( cls.game.theater, FrontLine(player_cp, enemy_cp), - cls.game.player_name, - cls.game.enemy_name, + cls.game.player_faction.name, + cls.game.enemy_faction.name, cls.game.player_country, cls.game.enemy_country, mid_point, @@ -389,8 +389,8 @@ class Operation: player_cp = front_line.blue_cp enemy_cp = front_line.red_cp conflict = Conflict.frontline_cas_conflict( - cls.game.player_name, - cls.game.enemy_name, + cls.game.player_faction.name, + cls.game.enemy_faction.name, cls.current_mission.country(cls.game.player_country), cls.current_mission.country(cls.game.enemy_country), front_line, diff --git a/game/settings.py b/game/settings.py index 51384222..622ebde0 100644 --- a/game/settings.py +++ b/game/settings.py @@ -110,16 +110,3 @@ class Settings: new_state = Settings().__dict__ new_state.update(state) self.__dict__.update(new_state) - - -@dataclass -class ModSettings: - # Aircraft Mods - a4_skyhawk: bool = False - f22_raptor: bool = False - hercules: bool = False - jas39_gripen: bool = False - su57_felon: bool = False - # Ground Asset Mods - frenchpack: bool = False - high_digit_sams: bool = False diff --git a/game/theater/start_generator.py b/game/theater/start_generator.py index 6810e78d..4ec827ec 100644 --- a/game/theater/start_generator.py +++ b/game/theater/start_generator.py @@ -49,7 +49,7 @@ from . import ( OffMapSpawn, ) from ..profiling import logged_duration -from ..settings import ModSettings, Settings +from ..settings import Settings GroundObjectTemplates = Dict[str, Dict[str, Any]] @@ -78,11 +78,22 @@ class GeneratorSettings: no_enemy_navy: bool +@dataclass +class ModSettings: + a4_skyhawk: bool = False + f22_raptor: bool = False + hercules: bool = False + jas39_gripen: bool = False + su57_felon: bool = False + frenchpack: bool = False + high_digit_sams: bool = False + + class GameGenerator: def __init__( self, - player: str, - enemy: str, + player: Faction, + enemy: Faction, theater: ConflictTheater, settings: Settings, generator_settings: GeneratorSettings, @@ -101,14 +112,13 @@ class GameGenerator: namegen.reset() self.prepare_theater() game = Game( - player_name=self.player, - enemy_name=self.enemy, + player_faction=self.player.apply_mod_settings(self.mod_settings), + enemy_faction=self.enemy.apply_mod_settings(self.mod_settings), theater=self.theater, start_date=self.generator_settings.start_date, settings=self.settings, player_budget=self.generator_settings.player_budget, enemy_budget=self.generator_settings.enemy_budget, - mod_settings=self.mod_settings, ) GroundObjectGenerator(game, self.generator_settings).generate() @@ -162,9 +172,9 @@ class ControlPointGroundObjectGenerator: @property def faction_name(self) -> str: if self.control_point.captured: - return self.game.player_name + return self.game.player_faction.name else: - return self.game.enemy_name + return self.game.enemy_faction.name @property def faction(self) -> Faction: diff --git a/qt_ui/main.py b/qt_ui/main.py index 2b49ff6b..64051a36 100644 --- a/qt_ui/main.py +++ b/qt_ui/main.py @@ -19,8 +19,8 @@ from game.data.weapons import ( Weapon, ) from game.profiling import logged_duration -from game.settings import ModSettings, Settings -from game.theater.start_generator import GameGenerator, GeneratorSettings +from game.settings import Settings +from game.theater.start_generator import GameGenerator, GeneratorSettings, ModSettings from qt_ui import ( liberation_install, liberation_theme, diff --git a/qt_ui/widgets/QFactionsInfos.py b/qt_ui/widgets/QFactionsInfos.py index 40369356..935f4af9 100644 --- a/qt_ui/widgets/QFactionsInfos.py +++ b/qt_ui/widgets/QFactionsInfos.py @@ -24,8 +24,8 @@ class QFactionsInfos(QGroupBox): def setGame(self, game: Game): if game is not None: - self.player_name.setText(game.player_name) - self.enemy_name.setText(game.enemy_name) + self.player_name.setText(game.player_faction.name) + self.enemy_name.setText(game.enemy_faction.name) else: self.player_name.setText("") self.enemy_name.setText("") diff --git a/qt_ui/widgets/QTopPanel.py b/qt_ui/widgets/QTopPanel.py index 7292cec4..d3ad018f 100644 --- a/qt_ui/widgets/QTopPanel.py +++ b/qt_ui/widgets/QTopPanel.py @@ -267,8 +267,8 @@ class QTopPanel(QFrame): closest_cps[0], closest_cps[1], self.game.theater.controlpoints[0].position, - self.game.player_name, - self.game.enemy_name, + self.game.player_faction.name, + self.game.enemy_faction.name, ) unit_map = self.game.initiate_event(game_event) diff --git a/qt_ui/windows/newgame/QNewGameWizard.py b/qt_ui/windows/newgame/QNewGameWizard.py index 3a993c3d..50a48815 100644 --- a/qt_ui/windows/newgame/QNewGameWizard.py +++ b/qt_ui/windows/newgame/QNewGameWizard.py @@ -10,8 +10,9 @@ from PySide2.QtWidgets import QVBoxLayout, QTextEdit, QLabel, QCheckBox from jinja2 import Environment, FileSystemLoader, select_autoescape from game import db -from game.settings import Settings, ModSettings -from game.theater.start_generator import GameGenerator, GeneratorSettings +from game.settings import Settings +from game.theater.start_generator import GameGenerator, GeneratorSettings, ModSettings +from game.factions.faction import Faction from qt_ui.widgets.QLiberationCalendar import QLiberationCalendar from qt_ui.widgets.spinsliders import TenthsSpinSlider, TimeInputs, CurrencySpinner from qt_ui.windows.newgame.QCampaignList import ( @@ -112,8 +113,8 @@ class NewGameWizard(QtWidgets.QWizard): high_digit_sams=self.field("high_digit_sams"), ) - blue_faction = [c for c in db.FACTIONS][self.field("blueFaction")] - red_faction = [c for c in db.FACTIONS][self.field("redFaction")] + blue_faction = self.faction_selection_page.selected_blue_faction + red_faction = self.faction_selection_page.selected_red_faction generator = GameGenerator( blue_faction, red_faction, @@ -258,6 +259,14 @@ class FactionSelection(QtWidgets.QWizardPage): self.blueFactionDescription.setText(blue_faction_txt) self.redFactionDescription.setText(red_faction_txt) + @property + def selected_blue_faction(self) -> Faction: + return db.FACTIONS[self.blueFactionSelect.currentText()] + + @property + def selected_red_faction(self) -> Faction: + return db.FACTIONS[self.redFactionSelect.currentText()] + class TheaterConfiguration(QtWidgets.QWizardPage): def __init__( diff --git a/resources/factions/france_1985.json b/resources/factions/france_1985.json new file mode 100644 index 00000000..2211d650 --- /dev/null +++ b/resources/factions/france_1985.json @@ -0,0 +1,79 @@ +{ + "country": "France", + "name": "France 1985", + "authors": "Colonel Panic", + "description": "

1980s French equipment using FrenchPack.

", + "locales": [ + "fr_FR" + ], + "doctrine": "coldwar", + "aircrafts": [ + "Mirage 2000C", + "SA 342L Gazelle", + "SA 342M Gazelle", + "SA 342M Gazelle Mistral" + ], + "awacs": [ + "E-3A" + ], + "tankers": [ + "KC-130", + "KC-135 Stratotanker" + ], + "frontline_units": [ + "AMX.30B2", + "Leclerc S\u00e9ries 2", + "Leclerc S\u00e9ries 2", + "Pamela", + "Panhard", + "Roland 2 (Marder Chassis)", + "VAB .50", + "VAB Mephisto", + "VAB T20/13", + "VBL .50", + "VBL AANF1" + ], + "artillery_units": [ + "M109A6 Paladin", + "M270 Multiple Launch Rocket System" + ], + "logistics_units": [ + "Truck M818 6x6" + ], + "infantry_units": [ + "Infantry M249", + "Infantry M4", + "MANPADS Stinger" + ], + "air_defenses": [ + "RolandGenerator", + "HawkGenerator" + ], + "aircraft_carrier": [], + "helicopter_carrier": [ + "LHA_Tarawa" + ], + "destroyers": [ + "USS_Arleigh_Burke_IIa" + ], + "cruisers": [ + "TICONDEROG" + ], + "requirements": { + "frenchpack V3.5": "https://forums.eagle.ru/showthread.php?t=279974" + }, + "carrier_names": [ + "R91 Charles de Gaulle" + ], + "helicopter_carrier_names": [ + "R97 Jeanne d'Arc", + "L9013 Mistral", + "L9014 Tonerre", + "L9015 Dixmude" + ], + "navy_generators": [ + "ArleighBurkeGroupGenerator" + ], + "has_jtac": true, + "jtac_unit": "SA 342L Gazelle" + } \ No newline at end of file diff --git a/resources/factions/france_2005.json b/resources/factions/france_2005.json new file mode 100644 index 00000000..18e5ddc2 --- /dev/null +++ b/resources/factions/france_2005.json @@ -0,0 +1,86 @@ +{ + "country": "France", + "name": "France 2005", + "authors": "HerrTom", + "description": "

French equipment using the Frenchpack, but without the Rafale mod.

", + "locales": [ + "fr_FR" + ], + "aircrafts": [ + "Mirage 2000-5", + "Mirage 2000C", + "SA 342L Gazelle", + "SA 342M Gazelle", + "SA 342M Gazelle Mistral" + ], + "awacs": [ + "E-2C Hawkeye", + "E-3A" + ], + "tankers": [ + "KC-130", + "KC-135 Stratotanker" + ], + "frontline_units": [ + "AMX.30B2", + "Leclerc S\u00e9ries 2", + "Leclerc S\u00e9ries 2", + "Leclerc_XXI", + "Pamela", + "Panhard", + "Roland 2 (Marder Chassis)", + "VAB .50", + "VAB Mephisto", + "VAB T20/13", + "VAB T20/13", + "VBAE CRAB", + "VBAE CRAB MMP", + "VBL .50", + "VBL AANF1" + ], + "artillery_units": [ + "M109A6 Paladin", + "M270 Multiple Launch Rocket System" + ], + "logistics_units": [ + "Truck M818 6x6" + ], + "infantry_units": [ + "Infantry M249", + "Infantry M4", + "MANPADS Stinger" + ], + "air_defenses": [ + "RolandGenerator", + "HawkGenerator" + ], + "aircraft_carrier": [ + "Stennis" + ], + "helicopter_carrier": [ + "LHA_Tarawa" + ], + "destroyers": [ + "USS_Arleigh_Burke_IIa" + ], + "cruisers": [ + "TICONDEROG" + ], + "requirements": { + "frenchpack V3.5": "https://forums.eagle.ru/showthread.php?t=279974" + }, + "carrier_names": [ + "R91 Charles de Gaulle" + ], + "helicopter_carrier_names": [ + "R97 Jeanne d'Arc", + "L9013 Mistral", + "L9014 Tonerre", + "L9015 Dixmude" + ], + "navy_generators": [ + "ArleighBurkeGroupGenerator" + ], + "has_jtac": true, + "jtac_unit": "MQ-9 Reaper" + } \ No newline at end of file diff --git a/resources/factions/sweden_2002.json b/resources/factions/sweden_2002.json new file mode 100644 index 00000000..a3efd379 --- /dev/null +++ b/resources/factions/sweden_2002.json @@ -0,0 +1,52 @@ +{ + "country": "Sweden", + "name": "Sweden 2002", + "authors": "Khopa (updated with Gripen by bgreman)", + "description": "

Sweden in 2002 after the addition of the Gripen-C.

", + "locales": [ + "sv_SE" + ], + "aircrafts": [ + "AJS-37 Viggen", + "JAS 39 Gripen", + "JAS 39 Gripen A/G", + "UH-1H Iroquois" + ], + "awacs": [ + "E-3A" + ], + "tankers": [ + "KC-130", + "KC-135 Stratotanker" + ], + "frontline_units": [ + "FV510 Warrior", + "Leopard 2A4", + "M1097 Heavy HMMWV Avenger", + "M1126 Stryker ICV (M2 HMG)" + ], + "artillery_units": [], + "logistics_units": [ + "Truck M818 6x6" + ], + "infantry_units": [ + "Infantry M249", + "Infantry M4", + "MANPADS Stinger" + ], + "air_defenses": [ + "AvengerGenerator", + "HawkGenerator" + ], + "ewrs": [ + "HawkEwrGenerator" + ], + "navy_generators": [ + "OliverHazardPerryGroupGenerator" + ], + "requirements": { + "JAS39 Gripen Mod by Community": "https://github.com/whisky-actual/Community-JAS-39-C" + }, + "has_jtac": true, + "jtac_unit": "MQ-9 Reaper" + } \ No newline at end of file