diff --git a/game/event/intercept.py b/game/event/intercept.py index 3497a519..76b1f276 100644 --- a/game/event/intercept.py +++ b/game/event/intercept.py @@ -22,9 +22,13 @@ class InterceptEvent(Event): def __str__(self): return "Intercept from {} at {}".format(self.from_cp, self.to_cp) + def _enemy_scramble_multiplier(self) -> float: + is_global = self.from_cp.is_global or self.to_cp.is_global + return self.game.settings.multiplier * is_global and 0.5 or 1 + @property def threat_description(self): - return "{} aircraft".format(self.enemy_cp.base.scramble_count(self.game.settings.multiplier, CAP)) + return "{} aircraft".format(self.enemy_cp.base.scramble_count(self._enemy_scramble_multiplier(), CAP)) def is_successfull(self, debriefing: Debriefing): units_destroyed = debriefing.destroyed_units[self.defender_name].get(self.transport_unit, 0) @@ -54,7 +58,7 @@ class InterceptEvent(Event): self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE) def player_attacking(self, interceptors: db.PlaneDict, clients: db.PlaneDict): - escort = self.to_cp.base.scramble_sweep(self.game.settings.multiplier) + escort = self.to_cp.base.scramble_sweep(self._enemy_scramble_multiplier()) self.transport_unit = random.choice(db.find_unittype(Transport, self.defender_name)) assert self.transport_unit is not None diff --git a/game/game.py b/game/game.py index 3ec99636..0edfbf15 100644 --- a/game/game.py +++ b/game/game.py @@ -30,7 +30,7 @@ COMMISION_AMOUNTS_FACTORS = { AirDefence: 0.3, } -PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 25 +PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 30 PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG = 2 PLAYER_BASEATTACK_THRESHOLD = 0.2 diff --git a/game/operation/operation.py b/game/operation/operation.py index 8a6cedd7..a542ad0e 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -87,7 +87,10 @@ class Operation: else: cp = self.conflict.to_cp - self.triggersgen.generate(cp, self.is_quick, self.trigger_radius) + self.triggersgen.generate(player_cp=cp, + is_quick=self.is_quick, + activation_trigger_radius=self.trigger_radius, + awacs_enabled=self.is_awacs_enabled) if self.environment_settings is None: self.environment_settings = self.envgen.generate() diff --git a/game/settings.py b/game/settings.py index 69db52b2..2e29ffba 100644 --- a/game/settings.py +++ b/game/settings.py @@ -6,3 +6,4 @@ class Settings: night_disabled = False multiplier = 1 sams = True + cold_start = False diff --git a/gen/aircraft.py b/gen/aircraft.py index 5b961738..0e9ae4b0 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -45,6 +45,9 @@ class AircraftConflictGenerator: self.conflict = conflict self.escort_targets = [] + def _start_type(self) -> StartType: + return self.settings.cold_start and StartType.Cold or StartType.Warm + def _group_point(self, point) -> Point: distance = randint( int(self.conflict.size * SPREAD_DISTANCE_FACTOR[0]), @@ -109,7 +112,7 @@ class AircraftConflictGenerator: aircraft_type=unit_type, airport=self.m.terrain.airport_by_id(airport.id), maintask=None, - start_type=StartType.Warm, + start_type=self._start_type(), group_size=count, parking_slots=None) @@ -135,7 +138,7 @@ class AircraftConflictGenerator: altitude=alt, speed=speed, maintask=None, - start_type=StartType.Warm, + start_type=self._start_type(), group_size=count) def _generate_at_carrier(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: ShipGroup) -> FlyingGroup: @@ -148,7 +151,7 @@ class AircraftConflictGenerator: aircraft_type=unit_type, pad_group=at, maintask=None, - start_type=StartType.Warm, + start_type=self._start_type(), group_size=count) def _generate_group(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: db.StartingPosition): @@ -206,9 +209,11 @@ class AircraftConflictGenerator: group.task = Escort.name + """ heading = group.position.heading_between_point(self.conflict.position) 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, CAP, client_count) for escorted_group, waypoint_index in self.escort_targets: @@ -216,7 +221,7 @@ class AircraftConflictGenerator: if not is_quick: waypoint_index += TRIGGER_WAYPOINT_OFFSET - wayp.tasks.append(EscortTaskAction(escorted_group.id, engagement_max_dist=ESCORT_ENGAGEMENT_MAX_DIST, lastwpt=waypoint_index)) + group.points[0].tasks.append(EscortTaskAction(escorted_group.id, engagement_max_dist=ESCORT_ENGAGEMENT_MAX_DIST, lastwpt=waypoint_index)) if should_orbit: orbit_task = ControlledTask(OrbitAction(ATTACK_CIRCLE_ALT, pattern=OrbitAction.OrbitPattern.Circle)) diff --git a/gen/airsupportgen.py b/gen/airsupportgen.py index e3e34aa3..a3c56562 100644 --- a/gen/airsupportgen.py +++ b/gen/airsupportgen.py @@ -25,7 +25,7 @@ class AirSupportConflictGenerator: tanker_unit = db.find_unittype(Refueling, self.conflict.attackers_side.name)[0] tanker_heading = self.conflict.to_cp.position.heading_between_point(self.conflict.from_cp.position) tanker_position = self.conflict.from_cp.position.point_from_heading(tanker_heading, TANKER_DISTANCE) - self.mission.refuel_flight( + tanker_group = self.mission.refuel_flight( country=self.mission.country(self.game.player), name=namegen.next_tanker_name(self.mission.country(self.game.player)), airport=None, @@ -34,8 +34,11 @@ class AirSupportConflictGenerator: altitude=TANKER_ALT, frequency=140, start_type=StartType.Warm, + tacanchannel="99X", ) + tanker_group.points[0].tasks.append(ActivateBeaconCommand(channel=10, unit_id=tanker_group.id, aa=False)) + if is_awacs_enabled: awacs_unit = db.find_unittype(AWACS, self.conflict.attackers_side.name)[0] self.mission.awacs_flight( @@ -45,6 +48,6 @@ class AirSupportConflictGenerator: altitude=AWACS_ALT, airport=None, position=self.conflict.position.random_point_within(AWACS_DISTANCE, AWACS_DISTANCE), - frequency=251, + frequency=180, start_type=StartType.Warm, ) diff --git a/gen/shipgen.py b/gen/shipgen.py index 31b28dc5..7634236e 100644 --- a/gen/shipgen.py +++ b/gen/shipgen.py @@ -15,12 +15,16 @@ class ShipGenerator: self.conflict = conflict def generate_carrier(self, type: ShipType, country: str, at: Point) -> ShipGroup: - return self.m.ship_group( + group = self.m.ship_group( country=self.m.country(country), name=namegen.next_carrier_name(self.m.country(country)), _type=type, position=at) + group.points[0].tasks.append(ActivateBeaconCommand(unit_id=group.id, channel=20, callsign="SHDW", aa=False)) + group.points[0].tasks.append(ActivateICLSCommand(unit_id=group.id, channel=1)) + return group + def generate_cargo(self, units: db.ShipDict) -> typing.Collection[ShipGroup]: groups = [] for unit_type, unit_count in units.items(): diff --git a/gen/triggergen.py b/gen/triggergen.py index 3c564b6c..859d0a6e 100644 --- a/gen/triggergen.py +++ b/gen/triggergen.py @@ -136,7 +136,7 @@ class TriggersGenerator: for vehicle_group in country.vehicle_group: vehicle_group.set_skill(Skill(skill_level)) - def generate(self, player_cp: ControlPoint, is_quick: bool, activation_trigger_radius: int): + def generate(self, player_cp: ControlPoint, is_quick: bool, activation_trigger_radius: int, awacs_enabled: bool): player_coalition = self.game.player == "USA" and "blue" or "red" enemy_coalition = player_coalition == "blue" and "red" or "blue" @@ -146,6 +146,19 @@ class TriggersGenerator: self._set_skill(player_coalition, enemy_coalition) self._set_allegiances(player_coalition, enemy_coalition) + description = "" + description += "FREQUENCIES:" + description += "\nFlight: 251 MHz AM" + description += "\nTanker: 10X/140 MHz" + + if awacs_enabled: + description += "\nAWACS: 180 MHz" + + if self.conflict.from_cp.is_global or self.conflict.to_cp.is_global: + description += "\nCarrier: 20X/ICLS CHAN1" + + self.mission.set_description_text(description) + if not is_quick: # TODO: waypoint parts of this should not be post-hacked but added in airgen self._gen_activation_trigger(activation_trigger_radius, player_cp, player_coalition, enemy_coalition) diff --git a/resources/persiangulf.gif b/resources/persiangulf.gif index 42a360aa..af08e704 100644 Binary files a/resources/persiangulf.gif and b/resources/persiangulf.gif differ diff --git a/theater/persiangulf.py b/theater/persiangulf.py index 2ccecf23..a61130bb 100644 --- a/theater/persiangulf.py +++ b/theater/persiangulf.py @@ -9,8 +9,8 @@ from .landmap import load_poly class PersianGulfTheater(ConflictTheater): terrain = dcs.terrain.PersianGulf() overview_image = "persiangulf.gif" - reference_points = {(persiangulf.Sir_Abu_Nuayr.position.x, persiangulf.Sir_Abu_Nuayr.position.y): (351, 115), - (persiangulf.Sirri_Island.position.x, persiangulf.Sirri_Island.position.y): (389, 22), } + reference_points = {(persiangulf.Sir_Abu_Nuayr.position.x, persiangulf.Sir_Abu_Nuayr.position.y): (321, 145), + (persiangulf.Sirri_Island.position.x, persiangulf.Sirri_Island.position.y): (347, 82), } landmap_poly = load_poly("resources\\gulflandmap.p") daytime_map = { "dawn": (6, 8), @@ -35,11 +35,13 @@ class PersianGulfTheater(ConflictTheater): tunb_kochak = ControlPoint.from_airport(persiangulf.Tunb_Kochak, [135, 180], SIZE_SMALL, 1.2, has_frontline=False) bandar_lengeh = ControlPoint.from_airport(persiangulf.Bandar_Lengeh, [270, 315, 0, 45], SIZE_SMALL, 1.1) - qeshm = ControlPoint.from_airport(persiangulf.Qeshm_Island, [270, 315, 0, 45, 90, 135, 180], SIZE_SMALL, 1.1, has_frontline=False) + qeshm = ControlPoint.from_airport(persiangulf.Qeshm_Island, [270, 315, 0, 45, 90, 135, 180], SIZE_SMALL, 1.3, has_frontline=False) - havadarya = ControlPoint.from_airport(persiangulf.Havadarya, COAST_DL_W, SIZE_REGULAR, IMPORTANCE_LOW) + havadarya = ControlPoint.from_airport(persiangulf.Havadarya, COAST_DL_W, SIZE_REGULAR, 1.2) bandar_abbas = ControlPoint.from_airport(persiangulf.Bandar_Abbas_Intl, LAND, SIZE_BIG, 1.3) - lar = ControlPoint.from_airport(persiangulf.Lar_Airbase, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + lar = ControlPoint.from_airport(persiangulf.Lar_Airbase, LAND, SIZE_REGULAR, 1.1) + shiraz = ControlPoint.from_airport(persiangulf.Shiraz_International_Airport, LAND, SIZE_BIG, IMPORTANCE_LOW) + kerman = ControlPoint.from_airport(persiangulf.Kerman_Airport, LAND, SIZE_BIG, IMPORTANCE_LOW) west_carrier = ControlPoint.carrier("East carrier", Point(-100531.972946, 60939.275818)) @@ -64,12 +66,14 @@ class PersianGulfTheater(ConflictTheater): self.add_controlpoint(self.qeshm, connected_to=[self.bandar_lengeh, self.havadarya, self.tunb_island, self.lar]) self.add_controlpoint(self.havadarya, connected_to=[self.lar, self.qeshm, self.bandar_abbas]) self.add_controlpoint(self.bandar_abbas, connected_to=[self.havadarya]) - self.add_controlpoint(self.lar, connected_to=[self.bandar_lengeh, self.qeshm, self.havadarya]) + self.add_controlpoint(self.lar, connected_to=[self.bandar_lengeh, self.qeshm, self.havadarya, self.shiraz, self.kerman]) + self.add_controlpoint(self.shiraz, connected_to=[self.lar, self.kerman]) + self.add_controlpoint(self.kerman, connected_to=[self.lar, self.shiraz]) self.add_controlpoint(self.west_carrier) self.west_carrier.captured = True - self.lar.captured = True + self.kerman.captured = True """ Mid game: diff --git a/ui/configurationmenu.py b/ui/configurationmenu.py index c52e8a59..7add0536 100644 --- a/ui/configurationmenu.py +++ b/ui/configurationmenu.py @@ -20,11 +20,15 @@ class ConfigurationMenu(Menu): self.night_var = BooleanVar() self.night_var.set(self.game.settings.night_disabled) + self.cold_start_var = BooleanVar() + self.cold_start_var.set(self.game.settings.cold_start) + def dismiss(self): self.game.settings.player_skill = self.player_skill_var.get() self.game.settings.enemy_skill = self.enemy_skill_var.get() self.game.settings.only_player_takeoff = self.takeoff_var.get() self.game.settings.night_disabled = self.night_var.get() + self.game.settings.cold_start = self.cold_start_var.get() super(ConfigurationMenu, self).dismiss() def display(self): @@ -36,11 +40,16 @@ class ConfigurationMenu(Menu): OptionMenu(self.frame, self.player_skill_var, "Average", "Good", "High", "Excellent").grid(row=0, column=1) OptionMenu(self.frame, self.enemy_skill_var, "Average", "Good", "High", "Excellent").grid(row=1, column=1) - Checkbutton(self.frame, text="Takeoff only for player group", variable=self.takeoff_var).grid(row=2, column=0, columnspan=2) - Checkbutton(self.frame, text="Disable night missions", variable=self.night_var).grid(row=3, column=0, columnspan=2) + Label(self.frame, text="Aircraft cold start").grid(row=2, column=0) + Label(self.frame, text="Takeoff only for player group").grid(row=3, column=0) + Label(self.frame, text="Disable night missions").grid(row=4, column=0) - Button(self.frame, text="Back", command=self.dismiss).grid(row=4, column=0, columnspan=1) - Button(self.frame, text="Cheat +200m", command=self.cheat_money).grid(row=5, column=0) + Checkbutton(self.frame, variable=self.cold_start_var).grid(row=2, column=1) + Checkbutton(self.frame, variable=self.takeoff_var).grid(row=3, column=1) + Checkbutton(self.frame, variable=self.night_var).grid(row=4, column=1) + + Button(self.frame, text="Back", command=self.dismiss).grid(row=5, column=0, columnspan=1) + Button(self.frame, text="Cheat +200m", command=self.cheat_money).grid(row=6, column=1) def cheat_money(self): self.game.budget += 200 diff --git a/ui/overviewcanvas.py b/ui/overviewcanvas.py index 9fb58473..a235d8f1 100644 --- a/ui/overviewcanvas.py +++ b/ui/overviewcanvas.py @@ -28,20 +28,24 @@ class OverviewCanvas: point_b = list(self.game.theater.reference_points.keys())[1] point_b_img = self.game.theater.reference_points[point_b] - x_dist = point_a_img[0] - point_b_img[0] + Y_dist = point_a_img[0] - point_b_img[0] lon_dist = point_a[1] - point_b[1] - y_dist = point_a_img[1] - point_b_img[1] + X_dist = point_a_img[1] - point_b_img[1] lat_dist = point_b[0] - point_a[0] - x_scale = float(x_dist) / float(lon_dist) - y_scale = float(y_dist) / float(lat_dist) + Y_scale = float(Y_dist) / float(lon_dist) + X_scale = float(X_dist) / float(lat_dist) # --- - x_offset = p.x - point_a[0] - y_offset = p.y - point_a[1] + Y_offset = p.x - point_a[0] + X_offset = p.y - point_a[1] - return point_b_img[1] + y_offset * y_scale, point_a_img[0] - x_offset * x_scale + X = point_b_img[1] + X_offset * X_scale + Y = point_a_img[0] - Y_offset * Y_scale + + treshold = 30 + return X > treshold and X or treshold, Y > treshold and Y or treshold def create_cp_title(self, coords, cp: ControlPoint): title = cp.name