コード例 #1
0
 def get_carrier_group_name(self):
     """
     Get the carrier group name if the airbase is a carrier
     :return: Carrier group name
     """
     if self.cptype in [
             ControlPointType.AIRCRAFT_CARRIER_GROUP,
             ControlPointType.LHA_GROUP
     ]:
         for g in self.ground_objects:
             if g.dcs_identifier == "CARRIER":
                 for group in g.groups:
                     for u in group.units:
                         if db.unit_type_from_name(u.type) in [
                                 CVN_74_John_C__Stennis,
                                 CV_1143_5_Admiral_Kuznetsov
                         ]:
                             return group.name
             elif g.dcs_identifier == "LHA":
                 for group in g.groups:
                     for u in group.units:
                         if db.unit_type_from_name(
                                 u.type) in [LHA_1_Tarawa]:
                             return group.name
     return None
コード例 #2
0
    def generate(self) -> None:
        if self.game.position_culled(self.ground_object.position):
            return

        for group in self.ground_object.groups:
            if not group.units:
                logging.warning(f"Found empty group in {self.ground_object}")
                continue

            unit_type = unit_type_from_name(group.units[0].type)
            if unit_type is None:
                raise RuntimeError(
                    f"Unrecognized unit type: {group.units[0].type}")

            vg = self.m.vehicle_group(self.country,
                                      group.name,
                                      unit_type,
                                      position=group.position,
                                      heading=group.units[0].heading)
            vg.units[0].name = self.m.string(group.units[0].name)
            vg.units[0].player_can_drive = True
            for i, u in enumerate(group.units):
                if i > 0:
                    vehicle = Vehicle(self.m.next_unit_id(),
                                      self.m.string(u.name), u.type)
                    vehicle.position.x = u.position.x
                    vehicle.position.y = u.position.y
                    vehicle.heading = u.heading
                    vehicle.player_can_drive = True
                    vg.add_unit(vehicle)

            self.enable_eplrs(vg, unit_type)
            self.set_alarm_state(vg)
コード例 #3
0
 def object_has_radar(ground_object: TheaterGroundObject) -> bool:
     """Returns True if the ground object contains a unit with radar."""
     for group in ground_object.groups:
         for unit in group.units:
             if db.unit_type_from_name(unit.type) in UNITS_WITH_RADAR:
                 return True
     return False
コード例 #4
0
 def create_ship(self, unit: Unit, atc_channel: RadioFrequency) -> Ship:
     ship = Ship(self.m.next_unit_id(), self.m.string(unit.name),
                 unit_type_from_name(unit.type))
     ship.position.x = unit.position.x
     ship.position.y = unit.position.y
     ship.heading = unit.heading
     # TODO: Verify.
     ship.set_frequency(atc_channel.hertz)
     return ship
コード例 #5
0
 def runway_is_operational(self) -> bool:
     # Necessary because it's possible for the carrier itself to have sunk
     # while its escorts are still alive.
     for g in self.ground_objects:
         if g.dcs_identifier in ["CARRIER", "LHA"]:
             for group in g.groups:
                 for u in group.units:
                     if db.unit_type_from_name(u.type) in [
                             CVN_74_John_C__Stennis, LHA_1_Tarawa,
                             CV_1143_5_Admiral_Kuznetsov,
                             Type_071_Amphibious_Transport_Dock]:
                         return True
     return False
コード例 #6
0
 def runway_is_operational(self) -> bool:
     # Necessary because it's possible for the carrier itself to have sunk
     # while its escorts are still alive.
     for group in self.find_main_tgo().groups:
         for u in group.units:
             if db.unit_type_from_name(u.type) in [
                     Stennis,
                     LHA_Tarawa,
                     KUZNECOW,
                     Type_071,
             ]:
                 return True
     return False
コード例 #7
0
    def generate(self) -> None:
        if self.game.position_culled(self.ground_object.position):
            return

        for group in self.ground_object.groups:
            if not group.units:
                logging.warning(f"Found empty group in {self.ground_object}")
                continue

            unit_type = unit_type_from_name(group.units[0].type)
            if unit_type is None:
                raise RuntimeError(f"Unrecognized unit type: {group.units[0].type}")

            self.generate_group(group, unit_type)
コード例 #8
0
 def get_carrier_group_name(self) -> Optional[str]:
     """
     Get the carrier group name if the airbase is a carrier
     :return: Carrier group name
     """
     if self.cptype in [
             ControlPointType.AIRCRAFT_CARRIER_GROUP,
             ControlPointType.LHA_GROUP,
     ]:
         for g in self.ground_objects:
             if g.dcs_identifier == "CARRIER":
                 for group in g.groups:
                     for u in group.units:
                         if db.unit_type_from_name(u.type) in [
                                 Stennis,
                                 KUZNECOW,
                         ]:
                             return group.name
             elif g.dcs_identifier == "LHA":
                 for group in g.groups:
                     for u in group.units:
                         if db.unit_type_from_name(u.type) in [LHA_Tarawa]:
                             return group.name
     return None
