def scene_create_lines_for_cp(self, cp: ControlPoint, playerColor, enemyColor): scene = self.scene() pos = self._transform_point(cp.position) for connected_cp in cp.connected_points: pos2 = self._transform_point(connected_cp.position) if not cp.captured: color = CONST.COLORS["dark_"+enemyColor] elif cp.captured: color = CONST.COLORS["dark_"+playerColor] else: color = CONST.COLORS["dark_"+enemyColor] pen = QPen(brush=color) pen.setColor(color) pen.setWidth(6) if cp.captured and not connected_cp.captured and Conflict.has_frontline_between(cp, connected_cp): if not cp.captured: scene.addLine(pos[0], pos[1], pos2[0], pos2[1], pen=pen) else: posx, h = Conflict.frontline_position(self.game.theater, cp, connected_cp) pos2 = self._transform_point(posx) scene.addLine(pos[0], pos[1], pos2[0], pos2[1], pen=pen) p1 = point_from_heading(pos2[0], pos2[1], h+180, 25) p2 = point_from_heading(pos2[0], pos2[1], h, 25) frontline_pen = QPen(brush=CONST.COLORS["bright_red"]) frontline_pen.setColor(CONST.COLORS["orange"]) frontline_pen.setWidth(8) scene.addLine(p1[0], p1[1], p2[0], p2[1], pen=frontline_pen) else: scene.addLine(pos[0], pos[1], pos2[0], pos2[1], pen=pen)
def _generate_ground_conflicts(cls) -> None: """For each frontline in the Operation, generate the ground conflicts and JTACs""" cls.jtacs = [] for front_line in cls.game.theater.conflicts(): player_cp = front_line.blue_cp enemy_cp = front_line.red_cp conflict = Conflict.frontline_cas_conflict( 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, cls.game.theater, ) # Generate frontline ops player_gp = cls.game.ground_planners[player_cp.id].units_per_cp[ enemy_cp.id] enemy_gp = cls.game.ground_planners[enemy_cp.id].units_per_cp[ player_cp.id] ground_conflict_gen = GroundConflictGenerator( cls.current_mission, conflict, cls.game, player_gp, enemy_gp, player_cp.stances[enemy_cp.id], cls.unit_map, ) ground_conflict_gen.generate() cls.jtacs.extend(ground_conflict_gen.jtacs)
def conflicts(cls) -> Iterable[Conflict]: assert cls.game for frontline in cls.game.theater.conflicts(): yield Conflict(cls.game.theater, frontline.control_point_a, frontline.control_point_b, cls.game.player_name, cls.game.enemy_name, cls.game.player_country, cls.game.enemy_country, frontline.position)
def front_lines(self) -> Iterator[FrontLine]: """Iterates over all active front lines in the theater.""" for cp in self.friendly_control_points(): for connected in cp.connected_points: if connected.is_friendly(self.is_player): continue if Conflict.has_frontline_between(cp, connected): yield FrontLine(cp, connected, self.game.theater)
def _frontline_vector(self, from_cp: ControlPoint, to_cp: ControlPoint): # Cache mechanism to avoid performing frontline vector computation on every frame key = str(from_cp.id) + "_" + str(to_cp.id) if key in self.frontline_vector_cache: return self.frontline_vector_cache[key] else: frontline = Conflict.frontline_vector(from_cp, to_cp, self.game.theater) self.frontline_vector_cache[key] = frontline return frontline
def generate_frontline_cap(self, flight, ally_cp, enemy_cp): """ Generate a cap flight for the frontline between ally_cp and enemy cp in order to ensure air superiority and protect friendly CAP airbase :param flight: Flight to setup :param ally_cp: CP to protect :param enemy_cp: Enemy connected cp """ flight.flight_type = FlightType.CAP patrol_alt = random.randint(self.doctrine["PATROL_ALT_RANGE"][0], self.doctrine["PATROL_ALT_RANGE"][1]) # Find targets waypoints ingress, heading, distance = Conflict.frontline_vector( ally_cp, enemy_cp, self.game.theater) center = ingress.point_from_heading(heading, distance / 2) orbit_center = center.point_from_heading( heading - 90, random.randint(nm_to_meter(6), nm_to_meter(15))) combat_width = distance / 2 if combat_width > 500000: combat_width = 500000 if combat_width < 35000: combat_width = 35000 radius = combat_width * 1.25 orbit0p = orbit_center.point_from_heading(heading, radius) orbit1p = orbit_center.point_from_heading(heading + 180, radius) # Create points ascend = self.generate_ascend_point(flight.from_cp) flight.points.append(ascend) orbit0 = FlightWaypoint(orbit0p.x, orbit0p.y, patrol_alt) orbit0.name = "ORBIT 0" orbit0.description = "Standby between this point and the next one" orbit0.pretty_name = "Race-track start" orbit0.waypoint_type = FlightWaypointType.PATROL_TRACK flight.points.append(orbit0) orbit1 = FlightWaypoint(orbit1p.x, orbit1p.y, patrol_alt) orbit1.name = "ORBIT 1" orbit1.description = "Standby between this point and the previous one" orbit1.pretty_name = "Race-track end" orbit1.waypoint_type = FlightWaypointType.PATROL flight.points.append(orbit1) # Note : Targets of a PATROL TRACK waypoints are the points to be defended orbit0.targets.append(flight.from_cp) orbit0.targets.append(center) descend = self.generate_descend_point(flight.from_cp) flight.points.append(descend) rtb = self.generate_rtb_waypoint(flight.from_cp) flight.points.append(rtb)
def generate_cas(self, flight, from_cp, location): """ Generate a CAS flight at a given location :param flight: Flight to setup :param location: Location of the CAS targets """ is_helo = hasattr(flight.unit_type, "helicopter") and flight.unit_type.helicopter cap_alt = 1000 flight.points = [] flight.flight_type = FlightType.CAS ingress, heading, distance = Conflict.frontline_vector( from_cp, location, self.game.theater) center = ingress.point_from_heading(heading, distance / 2) egress = ingress.point_from_heading(heading, distance) ascend = self.generate_ascend_point(flight.from_cp) if is_helo: cap_alt = 500 ascend.alt = 500 flight.points.append(ascend) ingress_point = FlightWaypoint(ingress.x, ingress.y, cap_alt) ingress_point.alt_type = "RADIO" ingress_point.name = "INGRESS" ingress_point.pretty_name = "INGRESS" ingress_point.description = "Ingress into CAS area" ingress_point.waypoint_type = FlightWaypointType.INGRESS_CAS flight.points.append(ingress_point) center_point = FlightWaypoint(center.x, center.y, cap_alt) center_point.alt_type = "RADIO" center_point.description = "Provide CAS" center_point.name = "CAS" center_point.pretty_name = "CAS" center_point.waypoint_type = FlightWaypointType.CAS flight.points.append(center_point) egress_point = FlightWaypoint(egress.x, egress.y, cap_alt) 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(flight.from_cp) if is_helo: descend.alt = 300 flight.points.append(descend) rtb = self.generate_rtb_waypoint(flight.from_cp) flight.points.append(rtb)
def air_conflict(cls) -> Conflict: assert cls.game player_cp, enemy_cp = cls.game.theater.closest_opposing_control_points( ) mid_point = player_cp.position.point_from_heading( player_cp.position.heading_between_point(enemy_cp.position), player_cp.position.distance_to_point(enemy_cp.position) / 2) return Conflict(cls.game.theater, player_cp, enemy_cp, cls.game.player_name, cls.game.enemy_name, cls.game.player_country, cls.game.enemy_country, mid_point)
def draw_actual_frontline(self, frontline: FrontLine, scene: QGraphicsScene, pen: QPen) -> None: self.draw_bezier_frontline(scene, pen, frontline) vector = Conflict.frontline_vector(frontline.control_point_a, frontline.control_point_b, self.game.theater) left_pos = self._transform_point(vector[0]) right_pos = self._transform_point(vector[0].point_from_heading( vector[1], vector[2])) scene.addItem( QFrontLine(left_pos[0], left_pos[1], right_pos[0], right_pos[1], frontline, self.game_model))
def for_faction(cls, game: Game, player: bool) -> ThreatZones: """Generates the threat zones projected by the given coalition. Args: game: The game to generate the threat zone for. player: True if the coalition projecting the threat zone belongs to the player. Returns: The threat zones projected by the given coalition. If the threat zone belongs to the player, it is the zone that will be avoided by the enemy and vice versa. """ air_threats = [] air_defenses = [] for control_point in game.theater.controlpoints: if control_point.captured != player: continue if control_point.runway_is_operational(): point = ShapelyPoint(control_point.position.x, control_point.position.y) cap_threat_range = cls.barcap_threat_range(game, control_point) air_threats.append(point.buffer(cap_threat_range.meters)) for tgo in control_point.ground_objects: for group in tgo.groups: threat_range = tgo.threat_range(group) # Any system with a shorter range than this is not worth # even avoiding. if threat_range > nautical_miles(3): point = ShapelyPoint(tgo.position.x, tgo.position.y) threat_zone = point.buffer(threat_range.meters) air_defenses.append(threat_zone) for front_line in game.theater.conflicts(player): vector = Conflict.frontline_vector(front_line.control_point_a, front_line.control_point_b, game.theater) start = vector[0] end = vector[0].point_from_heading(vector[1], vector[2]) line = LineString([ ShapelyPoint(start.x, start.y), ShapelyPoint(end.x, end.y), ]) doctrine = game.faction_for(player).doctrine air_threats.append( line.buffer(doctrine.cap_engagement_range.meters)) return cls(airbases=unary_union(air_threats), air_defenses=unary_union(air_defenses))
def air_conflict(cls) -> Conflict: assert cls.game player_cp, enemy_cp = cls.game.theater.closest_opposing_control_points( ) mid_point = player_cp.position.point_from_heading( player_cp.position.heading_between_point(enemy_cp.position), player_cp.position.distance_to_point(enemy_cp.position) / 2, ) return Conflict( cls.game.theater, FrontLine(player_cp, enemy_cp), 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), mid_point, )
def scene_create_lines_for_cp(self, cp: ControlPoint, playerColor, enemyColor): scene = self.scene() for connected_cp in cp.connected_points: pos2 = self._transform_point(connected_cp.position) if not cp.captured: color = CONST.COLORS["dark_" + enemyColor] else: color = CONST.COLORS["dark_" + playerColor] pen = QPen(brush=color) pen.setColor(color) pen.setWidth(6) frontline = FrontLine(cp, connected_cp, self.game.theater) if cp.captured and not connected_cp.captured and Conflict.has_frontline_between( cp, connected_cp): if DisplayOptions.actual_frontline_pos: self.draw_actual_frontline(frontline, scene, pen) else: self.draw_frontline_approximation(frontline, scene, pen) else: self.draw_bezier_frontline(scene, pen, frontline)
def find_possible_waypoints(self): self.wpts = [] model = QStandardItemModel() i = 0 def add_model_item(i, model, name, wpt): item = QStandardItem(name) model.setItem(i, 0, item) self.wpts.append(wpt) return i + 1 if self.include_frontlines: for cp in self.game.theater.controlpoints: if cp.captured: enemy_cp = [ ecp for ecp in cp.connected_points if ecp.captured != cp.captured ] for ecp in enemy_cp: pos = Conflict.frontline_position( cp, ecp, self.game.theater)[0] wpt = FlightWaypoint( FlightWaypointType.CUSTOM, pos.x, pos.y, Distance.from_meters(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) if self.include_targets: for cp in self.game.theater.controlpoints: if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): for ground_object in cp.ground_objects: if not ground_object.is_dead and isinstance( ground_object, BuildingGroundObject): wpt = FlightWaypoint( FlightWaypointType.CUSTOM, ground_object.position.x, ground_object.position.y, Distance.from_meters(0), ) wpt.alt_type = "RADIO" wpt.name = ground_object.waypoint_name wpt.pretty_name = wpt.name wpt.obj_name = ground_object.obj_name wpt.targets.append(ground_object) if cp.captured: wpt.description = "Friendly Building" else: wpt.description = "Enemy Building" i = add_model_item(i, model, wpt.pretty_name, wpt) if self.include_units: for cp in self.game.theater.controlpoints: if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): for ground_object in cp.ground_objects: if (not ground_object.is_dead and ground_object.dcs_identifier == "AA"): for g in ground_object.groups: for j, u in enumerate(g.units): wpt = FlightWaypoint( FlightWaypointType.CUSTOM, u.position.x, u.position.y, Distance.from_meters(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) wpt.obj_name = ground_object.obj_name wpt.waypoint_type = FlightWaypointType.CUSTOM if cp.captured: wpt.description = "Friendly unit : " + u.type else: wpt.description = "Enemy unit : " + u.type i = add_model_item(i, model, wpt.pretty_name, wpt) if self.include_airbases: for cp in self.game.theater.controlpoints: if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): wpt = FlightWaypoint( FlightWaypointType.CUSTOM, cp.position.x, cp.position.y, Distance.from_meters(0), ) wpt.alt_type = "RADIO" wpt.name = cp.name if cp.captured: wpt.description = ("Position of " + cp.name + " [Friendly Airbase]") else: wpt.description = "Position of " + cp.name + " [Enemy Airbase]" if cp.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP: wpt.pretty_name = cp.name + " (Aircraft Carrier Group)" elif cp.cptype == ControlPointType.LHA_GROUP: wpt.pretty_name = cp.name + " (LHA Group)" else: wpt.pretty_name = cp.name + " (Airbase)" i = add_model_item(i, model, wpt.pretty_name, wpt) self.setModel(model)
def find_possible_waypoints(self): self.wpts = [] model = QStandardItemModel() i = 0 def add_model_item(i, model, name, wpt): print(name) item = QStandardItem(name) model.setItem(i, 0, item) self.wpts.append(wpt) return i + 1 if self.include_frontlines: for cp in self.game.theater.controlpoints: if cp.captured: enemy_cp = [ecp for ecp in cp.connected_points if ecp.captured != cp.captured] for ecp in enemy_cp: pos = Conflict.frontline_position(self.game.theater, cp, ecp)[0] wpt = FlightWaypoint( FlightWaypointType.CUSTOM, 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" wpt.data = [cp, ecp] wpt.category = PredefinedWaypointCategory.FRONTLINE i = add_model_item(i, model, wpt.pretty_name, wpt) if self.include_targets: for cp in self.game.theater.controlpoints: if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): for ground_object in cp.ground_objects: if not ground_object.is_dead and not ground_object.dcs_identifier == "AA": wpt = FlightWaypoint( FlightWaypointType.CUSTOM, 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 wpt.targets.append(ground_object) wpt.data = ground_object if cp.captured: wpt.description = "Friendly Building" wpt.category = PredefinedWaypointCategory.ALLY_BUILDING else: wpt.description = "Enemy Building" wpt.category = PredefinedWaypointCategory.ENEMY_BUILDING i = add_model_item(i, model, wpt.pretty_name, wpt) if self.include_units: for cp in self.game.theater.controlpoints: if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): for ground_object in cp.ground_objects: if not ground_object.is_dead and ground_object.dcs_identifier == "AA": for g in ground_object.groups: for j, u in enumerate(g.units): wpt = FlightWaypoint( FlightWaypointType.CUSTOM, 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) wpt.data = u wpt.obj_name = ground_object.obj_name wpt.waypoint_type = FlightWaypointType.CUSTOM if cp.captured: wpt.description = "Friendly unit : " + u.type wpt.category = PredefinedWaypointCategory.ALLY_UNIT else: wpt.description = "Enemy unit : " + u.type wpt.category = PredefinedWaypointCategory.ENEMY_UNIT i = add_model_item(i, model, wpt.pretty_name, wpt) if self.include_airbases: for cp in self.game.theater.controlpoints: if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): wpt = FlightWaypoint( FlightWaypointType.CUSTOM, cp.position.x, cp.position.y, 0 ) wpt.alt_type = "RADIO" wpt.name = cp.name wpt.data = cp if cp.captured: wpt.description = "Position of " + cp.name + " [Friendly Airbase]" wpt.category = PredefinedWaypointCategory.ALLY_CP else: wpt.description = "Position of " + cp.name + " [Enemy Airbase]" wpt.category = PredefinedWaypointCategory.ENEMY_CP if cp.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP: wpt.pretty_name = cp.name + " (Aircraft Carrier Group)" elif cp.cptype == ControlPointType.LHA_GROUP: wpt.pretty_name = cp.name + " (LHA Group)" else: wpt.pretty_name = cp.name + " (Airbase)" i = add_model_item(i, model, wpt.pretty_name, wpt) self.setModel(model)
def generate(self): radio_registry = RadioRegistry() tacan_registry = TacanRegistry() # Dedup beacon/radio frequencies, since some maps have some frequencies # used multiple times. beacons = load_beacons_for_terrain(self.game.theater.terrain.name) unique_map_frequencies: Set[RadioFrequency] = set() for beacon in beacons: unique_map_frequencies.add(beacon.frequency) if beacon.is_tacan: if beacon.channel is None: logging.error( f"TACAN beacon has no channel: {beacon.callsign}") else: tacan_registry.reserve(beacon.tacan_channel) for airfield, data in AIRFIELD_DATA.items(): if data.theater == self.game.theater.terrain.name: unique_map_frequencies.add(data.atc.hf) unique_map_frequencies.add(data.atc.vhf_fm) unique_map_frequencies.add(data.atc.vhf_am) unique_map_frequencies.add(data.atc.uhf) # No need to reserve ILS or TACAN because those are in the # beacon list. for frequency in unique_map_frequencies: radio_registry.reserve(frequency) # Set mission time and weather conditions. EnvironmentGenerator(self.current_mission, self.game.conditions).generate() # Generate ground object first groundobjectgen = GroundObjectsGenerator(self.current_mission, self.conflict, self.game, radio_registry, tacan_registry) groundobjectgen.generate() # Generate destroyed units for d in self.game.get_destroyed_units(): try: utype = db.unit_type_from_name(d["type"]) except KeyError: continue pos = Point(d["x"], d["z"]) if utype is not None and not self.game.position_culled( pos) and self.game.settings.perf_destroyed_units: self.current_mission.static_group( country=self.current_mission.country( self.game.player_country), name="", _type=utype, hidden=True, position=pos, heading=d["orientation"], dead=True, ) # Air Support (Tanker & Awacs) airsupportgen = AirSupportConflictGenerator(self.current_mission, self.conflict, self.game, radio_registry, tacan_registry) airsupportgen.generate(self.is_awacs_enabled) # Generate Activity on the map airgen = AircraftConflictGenerator(self.current_mission, self.conflict, self.game.settings, self.game, radio_registry) airgen.generate_flights( self.current_mission.country(self.game.player_country), self.game.blue_ato, groundobjectgen.runways) airgen.generate_flights( self.current_mission.country(self.game.enemy_country), self.game.red_ato, groundobjectgen.runways) # Generate ground units on frontline everywhere jtacs: List[JtacInfo] = [] for front_line in self.game.theater.conflicts(True): player_cp = front_line.control_point_a enemy_cp = front_line.control_point_b conflict = Conflict.frontline_cas_conflict( self.attacker_name, self.defender_name, self.current_mission.country(self.attacker_country), self.current_mission.country(self.defender_country), player_cp, enemy_cp, self.game.theater) # Generate frontline ops player_gp = self.game.ground_planners[player_cp.id].units_per_cp[ enemy_cp.id] enemy_gp = self.game.ground_planners[enemy_cp.id].units_per_cp[ player_cp.id] groundConflictGen = GroundConflictGenerator( self.current_mission, conflict, self.game, player_gp, enemy_gp, player_cp.stances[enemy_cp.id]) groundConflictGen.generate() jtacs.extend(groundConflictGen.jtacs) # Setup combined arms parameters self.current_mission.groundControl.pilot_can_control_vehicles = self.ca_slots > 0 if self.game.player_country in [ country.name for country in self.current_mission.coalition["blue"].countries.values() ]: self.current_mission.groundControl.blue_tactical_commander = self.ca_slots else: self.current_mission.groundControl.red_tactical_commander = self.ca_slots # Triggers triggersgen = TriggersGenerator(self.current_mission, self.conflict, self.game) triggersgen.generate() # Options forcedoptionsgen = ForcedOptionsGenerator(self.current_mission, self.conflict, self.game) forcedoptionsgen.generate() # Generate Visuals Smoke Effects visualgen = VisualGenerator(self.current_mission, self.conflict, self.game) if self.game.settings.perf_smoke_gen: visualgen.generate() luaData = {} luaData["AircraftCarriers"] = {} luaData["Tankers"] = {} luaData["AWACs"] = {} luaData["JTACs"] = {} luaData["TargetPoints"] = {} self.assign_channels_to_flights(airgen.flights, airsupportgen.air_support) for tanker in airsupportgen.air_support.tankers: luaData["Tankers"][tanker.callsign] = { "dcsGroupName": tanker.dcsGroupName, "callsign": tanker.callsign, "variant": tanker.variant, "radio": tanker.freq.mhz, "tacan": str(tanker.tacan.number) + tanker.tacan.band.name } if self.is_awacs_enabled: for awacs in airsupportgen.air_support.awacs: luaData["AWACs"][awacs.callsign] = { "dcsGroupName": awacs.dcsGroupName, "callsign": awacs.callsign, "radio": awacs.freq.mhz } for jtac in jtacs: luaData["JTACs"][jtac.callsign] = { "dcsGroupName": jtac.dcsGroupName, "callsign": jtac.callsign, "zone": jtac.region, "dcsUnit": jtac.unit_name, "laserCode": jtac.code } for flight in airgen.flights: if flight.friendly and flight.flight_type in [ FlightType.ANTISHIP, FlightType.DEAD, FlightType.SEAD, FlightType.STRIKE ]: flightType = flight.flight_type.name flightTarget = flight.package.target if flightTarget: flightTargetName = None flightTargetType = None if hasattr(flightTarget, 'obj_name'): flightTargetName = flightTarget.obj_name flightTargetType = flightType + f" TGT ({flightTarget.category})" elif hasattr(flightTarget, 'name'): flightTargetName = flightTarget.name flightTargetType = flightType + " TGT (Airbase)" luaData["TargetPoints"][flightTargetName] = { "name": flightTargetName, "type": flightTargetType, "position": { "x": flightTarget.position.x, "y": flightTarget.position.y } } # set a LUA table with data from Liberation that we want to set # at the moment it contains Liberation's install path, and an overridable definition for the JTACAutoLase function # later, we'll add data about the units and points having been generated, in order to facilitate the configuration of the plugin lua scripts state_location = "[[" + os.path.abspath(".") + "]]" lua = """ -- setting configuration table env.info("DCSLiberation|: setting configuration table") -- all data in this table is overridable. dcsLiberation = {} -- the base location for state.json; if non-existent, it'll be replaced with LIBERATION_EXPORT_DIR, TEMP, or DCS working directory dcsLiberation.installPath=""" + state_location + """ """ # Process the tankers lua += """ -- list the tankers generated by Liberation dcsLiberation.Tankers = { """ for key in luaData["Tankers"]: data = luaData["Tankers"][key] dcsGroupName = data["dcsGroupName"] callsign = data["callsign"] variant = data["variant"] tacan = data["tacan"] radio = data["radio"] lua += f" {{dcsGroupName='{dcsGroupName}', callsign='{callsign}', variant='{variant}', tacan='{tacan}', radio='{radio}' }}, \n" #lua += f" {{name='{dcsGroupName}', description='{callsign} ({variant})', information='Tacan:{tacan} Radio:{radio}' }}, \n" lua += "}" # Process the AWACSes lua += """ -- list the AWACs generated by Liberation dcsLiberation.AWACs = { """ for key in luaData["AWACs"]: data = luaData["AWACs"][key] dcsGroupName = data["dcsGroupName"] callsign = data["callsign"] radio = data["radio"] lua += f" {{dcsGroupName='{dcsGroupName}', callsign='{callsign}', radio='{radio}' }}, \n" #lua += f" {{name='{dcsGroupName}', description='{callsign} (AWACS)', information='Radio:{radio}' }}, \n" lua += "}" # Process the JTACs lua += """ -- list the JTACs generated by Liberation dcsLiberation.JTACs = { """ for key in luaData["JTACs"]: data = luaData["JTACs"][key] dcsGroupName = data["dcsGroupName"] callsign = data["callsign"] zone = data["zone"] laserCode = data["laserCode"] dcsUnit = data["dcsUnit"] lua += f" {{dcsGroupName='{dcsGroupName}', callsign='{callsign}', zone='{zone}', laserCode='{laserCode}', dcsUnit='{dcsUnit}' }}, \n" #lua += f" {{name='{dcsGroupName}', description='JTAC {callsign} ', information='Laser:{laserCode}', jtac={laserCode} }}, \n" lua += "}" # Process the Target Points lua += """ -- list the target points generated by Liberation dcsLiberation.TargetPoints = { """ for key in luaData["TargetPoints"]: data = luaData["TargetPoints"][key] name = data["name"] pointType = data["type"] positionX = data["position"]["x"] positionY = data["position"]["y"] lua += f" {{name='{name}', pointType='{pointType}', positionX='{positionX}', positionY='{positionY}' }}, \n" #lua += f" {{name='{pointType} {name}', point{{x={positionX}, z={positionY} }} }}, \n" lua += "}" lua += """ -- list the airbases generated by Liberation -- dcsLiberation.Airbases = {} -- list the aircraft carriers generated by Liberation -- dcsLiberation.Carriers = {} -- later, we'll add more data to the table """ trigger = TriggerStart(comment="Set DCS Liberation data") trigger.add_action(DoScript(String(lua))) self.current_mission.triggerrules.triggers.append(trigger) # Inject Plugins Lua Scripts and data for plugin in LuaPluginManager.plugins(): if plugin.enabled: plugin.inject_scripts(self) plugin.inject_configuration(self) self.assign_channels_to_flights(airgen.flights, airsupportgen.air_support) self.notify_info_generators(groundobjectgen, airsupportgen, jtacs, airgen)