예제 #1
0
def pathfinder_enemy_array_for_room(room_name):
    # type: (str) -> List[Dict[str, Any]]
    cache = volatile_cache.mem("enemy_lists")
    if cache.has(room_name):
        return cache.get(room_name)
    my = is_room_mostly_safe(room_name)
    enemy_positions = []
    for h in defense.stored_hostiles_near(room_name):
        if not is_room_mostly_safe(room_name):
            if h.user == INVADER_USERNAME:
                if my:
                    enemy_range = 2
                else:
                    enemy_range = 5
            elif h.ranged or h.attack:
                enemy_range = 10
            else:
                continue
        elif h.user == INVADER_USERNAME:
            enemy_range = 5
        elif h.ranged:
            enemy_range = 7
        elif h.attack:
            enemy_range = 5
        else:
            continue

        pos = __new__(RoomPosition(h.pos & 0x3F, h.pos >> 6 & 0x3F, h.room))
        # NOTE: here we multiply by two, so that when we pass this array to the PathFinder we'll get a better path.
        enemy_positions.append({"pos": pos, "range": enemy_range * 4})

    cache.set(room_name, enemy_positions)
    return enemy_positions
예제 #2
0
def find_new_target_extension(targets, creep):
    # type: (TargetMind, RoleBase) -> Optional[str]
    closest_distance = Infinity
    best_id = None
    stealing_from = None
    structures = cast(
        List[Union[StructureExtension, StructureSpawn]],
        _.filter(
            creep.home.find(FIND_MY_STRUCTURES), lambda s:
            ((s.structureType == STRUCTURE_EXTENSION or s.structureType ==
              STRUCTURE_SPAWN) and s.energy < s.energyCapacity)))
    if len(structures):
        for structure in structures:
            structure_id = structure.id
            if volatile_cache.mem("extensions_filled").has(structure_id):
                continue
            current_carry = targets.workforce_of(target_spawn_deposit,
                                                 structure_id)
            distance = movement.distance_squared_room_pos(
                structure.pos, creep.creep.pos)
            if distance < closest_distance:
                max_to_deposit = structure.energyCapacity / 50.0
                if not current_carry or current_carry < max_to_deposit:
                    closest_distance = distance
                    best_id = structure_id
                    stealing_from = None
                else:
                    targeting = targets.reverse_targets[target_spawn_deposit][
                        structure_id]
                    if len(targeting):
                        for name in targeting:
                            if not Game.creeps[
                                    name] or movement.distance_squared_room_pos(
                                        Game.creeps[name].pos,
                                        structure.pos) > distance * 2.25:
                                # If we're at least 1.5x closer than them, let's steal their place.
                                # Note that 1.5^2 is 2.25, which is what we should be using since we're comparing
                                # squared distances. d1 > d2 * 1.5 is equivalent to d1^2 > d2^2 * 1.5^2 which is
                                # equivalent to d1^2 > d2^2 * 2.25
                                closest_distance = distance
                                best_id = structure_id
                                stealing_from = name
                                break
                    else:
                        closest_distance = distance
                        best_id = structure_id
                        stealing_from = None
        if stealing_from is not None:
            targets.unregister_name(stealing_from, target_spawn_deposit)
    elif creep.home.full_storage_use:
        flag_list = flags.find_flags(creep.home, SPAWN_FILL_WAIT)
        if len(flag_list):
            best_id = _(flag_list).map(lambda f: "flag-{}".format(f.name)) \
                .min(lambda fid: targets.reverse_targets[target_spawn_deposit][fid] or 0)
            if best_id is Infinity:
                best_id = None
    return best_id
예제 #3
0
def room_hostile(room_name):
    # type: (str) -> bool
    cache = volatile_cache.mem("rua")
    if cache.has(room_name):
        return cache.get(room_name)

    # This will only get "active" hostiles, which doesn't count source keepers, or non-ATTACK/RANGED_ATTACK creeps in
    # owned rooms.
    room_under_attack = not not len(defense.stored_hostiles_in(room_name))

    cache.set(room_name, room_under_attack)
    return room_under_attack
