Esempio n. 1
0
 def is_valid(self):
     if not super(OrderColonize, self).is_valid():
         return False
     universe = fo.getUniverse()
     planet = self.target.get_object()
     sys_partial_vis_turn = universe.getVisibilityTurnsMap(planet.systemID, fo.empireID()).get(fo.visibility.partial, -9999)
     planet_partial_vis_turn = universe.getVisibilityTurnsMap(planet.id, fo.empireID()).get(fo.visibility.partial, -9999)
     if not (planet_partial_vis_turn == sys_partial_vis_turn and planet.unowned or (planet.ownedBy(fo.empireID()) and not planet.currentMeterValue(fo.meterType.population))):
         self.executed = True
         self.order_issued = True
         return False
     else:
         return self.fleet.get_object().hasColonyShips
Esempio n. 2
0
 def is_valid(self):
     if not super(OrderOutpost, self).is_valid():
         return False
     universe = fo.getUniverse()
     planet = self.target.get_object()
     sys_partial_vis_turn = universe.getVisibilityTurnsMap(planet.systemID, fo.empireID()).get(fo.visibility.partial, -9999)
     planet_partial_vis_turn = universe.getVisibilityTurnsMap(planet.id, fo.empireID()).get(fo.visibility.partial, -9999)
     if not (planet_partial_vis_turn == sys_partial_vis_turn and planet.unowned):
         self.executed = True
         self.order_issued = True
         return False
     else:
         return self.fleet.get_object().hasOutpostShips
Esempio n. 3
0
 def handle_diplomatic_message(self, message):
     """Handle a diplomatic message update from the server,
     such as if another player declares war, accepts peace, or cancels a proposed peace treaty.
     :param message: message.recipient and message.sender are respective empire IDs
     :return:
     """
     debug("Received diplomatic %s message from %s to %s." % (
         message.type, fo.getEmpire(message.sender),
         'me' if message.recipient == fo.empireID() else fo.getEmpire(message.recipient)))
     # TODO: remove the following early return once proper support for third party diplomatic history is added
     if message.recipient != fo.empireID():
         return
     aistate = get_aistate()
     if message.type == fo.diplomaticMessageType.peaceProposal:
         aistate.log_peace_request(message.sender, message.recipient)
         proposal_sender_player = fo.empirePlayerID(message.sender)
         attitude = aistate.character.attitude_to_empire(message.sender, aistate.diplomatic_logs)
         possible_acknowledgments = []
         aggression = aistate.character.get_trait(Aggression)
         if aggression.key <= fo.aggression.typical:
             possible_acknowledgments = UserStringList("AI_PEACE_PROPOSAL_ACKNOWLEDGEMENTS_MILD_LIST")
             if attitude > 0:
                 possible_replies = UserStringList("AI_PEACE_PROPOSAL_RESPONSES_YES_MILD_LIST")
             else:
                 possible_replies = UserStringList("AI_PEACE_PROPOSAL_RESPONSES_NO_MILD_LIST")
         else:
             possible_acknowledgments = UserStringList("AI_PEACE_PROPOSAL_ACKNOWLEDGEMENTS_HARSH_LIST")
             if attitude > 0:
                 possible_replies = UserStringList("AI_PEACE_PROPOSAL_RESPONSES_YES_HARSH_LIST")
             else:
                 possible_replies = UserStringList("AI_PEACE_PROPOSAL_RESPONSES_NO_HARSH_LIST")
         acknowledgement = random.choice(possible_acknowledgments)
         reply_text = random.choice(possible_replies)
         debug("Acknowledging proposal with initial message (from %d choices): '%s'" % (
             len(possible_acknowledgments), acknowledgement))
         fo.sendChatMessage(proposal_sender_player, acknowledgement)
         if attitude > 0:
             diplo_reply = fo.diplomaticMessage(message.recipient, message.sender,
                                                fo.diplomaticMessageType.acceptPeaceProposal)
             debug("Sending diplomatic message to empire %s of type %s" % (message.sender, diplo_reply.type))
             fo.sendDiplomaticMessage(diplo_reply)
         debug("sending chat to player %d of empire %d, message body: '%s'" % (
             proposal_sender_player, message.sender, reply_text))
         fo.sendChatMessage(proposal_sender_player, reply_text)
     elif message.type == fo.diplomaticMessageType.warDeclaration:
         # note: apparently this is currently (normally?) sent not as a warDeclaration,
         # but as a simple diplomatic_status_update to war
         aistate.log_war_declaration(message.sender, message.recipient)
Esempio n. 4
0
def declare_war_on_all():  # pylint: disable=invalid-name
    """Used to declare war on all other empires (at start of game)"""
    my_emp_id = fo.empireID()
    for emp_id in fo.allEmpireIDs():
        if emp_id != my_emp_id:
            msg = fo.diplomaticMessage(my_emp_id, emp_id, fo.diplomaticMessageType.warDeclaration)
            fo.sendDiplomaticMessage(msg)
Esempio n. 5
0
def getAIFleetOrdersFromSystemAITargets(fleetAITarget, aiTargets):
    result = []
    # TODO: use Graph Theory to construct move orders
    # TODO: add priority
    empireID = fo.empireID()
    # determine system where fleet will be or where is if is going nowhere
    lastSystemAITarget = fleetAITarget.getRequiredSystemAITargets()[0]
    # for every system which fleet wanted to visit, determine systems to visit and create move orders
    for aiTarget in aiTargets:
        # determine systems required to visit(with possible return to supplied system)
        systemAITargets = canTravelToSystemAndReturnToResupply(
            fleetAITarget.getTargetID(), lastSystemAITarget, aiTarget, empireID
        )
        if len(systemAITargets) > 0:
            # for every system required to visit create move order
            for systemAITarget in systemAITargets:
                # remember last system which will be visited
                lastSystemAITarget = systemAITarget
                # create move order
                aiFleetOrder = AIFleetOrder.AIFleetOrder(AIFleetOrderType.ORDER_MOVE, fleetAITarget, systemAITarget)
                result.append(aiFleetOrder)
        else:
            print "fleetID: " + str(fleetAITarget.getTargetID()) + " can't travel to target:" + str(aiTarget)

    return result
Esempio n. 6
0
 def issue_order(self):
     if not super(OrderMilitary, self).issue_order():
         return False
     target_sys_id = self.target.id
     fleet = self.target.get_object()
     system_status = get_aistate().systemStatus.get(target_sys_id, {})
     total_threat = sum(system_status.get(threat, 0) for threat in ("fleetThreat", "planetThreat", "monsterThreat"))
     combat_trigger = system_status.get("fleetThreat", 0) or system_status.get("monsterThreat", 0)
     if not combat_trigger and system_status.get("planetThreat", 0):
         universe = fo.getUniverse()
         system = universe.getSystem(target_sys_id)
         for planet_id in system.planetIDs:
             planet = universe.getPlanet(planet_id)
             if planet.ownedBy(fo.empireID()):  # TODO: also exclude at-peace planets
                 continue
             if planet.unowned and not EspionageAI.colony_detectable_by_empire(planet_id, empire=fo.empireID()):
                 continue
             if sum(
                 [
                     planet.currentMeterValue(meter_type)
                     for meter_type in [fo.meterType.defense, fo.meterType.shield, fo.meterType.construction]
                 ]
             ):
                 combat_trigger = True
                 break
     if not all(
         (
             fleet,
             fleet.systemID == target_sys_id,
             system_status.get("currently_visible", False),
             not (total_threat and combat_trigger),
         )
     ):
         self.executed = False
     return True
Esempio n. 7
0
 def handle_diplomatic_status_update(self, status_update):
     """Handle an update about the diplomatic status between players, which may
     or may not include this player."""
     print "Received diplomatic status update to %s about empire %s and empire %s" % (
         status_update.status, status_update.empire1, status_update.empire2)
     if status_update.empire2 == fo.empireID() and status_update.status == fo.diplomaticStatus.war:
         foAI.foAIstate.log_war_declaration(status_update.empire1, status_update.empire2)
Esempio n. 8
0
 def attitude_to_empire(self, other_empire_id, diplomatic_logs):
     # TODO: In other traits consider proximity, competitive
     # needs, relations with other empires, past history with this
     # empire, etc.
     # in the meantime, somewhat random
     # TODO: Move the diplomatic log portion of this trait back
     # into diplomacy where it belongs.
     if self.aggression == fo.aggression.maniacal:
         return -9
     if self.aggression == fo.aggression.beginner:
         return 9
     log_index = (other_empire_id, fo.empireID())
     num_alliance_requests = len(
         diplomatic_logs.get('alliance_requests', {}).get(log_index, []))
     num_peace_requests = len(
         diplomatic_logs.get('peace_requests', {}).get(log_index, []))
     num_war_declarations = len(
         diplomatic_logs.get('war_declarations', {}).get(log_index, []))
     # Too many requests for peace irritate the AI, as do any war declarations
     irritation = (
         self.aggression *
         (2.0 + num_alliance_requests / 5.0 + num_peace_requests / 10.0 +
          2.0 * num_war_declarations) + 0.5)
     attitude = 10 * random.random() - irritation
     return min(10, max(-10, attitude))
Esempio n. 9
0
def split_fleet(fleet_id: int) -> List[int]:
    """Split a fleet into its ships.

    :param fleet_id: fleet to be split.
    :return: New fleets. Empty if couldn't split.
    """
    universe = fo.getUniverse()
    empire_id = fo.empireID()
    fleet = universe.getFleet(fleet_id)
    new_fleets = []

    if fleet is None:
        return []
    if not fleet.ownedBy(empire_id):
        return []

    if len(list(
            fleet.shipIDs)) <= 1:  # fleet with only one ship cannot be split
        return []
    ship_ids = list(fleet.shipIDs)
    aistate = get_aistate()
    for ship_id in ship_ids[1:]:
        new_fleet_id = split_ship_from_fleet(fleet_id, ship_id)
        new_fleets.append(new_fleet_id)

    aistate.get_fleet_role(fleet_id, force_new=True)
    aistate.update_fleet_rating(fleet_id)
    if new_fleets:
        aistate.ensure_have_fleet_missions(new_fleets)

    return new_fleets
