예제 #1
0
    def can_issue_order(self, verbose=False):
        if not super(OrderMove, self).can_issue_order(verbose=verbose):
            return False
        # TODO: figure out better way to have invasions (& possibly colonizations) require visibility on target without needing visibility of all intermediate systems
        # if False and main_mission_type not in [AIFleetMissionType.FLEET_MISSION_ATTACK,  # TODO: consider this later
        #                                      AIFleetMissionType.FLEET_MISSION_MILITARY,
        #                                      AIFleetMissionType.FLEET_MISSION_SECURE,
        #                                      AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN,
        #                                      AIFleetMissionType.FLEET_MISSION_EXPLORATION]:
        #     if not universe.getVisibility(target_id, foAI.foAIstate.empireID) >= fo.visibility.partial:
        #         #if not target_id in interior systems
        #         foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID)
        #         return False
        system_id = self.fleet.get_system().id
        if system_id == self.target.get_system().id:
            return True  # TODO: already there, but could consider retreating

        fleet_rating = foAI.foAIstate.get_rating(self.fleet.id).get('overall', 0)
        target_sys_status = foAI.foAIstate.systemStatus.get(self.target.id, {})
        f_threat = target_sys_status.get('fleetThreat', 0)
        m_threat = target_sys_status.get('monsterThreat', 0)
        p_threat = target_sys_status.get('planetThreat', 0)
        threat = f_threat + m_threat + p_threat
        safety_factor = MilitaryAI.get_safety_factor()
        universe = fo.getUniverse()
        if fleet_rating >= safety_factor * threat:
            return True
        elif not p_threat and self.target.id in fo.getEmpire().supplyUnobstructedSystems:
                    return True
        else:
            sys1 = universe.getSystem(system_id)
            sys1_name = sys1 and sys1.name or "unknown"
            targ1 = self.target.get_system()
            targ1_name = (targ1 and targ1.get_object().name) or "unknown"
            # following line was poor because AIstate.militaryFleetIDs only covers fleets without current missions
            # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('rating', 0) for fleet_id in foAI.foAIstate.militaryFleetIDs if ( foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('sysID', -1) == thisSystemID ) ])
            # myOtherFleetsRatings = [foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', {}) for fid in foAI.foAIstate.systemStatus.get(target_id, {}).get('myfleets', [])]
            # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', 0) for fid in foAI.foAIstate.systemStatus.get( target_id, {}).get('myfleets', []) ])
            my_other_fleet_rating = foAI.foAIstate.systemStatus.get(self.target.id, {}).get('myFleetRating', 0)  # TODO: adjust calc for any departing fleets
            is_military = foAI.foAIstate.get_fleet_role(self.fleet.id) == AIFleetMissionType.FLEET_MISSION_MILITARY
            if ((my_other_fleet_rating > 3 * safety_factor * threat) or
                        (is_military and my_other_fleet_rating + fleet_rating > safety_factor * threat) or
                        (is_military and my_other_fleet_rating + fleet_rating > 0.8 * safety_factor * threat and fleet_rating > 0.2 * threat)):
                if verbose:
                    print "\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with threat %d because of sufficient empire fleet strength already at destination" % (
                        self.fleet.id, fleet_rating, system_id, sys1_name, self.target.id, targ1_name, threat)
                return True
            elif threat == p_threat and not self.fleet.get_object().aggressive and not my_other_fleet_rating and not target_sys_status.get('localEnemyFleetIDs', [-1]):
                if verbose:
                    print ("\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with planet threat %d because nonaggressive" +
                           " and no other fleets present to trigger combat") % (self.fleet.id, fleet_rating, system_id, sys1_name, self.target.id, targ1_name, threat)
                return True
            else:
                if verbose:
                    print "\tHolding fleet %d (rating %d) at system %d (%s) before travelling to system %d (%s) with threat %d" % (self.fleet.id, fleet_rating, system_id, sys1_name, self.target.id, targ1_name, threat)
                needs_vis = foAI.foAIstate.misc.setdefault('needs_vis', [])
                if self.target.id not in needs_vis:
                    needs_vis.append(self.target.id)
                return False
        return True
