def get_location_target(self): """system AITarget where fleet is or will be""" # TODO add parameter turn fleet = fo.getUniverse().getFleet(self.target_id) system_id = fleet.systemID if system_id >= 0: return AITarget(EnumsAI.TargetType.TARGET_SYSTEM, system_id) else: # in starlane, so return next system return AITarget(EnumsAI.TargetType.TARGET_SYSTEM, fleet.nextSystemID)
def __init__(self, fleet_id): self.orders = [] self.mission_type = EnumsAI.AIMissionType.FLEET_MISSION self.target = AITarget(EnumsAI.TargetType.TARGET_FLEET, fleet_id) self._mission_types = {} for mt in FLEET_MISSION_TYPES: self._mission_types[mt] = [] self.target_id = self.target.target_id self.target_type = self.target.target_type
def generate_fleet_orders(self): """generates AIFleetOrders from fleets targets to accomplish""" universe = fo.getUniverse() fleet_id = self.target_id fleet = universe.getFleet(fleet_id) if (not fleet) or fleet.empty or ( fleet_id in universe.destroyedObjectIDs(fo.empireID()) ): # fleet was probably merged into another or was destroyed foAI.foAIstate.delete_fleet_info(fleet_id) return # TODO: priority self.clear_fleet_orders() system_id = fleet.systemID start_sys_id = [fleet.nextSystemID, system_id][system_id >= 0] # if fleet doesn't have any mission, then repair if needed or resupply if is current location not in supplyable system empire = fo.getEmpire() fleet_supplyable_system_ids = empire.fleetSupplyableSystemIDs #if (not self.hasAnyAIMissionTypes()): ntargets = 0 for mission_type in self.get_mission_types(): ntargets += len(self.get_targets(mission_type)) if not ntargets and (system_id not in set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs + AIstate.invasionTargetedSystemIDs + AIstate.blockadeTargetedSystemIDs)): if self._need_repair(): repair_fleet_order = MoveUtilsAI.get_repair_fleet_order( self.target, start_sys_id) if repair_fleet_order.is_valid(): self.orders.append(repair_fleet_order) if self.get_location_target( ).target_id not in fleet_supplyable_system_ids: resupply_fleet_order = MoveUtilsAI.get_resupply_fleet_order( self.target, self.get_location_target()) if resupply_fleet_order.is_valid(): self.orders.append(resupply_fleet_order) return # no targets # for some targets fleet has to visit systems and therefore fleet visit them system_targets_required_to_visit = [] for mission_type in self.get_mission_types(): for aiTarget in self.get_targets(mission_type): system_targets_required_to_visit.extend( aiTarget.get_required_system_ai_targets()) orders_to_visit_systems = MoveUtilsAI.get_fleet_orders_from_system_targets( self.target, system_targets_required_to_visit) #TODO: if fleet doesn't have enough fuel to get to final target, consider resetting Mission #print "----------------------------------------" #print "*+*+ fleet %d : has fleet action system targets: %s"%(fleet_id, [str(obj) for obj in system_targets_required_to_visit]) #print "----------" #print "*+*+ fleet %d: has movement orders: %s"%(fleet_id, [str(obj) for obj in orders_to_visit_systems]) for fleet_order in orders_to_visit_systems: self.orders.append(fleet_order) # if fleet is in some system = fleet.system_id >=0, then also generate system AIFleetOrders if system_id >= 0: # system in where fleet is system_target = AITarget(EnumsAI.TargetType.TARGET_SYSTEM, system_id) # if mission aiTarget has required system where fleet is, then generate fleet_order from this aiTarget # for all targets in all mission types get required systems to visit for mission_type in self.get_mission_types(): tragets = self.get_targets(mission_type) for target in tragets: if system_target in target.get_required_system_ai_targets( ): # from target required to visit get fleet orders to accomplish target fleet_order = self._get_fleet_order_from_target( mission_type, target) self.orders.append(fleet_order)
def _check_retarget_invasion(self): """checks if an invasion mission should be retargeted""" universe = fo.getUniverse() empire = fo.getEmpire() empire_id = fo.empireID() fleet_id = self.target_id fleet = universe.getFleet(fleet_id) if fleet.systemID == -1: # next_loc = fleet.nextSystemID return # TODO: still check system = universe.getSystem(fleet.systemID) if not system: return orders = self.orders last_sys_target = -1 if orders: last_sys_target = orders[-1].target.target_id if last_sys_target == fleet.systemID: return # TODO: check for best local target open_targets = [] already_targeted = InvasionAI.get_invasion_targeted_planet_ids( system.planetIDs, AIFleetMissionType.FLEET_MISSION_INVASION, empire_id) for pid in system.planetIDs: if pid in already_targeted or ( pid in foAI.foAIstate.qualifyingTroopBaseTargets): continue planet = universe.getPlanet(pid) if planet.unowned or (planet.owner == empire_id): continue if (planet.currentMeterValue(fo.meterType.shield)) <= 0: open_targets.append(pid) if not open_targets: return troop_pod_tally = FleetUtilsAI.count_parts_fleetwide( fleet_id, ["GT_TROOP_POD"]) target_id = -1 best_score = -1 target_troops = 0 # fleet_supplyable_system_ids = empire.fleetSupplyableSystemIDs fleet_supplyable_planet_ids = PlanetUtilsAI.get_planets_in__systems_ids( fleet_supplyable_system_ids) for pid, rating in InvasionAI.assign_invasion_values( open_targets, AIFleetMissionType.FLEET_MISSION_INVASION, fleet_supplyable_planet_ids, empire).items(): p_score, p_troops = rating if p_score > best_score: if p_troops >= 2 * troop_pod_tally: continue best_score = p_score target_id = pid target_troops = p_troops if target_id == -1: return print "\t AIFleetMission._check_retarget_invasion: splitting and retargetting fleet %d" % fleet_id new_fleets = FleetUtilsAI.split_fleet(fleet_id) self.clear_targets(-1) # TODO: clear from foAIstate self.clear_fleet_orders() pods_needed = max( 0, math.ceil((target_troops - 2 * (FleetUtilsAI.count_parts_fleetwide( fleet_id, ["GT_TROOP_POD"])) + 0.05) / 2.0)) found_stats = {} min_stats = {'rating': 0, 'troopPods': pods_needed} target_stats = {'rating': 10, 'troopPods': pods_needed} found_fleets = [] # TODO check if next statement does not mutate any global states and can be removed _ = FleetUtilsAI.get_fleets_for_mission( 1, target_stats, min_stats, found_stats, "", systems_to_check=[fleet.systemID], systems_checked=[], fleet_pool_set=set(new_fleets), fleet_list=found_fleets, verbose=False) for fid in found_fleets: FleetUtilsAI.merge_fleet_a_into_b(fid, fleet_id) target = AITarget(EnumsAI.TargetType.TARGET_PLANET, target_id) self.add_target(AIFleetMissionType.FLEET_MISSION_INVASION, target) self.generate_fleet_orders()
def _get_fleet_order_from_target(self, mission_type, target): fleet_targets = AITarget(EnumsAI.TargetType.TARGET_FLEET, self.target_id) order_type = ORDERS_FOR_MISSION.get(mission_type, AIFleetOrderType.ORDER_INVALID) return AIFleetOrder.AIFleetOrder(order_type, fleet_targets, target)