예제 #4
0
 def run_squad(self, members, target):
     # type: (List[SquadDrone], Location) -> None
     attacked = False
     here = cast(List[Creep], self.room.find(FIND_HOSTILE_CREEPS))
     if len(here):
         directly_nearby = 0
         best = None
         best_range = Infinity
         best_rank = -Infinity
         for enemy in here:
             enemy_range = movement.chebyshev_distance_room_pos(enemy.pos, self.pos)
             if enemy_range <= 3:
                 specialty = enemy.findSpecialty()
                 if specialty == ATTACK or specialty == RANGED_ATTACK:
                     rank = 40
                 elif specialty == WORK:
                     rank = 35
                 else:
                     rank = 30
                 if _.some(self.room.look_at(LOOK_STRUCTURES, enemy.pos),
                           lambda s: s.structureType == STRUCTURE_RAMPART and not s.my):
                     rank -= 20
                 rank += (enemy.hitsMax - enemy.hits) / enemy.hitsMax * 5
                 if enemy_range < 1:
                     directly_nearby += rank
                 if rank > best_rank:
                     best_rank = rank
                     best_range = enemy_range
                     best = enemy
         if directly_nearby > 65 or best_range <= 1:
             result = self.creep.rangedMassAttack()
             if result != OK:
                 self.log("Unknown result from {}.rangedMassAttack(): {}"
                          .format(self.creep, result))
             attacked = True
         elif best:
             result = self.creep.rangedAttack(best)
             if result != OK:
                 self.log("Unknown result from {}.rangedAttack({}): {}"
                          .format(self.creep, best, result))
             attacked = True
     if not attacked:
         to_dismantle = volatile_cache.mem('dismantle_squad_dismantling').get(target.name)
         if to_dismantle:
             self.creep.rangedAttack(to_dismantle)
예제 #5
0
def enemy_purposes_cost_matrix(room_name):
    # type: (str) -> PathFinder.CostMatrix
    cache = volatile_cache.mem("super_simple_cost_matrix")
    if cache.has(room_name):
        return cache.get(room_name)

    room = context.hive().get_room(room_name)
    if not room:
        return __new__(PathFinder.CostMatrix())

    cost_matrix = __new__(PathFinder.CostMatrix())

    for struct in cast(List[Structure], room.find(FIND_STRUCTURES)):
        if struct.structureType != STRUCTURE_ROAD and struct.structureType != STRUCTURE_CONTAINER \
                and (struct.structureType != STRUCTURE_RAMPART or cast(StructureRampart, struct).my):
            cost_matrix.set(struct.pos.x, struct.pos.y, 255)

    cache.set(room_name, cost_matrix)
    return cost_matrix
예제 #6
0
def simple_cost_matrix(room_name):
    # type: (str) -> Union[PathFinder.CostMatrix, bool]
    cache = volatile_cache.mem("enemy_cost_matrix")
    # TODO: some of this is duplicated in honey.HoneyTrails

    room = context.hive().get_room(room_name)
    if not room:
        if room_hostile(room_name) or hostile_utils.enemy_using_room(
                room_name):
            return False
        else:
            return __new__(PathFinder.CostMatrix())

    # The basic cost matrix already has impassable things on it, and already has SK lairs avoided, but does not
    # have any non-hostile creeps. It also already has exits marked.
    cost_matrix = walkby_move.get_basic_cost_matrix(room_name, False)

    def wall_at(x, y):
        return Game.map.getTerrainAt(x, y, room_name) == 'wall'

    def set_in_range(pos, drange, value, increase_by_center):
        for x in range(pos.x - drange, pos.x + drange + 1):
            for y in range(pos.y - drange, pos.y + drange + 1):
                if not wall_at(x, y) and cost_matrix.get(x, y) < value:
                    cost_matrix.set(x, y, value)
        if increase_by_center > 0 and drange > 0:
            set_in_range(pos, drange - 1, value + increase_by_center,
                         increase_by_center)

    for creep in room.find(FIND_CREEPS):
        set_in_range(creep.pos, 1, 5, 0)
        cost_matrix.set(creep.pos.x, creep.pos.y, 255)
    for creep in room.find(FIND_HOSTILE_CREEPS):
        set_in_range(creep.pos, 7, 2, 7)
        cost_matrix.set(creep.pos.x, creep.pos.y, 255)

    cache.set(room_name, cost_matrix)
    return cost_matrix
