예제 #1
0
def trooper_move_reqs_met(main_fleet_mission, order, verbose):
    """
    Indicates whether or not move requirements specific to invasion troopers are met for the provided mission and order.
    :type main_fleet_mission: AIFleetMission.AIFleetMission
    :type order: OrderMove
    :param verbose: whether to print verbose decision details
    :type verbose: bool
    :rtype: bool
    """
    # Don't advance outside of our fleet-supply zone unless the target either has no shields at all or there
    # is already a military fleet assigned to secure the target, and don't take final jump unless the planet is
    # (to the AI's knowledge) down to zero shields.  Additional checks will also be done by the later
    # generic movement code
    invasion_target = main_fleet_mission.target
    invasion_planet = invasion_target.get_object()
    invasion_system = invasion_target.get_system()
    supplied_systems = fo.getEmpire().fleetSupplyableSystemIDs
    # if about to leave supply lines
    if order.target.id not in supplied_systems or fo.getUniverse(
    ).jumpDistance(order.fleet.id, invasion_system.id) < 5:
        if invasion_planet.currentMeterValue(fo.meterType.maxShield):
            military_support_fleets = MilitaryAI.get_military_fleets_with_target_system(
                invasion_system.id)
            if not military_support_fleets:
                if verbose:
                    debug(
                        "trooper_move_reqs_met() holding Invasion fleet %d before leaving supply "
                        "because target (%s) has nonzero max shields and there is not yet a military fleet "
                        "assigned to secure the target system." %
                        (order.fleet.id, invasion_planet))
                return False

            # if there is a threat in the enemy system, do give military ships at least 1 turn to clear it
            delay_to_move_troops = 1 if MilitaryAI.get_system_local_threat(
                order.target.id) else 0

            def eta(fleet_id):
                return FleetUtilsAI.calculate_estimated_time_of_arrival(
                    fleet_id, invasion_system.id)

            eta_this_fleet = eta(order.fleet.id)
            if all(((eta_this_fleet -
                     delay_to_move_troops) <= eta(fid) and eta(fid))
                   for fid in military_support_fleets):
                if verbose:
                    debug(
                        "trooper_move_reqs_met() holding Invasion fleet %d before leaving supply "
                        "because target (%s) has nonzero max shields and no assigned military fleet would arrive"
                        "at least %d turn earlier than the invasion fleet" %
                        (order.fleet.id, invasion_planet,
                         delay_to_move_troops))
                return False

        if verbose:
            debug(
                "trooper_move_reqs_met() allowing Invasion fleet %d to leave supply "
                "because target (%s) has zero max shields or there is a military fleet assigned to secure "
                "the target system which will arrive at least 1 turn before the invasion fleet.",
                order.fleet.id, invasion_planet)
    return True
