Beispiel #1
0
 def checkMergers(self,  fleetID=None,  context=""):
     if fleetID==None:
                     fleetID = self.getAITargetID()
     #mainFleetMission=foAI.foAIstate.getAIFleetMission(fleetID)
     mainMissionTypeList = self.getAIMissionTypes()  #normally, currently, should only be one
     if len( mainMissionTypeList ) != 1:
         return #if this fleet has multiple mission types, will not subsume other fleets
     fleetRoleB =  foAI.foAIstate.getFleetRole(fleetID)
     mainMissionType = mainMissionTypeList[0]
     if mainMissionType not in [  EnumsAI.AIFleetMissionType.FLEET_MISSION_ATTACK,
                                                                     EnumsAI.AIFleetMissionType.FLEET_MISSION_DEFEND, 
                                                                     EnumsAI.AIFleetMissionType.FLEET_MISSION_LAST_STAND ,  
                                                                     EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY, 
                                                                     EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION, 
                                                                     EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION, 
                                                                     EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE, 
                                                                     EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_DEFENSE, 
                                                                 ]:
         return
     universe = fo.getUniverse()
     empireID = fo.empireID() 
     fleetB = universe.getFleet(fleetID)
     systemID = fleetB.systemID
     if systemID == -1:
         return # can't merge fleets in middle of starlane
     sysStatus = foAI.foAIstate.systemStatus[systemID]
     destroyedList = list( universe.destroyedObjectIDs(empireID) )
     otherFleetsHere= [fid for fid in sysStatus.get('myfleets', []) if ( (fid != fleetID) and (fid not in destroyedList) ) ]
     if otherFleetsHere==[]:
         return #nothing of record to merge with
     mainMissionTargets = self.getAITargets(mainMissionType)
     if mainMissionTargets == []:
         pass
         #return  #let's let invasion fleets with no target get merged
         mMT0=None
         mMT0ID = None
     else:
         mMT0=mainMissionTargets[0]
         mMT0ID = mMT0.getTargetID()
     if len(mainMissionTargets)>1: 
         pass
         print "\tConsidering merging fleets into  fleet  %d, but it has multiple targets: %s"%(fleetID,  str(mainMissionTargets))
     sys1=universe.getSystem(systemID)
     sysName = (sys1 and sys1.name) or "unknown"
     compatibileRolesMap={ EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_DEFENSE:         [EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_DEFENSE], 
                                                             EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY:                               [EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY], 
                                                             EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION:        [EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION], 
                                                             EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION:                              [EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION], 
                                                             }
     for fid in otherFleetsHere:
         fleetRoleA = foAI.foAIstate.getFleetRole(fid)
         if fleetRoleA not in  compatibileRolesMap[fleetRoleB] : #TODO: if fleetRoles such as LongRange start being used, adjust this
             continue # will only considering subsuming fleets that have a compatible role
         fleet2 = universe.getFleet(fid)
         if not (fleet2 and (fleet2.systemID == systemID)):
             continue
         if not (fleet2.ownedBy(foAI.foAIstate.empireID) and ( (fleet2.speed > 0) or (fleetB.speed == 0)  )):
             continue
         f2Mission=foAI.foAIstate.getAIFleetMission(fid)
         doMerge=False
         needLeft=0
         if  ( fleetRoleA== EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_DEFENSE ) or  (fleetRoleB== EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_DEFENSE ):
             if fleetRoleA==fleetRoleB:
                 doMerge=True
         elif  ( fleetRoleA== EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION ) or  (fleetRoleB== EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION ):
             if fleetRoleA==fleetRoleB:
                 doMerge=False#TODO: could  allow merger if both orb invaders and both same target
         elif not f2Mission and (fleetB.speed > 0) and (fleet2.speed > 0):
             doMerge=True
         else:
             f2MType = (f2Mission.getAIMissionTypes()+[-1])[0]
             f2Targets = f2Mission.getAITargets(f2MType)
             if len(f2Targets)>1: 
                 pass
             elif len(f2Targets)==0 and ( (fleetB.speed > 0) or (fleet2.speed == 0)  ): 
                 #print "\t\t\t ** Considering merging  fleetA (id: %4d)  into fleetB (id %d  ) and former has no targets, will take it.  FleetA mission was %s   "%(fid, fleetID,   f2Mission)
                 doMerge=True
             else:
                 targetB = f2Targets[0].getTargetID()
                 if targetB == mMT0ID:
                     print "Military fleet %d has same target as %s fleet %d and will (at least temporarily) be merged into the latter"%(fid, AIFleetMissionTypeNames.name( fleetRoleB)  ,  fleetID)
                     doMerge=True #TODO: should probably ensure that fleetA  has aggression on now
                 elif (fleetB.speed > 0):
                     neighbors = foAI.foAIstate.systemStatus.get(systemID,  {}).get('neighbors', [])
                     if (targetB==systemID) and mMT0ID in neighbors: #consider 'borrowing' for work in neighbor system
                         if f2MType  in [  EnumsAI.AIFleetMissionType.FLEET_MISSION_ATTACK,
                                                             EnumsAI.AIFleetMissionType.FLEET_MISSION_DEFEND, 
                                                             EnumsAI.AIFleetMissionType.FLEET_MISSION_MILITARY, 
                                                             EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE, 
                                                             ]:
                             #continue
                             if f2MType  in [  EnumsAI.AIFleetMissionType.FLEET_MISSION_DEFEND,  
                                                                 EnumsAI.AIFleetMissionType.FLEET_MISSION_SECURE, #actually, currently this is probably the onle one of all four that should really be possibile in this situation
                                                                 ]:
                                 needLeft = 1.5*sum( [  sysStat.get('fleetThreat', 0) for sysStat in 
                                                                                                       [foAI.foAIstate.systemStatus.get(neighbor, {}) for neighbor in  
                                                                                                       [ nid for nid in foAI.foAIstate.systemStatus.get(systemID, {}).get('neighbors', []) if nid != mMT0ID    ]   ]  ] )
                                 fBRating = foAI.foAIstate.getRating(fid)
                                 if (needLeft < fBRating.get('overall', 0)) and fBRating.get('nships', 0)>1 :
                                     doMerge=True
         if doMerge:
             FleetUtilsAI.mergeFleetAintoB(fid,  fleetID,  needLeft,  context="Order %s  of mission %s"%(context,  str(self)))
     return
Beispiel #2
0
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")
Beispiel #3
0
 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()