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
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
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