예제 #7
0
def kiting_cost_matrix(room_name, target):
    # type: (str, Flag) -> Union[PathFinder.CostMatrix, bool]
    cache = volatile_cache.mem("kiting_cost_matrix")
    if cache.has(room_name):
        return cache.get(room_name)
    if hostile_utils.enemy_using_room(room_name) and room_name != target.pos.roomName:
        return False
    # TODO: some of this is duplicated in honey.HoneyTrails

    cost_matrix = __new__(PathFinder.CostMatrix())

    def set_in_range_xy(initial_x, initial_y, distance, value, increase_by_center):
        for x in range(initial_x - distance, initial_x + distance + 1):
            for y in range(initial_y - distance, initial_y + distance + 1):
                if increase_by_center:
                    value_here = value + increase_by_center \
                                         * (distance - movement.chebyshev_distance_xy(initial_x, initial_y, x, y))
                else:
                    value_here = value
                existing_cost = cost_matrix.get(x, y)
                if existing_cost == 0:
                    terrain_here = Game.map.getTerrainAt(x, y, room_name)
                    if terrain_here[0] == 'p':
                        existing_cost = 1
                    elif terrain_here[0] == 's':
                        existing_cost = 25
                    elif terrain_here[0] == 'w':
                        continue
                cost_matrix.set(x, y, existing_cost + value_here)

    def set_in_range(pos, distance, value, increase_by_center):
        pos = pos.pos or pos
        set_in_range_xy(pos.x, pos.y, distance, value, increase_by_center)

    room = context.hive().get_room(room_name)

    if room:
        any_lairs = False
        for struct in cast(List[OwnedStructure], room.find(FIND_STRUCTURES)):
            if struct.structureType == STRUCTURE_ROAD:
                cost_matrix.set(struct.pos.x, struct.pos.y, 1)
            elif struct.structureType != STRUCTURE_CONTAINER and (struct.structureType != STRUCTURE_RAMPART
                                                                  or not struct.my):
                if struct.structureType == STRUCTURE_KEEPER_LAIR:
                    any_lairs = True
                cost_matrix.set(struct.pos.x, struct.pos.y, 255)
        for creep in room.find(FIND_MY_CREEPS):
            cost_matrix.set(creep.pos.x, creep.pos.y, 255)
        if any_lairs:
            for source in room.find(FIND_SOURCES):
                set_in_range(source.pos, 4, 255, 0)
            for mineral in room.find(FIND_MINERALS):
                set_in_range(mineral.pos, 4, 255, 0)
    else:
        data = stored_data.get_data(room_name)
        if data:
            for obstacle in data.obstacles:
                if obstacle.type == StoredObstacleType.ROAD:
                    cost_matrix.set(obstacle.x, obstacle.y, 1)
                elif obstacle.type == StoredObstacleType.SOURCE_KEEPER_LAIR \
                        or obstacle.type == StoredObstacleType.SOURCE_KEEPER_SOURCE \
                        or obstacle.type == StoredObstacleType.SOURCE_KEEPER_MINERAL:
                    set_in_range(obstacle, 4, 255, 0)
                else:
                    cost_matrix.set(obstacle.x, obstacle.y, 255)

    for info in defense.stored_hostiles_in(room_name):
        x, y = positions.deserialize_xy(info.pos)
        set_in_range_xy(x, y, 3, 5, 10)
        cost_matrix.set(x, y, 255)

    for x in [0, 49]:
        for y in range(0, 49):
            existing = cost_matrix.get(x, y)
            if existing == 0:
                terrain = Game.map.getTerrainAt(x, y, room_name)
                if terrain[0] == 'p':
                    existing = 1
                elif terrain[0] == 's':
                    existing = 25
                else:
                    continue  # wall
            cost_matrix.set(x, y, existing + 5)
    for y in [0, 49]:
        for x in range(0, 49):
            existing = cost_matrix.get(x, y)
            if existing == 0:
                terrain = Game.map.getTerrainAt(x, y, room_name)
                if terrain[0] == 'p':
                    existing = 1
                elif terrain[0] == 's':
                    existing = 25
                else:
                    continue  # wall
            cost_matrix.set(x, y, existing + 5)

    cache.set(room_name, cost_matrix)

    return cost_matrix