コード例 #9
0
 def add_front_line_units(self, group: Group, origin: ControlPoint) -> None:
     for unit in group.units:
         # The actual name is a String (the pydcs translatable string), which
         # doesn't define __eq__.
         name = str(unit.name)
         if name in self.front_line_units:
             raise RuntimeError(f"Duplicate front line unit: {name}")
         unit_type = db.unit_type_from_name(unit.type)
         if unit_type is None:
             raise RuntimeError(f"Unknown unit type: {unit.type}")
         if not issubclass(unit_type, VehicleType):
             raise RuntimeError(
                 f"{name} is a {unit_type.__name__}, expected a VehicleType"
             )
         self.front_line_units[name] = FrontLineUnit(unit_type, origin)
コード例 #10
0
 def has_runway(self):
     """
     Check whether this control point can have aircraft taking off or landing.
     :return:
     """
     if self.cptype in [ControlPointType.AIRCRAFT_CARRIER_GROUP, ControlPointType.LHA_GROUP] :
         for g in self.ground_objects:
             if g.dcs_identifier in ["CARRIER", "LHA"]:
                 for group in g.groups:
                     for u in group.units:
                         if db.unit_type_from_name(u.type) in [CVN_74_John_C__Stennis, LHA_1_Tarawa, CV_1143_5_Admiral_Kuznetsov]:
                             return True
         return False
     elif self.cptype in [ControlPointType.AIRBASE, ControlPointType.FARP]:
         return True
     else:
         return True
コード例 #11
0
 def generate_group(self, group_def: Group, unit_type: UnitType):
     group = self.m.ship_group(self.country,
                               group_def.name,
                               unit_type,
                               position=group_def.position,
                               heading=group_def.units[0].heading)
     group.units[0].name = self.m.string(group_def.units[0].name)
     # TODO: Skipping the first unit looks like copy pasta from the carrier.
     for unit in group_def.units[1:]:
         unit_type = unit_type_from_name(unit.type)
         ship = Ship(self.m.next_unit_id(), self.m.string(unit.name),
                     unit_type)
         ship.position.x = unit.position.x
         ship.position.y = unit.position.y
         ship.heading = unit.heading
         group.add_unit(ship)
     self.set_alarm_state(group)
コード例 #12
0
    def compute_sead_targets(self):
        """
        @return a list of potential sead targets in range
        """

        # target, distance
        self.potential_sead_targets = []

        for cp in [
                c for c in self.game.theater.controlpoints
                if c.captured != self.from_cp.captured
        ]:

            # Compute distance to current cp
            distance = math.hypot(cp.position.x - self.from_cp.position.x,
                                  cp.position.y - self.from_cp.position.y)

            # Then it's unlikely any ground object is range
            if distance > 2 * self.doctrine["SEAD_MAX_RANGE"]:
                return

            for g in cp.ground_objects:

                if g.dcs_identifier == "AA":

                    # Check that there is at least one unit with a radar in the ground objects unit groups
                    number_of_units = sum([
                        len([
                            r for r in group.units if db.unit_type_from_name(
                                r.type) in UNITS_WITH_RADAR
                        ]) for group in g.groups
                    ])
                    if number_of_units <= 0:
                        continue

                    # Compute distance to current cp
                    distance = math.hypot(
                        cp.position.x - self.from_cp.position.x,
                        cp.position.y - self.from_cp.position.y)

                    if distance < self.doctrine["SEAD_MAX_RANGE"]:
                        self.potential_sead_targets.append((g, distance))

        self.potential_sead_targets.sort(key=operator.itemgetter(1))
コード例 #13
0
 def generate_group(self, group_def: ShipGroup,
                    first_unit_type: Type[ShipType]) -> None:
     group = self.m.ship_group(
         self.country,
         group_def.name,
         first_unit_type,
         position=group_def.position,
         heading=group_def.units[0].heading,
     )
     group.units[0].name = group_def.units[0].name
     # TODO: Skipping the first unit looks like copy pasta from the carrier.
     for unit in group_def.units[1:]:
         unit_type = unit_type_from_name(unit.type)
         ship = Ship(self.m.next_unit_id(), unit.name, unit_type)
         ship.position.x = unit.position.x
         ship.position.y = unit.position.y
         ship.heading = unit.heading
         group.add_unit(ship)
     self.set_alarm_state(group)
     self._register_unit_group(group_def, group)
コード例 #14
0
    def aa_ranges(ground_object: TheaterGroundObject) -> Tuple[int, int]:
        detection_range = 0
        threat_range = 0
        for g in ground_object.groups:
            for u in g.units:
                unit = db.unit_type_from_name(u.type)
                if unit is None:
                    logging.error(f"Unknown unit type {u.type}")
                    continue

                # Some units in pydcs have detection_range and threat_range
                # defined, but explicitly set to None.
                unit_detection_range = getattr(unit, "detection_range", None)
                if unit_detection_range is not None:
                    detection_range = max(detection_range, unit_detection_range)

                unit_threat_range = getattr(unit, "threat_range", None)
                if unit_threat_range is not None:
                    threat_range = max(threat_range, unit_threat_range)

        return detection_range, threat_range