Esempio n. 10
0
def declare_war_on_all():  # pylint: disable=invalid-name
    """Used to declare war on all other empires (at start of game)"""
    my_emp_id = fo.empireID()
    for emp_id in fo.allEmpireIDs():
        if emp_id != my_emp_id:
            msg = fo.diplomaticMessage(my_emp_id, emp_id, fo.diplomaticMessageType.warDeclaration)
            fo.sendDiplomaticMessage(msg)
Esempio n. 11
0
def get_current_and_max_structure(fleet: int) -> Tuple[float, float]:
    """Return a 2-tuple of the sums of structure and maxStructure meters of all ships in the fleet."""

    universe = fo.getUniverse()
    destroyed_ids = universe.destroyedObjectIDs(fo.empireID())
    fleet = universe.getFleet(fleet)
    if not fleet:
        return (0.0, 0.0)
    ships_cur_health = 0
    ships_max_health = 0
    for ship_id in fleet.shipIDs:
        # Check if we have see this ship get destroyed in a different fleet since the last time we saw the subject fleet
        # this may be redundant with the new fleet assignment check made below, but for its limited scope it may be more
        # reliable, in that it does not rely on any particular handling of post-destruction stats
        if ship_id in destroyed_ids:
            continue
        this_ship = universe.getShip(ship_id)
        # check that the ship has not been seen in a new fleet since this current fleet was last observed
        if not (this_ship and this_ship.fleetID == fleet.id):
            continue
        ships_cur_health += this_ship.initialMeterValue(fo.meterType.structure)
        ships_max_health += this_ship.initialMeterValue(
            fo.meterType.maxStructure)

    return ships_cur_health, ships_max_health
Esempio n. 12
0
    def __init__(self):
        self.have_gas_giant = False
        self.have_asteroids = False
        self.have_ruins = False
        self.have_nest = False
        self.have_computronium = False
        self.num_researchers = 0  # population with research focus
        self.num_industrialists = 0  # population with industry focus

        empire_id = fo.empireID()
        universe = fo.getUniverse()

        for planet_info in _get_planets_info().values():
            planet = universe.getPlanet(planet_info.pid)
            if planet.ownedBy(empire_id):

                if AIDependencies.ANCIENT_RUINS_SPECIAL in planet.specials:
                    self.have_ruins = True

                population = planet.currentMeterValue(fo.meterType.population)
                if population > 0 and AIDependencies.COMPUTRONIUM_SPECIAL in planet.specials:
                    self.have_computronium = True  # TODO: Check if species can set research focus

                if planet.focus == FocusType.FOCUS_INDUSTRY:
                    self.num_industrialists += population
                elif planet.focus == FocusType.FOCUS_RESEARCH:
                    self.num_researchers += population
Esempio n. 13
0
 def issue_order(self):
     if not super(OrderMilitary, self).issue_order():
         return False
     target_sys_id = self.target.id
     fleet = self.target.get_object()
     system_status = foAI.foAIstate.systemStatus.get(target_sys_id, {})
     total_threat = sum(system_status.get(threat, 0) for threat in ('fleetThreat', 'planetThreat', 'monsterThreat'))
     combat_trigger = system_status.get('fleetThreat', 0) or system_status.get('monsterThreat', 0)
     if not combat_trigger and system_status.get('planetThreat', 0):
         universe = fo.getUniverse()
         system = universe.getSystem(target_sys_id)
         for planet_id in system.planetIDs:
             planet = universe.getPlanet(planet_id)
             if planet.ownedBy(fo.empireID()):  # TODO: also exclude at-peace planets
                 continue
             if planet.unowned and not EspionageAI.colony_detectable_by_empire(planet_id, empire=fo.empireID()):
                 continue
             if sum([planet.currentMeterValue(meter_type) for meter_type in
                     [fo.meterType.defense, fo.meterType.shield, fo.meterType.construction]]):
                 combat_trigger = True
                 break
     if not all((
                 fleet,
                 fleet.systemID == target_sys_id,
                 system_status.get('currently_visible', False),
                 not (total_threat and combat_trigger)
     )):
         self.executed = False
     return True
Esempio n. 14
0
def getAIFleetOrdersFromSystemAITargets(fleetAITarget, aiTargets):
    result = []
    # TODO: use Graph Theory to construct move orders
    # TODO: add priority
    empireID = fo.empireID()
    # determine system where fleet will be or where is if is going nowhere
    lastSystemAITarget = fleetAITarget.getRequiredSystemAITargets()[0]
    # for every system which fleet wanted to visit, determine systems to visit and create move orders 
    for aiTarget in aiTargets:
        # determine systems required to visit(with possible return to supplied system)
        #print "checking system targets"
        systemAITargets = canTravelToSystem(fleetAITarget.getTargetID(), lastSystemAITarget, aiTarget, empireID)
        #print "making path with %d targets: "%len(systemAITargets) ,   PlanetUtilsAI.sysNameIDs( [sysTarg. getTargetID() for sysTarg in systemAITargets])
        if len(systemAITargets) > 0:
            # for every system required to visit create move order
            for systemAITarget in systemAITargets:
                # remember last system which will be visited
                lastSystemAITarget = systemAITarget
                # create move order
                aiFleetOrder = AIFleetOrder.AIFleetOrder(AIFleetOrderType.ORDER_MOVE, fleetAITarget, systemAITarget)
                result.append(aiFleetOrder)
        else:
            startSysID = lastSystemAITarget.getTargetID()
            targetSysID = aiTarget.getTargetID()
            if startSysID != targetSysID:
                print "fleetID: " + str(fleetAITarget.getTargetID()) + " can't travel to target:" + str(aiTarget)

    return result
Esempio n. 15
0
    def __update_empire_standard_enemy(self):
        """Update the empire's standard enemy.

        The standard enemy is the enemy that is most often seen.
        """
        # TODO: If no current information available, rate against own fighters
        universe = fo.getUniverse()
        empire_id = fo.empireID()

        # assess enemy fleets that may have been momentarily visible (start with dummy entries)
        dummy_stats = CombatRatingsAI.default_ship_stats().get_stats(hashable=True)
        cur_e_fighters = Counter()  # actual visible enemies
        old_e_fighters = Counter({dummy_stats: 0})  # destroyed enemies TODO: consider seen but out of sight enemies

        for fleet_id in universe.fleetIDs:
            fleet = universe.getFleet(fleet_id)
            if (not fleet or fleet.empty or fleet.ownedBy(empire_id) or fleet.unowned or
                    not (fleet.hasArmedShips or fleet.hasFighterShips)):
                continue

            # track old/dead enemy fighters for rating assessments in case not enough current info
            ship_stats = CombatRatingsAI.FleetCombatStats(fleet_id).get_ship_stats(hashable=True)
            dead_fleet = fleet_id in universe.destroyedObjectIDs(empire_id)
            e_f_dict = old_e_fighters if dead_fleet else cur_e_fighters
            for stats in ship_stats:
                # log only ships that are armed
                if stats[0]:
                    e_f_dict[stats] += 1

        e_f_dict = cur_e_fighters or old_e_fighters
        self.__empire_standard_enemy = sorted([(v, k) for k, v in e_f_dict.items()])[-1][1]
        self.empire_standard_enemy_rating = self.get_standard_enemy().get_rating()
Esempio n. 16
0
def getAIFleetOrdersFromSystemAITargets(fleetAITarget, aiTargets):
    result = []
    # TODO: use Graph Theory to construct move orders
    # TODO: add priority
    empireID = fo.empireID()
    # determine system where fleet will be or where is if is going nowhere
    lastSystemAITarget = fleetAITarget.get_required_system_ai_targets()[0]
    secure_targets = set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs + AIstate.invasionTargetedSystemIDs + AIstate.blockadeTargetedSystemIDs)
    # for every system which fleet wanted to visit, determine systems to visit and create move orders
    for aiTarget in aiTargets:
        # determine systems required to visit(with possible return to supplied system)
        #print "checking system targets"
        ensure_return = aiTarget.target_id not in  secure_targets
        systemAITargets = canTravelToSystem(fleetAITarget.target_id, lastSystemAITarget, aiTarget, empireID, ensure_return=ensure_return)
        #print "making path with %d targets: "%len(systemAITargets) ,   PlanetUtilsAI.sysNameIDs( [sysTarg.target_id for sysTarg in systemAITargets])
        if len(systemAITargets) > 0:
            # for every system required to visit create move order
            for systemAITarget in systemAITargets:
                # remember last system which will be visited
                lastSystemAITarget = systemAITarget
                # create move order
                aiFleetOrder = AIFleetOrder.AIFleetOrder(AIFleetOrderType.ORDER_MOVE, fleetAITarget, systemAITarget)
                result.append(aiFleetOrder)
        else:
            startSysID = lastSystemAITarget.target_id
            targetSysID = aiTarget.target_id
            if startSysID != targetSysID:
                print "fleetID: " + str(fleetAITarget.target_id) + " can't travel to target:" + str(aiTarget)

    return result