예제 #8
0
    def run_squad(self, members, target):
        # type: (List[SquadDrone], Location) -> None
        if movement.chebyshev_distance_room_pos(self.pos, target) > 150:
            return
        opts = get_opts(self.pos.roomName)
        self.log("running with opts {}", JSON.stringify(opts))
        owner = stored_data._find_room_owner(self.room.room)
        if (owner and (Memory.meta.friends.includes(owner.name.lower())
                       or owner.name == self.creep.owner.username)):
            return

        next_pos = None

        path = _.get(self.memory, ['_move', 'path'])
        if path:
            next_pos = self.creep.findNextPathPos(path)
            if not _.isObject(next_pos) or not self.pos.isNearTo(next_pos):
                next_pos = None

        if next_pos is None and self.creep.__direction_moved:
            next_pos = movement.apply_direction(self.pos,
                                                self.creep.__direction_moved)

        if next_pos is not None:
            best_structure = cast(
                Structure,
                _.find(self.room.look_at(LOOK_STRUCTURES, next_pos),
                       get_dismantle_condition_not_a_road(opts)))
            if best_structure:
                result = self.creep.dismantle(best_structure)
                if result != OK:
                    self.log("Unknown result from {}.dismantle({}): {}",
                             self.creep, best_structure, result)
                if result != ERR_NOT_IN_RANGE:
                    return
        elif next_pos == ERR_NOT_FOUND:
            del self.memory['_move']
        structures_around = cast(
            List[Dict[str, Structure]],
            self.room.look_for_in_area_around(LOOK_STRUCTURES, self.pos, 1))
        best_structure = None
        our_dismantle_power = DISMANTLE_POWER * self.creep.getActiveBodypartsBoostEquivalent(
            WORK, 'dismantle')
        if len(structures_around) > 1:
            ramparts_at = None
            for structure_obj in structures_around:
                if structure_obj[
                        LOOK_STRUCTURES].structureType == STRUCTURE_RAMPART:
                    if ramparts_at is None:
                        ramparts_at = {}
                    ramparts_at[positions.serialize_pos_xy(structure_obj[LOOK_STRUCTURES].pos)] \
                        = structure_obj[LOOK_STRUCTURES].hits
            best_rank = -Infinity
            for structure_obj in cast(
                    List[Dict[str, Structure]],
                    self.room.look_for_in_area_around(LOOK_STRUCTURES,
                                                      self.pos, 1)):
                structure = structure_obj[LOOK_STRUCTURES]
                if not can_target_struct(structure, opts):
                    continue
                structure_type = structure.structureType
                if structure_type == STRUCTURE_TOWER:
                    rank = 55
                elif structure_type == STRUCTURE_SPAWN:
                    rank = 50
                elif structure_type == STRUCTURE_LAB:
                    rank = 45
                elif structure_type == STRUCTURE_EXTENSION:
                    rank = 40
                elif structure_type == STRUCTURE_LINK:
                    rank = 30
                else:
                    rank = 10

                hits = structure.hits

                if structure_type != STRUCTURE_RAMPART and ramparts_at:
                    rampart = ramparts_at[positions.serialize_pos_xy(
                        structure.pos)]
                    if rampart and rampart.hits:
                        hits += rampart.hits

                if hits < our_dismantle_power:
                    rank -= hits / our_dismantle_power
                if rank > best_rank:
                    best_rank = rank
                    best_structure = structure
        elif len(structures_around):
            best_structure = structures_around[0][LOOK_STRUCTURES]
            if not can_target_struct(best_structure, opts):
                return
        else:
            return

        if best_structure:
            result = self.creep.dismantle(best_structure)
            volatile_cache.mem('dismantle_squad_dismantling').set(
                target.name, best_structure)
            if result == OK:
                if best_structure.hits < our_dismantle_power \
                        or best_structure.hits < our_dismantle_power + _.sum(
                            members, lambda x: x.creep.getActiveBodypartsBoostEquivalent(RANGED_ATTACK, 'rangedAttack')
                                    * RANGED_ATTACK_POWER):
                    del self.memory._move
            else:
                self.log("Unknown result from {}.dismantle({}): {}".format(
                    self.creep, best_structure, result))
