def can_issue_order(self, verbose=False): if not super(OrderMove, self).can_issue_order(verbose=verbose): return False # TODO: figure out better way to have invasions (& possibly colonizations) require visibility on target without needing visibility of all intermediate systems # if False and main_mission_type not in [AIFleetMissionType.FLEET_MISSION_ATTACK, # TODO: consider this later # AIFleetMissionType.FLEET_MISSION_MILITARY, # AIFleetMissionType.FLEET_MISSION_SECURE, # AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN, # AIFleetMissionType.FLEET_MISSION_EXPLORATION]: # if not universe.getVisibility(target_id, foAI.foAIstate.empireID) >= fo.visibility.partial: # #if not target_id in interior systems # foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID) # return False system_id = self.fleet.get_system().id if system_id == self.target.get_system().id: return True # TODO: already there, but could consider retreating fleet_rating = foAI.foAIstate.get_rating(self.fleet.id).get('overall', 0) target_sys_status = foAI.foAIstate.systemStatus.get(self.target.id, {}) f_threat = target_sys_status.get('fleetThreat', 0) m_threat = target_sys_status.get('monsterThreat', 0) p_threat = target_sys_status.get('planetThreat', 0) threat = f_threat + m_threat + p_threat safety_factor = MilitaryAI.get_safety_factor() universe = fo.getUniverse() if fleet_rating >= safety_factor * threat: return True elif not p_threat and self.target.id in fo.getEmpire().supplyUnobstructedSystems: return True else: sys1 = universe.getSystem(system_id) sys1_name = sys1 and sys1.name or "unknown" targ1 = self.target.get_system() targ1_name = (targ1 and targ1.get_object().name) or "unknown" # following line was poor because AIstate.militaryFleetIDs only covers fleets without current missions # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('rating', 0) for fleet_id in foAI.foAIstate.militaryFleetIDs if ( foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('sysID', -1) == thisSystemID ) ]) # myOtherFleetsRatings = [foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', {}) for fid in foAI.foAIstate.systemStatus.get(target_id, {}).get('myfleets', [])] # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', 0) for fid in foAI.foAIstate.systemStatus.get( target_id, {}).get('myfleets', []) ]) my_other_fleet_rating = foAI.foAIstate.systemStatus.get(self.target.id, {}).get('myFleetRating', 0) # TODO: adjust calc for any departing fleets is_military = foAI.foAIstate.get_fleet_role(self.fleet.id) == AIFleetMissionType.FLEET_MISSION_MILITARY if ((my_other_fleet_rating > 3 * safety_factor * threat) or (is_military and my_other_fleet_rating + fleet_rating > safety_factor * threat) or (is_military and my_other_fleet_rating + fleet_rating > 0.8 * safety_factor * threat and fleet_rating > 0.2 * threat)): if verbose: print "\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with threat %d because of sufficient empire fleet strength already at destination" % ( self.fleet.id, fleet_rating, system_id, sys1_name, self.target.id, targ1_name, threat) return True elif threat == p_threat and not self.fleet.get_object().aggressive and not my_other_fleet_rating and not target_sys_status.get('localEnemyFleetIDs', [-1]): if verbose: print ("\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with planet threat %d because nonaggressive" + " and no other fleets present to trigger combat") % (self.fleet.id, fleet_rating, system_id, sys1_name, self.target.id, targ1_name, threat) return True else: if verbose: print "\tHolding fleet %d (rating %d) at system %d (%s) before travelling to system %d (%s) with threat %d" % (self.fleet.id, fleet_rating, system_id, sys1_name, self.target.id, targ1_name, threat) needs_vis = foAI.foAIstate.misc.setdefault('needs_vis', []) if self.target.id not in needs_vis: needs_vis.append(self.target.id) return False return True
def can_issue_order(self, verbose=False): if not super(OrderMove, self).can_issue_order(verbose=verbose): return False # TODO: figure out better way to have invasions (& possibly colonizations) require visibility on target without needing visibility of all intermediate systems # if False and main_mission_type not in [MissionType.ATTACK, # TODO: consider this later # MissionType.MILITARY, # MissionType.SECURE, # MissionType.HIT_AND_RUN, # MissionType.EXPLORATION]: # if not universe.getVisibility(target_id, foAI.foAIstate.empireID) >= fo.visibility.partial: # #if not target_id in interior systems # foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID) # return False system_id = self.fleet.get_system().id if system_id == self.target.get_system().id: return True # TODO: already there, but could consider retreating fleet_rating = foAI.foAIstate.get_rating(self.fleet.id).get( 'overall', 0) target_sys_status = foAI.foAIstate.systemStatus.get(self.target.id, {}) f_threat = target_sys_status.get('fleetThreat', 0) m_threat = target_sys_status.get('monsterThreat', 0) p_threat = target_sys_status.get('planetThreat', 0) threat = f_threat + m_threat + p_threat safety_factor = MilitaryAI.get_safety_factor() universe = fo.getUniverse() if fleet_rating >= safety_factor * threat: return True elif not p_threat and self.target.id in fo.getEmpire( ).supplyUnobstructedSystems: return True else: sys1 = universe.getSystem(system_id) sys1_name = sys1 and sys1.name or "unknown" target_system = self.target.get_system() target_system_name = (target_system and target_system.get_object().name) or "unknown" my_other_fleet_rating = foAI.foAIstate.systemStatus.get( self.target.id, {}).get('myFleetRating', 0) # TODO: adjust calc for any departing fleets is_military = foAI.foAIstate.get_fleet_role( self.fleet.id) == MissionType.MILITARY total_rating = my_other_fleet_rating + fleet_rating if any( ((my_other_fleet_rating > 3 * safety_factor * threat), (is_military and total_rating > safety_factor * threat), (is_military and total_rating > 0.8 * safety_factor * threat and fleet_rating > 0.2 * threat))): if verbose: print "\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with threat %d because of sufficient empire fleet strength already at destination" % ( self.fleet.id, fleet_rating, system_id, sys1_name, self.target.id, target_system_name, threat) return True elif threat == p_threat and not self.fleet.get_object( ).aggressive and not my_other_fleet_rating and not target_sys_status.get( 'localEnemyFleetIDs', [-1]): if verbose: print( "\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with planet threat %d because nonaggressive" + " and no other fleets present to trigger combat") % ( self.fleet.id, fleet_rating, system_id, sys1_name, self.target.id, target_system_name, threat) return True else: if verbose: print "\tHolding fleet %d (rating %d) at system %d (%s) before travelling to system %d (%s) with threat %d" % ( self.fleet.id, fleet_rating, system_id, sys1_name, self.target.id, target_system_name, threat) needs_vis = foAI.foAIstate.misc.setdefault('needs_vis', []) if self.target.id not in needs_vis: needs_vis.append(self.target.id) return False return True
def can_issue_order(self, verbose=False): """If FleetOrder can be issued now.""" # for some orders, may need to re-issue if invasion/outposting/colonization was interrupted if self.executed and self.order_type not in [AIFleetOrderType.ORDER_OUTPOST, AIFleetOrderType.ORDER_COLONISE, AIFleetOrderType.ORDER_INVADE]: return False if not self.is_valid(): return False universe = fo.getUniverse() ship_id = None fleet_id = self.fleet.target_id fleet = universe.getFleet(fleet_id) system_id = fleet.systemID target_id = self.target.target_id if verbose: sys1 = universe.getSystem(system_id) sys_name = sys1 and sys1.name or "unknown" main_fleet_mission = foAI.foAIstate.get_fleet_mission(fleet_id) main_mission_type = (main_fleet_mission.get_mission_types() + [-1])[0] print "** %s -- Mission Type %s (%s) , current loc sys %d - %s" % (self, AIFleetMissionTypeNames.name(main_mission_type), main_mission_type, system_id, sys_name) # # outpost # if AIFleetOrderType.ORDER_OUTPOST == self.order_type: # TODO: check for separate fleet holding outpost ships ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_CIVILIAN_OUTPOST) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_BASE_OUTPOST) ship = universe.getShip(ship_id) planet = universe.getPlanet(self.target.target_id) return ship is not None and fleet.systemID == planet.systemID and ship.canColonize # # colonise # elif AIFleetOrderType.ORDER_COLONISE == self.order_type: # TODO: check for separate fleet holding colony ships if TargetType.TARGET_FLEET == self.fleet.target_type: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_CIVILIAN_COLONISATION) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_BASE_COLONISATION) ship = universe.getShip(ship_id) planet = universe.getPlanet(self.target.target_id) if ship and not ship.canColonize: print "Error: colonization fleet %d has no colony ship" % fleet_id return ship is not None and fleet.systemID == planet.systemID and ship.canColonize # # invade # elif AIFleetOrderType.ORDER_INVADE == self.order_type: # TODO: check for separate fleet holding invasion ships if TargetType.TARGET_FLEET == self.fleet.target_type: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, False) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_BASE_INVASION) ship = universe.getShip(ship_id) planet = universe.getPlanet(self.target.target_id) return ship is not None and fleet.systemID == planet.systemID and ship.canInvade and not planet.currentMeterValue(fo.meterType.shield) # # military # elif AIFleetOrderType.ORDER_MILITARY == self.order_type: if TargetType.TARGET_FLEET == self.fleet.target_type: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_MILITARY) ship = universe.getShip(ship_id) system = universe.getSystem(self.target.target_id) return ship is not None and fleet.systemID == system.systemID and ship.isArmed # # split fleet # elif AIFleetOrderType.ORDER_SPLIT_FLEET == self.order_type: return len(fleet.shipIDs) > 1 # # move -- have fleets will do a safety check, also check for potential military fleet mergers # elif AIFleetOrderType.ORDER_MOVE == self.order_type: # target_id = self.target.target_id # TODO: figure out better way to have invasions (& possibly colonizations) require visibility on target without needing visibility of all intermediate systems if False and main_mission_type not in [AIFleetMissionType.FLEET_MISSION_ATTACK, # TODO: consider this later AIFleetMissionType.FLEET_MISSION_MILITARY, AIFleetMissionType.FLEET_MISSION_SECURE, AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN, AIFleetMissionType.FLEET_MISSION_EXPLORATION]: if not universe.getVisibility(target_id, foAI.foAIstate.empireID) >= fo.visibility.partial: #if not target_id in interior systems foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID) return False system_id = fleet.systemID if system_id == target_id: return True # TODO: already there, but could consider retreating fleet_rating = foAI.foAIstate.get_rating(fleet_id).get('overall', 0) target_sys_status = foAI.foAIstate.systemStatus.get(target_id, {}) f_threat = target_sys_status.get('fleetThreat', 0) m_threat = target_sys_status.get('monsterThreat', 0) p_threat = target_sys_status.get('planetThreat', 0) threat = f_threat + m_threat + p_threat safety_factor = MilitaryAI.get_safety_factor() if fleet_rating >= safety_factor * threat: return True else: sys1 = universe.getSystem(system_id) sys1_name = sys1 and sys1.name or "unknown" targ1 = universe.getSystem(target_id) targ1_name = (targ1 and targ1.name) or "unknown" # following line was poor because AIstate.militaryFleetIDs only covers fleets without current missions # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('rating', 0) for fleet_id in foAI.foAIstate.militaryFleetIDs if ( foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('sysID', -1) == thisSystemID ) ]) # myOtherFleetsRatings = [foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', {}) for fid in foAI.foAIstate.systemStatus.get(target_id, {}).get('myfleets', [])] # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', 0) for fid in foAI.foAIstate.systemStatus.get( target_id, {}).get('myfleets', []) ]) my_other_fleet_rating = foAI.foAIstate.systemStatus.get(target_id, {}).get('myFleetRating', 0) # TODO: adjust calc for any departing fleets is_military = foAI.foAIstate.get_fleet_role(fleet_id) == AIFleetMissionType.FLEET_MISSION_MILITARY if ((my_other_fleet_rating > 3 * safety_factor * threat) or (is_military and my_other_fleet_rating + fleet_rating > safety_factor * threat) or (is_military and my_other_fleet_rating + fleet_rating > 0.8 * safety_factor * threat and fleet_rating > 0.2 * threat)): if verbose: print "\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with threat %d because of sufficient empire fleet strength already at destination" % (fleet_id, fleet_rating, system_id, sys1_name, target_id, targ1_name, threat) return True elif threat == p_threat and not fleet.aggressive and not my_other_fleet_rating and not target_sys_status.get('localEnemyFleetIDs', [-1]): if verbose: print ("\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with planet threat %d because nonaggressive" + " and no other fleets present to trigger combat") % (fleet_id, fleet_rating, system_id, sys1_name, target_id, targ1_name, threat) return True else: if verbose: print "\tHolding fleet %d (rating %d) at system %d (%s) before travelling to system %d (%s) with threat %d" % (fleet_id, fleet_rating, system_id, sys1_name, target_id, targ1_name, threat) return False else: # default returns true return True