Esempio n. 17
0
def assign_invasion_values(planet_ids):
    """Creates a dictionary that takes planet_ids as key and their invasion score as value."""
    empire_id = fo.empireID()
    planet_values = {}
    neighbor_values = {}
    neighbor_val_ratio = .95
    universe = fo.getUniverse()
    secure_missions = foAI.foAIstate.get_fleet_missions_with_any_mission_types([MissionType.SECURE])
    for pid in planet_ids:
        planet_values[pid] = neighbor_values.setdefault(pid, evaluate_invasion_planet(pid, secure_missions))
        print "planet %d, values %s" % (pid, planet_values[pid])
        planet = universe.getPlanet(pid)
        species_name = (planet and planet.speciesName) or ""
        species = fo.getSpecies(species_name)
        if species and species.canProduceShips:
            system = universe.getSystem(planet.systemID)
            if not system:
                continue
            planet_industries = {}
            for pid2 in system.planetIDs:
                planet2 = universe.getPlanet(pid2)
                species_name2 = (planet2 and planet2.speciesName) or ""
                species2 = fo.getSpecies(species_name2)
                if species2 and species2.canProduceShips:
                    planet_industries[pid2] = planet2.currentMeterValue(fo.meterType.industry) + 0.1  # to prevent divide-by-zero
            industry_ratio = planet_industries[pid] / max(planet_industries.values())
            for pid2 in system.planetIDs:
                if pid2 == pid:
                    continue
                planet2 = universe.getPlanet(pid2)
                if planet2 and (planet2.owner != empire_id) and ((planet2.owner != -1) or (planet.currentMeterValue(fo.meterType.population) > 0)):  # TODO check for allies
                    planet_values[pid][0] += industry_ratio * neighbor_val_ratio * (neighbor_values.setdefault(pid2, evaluate_invasion_planet(pid2, secure_missions))[0])
    return planet_values
Esempio n. 18
0
def merge_fleet_a_into_b(fleet_a_id, fleet_b_id, leave_rating=0, need_rating=0, context=""):
    universe = fo.getUniverse()
    fleet_a = universe.getFleet(fleet_a_id)
    fleet_b = universe.getFleet(fleet_b_id)
    if not fleet_a or not fleet_b:
        return 0
    system_id = fleet_a.systemID
    if fleet_b.systemID != system_id:
        return 0
    remaining_rating = CombatRatingsAI.get_fleet_rating(fleet_a_id)
    transferred_rating = 0
    for ship_id in fleet_a.shipIDs:
        this_ship = universe.getShip(ship_id)
        if not this_ship:
            continue
        this_rating = CombatRatingsAI.ShipCombatStats(ship_id).get_rating()
        remaining_rating = CombatRatingsAI.rating_needed(remaining_rating, this_rating)
        if remaining_rating < leave_rating:  # merging this would leave old fleet under minimum rating, try other ships.
            continue
        transferred = fo.issueFleetTransferOrder(ship_id, fleet_b_id)
        if transferred:
            transferred_rating = CombatRatingsAI.combine_ratings(transferred_rating, this_rating)
        else:
            print "  *** transfer of ship %4d, formerly of fleet %4d, into fleet %4d failed; %s" % (
                ship_id, fleet_a_id, fleet_b_id, (" context is %s" % context) if context else "")
        if need_rating != 0 and need_rating <= transferred_rating:
            break
    fleet_a = universe.getFleet(fleet_a_id)
    if not fleet_a or fleet_a.empty or fleet_a_id in universe.destroyedObjectIDs(fo.empireID()):
        foAI.foAIstate.delete_fleet_info(fleet_a_id)
    foAI.foAIstate.update_fleet_rating(fleet_b_id)
Esempio n. 19
0
 def handle_diplomatic_status_update(self, status_update):
     """Handle an update about the diplomatic status between players, which may
     or may not include this player."""
     print "Received diplomatic status update to %s about empire %s and empire %s" % (
         status_update.status, status_update.empire1, status_update.empire2)
     if status_update.empire2 == fo.empireID() and status_update.status == fo.diplomaticStatus.war:
         foAI.foAIstate.log_war_declaration(status_update.empire1, status_update.empire2)
Esempio n. 20
0
def get_current_and_max_structure(fleet):
    """Return a 2-tuple of the sums of structure and maxStructure meters of all ships in the fleet

    :param fleet:
    :type fleet: int | universe_object.Fleet | fo.Fleet
    :return: tuple of sums of structure and maxStructure meters of all ships in the fleet
    :rtype: (float, float)
    """

    universe = fo.getUniverse()
    destroyed_ids = universe.destroyedObjectIDs(fo.empireID())
    if isinstance(fleet, int):
        fleet = universe.getFleet(fleet)
    elif isinstance(fleet, Fleet):
        fleet = fleet.get_object()
    if not fleet:
        return (0.0, 0.0)
    ships_cur_health = 0
    ships_max_health = 0
    for ship_id in fleet.shipIDs:
        # Check if we have see this ship get destroyed in a different fleet since the last time we saw the subject fleet
        # this may be redundant with the new fleet assignment check made below, but for its limited scope it may be more
        # reliable, in that it does not rely on any particular handling of post-destruction stats
        if ship_id in destroyed_ids:
            continue
        this_ship = universe.getShip(ship_id)
        # check that the ship has not been seen in a new fleet since this current fleet was last observed
        if not (this_ship and this_ship.fleetID == fleet.id):
            continue
        ships_cur_health += this_ship.initialMeterValue(fo.meterType.structure)
        ships_max_health += this_ship.initialMeterValue(fo.meterType.maxStructure)

    return ships_cur_health, ships_max_health
Esempio n. 21
0
    def __cleanExplorableSystems(self, startSystemID):
        "cleanup of all explorable systems"

        universe = fo.getUniverse()
        systemIDs = universe.systemIDs
        empireID = fo.empireID()
        empire = fo.getEmpire()

        for systemID in systemIDs:
            system = universe.getSystem(systemID)
            if not system: continue

            #print "system with id: " + str(systemID)

            if (empire.hasExploredSystem(systemID)):
                self.addExplorableSystem(AIExplorableSystemType.EXPLORABLE_SYSTEM_EXPLORED, systemID)
                self.removeExplorableSystem(AIExplorableSystemType.EXPLORABLE_SYSTEM_UNEXPLORED, systemID)
                #print "    has been explored"
                continue
            if (startSystemID == -1 or not universe.systemsConnected(systemID, startSystemID, empireID)):
                for explorableSystemsType in EnumsAI.getAIExplorableSystemTypes():
                    self.removeExplorableSystem(explorableSystemsType, systemID)
                #print "    is not connected to system with id: " + str(startSystemID)
                continue
            explorableSystemsType = self.getExplorableSystem(systemID)
            if (explorableSystemsType == AIExplorableSystemType.EXPLORABLE_SYSTEM_VISIBLE):
                #print "    is already explored system target"
                continue
            #print "    is now an unexplored system"
            self.addExplorableSystem(AIExplorableSystemType.EXPLORABLE_SYSTEM_UNEXPLORED, systemID)
Esempio n. 22
0
def splitFleet(fleetID):
    "splits a fleet into its ships"

    universe = fo.getUniverse()
    empireID = fo.empireID()

    fleet = universe.getFleet(fleetID)
    newfleets = []

    if fleet == None: return []
    if not fleet.ownedBy(empireID): return []

    if len(list(fleet.shipIDs)) <= 1:  # fleet with only one ship cannot be split
       return [fleetID]
    shipIDs = list( fleet.shipIDs )
    for shipID in shipIDs[1:]:
        newFleetID = fo.issueNewFleetOrder("Fleet %d"%(shipID), shipID)
        if newFleetID:
            newFleet=universe.getFleet(newFleetID)
            if not newFleet:
                print "Error: newly split fleet %d not available from universe"%newFleetID
            fo.issueRenameOrder(newFleetID,  "Fleet %5d"%newFleetID) #to ease review of debugging logs
            fo.issueAggressionOrder(newFleetID,  True)
            role = foAI.foAIstate.getFleetRole(newFleetID) #and mission?
            foAI.foAIstate.getRating(newFleetID) #
            newfleets.append(newFleetID)
            foAI.foAIstate.newlySplitFleets[newFleetID]=True
        else:
            print "Error - got no fleet ID back after trying to split a ship from fleet %d"%fleetID
    foAI.foAIstate.getFleetRole(fleetID, forceNew=True) #
    foAI.foAIstate.updateFleetRating(fleetID) #
    foAI.foAIstate.ensureHaveFleetMissions(newfleets)
    return newfleets
Esempio n. 23
0
def calculateColonisationPriority():
    """calculates the demand for colony ships by colonisable planets"""
    global allottedColonyTargets, colony_growth_barrier
    enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {})
    galaxy_is_sparse = ColonisationAI.galaxy_is_sparse()
    total_pp = fo.getEmpire().productionPoints
    num_colonies = len(list(AIstate.popCtrIDs))
    # significant growth barrier for low aggression, negligible for high aggression
    colony_growth_barrier = 2 + (
        (0.5 + foAI.foAIstate.aggression)**2) * fo.currentTurn() / 50.0
    colonyCost = AIDependencies.COLONY_POD_COST * (
        1 + AIDependencies.COLONY_POD_UPKEEP * num_colonies)
    turnsToBuild = 8  # TODO: check for susp anim pods, build time 10
    mil_prio = foAI.foAIstate.get_priority(
        EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY)
    allottedPortion = ([[[0.6, 0.8], [0.3, 0.4]], [[0.8, 0.9], [
        0.3, 0.4
    ]]][galaxy_is_sparse][any(enemies_sighted)][fo.empireID() % 2])
    #if ( foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_COLONISATION)
    # > 2 * foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY)):
    # allottedPortion *= 1.5
    if mil_prio < 100:
        allottedPortion *= 2
    elif mil_prio < 200:
        allottedPortion *= 1.5
    elif fo.currentTurn() > 100:
        allottedPortion *= 0.75**(num_colonies / 10.0)
    #allottedColonyTargets = 1+ int(fo.currentTurn()/50)
    allottedColonyTargets = 1 + int(
        total_pp * turnsToBuild * allottedPortion / colonyCost)
    outpost_prio = foAI.foAIstate.get_priority(
        EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_OUTPOST)
    # if have any outposts to build, don't build colony ships TODO: make more complex assessment
    if outpost_prio > 0 or num_colonies > colony_growth_barrier:
        return 0.0

    if num_colonies > colony_growth_barrier:
        return 0.0
    numColonisablePlanetIDs = len([
        pid
        for (pid, (score, _)) in foAI.foAIstate.colonisablePlanetIDs.items()
        if score > 60
    ][:allottedColonyTargets + 2])
    if numColonisablePlanetIDs == 0: return 1

    colonyshipIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(
        EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION)
    numColonyships = len(
        FleetUtilsAI.extract_fleet_ids_without_mission_types(colonyshipIDs))
    colonisationPriority = 60 * (1 + numColonisablePlanetIDs - numColonyships
                                 ) / (numColonisablePlanetIDs + 1)

    # print
    # print "Number of Colony Ships : " + str(numColonyships)
    # print "Number of Colonisable planets : " + str(numColonisablePlanetIDs)
    # print "Priority for colony ships : " + str(colonisationPriority)

    if colonisationPriority < 1: return 0
    return colonisationPriority