예제 #9
0
    def run(self):
        if self.creep.ticksToLive < recycle_time and not self.home.under_siege(
        ):
            self.memory.role = role_recycling
            self.memory.last_role = role_spawn_fill
            return False
        if self.memory.filling and self.creep.carry[
                RESOURCE_ENERGY] >= self.creep.carryCapacity:
            self.memory.filling = False
            if self.memory.role == role_spawn_fill or self.memory.role == role_tower_fill:
                self.targets.untarget_all(self)
            else:
                return True
        elif not self.memory.filling and (
                self.creep.carry[RESOURCE_ENERGY] <= 0 or
            (self.creep.carry[RESOURCE_ENERGY] <= 20 and self.home.room.storage
             and movement.chebyshev_distance_room_pos(
                 self.pos, self.home.room.storage.pos) < 5)):
            self.memory.filling = True
            del self.memory.running
            if self.memory.role == role_spawn_fill or self.memory.role == role_tower_fill:
                self.targets.untarget_all(self)
            else:
                return True

        if self.memory.filling:
            return self.harvest_energy()
        else:
            if 'running' in self.memory:
                if self.memory.running == role_upgrader:
                    return upgrading.Upgrader.run(self)
                elif self.memory.running == role_builder:
                    return building.Builder.run(self)
                elif self.memory.running == "refill":
                    return self.refill_creeps()
                elif self.memory.running != role_spawn_fill and self.memory.running != "spawn_wait":
                    self.log("WARNING: Unknown running value: {}",
                             self.memory.running)
                    del self.memory.running
            elif self.home.room.energyCapacityAvailable < 550 and self.home.room.energyAvailable < 300 \
                    and self.home.next_role is None:
                if self.creep.hasActiveBodyparts(WORK):
                    self.memory.running = role_builder
                    return building.Builder.run(self)
                else:
                    self.memory.running = "refill"
                    return self.refill_creeps()
            target = cast(
                Union[StructureExtension, Flag, None],
                self.targets.get_new_target(self, target_spawn_deposit))
            if target:
                if cast(Flag, target).color:  # it's a spawn fill wait flag
                    assert isinstance(target, Flag)
                    self.memory.running = "spawn_wait"
                    rwc_cache = volatile_cache.mem("sfrwc")
                    if not rwc_cache.has(self.pos.roomName):
                        rwc_cache.set(
                            self.pos.roomName, not not _.find(
                                self.room.find(FIND_MY_STRUCTURES), lambda s:
                                (s.structureType == STRUCTURE_EXTENSION or s.
                                 structureType == STRUCTURE_SPAWN) and s.energy
                                < s.energyCapacity))
                    if rwc_cache.get(self.pos.roomName):
                        self.targets.untarget(self, target_spawn_deposit)
                        return True
                    if self.creep.carry[
                            RESOURCE_ENERGY] < self.creep.carryCapacity:
                        self.memory.filling = True
                        return True
                    if not self.home.full_storage_use:
                        self.memory.running = "refill"
                        return self.refill_creeps()
                    if not self.pos.isEqualTo(target):
                        self.move_to(target)
                    return False
                else:
                    assert isinstance(target, StructureExtension)
                    if self.memory.running == "spawn_wait":
                        del self.memory.running
                    if target.energy >= target.energyCapacity:
                        self.targets.untarget(self, target_spawn_deposit)
                        return True
                    else:
                        if not self.pos.isNearTo(target):
                            self.move_to(target)
                            return False
                        del self.memory.nbm

                        result = self.creep.transfer(target, RESOURCE_ENERGY)

                        if result == OK:
                            if self.creep.carry[
                                    RESOURCE_ENERGY] > target.energyCapacity - target.energy:
                                volatile_cache.mem("extensions_filled").set(
                                    target.id, True)
                                if self.creep.carry[
                                        RESOURCE_ENERGY] + target.energy - target.energyCapacity > 0:
                                    self.targets.untarget(
                                        self, target_spawn_deposit)
                                    new_target = self.targets.get_new_target(
                                        self, target_spawn_deposit)
                                    if new_target and not self.pos.isNearTo(
                                            new_target):
                                        self.move_to(new_target)
                                else:
                                    self.harvest_energy(
                                    )  # Get a head start on this too!
                        elif result == ERR_FULL:
                            self.targets.untarget(self, target_spawn_deposit)
                            return True
                        else:
                            self.log(
                                "Unknown result from spawn_fill-creep.transfer({}): {}",
                                target, result)
                            self.targets.untarget(self, target_spawn_deposit)
                            return True
                        return False

            if self.home.full_storage_use and self.memory.role == role_spawn_fill_backup \
                    and self.home.carry_mass_of(role_tower_fill) + self.home.carry_mass_of(role_spawn_fill) \
                            >= self.home.get_target_total_spawn_fill_mass():
                self.memory.role = role_builder
                return building.Builder.run(self)
            elif self.memory.role == role_spawn_fill_backup:
                if _.find(self.room.building.get_construction_targets(),
                          lambda s: s.structureType == STRUCTURE_EXTENSION
                          ) or self.home.upgrading_deprioritized():
                    self.memory.running = role_builder
                    return building.Builder.run(self)
                else:
                    self.memory.running = role_upgrader
                    return upgrading.Upgrader.run(self)
            elif not self.home.full_storage_use or self.home.room.storage.storeCapacity <= 0:
                self.memory.running = "refill"
                return self.refill_creeps()
            elif self.creep.carry[RESOURCE_ENERGY] < self.creep.carryCapacity:
                self.memory.filling = True
                return self.harvest_energy()
        return False