コード例 #15
0
    def generate(self):

        for cp in self.game.theater.controlpoints:

            if cp.captured:
                country = self.game.player_country
            else:
                country = self.game.enemy_country
            side = self.m.country(country)

            for ground_object in cp.ground_objects:
                if ground_object.dcs_identifier == "AA":

                    if self.game.position_culled(ground_object.position):
                        continue

                    for g in ground_object.groups:
                        if len(g.units) > 0:
                            utype = unit_type_from_name(g.units[0].type)

                            if not ground_object.sea_object:
                                vg = self.m.vehicle_group(
                                    side,
                                    g.name,
                                    utype,
                                    position=g.position,
                                    heading=g.units[0].heading)
                                vg.units[0].name = self.m.string(
                                    g.units[0].name)
                                vg.units[0].player_can_drive = True
                                for i, u in enumerate(g.units):
                                    if i > 0:
                                        vehicle = Vehicle(
                                            self.m.next_unit_id(),
                                            self.m.string(u.name), u.type)
                                        vehicle.position.x = u.position.x
                                        vehicle.position.y = u.position.y
                                        vehicle.heading = u.heading
                                        vehicle.player_can_drive = True
                                        vg.add_unit(vehicle)

                                if hasattr(utype, 'eplrs'):
                                    if utype.eplrs:
                                        vg.points[0].tasks.append(EPLRS(vg.id))
                            else:
                                vg = self.m.ship_group(
                                    side,
                                    g.name,
                                    utype,
                                    position=g.position,
                                    heading=g.units[0].heading)
                                vg.units[0].name = self.m.string(
                                    g.units[0].name)
                                for i, u in enumerate(g.units):
                                    utype = unit_type_from_name(u.type)
                                    if i > 0:
                                        ship = Ship(self.m.next_unit_id(),
                                                    self.m.string(u.name),
                                                    utype)
                                        ship.position.x = u.position.x
                                        ship.position.y = u.position.y
                                        ship.heading = u.heading
                                        vg.add_unit(ship)

                            if self.game.settings.perf_red_alert_state:
                                vg.points[0].tasks.append(OptAlarmState(2))
                            else:
                                vg.points[0].tasks.append(OptAlarmState(1))

                elif ground_object.dcs_identifier in ["CARRIER", "LHA"]:
                    for g in ground_object.groups:
                        if len(g.units) > 0:

                            utype = unit_type_from_name(g.units[0].type)
                            if ground_object.dcs_identifier == "CARRIER" and self.game.settings.supercarrier == True:
                                utype = db.upgrade_to_supercarrier(
                                    utype, cp.name)

                            sg = self.m.ship_group(side,
                                                   g.name,
                                                   utype,
                                                   position=g.position,
                                                   heading=g.units[0].heading)
                            atc_channel = self.radio_registry.alloc_uhf()
                            sg.set_frequency(atc_channel.hertz)
                            sg.units[0].name = self.m.string(g.units[0].name)

                            for i, u in enumerate(g.units):
                                if i > 0:
                                    ship = Ship(self.m.next_unit_id(),
                                                self.m.string(u.name),
                                                unit_type_from_name(u.type))
                                    ship.position.x = u.position.x
                                    ship.position.y = u.position.y
                                    ship.heading = u.heading
                                    # TODO: Verify.
                                    ship.set_frequency(atc_channel.hertz)
                                    sg.add_unit(ship)

                            # Find carrier direction (In the wind)
                            found_carrier_destination = False
                            attempt = 0
                            while not found_carrier_destination and attempt < 5:
                                point = sg.points[
                                    0].position.point_from_heading(
                                        self.m.weather.wind_at_ground.direction
                                        + 180, 100000 - attempt * 20000)
                                if self.game.theater.is_in_sea(point):
                                    found_carrier_destination = True
                                    sg.add_waypoint(point)
                                else:
                                    attempt = attempt + 1

                            # Set UP TACAN and ICLS
                            tacan = self.tacan_registry.alloc_for_band(
                                TacanBand.X)
                            icls_channel = next(self.icls_alloc)
                            # TODO: Assign these properly.
                            if ground_object.dcs_identifier == "CARRIER":
                                tacan_callsign = random.choice([
                                    "STE",
                                    "CVN",
                                    "CVH",
                                    "CCV",
                                    "ACC",
                                    "ARC",
                                    "GER",
                                    "ABR",
                                    "LIN",
                                    "TRU",
                                ])
                            else:
                                tacan_callsign = random.choice([
                                    "LHD",
                                    "LHA",
                                    "LHB",
                                    "LHC",
                                    "LHD",
                                    "LDS",
                                ])
                            sg.points[0].tasks.append(
                                ActivateBeaconCommand(
                                    channel=tacan.number,
                                    modechannel=tacan.band.value,
                                    callsign=tacan_callsign,
                                    unit_id=sg.units[0].id,
                                    aa=False))
                            sg.points[0].tasks.append(
                                ActivateICLSCommand(icls_channel,
                                                    unit_id=sg.units[0].id))
                            # TODO: Make unit name usable.
                            # This relies on one control point mapping exactly
                            # to one LHA, carrier, or other usable "runway".
                            # This isn't wholly true, since the DD escorts of
                            # the carrier group are valid for helicopters, but
                            # they aren't exposed as such to the game. Should
                            # clean this up so that's possible. We can't use the
                            # unit name since it's an arbitrary ID.
                            self.runways[cp.name] = RunwayData(
                                cp.name,
                                "N/A",
                                atc=atc_channel,
                                tacan=tacan,
                                tacan_callsign=tacan_callsign,
                                icls=icls_channel,
                            )

                else:

                    if self.game.position_culled(ground_object.position):
                        continue

                    static_type = None
                    if ground_object.dcs_identifier in warehouse_map:
                        static_type = warehouse_map[
                            ground_object.dcs_identifier]
                    elif ground_object.dcs_identifier in fortification_map:
                        static_type = fortification_map[
                            ground_object.dcs_identifier]
                    elif ground_object.dcs_identifier in FORTIFICATION_UNITS_ID:
                        for f in FORTIFICATION_UNITS:
                            if f.id == ground_object.dcs_identifier:
                                unit_type = f
                                break
                    else:
                        print("Didn't find {} in static _map(s)!".format(
                            ground_object.dcs_identifier))
                        continue

                    if static_type is None:
                        if not ground_object.is_dead:
                            group = self.m.vehicle_group(
                                country=side,
                                name=ground_object.string_identifier,
                                _type=unit_type,
                                position=ground_object.position,
                                heading=ground_object.heading,
                            )
                            logging.info(
                                "generated {}object identifier {} with mission id {}"
                                .format(
                                    "dead " if ground_object.is_dead else "",
                                    group.name, group.id))
                    else:
                        group = self.m.static_group(
                            country=side,
                            name=ground_object.string_identifier,
                            _type=static_type,
                            position=ground_object.position,
                            heading=ground_object.heading,
                            dead=ground_object.is_dead,
                        )

                        logging.info(
                            "generated {}object identifier {} with mission id {}"
                            .format("dead " if ground_object.is_dead else "",
                                    group.name, group.id))
