def can_issue_order(self, verbose=False): # TODO: check for separate fleet holding outpost ships if not super(OrderOutpost, self).can_issue_order(verbose=verbose): return False universe = fo.getUniverse() ship_id = FleetUtilsAI.get_ship_id_with_role(self.fleet.id, ShipRoleType.CIVILIAN_OUTPOST) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(self.fleet.id, ShipRoleType.BASE_OUTPOST) ship = universe.getShip(ship_id) return ship is not None and self.fleet.get_object().systemID == self.target.get_system().id and ship.canColonize
def can_issue_order(self, verbose=False): if not super(OrderInvade, self).is_valid(): return False # TODO: check for separate fleet holding invasion ships ship_id = FleetUtilsAI.get_ship_id_with_role(self.fleet.id, AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, False) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(self.fleet.id, AIShipRoleType.SHIP_ROLE_BASE_INVASION) universe = fo.getUniverse() ship = universe.getShip(ship_id) planet = self.target.get_object() return ship is not None and self.fleet.get_system().id == planet.systemID \ and ship.canInvade and not planet.currentMeterValue(fo.meterType.shield)
def can_issue_order(self, verbose=False): if not super(OrderColonize, self).is_valid(): return False # TODO: check for separate fleet holding colony ships ship_id = FleetUtilsAI.get_ship_id_with_role(self.fleet.id, ShipRoleType.CIVILIAN_COLONISATION) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(self.fleet.id, ShipRoleType.BASE_COLONISATION) universe = fo.getUniverse() ship = universe.getShip(ship_id) if ship and not ship.canColonize: warn("colonization fleet %d has no colony ship" % self.fleet.id) return ship is not None and self.fleet.get_object().systemID == self.target.get_system().id and ship.canColonize
def can_issue_order(self, verbose=False): if not super(OrderInvade, self).is_valid(): return False # TODO: check for separate fleet holding invasion ships ship_id = FleetUtilsAI.get_ship_id_with_role( self.fleet.id, AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, False) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role( self.fleet.id, AIShipRoleType.SHIP_ROLE_BASE_INVASION) universe = fo.getUniverse() ship = universe.getShip(ship_id) planet = self.target.get_object() return ship is not None and self.fleet.get_system().id == planet.systemID \ and ship.canInvade and not planet.currentMeterValue(fo.meterType.shield)
def issue_order(self): if not super(OrderOutpost, self).issue_order(): return planet = self.target.get_object() if not planet.unowned: self.order_issued = True return fleet_id = self.fleet.id ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.CIVILIAN_OUTPOST) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.BASE_OUTPOST) result = fo.issueColonizeOrder(ship_id, self.target.id) print "Order issued: %s fleet: %s target: %s" % (self.ORDER_NAME, self.fleet, self.target) if not result: self.executed = False
def issue_order(self): if not super(OrderOutpost, self).issue_order(): return planet = self.target.get_object() if not planet.unowned: self.order_issued = True return fleet_id = self.fleet.id ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.CIVILIAN_OUTPOST) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.BASE_OUTPOST) result = fo.issueColonizeOrder(ship_id, self.target.id) print "Order issued: %s fleet: %s target: %s" % (self.ORDER_NAME, self.fleet, self.target) if not result: self.executed = False
def can_issue_order(self, verbose=False): # TODO: consider bombardment # TODO: consider simmply looking at fleet characteristics, as is done for is_valid() ship_id = FleetUtilsAI.get_ship_id_with_role(self.fleet.id, ShipRoleType.MILITARY) universe = fo.getUniverse() ship = universe.getShip(ship_id) return ship is not None and self.fleet.get_object().systemID == self.target.id and (ship.isArmed or ship.hasFighters)
def issue_order(self): if not super(OrderColonize, self).issue_order(): return fleet_id = self.fleet.id ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.CIVILIAN_COLONISATION) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.BASE_COLONISATION) planet = self.target.get_object() planet_name = planet and planet.name or "apparently invisible" result = fo.issueColonizeOrder(ship_id, self.target.id) print "Order issued: %s fleet: %s target: %s" % (self.ORDER_NAME, self.fleet, self.target) print "Ordered colony ship ID %d to colonize %s, got result %d" % (ship_id, planet_name, result) if not result: self.executed = False
def issue_order(self): if not super(OrderColonize, self).issue_order(): return fleet_id = self.fleet.id ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.CIVILIAN_COLONISATION) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.BASE_COLONISATION) planet = self.target.get_object() planet_name = planet and planet.name or "apparently invisible" result = fo.issueColonizeOrder(ship_id, self.target.id) print "Order issued: %s fleet: %s target: %s" % (self.ORDER_NAME, self.fleet, self.target) print "Ordered colony ship ID %d to colonize %s, got result %d" % (ship_id, planet_name, result) if not result: self.executed = False
def can_issue_order(self, verbose=False): ship_id = FleetUtilsAI.get_ship_id_with_role(self.fleet.id, ShipRoleType.MILITARY) universe = fo.getUniverse() ship = universe.getShip(ship_id) return ship is not None and self.fleet.get_system( ) == self.target and ship.isArmed
def issue_order(self): if not super(OrderColonize, self).issue_order(): return False # we can't know yet if the order will actually execute; instead, rely on the fact that if the order does get # executed, then next turn it will be invalid self.executed = False fleet_id = self.fleet.id ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.CIVILIAN_COLONISATION) if ship_id is None: ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, ShipRoleType.BASE_COLONISATION) if fo.issueColonizeOrder(ship_id, self.target.id): debug("Order issued: %s fleet: %s target: %s" % (self.ORDER_NAME, self.fleet, self.target)) return True else: self.order_issued = False warn("Order issuance failed: %s fleet: %s target: %s" % (self.ORDER_NAME, self.fleet, self.target)) return False
def can_issue_order(self, considerMergers=False, verbose=False): """if FleetOrder can be issued now""" #for some orders, may need to re-issue if invasion/outposting/colonization was interrupted if self.is_executed() and self.get_fleet_order_type() not in [ AIFleetOrderType.ORDER_OUTPOST, AIFleetOrderType.ORDER_COLONISE, AIFleetOrderType.ORDER_INVADE ]: return False if not self.is_valid(): return False reason = "" universe = fo.getUniverse() fleetID = None shipID = None if AITargetType.TARGET_SHIP == self.get_source_target().target_type: shipID = self.get_source_target().target_id ship = universe.getShip(shipID) fleetID = ship.fleetID elif AITargetType.TARGET_FLEET == self.get_source_target().target_type: fleetID = self.get_source_target().target_id fleet = universe.getFleet(fleetID) systemID = fleet.systemID sys1=universe.getSystem(systemID) sysName = (sys1 and sys1.name) or "unknown" targetID = self.get_target_target().target_id if verbose: mainFleetMission=foAI.foAIstate.get_fleet_mission(fleetID) mainMissionType = (mainFleetMission.get_mission_types() + [-1])[0] msgP1 = "** %s -- Mission Type %s (%s) , current loc sys %d - %s" % (self, AIFleetMissionTypeNames.name(mainMissionType), mainMissionType, systemID, sysName) print msgP1 # # outpost # if AIFleetOrderType.ORDER_OUTPOST == self.get_fleet_order_type():#TODO: check for separate fleet holding outpost ships if AITargetType.TARGET_FLEET == self.get_source_target().target_type: shipID = FleetUtilsAI.get_ship_id_with_role(fleetID, AIShipRoleType.SHIP_ROLE_CIVILIAN_OUTPOST) if shipID is None: shipID = FleetUtilsAI.get_ship_id_with_role(fleetID, AIShipRoleType.SHIP_ROLE_BASE_OUTPOST) ship = universe.getShip(shipID) planet = universe.getPlanet(self.get_target_target().target_id) if (ship is not None) and (fleet.systemID == planet.systemID) and ship.canColonize: return True return False # # colonise # elif AIFleetOrderType.ORDER_COLONISE == self.get_fleet_order_type():#TODO: check for separate fleet holding colony ships if AITargetType.TARGET_FLEET == self.get_source_target().target_type: shipID = FleetUtilsAI.get_ship_id_with_role(fleetID, AIShipRoleType.SHIP_ROLE_CIVILIAN_COLONISATION) if shipID is None: shipID = FleetUtilsAI.get_ship_id_with_role(fleetID, AIShipRoleType.SHIP_ROLE_BASE_COLONISATION) ship = universe.getShip(shipID) planet = universe.getPlanet(self.get_target_target().target_id) if ship and not ship.canColonize: print "Error: colonization fleet %d has no colony ship"%fleetID if (ship is not None) and (fleet.systemID == planet.systemID) and ship.canColonize: return True return False # # invade # elif AIFleetOrderType.ORDER_INVADE == self.get_fleet_order_type():#TODO: check for separate fleet holding invasion ships if AITargetType.TARGET_FLEET == self.get_source_target().target_type: shipID = FleetUtilsAI.get_ship_id_with_role(fleetID, AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, False) if shipID is None: shipID = FleetUtilsAI.get_ship_id_with_role(fleetID, AIShipRoleType.SHIP_ROLE_BASE_INVASION) ship = universe.getShip(shipID) planet = universe.getPlanet(self.get_target_target().target_id) if (ship is not None) and (fleet.systemID == planet.systemID) and ship.canInvade and ( planet.currentMeterValue(fo.meterType.shield) ==0): return True return False # # military # elif AIFleetOrderType.ORDER_MILITARY == self.get_fleet_order_type(): if AITargetType.TARGET_FLEET == self.get_source_target().target_type: shipID = FleetUtilsAI.get_ship_id_with_role(fleetID, AIShipRoleType.SHIP_ROLE_MILITARY) ship = universe.getShip(shipID) system = universe.getSystem(self.get_target_target().target_id) if (ship is not None) and (fleet.systemID == system.systemID) and ship.isArmed: return True return False # # split fleet # elif AIFleetOrderType.ORDER_SPLIT_FLEET == self.get_fleet_order_type(): fleet2 = universe.getFleet(self.get_source_target().target_id) if len(fleet2.shipIDs) <= 1: return False # # move -- have fleets will do a safety check, also check for potential military fleet mergers # elif AIFleetOrderType.ORDER_MOVE == self.get_fleet_order_type(): #targetID = self.get_target_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 mainMissionType 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(targetID, foAI.foAIstate.empireID) >= fo.visibility.partial): #if not targetID in interior systems foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID) return False systemID = fleet.systemID if systemID == targetID: return True #already there so no point to worry about threat sys1=universe.getSystem(systemID) sys1Name = (sys1 and sys1.name) or "unknown" targ1 = universe.getSystem(targetID) targ1Name = (targ1 and targ1.name) or "unknown" fleetRating = foAI.foAIstate.get_rating(fleetID).get('overall', 0) target_sys_status = foAI.foAIstate.systemStatus.get(targetID, {}) 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 safetyFactor = 1.1 if fleetRating >= safetyFactor* threat: return True else: #following line was poor because AIstate.militaryFleetIDs only covers fleets without current missions #myOtherFleetsRating = sum([foAI.foAIstate.fleetStatus.get(fleetID, {}).get('rating', 0) for fleetID in foAI.foAIstate.militaryFleetIDs if ( foAI.foAIstate.fleetStatus.get(fleetID, {}).get('sysID', -1) == thisSystemID ) ]) myOtherFleetsRatings = [foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', {}) for fid in foAI.foAIstate.systemStatus.get( targetID, {}).get('myfleets', []) ] #myOtherFleetsRating = sum([foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', 0) for fid in foAI.foAIstate.systemStatus.get( targetID, {}).get('myfleets', []) ]) myOtherFleetsRating = foAI.foAIstate.systemStatus.get( targetID, {}).get('myFleetRating', 0) if (myOtherFleetsRating > 1.5 * safetyFactor * threat) or (myOtherFleetsRating + fleetRating > 2.0 * safetyFactor * 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 desination"%(fleetID, fleetRating, systemID, sys1Name, targetID, targ1Name, threat) return True elif (threat == p_threat) and ( not fleet.aggressive ) and (myOtherFleetsRating == 0) and (len(target_sys_status.get('localEnemyFleetIDs', [-1]))==0): 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")%(fleetID, fleetRating, systemID, sys1Name, targetID, targ1Name, 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"%(fleetID, fleetRating, systemID, sys1Name, targetID, targ1Name, threat) return False else: # default returns true return True
def issue_order(self): global dumpTurn if not self.can_issue_order(): # appears to be redundant with check in IAFleetMission? print "\tcan't issue %s" % self else: universe = fo.getUniverse() self.executed = True # outpost if AIFleetOrderType.ORDER_OUTPOST == self.order_type: planet = universe.getPlanet(self.target.target_id) if not planet.unowned: self.execution_completed = True return fleet_id = self.fleet.target_id 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) result = fo.issueColonizeOrder(ship_id, self.target.target_id) if not result: self.executed = False # colonise elif AIFleetOrderType.ORDER_COLONISE == self.order_type: fleet_id = self.fleet.target_id 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) planet_id = self.target.target_id planet = universe.getPlanet(planet_id) planet_name = planet and planet.name or "apparently invisible" result = fo.issueColonizeOrder(ship_id, planet_id) print "Ordered colony ship ID %d to colonize %s, got result %d" % (ship_id, planet_name, result) if not result: self.executed = False # invade elif AIFleetOrderType.ORDER_INVADE == self.order_type: result = False planet_id = self.target.target_id planet = universe.getPlanet(planet_id) planet_name = planet and planet.name or "invisible" fleet_id = self.fleet.target_id fleet = fo.getUniverse().getFleet(fleet_id) detail_str = "" for ship_id in fleet.shipIDs: ship = universe.getShip(ship_id) if foAI.foAIstate.get_ship_role(ship.design.id) in [AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, AIShipRoleType.SHIP_ROLE_BASE_INVASION]: result = fo.issueInvadeOrder(ship_id, planet_id) or result # will track if at least one invasion troops successfully deployed shields = planet.currentMeterValue(fo.meterType.shield) owner = planet.owner if not result: pstealth = planet.currentMeterValue(fo.meterType.stealth) pop = planet.currentMeterValue(fo.meterType.population) detail_str = " -- planet has %.1f stealth, shields %.1f, %.1f population and is owned by empire %d" % (pstealth, shields, pop, owner) print "Ordered troop ship ID %d to invade %s, got result %d" % (ship_id, planet_name, result), detail_str if not result: if 'needsEmergencyExploration' not in dir(foAI.foAIstate): foAI.foAIstate.needsEmergencyExploration = [] if fleet.systemID not in foAI.foAIstate.needsEmergencyExploration: foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID) print "Due to trouble invading, adding system %d to Emergency Exploration List" % fleet.systemID self.executed = False if shields > 0 and owner == -1 and dumpTurn < fo.currentTurn(): dumpTurn = fo.currentTurn() print "Universe Dump to debug invasions:" universe.dump() break if result: print "Successfully ordered troop ship(s) to invade %s, with detail %s" % (planet_name, detail_str) # military elif AIFleetOrderType.ORDER_MILITARY == self.order_type: fleet_id = self.fleet.target_id #fo.issueFleetMoveOrder(fleet_id, self.target.target_id) #moving is already taken care of separately target_sys_id = self.target.target_id fleet = fo.getUniverse().getFleet(fleet_id) system_status = foAI.foAIstate.systemStatus.get(target_sys_id, {}) if fleet and fleet.systemID == target_sys_id and not (system_status.get('fleetThreat', 0) + system_status.get('planetThreat', 0) + system_status.get('monsterThreat', 0)): self.execution_completed = True # move or resupply elif self.order_type in [AIFleetOrderType.ORDER_MOVE, AIFleetOrderType.ORDER_REPAIR, AIFleetOrderType.ORDER_RESUPPLY]: fleet_id = self.fleet.target_id system_id = self.target.target_id fleet = fo.getUniverse().getFleet(fleet_id) if system_id not in [fleet.systemID, fleet.nextSystemID]: if self.order_type == AIFleetOrderType.ORDER_MOVE: dest_id = system_id else: if self.order_type == AIFleetOrderType.ORDER_REPAIR: fo.issueAggressionOrder(fleet_id, False) start_id = [fleet.systemID, fleet.nextSystemID][fleet.systemID == -1] dest_id = MoveUtilsAI.get_safe_path_leg_to_dest(fleet_id, start_id, system_id) print "fleet %d with order type(%s) sent to safe leg dest %s and ultimate dest %s" % (fleet_id, AIFleetOrderTypeNames.name(self.order_type), PlanetUtilsAI.sys_name_ids([dest_id]), PlanetUtilsAI.sys_name_ids([system_id])) fo.issueFleetMoveOrder(fleet_id, dest_id) if system_id == fleet.systemID: if foAI.foAIstate.get_fleet_role(fleet_id) == AIFleetMissionType.FLEET_MISSION_EXPLORATION: if system_id in foAI.foAIstate.needsEmergencyExploration: del foAI.foAIstate.needsEmergencyExploration[foAI.foAIstate.needsEmergencyExploration.index(system_id)] self.execution_completed = True # split fleet elif AIFleetOrderType.ORDER_SPLIT_FLEET == self.order_type: fleet_id = self.fleet.target_id ship_id = self.target.target_id fleet = fo.getUniverse().getFleet(fleet_id) if ship_id in fleet.shipIDs: fo.issueNewFleetOrder(str(ship_id), ship_id) self.execution_completed = True # attack elif AIFleetOrderType.ORDER_ATTACK == self.order_type: fleet_id = self.fleet.target_id fo.issueFleetMoveOrder(fleet_id, self.target.get_required_system_ai_targets()[0].target_id)
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
def issue_order(self): global dumpTurn if not self.can_issue_order(): # appears to be redundant with check in IAFleetMission? print "\tcan't issue %s" % self else: universe = fo.getUniverse() self.executed = True # outpost if AIFleetOrderType.ORDER_OUTPOST == self.order_type: planet = universe.getPlanet(self.target.target_id) if not planet.unowned: self.execution_completed = True return fleet_id = self.fleet.target_id 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) result = fo.issueColonizeOrder(ship_id, self.target.target_id) if not result: self.executed = False # colonise elif AIFleetOrderType.ORDER_COLONISE == self.order_type: fleet_id = self.fleet.target_id 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) planet_id = self.target.target_id planet = universe.getPlanet(planet_id) planet_name = planet and planet.name or "apparently invisible" result = fo.issueColonizeOrder(ship_id, planet_id) print "Ordered colony ship ID %d to colonize %s, got result %d" % (ship_id, planet_name, result) if not result: self.executed = False # invade elif AIFleetOrderType.ORDER_INVADE == self.order_type: result = False planet_id = self.target.target_id planet = universe.getPlanet(planet_id) planet_name = planet and planet.name or "invisible" fleet_id = self.fleet.target_id fleet = fo.getUniverse().getFleet(fleet_id) detail_str = "" for ship_id in fleet.shipIDs: ship = universe.getShip(ship_id) if foAI.foAIstate.get_ship_role(ship.design.id) in [AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, AIShipRoleType.SHIP_ROLE_BASE_INVASION]: result = fo.issueInvadeOrder(ship_id, planet_id) or result # will track if at least one invasion troops successfully deployed shields = planet.currentMeterValue(fo.meterType.shield) owner = planet.owner if not result: pstealth = planet.currentMeterValue(fo.meterType.stealth) pop = planet.currentMeterValue(fo.meterType.population) detail_str = " -- planet has %.1f stealth, shields %.1f, %.1f population and is owned by empire %d" % (pstealth, shields, pop, owner) print "Ordered troop ship ID %d to invade %s, got result %d" % (ship_id, planet_name, result), detail_str if not result: if 'needsEmergencyExploration' not in dir(foAI.foAIstate): foAI.foAIstate.needsEmergencyExploration = [] if fleet.systemID not in foAI.foAIstate.needsEmergencyExploration: foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID) print "Due to trouble invading, adding system %d to Emergency Exploration List" % fleet.systemID self.executed = False if shields > 0 and owner == -1 and dumpTurn < fo.currentTurn(): dumpTurn = fo.currentTurn() print "Universe Dump to debug invasions:" universe.dump() break if result: print "Successfully ordered troop ship(s) to invade %s, with detail %s" % (planet_name, detail_str) # military elif AIFleetOrderType.ORDER_MILITARY == self.order_type: fleet_id = self.fleet.target_id #fo.issueFleetMoveOrder(fleet_id, self.target.target_id) #moving is already taken care of separately target_sys_id = self.target.target_id fleet = fo.getUniverse().getFleet(fleet_id) system_status = foAI.foAIstate.systemStatus.get(target_sys_id, {}) if fleet and fleet.systemID == target_sys_id and not (system_status.get('fleetThreat', 0) + system_status.get('planetThreat', 0) + system_status.get('monsterThreat', 0)): self.execution_completed = True # move or resupply elif self.order_type in [AIFleetOrderType.ORDER_MOVE, AIFleetOrderType.ORDER_REPAIR, AIFleetOrderType.ORDER_RESUPPLY]: fleet_id = self.fleet.target_id system_id = self.target.target_id fleet = fo.getUniverse().getFleet(fleet_id) if system_id not in [fleet.systemID, fleet.nextSystemID]: if self.order_type == AIFleetOrderType.ORDER_MOVE: dest_id = system_id else: if self.order_type == AIFleetOrderType.ORDER_REPAIR: fo.issueAggressionOrder(fleet_id, False) start_id = [fleet.systemID, fleet.nextSystemID][fleet.systemID == -1] dest_id = MoveUtilsAI.get_safe_path_leg_to_dest(fleet_id, start_id, system_id) print "fleet %d with order type(%s) sent to safe leg dest %s and ultimate dest %s" % (fleet_id, AIFleetOrderTypeNames.name(self.order_type), PlanetUtilsAI.sys_name_ids([dest_id]), PlanetUtilsAI.sys_name_ids([system_id])) fo.issueFleetMoveOrder(fleet_id, dest_id) if system_id == fleet.systemID: if foAI.foAIstate.get_fleet_role(fleet_id) == AIFleetMissionType.FLEET_MISSION_EXPLORATION: if system_id in foAI.foAIstate.needsEmergencyExploration: del foAI.foAIstate.needsEmergencyExploration[foAI.foAIstate.needsEmergencyExploration.index(system_id)] self.execution_completed = True # split fleet elif AIFleetOrderType.ORDER_SPLIT_FLEET == self.order_type: fleet_id = self.fleet.target_id ship_id = self.target.target_id fleet = fo.getUniverse().getFleet(fleet_id) if ship_id in fleet.shipIDs: fo.issueNewFleetOrder(str(ship_id), ship_id) self.execution_completed = True # attack elif AIFleetOrderType.ORDER_ATTACK == self.order_type: fleet_id = self.fleet.target_id fo.issueFleetMoveOrder(fleet_id, self.target.get_required_system_ai_targets()[0].target_id)
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
def can_issue_order(self, verbose=False): ship_id = FleetUtilsAI.get_ship_id_with_role(self.fleet.id, AIShipRoleType.SHIP_ROLE_MILITARY) universe = fo.getUniverse() ship = universe.getShip(ship_id) return ship is not None and self.fleet.get_system() == self.target and ship.isArmed