diff --git a/game/db.py b/game/db.py index 3f91951e..ee798658 100644 --- a/game/db.py +++ b/game/db.py @@ -24,7 +24,6 @@ PRICES = { M_2000C: 18, FA_18C_hornet: 22, - AV8BNA: 18, F_15C: 28, # bomber @@ -75,7 +74,7 @@ PRICES = { } UNIT_BY_TASK = { - FighterSweep: [ + CAP: [ C_101CC, AJS37, F_5E, @@ -84,21 +83,20 @@ UNIT_BY_TASK = { MiG_31, Su_27, Su_33, - MiG_15bis, MiG_21Bis, MiG_29A, FA_18C_hornet, - AV8BNA, F_15C, M_2000C, ], CAS: [ + MiG_15bis, + L_39ZA, A_10A, A_10C, Su_25T, Su_24M, Su_17M4, - L_39ZA, MiG_29G, Su_34, ], @@ -114,7 +112,7 @@ UNIT_BY_TASK = { ], AWACS: [E_3A, A_50, ], - CAP: [Armor.MBT_T_90, Armor.MBT_T_80U, Armor.MBT_T_55, Armor.MBT_M1A2_Abrams, Armor.MBT_M60A3_Patton, Armor.ATGM_M1134_Stryker, Armor.APC_BTR_80, ], + PinpointStrike: [Armor.MBT_T_90, Armor.MBT_T_80U, Armor.MBT_T_55, Armor.MBT_M1A2_Abrams, Armor.MBT_M60A3_Patton, Armor.ATGM_M1134_Stryker, Armor.APC_BTR_80, ], AirDefence: [ AirDefence.AAA_Vulcan_M163, AirDefence.AAA_Vulcan_M163, @@ -192,7 +190,6 @@ UNIT_BY_COUNTRY = { "USA": [ F_15C, FA_18C_hornet, - AV8BNA, AJS37, F_5E, M_2000C, @@ -223,6 +220,12 @@ PLANE_PAYLOAD_OVERRIDES = { "*": "AIM-9M*6, AIM-7M*2, FUEL*3", }, + Su_33: FighterSweep, + + M_2000C: { + "*": "Combat Air Patrol", + }, + MiG_21Bis: { "*": "Patrol, medium range", } diff --git a/game/event.py b/game/event.py index 535c082f..73274785 100644 --- a/game/event.py +++ b/game/event.py @@ -104,7 +104,7 @@ class GroundInterceptEvent(Event): pass def player_attacking(self, strikegroup: db.PlaneDict, clients: db.PlaneDict): - suitable_unittypes = db.find_unittype(CAP, self.defender_name) + suitable_unittypes = db.find_unittype(PinpointStrike, self.defender_name) random.shuffle(suitable_unittypes) unittypes = suitable_unittypes[:self.TARGET_VARIETY] typecount = max(math.floor(self.difficulty * self.TARGET_AMOUNT_FACTOR), 1) diff --git a/game/game.py b/game/game.py index 562149d4..d4d8a4b3 100644 --- a/game/game.py +++ b/game/game.py @@ -2,18 +2,18 @@ from game.event import * COMMISION_LIMITS_SCALE = 2 COMMISION_LIMITS_FACTORS = { - CAP: 2, + PinpointStrike: 2, CAS: 1, - FighterSweep: 3, + CAP: 3, AirDefence: 1, } COMMISION_AMOUNTS_SCALE = 2 COMMISION_UNIT_VARIETY = 4 COMMISION_AMOUNTS_FACTORS = { - CAP: 0.6, + PinpointStrike: 0.6, CAS: 0.3, - FighterSweep: 0.5, + CAP: 0.5, AirDefence: 0.3, } @@ -76,7 +76,7 @@ class Game: def _generate_interceptions(self): enemy_interception = False for from_cp, to_cp in self.theater.conflicts(False): - if from_cp.base.total_units(FighterSweep) == 0: + if from_cp.base.total_units(CAP) == 0: continue if self._roll(ENEMY_INTERCEPT_PROBABILITY_BASE, from_cp.base.strength): @@ -93,7 +93,7 @@ class Game: if self._roll(ENEMY_INTERCEPT_GLOBAL_PROBABILITY_BASE, 1): for from_cp, _ in self.theater.conflicts(False): - if from_cp.base.total_units(FighterSweep) > 0: + if from_cp.base.total_units(CAP) > 0: self.events.append(InterceptEvent(attacker_name=self.enemy, defender_name=self.player, from_cp=from_cp, @@ -136,7 +136,7 @@ class Game: break def _commision_units(self, cp: ControlPoint): - for for_task in [CAP, CAS, FighterSweep, AirDefence]: + for for_task in [PinpointStrike, CAS, CAP, AirDefence]: limit = COMMISION_LIMITS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_LIMITS_SCALE) missing_units = limit - cp.base.total_units(for_task) if missing_units > 0: diff --git a/gen/aircraft.py b/gen/aircraft.py index 59df1dc4..1db7243b 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -58,11 +58,16 @@ class AircraftConflictGenerator: did_load_loadout = False unit_type = group.units[0].unit_type if unit_type in db.PLANE_PAYLOAD_OVERRIDES: - if for_task in db.PLANE_PAYLOAD_OVERRIDES[unit_type]: - group.load_loadout(db.PLANE_PAYLOAD_OVERRIDES[unit_type][for_task]) - did_load_loadout = True - elif "*" in db.PLANE_PAYLOAD_OVERRIDES[unit_type]: - group.load_loadout(db.PLANE_PAYLOAD_OVERRIDES[unit_type]["*"]) + override_loadout = db.PLANE_PAYLOAD_OVERRIDES[unit_type] + if type(override_loadout) == dict: + if for_task in db.PLANE_PAYLOAD_OVERRIDES[unit_type]: + group.load_loadout(db.PLANE_PAYLOAD_OVERRIDES[unit_type][for_task]) + did_load_loadout = True + elif "*" in db.PLANE_PAYLOAD_OVERRIDES[unit_type]: + group.load_loadout(db.PLANE_PAYLOAD_OVERRIDES[unit_type]["*"]) + did_load_loadout = True + elif issubclass(override_loadout, MainTask): + group.load_task_default_loadout(override_loadout) did_load_loadout = True if not did_load_loadout: @@ -162,7 +167,7 @@ class AircraftConflictGenerator: position = group.position # type: Point wayp = group.add_waypoint(position.point_from_heading(heading, WORKAROUND_WAYP_DIST), CAS_ALTITUDE, WARM_START_AIRSPEED) - self._setup_group(group, FighterSweep) + self._setup_group(group, CAP) for group in self.escort_targets: wayp.tasks.append(EscortTaskAction(group.id, engagement_max_dist=ESCORT_MAX_DIST)) @@ -208,11 +213,11 @@ class AircraftConflictGenerator: client_count=client_count, at=at and at or self._group_point(self.conflict.air_defenders_location)) - group.task = FighterSweep.name + group.task = CAP.name wayp = group.add_waypoint(self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED) wayp.tasks.append(dcs.task.EngageTargets(max_distance=self.conflict.size * INTERCEPT_MAX_DISTANCE_FACTOR)) wayp.tasks.append(dcs.task.OrbitAction()) - self._setup_group(group, FighterSweep) + self._setup_group(group, CAP) def generate_transport(self, transport: db.PlaneDict, destination: Airport): assert len(self.escort_targets) == 0 @@ -242,7 +247,7 @@ class AircraftConflictGenerator: client_count=client_count, at=at and at or self._group_point(self.conflict.air_attackers_location)) - group.task = FighterSweep.name + group.task = CAP.name heading = group.position.heading_between_point(self.conflict.position) initial_wayp = group.add_waypoint(group.position.point_from_heading(heading, WORKAROUND_WAYP_DIST), INTERCEPTION_ALT, INTERCEPTION_AIRSPEED) @@ -250,4 +255,4 @@ class AircraftConflictGenerator: wayp = group.add_waypoint(self.conflict.position, 0) wayp.tasks.append(EngageTargets()) - self._setup_group(group, FighterSweep) + self._setup_group(group, CAP) diff --git a/resources/cau_terrain.miz b/resources/tools/cau_terrain.miz similarity index 100% rename from resources/cau_terrain.miz rename to resources/tools/cau_terrain.miz diff --git a/resources/generate_landmap.py b/resources/tools/generate_landmap.py similarity index 100% rename from resources/generate_landmap.py rename to resources/tools/generate_landmap.py diff --git a/resources/tools/generate_loadout_check.py b/resources/tools/generate_loadout_check.py new file mode 100644 index 00000000..88d0b919 --- /dev/null +++ b/resources/tools/generate_loadout_check.py @@ -0,0 +1,30 @@ +import dcs + +from gen.aircraft import AircraftConflictGenerator +from game import db +mis = dcs.Mission(dcs.terrain.PersianGulf()) +pos = dcs.terrain.PersianGulf().khasab().position +airgen = AircraftConflictGenerator(mis, None) + +for t, uts in db.UNIT_BY_TASK.items(): + if t != dcs.task.CAP and t != dcs.task.CAS: + continue + + pos.y = dcs.terrain.PersianGulf().khasab().position.x + for t in t == dcs.task.CAP and [dcs.task.CAP, dcs.task.Escort] or [t]: + pos.x += 10000 + for ut in uts: + pos.y += 5000 + ctr = mis.country([k for k, v in db.UNIT_BY_COUNTRY.items() if ut in v][0]) + + g = mis.flight_group_inflight( + country=ctr, + name="{} - {}".format(t.name, ut), + aircraft_type=ut, + position=pos, + altitude=10000 + ) + g.task = t.name + airgen._setup_group(g, t) + +mis.save("loadout_test.miz") diff --git a/resources/gulf_terrain.miz b/resources/tools/gulf_terrain.miz similarity index 100% rename from resources/gulf_terrain.miz rename to resources/tools/gulf_terrain.miz diff --git a/theater/base.py b/theater/base.py index 0b55cf27..a5e73c18 100644 --- a/theater/base.py +++ b/theater/base.py @@ -116,9 +116,9 @@ class Base: for_task = db.unit_task(unit_type) target_dict = None - if for_task == CAS or for_task == FighterSweep: + if for_task == CAS or for_task == CAP: target_dict = self.aircraft - elif for_task == CAP: + elif for_task == PinpointStrike: target_dict = self.armor elif for_task == AirDefence: target_dict = self.aa @@ -160,19 +160,19 @@ class Base: return int(self.total_aa * (self.strength > 0.2 and self.strength or 0)) def scramble_sweep(self) -> typing.Dict[PlaneType, int]: - return self._find_best_planes(FighterSweep, self.scramble_count()) + return self._find_best_planes(CAP, self.scramble_count()) def scramble_cas(self) -> typing.Dict[PlaneType, int]: return self._find_best_planes(CAS, self.scramble_count()) def scramble_interceptors(self) -> typing.Dict[PlaneType, int]: - return self._find_best_planes(FighterSweep, self.scramble_count()) + return self._find_best_planes(CAP, self.scramble_count()) def assemble_cap(self) -> typing.Dict[Armor, int]: - return self._find_best_armor(CAP, self.assemble_count()) + return self._find_best_armor(PinpointStrike, self.assemble_count()) def assemble_defense(self) -> typing.Dict[Armor, int]: - return self._find_best_armor(CAP, self.assemble_count()) + return self._find_best_armor(PinpointStrike, self.assemble_count()) def assemble_aa(self) -> typing.Dict[AirDefence, int]: return self._find_best_unit(self.aa, AirDefence, self.assemble_aa_count()) diff --git a/theater/start_generator.py b/theater/start_generator.py index 035b3b21..8e6f8e16 100644 --- a/theater/start_generator.py +++ b/theater/start_generator.py @@ -7,8 +7,8 @@ UNIT_VARIETY = 3 UNIT_AMOUNT_FACTOR = 16 COUNT_BY_TASK = { - CAP: 12, - FighterSweep: 16, + PinpointStrike: 12, + CAP: 16, CAS: 8, AirDefence: 0.5, } @@ -19,7 +19,7 @@ def generate_initial(theater: ConflictTheater, enemy: str, sams: bool): if cp.captured: continue - for task in [CAP, FighterSweep, CAS, AirDefence]: + for task in [PinpointStrike, CAP, CAS, AirDefence]: assert cp.importance <= IMPORTANCE_HIGH, "invalid importance {}".format(cp.importance) assert cp.importance >= IMPORTANCE_LOW, "invalid importance {}".format(cp.importance) diff --git a/ui/basemenu.py b/ui/basemenu.py index 9412df6a..62fd118e 100644 --- a/ui/basemenu.py +++ b/ui/basemenu.py @@ -30,9 +30,9 @@ class BaseMenu(Menu): row += 1 units = { - CAP: db.find_unittype(CAP, self.game.player), + PinpointStrike: db.find_unittype(PinpointStrike, self.game.player), CAS: db.find_unittype(CAS, self.game.player), - FighterSweep: db.find_unittype(FighterSweep, self.game.player), + CAP: db.find_unittype(CAP, self.game.player), AirDefence: db.find_unittype(AirDefence, self.game.player), } diff --git a/ui/eventmenu.py b/ui/eventmenu.py index d4555774..69e54975 100644 --- a/ui/eventmenu.py +++ b/ui/eventmenu.py @@ -111,7 +111,7 @@ class EventMenu(Menu): scrambled_aircraft[unit_type] = amount if task == CAS: scrambled_cas[unit_type] = amount - elif task == FighterSweep: + elif task == CAP: scrambled_sweep[unit_type] = amount scrambled_clients = {}