コード例 #16
0
    def __init__(self, state_data, game):
        self.base_capture_events = state_data["base_capture_events"]
        self.killed_aircrafts = state_data["killed_aircrafts"]
        self.killed_ground_units = state_data["killed_ground_units"]
        self.weapons_fired = state_data["weapons_fired"]
        self.mission_ended = state_data["mission_ended"]

        logging.info("--------------------------------")
        logging.info("Starting Debriefing preprocessing")
        logging.info("--------------------------------")
        logging.info(self.base_capture_events)
        logging.info(self.killed_aircrafts)
        logging.info(self.killed_ground_units)
        logging.info(self.weapons_fired)
        logging.info(self.mission_ended)
        logging.info("--------------------------------")

        self.player_country_id = db.country_id_from_name(game.player_country)
        self.enemy_country_id = db.country_id_from_name(game.enemy_country)

        self.dead_aircraft = []
        self.dead_units = []
        self.dead_aaa_groups = []
        self.dead_buildings = []

        for aircraft in self.killed_aircrafts:
            try:
                country = int(aircraft.split("|")[1])
                type = db.unit_type_from_name(aircraft.split("|")[4])
                player_unit = (country == self.player_country_id)
                aircraft = DebriefingDeadUnitInfo(country, player_unit, type)
                if type is not None:
                    self.dead_aircraft.append(aircraft)
            except Exception as e:
                logging.error(e)

        for unit in self.killed_ground_units:
            try:
                country = int(unit.split("|")[1])
                type = db.unit_type_from_name(unit.split("|")[4])
                player_unit = (country == self.player_country_id)
                unit = DebriefingDeadUnitInfo(country, player_unit, type)
                if type is not None:
                    self.dead_units.append(unit)
            except Exception as e:
                logging.error(e)

        for unit in self.killed_ground_units:
            for cp in game.theater.controlpoints:

                logging.info(cp.name)
                logging.info(cp.captured)

                if cp.captured:
                    country = self.player_country_id
                else:
                    country = self.enemy_country_id
                player_unit = (country == self.player_country_id)

                for i, ground_object in enumerate(cp.ground_objects):
                    logging.info(unit)
                    logging.info(ground_object.string_identifier)
                    if ground_object.matches_string_identifier(unit):
                        unit = DebriefingDeadUnitInfo(country, player_unit, ground_object.dcs_identifier)
                        self.dead_buildings.append(unit)
                    elif ground_object.dcs_identifier in ["AA", "CARRIER", "LHA"]:
                        for g in ground_object.groups:
                            for u in g.units:
                                if u.name == unit:
                                    unit = DebriefingDeadUnitInfo(country, player_unit, db.unit_type_from_name(u.type))
                                    self.dead_units.append(unit)

        self.player_dead_aircraft = [a for a in self.dead_aircraft if a.country_id == self.player_country_id]
        self.enemy_dead_aircraft = [a for a in self.dead_aircraft if a.country_id == self.enemy_country_id]
        self.player_dead_units = [a for a in self.dead_units if a.country_id == self.player_country_id]
        self.enemy_dead_units = [a for a in self.dead_units if a.country_id == self.enemy_country_id]
        self.player_dead_buildings = [a for a in self.dead_buildings if a.country_id == self.player_country_id]
        self.enemy_dead_buildings = [a for a in self.dead_buildings if a.country_id == self.enemy_country_id]

        logging.info(self.player_dead_aircraft)
        logging.info(self.enemy_dead_aircraft)
        logging.info(self.player_dead_units)
        logging.info(self.enemy_dead_units)

        self.player_dead_aircraft_dict = {}
        for a in self.player_dead_aircraft:
            if a.type in self.player_dead_aircraft_dict.keys():
                self.player_dead_aircraft_dict[a.type] = self.player_dead_aircraft_dict[a.type] + 1
            else:
                self.player_dead_aircraft_dict[a.type] = 1

        self.enemy_dead_aircraft_dict = {}
        for a in self.enemy_dead_aircraft:
            if a.type in self.enemy_dead_aircraft_dict.keys():
                self.enemy_dead_aircraft_dict[a.type] = self.enemy_dead_aircraft_dict[a.type] + 1
            else:
                self.enemy_dead_aircraft_dict[a.type] = 1

        self.player_dead_units_dict = {}
        for a in self.player_dead_units:
            if a.type in self.player_dead_units_dict.keys():
                self.player_dead_units_dict[a.type] = self.player_dead_units_dict[a.type] + 1
            else:
                self.player_dead_units_dict[a.type] = 1

        self.enemy_dead_units_dict = {}
        for a in self.enemy_dead_units:
            if a.type in self.enemy_dead_units_dict.keys():
                self.enemy_dead_units_dict[a.type] = self.enemy_dead_units_dict[a.type] + 1
            else:
                self.enemy_dead_units_dict[a.type] = 1

        self.player_dead_buildings_dict = {}
        for a in self.player_dead_buildings:
            if a.type in self.player_dead_buildings_dict.keys():
                self.player_dead_buildings_dict[a.type] = self.player_dead_buildings_dict[a.type] + 1
            else:
                self.player_dead_buildings_dict[a.type] = 1

        self.enemy_dead_buildings_dict = {}
        for a in self.enemy_dead_buildings:
            if a.type in self.enemy_dead_buildings_dict.keys():
                self.enemy_dead_buildings_dict[a.type] = self.enemy_dead_buildings_dict[a.type] + 1
            else:
                self.enemy_dead_buildings_dict[a.type] = 1

        logging.info("--------------------------------")
        logging.info("Debriefing pre process results :")
        logging.info("--------------------------------")
        logging.info(self.player_dead_aircraft_dict)
        logging.info(self.enemy_dead_aircraft_dict)
        logging.info(self.player_dead_units_dict)
        logging.info(self.enemy_dead_units_dict)
        logging.info(self.player_dead_buildings_dict)
        logging.info(self.enemy_dead_buildings_dict)
