def __border_exploration_update(self): universe = fo.getUniverse() exploration_center = PlanetUtilsAI.get_capital_sys_id() # a bad state probably from an old savegame, or else empire has lost (or almost has) if exploration_center == INVALID_ID: exploration_center = self.__origin_home_system_id ExplorationAI.graph_flags.clear() if fo.currentTurn() < 50: print "-------------------------------------------------" print "Border Exploration Update (relative to %s)" % universe.getSystem(exploration_center) print "-------------------------------------------------" if self.visBorderSystemIDs == {INVALID_ID}: self.visBorderSystemIDs.clear() self.visBorderSystemIDs.add(exploration_center) for sys_id in list(self.visBorderSystemIDs): # This set is modified during iteration. if fo.currentTurn() < 50: print "Considering border system %s" % universe.getSystem(sys_id) ExplorationAI.follow_vis_system_connections(sys_id, exploration_center) newly_explored = ExplorationAI.update_explored_systems() nametags = [] for sys_id in newly_explored: newsys = universe.getSystem(sys_id) # an explored system *should* always be able to be gotten nametags.append("ID:%4d -- %-20s" % (sys_id, (newsys and newsys.name) or "name unknown")) if newly_explored: print "-------------------------------------------------" print "Newly explored systems:\n%s" % "\n".join(nametags) print "-------------------------------------------------"
def generateOrders(): empire = fo.getEmpire() print "Empire: " + empire.name + " TURN: " + str(fo.currentTurn()) print "Capital: " + str(empire.capitalID) # turn cleanup splitFleet() identifyShipDesigns() identifyFleetsRoles() foAIstate.clean(ExplorationAI.getHomeSystemID(), FleetUtilsAI.getEmpireFleetIDs()) # ...missions # ...demands/priorities # call AI modules PriorityAI.calculatePriorities() ExplorationAI.assignScoutsToExploreSystems() ColonisationAI.assignColonyFleetsToColonise() InvasionAI.assignInvasionFleetsToInvade() FleetUtilsAI.generateAIFleetOrdersForAIFleetMissions() FleetUtilsAI.issueAIFleetOrdersForAIFleetMissions() ResearchAI.generateResearchOrders() ProductionAI.generateProductionOrders() ResourcesAI.generateResourcesOrders() foAIstate.afterTurnCleanup() fo.doneTurn()
def __border_exploration_update(self): universe = fo.getUniverse() exploration_center = PlanetUtilsAI.get_capital_sys_id() # a bad state probably from an old savegame, or else empire has lost (or almost has) if exploration_center == INVALID_ID: exploration_center = self.__origin_home_system_id ExplorationAI.graph_flags.clear() if fo.currentTurn() < 50: debug("-------------------------------------------------") debug("Border Exploration Update (relative to %s)" % universe.getSystem(exploration_center)) debug("-------------------------------------------------") if self.visBorderSystemIDs == {INVALID_ID}: self.visBorderSystemIDs.clear() self.visBorderSystemIDs.add(exploration_center) for sys_id in list(self.visBorderSystemIDs): # This set is modified during iteration. if fo.currentTurn() < 50: debug("Considering border system %s" % universe.getSystem(sys_id)) ExplorationAI.follow_vis_system_connections(sys_id, exploration_center) newly_explored = ExplorationAI.update_explored_systems() nametags = [] for sys_id in newly_explored: newsys = universe.getSystem(sys_id) # an explored system *should* always be able to be gotten nametags.append("ID:%4d -- %-20s" % (sys_id, (newsys and newsys.name) or "name unknown")) if newly_explored: debug("-------------------------------------------------") debug("Newly explored systems:\n%s" % "\n".join(nametags)) debug("-------------------------------------------------")
def clean(self): global invasionTargets "turn start AIstate cleanup" fleetsLostBySystem.clear() fleetsLostByID.clear() invasionTargets=[] ExplorationAI.graphFlags.clear() print "-------------------------------------------------" print "Border Exploration Update" print "-------------------------------------------------" for sysID in list(self.visBorderSystemIDs): ExplorationAI.followVisSystemConnections(sysID, self.origHomeSystemID) newlyExplored = ExplorationAI.updateExploredSystems() nametags=[] universe = fo.getUniverse() for sysID in newlyExplored: newsys = universe.getSystem(sysID) nametags.append( "ID:%4d -- %20s"%(sysID, (newsys and newsys.name) or"name unknown" ) )# an explored system *should* always be able to be gotten if newlyExplored: print "-------------------------------------------------" print "newly explored systems: \n"+"\n".join(nametags) print "-------------------------------------------------" # cleanup fleet roles #self.updateFleetLocs() self.__cleanFleetRoles() self.__cleanAIFleetMissions(FleetUtilsAI.getEmpireFleetIDs()) print "Fleets lost by system: %s"%fleetsLostBySystem self.updateSystemStatus() ExplorationAI.updateScoutFleets() #should do this after clearing dead fleets, currently should be already done here
def generateOrders(): print ("Genearting Orders") universe = fo.getUniverse() empire = fo.getEmpire() planetID = empire.capitalID planet = universe.getPlanet(planetID) print "EmpireID: " + str(empire.empireID) + " Name: " + empire.name + " Turn: " + str(fo.currentTurn()) print "CapitalID: " + str(planetID) + " Name: " + planet.name + " Species: " + planet.speciesName # turn cleanup splitFleet() identifyShipDesigns() identifyFleetsRoles() foAIstate.clean(ExplorationAI.getHomeSystemID(), FleetUtilsAI.getEmpireFleetIDs()) # ...missions # ...demands/priorities print("Calling AI Modules") # call AI modules PriorityAI.calculatePriorities() ExplorationAI.assignScoutsToExploreSystems() ColonisationAI.assignColonyFleetsToColonise() InvasionAI.assignInvasionFleetsToInvade() MilitaryAI.assignMilitaryFleetsToSystems() FleetUtilsAI.generateAIFleetOrdersForAIFleetMissions() FleetUtilsAI.issueAIFleetOrdersForAIFleetMissions() ResearchAI.generateResearchOrders() ProductionAI.generateProductionOrders() ResourcesAI.generateResourcesOrders() foAIstate.afterTurnCleanup() fo.doneTurn()
def refresh(self): """Turn start AIstate cleanup/refresh.""" universe = fo.getUniverse() # checks exploration border & clears roles/missions of missing fleets & updates fleet locs & threats fleetsLostBySystem.clear() invasionTargets[:] = [] exploration_center = PlanetUtilsAI.get_capital_sys_id() # a bad state probably from an old savegame, or else empire has lost (or almost has) if exploration_center == INVALID_ID: exploration_center = self.__origin_home_system_id for system_id, info in sorted(self.systemStatus.items()): self.systemStatus[system_id][ 'enemy_ship_count'] = 0 # clear now in prep for update_system_status() ExplorationAI.graph_flags.clear() if fo.currentTurn() < 50: print "-------------------------------------------------" print "Border Exploration Update (relative to %s)" % ( PlanetUtilsAI.sys_name_ids([exploration_center, INVALID_ID ])[0]) print "-------------------------------------------------" if self.visBorderSystemIDs == {INVALID_ID}: self.visBorderSystemIDs.clear() self.visBorderSystemIDs.add(exploration_center) for sys_id in list(self.visBorderSystemIDs ): # This set is modified during iteration. if fo.currentTurn() < 50: print "Considering border system %s" % ( PlanetUtilsAI.sys_name_ids([sys_id, INVALID_ID])[0]) ExplorationAI.follow_vis_system_connections( sys_id, exploration_center) newly_explored = ExplorationAI.update_explored_systems() nametags = [] for sys_id in newly_explored: newsys = universe.getSystem(sys_id) # an explored system *should* always be able to be gotten nametags.append("ID:%4d -- %-20s" % (sys_id, (newsys and newsys.name) or "name unknown")) if newly_explored: print "-------------------------------------------------" print "Newly explored systems:\n%s" % "\n".join(nametags) print "-------------------------------------------------" # cleanup fleet roles # self.update_fleet_locs() self.__clean_fleet_roles() self.__clean_fleet_missions(FleetUtilsAI.get_empire_fleet_ids()) print "Fleets lost by system: %s" % fleetsLostBySystem self.update_system_status()
def refresh(self): """Turn start AIstate cleanup/refresh.""" universe = fo.getUniverse() # checks exploration border & clears roles/missions of missing fleets & updates fleet locs & threats fleetsLostBySystem.clear() invasionTargets[:] = [] exploration_center = PlanetUtilsAI.get_capital_sys_id() if exploration_center == -1: # a bad state probably from an old savegame, or else empire has lost (or almost has) exploration_center = self.__origin_home_system_id # check if planets in cache is still present. Remove destroyed. for system_id, info in sorted(self.systemStatus.items()): planet_dict = info.get('planets', {}) cache_planet_set = set(planet_dict) system_planet_set = set(universe.getSystem(system_id).planetIDs) diff = cache_planet_set - system_planet_set if diff: print "Removing destroyed planets from systemStatus for system %s: planets to be removed: %s" % (system_id, sorted(diff)) for key in diff: del planet_dict[key] ExplorationAI.graphFlags.clear() if fo.currentTurn() < 50: print "-------------------------------------------------" print "Border Exploration Update (relative to %s)" % (PlanetUtilsAI.sys_name_ids([exploration_center, -1])[0]) print "-------------------------------------------------" if self.visBorderSystemIDs.keys() == [-1]: self.visBorderSystemIDs.clear() self.visBorderSystemIDs[exploration_center] = 1 for sys_id in self.visBorderSystemIDs.keys(): # This dict modified during iteration. if fo.currentTurn() < 50: print "Considering border system %s" % (PlanetUtilsAI.sys_name_ids([sys_id, -1])[0]) ExplorationAI.follow_vis_system_connections(sys_id, exploration_center) newly_explored = ExplorationAI.update_explored_systems() nametags = [] for sys_id in newly_explored: newsys = universe.getSystem(sys_id) nametags.append("ID:%4d -- %-20s" % (sys_id, (newsys and newsys.name) or "name unknown")) # an explored system *should* always be able to be gotten if newly_explored: print "-------------------------------------------------" print "Newly explored systems:\n%s" % "\n".join(nametags) print "-------------------------------------------------" # cleanup fleet roles # self.update_fleet_locs() self.__clean_fleet_roles() self.__clean_fleet_missions(FleetUtilsAI.get_empire_fleet_ids()) print "Fleets lost by system: %s" % fleetsLostBySystem self.update_system_status()
def clean(self): "turn start AIstate cleanup" fleetsLostBySystem.clear() fleetsLostByID.clear() invasionTargets[:]=[] exploration_center = PlanetUtilsAI.getCapitalSysID() if exploration_center == -1: #a bad state probably from an old savegame exploration_center = self.origHomeSystemID ExplorationAI.graphFlags.clear() if fo.currentTurn() < 50: print "-------------------------------------------------" print "Border Exploration Update (relative to %s"%(PlanetUtilsAI.sysNameIDs([exploration_center, -1])[0]) print "-------------------------------------------------" if self.visBorderSystemIDs.keys() == [-1]: self.visBorderSystemIDs.clear() self.visBorderSystemIDs[exploration_center] = 1 for sysID in list(self.visBorderSystemIDs): if fo.currentTurn() < 50: print "Considering border system %s"%(PlanetUtilsAI.sysNameIDs([sysID, -1])[0]) ExplorationAI.followVisSystemConnections(sysID, exploration_center) newlyExplored = ExplorationAI.updateExploredSystems() nametags=[] universe = fo.getUniverse() for sysID in newlyExplored: newsys = universe.getSystem(sysID) nametags.append( "ID:%4d -- %20s"%(sysID, (newsys and newsys.name) or"name unknown" ) )# an explored system *should* always be able to be gotten if newlyExplored: print "-------------------------------------------------" print "newly explored systems: \n"+"\n".join(nametags) print "-------------------------------------------------" # cleanup fleet roles #self.updateFleetLocs() self.__cleanFleetRoles() self.__cleanAIFleetMissions(FleetUtilsAI.getEmpireFleetIDs()) print "Fleets lost by system: %s"%fleetsLostBySystem self.updateSystemStatus() ExplorationAI.updateScoutFleets() #should do this after clearing dead fleets, currently should be already done here
def refresh(self): """Turn start AIstate cleanup/refresh.""" universe = fo.getUniverse() # checks exploration border & clears roles/missions of missing fleets & updates fleet locs & threats fleetsLostBySystem.clear() invasionTargets[:] = [] exploration_center = PlanetUtilsAI.get_capital_sys_id() if exploration_center == INVALID_ID: # a bad state probably from an old savegame, or else empire has lost (or almost has) exploration_center = self.__origin_home_system_id for system_id, info in sorted(self.systemStatus.items()): self.systemStatus[system_id]['enemy_ship_count'] = 0 # clear now in prep for update_system_status() ExplorationAI.graph_flags.clear() if fo.currentTurn() < 50: print "-------------------------------------------------" print "Border Exploration Update (relative to %s)" % (PlanetUtilsAI.sys_name_ids([exploration_center, INVALID_ID])[0]) print "-------------------------------------------------" if self.visBorderSystemIDs == {INVALID_ID}: self.visBorderSystemIDs.clear() self.visBorderSystemIDs.add(exploration_center) for sys_id in list(self.visBorderSystemIDs): # This set is modified during iteration. if fo.currentTurn() < 50: print "Considering border system %s" % (PlanetUtilsAI.sys_name_ids([sys_id, INVALID_ID])[0]) ExplorationAI.follow_vis_system_connections(sys_id, exploration_center) newly_explored = ExplorationAI.update_explored_systems() nametags = [] for sys_id in newly_explored: newsys = universe.getSystem(sys_id) nametags.append("ID:%4d -- %-20s" % (sys_id, (newsys and newsys.name) or "name unknown")) # an explored system *should* always be able to be gotten if newly_explored: print "-------------------------------------------------" print "Newly explored systems:\n%s" % "\n".join(nametags) print "-------------------------------------------------" # cleanup fleet roles # self.update_fleet_locs() self.__clean_fleet_roles() self.__clean_fleet_missions(FleetUtilsAI.get_empire_fleet_ids()) print "Fleets lost by system: %s" % fleetsLostBySystem self.update_system_status()
def getMilitaryFleets(tryReset=True): "get armed military fleets" global MilitaryAllocations, totMilRating universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID capitalID = PlanetUtilsAI.getCapital() if capitalID == None: homeworld=None else: homeworld = universe.getPlanet(capitalID) if homeworld: homeSystemID = homeworld.systemID else: homeSystemID=-1 allMilitaryFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_MILITARY ) if tryReset and ((fo.currentTurn()+empireID) % 10 ==0): tryAgain(allMilitaryFleetIDs) totMilRating = sum( map(lambda x: foAI.foAIstate.getRating(x).get('overall', 0), allMilitaryFleetIDs ) ) milShips = 0 for fid in allMilitaryFleetIDs: milShips += foAI.foAIstate.fleetStatus.get(fid, {}).get('nships', 0) print "==================================================" print "Total Military Rating: %d"%totMilRating print "---------------------------------" foAI.foAIstate.militaryRating=totMilRating milFleetIDs = list( FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allMilitaryFleetIDs)) availMilRating = sum( map(lambda x: foAI.foAIstate.getRating(x).get('overall', 0), milFleetIDs ) ) print "==================================================" print "Available Military Rating: %d"%availMilRating print "---------------------------------" remainingMilRating = availMilRating allocations = [] if milFleetIDs == []: MilitaryAllocations = [] return alreadyAssignedRating={} for sysID in universe.systemIDs: alreadyAssignedRating[sysID]=0 for fleetID in [fid for fid in allMilitaryFleetIDs if fid not in milFleetIDs]: aiFleetMission = foAI.foAIstate.getAIFleetMission(fleetID) sysTargets= [] for aiFleetMissionType in aiFleetMission.getAIMissionTypes(): aiTargets = aiFleetMission.getAITargets(aiFleetMissionType) for aiTarget in aiTargets: sysTargets.extend(aiTarget.getRequiredSystemAITargets()) if not sysTargets: #shouldn't really be possible continue lastSys = sysTargets[-1].getTargetID() # will count this fleet as assigned to last system in target list alreadyAssignedRating[lastSys] += foAI.foAIstate.getRating(fleetID).get('overall', 0) #TODO: would preferably tally attack and health and take product # get systems to defend capitalID = PlanetUtilsAI.getCapital() if capitalID != None: capitalPlanet = universe.getPlanet(capitalID) else: capitalPlanet=None #TODO: if no owned planets try to capture one! if capitalPlanet: capitalSysID = capitalPlanet.systemID else: # should be rare, but so as to not break code below, pick a randomish mil-centroid system systemDict = {} for fleetID in allMilitaryFleetIDs: status = foAI.foAIstate.fleetStatus.get(fleetID, None) if status is not None: sysID = status['sysID'] if len( list( universe.getSystem(sysID).planetIDs ) ) ==0: continue systemDict[sysID] = systemDict.get( sysID, 0) + status.get('rating', {}).get('overall', 0) rankedSystems = sorted( [(val, sysID) for sysID, val in systemDict.items() ] ) if rankedSystems: capitalSysID = rankedSystems[-1][-1] else: capitalSysID = foAI.foAIstate.fleetStatus.items()[0]['sysID'] if fo.currentTurn() < 20: threatBias = 0 elif fo.currentTurn() < 40: threatBias = 10 elif fo.currentTurn() < 60: threatBias = 80 elif fo.currentTurn() < 80: threatBias = 200 else: threatBias = 400 threatBias = 0 safetyFactor = [ 4.0, 3.0, 1.5, 1.0, 1.0, 0.95 ][foAI.foAIstate.aggression] topTargetPlanets = [pid for pid, pscore, trp in AIstate.invasionTargets[:PriorityAI.allottedInvasionTargets] if pscore > 20] + [pid for pid, pscore in foAI.foAIstate.colonisablePlanetIDs[:10] if pscore > 20] topTargetSystems = [] for sysID in PlanetUtilsAI.getSystems( topTargetPlanets ): if sysID not in topTargetSystems: topTargetSystems.append(sysID) #doing this rather than set, to preserve order # allocation format: ( sysID, newAllocation, takeAny, maxMultiplier ) #================================ #--------Capital Threat ---------- capitalThreat = safetyFactor*(2* threatBias +sum( [ foAI.foAIstate.systemStatus[capitalSysID][thrtKey] for thrtKey in [tkey for tkey in foAI.foAIstate.systemStatus.get(capitalSysID, {}).keys() if 'Threat' in tkey]] )) newAlloc=0 if tryReset: if (capitalThreat > 0.5*(availMilRating+0.8*alreadyAssignedRating[capitalSysID]) ) : tryAgain(allMilitaryFleetIDs) return if capitalThreat > 0.8*alreadyAssignedRating[capitalSysID]: newAlloc = min(remainingMilRating, int( 0.999 + 1.2*(capitalThreat- 0.8*alreadyAssignedRating[capitalSysID]) ) ) allocations.append( ( capitalSysID, newAlloc, True, 3) ) remainingMilRating -= newAlloc print "Empire Capital System: (%d) %s -- threat : %d, military allocation: existing: %d ; new: %d"%(capitalSysID, universe.getSystem(capitalSysID).name , capitalThreat, alreadyAssignedRating[capitalSysID], newAlloc) print "-----------------" #================================ #--------Empire Occupied Systems ---------- empirePlanetIDs = PlanetUtilsAI.getOwnedPlanetsByEmpire(universe.planetIDs, empireID) empireOccupiedSystemIDs = list( set(PlanetUtilsAI.getSystems(empirePlanetIDs)) - set([capitalSysID] ) ) print "Empire-Occupied Systems: %s"%( [ "| %d %s |"%(eoSysID, universe.getSystem(eoSysID).name) for eoSysID in empireOccupiedSystemIDs ] ) print "-----------------" if len( empireOccupiedSystemIDs ) > 0: ocSysTotThreat = [ ( oSID, threatBias +safetyFactor*sum( [ foAI.foAIstate.systemStatus.get(oSID, {}).get(thrtKey, 0) for thrtKey in ['fleetThreat', 'monsterThreat','planetThreat', 'neighborThreat']] ) ) for oSID in empireOccupiedSystemIDs ] totocSysThreat = sum( [thrt for sid, thrt in ocSysTotThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in ocSysTotThreat] ) allocationFactor = min( 1.2, remainingMilRating /max(0.01, ( totocSysThreat -totCurAlloc) )) ocSysAlloc = 0 for sid, thrt in ocSysTotThreat: curAlloc=0.8*alreadyAssignedRating[sid] if (thrt > 0.8*(remainingMilRating+curAlloc )) and tryReset: tryAgain(allMilitaryFleetIDs) return thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 0: thisAlloc = max(0, min( min( int(0.99999 + (thrt-curAlloc)*allocationFactor ), 0.5*availMilRating) , remainingMilRating)) allocations.append( (sid, thisAlloc, True, 2) ) remainingMilRating -= thisAlloc ocSysAlloc += thisAlloc print "Provincial Empire-Occupied Sytems under total threat: %d -- total mil allocation: existing %d ; new: %d"%(totocSysThreat, totCurAlloc, ocSysAlloc ) print "-----------------" #================================ #--------Top Targeted Systems ---------- #TODO: do native invasions highest priority otherTargetedSystemIDs = topTargetSystems print "Top Colony and Invasion Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0)) ) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if 2*thrt>curAlloc and (curAlloc>0 or remainingMilRating > (10+ (2*thrt-curAlloc))): #only record more allocation for this invasion if we already started or have enough rating available thisAlloc =int(10.99999 + (1.5*thrt-curAlloc)) takeAny= curAlloc>0 allocations.append( (sid, thisAlloc, takeAny ,4) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Top Colony and Invasion Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" #================================ #--------Targeted Systems ---------- #TODO: do native invasions highest priority otherTargetedSystemIDs = [sysID for sysID in AIstate.invasionTargetedSystemIDs if sysID not in topTargetSystems] print "Other Invasion Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, max(10, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0)) ) ) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if thrt>curAlloc and remainingMilRating > 10+ 1.5*(thrt-curAlloc) : #only record an allocation for this invasion if we have enough rating available thisAlloc =int(10.99999 + (thrt-curAlloc)*1.5) allocations.append( (sid, thisAlloc, False, 3) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Invasion Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" otherTargetedSystemIDs = [sysID for sysID in list(set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs)) if sysID not in topTargetSystems] print "Other Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, safetyFactor*(threatBias +foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) )) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 1.5*(thrt-curAlloc): thisAlloc = min( min( int(0.99999 + (thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, False, 2.0) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Other Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" otherTargetedSystemIDs = [] fleetSuppliableSystemIDs = empire.fleetSupplyableSystemIDs for sysID in AIstate.opponentSystemIDs: if sysID in fleetSuppliableSystemIDs: otherTargetedSystemIDs.append(sysID) else: for nID in universe.getImmediateNeighbors(sysID, empireID): if nID in fleetSuppliableSystemIDs: otherTargetedSystemIDs.append(sysID) break print "Blockade Targeted Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in otherTargetedSystemIDs ] ) print "-----------------" # for these, calc local threat only, no neighbor threat, but use a multiplier for fleet safety if len( otherTargetedSystemIDs ) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) )) for oSID in otherTargetedSystemIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 1.5*(thrt-curAlloc): thisAlloc = min( min( int(0.99999 + (thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, False, 10) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Blockade Targeted system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Blockade Targeted Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" currentMilSystems = [sid for sid, alloc, takeAny, mm in allocations ] interiorIDs = list( foAI.foAIstate.expInteriorSystemIDs) interiorTargets1 = [sid for sid in interiorIDs if ( ( sid not in currentMilSystems )) ] interiorTargets = [sid for sid in interiorIDs if ( (threatBias + foAI.foAIstate.systemStatus.get(sid, {}).get('fleetThreat', 0) >0.8*alreadyAssignedRating[sid] ) ) ] print "" print "Other Empire-Interior Systems : %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in interiorTargets1 ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety if len(interiorTargets) >0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)) ) for oSID in interiorTargets ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 0 : thisAlloc = min( min( int(0.99999 +( thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, True, 1.2) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Other interior system %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Other Interior Systems under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" else: print "-----------------" print "No Other Interior Systems with fleet threat " print "-----------------" monsterDens=[] exploTargetIDs, _ = ExplorationAI.getCurrentExplorationInfo(verbose=False) print "" print "Exploration-targeted Systems: %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in exploTargetIDs ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety if len(exploTargetIDs) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) )) for oSID in exploTargetIDs ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) if availMilRating <1125: maxMilRating = availMilRating else: maxMilRating = 0.5*availMilRating for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 0: if foAI.foAIstate.systemStatus.get(sid, {}).get('monsterThreat', 0) > 2000: monsterDens.append(sid) continue # consider dealing with big monsters later thisAlloc = min( min( int(0.99999 + (thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, False, 2) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Exploration-targeted %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Exploration-targeted s under total threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" visibleSystemIDs = foAI.foAIstate.visInteriorSystemIDs.keys() + foAI.foAIstate. visBorderSystemIDs.keys() accessibleSystemIDs = [sysID for sysID in visibleSystemIDs if universe.systemsConnected(sysID, homeSystemID, empireID) ] currentMilSystems = [sid for sid, alloc, takeAny, multiplier in allocations if alloc > 0 ] borderTargets1 = [sid for sid in accessibleSystemIDs if ( ( sid not in currentMilSystems )) ] borderTargets = [sid for sid in borderTargets1 if ( ( threatBias +foAI.foAIstate.systemStatus.get(sid, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(sid, {}).get('planetThreat', 0) > 0.8*alreadyAssignedRating[sid] )) ] print "" print "Empire-Accessible Systems not yet allocated military: %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID) and universe.getSystem(sysID).name) for sysID in borderTargets1 ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety if len(borderTargets) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, threatBias +safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0)+ foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0)) ) for oSID in borderTargets ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 0: if foAI.foAIstate.systemStatus.get(sid, {}).get('monsterThreat', 0) > 2000: if sid not in monsterDens: monsterDens.append(sid) continue # consider dealing with big monsters later thisAlloc = min( min( int(0.99999 + (thrt-curAlloc)*1.5), remainingMilRating ), 0.5*availMilRating) allocations.append( (sid, thisAlloc, False, 5) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Other Empire-Accessible system %4d ( %10s ) has local biased threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" print "Other Empire-Accessible Systems under total biased threat: %d -- total mil allocation-- existing: %d ; new: %d"%(tototSysThreat, totCurAlloc, otSysAlloc ) print "-----------------" else: print "-----------------" print "No Other Empire-Accessible Systems with biased local threat " print "-----------------" print "" print "Big-Monster Dens: %s"%( [ "| %d %s |"%(sysID, universe.getSystem(sysID).name) for sysID in monsterDens ] ) print "-----------------" # for these, calc fleet threat only, no neighbor threat, but use a multiplier for fleet safety if len(monsterDens) > 0: otSysAlloc = 0 otSysThreat = [ ( oSID, safetyFactor*(foAI.foAIstate.systemStatus.get(oSID, {}).get('fleetThreat', 0)+foAI.foAIstate.systemStatus.get(oSID, {}).get('monsterThreat', 0) + foAI.foAIstate.systemStatus.get(oSID, {}).get('planetThreat', 0) ) ) for oSID in monsterDens ] tototSysThreat = sum( [thrt for sid, thrt in otSysThreat] ) totCurAlloc = sum( [0.8*alreadyAssignedRating[sid] for sid, thrt in otSysThreat] ) for sid, thrt in otSysThreat: curAlloc=0.8*alreadyAssignedRating[sid] thisAlloc=0 if (thrt > curAlloc) and remainingMilRating > 2* thrt: thisAlloc = int(0.99999 + (thrt-curAlloc)*1.5) allocations.append( (sid, thisAlloc, False, 5) ) remainingMilRating -= thisAlloc otSysAlloc += thisAlloc print "Monster Den %4d ( %10s ) has local threat %8d ; existing military allocation %d and new allocation %8d"%(sid, universe.getSystem(sid).name, thrt, curAlloc, thisAlloc) print "-----------------" if remainingMilRating <=6: newAllocations = [ (sid, alc, alc, ta) for (sid, alc, ta, mm) in allocations ] else: try: totAlloc = sum( [alloc for sid, alloc, takeAny, maxMul in allocations ] ) except: print "error unpacking sid, alloc, takeAny, maxMul from ", allocations factor =(2.0* remainingMilRating ) / ( totAlloc + 0.1) print "Remaining military strength allocation %d will be allocated as %.1f %% surplus allocation to top current priorities"%(remainingMilRating, 100*factor) newAllocations = [] for sid, alloc, takeAny, maxMul in allocations: if remainingMilRating <= 0 : newAllocations.append( ( sid, alloc, alloc, takeAny ) ) else: thisAlloc = int( max( maxMul-1, factor )* alloc ) newAllocations.append( ( sid, alloc+thisAlloc, alloc, takeAny ) ) remainingMilRating -= thisAlloc MilitaryAllocations = newAllocations minMilAllocations = dict( [ (sid, alloc) for sid, alloc, takeAny, mm in allocations ] ) print "------------------------------\nFinal Military Allocations: %s \n-----------------------"%dict( [ (sid, alloc) for sid, alloc, minalloc, takeAny in newAllocations ] ) # export military systems for other AI modules AIstate.militarySystemIDs = [sid for sid, alloc, minalloc, takeAny in newAllocations]
def send_colony_ships(colony_fleet_ids, evaluated_planets, mission_type): """sends a list of colony ships to a list of planet_value_pairs""" fleet_pool = colony_fleet_ids[:] try_all = False if mission_type == MissionType.OUTPOST: cost = 20 + outpod_pod_cost() else: try_all = True cost = 20 + colony_pod_cost_turns()[1] if fo.currentTurn() < 50: cost *= 0.4 # will be making fast tech progress so value is underestimated elif fo.currentTurn() < 80: cost *= 0.8 # will be making fast-ish tech progress so value is underestimated potential_targets = [ (pid, (score, specName)) for (pid, (score, specName)) in evaluated_planets if score > (0.8 * cost) and score > MINIMUM_COLONY_SCORE ] debug("Colony/outpost ship matching: fleets %s to planets %s" % (fleet_pool, evaluated_planets)) if try_all: debug("Trying best matches to current colony ships") best_scores = dict(evaluated_planets) potential_targets = [] for pid, ratings in _all_colony_opportunities.items(): for rating in ratings: if rating[0] >= 0.75 * best_scores.get(pid, [9999])[0]: potential_targets.append((pid, rating)) potential_targets.sort(key=itemgetter(1), reverse=True) # added a lot of checking because have been getting mysterious exception, after too many recursions to get info fleet_pool = set(fleet_pool) universe = fo.getUniverse() for fid in fleet_pool: fleet = universe.getFleet(fid) if not fleet or fleet.empty: warning("Bad fleet ( ID %d ) given to colonization routine; will be skipped" % fid) fleet_pool.remove(fid) continue report_str = "Fleet ID (%d): %d ships; species: " % (fid, fleet.numShips) for sid in fleet.shipIDs: ship = universe.getShip(sid) if not ship: report_str += "NoShip, " else: report_str += "%s, " % ship.speciesName debug(report_str) debug("") already_targeted = [] # for planetID_value_pair in evaluatedPlanets: aistate = get_aistate() while fleet_pool and potential_targets: target = potential_targets.pop(0) if target in already_targeted: continue planet_id = target[0] if planet_id in already_targeted: continue planet = universe.getPlanet(planet_id) sys_id = planet.systemID if ( aistate.systemStatus.setdefault(sys_id, {}).setdefault("monsterThreat", 0) > 2000 or fo.currentTurn() < 20 and aistate.systemStatus[sys_id]["monsterThreat"] > 200 ): debug( "Skipping colonization of system %s due to Big Monster, threat %d" % (universe.getSystem(sys_id), aistate.systemStatus[sys_id]["monsterThreat"]) ) already_targeted.append(planet_id) continue # make sure not to run into stationary guards if ExplorationAI.system_could_have_unknown_stationary_guard(sys_id): ExplorationAI.request_emergency_exploration(sys_id) continue this_spec = target[1][1] found_fleets = [] try: this_fleet_list = FleetUtilsAI.get_fleets_for_mission( target_stats={}, min_stats={}, cur_stats={}, starting_system=sys_id, species=this_spec, fleet_pool_set=fleet_pool, fleet_list=found_fleets, ) except Exception as e: error(e, exc_info=True) continue if not this_fleet_list: fleet_pool.update(found_fleets) # just to be safe continue # must have no compatible colony/outpost ships fleet_id = this_fleet_list[0] already_targeted.append(planet_id) ai_target = TargetPlanet(planet_id) aistate.get_fleet_mission(fleet_id).set_target(mission_type, ai_target)
def generateOrders(): global lastTurnTimestamp universe = fo.getUniverse() turnStartTime=time() #starting AI timer here, to be sure AI doesn't get blame for any lags in server being able to provide the Universe object empire = fo.getEmpire() planetID = PlanetUtilsAI.getCapital() planet=None if planetID is not None: planet = universe.getPlanet(planetID) print "***************************************************************************" print "***************************************************************************" print ("Generating Orders") print "EmpireID: " + str(empire.empireID) + " Name: " + empire.name+ "_"+str(empire.empireID-1) +"_pid:"+str(fo.playerID())+"_"+fo.playerName()+"_"+aggressions.get(foAIstate.aggression, "?") + " Turn: " + str(fo.currentTurn()) empireColor=empire.colour print "EmpireColors: %d %d %d %d"%(empireColor.r, empireColor.g, empireColor.b, empireColor.a) if planet: print "CapitalID: " + str(planetID) + " Name: " + planet.name + " Species: " + planet.speciesName else: print "CapitalID: None Currently Name: None Species: None " print "***************************************************************************" print "***************************************************************************" if fo.currentTurn() == 1: declareWarOnAll() # turn cleanup !!! this was formerly done at start of every turn -- not sure why splitNewFleets() #updateShipDesigns() #should not be needed anymore; #updateFleetsRoles() foAIstate.clean() #checks exploration border & clears roles/missions of missing fleets & updates fleet locs foAIstate.reportSystemThreats() # ...missions # ...demands/priorities print("Calling AI Modules") # call AI modules timer=[time()] try: PriorityAI.calculatePriorities() except: print "Error: exception triggered and caught: ", traceback.format_exc() # try traceback.print_exc() timer.append( time() ) try: ExplorationAI.assignScoutsToExploreSystems() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: ColonisationAI.assignColonyFleetsToColonise() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: InvasionAI.assignInvasionFleetsToInvade() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: MilitaryAI.assignMilitaryFleetsToSystems() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: FleetUtilsAI.generateAIFleetOrdersForAIFleetMissions() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: FleetUtilsAI.issueAIFleetOrdersForAIFleetMissions() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: ResearchAI.generateResearchOrders() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: ProductionAI.generateProductionOrders() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: ResourcesAI.generateResourcesOrders() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) try: foAIstate.afterTurnCleanup() except: print "Error: exception triggered and caught: ", traceback.format_exc() timer.append( time() ) times = [timer[i] - timer[i-1] for i in range(1, len(timer) ) ] turnEndTime=time() timeFmt = "%30s: %8d msec " print "AI Module Time Requirements:" for mod, modTime in zip(__timerEntries, times): print timeFmt%((30*' '+mod)[-30:], int(1000*modTime)) if __timerFile: __timerFile.write( __timerFileFmt%tuple( [ fo.currentTurn() ]+map(lambda x: int(1000*x), times )) +'\n') __timerFile.flush() if __timerBucketFile: __timerBucketFile.write( __timerBucketFileFmt%tuple( [ fo.currentTurn(), (turnStartTime-lastTurnTimestamp)*1000, (turnEndTime-turnStartTime)*1000 ]) +'\n') __timerBucketFile.flush() lastTurnTimestamp = time() try: fo.doneTurn() except: print "Error: exception triggered and caught: ", traceback.format_exc()
def refresh(self): """Turn start AIstate cleanup/refresh.""" universe = fo.getUniverse() # checks exploration border & clears roles/missions of missing fleets & updates fleet locs & threats fleetsLostBySystem.clear() invasionTargets[:] = [] exploration_center = PlanetUtilsAI.get_capital_sys_id() if exploration_center == INVALID_ID: # a bad state probably from an old savegame, or else empire has lost (or almost has) exploration_center = self.__origin_home_system_id # check if planets in cache is still present. Remove destroyed. for system_id, info in sorted(self.systemStatus.items()): self.systemStatus[system_id][ 'enemy_ship_count'] = 0 # clear now in prep for update_system_status() planet_dict = info.get('planets', {}) cache_planet_set = set(planet_dict) system_planet_set = set( *(sys.planetIDs for sys in [universe.getSystem(system_id)] if sys)) diff = cache_planet_set - system_planet_set if diff: print "Removing destroyed planets from systemStatus for system %s: planets to be removed: %s" % ( system_id, sorted(diff)) for key in diff: del planet_dict[key] ExplorationAI.graphFlags.clear() if fo.currentTurn() < 50: print "-------------------------------------------------" print "Border Exploration Update (relative to %s)" % ( PlanetUtilsAI.sys_name_ids([exploration_center, INVALID_ID ])[0]) print "-------------------------------------------------" if self.visBorderSystemIDs.keys() == [INVALID_ID]: self.visBorderSystemIDs.clear() self.visBorderSystemIDs[exploration_center] = 1 for sys_id in self.visBorderSystemIDs.keys( ): # This dict modified during iteration. if fo.currentTurn() < 50: print "Considering border system %s" % ( PlanetUtilsAI.sys_name_ids([sys_id, INVALID_ID])[0]) ExplorationAI.follow_vis_system_connections( sys_id, exploration_center) newly_explored = ExplorationAI.update_explored_systems() nametags = [] for sys_id in newly_explored: newsys = universe.getSystem(sys_id) nametags.append( "ID:%4d -- %-20s" % (sys_id, (newsys and newsys.name) or "name unknown") ) # an explored system *should* always be able to be gotten if newly_explored: print "-------------------------------------------------" print "Newly explored systems:\n%s" % "\n".join(nametags) print "-------------------------------------------------" # cleanup fleet roles # self.update_fleet_locs() self.__clean_fleet_roles() self.__clean_fleet_missions(FleetUtilsAI.get_empire_fleet_ids()) print "Fleets lost by system: %s" % fleetsLostBySystem self.update_system_status()
def issue_order(self): if not super(OrderInvade, self).can_issue_order(): return False universe = fo.getUniverse() planet_id = self.target.id planet = self.target.get_object() fleet = self.fleet.get_object() invasion_roles = (ShipRoleType.BASE_INVASION, ShipRoleType.MILITARY_INVASION) debug("Issuing order: %s fleet: %s target: %s" % (self.ORDER_NAME, self.fleet, self.target)) # will track if at least one invasion troops successfully deployed result = True aistate = get_aistate() overkill_margin = 2 # TODO: get from character module; allows a handful of extra troops to be immediately # defending planet # invasion orders processed before regen takes place, so use initialMeterValue() here troops_wanted = planet.initialMeterValue( fo.meterType.troops) + overkill_margin troops_already_assigned = 0 # TODO: get from other fleets in same system troops_assigned = 0 # Todo: evaluate all local troop ships (including other fleets) before using any, make sure base invasion troops # are used first, and that not too many altogether are used (choosing an optimal collection to use). for invasion_role in invasion_roles: # first checks base troops, then regular if not result: break for ship_id in fleet.shipIDs: if troops_already_assigned + troops_assigned >= troops_wanted: break ship = universe.getShip(ship_id) if aistate.get_ship_role(ship.design.id) != invasion_role: continue debug("Ordering troop ship %d to invade %s" % (ship_id, planet)) result = fo.issueInvadeOrder(ship_id, planet_id) and result if not result: shields = planet.currentMeterValue(fo.meterType.shield) planet_stealth = planet.currentMeterValue( fo.meterType.stealth) pop = planet.currentMeterValue(fo.meterType.population) warning("Invasion order failed!") debug( " -- planet has %.1f stealth, shields %.1f, %.1f population and " "is owned by empire %d" % (planet_stealth, shields, pop, planet.owner)) if "needsEmergencyExploration" not in dir(aistate): aistate.needsEmergencyExploration = [] # TODO: Check if this even makes sense - to invade a planet the ship must be in the system # which should grant the same visibility as a scout ship... ExplorationAI.request_emergency_exploration(fleet.systemID) debug( "Due to trouble invading, added system %d to Emergency Exploration List" % fleet.systemID) self.executed = False # debug(universe.getPlanet(planet_id).dump()) # TODO: fix fo.UniverseObject.dump() break troops_assigned += ship.troopCapacity # TODO: split off unused troop ships into new fleet and give new orders this cycle if result: debug("Successfully ordered %d troopers to invade %s" % (troops_assigned, planet)) return True else: return False