예제 #10
0
    def refill_creeps(self):
        # type: () -> bool
        if not self.creep.carry[RESOURCE_ENERGY]:
            self.memory.filling = True
            return True
        target = cast(Union[Creep, Structure, None],
                      self.targets.get_new_target(self, target_refill))
        if target:
            full = robjs.capacity(
                target) and robjs.energy(target) >= robjs.capacity(target)
            if full:
                self.targets.untarget(self, target_refill)
                target = self.targets.get_new_target(self, target_refill)
        if target:
            if not self.pos.isNearTo(target):
                self.move_to(target)
                if Game.cpu.bucket >= 4000:
                    other = _.find(
                        self.home.find_in_range(FIND_MY_STRUCTURES, 1,
                                                self.pos), lambda c:
                        (c.energyCapacity and c.energy < c.energyCapacity) or
                        (c.storeCapacity and _.sum(c.store) < c.storeCapacity))
                    if not other:
                        other = _.find(
                            self.home.find_in_range(FIND_MY_CREEPS, 1,
                                                    self.pos),
                            lambda c: c.name != self.name and
                            (c.memory.role == role_builder or c.memory.role ==
                             role_upgrader) and _.sum(c.carry
                                                      ) < c.carryCapacity)
                    if other:
                        result = self.creep.transfer(cast(Structure, other),
                                                     RESOURCE_ENERGY)
                        if result == ERR_NOT_ENOUGH_RESOURCES:
                            self.memory.filling = True
                            return True
                        elif result != OK:
                            self.log(
                                "Unknown result from passingby refill.transfer({}): {}",
                                other, result)
                    return False

            latched = False
            target_creep = cast(Creep, target)
            if self.creep.hasActiveBodyparts(
                    WORK
            ) and target_creep.memory and not target_creep.memory.filling:
                # Let's latch on and work on whatever they're working on
                role = target_creep.memory.role
                result = None
                latched_target = None
                if role == role_builder:
                    sc_last_action = target_creep.memory.la
                    if sc_last_action == "r":
                        latched_target = cast(
                            Structure,
                            self.targets.get_existing_target(
                                target_creep, target_repair))
                        if latched_target:
                            result = self.creep.repair(latched_target)
                    elif sc_last_action == "c":
                        latched_target = cast(
                            ConstructionSite,
                            self.targets.get_existing_target(
                                target_creep, target_construction))
                        if latched_target:
                            result = self.creep.build(latched_target)
                    elif sc_last_action == "b":
                        latched_target = cast(
                            Structure,
                            self.targets.get_existing_target(
                                target_creep, target_big_repair))
                        if latched_target:
                            result = self.creep.repair(latched_target)
                elif role == role_upgrader:
                    latched_target = self.home.room.controller
                    result = self.creep.upgradeController(latched_target)
                if result is not None:
                    if result == OK:
                        latched = True
                    elif result == ERR_NOT_IN_RANGE:
                        self.basic_move_to(latched_target)

            if Game.cpu.bucket >= 8000 and target_creep.carry:
                min_cap = 0
                other = target_creep
                for obj in cast(
                        List[Dict[str, Creep]],
                        self.home.look_for_in_area_around(
                            LOOK_CREEPS, self.pos, 1)):
                    creep = obj[LOOK_CREEPS]
                    if (creep.memory.role == role_builder or creep.memory.role == role_upgrader) \
                            and creep.name != self.name:
                        empty_percent = (creep.carryCapacity - _.sum(
                            creep.carry)) / creep.carryCapacity
                        if empty_percent > min_cap:
                            other = creep
                            min_cap = empty_percent
                for obj in cast(
                        List[Dict[str, Structure]],
                        self.home.look_for_in_area_around(
                            LOOK_STRUCTURES, self.pos, 1)):
                    structure = obj[LOOK_STRUCTURES]
                    if structure.structureType == STRUCTURE_EXTENSION or structure.structureType == STRUCTURE_SPAWN:
                        structure = cast(
                            Union[StructureSpawn, StructureExtension],
                            structure)
                        empty_percent = 0.1 * (
                            structure.energyCapacity -
                            structure.energy) / structure.energyCapacity
                        if empty_percent > 0.1 and empty_percent > min_cap:
                            other = structure
                            min_cap = empty_percent
                if other != target:
                    result = self.creep.transfer(other, RESOURCE_ENERGY)
                    if result != OK:
                        self.log(
                            "Unknown result from passingby refill.transfer({}): {}",
                            other, result)
                    return False
            result = self.creep.transfer(target, RESOURCE_ENERGY)

            if result == OK:
                target_empty = robjs.capacity(target) - robjs.energy(target)
                if not latched and self.creep.carry[
                        RESOURCE_ENERGY] > target_empty:
                    volatile_cache.mem("extensions_filled").set(
                        target.id, True)
                    if self.creep.carry[RESOURCE_ENERGY] - target_empty > 0:
                        self.targets.untarget(self, target_refill)
                        new_target = self.targets.get_new_target(
                            self, target_refill)
                        if new_target and not self.pos.isNearTo(new_target):
                            self.move_to(new_target)
            elif result == ERR_FULL:
                if not latched:
                    self.targets.untarget(self, target_refill)
                    return True
            else:
                self.log("Unknown result from refill.transfer({}): {}", target,
                         result)
                self.targets.untarget(self, target_refill)
            return False
        else:
            self.go_to_depot()
            if not self.home.spawn:
                return False
            # haha, total hack...
            if not self.home.spawn.spawning and self.home.get_next_role(
            ) is None:
                self.home.mem[
                    rmem_key_planned_role_to_spawn] = generate_role_obj(
                        self.home)
            else:
                v = volatile_cache.volatile()
                if v.has("refills_idle"):
                    idle = v.get("refills_idle") + 1
                else:
                    idle = 1
                if idle >= 3:
                    role = self.home.get_next_role()
                    if not role or (
                        (role[roleobj_key_role] == role_hauler
                         or role[roleobj_key_role] == role_spawn_fill) and
                        (self.home.get_target_builder_work_mass()
                         or self.home.get_target_upgrader_work_mass())
                    ) or idle >= 7:
                        self.home.mem[
                            rmem_key_planned_role_to_spawn] = generate_role_obj(
                                self.home)
                        v.set("refills_idle", -Infinity)
                else:
                    v.set("refills_idle", idle)
