def calculateInvasionPriority(): "calculates the demand for troop ships by opponent planets" global allottedInvasionTargets troopsPerPod=2 empire=fo.getEmpire() if foAI.foAIstate.aggression==fo.aggression.beginner and fo.currentTurn()<150: return 0 allottedInvasionTargets = 1+ int(fo.currentTurn()/25) totalVal= sum( [pscore for pid, pscore, trp in AIstate.invasionTargets[:allottedInvasionTargets] ] ) troopsNeeded= sum( [(trp+4) for pid, pscore, trp in AIstate.invasionTargets[:allottedInvasionTargets] ] ) if totalVal == 0: return 0 opponentTroopPods = int(troopsNeeded/troopsPerPod) productionQueue = empire.productionQueue queuedTroopPods=0 for queue_index in range(0, len(productionQueue)): element=productionQueue[queue_index] if element.buildType == AIEmpireProductionTypes.BT_SHIP: if foAI.foAIstate.getShipRole(element.designID) in [ AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, AIShipRoleType.SHIP_ROLE_BASE_INVASION] : design = fo.getShipDesign(element.designID) queuedTroopPods += element.remaining*element.blocksize * list(design.parts).count("GT_TROOP_POD") bestShip, bestDesign, buildChoices = getBestShipInfo( AIPriorityType.PRIORITY_PRODUCTION_INVASION) if bestDesign: troopsPerBestShip = troopsPerPod*( list(bestDesign.parts).count("GT_TROOP_POD") ) else: troopsPerBestShip=troopsPerPod #may actually not have any troopers available, but this num will do for now #don't cound troop bases here since if through misplanning cannot be used where made, cannot be redeployed #troopFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION) + FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION) troopFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION) numTroopPods = sum([ FleetUtilsAI.countPartsFleetwide(fleetID, ["GT_TROOP_POD"]) for fleetID in troopFleetIDs]) troopShipsNeeded = math.ceil((opponentTroopPods - (numTroopPods+ queuedTroopPods ))/troopsPerBestShip) #invasionPriority = max( 10+ 200*max(0, troopShipsNeeded ) , int(0.1* totalVal) ) invasionPriority = 20+ 120*max(0, troopShipsNeeded ) if invasionPriority < 0: return 0 if foAI.foAIstate.aggression==fo.aggression.beginner: return 0.5* invasionPriority else: return invasionPriority
def calculateInvasionPriority(): "calculates the demand for troop ships by opponent planets" empire=fo.getEmpire() numOpponentPlanetIDs = len(AIstate.opponentPlanetIDs) if numOpponentPlanetIDs == 0: return 10 #hsould always have at least a low lvl of production going into fleets opponentTroopPods = sum( [math.ceil((ptroops+1)/5) for sid, pscore, ptroops in AIstate.invasionTargets] ) productionQueue = empire.productionQueue queuedTroopPods=0 for queue_index in range(0, len(productionQueue)): element=productionQueue[queue_index] if element.buildType == AIEmpireProductionTypes.BT_SHIP: if foAI.foAIstate.getShipRole(element.designID) == AIShipRoleType.SHIP_ROLE_MILITARY_INVASION: design = fo.getShipDesign(element.designID) queuedTroopPods += element.remaining*element.blocksize * list(design.parts).count("GT_TROOP_POD") bestShip, bestDesign, buildChoices = getBestShipInfo( AIPriorityType.PRIORITY_PRODUCTION_INVASION) if bestDesign: troopsPerBestShip = 2*( list(bestDesign.parts).count("GT_TROOP_POD") ) else: troopsPerBestShip=2 #may actually not have any troopers available, but this num will do for now troopFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(AIFleetMissionType.FLEET_MISSION_INVASION) numTroopPods = sum([ FleetUtilsAI.countPartsFleetwide(fleetID, ["GT_TROOP_POD"]) for fleetID in FleetUtilsAI.extractFleetIDsWithoutMissionTypes(troopFleetIDs)]) troopShipsNeeded = math.ceil((opponentTroopPods - (numTroopPods+ queuedTroopPods ))/troopsPerBestShip) #milFleetEquiv= math.ceil( MilitaryAI.totMilRating / curBestMilShipRating() ) #troopShipsNeeded = min( troopShipsNeeded , math.floor( milFleetEquiv / 2) - myTroopShips) # stale calcs to limit troops priority relative to current tot mil rating invasionPriority = 10+ 200*max(0, troopShipsNeeded ) # print "" # print "Number of Troop Ships Without Missions: " + str(numTroopShips) # print "Number of Opponent Planets: " + str(numOpponentPlanetIDs) # print "Priority for Troop Ships : " + str(invasionPriority) print "Invasion Priority Calc: Opponent TroopsPods: %d , my queued Pods: %d, my fleet troop pods: %d -- priority %d"%(opponentTroopPods, queuedTroopPods, numTroopPods, invasionPriority) if invasionPriority < 0: return 0 return invasionPriority
def assignInvasionFleetsToInvade(): # assign fleet targets to invadable planets universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) allTroopBaseFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION) availTroopBaseFleetIDs = set(FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allTroopBaseFleetIDs)) for fid in list(availTroopBaseFleetIDs): if fid not in availTroopBaseFleetIDs: continue fleet = universe.getFleet(fid) if not fleet: continue sysID = fleet.systemID system = universe.getSystem(sysID) availPlanets = set(system.planetIDs).intersection(set( foAI.foAIstate.qualifyingTroopBaseTargets.keys())) print "Considering Base Troopers in %s, found planets %s and regtistered targets %s with status %s"%(system.name, list(system.planetIDs), availPlanets, [(pid, foAI.foAIstate.qualifyingTroopBaseTargets[pid]) for pid in availPlanets]) targets = [pid for pid in availPlanets if foAI.foAIstate.qualifyingTroopBaseTargets[pid][1] != -1 ] if not targets: print "Error found no valid target for troop base in system %s (%d)"%(system.name, sysID) continue status=foAI.foAIstate.systemStatus.get( sysID, {} ) local_base_troops = set(status.get('myfleets', [])).intersection(availTroopBaseFleetIDs) troop_pod_tally = 0 for fid2 in local_base_troops: troop_pod_tally += FleetUtilsAI.countPartsFleetwide(fid2, ["GT_TROOP_POD"]) targetID=-1 bestScore=-1 target_troops = 0 # for pid, rating in assignInvasionValues(targets, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire).items(): p_score, p_troops = rating if p_score>bestScore: if p_troops >= 2*troop_pod_tally: pass #continue bestScore = p_score targetID = pid target_troops = p_troops if targetID != -1: local_base_troops.discard(fid) foundFleets = [] podsNeeded= math.ceil( (target_troops - 2*(FleetUtilsAI.countPartsFleetwide(fid, ["GT_TROOP_POD"]))+0.05)/2.0) foundStats={} minStats= {'rating':0, 'troopPods':podsNeeded} targetStats={'rating':10,'troopPods':podsNeeded} theseFleets = FleetUtilsAI.getFleetsForMission(1, targetStats , minStats, foundStats, "", systemsToCheck=[sysID], systemsChecked=[], fleetPoolSet=local_base_troops, fleetList=foundFleets, verbose=False) for fid2 in foundFleets: FleetUtilsAI.mergeFleetAintoB(fid2, fid) availTroopBaseFleetIDs.discard(fid2) availTroopBaseFleetIDs.discard(fid) foAI.foAIstate.qualifyingTroopBaseTargets[targetID][1] = -1 #TODO: should probably delete aiTarget = AITarget.AITarget(EnumsAI.AITargetType.TARGET_PLANET, targetID) aiFleetMission = foAI.foAIstate.getAIFleetMission(fid) aiFleetMission.addAITarget(EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION, aiTarget) invasionFleetIDs = AIstate.invasionFleetIDs sendInvasionFleets(invasionFleetIDs, AIstate.invasionTargets, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) allInvasionFleetIDs = FleetUtilsAI.getEmpireFleetIDsByRole(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) for fid in FleetUtilsAI.extractFleetIDsWithoutMissionTypes(allInvasionFleetIDs): thisMission = foAI.foAIstate.getAIFleetMission(fid) thisMission.checkMergers(context="Post-send consolidation of unassigned troops")
def check_retarget_invasion(self): "checks if an invasion mission should be retargeted" universe=fo.getUniverse() empire = fo.getEmpire() empire_id = fo.empireID() fleet_id = self.target_id fleet=universe.getFleet(fleet_id) if fleet.systemID == -1: #next_loc=fleet.nextSystemID return #TODO: still check system = universe.getSystem(fleet.systemID) if not system: return orders=self.getAIFleetOrders() last_sys_target = -1 if orders: last_sys_target = orders[-1].getTargetAITarget().target_id if last_sys_target == fleet.systemID: return #TODO: check for best local target open_targets = [] already_targeted = InvasionAI.getInvasionTargetedPlanetIDs(system.planetIDs, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, empire_id) for pid in system.planetIDs: if pid in already_targeted or (pid in foAI.foAIstate.qualifyingTroopBaseTargets): continue planet = universe.getPlanet(pid) if planet.unowned or (planet.owner == empire_id): continue if (planet.currentMeterValue(fo.meterType.shield)) <= 0: open_targets.append(pid) if not open_targets: return troop_pod_tally = FleetUtilsAI.countPartsFleetwide(fleet_id, ["GT_TROOP_POD"]) targetID=-1 bestScore=-1 target_troops = 0 # fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.getPlanetsInSystemsIDs(fleetSupplyableSystemIDs) for pid, rating in InvasionAI.assignInvasionValues(open_targets, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, fleetSupplyablePlanetIDs, empire).items(): p_score, p_troops = rating if p_score>bestScore: if p_troops >= 2*troop_pod_tally: continue bestScore = p_score targetID = pid target_troops = p_troops if targetID == -1: return newFleets=FleetUtilsAI.splitFleet(fleet_id) self.clearAITargets(-1)#TODO: clear from foAIstate self.clearAIFleetOrders() podsNeeded= max(0, math.ceil( (target_troops - 2*(FleetUtilsAI.countPartsFleetwide(fleet_id, ["GT_TROOP_POD"]))+0.05)/2.0) ) foundStats={} minStats= {'rating':0, 'troopPods':podsNeeded} targetStats={'rating':10,'troopPods':podsNeeded} foundFleets = [] theseFleets = FleetUtilsAI.getFleetsForMission(1, targetStats , minStats, foundStats, "", systemsToCheck=[fleet.systemID], systemsChecked=[], fleetPoolSet=set(newFleets), fleetList=foundFleets, verbose=False) for fid2 in foundFleets: FleetUtilsAI.mergeFleetAintoB(fid2, fleet_id) aiTarget = AITarget.AITarget(EnumsAI.AITargetType.TARGET_PLANET, targetID) self.addAITarget(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, aiTarget) self.generateAIFleetOrders()