diff --git a/game/event/event.py b/game/event/event.py index d1f1da34..21c8aad0 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -220,7 +220,7 @@ class Event: if cp.captured and new_owner_coalition != coalition: cp.captured = False info = Information(cp.name + " lost !", - "The ennemy took control of " + cp.name + "\nShame on us !", + "We took control of " + cp.name + "! Great job !", self.game.turn) self.game.informations.append(info) pname = self.game.enemy_name diff --git a/gen/aircraft.py b/gen/aircraft.py index 6d70b56e..25b4c891 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -51,33 +51,6 @@ class AircraftConflictGenerator: 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]), - int(self.conflict.size * SPREAD_DISTANCE_FACTOR[1]), - ) - return point.random_point_within(distance, self.conflict.size * SPREAD_DISTANCE_FACTOR[0]) - - def _split_to_groups(self, dict: db.PlaneDict, clients: db.PlaneDict = None) -> typing.Collection[typing.Tuple[FlyingType, int, int]]: - for flying_type, count in dict.items(): - if clients: - client_count = clients.get(flying_type, 0) - else: - client_count = 0 - - if flying_type == F_14B: - # workaround since 2 and 3 tomcat collide on carrier - group_size = 2 - else: - group_size = 4 - - while count > 0: - group_size = min(count, group_size) - client_size = max(min(client_count, group_size), 0) - - yield (flying_type, group_size, client_size) - count -= group_size - client_count -= client_size def _setup_group(self, group: FlyingGroup, for_task: typing.Type[Task], client_count: int): did_load_loadout = False @@ -251,37 +224,6 @@ class AircraftConflictGenerator: else: assert False - def _generate_escort(self, side: Country, units: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition, cp, is_quick=False, should_orbit=False): - groups = [] - for flying_type, count, client_count in self._split_to_groups(units, clients): - group = self._generate_group( - name=namegen.next_unit_name(side, cp.id, flying_type), - side=side, - unit_type=flying_type, - count=count, - client_count=client_count, - at=at) - - group.task = Escort.name - self._setup_group(group, CAP, client_count) - - for escorted_group, waypoint_index in self.escort_targets: - waypoint_index += 1 - if not is_quick: - waypoint_index += TRIGGER_WAYPOINT_OFFSET - - 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)) - orbit_task.stop_after_duration(ATTACK_CIRCLE_DURATION * 60) - - orbit_waypoint = self._add_radio_waypoint(group, self.conflict.position, CAS_ALTITUDE) - orbit_waypoint.tasks.append(orbit_task) - orbit_waypoint.tasks.append(EngageTargets(max_distance=DEFENCE_ENGAGEMENT_MAX_DISTANCE)) - - groups.append(group) - return groups def _setup_custom_payload(self, flight, group:FlyingGroup): if flight.use_custom_loadout: @@ -303,55 +245,16 @@ class AircraftConflictGenerator: def generate_flights(self, cp, country, flight_planner:FlightPlanner): - for flight in flight_planner.interceptor_flights: - group = self.generate_planned_flight(cp, country, flight) - self.setup_group_as_intercept_flight(group, flight) - self._setup_custom_payload(flight, group) - self.setup_group_activation_trigger(flight, group) - - for flight in flight_planner.cap_flights: - group = self.generate_planned_flight(cp, country, flight) - self.setup_group_as_cap_flight(group, flight) - self._setup_custom_payload(flight, group) - self.setup_group_activation_trigger(flight, group) - - for flight in flight_planner.cas_flights: - group = self.generate_planned_flight(cp, country, flight) - self.setup_group_as_cas_flight(group, flight) - self._setup_custom_payload(flight, group) - self.setup_group_activation_trigger(flight, group) - - for flight in flight_planner.sead_flights: - group = self.generate_planned_flight(cp, country, flight) - self.setup_group_as_sead_flight(group, flight) - self._setup_custom_payload(flight, group) - self.setup_group_activation_trigger(flight, group) - - for flight in flight_planner.strike_flights: - group = self.generate_planned_flight(cp, country, flight) - self.setup_group_as_strike_flight(group, flight) - self._setup_custom_payload(flight, group) - self.setup_group_activation_trigger(flight, group) - - for flight in flight_planner.custom_flights: + for flight in flight_planner.flights: group = self.generate_planned_flight(cp, country, flight) if flight.flight_type == FlightType.INTERCEPTION: self.setup_group_as_intercept_flight(group, flight) - elif flight.flight_type in [FlightType.CAP, FlightType.TARCAP, FlightType.BARCAP]: - self.setup_group_as_cap_flight(group, flight) - elif flight.flight_type in [FlightType.CAS, FlightType.BAI]: - self.setup_group_as_cas_flight(group, flight) - elif flight.flight_type in [FlightType.STRIKE]: - self.setup_group_as_strike_flight(group, flight) - elif flight.flight_type in [FlightType.ANTISHIP]: - self.setup_group_as_antiship_flight(group, flight) - elif flight.flight_type in [FlightType.SEAD, FlightType.DEAD]: - self.setup_group_as_sead_flight(group, flight) + self._setup_custom_payload(flight, group) else: - self.setup_group_as_cap_flight(group, flight) - self._setup_custom_payload(flight, group) + self.setup_flight_group(group, flight, flight.flight_type) self.setup_group_activation_trigger(flight, group) + def setup_group_activation_trigger(self, flight, group): if flight.scheduled_in > 0 and flight.client_count == 0: @@ -383,13 +286,12 @@ class AircraftConflictGenerator: else: activation_trigger.add_condition(CoalitionHasAirdrome(self.game.get_enemy_coalition_id(), flight.from_cp.id)) - activation_trigger.add_action(ActivateGroup(group.id)) self.m.triggerrules.triggers.append(activation_trigger) def generate_planned_flight(self, cp, country, flight:Flight): try: - if flight.client_count == 0 and self.game.perf_ai_parking_start: + if flight.client_count == 0 and self.game.settings.perf_ai_parking_start: flight.start_type = "Warm" if flight.start_type == "In Flight": @@ -447,19 +349,40 @@ class AircraftConflictGenerator: group.add_waypoint(Point(point.x,point.y), point.alt) - def setup_group_as_cap_flight(self, group, flight): - self._setup_group(group, CAP, flight.client_count) + def setup_flight_group(self, group, flight, flight_type): - #group.points[0].tasks.clear() - #group.tasks.clear() - #group.tasks.append(EngageTargets(max_distance=40, targets=[Targets.All.Air])) - #group.tasks.append(EngageTargets(max_distance=nm_to_meter(120), targets=[Targets.All.Air])) + + if flight_type in [FlightType.CAP, FlightType.BARCAP, FlightType.TARCAP]: + self._setup_group(group, CAP, flight.client_count) + # group.points[0].tasks.clear() + # group.tasks.clear() + # group.tasks.append(EngageTargets(max_distance=40, targets=[Targets.All.Air])) + # group.tasks.append(EngageTargets(max_distance=nm_to_meter(120), targets=[Targets.All.Air])) + pass + elif flight_type in [FlightType.CAS, FlightType.BAI]: + self._setup_group(group, CAS, flight.client_count) + group.points[0].tasks.clear() + group.points[0].tasks.append(CASTaskAction()) + group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)) + group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree)) + elif flight_type in [FlightType.SEAD, FlightType.DEAD]: + self._setup_group(group, SEAD, flight.client_count) + group.points[0].tasks.clear() + group.points[0].tasks.append(SEADTaskAction()) + group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)) + group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree)) + group.points[0].tasks.append(OptRestrictJettison(True)) + elif flight_type in [FlightType.STRIKE]: + self._setup_group(group, PinpointStrike, flight.client_count) + group.points[0].tasks.clear() + group.points[0].tasks.append(CASTaskAction()) + group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)) + group.points[0].tasks.append(OptROE(OptROE.Values.OpenFire)) + group.points[0].tasks.append(OptRestrictJettison(True)) for i, point in enumerate(flight.points): - if not point.only_for_player or (point.only_for_player and flight.client_count > 0): pt = group.add_waypoint(Point(point.x, point.y), point.alt) - if point.waypoint_type == FlightWaypointType.PATROL_TRACK: action = OrbitAction(altitude=pt.alt, pattern=OrbitAction.OrbitPattern.RaceTrack) pt.tasks.append(action) @@ -469,66 +392,22 @@ class AircraftConflictGenerator: # pt.tasks.append(engagetgt) elif point.waypoint_type == FlightWaypointType.LANDING_POINT: pt.type = "Land" + elif point.waypoint_type == FlightWaypointType.INGRESS_STRIKE: + for j, t in enumerate(point.targets): + if hasattr(t, "obj_name"): + buildings = self.game.theater.find_ground_objects_by_obj_name(t.obj_name) + for j, building in enumerate(buildings): + group.points[i].tasks.append(Bombing(building.position)) + if group.units[0].unit_type == JF_17 and j < 4: + group.add_nav_target_point(building.position, "PP" + str(j + 1)) + if group.units[0].unit_type == F_14B and j == 0: + group.add_nav_target_point(building.position, "ST") + else: + group.points[i].tasks.append(Bombing(t.position)) + if pt is not None: + pt.alt_type = point.alt_type - - def setup_group_as_cas_flight(self, group, flight): - group.task = CAS.name - self._setup_group(group, CAS, flight.client_count) - - group.points[0].tasks.clear() - group.points[0].tasks.append(CASTaskAction()) - group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)) - group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree)) - #group.points[0].tasks.append(OptRestrictJettison(True)) - - for point in flight.points: - group.add_waypoint(Point(point.x,point.y), point.alt) - - def setup_group_as_sead_flight(self, group, flight): - group.task = SEAD.name - self._setup_group(group, SEAD, flight.client_count) - - group.points[0].tasks.clear() - group.points[0].tasks.append(SEADTaskAction()) - group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)) - group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree)) - group.points[0].tasks.append(OptRestrictJettison(True)) - - i = 1 - for point in flight.points: - group.add_waypoint(Point(point.x,point.y), point.alt) - group.points[i].tasks.clear() - group.points[i].tasks.append(SEADTaskAction()) - i = i + 1 - - def setup_group_as_strike_flight(self, group, flight): - group.task = PinpointStrike.name - self._setup_group(group, GroundAttack, flight.client_count) - - group.points[0].tasks.clear() - group.points[0].tasks.append(CASTaskAction()) - group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)) - group.points[0].tasks.append(OptROE(OptROE.Values.OpenFire)) - group.points[0].tasks.append(OptRestrictJettison(True)) - - i = 1 - bombing_point_found = False - for point in flight.points: - group.add_waypoint(Point(point.x,point.y), point.alt) - if not bombing_point_found: - for j, t in enumerate(point.targets): - if hasattr(t, "obj_name"): - buildings = self.game.theater.find_ground_objects_by_obj_name(t.obj_name) - for j, building in enumerate(buildings): - group.points[i].tasks.append(Bombing(building.position)) - if group.units[0].unit_type == JF_17 and j < 4: - group.add_nav_target_point(building.position, "PP" + str(j+1)) - if group.units[0].unit_type == F_14B and j == 0: - group.add_nav_target_point(building.position, "ST") - else: - group.points[i].tasks.append(Bombing(t.position)) - bombing_point_found = True - i = i + 1 + self._setup_custom_payload(flight, group) def setup_group_as_antiship_flight(self, group, flight): diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index fc4bc777..f47b71f4 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -161,9 +161,8 @@ class FlightPlanner: patrol_alt = random.randint(PATROL_ALT_RANGE[0], PATROL_ALT_RANGE[1]) - # Choose a location for CAP patrols (Either behind frontline, or to protect ground objects) - rng = random.randint(0,100) - if rng < 80 and len(self._get_cas_locations()) > 0: + # Choose a location for CAP patrols (Either behind frontline if there is one, or to protect ground objects) + if len(self._get_cas_locations()) > 0: loc = random.choice(self._get_cas_locations()) ingress, heading, distance = Conflict.frontline_vector(self.from_cp, loc, self.game.theater) center = ingress.point_from_heading(heading, distance / 2) @@ -186,13 +185,7 @@ class FlightPlanner: # Create points - ascend_heading = random.randint(0, 360) - pos_ascend = self.from_cp.position.point_from_heading(ascend_heading, 30000) - ascend = FlightWaypoint(pos_ascend.x, pos_ascend.y, patrol_alt) - ascend.name = "ASCEND" - ascend.description = "Ascend to alt [" + str(meter_to_feet(patrol_alt)) + " ft]" - ascend.pretty_name = "Ascend to alt [" + str(meter_to_feet(patrol_alt)) + " ft]" - ascend.waypoint_type = FlightWaypointType.ASCEND_POINT + ascend = self.generate_ascend_point(self.from_cp) flight.points.append(ascend) orbit0 = FlightWaypoint(orbit0p.x, orbit0p.y, patrol_alt) @@ -216,20 +209,10 @@ class FlightPlanner: orbit0.targets.append(ground_object) obj_added.append(ground_object.obj_name) - descend = self.from_cp.position.point_from_heading(ascend_heading-180, 30000) - descend = FlightWaypoint(descend.x, descend.y, PATTERN_ALTITUDE) - descend.name = "DESCEND" - descend.description = "Descend to pattern alt [5000ft]" - descend.pretty_name = "Descend to pattern alt [5000ft]" - descend.waypoint_type = FlightWaypointType.DESCENT_POINT + descend = self.generate_descend_point(self.from_cp) flight.points.append(descend) - rtb = self.from_cp.position.point_from_heading(ascend_heading - 180, 30000) - rtb = FlightWaypoint(rtb.x, rtb.y, PATTERN_ALTITUDE) - rtb.name = "LANDING" - rtb.description = "RTB" - rtb.pretty_name = "RTB" - rtb.waypoint_type = FlightWaypointType.LANDING_POINT + rtb = self.generate_rtb_waypoint(self.from_cp) flight.points.append(rtb) self.cap_flights.append(flight) @@ -269,9 +252,11 @@ class FlightPlanner: center = ingress.point_from_heading(heading, distance/2) egress = ingress.point_from_heading(heading, distance) - flight.targets.append(center) + ascend = self.generate_ascend_point(self.from_cp) + flight.points.append(ascend) ingress_point = FlightWaypoint(ingress.x, ingress.y, 1000) + ingress_point.alt_type = "RADIO" ingress_point.name = "INGRESS" ingress_point.pretty_name = "INGRESS" ingress_point.description = "Ingress into CAS area" @@ -279,6 +264,7 @@ class FlightPlanner: flight.points.append(ingress_point) center_point = FlightWaypoint(center.x, center.y, 1000) + center_point.alt_type = "RADIO" center_point.description = "Provide CAS" center_point.name = "CAS" center_point.pretty_name = "INGRESS" @@ -286,12 +272,19 @@ class FlightPlanner: flight.points.append(center_point) egress_point = FlightWaypoint(egress.x, egress.y, 1000) + egress_point.alt_type = "RADIO" egress_point.description = "Egress from CAS area" egress_point.name = "EGRESS" egress_point.pretty_name = "EGRESS" egress_point.waypoint_type = FlightWaypointType.EGRESS flight.points.append(egress_point) + descend = self.generate_descend_point(self.from_cp) + flight.points.append(descend) + + rtb = self.generate_rtb_waypoint(self.from_cp) + flight.points.append(rtb) + self.cas_flights.append(flight) self.flights.append(flight) @@ -326,6 +319,9 @@ class FlightPlanner: flight.points = [] flight.scheduled_in = offset + i*random.randint(SEAD_EVERY_X_MINUTES-5, SEAD_EVERY_X_MINUTES+5) + ascend = self.generate_ascend_point(self.from_cp) + flight.points.append(ascend) + location = self.potential_sead_targets[0][0] self.potential_sead_targets.pop(0) @@ -341,6 +337,7 @@ class FlightPlanner: flight.points.append(ingress_point) point = FlightWaypoint(location.position.x, location.position.y, 0) + point.alt_type = "RADIO" if flight.flight_type == FlightType.DEAD: point.description = "SEAD on " + location.obj_name point.pretty_name = "SEAD on " + location.obj_name @@ -355,11 +352,17 @@ class FlightPlanner: egress_pos = location.position.point_from_heading(egress_heading, INGRESS_EGRESS_DISTANCE) egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, EGRESS_ALT) - egress_point.pretty_name = "EGRESS on " + location.obj_name - egress_point.description = "EGRESS on " + location.obj_name + egress_point.pretty_name = "EGRESS from " + location.obj_name + egress_point.description = "EGRESS from " + location.obj_name egress_point.waypoint_type = FlightWaypointType.EGRESS flight.points.append(egress_point) + descend = self.generate_descend_point(self.from_cp) + flight.points.append(descend) + + rtb = self.generate_rtb_waypoint(self.from_cp) + flight.points.append(rtb) + self.sead_flights.append(flight) self.flights.append(flight) @@ -394,6 +397,9 @@ class FlightPlanner: flight.points = [] flight.scheduled_in = offset + i*random.randint(SEAD_EVERY_X_MINUTES-5, SEAD_EVERY_X_MINUTES+5) + ascend = self.generate_ascend_point(self.from_cp) + flight.points.append(ascend) + location = self.potential_strike_targets[0][0] self.potential_strike_targets.pop(0) @@ -424,10 +430,16 @@ class FlightPlanner: egress_pos = location.position.point_from_heading(egress_heading, INGRESS_EGRESS_DISTANCE) egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, EGRESS_ALT) - egress_point.pretty_name = "EGRESS on " + location.obj_name - egress_point.description = "EGRESS on " + location.obj_name + egress_point.pretty_name = "EGRESS from " + location.obj_name + egress_point.description = "EGRESS from " + location.obj_name flight.points.append(egress_point) + descend = self.generate_descend_point(self.from_cp) + flight.points.append(descend) + + rtb = self.generate_rtb_waypoint(self.from_cp) + flight.points.append(rtb) + self.strike_flights.append(flight) self.flights.append(flight) @@ -524,3 +536,36 @@ class FlightPlanner: del base_aircraft_inventory[f.unit_type] return base_aircraft_inventory + def generate_ascend_point(self, from_cp): + ascend_heading = from_cp.heading + pos_ascend = from_cp.position.point_from_heading(ascend_heading, 10000) + ascend = FlightWaypoint(pos_ascend.x, pos_ascend.y, PATTERN_ALTITUDE) + ascend.name = "ASCEND" + ascend.alt_type = "RADIO" + ascend.description = "Ascend to alt [" + str(meter_to_feet(PATTERN_ALTITUDE)) + " ft AGL], then proceed to next waypoint" + ascend.pretty_name = "Ascend to alt [" + str(meter_to_feet(PATTERN_ALTITUDE)) + " ft AGL]" + ascend.waypoint_type = FlightWaypointType.ASCEND_POINT + return ascend + + def generate_descend_point(self, from_cp): + ascend_heading = from_cp.heading + descend = from_cp.position.point_from_heading(ascend_heading - 180, 30000) + descend = FlightWaypoint(descend.x, descend.y, PATTERN_ALTITUDE) + descend.name = "DESCEND" + descend.alt_type = "RADIO" + descend.description = "Descend to pattern alt [" + str(meter_to_feet(PATTERN_ALTITUDE)) + " ft AGL], contact tower, and land" + descend.pretty_name = "Descend to pattern alt [" + str(meter_to_feet(PATTERN_ALTITUDE)) + " ft AGL]" + descend.waypoint_type = FlightWaypointType.DESCENT_POINT + return descend + + def generate_rtb_waypoint(self, from_cp): + ascend_heading = from_cp.heading + rtb = from_cp.position.point_from_heading(ascend_heading - 180, 30000) + rtb = FlightWaypoint(rtb.x, rtb.y, 0) + rtb.name = "LANDING" + rtb.alt_type = "RADIO" + rtb.description = "RTB" + rtb.pretty_name = "RTB" + rtb.waypoint_type = FlightWaypointType.LANDING_POINT + return rtb + diff --git a/gen/flights/flight.py b/gen/flights/flight.py index 84bd5c32..e24dd92f 100644 --- a/gen/flights/flight.py +++ b/gen/flights/flight.py @@ -54,6 +54,7 @@ class FlightWaypoint: self.x = x self.y = y self.alt = alt + self.alt_type = "BARO" self.name = "" self.description = "" self.targets = [] diff --git a/qt_ui/widgets/QPredefinedWaypointSelectionComboBox.py b/qt_ui/widgets/QPredefinedWaypointSelectionComboBox.py index 2ee5ba33..167ae8e6 100644 --- a/qt_ui/widgets/QPredefinedWaypointSelectionComboBox.py +++ b/qt_ui/widgets/QPredefinedWaypointSelectionComboBox.py @@ -93,15 +93,16 @@ class QPredefinedWaypointSelectionComboBox(QComboBox): pos = Conflict.frontline_position(self.game.theater, cp, ecp)[0] wpt = FlightWaypoint(pos.x, pos.y, 800) wpt.name = "Frontline " + cp.name + "/" + ecp.name + " [CAS]" + wpt.alt_type = "RADIO" wpt.pretty_name = wpt.name wpt.description = "Frontline" i = add_model_item(i, model, wpt.pretty_name, wpt) - for cp in self.game.theater.controlpoints: for ground_object in cp.ground_objects: if not ground_object.is_dead and not ground_object.dcs_identifier == "AA": wpt = FlightWaypoint(ground_object.position.x,ground_object.position.y, 0) + wpt.alt_type = "RADIO" wpt.name = wpt.name = "[" + str(ground_object.obj_name) + "] : " + ground_object.category + " #" + str(ground_object.object_id) wpt.pretty_name = wpt.name wpt.obj_name = ground_object.obj_name @@ -119,6 +120,7 @@ class QPredefinedWaypointSelectionComboBox(QComboBox): for g in ground_object.groups: for j, u in enumerate(g.units): wpt = FlightWaypoint(u.position.x, u.position.y, 0) + wpt.alt_type = "RADIO" wpt.name = wpt.name = "[" + str(ground_object.obj_name) + "] : " + u.type + " #" + str(j) wpt.pretty_name = wpt.name wpt.targets.append(u) @@ -132,6 +134,7 @@ class QPredefinedWaypointSelectionComboBox(QComboBox): for cp in self.game.theater.controlpoints: wpt = FlightWaypoint(cp.position.x, cp.position.y, 0) + wpt.alt_type = "RADIO" wpt.name = cp.name if cp.captured: wpt.description = "Position of " + cp.name + " [Friendly Airbase]" diff --git a/theater/caucasus.py b/theater/caucasus.py index fa1e3d7f..1256ba58 100644 --- a/theater/caucasus.py +++ b/theater/caucasus.py @@ -180,7 +180,7 @@ class NorthCaucasus(ConflictTheater): super(NorthCaucasus, self).__init__() self.kutaisi = ControlPoint.from_airport(caucasus.Kutaisi, LAND, SIZE_SMALL, IMPORTANCE_LOW) - self.soganlug = ControlPoint.from_airport(caucasus.Soganlug, LAND, SIZE_SMALL, IMPORTANCE_LOW) + self.vaziani = ControlPoint.from_airport(caucasus.Vaziani, LAND, SIZE_SMALL, IMPORTANCE_LOW) self.maykop = ControlPoint.from_airport(caucasus.Maykop_Khanskaya, LAND, SIZE_LARGE, IMPORTANCE_HIGH) self.beslan = ControlPoint.from_airport(caucasus.Beslan, LAND, SIZE_REGULAR, IMPORTANCE_LOW) self.nalchik = ControlPoint.from_airport(caucasus.Nalchik, LAND, SIZE_REGULAR, 1.1) @@ -188,12 +188,12 @@ class NorthCaucasus(ConflictTheater): self.mozdok = ControlPoint.from_airport(caucasus.Mozdok, LAND, SIZE_BIG, 1.1) self.carrier_1 = ControlPoint.carrier("Carrier", mapping.Point(-285810.6875, 496399.1875)) - self.soganlug.frontline_offset = 0.5 - self.soganlug.base.strength = 1 + self.vaziani.frontline_offset = 0.5 + self.vaziani.base.strength = 1 - self.add_controlpoint(self.kutaisi, connected_to=[self.soganlug]) - self.add_controlpoint(self.soganlug, connected_to=[self.beslan, self.kutaisi]) - self.add_controlpoint(self.beslan, connected_to=[self.soganlug, self.mozdok, self.nalchik]) + self.add_controlpoint(self.kutaisi, connected_to=[self.vaziani]) + self.add_controlpoint(self.vaziani, connected_to=[self.beslan, self.kutaisi]) + self.add_controlpoint(self.beslan, connected_to=[self.vaziani, self.mozdok, self.nalchik]) self.add_controlpoint(self.nalchik, connected_to=[self.beslan, self.mozdok, self.mineralnye]) self.add_controlpoint(self.mozdok, connected_to=[self.nalchik, self.beslan, self.mineralnye]) self.add_controlpoint(self.mineralnye, connected_to=[self.nalchik, self.mozdok, self.maykop]) @@ -201,5 +201,5 @@ class NorthCaucasus(ConflictTheater): self.add_controlpoint(self.carrier_1, connected_to=[]) self.carrier_1.captured = True - self.soganlug.captured = True + self.vaziani.captured = True self.kutaisi.captured = True diff --git a/theater/controlpoint.py b/theater/controlpoint.py index 28431f02..0cf09872 100644 --- a/theater/controlpoint.py +++ b/theater/controlpoint.py @@ -65,18 +65,21 @@ class ControlPoint: self.tacanN = None self.tacanI = "TAC" self.icls = 0 + self.airport = None @classmethod def from_airport(cls, airport: Airport, radials: typing.Collection[int], size: int, importance: float, has_frontline=True): assert airport - return cls(airport.id, airport.name, airport.position, airport, radials, size, importance, has_frontline, cptype=ControlPointType.AIRBASE) + obj = cls(airport.id, airport.name, airport.position, airport, radials, size, importance, has_frontline, cptype=ControlPointType.AIRBASE) + obj.airport = airport() + return obj @classmethod def carrier(cls, name: str, at: Point, id: int = 1001): import theater.conflicttheater cp = cls(id, name, at, at, theater.conflicttheater.LAND, theater.conflicttheater.SIZE_SMALL, 1, has_frontline=False, cptype=ControlPointType.AIRCRAFT_CARRIER_GROUP) - cp.tacanY = random.choice([True, False]) + cp.tacanY = False cp.tacanN = random.randint(26, 49) cp.tacanI = random.choice(["STE", "CVN", "CVH", "CCV", "ACC", "ARC", "GER", "ABR", "LIN", "TRU"]) ControlPoint.ICLS_counter = ControlPoint.ICLS_counter + 1 @@ -88,11 +91,20 @@ class ControlPoint: import theater.conflicttheater cp = cls(id, name, at, at, theater.conflicttheater.LAND, theater.conflicttheater.SIZE_SMALL, 1, has_frontline=False, cptype=ControlPointType.LHA_GROUP) - cp.tacanY = random.choice([True, False]) + cp.tacanY = False cp.tacanN = random.randint(1,25) cp.tacanI = random.choice(["LHD", "LHA", "LHB", "LHC", "LHD", "LDS"]) return cp + @property + def heading(self): + if self.cptype == ControlPointType.AIRBASE: + return self.airport.runways[0].heading + elif self.cptype in [ControlPointType.AIRCRAFT_CARRIER_GROUP, ControlPointType.LHA_GROUP]: + return 0 # TODO compute heading + else: + return 0 + def __str__(self): return self.name