예제 #2
0
    def can_issue_order(self, verbose=False):
        if not super(OrderMove, self).can_issue_order(verbose=verbose):
            return False
        # TODO: figure out better way to have invasions (& possibly colonizations) require visibility on target without needing visibility of all intermediate systems
        # if False and main_mission_type not in [MissionType.ATTACK,  # TODO: consider this later
        #                                        MissionType.MILITARY,
        #                                        MissionType.SECURE,
        #                                        MissionType.HIT_AND_RUN,
        #                                        MissionType.EXPLORATION]:
        #     if not universe.getVisibility(target_id, foAI.foAIstate.empireID) >= fo.visibility.partial:
        #         #if not target_id in interior systems
        #         foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID)
        #         return False
        system_id = self.fleet.get_system().id
        if system_id == self.target.get_system().id:
            return True  # TODO: already there, but could consider retreating

        fleet_rating = foAI.foAIstate.get_rating(self.fleet.id).get(
            'overall', 0)
        target_sys_status = foAI.foAIstate.systemStatus.get(self.target.id, {})
        f_threat = target_sys_status.get('fleetThreat', 0)
        m_threat = target_sys_status.get('monsterThreat', 0)
        p_threat = target_sys_status.get('planetThreat', 0)
        threat = f_threat + m_threat + p_threat
        safety_factor = MilitaryAI.get_safety_factor()
        universe = fo.getUniverse()
        if fleet_rating >= safety_factor * threat:
            return True
        elif not p_threat and self.target.id in fo.getEmpire(
        ).supplyUnobstructedSystems:
            return True
        else:
            sys1 = universe.getSystem(system_id)
            sys1_name = sys1 and sys1.name or "unknown"
            target_system = self.target.get_system()
            target_system_name = (target_system and
                                  target_system.get_object().name) or "unknown"
            my_other_fleet_rating = foAI.foAIstate.systemStatus.get(
                self.target.id,
                {}).get('myFleetRating',
                        0)  # TODO: adjust calc for any departing fleets
            is_military = foAI.foAIstate.get_fleet_role(
                self.fleet.id) == MissionType.MILITARY

            total_rating = my_other_fleet_rating + fleet_rating
            if any(
                ((my_other_fleet_rating > 3 * safety_factor * threat),
                 (is_military and total_rating > safety_factor * threat),
                 (is_military and total_rating > 0.8 * safety_factor * threat
                  and fleet_rating > 0.2 * threat))):
                if verbose:
                    print "\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with threat %d because of sufficient empire fleet strength already at destination" % (
                        self.fleet.id, fleet_rating, system_id, sys1_name,
                        self.target.id, target_system_name, threat)
                return True
            elif threat == p_threat and not self.fleet.get_object(
            ).aggressive and not my_other_fleet_rating and not target_sys_status.get(
                    'localEnemyFleetIDs', [-1]):
                if verbose:
                    print(
                        "\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with planet threat %d because nonaggressive"
                        + " and no other fleets present to trigger combat") % (
                            self.fleet.id, fleet_rating, system_id, sys1_name,
                            self.target.id, target_system_name, threat)
                return True
            else:
                if verbose:
                    print "\tHolding fleet %d (rating %d) at system %d (%s) before travelling to system %d (%s) with threat %d" % (
                        self.fleet.id, fleet_rating, system_id, sys1_name,
                        self.target.id, target_system_name, threat)
                needs_vis = foAI.foAIstate.misc.setdefault('needs_vis', [])
                if self.target.id not in needs_vis:
                    needs_vis.append(self.target.id)
                return False
        return True
    def can_issue_order(self, verbose=False):
        """If FleetOrder can be issued now."""
        # for some orders, may need to re-issue if invasion/outposting/colonization was interrupted
        if self.executed and self.order_type not in [AIFleetOrderType.ORDER_OUTPOST, AIFleetOrderType.ORDER_COLONISE, AIFleetOrderType.ORDER_INVADE]:
            return False
        if not self.is_valid():
            return False
        universe = fo.getUniverse()
        ship_id = None
        fleet_id = self.fleet.target_id
        fleet = universe.getFleet(fleet_id)
        system_id = fleet.systemID
        target_id = self.target.target_id

        if verbose:
            sys1 = universe.getSystem(system_id)
            sys_name = sys1 and sys1.name or "unknown"
            main_fleet_mission = foAI.foAIstate.get_fleet_mission(fleet_id)
            main_mission_type = (main_fleet_mission.get_mission_types() + [-1])[0]
            print "** %s -- Mission Type  %s (%s) , current loc sys %d  - %s" % (self, AIFleetMissionTypeNames.name(main_mission_type), main_mission_type, system_id, sys_name)
        #
        # outpost
        #
        if AIFleetOrderType.ORDER_OUTPOST == self.order_type:  # TODO: check for separate fleet holding outpost ships

            ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_CIVILIAN_OUTPOST)
            if ship_id is None:
                ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_BASE_OUTPOST)
            ship = universe.getShip(ship_id)
            planet = universe.getPlanet(self.target.target_id)
            return ship is not None and fleet.systemID == planet.systemID and ship.canColonize
        #
        # colonise
        #
        elif AIFleetOrderType.ORDER_COLONISE == self.order_type:  # TODO: check for separate fleet holding colony ships
            if TargetType.TARGET_FLEET == self.fleet.target_type:
                ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_CIVILIAN_COLONISATION)
                if ship_id is None:
                    ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_BASE_COLONISATION)
            ship = universe.getShip(ship_id)
            planet = universe.getPlanet(self.target.target_id)
            if ship and not ship.canColonize:
                print "Error: colonization fleet %d has no colony ship" % fleet_id
            return ship is not None and fleet.systemID == planet.systemID and ship.canColonize
        #
        # invade
        #
        elif AIFleetOrderType.ORDER_INVADE == self.order_type:  # TODO: check for separate fleet holding invasion ships
            if TargetType.TARGET_FLEET == self.fleet.target_type:
                ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, False)
                if ship_id is None:
                    ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_BASE_INVASION)
            ship = universe.getShip(ship_id)
            planet = universe.getPlanet(self.target.target_id)
            return ship is not None and fleet.systemID == planet.systemID and ship.canInvade and not planet.currentMeterValue(fo.meterType.shield)
        #
        # military
        #
        elif AIFleetOrderType.ORDER_MILITARY == self.order_type:
            if TargetType.TARGET_FLEET == self.fleet.target_type:
                ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_MILITARY)
            ship = universe.getShip(ship_id)
            system = universe.getSystem(self.target.target_id)
            return ship is not None and fleet.systemID == system.systemID and ship.isArmed
        #
        # split fleet
        #
        elif AIFleetOrderType.ORDER_SPLIT_FLEET == self.order_type:
            return len(fleet.shipIDs) > 1
        #
        # move -- have fleets will do a safety check, also check for potential military fleet mergers
        #
        elif AIFleetOrderType.ORDER_MOVE == self.order_type:
            #  target_id = self.target.target_id
            # TODO: figure out better way to have invasions (& possibly colonizations) require visibility on target without needing visibility of all intermediate systems
            if False and main_mission_type not in [AIFleetMissionType.FLEET_MISSION_ATTACK,  # TODO: consider this later
                                                 AIFleetMissionType.FLEET_MISSION_MILITARY,
                                                 AIFleetMissionType.FLEET_MISSION_SECURE,
                                                 AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN,
                                                 AIFleetMissionType.FLEET_MISSION_EXPLORATION]:
                if not universe.getVisibility(target_id, foAI.foAIstate.empireID) >= fo.visibility.partial:
                    #if not target_id in interior systems
                    foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID)
                    return False

            system_id = fleet.systemID
            if system_id == target_id:
                return True  # TODO: already there, but could consider retreating

            fleet_rating = foAI.foAIstate.get_rating(fleet_id).get('overall', 0)
            target_sys_status = foAI.foAIstate.systemStatus.get(target_id, {})
            f_threat = target_sys_status.get('fleetThreat', 0)
            m_threat = target_sys_status.get('monsterThreat', 0)
            p_threat = target_sys_status.get('planetThreat', 0)
            threat = f_threat + m_threat + p_threat
            safety_factor = MilitaryAI.get_safety_factor()
            if fleet_rating >= safety_factor * threat:
                return True
            else:
                sys1 = universe.getSystem(system_id)
                sys1_name = sys1 and sys1.name or "unknown"
                targ1 = universe.getSystem(target_id)
                targ1_name = (targ1 and targ1.name) or "unknown"
                # following line was poor because AIstate.militaryFleetIDs only covers fleets without current missions
                # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('rating', 0) for fleet_id in foAI.foAIstate.militaryFleetIDs if ( foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('sysID', -1) == thisSystemID ) ])
                # myOtherFleetsRatings = [foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', {}) for fid in foAI.foAIstate.systemStatus.get(target_id, {}).get('myfleets', [])]
                # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', 0) for fid in foAI.foAIstate.systemStatus.get( target_id, {}).get('myfleets', []) ])
                my_other_fleet_rating = foAI.foAIstate.systemStatus.get(target_id, {}).get('myFleetRating', 0)  # TODO: adjust calc for any departing fleets
                is_military = foAI.foAIstate.get_fleet_role(fleet_id) == AIFleetMissionType.FLEET_MISSION_MILITARY
                if ((my_other_fleet_rating > 3 * safety_factor * threat) or
                            (is_military and my_other_fleet_rating + fleet_rating > safety_factor * threat) or
                            (is_military and my_other_fleet_rating + fleet_rating > 0.8 * safety_factor * threat and fleet_rating > 0.2 * threat)):
                    if verbose:
                        print "\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with threat %d because of sufficient empire fleet strength already at destination" % (fleet_id, fleet_rating, system_id, sys1_name, target_id, targ1_name, threat)
                    return True
                elif threat == p_threat and not fleet.aggressive and not my_other_fleet_rating and not target_sys_status.get('localEnemyFleetIDs', [-1]):
                    if verbose:
                        print ("\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with planet threat %d because nonaggressive" +
                               " and no other fleets present to trigger combat") % (fleet_id, fleet_rating, system_id, sys1_name, target_id, targ1_name, threat)
                    return True
                else:
                    if verbose:
                        print "\tHolding fleet %d (rating %d) at system %d (%s) before travelling to system %d (%s) with threat %d" % (fleet_id, fleet_rating, system_id, sys1_name, target_id, targ1_name, threat)
                    return False
        else:  # default returns true
            return True