Esempio n. 24
0
    def generateAIFleetOrders(self):
        "generates AIFleetOrders from fleets targets to accomplish"

        universe = fo.getUniverse()
        fleetID = self.target_id
        fleet = universe.getFleet(fleetID)
        if (not fleet) or fleet.empty or (fleetID in universe.destroyedObjectIDs(fo.empireID())): #fleet was probably merged into another or was destroyed
            foAI.foAIstate.deleteFleetInfo(fleetID)
            return

        # TODO: priority
        self.clearAIFleetOrders()
        systemID = fleet.systemID
        start_sys_id = [ fleet.nextSystemID,  systemID ][ systemID >= 0 ]
        # if fleet doesn't have any mission, then repair if needed or resupply if is current location not in supplyable system
        empire = fo.getEmpire()
        fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
        #if (not self.hasAnyAIMissionTypes()):
        ntargets=0
        for aiFleetMissionType in self.getAIMissionTypes():
            ntargets += len( self.getAITargets(aiFleetMissionType) )
        if (ntargets ==0) and (systemID not in  set(AIstate.colonyTargetedSystemIDs + AIstate.outpostTargetedSystemIDs + 
                                                    AIstate.invasionTargetedSystemIDs + AIstate.blockadeTargetedSystemIDs)  ):
            if self.need_repair():
                repairAIFleetOrder = MoveUtilsAI.getRepairAIFleetOrder(self.getAITarget(), start_sys_id)
                if repairAIFleetOrder.isValid():
                    self.appendAIFleetOrder(repairAIFleetOrder)
            if not(self.getLocationAITarget().target_id in fleetSupplyableSystemIDs):
                resupplyAIFleetOrder = MoveUtilsAI.getResupplyAIFleetOrder(self.getAITarget(), self.getLocationAITarget())
                if resupplyAIFleetOrder.isValid():
                    self.appendAIFleetOrder(resupplyAIFleetOrder)
            return #no targets

        # for some targets fleet has to visit systems and therefore fleet visit them
        systemAITargets = self.__getRequiredToVisitSystemAITargets()
        aiFleetOrdersToVisitSystems = MoveUtilsAI.getAIFleetOrdersFromSystemAITargets(self.getAITarget(), systemAITargets)
        #TODO: if fleet doesn't have enough fuel to get to final target, consider resetting Mission
        #print "----------------------------------------"
        #print "*+*+ fleet %d :  has fleet action system targets:  %s"%(fleetID,  [str(obj) for obj in systemAITargets])
        #print "----------"
        #print "*+*+ fleet %d:  has movement  orders:  %s"%(fleetID,  [str(obj) for obj in aiFleetOrdersToVisitSystems])

        for aiFleetOrder in aiFleetOrdersToVisitSystems:
            self.appendAIFleetOrder(aiFleetOrder)

        # if fleet is in some system = fleet.systemID >=0, then also generate system AIFleetOrders
        if systemID >= 0:
            # system in where fleet is
            systemAITarget = AITarget.AITarget(EnumsAI.AITargetType.TARGET_SYSTEM, systemID)
            # if mission aiTarget has required system where fleet is, then generate aiFleetOrder from this aiTarget
            aiMissionTypes = self.getAIMissionTypes()
            # for all targets in all mission types get required systems to visit
            for aiFleetMissionType in aiMissionTypes:
                aiTargets = self.getAITargets(aiFleetMissionType)
                for aiTarget in aiTargets:
                    if systemAITarget in aiTarget.get_required_system_ai_targets():
                        # from target required to visit get fleet orders to accomplish target
                        aiFleetOrder = self.__getAIFleetOrderFromAITarget(aiFleetMissionType, aiTarget)
                        self.appendAIFleetOrder(aiFleetOrder)
Esempio n. 25
0
def follow_vis_system_connections(start_system_id, home_system_id):
    universe = fo.getUniverse()
    empire_id = fo.empireID()
    exploration_list = [start_system_id]
    while exploration_list:
        cur_system_id = exploration_list.pop()
        if cur_system_id in graph_flags:
            continue
        graph_flags.add(cur_system_id)
        system = universe.getSystem(cur_system_id)
        if cur_system_id in foAI.foAIstate.visBorderSystemIDs:
            pre_vis = "a border system"
        elif cur_system_id in foAI.foAIstate.visInteriorSystemIDs:
            pre_vis = "an interior system"
        else:
            pre_vis = "an unknown system"
        system_header = "*** system %s;" % system
        if fo.currentTurn() < 50:
            visibility_turn_list = sorted(universe.getVisibilityTurnsMap(
                cur_system_id, empire_id).items(),
                                          key=lambda x: x[0].numerator)
            visibility_info = ', '.join('%s: %s' % (vis.name, turn)
                                        for vis, turn in visibility_turn_list)
            print "%s previously %s. Visibility per turn: %s " % (
                system_header, pre_vis, visibility_info)
            status_info = []
        else:
            status_info = [system_header]

        has_been_visible = universe.getVisibilityTurnsMap(
            cur_system_id, empire_id).get(fo.visibility.partial, 0) > 0
        is_connected = universe.systemsConnected(cur_system_id, home_system_id,
                                                 -1)  # self.empire_id)
        status_info.append("    -- is%s partially visible" %
                           ("" if has_been_visible else " not"))
        status_info.append("    -- is%s visibly connected to homesystem" %
                           ("" if is_connected else " not"))
        if has_been_visible:
            sys_status = foAI.foAIstate.systemStatus.setdefault(
                cur_system_id, {})
            foAI.foAIstate.visInteriorSystemIDs.add(cur_system_id)
            foAI.foAIstate.visBorderSystemIDs.discard(cur_system_id)
            neighbors = set(
                dict_from_map(
                    universe.getSystemNeighborsMap(cur_system_id,
                                                   empire_id)).keys())
            sys_status.setdefault('neighbors', set()).update(neighbors)
            if neighbors:
                status_info.append(" -- has neighbors %s" % sorted(neighbors))
                for sys_id in neighbors:
                    if sys_id not in foAI.foAIstate.exploredSystemIDs:
                        foAI.foAIstate.unexploredSystemIDs.add(sys_id)
                    if (sys_id not in graph_flags) and (
                            sys_id not in foAI.foAIstate.visInteriorSystemIDs):
                        foAI.foAIstate.visBorderSystemIDs.add(sys_id)
                        exploration_list.append(sys_id)
        if fo.currentTurn() < 50:
            print '\n'.join(status_info)
            print "----------------------------------------------------------"
Esempio n. 26
0
def get_research_index():
    empire_id = fo.empireID()
    research_index = empire_id % 2
    if foAI.foAIstate.aggression >= fo.aggression.aggressive:  # maniacal
        research_index = 2 + (empire_id % 3)  # so indices [2,3,4]
    elif foAI.foAIstate.aggression >= fo.aggression.typical:
        research_index += 1
    return research_index
Esempio n. 27
0
def get_partial_visibility_turn(obj_id: int) -> int:
    """Return the last turn an object had at least partial visibility.

    :return: Last turn an object had at least partial visibility, -9999 if never
    """
    visibility_turns_map = fo.getUniverse().getVisibilityTurnsMap(
        obj_id, fo.empireID())
    return visibility_turns_map.get(fo.visibility.partial, -9999)
Esempio n. 28
0
    def get_inhabited_planets(self):
        """
        Return frozenset of empire planet ids with species.

        :rtype: frozenset[int]
        """
        empire_id = fo.empireID()
        return frozenset(x.pid for x in self.__planet_info.itervalues() if x.owner == empire_id and x.species_name)
Esempio n. 29
0
    def get_inhabited_planets(self):
        """
        Return frozenset of empire planet ids with species.

        :rtype: frozenset[int]
        """
        empire_id = fo.empireID()
        return frozenset(x.pid for x in self.__planet_info.values() if x.owner == empire_id and x.species_name)
Esempio n. 30
0
def get_research_index():
    empire_id = fo.empireID()
    research_index = empire_id % 2
    if foAI.foAIstate.aggression >= fo.aggression.aggressive:  # maniacal
        research_index = 2 + (empire_id % 3)  # so indices [2,3,4]
    elif foAI.foAIstate.aggression >= fo.aggression.typical:
        research_index += 1
    return research_index
Esempio n. 31
0
    def _check_abort_mission(self, fleet_order):
        """ checks if current mission (targeting a planet) should be aborted"""
        planet_stealthed = False
        target_is_planet = fleet_order.target and isinstance(
            fleet_order.target, TargetPlanet)
        planet = None
        if target_is_planet:
            planet = fleet_order.target.get_object()
            # Check visibility prediction, but if somehow still have current visibility, don't
            # abort the mission yet
            if not EspionageAI.colony_detectable_by_empire(
                    planet.id, empire=fo.empireID()):
                if get_partial_visibility_turn(planet.id) == fo.currentTurn():
                    debug(
                        "EspionageAI predicts planet id %d to be stealthed" %
                        planet.id +
                        ", but somehow have current visibity anyway, so won't trigger mission abort"
                    )
                else:
                    debug(
                        "EspionageAI predicts we can no longer detect %s, will abort mission"
                        % fleet_order.target)
                    planet_stealthed = True
        if target_is_planet and not planet_stealthed:
            if isinstance(fleet_order, OrderColonize):
                if (planet.initialMeterValue(fo.meterType.population) == 0
                        and (planet.ownedBy(fo.empireID()) or planet.unowned)):
                    return False
            elif isinstance(fleet_order, OrderOutpost):
                if planet.unowned:
                    return False
            elif isinstance(fleet_order,
                            OrderInvade):  # TODO add substantive abort check
                return False
            else:
                return False

        # canceling fleet orders
        debug("   %s" % fleet_order)
        debug(
            "Fleet %d had a target planet that is no longer valid for this mission; aborting."
            % self.fleet.id)
        self.clear_fleet_orders()
        self.clear_target()
        FleetUtilsAI.split_fleet(self.fleet.id)
        return True
