def send_invasion_fleets(fleet_ids, evaluated_planets, mission_type): """sends a list of invasion fleets to a list of planet_value_pairs""" if not fleet_ids: return universe = fo.getUniverse() invasion_fleet_pool = set(fleet_ids) for planet_id, pscore, ptroops in evaluated_planets: planet = universe.getPlanet(planet_id) if not planet: continue sys_id = planet.systemID found_fleets = [] found_stats = {} min_stats = {'rating': 0, 'troopCapacity': ptroops} target_stats = {'rating': 10, 'troopCapacity': ptroops + _TROOPS_SAFETY_MARGIN} these_fleets = FleetUtilsAI.get_fleets_for_mission(target_stats, min_stats, found_stats, starting_system=sys_id, fleet_pool_set=invasion_fleet_pool, fleet_list=found_fleets) if not these_fleets: if not FleetUtilsAI.stats_meet_reqs(found_stats, min_stats): print "Insufficient invasion troop allocation for system %d ( %s ) -- requested %s , found %s" % ( sys_id, universe.getSystem(sys_id).name, min_stats, found_stats) invasion_fleet_pool.update(found_fleets) continue else: these_fleets = found_fleets target = universe_object.Planet(planet_id) print "assigning invasion fleets %s to target %s" % (these_fleets, target) for fleetID in these_fleets: fleet_mission = foAI.foAIstate.get_fleet_mission(fleetID) fleet_mission.clear_fleet_orders() fleet_mission.clear_target() fleet_mission.set_target(mission_type, target)
def get_invasion_targeted_planet_ids(planet_ids, mission_type): invasion_feet_missions = foAI.foAIstate.get_fleet_missions_with_any_mission_types([mission_type]) targeted_planets = [] for pid in planet_ids: # add planets that are target of a mission for mission in invasion_feet_missions: target = universe_object.Planet(pid) if mission.has_target(mission_type, target): targeted_planets.append(pid) return targeted_planets
def assign_invasion_bases(): """Assign our troop bases to invasion targets.""" universe = fo.getUniverse() all_troopbase_fleet_ids = FleetUtilsAI.get_empire_fleet_ids_by_role(MissionType.ORBITAL_INVASION) available_troopbase_fleet_ids = set(FleetUtilsAI.extract_fleet_ids_without_mission_types(all_troopbase_fleet_ids)) for fid in list(available_troopbase_fleet_ids): if fid not in available_troopbase_fleet_ids: # entry may have been discarded in previous loop iterations continue fleet = universe.getFleet(fid) if not fleet: continue sys_id = fleet.systemID system = universe.getSystem(sys_id) available_planets = set(system.planetIDs).intersection(set(foAI.foAIstate.qualifyingTroopBaseTargets.keys())) print "Considering Base Troopers in %s, found planets %s and registered targets %s with status %s" % ( system.name, list(system.planetIDs), available_planets, [(pid, foAI.foAIstate.qualifyingTroopBaseTargets[pid]) for pid in available_planets]) targets = [pid for pid in available_planets if foAI.foAIstate.qualifyingTroopBaseTargets[pid][1] != -1] if not targets: print "Failure: found no valid target for troop base in system %s" % system continue status = foAI.foAIstate.systemStatus.get(sys_id, {}) local_base_troops = set(status.get('myfleets', [])).intersection(available_troopbase_fleet_ids) target_id = INVALID_ID best_score = -1 target_troops = 0 for pid, (p_score, p_troops) in assign_invasion_values(targets).items(): if p_score > best_score: best_score = p_score target_id = pid target_troops = p_troops if target_id == INVALID_ID: continue local_base_troops.discard(fid) found_fleets = [] troops_needed = max(0, target_troops - FleetUtilsAI.count_troops_in_fleet(fid)) found_stats = {} min_stats = {'rating': 0, 'troopCapacity': troops_needed} target_stats = {'rating': 10, 'troopCapacity': troops_needed + _TROOPS_SAFETY_MARGIN} FleetUtilsAI.get_fleets_for_mission(target_stats, min_stats, found_stats, starting_system=sys_id, fleet_pool_set=local_base_troops, fleet_list=found_fleets) for fid2 in found_fleets: FleetUtilsAI.merge_fleet_a_into_b(fid2, fid) available_troopbase_fleet_ids.discard(fid2) available_troopbase_fleet_ids.discard(fid) foAI.foAIstate.qualifyingTroopBaseTargets[target_id][1] = -1 # TODO: should probably delete target = universe_object.Planet(target_id) fleet_mission = foAI.foAIstate.get_fleet_mission(fid) fleet_mission.set_target(MissionType.ORBITAL_INVASION, target)
def assign_invasion_fleets_to_invade(): """Assign fleet targets to invadable planets.""" universe = fo.getUniverse() empire = fo.getEmpire() fleet_suppliable_system_ids = empire.fleetSupplyableSystemIDs fleet_suppliable_planet_ids = PlanetUtilsAI.get_planets_in__systems_ids( fleet_suppliable_system_ids) all_troopbase_fleet_ids = FleetUtilsAI.get_empire_fleet_ids_by_role( EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION) available_troopbase_fleet_ids = set( FleetUtilsAI.extract_fleet_ids_without_mission_types( all_troopbase_fleet_ids)) for fid in list(available_troopbase_fleet_ids): if fid not in available_troopbase_fleet_ids: # TODO: I do not see how this check makes sense, maybe remove? continue fleet = universe.getFleet(fid) if not fleet: continue sys_id = fleet.systemID system = universe.getSystem(sys_id) available_planets = set(system.planetIDs).intersection( set(foAI.foAIstate.qualifyingTroopBaseTargets.keys())) print "Considering Base Troopers in %s, found planets %s and registered targets %s with status %s" % ( system.name, list(system.planetIDs), available_planets, [ (pid, foAI.foAIstate.qualifyingTroopBaseTargets[pid]) for pid in available_planets ]) targets = [ pid for pid in available_planets if foAI.foAIstate.qualifyingTroopBaseTargets[pid][1] != -1 ] if not targets: print "Error: found no valid target for troop base in system %s (%d)" % ( system.name, sys_id) continue status = foAI.foAIstate.systemStatus.get(sys_id, {}) local_base_troops = set(status.get( 'myfleets', [])).intersection(available_troopbase_fleet_ids) troop_capacity_tally = 0 for fid2 in local_base_troops: troop_capacity_tally += FleetUtilsAI.count_troops_in_fleet(fid2) target_id = -1 best_score = -1 target_troops = 0 for pid, rating in assign_invasion_values( targets, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, fleet_suppliable_planet_ids, empire).items(): p_score, p_troops = rating if p_score > best_score: best_score = p_score target_id = pid target_troops = p_troops if target_id != -1: local_base_troops.discard(fid) found_fleets = [] troops_needed = max( 0, target_troops - FleetUtilsAI.count_troops_in_fleet(fid)) found_stats = {} min_stats = {'rating': 0, 'troopCapacity': troops_needed} target_stats = {'rating': 10, 'troopCapacity': troops_needed} FleetUtilsAI.get_fleets_for_mission( 1, target_stats, min_stats, found_stats, "", systems_to_check=[sys_id], systems_checked=[], fleet_pool_set=local_base_troops, fleet_list=found_fleets, verbose=False) for fid2 in found_fleets: FleetUtilsAI.merge_fleet_a_into_b(fid2, fid) available_troopbase_fleet_ids.discard(fid2) available_troopbase_fleet_ids.discard(fid) foAI.foAIstate.qualifyingTroopBaseTargets[target_id][ 1] = -1 # TODO: should probably delete target = universe_object.Planet(target_id) fleet_mission = foAI.foAIstate.get_fleet_mission(fid) fleet_mission.add_target( EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION, target) invasion_fleet_ids = AIstate.invasionFleetIDs send_invasion_fleets(invasion_fleet_ids, AIstate.invasionTargets, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) all_invasion_fleet_ids = FleetUtilsAI.get_empire_fleet_ids_by_role( EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) for fid in FleetUtilsAI.extract_fleet_ids_without_mission_types( all_invasion_fleet_ids): this_mission = foAI.foAIstate.get_fleet_mission(fid) this_mission.check_mergers( context="Post-send consolidation of unassigned troops")