コード例 #17
0
    def commit(self, debriefing: Debriefing):

        logging.info("Commiting mission results")

        # ------------------------------
        # Destroyed aircrafts
        cp_map = {cp.id: cp for cp in self.game.theater.controlpoints}
        for destroyed_aircraft in debriefing.killed_aircrafts:
            try:
                cpid = int(destroyed_aircraft.split("|")[3])
                type = db.unit_type_from_name(destroyed_aircraft.split("|")[4])
                if cpid in cp_map.keys():
                    cp = cp_map[cpid]
                    if type in cp.base.aircraft.keys():
                        logging.info("Aircraft destroyed : " + str(type))
                        cp.base.aircraft[type] = max(
                            0, cp.base.aircraft[type] - 1)
            except Exception as e:
                print(e)

        # ------------------------------
        # Destroyed ground units
        killed_unit_count_by_cp = {
            cp.id: 0
            for cp in self.game.theater.controlpoints
        }
        cp_map = {cp.id: cp for cp in self.game.theater.controlpoints}
        for killed_ground_unit in debriefing.killed_ground_units:
            try:
                cpid = int(killed_ground_unit.split("|")[3])
                type = db.unit_type_from_name(killed_ground_unit.split("|")[4])
                if cpid in cp_map.keys():
                    killed_unit_count_by_cp[
                        cpid] = killed_unit_count_by_cp[cpid] + 1
                    cp = cp_map[cpid]
                    if type in cp.base.armor.keys():
                        logging.info("Ground unit destroyed : " + str(type))
                        cp.base.armor[type] = max(0, cp.base.armor[type] - 1)
            except Exception as e:
                print(e)

        # ------------------------------
        # Static ground objects
        for destroyed_ground_unit_name in debriefing.killed_ground_units:
            for cp in self.game.theater.controlpoints:
                if not cp.ground_objects:
                    continue

                # -- Static ground objects
                for i, ground_object in enumerate(cp.ground_objects):
                    if ground_object.is_dead:
                        continue

                    if ground_object.matches_string_identifier(
                            destroyed_ground_unit_name):
                        logging.info("cp {} killing ground object {}".format(
                            cp, ground_object.string_identifier))
                        cp.ground_objects[i].is_dead = True

                        info = Information(
                            "Building destroyed",
                            ground_object.dcs_identifier +
                            " has been destroyed at location " +
                            ground_object.obj_name, self.game.turn)
                        self.game.informations.append(info)

                # -- AA Site groups
                destroyed_units = 0
                info = Information(
                    "Units destroyed at " + ground_object.obj_name, "",
                    self.game.turn)
                for i, ground_object in enumerate(cp.ground_objects):
                    if ground_object.dcs_identifier in [
                            "AA", "CARRIER", "LHA"
                    ]:
                        for g in ground_object.groups:
                            if not hasattr(g, "units_losts"):
                                g.units_losts = []
                            for u in g.units:
                                if u.name == destroyed_ground_unit_name:
                                    g.units.remove(u)
                                    g.units_losts.append(u)
                                    destroyed_units = destroyed_units + 1
                                    info.text = u.type
                        ucount = sum(
                            [len(g.units) for g in ground_object.groups])
                        if ucount == 0:
                            ground_object.is_dead = True
                if destroyed_units > 0:
                    self.game.informations.append(info)

        # ------------------------------
        # Captured bases
        #if self.game.player_country in db.BLUEFOR_FACTIONS:
        coalition = 2  # Value in DCS mission event for BLUE
        #else:
        #    coalition = 1 # Value in DCS mission event for RED

        for captured in debriefing.base_capture_events:
            try:
                id = int(captured.split("||")[0])
                new_owner_coalition = int(captured.split("||")[1])

                captured_cps = []
                for cp in self.game.theater.controlpoints:
                    if cp.id == id:

                        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 !", self.game.turn)
                            self.game.informations.append(info)
                            pname = self.game.enemy_name
                            captured_cps.append(cp)
                        elif not (cp.captured
                                  ) and new_owner_coalition == coalition:
                            cp.captured = True
                            info = Information(
                                cp.name + " captured !",
                                "We took control of " + cp.name +
                                "! Great job !", self.game.turn)
                            self.game.informations.append(info)
                            pname = self.game.player_name
                            captured_cps.append(cp)
                        else:
                            continue

                        cp.base.aircraft = {}
                        cp.base.armor = {}

                        airbase_def_id = 0
                        for g in cp.ground_objects:
                            g.groups = []
                            if g.airbase_group and pname != "":
                                generate_airbase_defense_group(
                                    airbase_def_id, g, pname, self.game, cp)
                                airbase_def_id = airbase_def_id + 1

                for cp in captured_cps:
                    logging.info("Will run redeploy for " + cp.name)
                    self.redeploy_units(cp)

            except Exception as e:
                print(e)

        # Destroyed units carcass
        # -------------------------
        for destroyed_unit in debriefing.destroyed_units:
            self.game.add_destroyed_units(destroyed_unit)

        # -----------------------------------
        # Compute damage to bases
        for cp in self.game.theater.player_points():
            enemy_cps = [e for e in cp.connected_points if not e.captured]
            for enemy_cp in enemy_cps:
                print("Compute frontline progression for : " + cp.name +
                      " to " + enemy_cp.name)

                delta = 0
                player_won = True
                ally_casualties = killed_unit_count_by_cp[cp.id]
                enemy_casualties = killed_unit_count_by_cp[enemy_cp.id]
                ally_units_alive = cp.base.total_armor
                enemy_units_alive = enemy_cp.base.total_armor

                print(ally_units_alive)
                print(enemy_units_alive)
                print(ally_casualties)
                print(enemy_casualties)

                ratio = (1.0 + enemy_casualties) / (1.0 + ally_casualties)

                player_aggresive = cp.stances[enemy_cp.id] in [
                    CombatStance.AGGRESIVE, CombatStance.ELIMINATION,
                    CombatStance.BREAKTHROUGH
                ]

                if ally_units_alive == 0:
                    player_won = False
                    delta = STRONG_DEFEAT_INFLUENCE
                elif enemy_units_alive == 0:
                    player_won = True
                    delta = STRONG_DEFEAT_INFLUENCE
                elif cp.stances[enemy_cp.id] == CombatStance.RETREAT:
                    player_won = False
                    delta = STRONG_DEFEAT_INFLUENCE
                else:
                    if enemy_casualties > ally_casualties:
                        player_won = True
                        if cp.stances[
                                enemy_cp.id] == CombatStance.BREAKTHROUGH:
                            delta = STRONG_DEFEAT_INFLUENCE
                        else:
                            if ratio > 3:
                                delta = STRONG_DEFEAT_INFLUENCE
                            elif ratio < 1.5:
                                delta = MINOR_DEFEAT_INFLUENCE
                            else:
                                delta = DEFEAT_INFLUENCE
                    elif ally_casualties > enemy_casualties:

                        if ally_units_alive > 2 * enemy_units_alive and player_aggresive:
                            # Even with casualties if the enemy is overwhelmed, they are going to lose ground
                            player_won = True
                            delta = MINOR_DEFEAT_INFLUENCE
                        elif ally_units_alive > 3 * enemy_units_alive and player_aggresive:
                            player_won = True
                            delta = STRONG_DEFEAT_INFLUENCE
                        else:
                            # But is the enemy is not outnumbered, we lose
                            player_won = False
                            if cp.stances[
                                    enemy_cp.id] == CombatStance.BREAKTHROUGH:
                                delta = STRONG_DEFEAT_INFLUENCE
                            else:
                                delta = STRONG_DEFEAT_INFLUENCE

                    # No progress with defensive strategies
                    if player_won and cp.stances[enemy_cp.id] in [
                            CombatStance.DEFENSIVE, CombatStance.AMBUSH
                    ]:
                        print("Defensive stance, progress is limited")
                        delta = MINOR_DEFEAT_INFLUENCE

                if player_won:
                    print(cp.name + " won !  factor > " + str(delta))
                    cp.base.affect_strength(delta)
                    enemy_cp.base.affect_strength(-delta)
                    info = Information(
                        "Frontline Report",
                        "Our ground forces from " + cp.name +
                        " are making progress toward " + enemy_cp.name,
                        self.game.turn)
                    self.game.informations.append(info)
                else:
                    print(cp.name + " lost !  factor > " + str(delta))
                    enemy_cp.base.affect_strength(delta)
                    cp.base.affect_strength(-delta)
                    info = Information(
                        "Frontline Report",
                        "Our ground forces from " + cp.name +
                        " are losing ground against the enemy forces from " +
                        enemy_cp.name, self.game.turn)
                    self.game.informations.append(info)