Esempio n. 32
0
def colony_detectable_by_empire(
    planet_id: int,
    species_name: Optional[str] = None,
    empire: Union[int, List[int]] = ALL_EMPIRES,
    future_stealth_bonus: int = 0,
    default_result: bool = True,
) -> bool:
    """
    Predicts if a planet/colony is/will-be detectable by an empire.

    The passed empire value can be a single empire ID or a list of empire IDs.  If passed ALL_empires, will use the list
    of all empires.  When using a list of empires (or when passed ALL_EMPIRES), the present empire is excluded.  To
    check for the present empire the current empire ID must be passed as a simple int.  Ignores current ownership of the
    planet unless the passed empire value is a simple int matching fo.empireID(), because in most cases we are concerned
    about (i) visibility to us of a planet we do not own, or (ii) visibility by enemies of a planet we own or expect to
    own at the time we are making the visibility projection for (even if they may own it right now).  The only case
    where current ownership matters is when we are considering whether to abort a colonization mission, which might be
    for a planet we already own.

    :param planet_id: required, the planet of concern
    :param species_name: will override the existing planet species if provided
    :param empire: empire ID (or list of empire IDs) whose detection ability is of concern
    :param future_stealth_bonus: can specify a projected future stealth bonus, such as from a stealth tech
    :param default_result: generally for offensive assessments should be False, for defensive should be True
    :return: whether the planet is predicted to be detectable

    """
    # The future_stealth_bonus can be used if the AI knows it has researched techs that would grant a stealth bonus to
    # the planet once it was colonized/captured

    planet = fo.getUniverse().getPlanet(planet_id)
    if not planet:
        error("Couldn't retrieve planet ID %d." % planet_id)
        return default_result
    if species_name is None:
        species_name = planet.speciesName

    # in case we are checking about aborting a colonization mission
    if empire == fo.empireID() and planet.ownedBy(empire):
        return True

    # could just check stealth meter, but this approach might allow us to plan ahead a bit even if the planet
    # is temporarily stealth boosted by temporary effects like ion storm
    planet_stealth = AIDependencies.BASE_PLANET_STEALTH
    if planet.specials:
        planet_stealth += max([AIDependencies.STEALTH_SPECIAL_STRENGTHS.get(_spec, 0) for _spec in planet.specials])
    # TODO: check planet buildings for stealth bonuses

    # if the planet already has an existing stealth special, then the most common situation is that it would be
    # overlapping with or superseded by the future_stealth_bonus, not additive with it.
    planet_stealth = max(planet_stealth, AIDependencies.BASE_PLANET_STEALTH + future_stealth_bonus)
    species_stealth_mod = get_species_tag_value(species_name, Tags.STEALTH)
    total_stealth = planet_stealth + species_stealth_mod
    if isinstance(empire, int):
        empire_detection = get_empire_detection(empire)
    else:
        empire_detection = get_max_empire_detection(empire)
    return total_stealth < empire_detection
Esempio n. 33
0
    def check_mergers(self, context=""):
        """
        Merge local fleets with same mission into this fleet.

        :param context: Context of the function call for logging purposes
        :type context: str
        """
        debug("Considering to merge %s", self.__str__())
        if self.type not in MERGEABLE_MISSION_TYPES:
            debug("Mission type does not allow merging.")
            return

        if not self.target:
            debug("Mission has no valid target - do not merge.")
            return

        universe = fo.getUniverse()
        empire_id = fo.empireID()

        fleet_id = self.fleet.id
        main_fleet = universe.getFleet(fleet_id)
        main_fleet_system_id = main_fleet.systemID
        if main_fleet_system_id == INVALID_ID:
            debug("Can't merge: fleet in middle of starlane.")
            return

        # only merge PROTECT_REGION if there is any threat near target
        if self.type == MissionType.PROTECT_REGION:
            neighbor_systems = universe.getImmediateNeighbors(
                self.target.id, empire_id)
            if not any(
                    MilitaryAI.get_system_local_threat(sys_id)
                    for sys_id in neighbor_systems):
                debug("Not merging PROTECT_REGION fleet - no threat nearby.")
                return

        destroyed_list = set(universe.destroyedObjectIDs(empire_id))
        aistate = get_aistate()
        system_status = aistate.systemStatus[main_fleet_system_id]
        other_fleets_here = [
            fid for fid in system_status.get('myFleetsAccessible', [])
            if fid != fleet_id and fid not in destroyed_list
            and universe.getFleet(fid).ownedBy(empire_id)
        ]
        if not other_fleets_here:
            debug("No other fleets here")
            return

        for fid in other_fleets_here:
            fleet_mission = aistate.get_fleet_mission(fid)
            if fleet_mission.type != self.type or fleet_mission.target != self.target:
                debug("Local candidate %s does not have same mission." %
                      fleet_mission)
                continue
            FleetUtilsAI.merge_fleet_a_into_b(
                fid,
                fleet_id,
                context="Order %s of mission %s" % (context, self))
Esempio n. 34
0
 def is_valid(self):
     if not super(OrderColonize, self).is_valid():
         return False
     universe = fo.getUniverse()
     planet = self.target.get_object()
     sys_partial_vis_turn = universe.getVisibilityTurnsMap(
         planet.systemID, fo.empireID()).get(fo.visibility.partial, -9999)
     planet_partial_vis_turn = universe.getVisibilityTurnsMap(
         planet.id, fo.empireID()).get(fo.visibility.partial, -9999)
     if not (planet_partial_vis_turn == sys_partial_vis_turn
             and planet.unowned or
             (planet.ownedBy(fo.empireID())
              and not planet.currentMeterValue(fo.meterType.population))):
         self.executed = True
         self.order_issued = True
         return False
     else:
         return self.fleet.get_object().hasColonyShips
Esempio n. 35
0
def handleDiplomaticMessage(message):
    print "Received diplomatic " + str(message.type) + " message from empire " + str(message.sender) + " to empire " + str(message.recipient)
    print "my empire id: " + str(fo.empireID())
    if (message.type == fo.diplomaticMessageType.peaceProposal and message.recipient == fo.empireID()):
        replySender = message.recipient
        replyRecipient = message.sender
        reply = fo.diplomaticMessage(replySender, replyRecipient, fo.diplomaticMessageType.acceptProposal)
        print "Sending diplomatic message to empire " + str(replyRecipient) + " of type " + str(reply.type)
        fo.sendDiplomaticMessage(reply)
Esempio n. 36
0
    def generate_fleet_orders(self):
        """generates AIFleetOrders from fleets targets to accomplish"""
        universe = fo.getUniverse()
        fleet_id = self.fleet.id
        fleet = universe.getFleet(fleet_id)
        if (not fleet) or fleet.empty or (
                fleet_id in universe.destroyedObjectIDs(fo.empireID())
        ):  # fleet was probably merged into another or was destroyed
            foAI.foAIstate.delete_fleet_info(fleet_id)
            return

        # TODO: priority
        self.clear_fleet_orders()
        system_id = fleet.systemID
        start_sys_id = [fleet.nextSystemID, system_id][system_id >= 0]
        # if fleet doesn't have any mission, then repair if needed or resupply if is current location not in supplyable system
        empire = fo.getEmpire()
        fleet_supplyable_system_ids = empire.fleetSupplyableSystemIDs
        # if (not self.hasAnyAIMissionTypes()):
        if not self.target and (system_id
                                not in set(AIstate.colonyTargetedSystemIDs +
                                           AIstate.outpostTargetedSystemIDs +
                                           AIstate.invasionTargetedSystemIDs +
                                           AIstate.blockadeTargetedSystemIDs)):
            if self._need_repair():
                repair_fleet_order = MoveUtilsAI.get_repair_fleet_order(
                    self.fleet, start_sys_id)
                if repair_fleet_order.is_valid():
                    self.orders.append(repair_fleet_order)
            if fleet.fuel < fleet.maxFuel and self.get_location_target(
            ).id not in fleet_supplyable_system_ids:
                resupply_fleet_order = MoveUtilsAI.get_resupply_fleet_order(
                    self.fleet, self.get_location_target())
                if resupply_fleet_order.is_valid():
                    self.orders.append(resupply_fleet_order)
            return  # no targets

        # for some targets fleet has to visit systems and therefore fleet visit them
        if self.target:
            system_targets_required_to_visit = [self.target.get_system()]
            orders_to_visit_systems = MoveUtilsAI.get_fleet_orders_from_system_targets(
                self.fleet, system_targets_required_to_visit)
            # TODO: if fleet doesn't have enough fuel to get to final target, consider resetting Mission
            for fleet_order in orders_to_visit_systems:
                self.orders.append(fleet_order)

        # if fleet is in some system = fleet.system_id >=0, then also generate system AIFleetOrders
        if system_id >= 0 and self.target:
            # system in where fleet is
            system_target = System(system_id)
            # if mission aiTarget has required system where fleet is, then generate fleet_order from this aiTarget
            # for all targets in all mission types get required systems to visit
            if system_target == self.target.get_system():
                # from target required to visit get fleet orders to accomplish target
                fleet_order = self._get_fleet_order_from_target(
                    self.type, self.target)
                self.orders.append(fleet_order)
Esempio n. 37
0
 def __cleanup_qualifiying_base_targets(self):
     """Cleanup invalid entries in qualifying base targets."""
     universe = fo.getUniverse()
     empire_id = fo.empireID()
     for dct in [self.qualifyingTroopBaseTargets]:
         for pid in dct.keys():
             planet = universe.getPlanet(pid)
             if planet and planet.ownedBy(empire_id):
                 del dct[pid]