예제 #4
0
    def can_issue_order(self, verbose=False):
        """If FleetOrder can be issued now."""
        # for some orders, may need to re-issue if invasion/outposting/colonization was interrupted
        if self.executed and self.order_type not in [AIFleetOrderType.ORDER_OUTPOST, AIFleetOrderType.ORDER_COLONISE, AIFleetOrderType.ORDER_INVADE]:
            return False
        if not self.is_valid():
            return False
        universe = fo.getUniverse()
        ship_id = None
        fleet_id = self.fleet.target_id
        fleet = universe.getFleet(fleet_id)
        system_id = fleet.systemID
        target_id = self.target.target_id

        if verbose:
            sys1 = universe.getSystem(system_id)
            sys_name = sys1 and sys1.name or "unknown"
            main_fleet_mission = foAI.foAIstate.get_fleet_mission(fleet_id)
            main_mission_type = (main_fleet_mission.get_mission_types() + [-1])[0]
            print "** %s -- Mission Type  %s (%s) , current loc sys %d  - %s" % (self, AIFleetMissionTypeNames.name(main_mission_type), main_mission_type, system_id, sys_name)
        #
        # outpost
        #
        if AIFleetOrderType.ORDER_OUTPOST == self.order_type:  # TODO: check for separate fleet holding outpost ships

            ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_CIVILIAN_OUTPOST)
            if ship_id is None:
                ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_BASE_OUTPOST)
            ship = universe.getShip(ship_id)
            planet = universe.getPlanet(self.target.target_id)
            return ship is not None and fleet.systemID == planet.systemID and ship.canColonize
        #
        # colonise
        #
        elif AIFleetOrderType.ORDER_COLONISE == self.order_type:  # TODO: check for separate fleet holding colony ships
            if TargetType.TARGET_FLEET == self.fleet.target_type:
                ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_CIVILIAN_COLONISATION)
                if ship_id is None:
                    ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_BASE_COLONISATION)
            ship = universe.getShip(ship_id)
            planet = universe.getPlanet(self.target.target_id)
            if ship and not ship.canColonize:
                print "Error: colonization fleet %d has no colony ship" % fleet_id
            return ship is not None and fleet.systemID == planet.systemID and ship.canColonize
        #
        # invade
        #
        elif AIFleetOrderType.ORDER_INVADE == self.order_type:  # TODO: check for separate fleet holding invasion ships
            if TargetType.TARGET_FLEET == self.fleet.target_type:
                ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_MILITARY_INVASION, False)
                if ship_id is None:
                    ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_BASE_INVASION)
            ship = universe.getShip(ship_id)
            planet = universe.getPlanet(self.target.target_id)
            return ship is not None and fleet.systemID == planet.systemID and ship.canInvade and not planet.currentMeterValue(fo.meterType.shield)
        #
        # military
        #
        elif AIFleetOrderType.ORDER_MILITARY == self.order_type:
            if TargetType.TARGET_FLEET == self.fleet.target_type:
                ship_id = FleetUtilsAI.get_ship_id_with_role(fleet_id, AIShipRoleType.SHIP_ROLE_MILITARY)
            ship = universe.getShip(ship_id)
            system = universe.getSystem(self.target.target_id)
            return ship is not None and fleet.systemID == system.systemID and ship.isArmed
        #
        # split fleet
        #
        elif AIFleetOrderType.ORDER_SPLIT_FLEET == self.order_type:
            return len(fleet.shipIDs) > 1
        #
        # move -- have fleets will do a safety check, also check for potential military fleet mergers
        #
        elif AIFleetOrderType.ORDER_MOVE == self.order_type:
            #  target_id = self.target.target_id
            # TODO: figure out better way to have invasions (& possibly colonizations) require visibility on target without needing visibility of all intermediate systems
            if False and main_mission_type not in [AIFleetMissionType.FLEET_MISSION_ATTACK,  # TODO: consider this later
                                                 AIFleetMissionType.FLEET_MISSION_MILITARY,
                                                 AIFleetMissionType.FLEET_MISSION_SECURE,
                                                 AIFleetMissionType.FLEET_MISSION_HIT_AND_RUN,
                                                 AIFleetMissionType.FLEET_MISSION_EXPLORATION]:
                if not universe.getVisibility(target_id, foAI.foAIstate.empireID) >= fo.visibility.partial:
                    #if not target_id in interior systems
                    foAI.foAIstate.needsEmergencyExploration.append(fleet.systemID)
                    return False

            system_id = fleet.systemID
            if system_id == target_id:
                return True  # TODO: already there, but could consider retreating

            fleet_rating = foAI.foAIstate.get_rating(fleet_id).get('overall', 0)
            target_sys_status = foAI.foAIstate.systemStatus.get(target_id, {})
            f_threat = target_sys_status.get('fleetThreat', 0)
            m_threat = target_sys_status.get('monsterThreat', 0)
            p_threat = target_sys_status.get('planetThreat', 0)
            threat = f_threat + m_threat + p_threat
            safety_factor = MilitaryAI.get_safety_factor()
            if fleet_rating >= safety_factor * threat:
                return True
            else:
                sys1 = universe.getSystem(system_id)
                sys1_name = sys1 and sys1.name or "unknown"
                targ1 = universe.getSystem(target_id)
                targ1_name = (targ1 and targ1.name) or "unknown"
                # following line was poor because AIstate.militaryFleetIDs only covers fleets without current missions
                # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('rating', 0) for fleet_id in foAI.foAIstate.militaryFleetIDs if ( foAI.foAIstate.fleetStatus.get(fleet_id, {}).get('sysID', -1) == thisSystemID ) ])
                # myOtherFleetsRatings = [foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', {}) for fid in foAI.foAIstate.systemStatus.get(target_id, {}).get('myfleets', [])]
                # my_other_fleet_rating = sum([foAI.foAIstate.fleetStatus.get(fid, {}).get('rating', 0) for fid in foAI.foAIstate.systemStatus.get( target_id, {}).get('myfleets', []) ])
                my_other_fleet_rating = foAI.foAIstate.systemStatus.get(target_id, {}).get('myFleetRating', 0)  # TODO: adjust calc for any departing fleets
                is_military = foAI.foAIstate.get_fleet_role(fleet_id) == AIFleetMissionType.FLEET_MISSION_MILITARY
                if ((my_other_fleet_rating > 3 * safety_factor * threat) or
                            (is_military and my_other_fleet_rating + fleet_rating > safety_factor * threat) or
                            (is_military and my_other_fleet_rating + fleet_rating > 0.8 * safety_factor * threat and fleet_rating > 0.2 * threat)):
                    if verbose:
                        print "\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with threat %d because of sufficient empire fleet strength already at destination" % (fleet_id, fleet_rating, system_id, sys1_name, target_id, targ1_name, threat)
                    return True
                elif threat == p_threat and not fleet.aggressive and not my_other_fleet_rating and not target_sys_status.get('localEnemyFleetIDs', [-1]):
                    if verbose:
                        print ("\tAdvancing fleet %d (rating %d) at system %d (%s) into system %d (%s) with planet threat %d because nonaggressive" +
                               " and no other fleets present to trigger combat") % (fleet_id, fleet_rating, system_id, sys1_name, target_id, targ1_name, threat)
                    return True
                else:
                    if verbose:
                        print "\tHolding fleet %d (rating %d) at system %d (%s) before travelling to system %d (%s) with threat %d" % (fleet_id, fleet_rating, system_id, sys1_name, target_id, targ1_name, threat)
                    return False
        else:  # default returns true
            return True