예제 #2
0
    def _check_abort_mission(self, fleet_order: AIFleetOrder):
        """checks if current mission (targeting a planet) should be aborted"""
        planet_stealthed = False
        target_is_planet = fleet_order.target and isinstance(
            fleet_order.target, TargetPlanet)
        planet = None
        if target_is_planet:
            planet = fleet_order.target.get_object()
            # Check visibility prediction, but if somehow still have current visibility, don't
            # abort the mission yet
            if not EspionageAI.colony_detectable_by_empire(
                    planet.id, empire=fo.empireID()):
                if get_partial_visibility_turn(planet.id) == fo.currentTurn():
                    debug(
                        "EspionageAI predicts planet id %d to be stealthed" %
                        planet.id +
                        ", but somehow have current visibity anyway, so won't trigger mission abort"
                    )
                else:
                    debug(
                        "EspionageAI predicts we can no longer detect %s, will abort mission"
                        % fleet_order.target)
                    planet_stealthed = True
        if target_is_planet and not planet_stealthed:
            # TBD use fleet_order.is_valid or add fleet_order.should_abort
            if isinstance(fleet_order, OrderColonize):
                if planet.initialMeterValue(fo.meterType.population) == 0 and (
                        planet.ownedBy(fo.empireID()) or planet.unowned):
                    return False
            elif isinstance(fleet_order, OrderOutpost):
                if planet.unowned:
                    return False
            elif isinstance(fleet_order, OrderInvade):
                if planet.owner == fo.getEmpire().empireID:
                    debug(
                        f"Abandoning invasion for {planet}, it already belongs to us"
                    )
                    return True
                if planet.currentMeterValue(fo.meterType.maxShield):
                    military_support_fleets = MilitaryAI.get_military_fleets_with_target_system(
                        planet.systemID)
                    if not military_support_fleets:
                        # Maybe try again later...
                        debug(
                            f"Abandoning Invasion mission for {planet} because target has nonzero max shields "
                            f"and there is no military fleet assigned to secure the target system."
                        )
                        return True
                return False
            else:
                return False

        # canceling fleet orders
        debug("   %s" % fleet_order)
        debug(
            "Fleet %d had a target planet that is no longer valid for this mission; aborting."
            % self.fleet.id)
        FleetUtilsAI.split_fleet(self.fleet.id)
        return True
예제 #3
0
def trooper_move_reqs_met(main_fleet_mission, order, verbose):
    """
    Indicates whether or not move requirements specific to invasion troopers are met for the provided mission and order.
    :type main_fleet_mission: AIFleetMission.AIFleetMission
    :type order: OrderMove
    :param verbose: whether to print verbose decision details
    :type verbose: bool
    :rtype: bool
    """
    # Don't advance outside of our fleet-supply zone unless the target either has no shields at all or there
    # is already a military fleet assigned to secure the target, and don't take final jump unless the planet is
    # (to the AI's knowledge) down to zero shields.  Additional checks will also be done by the later
    # generic movement code
    invasion_target = main_fleet_mission.target
    invasion_planet = invasion_target.get_object()
    invasion_system = invasion_target.get_system()
    supplied_systems = fo.getEmpire().fleetSupplyableSystemIDs
    # if about to leave supply lines
    if order.target.id not in supplied_systems or fo.getUniverse().jumpDistance(order.fleet.id, invasion_system.id) < 5:
        if invasion_planet.currentMeterValue(fo.meterType.maxShield):
            military_support_fleets = MilitaryAI.get_military_fleets_with_target_system(invasion_system.id)
            if not military_support_fleets:
                if verbose:
                    print ("trooper_move_reqs_met() holding Invasion fleet %d before leaving supply "
                           "because target (%s) has nonzero max shields and there is not yet a military fleet "
                           "assigned to secure the target system.") % (order.fleet.id, invasion_planet)
                return False

            # if there is a threat in the enemy system, do give military ships at least 1 turn to clear it
            delay_to_move_troops = 1 if MilitaryAI.get_system_local_threat(order.target.id) else 0

            def eta(fleet_id):
                return FleetUtilsAI.calculate_estimated_time_of_arrival(fleet_id, invasion_system.id)

            eta_this_fleet = eta(order.fleet.id)
            if all(((eta_this_fleet - delay_to_move_troops) <= eta(fid) and eta(fid))
                   for fid in military_support_fleets):
                if verbose:
                    print ("trooper_move_reqs_met() holding Invasion fleet %d before leaving supply "
                           "because target (%s) has nonzero max shields and no assigned military fleet would arrive"
                           "at least %d turn earlier than the invasion fleet") % (
                                order.fleet.id, invasion_planet, delay_to_move_troops)
                return False

        if verbose:
            print ("trooper_move_reqs_met() allowing Invasion fleet %d to leave supply "
                   "because target (%s) has zero max shields or there is a military fleet assigned to secure "
                   "the target system which will arrive at least 1 turn before the invasion fleet.") % (order.fleet.id,
                                                                                                        invasion_planet)
    return True