예제 #11
0
def find_new_target_refill_destination(targets, creep):
    # type: (TargetMind, RoleBase) -> Optional[str]
    best_priority = Infinity
    best_id = None
    stealing_from = None
    structures = _.filter(
        creep.home.find(FIND_MY_STRUCTURES), lambda s:
        (s.structureType == STRUCTURE_EXTENSION or s.structureType ==
         STRUCTURE_SPAWN or s.structureType == STRUCTURE_CONTAINER or s.
         structureType == STRUCTURE_TOWER) and s.energy < s.energyCapacity)
    creeps = _.filter(
        creep.home.creeps, lambda c:
        (c.memory.role == role_upgrader or c.memory.role == role_builder
         ) and c.carry.energy < c.carryCapacity)
    extra = creep.home.get_extra_fill_targets()
    for structure in structures.concat(extra).concat(creeps):
        structure_id = structure.id
        if volatile_cache.mem("extensions_filled").has(structure_id):
            continue
        current_carry = targets.workforce_of(target_spawn_deposit, structure_id) \
                        + targets.workforce_of(target_refill, structure_id)
        empty = ((structure.energyCapacity or structure.carryCapacity
                  or structure.storeCapacity) -
                 ((structure.store and _.sum(structure.store.energy)) or
                  (structure.carry and _.sum(structure.carry.energy))
                  or structure.energy or 0))
        empty_percent = empty / (structure.energyCapacity or structure.carryCapacity or structure.storeCapacity) \
                        * 30
        if empty <= 0 or (empty <= 2 and not structure.structureType):
            continue
        distance = movement.chebyshev_distance_room_pos(
            structure.pos, creep.creep.pos)
        priority = distance - empty_percent
        if structure.memory and not structure.memory.filling:
            priority -= 15
        elif structure.structureType == STRUCTURE_CONTAINER:
            priority -= 40
        elif structure.structureType:
            priority -= 25
        if priority < best_priority:
            max_work_mass = empty / 50
            if not current_carry or current_carry < max_work_mass:
                best_priority = priority
                best_id = structure_id
                stealing_from = None
            else:
                targeting = targets.reverse_targets[target_refill][
                    structure_id]
                if len(targeting):
                    for name in targeting:
                        if not Game.creeps[
                                name] or movement.chebyshev_distance_room_pos(
                                    Game.creeps[name].pos,
                                    structure.pos) > distance * 1.5:
                            # If we're at least 1.5x closer than them, let's steal their place.
                            best_priority = priority
                            best_id = structure_id
                            stealing_from = name
                            break
    if stealing_from is not None:
        targets.unregister_name(stealing_from, target_refill)

    return best_id