コード例 #18
0
    def generate(self):

        cp = None  # type: ControlPoint
        if self.conflict.attackers_country.name == self.game.player_country:
            cp = self.conflict.to_cp
        else:
            cp = self.conflict.from_cp

        for cp in self.game.theater.controlpoints:

            if cp.captured:
                country = self.game.player_country
            else:
                country = self.game.enemy_country
            side = self.m.country(country)

            for ground_object in cp.ground_objects:
                if ground_object.dcs_identifier == "AA":

                    if self.game.position_culled(ground_object.position):
                        continue

                    for g in ground_object.groups:
                        if len(g.units) > 0:
                            utype = unit_type_from_name(g.units[0].type)

                            if not ground_object.sea_object:
                                vg = self.m.vehicle_group(
                                    side,
                                    g.name,
                                    utype,
                                    position=g.position,
                                    heading=g.units[0].heading)
                                vg.units[0].name = self.m.string(
                                    g.units[0].name)
                                for i, u in enumerate(g.units):
                                    if i > 0:
                                        vehicle = Vehicle(
                                            self.m.next_unit_id(),
                                            self.m.string(u.name), u.type)
                                        vehicle.position.x = u.position.x
                                        vehicle.position.y = u.position.y
                                        vehicle.heading = u.heading
                                        vg.add_unit(vehicle)
                            else:
                                vg = self.m.ship_group(
                                    side,
                                    g.name,
                                    utype,
                                    position=g.position,
                                    heading=g.units[0].heading)
                                vg.units[0].name = self.m.string(
                                    g.units[0].name)
                                for i, u in enumerate(g.units):
                                    utype = unit_type_from_name(u.type)
                                    if i > 0:
                                        ship = Ship(self.m.next_unit_id(),
                                                    self.m.string(u.name),
                                                    utype)
                                        ship.position.x = u.position.x
                                        ship.position.y = u.position.y
                                        ship.heading = u.heading
                                        vg.add_unit(ship)

                            if self.game.settings.perf_red_alert_state:
                                vg.points[0].tasks.append(OptAlarmState(2))
                            else:
                                vg.points[0].tasks.append(OptAlarmState(1))

                elif ground_object.dcs_identifier in ["CARRIER", "LHA"]:
                    for g in ground_object.groups:
                        if len(g.units) > 0:

                            utype = unit_type_from_name(g.units[0].type)
                            if ground_object.dcs_identifier == "CARRIER" and self.game.settings.supercarrier == True:
                                utype = db.upgrade_to_supercarrier(
                                    utype, cp.name)

                            sg = self.m.ship_group(side,
                                                   g.name,
                                                   utype,
                                                   position=g.position,
                                                   heading=g.units[0].heading)
                            sg.units[0].name = self.m.string(g.units[0].name)

                            for i, u in enumerate(g.units):
                                if i > 0:
                                    ship = Ship(self.m.next_unit_id(),
                                                self.m.string(u.name),
                                                unit_type_from_name(u.type))
                                    ship.position.x = u.position.x
                                    ship.position.y = u.position.y
                                    ship.heading = u.heading
                                    sg.add_unit(ship)

                            # Find carrier direction (In the wind)
                            found_carrier_destination = False
                            attempt = 0
                            while not found_carrier_destination and attempt < 5:
                                point = sg.points[
                                    0].position.point_from_heading(
                                        self.m.weather.wind_at_ground.
                                        direction, 100000 - attempt * 20000)
                                if self.game.theater.is_in_sea(point):
                                    found_carrier_destination = True
                                    sg.add_waypoint(point)
                                else:
                                    attempt = attempt + 1

                            # Set UP TACAN and ICLS
                            modeChannel = "X" if not cp.tacanY else "Y"
                            sg.points[0].tasks.append(
                                ActivateBeaconCommand(channel=cp.tacanN,
                                                      modechannel=modeChannel,
                                                      callsign=cp.tacanI,
                                                      unit_id=sg.units[0].id))
                            if ground_object.dcs_identifier == "CARRIER" and hasattr(
                                    cp, "icls"):
                                sg.points[0].tasks.append(
                                    ActivateICLSCommand(
                                        cp.icls, unit_id=sg.units[0].id))

                else:

                    if self.game.position_culled(ground_object.position):
                        continue

                    static_type = None
                    if ground_object.dcs_identifier in warehouse_map:
                        static_type = warehouse_map[
                            ground_object.dcs_identifier]
                    elif ground_object.dcs_identifier in fortification_map:
                        static_type = fortification_map[
                            ground_object.dcs_identifier]
                    elif ground_object.dcs_identifier in FORTIFICATION_UNITS_ID:
                        for f in FORTIFICATION_UNITS:
                            if f.id == ground_object.dcs_identifier:
                                unit_type = f
                                break
                    else:
                        print("Didn't find {} in static _map(s)!".format(
                            ground_object.dcs_identifier))
                        continue

                    if static_type is None:
                        if not ground_object.is_dead:
                            group = self.m.vehicle_group(
                                country=side,
                                name=ground_object.string_identifier,
                                _type=unit_type,
                                position=ground_object.position,
                                heading=ground_object.heading,
                            )
                            logging.info(
                                "generated {}object identifier {} with mission id {}"
                                .format(
                                    "dead " if ground_object.is_dead else "",
                                    group.name, group.id))
                    else:
                        group = self.m.static_group(
                            country=side,
                            name=ground_object.string_identifier,
                            _type=static_type,
                            position=ground_object.position,
                            heading=ground_object.heading,
                            dead=ground_object.is_dead,
                        )

                        logging.info(
                            "generated {}object identifier {} with mission id {}"
                            .format("dead " if ground_object.is_dead else "",
                                    group.name, group.id))
