コード例 #1
0
    def redeploy_units(self, cp):
        """"
        Auto redeploy units to newly captured base
        """

        ally_connected_cps = [
            ocp for ocp in cp.connected_points if cp.captured == ocp.captured
        ]
        enemy_connected_cps = [
            ocp for ocp in cp.connected_points if cp.captured != ocp.captured
        ]

        # If the newly captured cp does not have enemy connected cp,
        # then it is not necessary to redeploy frontline units there.
        if len(enemy_connected_cps) == 0:
            return
        else:
            # From each ally cp, send reinforcements
            for ally_cp in ally_connected_cps:
                total_units_redeployed = 0
                own_enemy_cp = [
                    ocp for ocp in ally_cp.connected_points
                    if ally_cp.captured != ocp.captured
                ]

                moved_units = {}

                # If the connected base, does not have any more enemy cp connected.
                # Or if it is not the opponent redeploying forces there (enemy AI will never redeploy all their forces at once)
                if len(own_enemy_cp) > 0 or not cp.captured:
                    for frontline_unit, count in ally_cp.base.armor.items():
                        moved_units[frontline_unit] = int(count / 2)
                        total_units_redeployed = total_units_redeployed + int(
                            count / 2)
                else:  # So if the old base, does not have any more enemy cp connected, or if it is an enemy base
                    for frontline_unit, count in ally_cp.base.armor.items():
                        moved_units[frontline_unit] = count
                        total_units_redeployed = total_units_redeployed + count

                cp.base.commision_units(moved_units)
                ally_cp.base.commit_losses(moved_units)

                if total_units_redeployed > 0:
                    info = Information("Units redeployed", "", self.game.turn)
                    info.text = str(
                        total_units_redeployed
                    ) + " units have been redeployed from " + ally_cp.name + " to " + cp.name
                    self.game.informations.append(info)
                    logging.info(info.text)
コード例 #2
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)