Esempio n. 38
0
def get_partial_visibility_turn(obj_id):
    """Return the last turn an object had at least partial visibility.

    :type obj_id: int
    :return: Last turn an object had at least partial visibility, -9999 if never
    :rtype: int
    """
    visibility_turns_map = fo.getUniverse().getVisibilityTurnsMap(obj_id, fo.empireID())
    return visibility_turns_map.get(fo.visibility.partial, -9999)
Esempio n. 39
0
 def __cleanup_qualifiying_base_targets(self):
     """Cleanup invalid entries in qualifying base targets."""
     universe = fo.getUniverse()
     empire_id = fo.empireID()
     for dct in [self.qualifyingTroopBaseTargets]:
         for pid in dct.keys():
             planet = universe.getPlanet(pid)
             if planet and planet.ownedBy(empire_id):
                 del dct[pid]
Esempio n. 40
0
    def generate_fleet_orders(self):
        """generates AIFleetOrders from fleets targets to accomplish"""
        universe = fo.getUniverse()
        fleet_id = self.fleet.id
        fleet = universe.getFleet(fleet_id)
        if (not fleet) or fleet.empty or (fleet_id
                                          in universe.destroyedObjectIDs(
                                              fo.empireID())):
            # fleet was probably merged into another or was destroyed
            foAI.foAIstate.delete_fleet_info(fleet_id)
            return

        # TODO: priority
        self.clear_fleet_orders()
        system_id = fleet.systemID
        start_sys_id = [fleet.nextSystemID, system_id][system_id >= 0]
        # if fleet doesn't have any mission,
        # then repair if needed or resupply if is current location not in supplyable system
        empire = fo.getEmpire()
        fleet_supplyable_system_ids = empire.fleetSupplyableSystemIDs
        # if (not self.hasAnyAIMissionTypes()):
        if not self.target and (system_id
                                not in set(AIstate.colonyTargetedSystemIDs +
                                           AIstate.outpostTargetedSystemIDs +
                                           AIstate.invasionTargetedSystemIDs +
                                           AIstate.blockadeTargetedSystemIDs)):
            if self._need_repair():
                repair_fleet_order = MoveUtilsAI.get_repair_fleet_order(
                    self.fleet, start_sys_id)
                if repair_fleet_order and repair_fleet_order.is_valid():
                    self.orders.append(repair_fleet_order)
            cur_fighter_capacity, max_fighter_capacity = FleetUtilsAI.get_fighter_capacity_of_fleet(
                fleet_id)
            if (fleet.fuel < fleet.maxFuel
                    or cur_fighter_capacity < max_fighter_capacity
                    and self.get_location_target().id
                    not in fleet_supplyable_system_ids):
                resupply_fleet_order = MoveUtilsAI.get_resupply_fleet_order(
                    self.fleet, self.get_location_target())
                if resupply_fleet_order.is_valid():
                    self.orders.append(resupply_fleet_order)
            return  # no targets

        if self.target:
            # for some targets fleet has to visit systems and therefore fleet visit them
            system_to_visit = self.target.get_system()
            orders_to_visit_systems = MoveUtilsAI.create_move_orders_to_system(
                self.fleet, system_to_visit)
            # TODO: if fleet doesn't have enough fuel to get to final target, consider resetting Mission
            for fleet_order in orders_to_visit_systems:
                self.orders.append(fleet_order)

            # also generate appropriate final orders
            fleet_order = self._get_fleet_order_from_target(
                self.type, self.target)
            self.orders.append(fleet_order)
Esempio n. 41
0
def merge_fleet_a_into_b(fleetA_ID, fleetB_ID, leaveRating=0, needRating=0, context=""):
    universe = fo.getUniverse()
    fleetA = universe.getFleet(fleetA_ID)
    sysID=fleetA.systemID
    fleetB = universe.getFleet(fleetB_ID)
    if not fleetA or not fleetB:
        return 0
    success = True
    initRating = foAI.foAIstate.get_rating(fleetA_ID)
    remainingRating = initRating.copy()
    transferredRating = 0
    transferredAttack=0
    transferredHealth=0
    BHasMonster=False
    for shipID in fleetB.shipIDs:
        thisShip=universe.getShip(shipID)
        if not thisShip:
            continue
        if thisShip.isMonster:
            BHasMonster = True
            break
    for shipID in fleetA.shipIDs:
        thisShip=universe.getShip(shipID)
        if (not thisShip) or ( thisShip.isMonster != BHasMonster ) :
            continue
        stats = foAI.foAIstate.get_design_id_stats(thisShip.designID)
        thisRating = stats['attack'] * ( stats['structure'] + stats['shields'] )
        if (remainingRating['attack'] -stats['attack'])*(remainingRating['health'] -( stats['structure'] + stats['shields'] )) < leaveRating:
            continue
        #remainingRating -= thisRating
        remainingRating['attack'] -= stats['attack']
        remainingRating['health'] -= ( stats['structure'] + stats['shields'] )
        thisSuccess = ( fo.issueFleetTransferOrder(shipID, fleetB_ID) )#returns a zero if transfer failure
        if thisSuccess:
            transferredRating += thisRating
            transferredAttack += stats['attack']
            transferredHealth += ( stats['structure'] + stats['shields'] )
        else:
            print "\t\t\t\t *** attempted transfer of ship %4d, formerly of fleet %4d, into fleet %4d with result %d; %s"%(shipID, fleetA_ID, fleetB_ID, thisSuccess, [" context is %s"%context, ""][context==""])
        success = success and thisSuccess
        if needRating !=0 and needRating <= transferredAttack*transferredHealth:  #transferredRating:
            break
    fleetA = universe.getFleet(fleetA_ID)
    if (not fleetA) or fleetA.empty or fleetA_ID in universe.destroyedObjectIDs(fo.empireID()):
        #print "\t\t\t\t\tdeleting fleet info for old fleet %d after transfers into fleet %d"%(fleetA_ID, fleetB_ID)
        foAI.foAIstate.delete_fleet_info(fleetA_ID)
    else:
        newARating = foAI.foAIstate.update_fleet_rating(fleetA_ID)
        if success : #and ( newARating==remainingRating) :
            #print "\t\t\t\t\t\t\%d rating from fleet %d successfully transferred to fleet %d, leaving %d"%(transferredAttack*transferredHealth, fleetA_ID, fleetB_ID, newARating['overall'])
            pass
        else:
            #print "\t\t\t\t\t\t transfer of %d rating from fleet %d to fleet %d was attempted but appears to have had problems, leaving %d"%(transferredAttack*transferredHealth, fleetA_ID, fleetB_ID, newARating['overall'])
            pass
    foAI.foAIstate.update_fleet_rating(fleetB_ID)
    return transferredAttack*transferredHealth, transferredAttack, transferredHealth
Esempio n. 42
0
def update_explored_systems():
    universe = fo.getUniverse()
    empire = fo.getEmpire()
    obs_lanes = empire.obstructedStarlanes()
    obs_lanes_list = [el for el in obs_lanes
                      ]  # should result in list of tuples (sys_id1, sys_id2)
    if obs_lanes_list:
        print "Obstructed starlanes are: %s" % ', '.join(
            '%s-%s' % item for item in obs_lanes_list)
    else:
        print "No obstructed Starlanes"
    empire_id = fo.empireID()
    newly_explored = []
    still_unexplored = []
    for sys_id in list(foAI.foAIstate.unexploredSystemIDs):
        if empire.hasExploredSystem(
                sys_id
        ):  # consider making determination according to visibility rather than actual visit, which I think is what empire.hasExploredSystem covers
            del foAI.foAIstate.unexploredSystemIDs[sys_id]
            foAI.foAIstate.exploredSystemIDs[sys_id] = 1
            system = universe.getSystem(sys_id)
            print "Moved system %s from unexplored list to explored list" % system
            if sys_id in borderUnexploredSystemIDs:
                del borderUnexploredSystemIDs[sys_id]
            newly_explored.append(sys_id)
        else:
            still_unexplored.append(sys_id)

    neighbor_list = []
    dummy = []
    for id_list, next_list in [(newly_explored, neighbor_list),
                               (neighbor_list, dummy)]:
        for sys_id in id_list:
            neighbors = list(universe.getImmediateNeighbors(sys_id, empire_id))
            all_explored = True
            for neighbor_id in neighbors:
                if neighbor_id in foAI.foAIstate.unexploredSystemIDs:  # when it matters, unexplored will be smaller than explored
                    all_explored = False
                else:
                    next_list.append(neighbor_id)
            if all_explored:
                interiorExploredSystemIDs[sys_id] = 1
                if sys_id in borderExploredSystemIDs:
                    del borderExploredSystemIDs[sys_id]
            else:
                borderExploredSystemIDs[sys_id] = 1

    for sys_id in still_unexplored:
        neighbors = list(universe.getImmediateNeighbors(sys_id, empire_id))
        any_explored = False
        for neighbor_id in neighbors:
            if neighbor_id in foAI.foAIstate.exploredSystemIDs:  # consider changing to unexplored test -- when it matters, unexplored will be smaller than explored, but need to not get previously untreated neighbors
                any_explored = True
        if any_explored:
            borderUnexploredSystemIDs[sys_id] = 1
    return newly_explored
Esempio n. 43
0
 def is_valid(self):
     if not super(OrderColonize, self).is_valid():
         return False
     planet = self.target.get_object()
     if (planet.unowned or planet.ownedBy(fo.empireID())) and not planet.currentMeterValue(fo.meterType.population):
         return self.fleet.get_object().hasColonyShips
     # Otherwise, terminate early
     self.executed = True
     self.order_issued = True
     return False