コード例 #19
0
    def reload_scene(self):
        scene = self.scene()
        scene.clear()

        playerColor = self.game.get_player_color()
        enemyColor = self.game.get_enemy_color()

        self.addBackground()

        # Uncomment below to help set up theater reference points
        #for i, r in enumerate(self.game.theater.reference_points.items()):
        #    text = scene.addText(str(r), font=QFont("Trebuchet MS", 10, weight=5, italic=False))
        #    text.setPos(0, i * 24)

        for cp in self.game.theater.controlpoints:
        
            pos = self._transform_point(cp.position)

            scene.addItem(QMapControlPoint(self, pos[0] - CONST.CP_SIZE / 2, pos[1] - CONST.CP_SIZE / 2, CONST.CP_SIZE,
                                           CONST.CP_SIZE, cp, self.game))

            if cp.captured:
                pen = QPen(brush=CONST.COLORS[playerColor])
                brush = CONST.COLORS[playerColor+"_transparent"]
            else:
                pen = QPen(brush=CONST.COLORS[enemyColor])
                brush = CONST.COLORS[enemyColor+"_transparent"]

            added_objects = []
            for ground_object in cp.ground_objects:
                if ground_object.obj_name in added_objects:
                    continue


                go_pos = self._transform_point(ground_object.position)
                if not ground_object.airbase_group:
                    buildings = self.game.theater.find_ground_objects_by_obj_name(ground_object.obj_name)
                    scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 12, 12, cp, ground_object, buildings))

                if ground_object.category == "aa" and self.get_display_rule("sam"):
                    max_range = 0
                    has_radar = False
                    if ground_object.groups:
                        for g in ground_object.groups:
                            for u in g.units:
                                unit = db.unit_type_from_name(u.type)
                                if unit in UNITS_WITH_RADAR:
                                    has_radar = True
                                if unit.threat_range > max_range:
                                    max_range = unit.threat_range
                    if has_radar:
                        scene.addEllipse(go_pos[0] - max_range/300.0 + 8, go_pos[1] - max_range/300.0 + 8, max_range/150.0, max_range/150.0, CONST.COLORS["white_transparent"], CONST.COLORS["grey_transparent"])
                added_objects.append(ground_object.obj_name)

        for cp in self.game.theater.enemy_points():
            if self.get_display_rule("lines"):
                self.scene_create_lines_for_cp(cp, playerColor, enemyColor)

        for cp in self.game.theater.player_points():
            if self.get_display_rule("lines"):
                self.scene_create_lines_for_cp(cp, playerColor, enemyColor)

        for cp in self.game.theater.controlpoints:

            if cp.captured:
                pen = QPen(brush=CONST.COLORS[playerColor])
                brush = CONST.COLORS[playerColor+"_transparent"]

                flight_path_pen = QPen(brush=CONST.COLORS[playerColor])
                flight_path_pen.setColor(CONST.COLORS[playerColor])

            else:
                pen = QPen(brush=CONST.COLORS[enemyColor])
                brush = CONST.COLORS[enemyColor+"_transparent"]

                flight_path_pen = QPen(brush=CONST.COLORS[enemyColor])
                flight_path_pen.setColor(CONST.COLORS[enemyColor])

            flight_path_pen.setWidth(1)
            flight_path_pen.setStyle(Qt.DashDotLine)

            pos = self._transform_point(cp.position)
            if self.get_display_rule("flight_paths"):
                if cp.id in self.game.planners.keys():
                    planner = self.game.planners[cp.id]
                    for flight in planner.flights:
                        scene.addEllipse(pos[0], pos[1], 4, 4)
                        prev_pos = list(pos)
                        for point in flight.points:
                            new_pos = self._transform_point(Point(point.x, point.y))
                            scene.addLine(prev_pos[0]+2, prev_pos[1]+2, new_pos[0]+2, new_pos[1]+2, flight_path_pen)
                            scene.addEllipse(new_pos[0], new_pos[1], 4, 4, pen, brush)
                            prev_pos = list(new_pos)
                        scene.addLine(prev_pos[0] + 2, prev_pos[1] + 2, pos[0] + 2, pos[1] + 2, flight_path_pen)

        for cp in self.game.theater.controlpoints:
            pos = self._transform_point(cp.position)
            text = scene.addText(cp.name, font=CONST.FONT_MAP)
            text.setPos(pos[0] + CONST.CP_SIZE, pos[1] - CONST.CP_SIZE / 2)
            text = scene.addText(cp.name, font=CONST.FONT_MAP)
            text.setDefaultTextColor(Qt.white)
            text.setPos(pos[0] + CONST.CP_SIZE + 1, pos[1] - CONST.CP_SIZE / 2 + 1)
コード例 #20
0
 def get_carrier_type(self, group: Group) -> UnitType:
     unit_type = unit_type_from_name(group.units[0].type)
     if unit_type is None:
         raise RuntimeError(
             f"Unrecognized carrier name: {group.units[0].type}")
     return unit_type