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.orders last_sys_target = -1 if orders: last_sys_target = orders[-1].get_target_target().target_id if last_sys_target == fleet.systemID: return # TODO: check for best local target open_targets = [] already_targeted = InvasionAI.get_invasion_targeted_planet_ids(system.planetIDs, 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.count_parts_fleetwide(fleet_id, ["GT_TROOP_POD"]) target_id = -1 best_score = -1 target_troops = 0 # fleet_supplyable_system_ids = empire.fleetSupplyableSystemIDs fleet_supplyable_planet_ids = PlanetUtilsAI.get_planets_in__systems_ids(fleet_supplyable_system_ids) for pid, rating in InvasionAI.assign_invasion_values(open_targets, AIFleetMissionType.FLEET_MISSION_INVASION, fleet_supplyable_planet_ids, empire).items(): p_score, p_troops = rating if p_score > best_score: if p_troops >= 2 * troop_pod_tally: continue best_score = p_score target_id = pid target_troops = p_troops if target_id == -1: return new_fleets = FleetUtilsAI.split_fleet(fleet_id) self.clear_targets(-1) # TODO: clear from foAIstate self.clear_fleet_orders() pods_needed = max(0, math.ceil((target_troops - 2 * (FleetUtilsAI.count_parts_fleetwide(fleet_id, ["GT_TROOP_POD"])) + 0.05) / 2.0)) found_stats = {} min_stats = {'rating': 0, 'troopPods': pods_needed} target_stats = {'rating': 10, 'troopPods': pods_needed} found_fleets = [] # TODO check if next statement does not mutate any global states and can be removed _ = FleetUtilsAI.get_fleets_for_mission(1, target_stats, min_stats, found_stats, "", systems_to_check=[fleet.systemID], systems_checked=[], fleet_pool_set=set(new_fleets), fleet_list=found_fleets, verbose=False) for fid in found_fleets: FleetUtilsAI.merge_fleet_a_into_b(fid, fleet_id) target = AITarget(EnumsAI.AITargetType.TARGET_PLANET, target_id) self.add_target(AIFleetMissionType.FLEET_MISSION_INVASION, target) self.generate_fleet_orders()
def calculateInvasionPriority(): """calculates the demand for troop ships by opponent planets""" global allottedInvasionTargets if foAI.foAIstate.aggression <= fo.aggression.turtle: return 0 troopsPerPod=2 empire=fo.getEmpire() enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted',{}) multiplier = 1 num_colonies = len( list(AIstate.popCtrIDs) ) if num_colonies > colonyGrowthBarrier: return 0.0 if len(foAI.foAIstate.colonisablePlanetIDs) > 0: bestColonyScore = max( 2, foAI.foAIstate.colonisablePlanetIDs[0][1][0] ) else: bestColonyScore = 2 if foAI.foAIstate.aggression==fo.aggression.beginner and fo.currentTurn()<150: return 0 allottedInvasionTargets = 1+ int(fo.currentTurn()/25) totalVal = 0 troopsNeeded = 0 for pid, pscore, trp in AIstate.invasionTargets[:allottedInvasionTargets]: if pscore > bestColonyScore: multiplier += 1 totalVal += 2 * pscore else: totalVal += pscore troopsNeeded += trp+4 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 == EnumsAI.AIEmpireProductionTypes.BT_SHIP: if foAI.foAIstate.get_ship_role(element.designID) in [ EnumsAI.AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, EnumsAI.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 = ProductionAI.getBestShipInfo( EnumsAI.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.get_empire_fleet_ids_by_role(AIFleetMissionType.FLEET_MISSION_INVASION) + FleetUtilsAI.get_empire_fleet_ids_by_role(AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION) troopFleetIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) numTroopPods = sum([ FleetUtilsAI.count_parts_fleetwide(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 = multiplier * (30+ 150*max(0, troopShipsNeeded )) if not ColonisationAI.colony_status.get('colonies_under_attack', []): if not ColonisationAI.colony_status.get('colonies_under_threat', []): invasionPriority *= 2.0 else: invasionPriority *= 1.5 if not enemies_sighted: invasionPriority *= 1.5 if invasionPriority < 0: return 0 if foAI.foAIstate.aggression==fo.aggression.beginner: return 0.5* invasionPriority else: return invasionPriority
def assign_invasion_fleets_to_invade(): # assign fleet targets to invadable planets universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.get_planets_in__systems_ids(fleetSupplyableSystemIDs) allTroopBaseFleetIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION) availTroopBaseFleetIDs = set(FleetUtilsAI.extract_fleet_ids_without_mission_types(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.count_parts_fleetwide(fid2, ["GT_TROOP_POD"]) targetID=-1 bestScore=-1 target_troops = 0 # for pid, rating in assign_invasion_values(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.count_parts_fleetwide(fid, ["GT_TROOP_POD"]))+0.05)/2.0) foundStats={} minStats= {'rating':0, 'troopPods':podsNeeded} targetStats={'rating':10,'troopPods':podsNeeded} theseFleets = FleetUtilsAI.get_fleets_for_mission(1, targetStats , minStats, foundStats, "", systems_to_check=[sysID], systems_checked=[], fleet_pool_set=local_base_troops, fleet_list=foundFleets, verbose=False) for fid2 in foundFleets: FleetUtilsAI.merge_fleet_a_into_b(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.get_fleet_mission(fid) aiFleetMission.add_target(EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION, aiTarget) invasionFleetIDs = AIstate.invasionFleetIDs send_invasion_fleets(invasionFleetIDs, AIstate.invasionTargets, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) allInvasionFleetIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) for fid in FleetUtilsAI.extract_fleet_ids_without_mission_types(allInvasionFleetIDs): thisMission = foAI.foAIstate.get_fleet_mission(fid) thisMission.check_mergers(context="Post-send consolidation of unassigned troops")
def calculateInvasionPriority(): """calculates the demand for troop ships by opponent planets""" global allottedInvasionTargets if foAI.foAIstate.aggression <= fo.aggression.turtle: return 0 troopsPerPod = 2 empire = fo.getEmpire() enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {}) multiplier = 1 num_colonies = len(list(AIstate.popCtrIDs)) if num_colonies > colonyGrowthBarrier: return 0.0 if len(foAI.foAIstate.colonisablePlanetIDs) > 0: bestColonyScore = max( 2, foAI.foAIstate.colonisablePlanetIDs.items()[0][1][0]) else: bestColonyScore = 2 if foAI.foAIstate.aggression == fo.aggression.beginner and fo.currentTurn( ) < 150: return 0 allottedInvasionTargets = 1 + int(fo.currentTurn() / 25) totalVal = 0 troopsNeeded = 0 for pid, pscore, trp in AIstate.invasionTargets[:allottedInvasionTargets]: if pscore > bestColonyScore: multiplier += 1 totalVal += 2 * pscore else: totalVal += pscore troopsNeeded += trp + 4 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 == EnumsAI.AIEmpireProductionTypes.BT_SHIP: if foAI.foAIstate.get_ship_role(element.designID) in [ EnumsAI.AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, EnumsAI.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 = ProductionAI.getBestShipInfo( EnumsAI.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.get_empire_fleet_ids_by_role(AIFleetMissionType.FLEET_MISSION_INVASION) + FleetUtilsAI.get_empire_fleet_ids_by_role(AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION) troopFleetIDs = FleetUtilsAI.get_empire_fleet_ids_by_role( EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) numTroopPods = sum([ FleetUtilsAI.count_parts_fleetwide(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 = multiplier * (30 + 150 * max(0, troopShipsNeeded)) if not ColonisationAI.colony_status.get('colonies_under_attack', []): if not ColonisationAI.colony_status.get('colonies_under_threat', []): invasionPriority *= 2.0 else: invasionPriority *= 1.5 if not enemies_sighted: invasionPriority *= 1.5 if invasionPriority < 0: return 0 if foAI.foAIstate.aggression == fo.aggression.beginner: return 0.5 * invasionPriority else: return invasionPriority
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.orders last_sys_target = -1 if orders: last_sys_target = orders[-1].target.target_id if last_sys_target == fleet.systemID: return # TODO: check for best local target open_targets = [] already_targeted = InvasionAI.get_invasion_targeted_planet_ids( system.planetIDs, 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.count_parts_fleetwide( fleet_id, ["GT_TROOP_POD"]) target_id = -1 best_score = -1 target_troops = 0 # fleet_supplyable_system_ids = empire.fleetSupplyableSystemIDs fleet_supplyable_planet_ids = PlanetUtilsAI.get_planets_in__systems_ids( fleet_supplyable_system_ids) for pid, rating in InvasionAI.assign_invasion_values( open_targets, AIFleetMissionType.FLEET_MISSION_INVASION, fleet_supplyable_planet_ids, empire).items(): p_score, p_troops = rating if p_score > best_score: if p_troops >= 2 * troop_pod_tally: continue best_score = p_score target_id = pid target_troops = p_troops if target_id == -1: return print "\t AIFleetMission._check_retarget_invasion: splitting and retargetting fleet %d" % fleet_id new_fleets = FleetUtilsAI.split_fleet(fleet_id) self.clear_targets(-1) # TODO: clear from foAIstate self.clear_fleet_orders() pods_needed = max( 0, math.ceil((target_troops - 2 * (FleetUtilsAI.count_parts_fleetwide( fleet_id, ["GT_TROOP_POD"])) + 0.05) / 2.0)) found_stats = {} min_stats = {'rating': 0, 'troopPods': pods_needed} target_stats = {'rating': 10, 'troopPods': pods_needed} found_fleets = [] # TODO check if next statement does not mutate any global states and can be removed _ = FleetUtilsAI.get_fleets_for_mission( 1, target_stats, min_stats, found_stats, "", systems_to_check=[fleet.systemID], systems_checked=[], fleet_pool_set=set(new_fleets), fleet_list=found_fleets, verbose=False) for fid in found_fleets: FleetUtilsAI.merge_fleet_a_into_b(fid, fleet_id) target = AITarget(EnumsAI.TargetType.TARGET_PLANET, target_id) self.add_target(AIFleetMissionType.FLEET_MISSION_INVASION, target) self.generate_fleet_orders()
def assign_invasion_fleets_to_invade(): # assign fleet targets to invadable planets universe = fo.getUniverse() empire = fo.getEmpire() empireID = empire.empireID fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs fleetSupplyablePlanetIDs = PlanetUtilsAI.get_planets_in__systems_ids(fleetSupplyableSystemIDs) allTroopBaseFleetIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION) availTroopBaseFleetIDs = set(FleetUtilsAI.extract_fleet_ids_without_mission_types(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.count_parts_fleetwide(fid2, ["GT_TROOP_POD"]) targetID=-1 bestScore=-1 target_troops = 0 # for pid, rating in assign_invasion_values(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.count_parts_fleetwide(fid, ["GT_TROOP_POD"]))+0.05)/2.0) foundStats={} minStats= {'rating':0, 'troopPods':podsNeeded} targetStats={'rating':10,'troopPods':podsNeeded} theseFleets = FleetUtilsAI.get_fleets_for_mission(1, targetStats , minStats, foundStats, "", systems_to_check=[sysID], systems_checked=[], fleet_pool_set=local_base_troops, fleet_list=foundFleets, verbose=False) for fid2 in foundFleets: FleetUtilsAI.merge_fleet_a_into_b(fid2, fid) availTroopBaseFleetIDs.discard(fid2) availTroopBaseFleetIDs.discard(fid) foAI.foAIstate.qualifyingTroopBaseTargets[targetID][1] = -1 #TODO: should probably delete aiTarget = AITarget.AITarget(EnumsAI.TargetType.TARGET_PLANET, targetID) aiFleetMission = foAI.foAIstate.get_fleet_mission(fid) aiFleetMission.add_target(EnumsAI.AIFleetMissionType.FLEET_MISSION_ORBITAL_INVASION, aiTarget) invasionFleetIDs = AIstate.invasionFleetIDs send_invasion_fleets(invasionFleetIDs, AIstate.invasionTargets, EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) allInvasionFleetIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(EnumsAI.AIFleetMissionType.FLEET_MISSION_INVASION) for fid in FleetUtilsAI.extract_fleet_ids_without_mission_types(allInvasionFleetIDs): thisMission = foAI.foAIstate.get_fleet_mission(fid) thisMission.check_mergers(context="Post-send consolidation of unassigned troops")