Esempio n. 44
0
def getRepairAIFleetOrder(fleetAITarget, current_sys_id):
    "returns repair AIFleetOrder to [nearest safe] drydock"
    # find nearest supplied system
    empireID = fo.empireID()
    drydock_sys_id = getNearestDrydockSystemID(current_sys_id)
    drydockSystemAITarget = AITarget.AITarget(AITargetType.TARGET_SYSTEM, drydock_sys_id)
    print "ordering fleet %d to %s for repair"%(fleetAITarget.target_id,  PlanetUtilsAI.sysNameIDs([drydock_sys_id]))
    # create resupply AIFleetOrder
    aiFleetOrder = AIFleetOrder.AIFleetOrder(AIFleetOrderType.ORDER_REPAIR, fleetAITarget, drydockSystemAITarget)
    return aiFleetOrder
Esempio n. 45
0
def calculateOutpostPriority():
    """calculates the demand for outpost ships by colonisable planets"""
    global allotted_outpost_targets
    base_outpost_cost = AIDependencies.OUTPOST_POD_COST

    enemies_sighted = foAI.foAIstate.misc.get('enemies_sighted', {})
    galaxy_is_sparse = ColonisationAI.galaxy_is_sparse()
    total_pp = fo.getEmpire().productionPoints
    num_colonies = len(list(AIstate.popCtrIDs))
    # significant growth barrier for low aggression, negligible for high aggression
    if num_colonies > colony_growth_barrier:
        return 0.0
    mil_prio = foAI.foAIstate.get_priority(
        EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY)

    NOT_SPARCE, ENEMY_UNSEEN = 0, 0
    IS_SPARCE, ENEMY_SEEN = 1, 1
    allotted_portion = {
        (NOT_SPARCE, ENEMY_UNSEEN): (0.6, 0.8),
        (NOT_SPARCE, ENEMY_SEEN): (0.3, 0.4),
        (IS_SPARCE, ENEMY_UNSEEN): (0.8, 0.9),
        (IS_SPARCE, ENEMY_SEEN): (0.3, 0.4),
    }[(galaxy_is_sparse, any(enemies_sighted))][fo.empireID() % 2]
    if mil_prio < 100:
        allotted_portion *= 2
    elif mil_prio < 200:
        allotted_portion *= 1.5
    allotted_outpost_targets = 1 + int(
        total_pp * 3 * allotted_portion / base_outpost_cost)

    num_outpost_targets = len([
        pid
        for (pid, (score,
                   specName)) in foAI.foAIstate.colonisableOutpostIDs.items()
        if score > 1.0 * base_outpost_cost / 3.0
    ][:allotted_outpost_targets])
    if num_outpost_targets == 0 or not tech_is_complete(
            AIDependencies.OUTPOSTING_TECH):
        return 0

    outpostShipIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(
        EnumsAI.AIFleetMissionType.FLEET_MISSION_OUTPOST)
    num_outpost_ships = len(
        FleetUtilsAI.extract_fleet_ids_without_mission_types(outpostShipIDs))
    outpost_priority = 50 * (num_outpost_targets -
                             num_outpost_ships) / num_outpost_targets

    # print
    # print "Number of Outpost Ships : " + str(num_outpost_ships)
    # print "Number of Colonisable outposts: " + str(num_outpost_planet_ids)
    print "Priority for outpost ships : " + str(outpost_priority)

    if outpost_priority < 1: return 0

    return outpost_priority
Esempio n. 46
0
def merge_fleet_a_into_b(fleet_a_id,
                         fleet_b_id,
                         leave_rating=0,
                         need_rating=0,
                         context=""):
    universe = fo.getUniverse()
    fleet_a = universe.getFleet(fleet_a_id)
    fleet_b = universe.getFleet(fleet_b_id)
    if not fleet_a or not fleet_b:
        return 0
    success = True
    init_rating = foAI.foAIstate.get_rating(fleet_a_id)
    remaining_rating = init_rating.copy()
    transferred_rating = 0
    transferred_attack = 0
    transferred_health = 0
    b_has_monster = False
    for ship_id in fleet_b.shipIDs:
        this_ship = universe.getShip(ship_id)
        if not this_ship:
            continue
        if this_ship.isMonster:
            b_has_monster = True
            break
    for ship_id in fleet_a.shipIDs:
        this_ship = universe.getShip(ship_id)
        if not this_ship or this_ship.isMonster != b_has_monster:
            continue
        stats = foAI.foAIstate.get_design_id_stats(this_ship.designID)
        this_rating = stats['attack'] * (stats['structure'] + stats['shields'])
        if (remaining_rating['attack'] - stats['attack']) * (
                remaining_rating['health'] -
            (stats['structure'] + stats['shields'])) < leave_rating:
            continue
        # remaining_rating -= this_rating
        remaining_rating['attack'] -= stats['attack']
        remaining_rating['health'] -= stats['structure'] + stats['shields']
        transferred = fo.issueFleetTransferOrder(ship_id, fleet_b_id)
        if transferred:
            transferred_rating += this_rating
            transferred_attack += stats['attack']
            transferred_health += stats['structure'] + stats['shields']
        else:
            print "  *** transfer of ship %4d, formerly of fleet %4d, into fleet %4d failed; %s" % (
                ship_id, fleet_a_id, fleet_b_id,
                [" context is %s" % context, ""][context == ""])
        success = success and transferred
        if need_rating != 0 and need_rating <= transferred_attack * transferred_health:  # transferred_rating:
            break
    fleet_a = universe.getFleet(fleet_a_id)
    if not fleet_a or fleet_a.empty or fleet_a_id in universe.destroyedObjectIDs(
            fo.empireID()):
        foAI.foAIstate.delete_fleet_info(fleet_a_id)
    foAI.foAIstate.update_fleet_rating(fleet_b_id)
    return transferred_attack * transferred_health, transferred_attack, transferred_health
Esempio n. 47
0
def getResupplyAIFleetOrder(fleetAITarget, currentSystemAITarget):
    "returns resupply AIFleetOrder to nearest supplied system"

    # find nearest supplied system
    empireID = fo.empireID()
    suppliedSystemAITarget = getNearestSuppliedSystem(currentSystemAITarget.getTargetID(), empireID)

    # create resupply AIFleetOrder
    aiFleetOrder = AIFleetOrder.AIFleetOrder(AIFleetOrderType.ORDER_RESUPPLY, fleetAITarget, suppliedSystemAITarget)

    return aiFleetOrder
Esempio n. 48
0
def get_safe_path_leg_to_dest(fleet_id,  start_id,  dest_id):
    start_targ = AITarget.AITarget(AITargetType.TARGET_SYSTEM, start_id)
    dest_targ = AITarget.AITarget(AITargetType.TARGET_SYSTEM, dest_id)
    #TODO actually get a safe path
    this_path = canTravelToSystem(fleet_id, start_targ, dest_targ, fo.empireID(),  ensure_return=False)
    path_ids = [ targ.target_id for targ in this_path if targ.target_id != start_id] + [start_id]
    start_info = PlanetUtilsAI.sysNameIDs([start_id])
    dest_info = PlanetUtilsAI.sysNameIDs([dest_id])
    path_info = [ PlanetUtilsAI.sysNameIDs([sys_id]) for sys_id in path_ids]
    print "Fleet %d requested safe path leg from %s to %s,  found path %s"%(fleet_id,  start_info, dest_info ,  path_info)
    return path_ids[0]
Esempio n. 49
0
 def __update_buildings(self):
     universe = fo.getUniverse()
     empire_id = fo.empireID()
     drydocks = {}
     for building_id in universe.buildingIDs:
         building = universe.getBuilding(building_id)
         if not building:
             continue
         if building.buildingTypeName == AIDependencies.BLD_SHIPYARD_ORBITAL_DRYDOCK and building.ownedBy(empire_id):
             drydocks.setdefault(building.systemID, []).append(building.planetID)
     self.__drydock_locations = ReadOnlyDict({k: tuple(v) for k, v in drydocks.iteritems()})
Esempio n. 50
0
    def get_empire_planets_by_species(self):
        """
        Return dict for empire from species to list of planet ids.

        :rtype: dict[str, list[int]]
        """
        empire_id = fo.empireID()
        result = {}
        for x in (x for x in self.__planet_info.values() if x.owner == empire_id and x.species_name):
            result.setdefault(x.species_name, []).append(x.pid)
        return result
Esempio n. 51
0
 def __update_buildings(self):
     universe = fo.getUniverse()
     empire_id = fo.empireID()
     drydocks = {}
     for building_id in universe.buildingIDs:
         building = universe.getBuilding(building_id)
         if not building:
             continue
         if building.buildingTypeName == AIDependencies.BLD_SHIPYARD_ORBITAL_DRYDOCK and building.ownedBy(empire_id):
             drydocks.setdefault(building.systemID, []).append(building.planetID)
     self.__drydock_locations = ReadOnlyDict({k: tuple(v) for k, v in drydocks.items()})
Esempio n. 52
0
def follow_vis_system_connections(start_system_id, home_system_id):
    universe = fo.getUniverse()
    empire_id = fo.empireID()
    exploration_list = [start_system_id]
    aistate = get_aistate()
    while exploration_list:
        cur_system_id = exploration_list.pop()
        if cur_system_id in graph_flags:
            continue
        graph_flags.add(cur_system_id)
        system = universe.getSystem(cur_system_id)
        if cur_system_id in aistate.visBorderSystemIDs:
            pre_vis = "a border system"
        elif cur_system_id in aistate.visInteriorSystemIDs:
            pre_vis = "an interior system"
        else:
            pre_vis = "an unknown system"
        system_header = "*** system %s;" % system
        if fo.currentTurn() < 50:
            visibility_turn_list = sorted(universe.getVisibilityTurnsMap(
                cur_system_id, empire_id).items(),
                                          key=lambda x: x[0].numerator)
            visibility_info = ", ".join("%s: %s" % (vis.name, turn)
                                        for vis, turn in visibility_turn_list)
            debug("%s previously %s. Visibility per turn: %s " %
                  (system_header, pre_vis, visibility_info))
            status_info = []
        else:
            status_info = [system_header]

        has_been_visible = get_partial_visibility_turn(cur_system_id) > 0
        is_connected = systems_connected(cur_system_id, home_system_id)
        status_info.append("    -- is%s partially visible" %
                           ("" if has_been_visible else " not"))
        status_info.append("    -- is%s visibly connected to homesystem" %
                           ("" if is_connected else " not"))
        if has_been_visible:
            sys_status = aistate.systemStatus.setdefault(cur_system_id, {})
            aistate.visInteriorSystemIDs.add(cur_system_id)
            aistate.visBorderSystemIDs.discard(cur_system_id)
            neighbors = get_neighbors(cur_system_id)
            sys_status.setdefault("neighbors", set()).update(neighbors)
            if neighbors:
                status_info.append(" -- has neighbors %s" % sorted(neighbors))
                for sys_id in neighbors:
                    if sys_id not in aistate.exploredSystemIDs:
                        aistate.unexploredSystemIDs.add(sys_id)
                    if (sys_id not in graph_flags) and (
                            sys_id not in aistate.visInteriorSystemIDs):
                        aistate.visBorderSystemIDs.add(sys_id)
                        exploration_list.append(sys_id)
        if fo.currentTurn() < 50:
            debug("\n".join(status_info))
            debug("----------------------------------------------------------")
Esempio n. 53
0
    def get_empire_planets_by_species(self):
        """
        Return dict for empire from species to list of planet ids.

        :rtype: dict[str, list[int]]
        """
        empire_id = fo.empireID()
        result = {}
        for x in (x for x in self.__planet_info.itervalues() if x.owner == empire_id and x.species_name):
            result.setdefault(x.species_name, []).append(x.pid)
        return result
Esempio n. 54
0
def calculateColonisationPriority():
    """calculates the demand for colony ships by colonisable planets"""
    global allottedColonyTargets, colony_growth_barrier
    enemies_sighted = foAI.foAIstate.misc.get("enemies_sighted", {})
    galaxy_is_sparse = ColonisationAI.galaxy_is_sparse()
    total_pp = fo.getEmpire().productionPoints
    num_colonies = len(list(AIstate.popCtrIDs))
    # significant growth barrier for low aggression, negligible for high aggression
    colony_growth_barrier = 2 + ((0.5 + foAI.foAIstate.aggression) ** 2) * fo.currentTurn() / 50.0
    colonyCost = AIDependencies.COLONY_POD_COST * (1 + AIDependencies.COLONY_POD_UPKEEP * num_colonies)
    turnsToBuild = 8  # TODO: check for susp anim pods, build time 10
    mil_prio = foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY)
    allottedPortion = [[[0.6, 0.8], [0.3, 0.4]], [[0.8, 0.9], [0.3, 0.4]]][galaxy_is_sparse][any(enemies_sighted)][
        fo.empireID() % 2
    ]
    # if ( foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_COLONISATION)
    # > 2 * foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_MILITARY)):
    # allottedPortion *= 1.5
    if mil_prio < 100:
        allottedPortion *= 2
    elif mil_prio < 200:
        allottedPortion *= 1.5
    elif fo.currentTurn() > 100:
        allottedPortion *= 0.75 ** (num_colonies / 10.0)
    # allottedColonyTargets = 1+ int(fo.currentTurn()/50)
    allottedColonyTargets = 1 + int(total_pp * turnsToBuild * allottedPortion / colonyCost)
    outpost_prio = foAI.foAIstate.get_priority(EnumsAI.AIPriorityType.PRIORITY_PRODUCTION_OUTPOST)
    # if have any outposts to build, don't build colony ships TODO: make more complex assessment
    if outpost_prio > 0 or num_colonies > colony_growth_barrier:
        return 0.0

    if num_colonies > colony_growth_barrier:
        return 0.0
    numColonisablePlanetIDs = len(
        [pid for (pid, (score, _)) in foAI.foAIstate.colonisablePlanetIDs.items() if score > 60][
            : allottedColonyTargets + 2
        ]
    )
    if numColonisablePlanetIDs == 0:
        return 1

    colonyshipIDs = FleetUtilsAI.get_empire_fleet_ids_by_role(EnumsAI.AIFleetMissionType.FLEET_MISSION_COLONISATION)
    numColonyships = len(FleetUtilsAI.extract_fleet_ids_without_mission_types(colonyshipIDs))
    colonisationPriority = 60 * (1 + numColonisablePlanetIDs - numColonyships) / (numColonisablePlanetIDs + 1)

    # print
    # print "Number of Colony Ships : " + str(numColonyships)
    # print "Number of Colonisable planets : " + str(numColonisablePlanetIDs)
    # print "Priority for colony ships : " + str(colonisationPriority)

    if colonisationPriority < 1:
        return 0
    return colonisationPriority
Esempio n. 55
0
    def generateAIFleetOrders(self):
        "generates AIFleetOrders from fleets targets to accomplish"

        universe = fo.getUniverse()
        fleetID = self.getAITargetID()
        fleet = universe.getFleet(fleetID)
        if (not fleet) or fleet.empty or (fleetID in universe.destroyedObjectIDs(fo.empireID())): #fleet was probably merged into another or was destroyed
            foAI.foAIstate.deleteFleetInfo(fleetID)
            return

        # TODO: priority
        self.clearAIFleetOrders()
        ntargets=0
        for aiFleetMissionType in self.getAIMissionTypes():
            ntargets += len( self.getAITargets(aiFleetMissionType) )
        if ntargets ==0:
            return #no targets

        # for some targets fleet has to visit systems and therefore fleet visit them
        systemAITargets = self.__getRequiredToVisitSystemAITargets()
        aiFleetOrdersToVisitSystems = MoveUtilsAI.getAIFleetOrdersFromSystemAITargets(self.getAITarget(), systemAITargets)
        #print "----------------------------------------"
        #print "*+*+ fleet %d :  has fleet action system targets:  %s"%(fleetID,  [str(obj) for obj in systemAITargets])
        #print "----------"
        #print "*+*+ fleet %d:  has movement  orders:  %s"%(fleetID,  [str(obj) for obj in aiFleetOrdersToVisitSystems])

        for aiFleetOrder in aiFleetOrdersToVisitSystems:
            self.appendAIFleetOrder(aiFleetOrder)

        # if fleet is in some system = fleet.systemID >=0, then also generate system AIFleetOrders
        systemID = fleet.systemID
        if systemID >= 0:
            # system in where fleet is
            systemAITarget = AITarget.AITarget(AITargetType.TARGET_SYSTEM, systemID)
            # if mission aiTarget has required system where fleet is, then generate aiFleetOrder from this aiTarget 
            aiMissionTypes = self.getAIMissionTypes()
            # for all targets in all mission types get required systems to visit 
            for aiFleetMissionType in aiMissionTypes:
                aiTargets = self.getAITargets(aiFleetMissionType)
                for aiTarget in aiTargets:
                    if systemAITarget in aiTarget.getRequiredSystemAITargets():
                        # from target required to visit get fleet orders to accomplish target
                        aiFleetOrder = self.__getAIFleetOrderFromAITarget(aiFleetMissionType, aiTarget)
                        self.appendAIFleetOrder(aiFleetOrder)


        # if fleet don't have any mission, then resupply if is current location not in supplyable system
        empire = fo.getEmpire()
        fleetSupplyableSystemIDs = empire.fleetSupplyableSystemIDs
        if (not self.hasAnyAIMissionTypes()) and not(self.getLocationAITarget().getTargetID() in fleetSupplyableSystemIDs):
            resupplyAIFleetOrder = MoveUtilsAI.getResupplyAIFleetOrder(self.getAITarget(), self.getLocationAITarget())
            if resupplyAIFleetOrder.isValid():
                self.appendAIFleetOrder(resupplyAIFleetOrder)
Esempio n. 56
0
def get_max_empire_detection(empire_list: Union[List[int], "fo.IntVec"]) -> float:
    """
    Returns the max detection strength across all empires except for the current AI's empire.

    :param empire_list: list of empire IDs
    :return: max detection strength of provided empires, excluding the current self empire
    """
    max_detection = 0
    for this_empire_id in empire_list:
        if this_empire_id != fo.empireID():
            max_detection = max(max_detection, get_empire_detection(this_empire_id))
    return max_detection
Esempio n. 57
0
    def is_valid(self):
        if not super(OrderColonize, self).is_valid():
            return False
        planet = self.target.get_object()

        sys_partial_vis_turn = get_partial_visibility_turn(planet.systemID)
        planet_partial_vis_turn = get_partial_visibility_turn(planet.id)
        if (planet_partial_vis_turn == sys_partial_vis_turn and planet.unowned or
                (planet.ownedBy(fo.empireID()) and not planet.currentMeterValue(fo.meterType.population))):
            return self.fleet.get_object().hasColonyShips
        self.executed = True
        self.order_issued = True
        return False
Esempio n. 58
0
    def get_empire_inhabited_planets_by_system(self):
        """
        Return dict from system id to planet ids of empire with species.

        :rtype: dict[int, list[int]]
        """
        # TODO: as currently used, is duplicative with combo of foAI.foAIstate.popCtrSystemIDs and foAI.foAIstate.colonizedSystems
        empire_id = fo.empireID()
        empire_planets_with_species = (x for x in self.__planet_info.itervalues() if x.owner == empire_id and x.species_name)
        result = {}
        for x in empire_planets_with_species:
            result.setdefault(x.system_id, []).append(x.pid)
        return result
Esempio n. 59
0
def get_empire_fleet_ids():
    """Returns all fleetIDs for current empire."""
    empire_id = fo.empireID()
    universe = fo.getUniverse()
    empire_fleet_ids = []
    destroyed_object_ids = universe.destroyedObjectIDs(empire_id)
    for fleet_id in set(list(universe.fleetIDs) + list(foAI.foAIstate.newlySplitFleets)):
        fleet = universe.getFleet(fleet_id)
        if fleet is None:
            continue
        if fleet.ownedBy(empire_id) and fleet_id not in destroyed_object_ids and not fleet.empty and fleet.shipIDs:
            empire_fleet_ids.append(fleet_id)
    return empire_fleet_ids