Пример #1
0
    def run(self):
        claim_flag = self.targets.get_new_target(self, target_single_flag,
                                                 CLAIM_LATER)
        if not claim_flag:
            self.memory.last_role = self.memory.role
            self.memory.role = role_recycling
            return
        if self.pos.roomName != claim_flag.pos.roomName:
            target = claim_flag.pos
            if 'checkpoint' not in self.memory or \
                            movement.chebyshev_distance_room_pos(self.memory.checkpoint, self.pos) > 50:
                self.memory.checkpoint = self.pos

            opts = {'range': 15}
            if self.creep.getActiveBodyparts(MOVE) >= len(
                    self.creep.body) * 5 / 7:
                opts.ignore_swamp = True
                opts.use_roads = False
            elif self.creep.getActiveBodyparts(MOVE) >= len(
                    self.creep.body) / 2:
                opts.use_roads = False
            self.follow_military_path(
                _.create(RoomPosition.prototype, self.memory.checkpoint),
                target, opts)
            return False

        target = self.creep.room.controller
        if not target:
            self.log("ERROR: Claim can't find controller in room {}!".format(
                self.creep.room.name))
            self.targets.untarget_all(self)
            return True

        if target.my:
            self.memory.home = self.pos.roomName
            self.targets.untarget_all(self)
            # I guess we can try and claim something else, if we have the life? otherwise this will go and activate the
            # recycle code.
            return True

        if not self.pos.isNearTo(target):
            self.move_to(target)
            return False

        if target.owner:
            self.creep.attackController(target)
        else:
            self.creep.claimController(target)
        room = self.hive.get_room(target.pos.roomName)
        room.mem.sponsor = self.home.name
        if _.get(
                flags.find_flags(room, CLAIM_LATER)[0], 'memory.prio_walls',
                False):
            room.mem.prio_walls = True
        if _.get(
                flags.find_flags(room, CLAIM_LATER)[0], 'memory.prio_spawn',
                False):
            room.mem.prio_spawn = True
Пример #2
0
def find_new_target_owned_typed_flag(targets, creep, args):
    # type: (TargetMind, RoleBase, Union[Tuple[int, Union[RoomPosition, RoomObject, None]], None, int]) -> Optional[str]
    pos = creep.pos
    if _.isNumber(args):
        flag_type = cast(int, args)
    elif args != undefined:
        flag_type, center_pos = cast(
            Tuple[int, Union[RoomPosition, RoomObject, None]], args)
        pos = cast(RoomObject, center_pos).pos or cast(RoomPosition,
                                                       center_pos)
    else:
        raise ValueError(
            "_find_closest_home_flag called for creep {} without second parameter!"
            .format(creep))
    closest_flag = None
    closest_distance = Infinity
    for flag in flags.find_flags(creep.home, flag_type):
        flag_id = "flag-{}".format(flag.name)
        current = targets.targets[target_home_flag][flag_id]
        if not current or current < 1:
            distance = movement.distance_squared_room_pos(pos, flag.pos)
            if distance < closest_distance:
                closest_distance = distance
                closest_flag = flag_id
    return closest_flag
Пример #3
0
 def check_move_parts(self):
     if not self.creep.hasActiveBodyparts(MOVE) \
             and not len(flags.find_flags(self.room.name, RANGED_DEFENSE)) \
             and not _.some(self.room.find(FIND_CREEPS), lambda creep: creep.hasActiveBodyparts(HEAL)):
         self.creep.suicide()
         self.home.check_all_creeps_next_tick()
         return False
Пример #4
0
    def run(self):
        reserve_flag = self.targets.get_new_target(self, target_reserve_now)

        if not reserve_flag:
            self.log("ReserveNow couldn't find controller to reserve.")
            self.recycle_me()
            return False

        if self.pos.roomName != reserve_flag.pos.roomName:
            self.follow_military_path(self.home.spawn.pos, reserve_flag.pos)
            return False

        controller = self.creep.room.controller

        if not self.pos.isNearTo(controller):
            self.move_to(controller)
            return False

        if controller.reservation and controller.reservation.username != self.creep.owner.username:
            self.log(
                "Remote reserve creep target owned by another player! {} has taken our reservation!",
                controller.reservation.username)
        if not controller.reservation or controller.reservation.ticksToEnd < 4998:
            if len(flags.find_flags(controller.room, CLAIM_LATER)):
                # claim this!
                self.creep.claimController(controller)
                controller.room.memory[rmem_key_sponsor] = self.home.name
            self.creep.reserveController(controller)
Пример #5
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
Пример #6
0
    def run(self):
        target = self.targets.get_new_target(self, target_single_flag,
                                             TD_H_H_STOP)
        if not target:
            if len(flags.find_flags(self.home, RAID_OVER)):
                self.memory.last_role = self.memory.role
                self.memory.role = role_recycling
            else:
                self.log("TowerDrainHealer has no target!")
                self.go_to_depot()
            return
        if not self.pos.isEqualTo(target):
            self.follow_military_path(self.home.spawn.pos, target)

        autoactions.instinct_do_heal(self)
Пример #7
0
 def should_reserve(self, room_name):
     # type: (str) -> bool
     if self.room.room.energyCapacityAvailable < (BODYPART_COST[CLAIM] +
                                                  BODYPART_COST[MOVE]) * 2:
         return False
     if Memory.no_controller and Memory.no_controller[room_name]:
         return False
     flag_list = flags.find_flags(room_name, REMOTE_MINE)
     if _.some(flag_list, is_sk):
         return False
     if _.some(flag_list,
               lambda f: f.name in Memory.flags and f.memory.do_reserve):
         return True
     if len(flag_list) < 2:
         return False
     return True
Пример #8
0
 def find_depot(self):
     # type: () -> RoomPosition
     depots = flags.find_flags(self.home, DEPOT)
     if len(depots):
         depot = depots[0].pos
     else:
         self.log("WARNING: No depots found in {}!".format(self.home.name))
         self.home.building.place_depot_flag()
         depots = flags.find_flags_global(DEPOT)
         if len(depots):
             depot = _.min(
                 depots, lambda d: movement.chebyshev_distance_room_pos(
                     self.pos, d.pos)).pos
         elif self.home.spawn:
             depot = self.home.spawn.pos
         else:
             depot = movement.find_an_open_space(self.home.name)
     return depot
Пример #9
0
    def run_dedicated_upgrading(self, link):
        controller = self.home.room.controller

        if self.memory.set_till > Game.time:
            result = self.upgrade(controller)
            if result == ERR_NOT_IN_RANGE:
                del self.memory.set_till
            else:
                result = self.harvest_from(link)
                if result == ERR_NOT_IN_RANGE:
                    del self.memory.set_till
                else:
                    return

        if not self.home.upgrading_deprioritized(
        ) or self.creep.room.controller.ticksToDowngrade <= 5000:
            self.upgrade(controller)
        elif Game.time % 15 == 2 or self.memory.set_till == Game.time:
            if not self.home.get_target_upgrader_work_mass(
            ) or not self.home.spawn:
                if len(self.creep.body) > 3 and spawning.find_base_type(
                        self) == creep_base_worker:
                    self.memory.role = role_builder
                    return False
                elif self.home.spawn:
                    self.memory.role = role_recycling
                    self.memory.last_role = role_upgrader
                    return False
        if Game.time % 15 == 7 or self.memory.set_till == Game.time:
            if self.home.overprioritize_building():
                # TODO: do this via push immediately after controller upgrade, instead of polling
                if len(self.creep.body) > 3 and spawning.find_base_type(
                        self) == creep_base_worker:
                    self.memory.role = role_builder
                    return False
            if self.home.rcl >= 8 and self.home.role_count(role_upgrader) > 1 \
                    and self.home.work_mass_of(role_upgrader) > self.home.get_target_upgrader_work_mass():
                needed = self.home.get_target_upgrader_work_mass()
                any_big_enough = _.find(
                    self.home.creeps, lambda c: c.memory.role == role_upgrader
                    and c.getBodyparts(WORK) >= needed)
                if any_big_enough:
                    for creep in self.home.creeps:
                        if creep.memory.role == role_upgrader and creep.name != any_big_enough.name:
                            creep.suicide()
                    self.home.check_all_creeps_next_tick()

        self.harvest_from(link)

        spot = self.targets.get_new_target(self, target_home_flag,
                                           UPGRADER_SPOT)
        if spot:
            if self.pos.isEqualTo(spot.pos):
                self.memory.set_till = Game.time + 30
            else:
                self.move_to(spot)
        else:
            if self.creep.ticksToLive < 50:
                self.creep.suicide()
                self.home.check_all_creeps_next_tick()
                return
            self.log("WARNING: Not enough set upgrader spots in {}".format(
                self.memory.home))
            if Game.time % 10 == 0 and not volatile_cache.setmem('upgraders_to_suicide_checked').has(self.home.name) \
                    and len(flags.find_flags(self.home, UPGRADER_SPOT)) >= 3 and \
                            self.home.work_mass_of(role_upgrader) > self.home.get_target_upgrader_work_mass():
                upgraders = self.home.rt_map[role_upgrader]
                if upgraders:
                    small = None
                    for name, replacement_time in upgraders:
                        creep = Game.creeps[name]
                        if creep:
                            if replacement_time <= Game.time:
                                creep.suicide()
                                self.home.check_all_creeps_next_tick()
                                break
                            elif creep.getBodyparts(WORK) < self.home.get_upgrader_size() \
                                    * (2 if self.home.get_variable_base(role_upgrader) is creep_base_full_upgrader
                                       else 1):
                                small = creep
                    else:
                        if small is not None:
                            small.suicide()
                            self.home.check_all_creeps_next_tick()
                volatile_cache.setmem('upgraders_to_suicide_checked').add(
                    self.home.name)

            available_positions = self.memory.controller_positions
            if not available_positions or (Game.time +
                                           self.creep.ticksToLive) % 25:
                available_positions = []
                for x in range(link.pos.x - 1, link.pos.x + 2):
                    for y in range(link.pos.y - 1, link.pos.y + 2):
                        if x != link.pos.x or y != link.pos.y:
                            if abs(x - controller.pos.x) <= 3 and abs(y - controller.pos.y) <= 3 \
                                    and Game.map.getTerrainAt(x, y, self.pos.roomName) != 'wall':
                                available_positions.append("{},{}".format(
                                    x, y))
                self.memory.controller_positions = available_positions

            if self.memory.get_near_controller:
                if self.creep.carry[
                        RESOURCE_ENERGY] > self.creep.carryCapacity * 0.5:
                    if self.pos.isNearTo(
                            link) or not self.pos.isNearTo(controller):
                        if self.home.role_count(role_upgrader) < 4:
                            basic_moved = self.basic_move_to(controller)
                        else:
                            self_empty = self.creep.carryCapacity - self.carry_sum(
                            )
                            basic_moved = self.force_basic_move_to(
                                controller, lambda other:
                                (other.carryCapacity - _.sum(other.carry)
                                 ) > self_empty)
                        if not basic_moved:
                            self.move_to(controller)
                    return
                else:
                    del self.memory.get_near_controller

            if not self.pos.inRangeTo(controller,
                                      3) or not self.pos.isNearTo(link):
                a_creep_with_energy = None
                for pos in available_positions:
                    x, y = split_pos_str(pos)
                    that_creep = cast(
                        Optional[Creep],
                        _.find(self.home.look_at(LOOK_CREEPS, x, y)))
                    if not that_creep:
                        self.move_to(
                            __new__(RoomPosition(x, y, self.home.name)))
                        break
                    elif that_creep.carry[RESOURCE_ENERGY] >= that_creep.carryCapacity * 0.5 \
                            and that_creep.memory.role == role_upgrader and not that_creep.memory.get_near_controller:
                        a_creep_with_energy = that_creep
                else:
                    if self.creep.carry[
                            RESOURCE_ENERGY] < self.creep.carryCapacity * 0.25:
                        closest_full = cast(
                            Optional[Dict[str, Creep]],
                            _.find(
                                self.room.look_for_in_area_around(
                                    LOOK_CREEPS, self.pos, 1),
                                lambda c: c.creep.memory.role == role_upgrader
                                and c.creep.carry.energy >= c.creep.
                                carryCapacity * 0.75 and c.creep.pos.inRangeTo(
                                    link.pos, 1)))
                        if closest_full:
                            closest_full[LOOK_CREEPS].move(
                                closest_full[LOOK_CREEPS].pos.getDirectionTo(
                                    self.pos))
                            self.creep.move(
                                self.pos.getDirectionTo(
                                    closest_full[LOOK_CREEPS].pos))
                        elif a_creep_with_energy:
                            a_creep_with_energy.memory.get_near_controller = True
                            self.creep.move(self.pos.getDirectionTo(link.pos))
                        elif not self.pos.inRangeTo(controller, 3):
                            self.move_to(controller)
                    elif not self.pos.inRangeTo(controller, 3):
                        self.move_to(controller)
                return

            if not _.find(
                    self.room.look_for_in_area_around(LOOK_CREEPS, self.pos,
                                                      1),
                    lambda c: c.creep.memory.role != role_upgrader and c.creep.
                    memory.role != role_link_manager):
                return  # No need to shuffle around if there's no one to move around for

            if len(available_positions):
                target_x, target_y = split_pos_str(
                    available_positions[(Game.time + 2) %
                                        len(available_positions)])
                self.basic_move_to(
                    __new__(RoomPosition(target_x, target_y,
                                         self.pos.roomName)))
Пример #10
0
    def run(self):
        if self.creep.ticksToLive > 1450 and not (self.memory.boosted >= 2):
            if 'boosted' not in self.memory:
                self.memory.boosted = 0
            if self.boost():
                return False

        hostiles_nearby = defense.stored_hostiles_near(self.pos.roomName)
        if self.creep.hits < self.creep.hitsMax or \
                (len(hostiles_nearby)
                 and _.find(hostiles_nearby,
                            lambda h: movement.chebyshev_distance_room_pos(
                                self.pos, positions.deserialize_xy_to_pos(h.pos, h.room)) <= 3)):
            self.creep.heal(self.creep)

        marker_flag = cast(Flag, self.targets.get_new_target(self, target_single_flag, RANGED_DEFENSE))
        if marker_flag is None:
            if self.pos.roomName == self.home.name and len(flags.find_flags(self.home, RAID_OVER)):
                if len(hostiles_nearby) or self.creep.hits < self.creep.hitsMax:
                    self.creep.heal(self.creep)
                return False
            else:
                marker_flag = cast(Flag, {'pos': self.find_depot()})

        if len(hostiles_nearby):
            if _.find(hostiles_nearby, lambda h: h.offensive and movement.chebyshev_distance_room_pos(
                    self.pos, positions.deserialize_xy_to_pos(h.pos, h.room)) <= 5):
                hostiles_nearby = _.filter(hostiles_nearby, 'offensive')
            nearby = _.filter(hostiles_nearby,
                              lambda h: movement.chebyshev_distance_room_pos(
                                  self.pos, positions.deserialize_xy_to_pos(h.pos, h.room)) <= 5)
            closest = _.min(
                hostiles_nearby,
                lambda h: movement.chebyshev_distance_room_pos(self.pos, positions.deserialize_xy_to_pos(h.pos, h.room))
                          - (5 if h.offensive else 0)
            )
            closest_pos = positions.deserialize_xy_to_pos(closest.pos, closest.room)
            harmless = not _.some(nearby, lambda x: x.attack or x.ranged)
            ranged = _.some(nearby, lambda x: x.ranged and x.ranged > x.attack)
            only_ranged = not _.some(nearby,
                                     lambda h: movement.chebyshev_distance_room_pos(
                                         self.pos, positions.deserialize_xy_to_pos(h.pos, h.room)) <= 4 and h.attack)
            mass_attack = _.some(nearby, lambda h: movement.chebyshev_distance_room_pos(
                self.pos, positions.deserialize_xy_to_pos(h.pos, h.room)) <= 1
                                                   and h.room == self.pos.roomName)
        else:
            enemies = self.room.find(FIND_HOSTILE_CREEPS)
            if len(enemies):
                if self.pos.roomName != marker_flag.pos.roomName:
                    enemies = _.filter(enemies, lambda h: hostile_utils.is_offensive(h)
                                                          and hostile_utils.not_sk(h))
                else:
                    any_offensive = _.find(enemies, hostile_utils.is_offensive)
                    if any_offensive:
                        enemies = _.filter(enemies, lambda h: hostile_utils.is_offensive(h)
                                                              and hostile_utils.not_sk(h))
                    else:
                        enemies = _.filter(enemies, hostile_utils.not_sk)
            if len(enemies):
                closest = _.min(enemies, lambda h: movement.chebyshev_distance_room_pos(self.pos, h.pos))
                closest_pos = closest.pos
                nearby = _.filter(enemies, lambda h: movement.chebyshev_distance_room_pos(h.pos, self.pos) <= 5)
                harmless = not _.some(nearby,
                                      lambda h: h.hasActiveBodyparts(ATTACK) or h.hasActiveBodyparts(RANGED_ATTACK)) \
                           and self.creep.hits >= self.creep.hitsMax
                ranged = _.some(nearby, lambda h: h.hasActiveBodyparts(RANGED_ATTACK)
                                                  and h.getActiveBodyparts(RANGED_ATTACK)
                                                      > h.getActiveBodyparts(ATTACK))
                only_ranged = not _.some(nearby,
                                         lambda h:
                                         movement.chebyshev_distance_room_pos(self.pos, h.pos) <= 4
                                         and h.hasBodyparts(ATTACK))
                mass_attack = _.some(nearby, lambda h: self.pos.isNearTo(h.pos) and self.pos.roomName == h.pos.roomName)
            else:
                closest = None
                closest_pos = None
                harmless = False
                ranged = False
                only_ranged = True
                mass_attack = False

        if not closest or (closest_pos.roomName != self.pos.roomName
                           and movement.chebyshev_distance_room_pos(closest_pos, self.pos) > 10):
            del self.memory.last_enemy_pos
            # self.creep.say("🐾 💚 🐾", True)
            if self.pos.roomName == marker_flag.pos.roomName and self.creep.hits >= self.creep.hitsMax:
                hurt = cast(List[Creep], self.room.find(PYFIND_HURT_CREEPS))
                if len(hurt):
                    damaged = _.min(hurt, lambda p: movement.chebyshev_distance_room_pos(p.pos, self.pos))
                    if self.pos.isNearTo(damaged):
                        self.creep.heal(damaged)
                    else:
                        self.move_to(damaged, _MOVE_TO_OPTIONS)
                    return False
            # TODO: turn this into part of a large generic cross-room movement module
            if not self.pos.isEqualTo(marker_flag.pos):
                distance = movement.chebyshev_distance_room_pos(self.pos, marker_flag.pos)
                if distance > 50:
                    if 'checkpoint' not in self.memory or \
                                    movement.chebyshev_distance_room_pos(self.memory.checkpoint, self.pos) > 50:
                        self.memory.checkpoint = self.pos
                    if self.memory.next_ppos \
                            and movement.chebyshev_distance_room_pos(self.pos, self.memory.next_ppos) > 10 \
                            and not hostile_utils.enemy_owns_room(self.pos.roomName):
                        self.memory.checkpoint = self.pos
                        del self.memory.next_ppos
                        del self.memory.off_path_for
                        del self.memory.lost_path_at
                        del self.memory._move

                    if hostile_utils.enemy_owns_room(self.memory.checkpoint.roomName):
                        self.memory.checkpoint = self.home.spawn or movement.find_an_open_space(self.home.name)

                    self.follow_military_path(_.create(RoomPosition.prototype, self.memory.checkpoint),
                                              marker_flag.pos, {'range': 1})
                    self.creep.say("G1")
                elif distance >= 1:
                    self.move_to(marker_flag, _MOVE_TO_OPTIONS)
                    self.creep.say("G2")
                else:
                    self.basic_move_to(marker_flag)
                    self.creep.say("G3")
            return False
        closest_creep = cast(Creep, Game.getObjectById(closest.id))
        min_distance = movement.chebyshev_distance_room_pos(closest_pos, self.pos)
        if Game.time % 2:
            self.creep.say("{},{}: {}".format(closest_pos.x, closest_pos.y, min_distance))
        else:
            self.creep.say("🐾 🏹 🐾", True)
        fatigue = (closest_creep and (closest_creep.fatigue or not closest_creep.hasActiveBodyparts(MOVE)))
        if self.memory.healing:
            self.memory.healing = self_damaged = self.creep.hits < self.creep.hitsMax
        else:
            # If 1/4 of our ranged attack parts are dead.
            total_ra = self.creep.getBodyparts(RANGED_ATTACK)
            alive_ra = self.creep.getActiveBodyparts(RANGED_ATTACK)
            self.memory.healing = self_damaged = (total_ra < 10 and alive_ra < total_ra / 2) or alive_ra < total_ra / 3

        if closest_pos.roomName == self.pos.roomName and min_distance <= 3:
            if mass_attack:
                self.creep.rangedMassAttack()
            else:
                self.creep.rangedAttack(closest_creep)

        if (min_distance <= 6) and self.pos.roomName != closest_pos.roomName:
            self.memory.countdown = (self.memory.countdown or 10) - 1
            if self.memory.countdown <= 0:
                if self.memory.countdown == 0:
                    self.memory.countdown -= 1
                if self.memory.countdown <= 5:
                    del self.memory.countdown
                self.move_to(marker_flag, _MOVE_TO_OPTIONS)
            return
        if ranged and self_damaged:
            safe_distance = 5
        elif ranged and only_ranged:
            safe_distance = 0
        else:
            safe_distance = 3
        should_run = (not _.some(self.pos.lookFor(LOOK_STRUCTURES), {'structureType': STRUCTURE_RAMPART, 'my': True})
                      and not harmless
                      and (min_distance < safe_distance or (min_distance == safe_distance and not fatigue)))

        should_approach = not should_run and (harmless or min_distance > safe_distance)
        if should_approach:
            # NOTE: this depends on our custom moveTo function not checking for instanceof RoomPosition
            self.move_to(closest_pos, _MOVE_TO_OPTIONS)
        elif should_run:
            kiting_path = errorlog.try_exec(
                'kiting-offense',
                kiting_away_raw_path,
                lambda pos: "Error calculating or moving by kiting path at pos {}.".format(pos),
                self.pos,
                [{
                    'pos': positions.deserialize_xy_to_pos(h.pos, h.room),
                    'range': 10,
                } for h in hostiles_nearby],
                marker_flag
            )
            if kiting_path is True:
                # errored
                self.creep.say("Err")
                self.go_to_depot()
            elif len(kiting_path):
                self.creep.move(self.pos.getDirectionTo(kiting_path[0]))
            else:
                self.log("WARNING: kiting offense has no path at position {}!".format(self.pos))
Пример #11
0
    def run(self):
        target_flag = cast(
            Flag,
            self.targets.get_existing_target(self,
                                             target_support_builder_wall))
        if not target_flag:
            if not self.memory.idle_for:
                self.log("WARNING: Support builder has no target.")
                self.memory.idle_for = 1
            else:
                self.memory.idle_for += 1
                if self.memory.idle_for >= 10:
                    self.log(
                        "Support builder idle for 10 ticks, committing suicide."
                    )
                    self.creep.suicide()
            return

        if self.creep.hits < self.creep.hitsMax:
            if not len(flags.find_flags(self.room.name, RANGED_DEFENSE)) \
                    or not _.some(self.room.find(FIND_CREEPS), lambda creep: creep.hasActiveBodyparts(HEAL)):
                if self.home.defense.healing_capable() and (
                        self.pos.roomName != self.home.name or self.pos.x > 40
                        or self.pos.y > 40 or self.pos.x < 10
                        or self.pos.y < 10):
                    self.follow_energy_path(target_flag, self.home.spawn)
                    return
                elif not self.creep.getActiveBodyparts(WORK):
                    self.creep.suicide()
                    return
        if self.memory.container_pos:
            sitting_target = positions.deserialize_xy_to_pos(
                self.memory.container_pos, target_flag.pos.roomName)
        else:
            sitting_target = target_flag.pos
        distance_away = self.pos.getRangeTo(target_flag)
        if distance_away > 2:
            if self.pos.roomName == target_flag.pos.roomName:
                if distance_away <= 3:
                    total_mass = self.home.mining.get_ideal_miner_workmass_for(
                        target_flag)
                    if self.creep.getActiveBodyparts(WORK) >= total_mass:
                        other_miner = cast(
                            Optional[Dict[str, Creep]],
                            _.find(
                                self.room.look_for_in_area_around(
                                    LOOK_CREEPS, target_flag.pos,
                                    1), lambda c: c.creep.my and c.creep.memory
                                .role == role_support_builder and c.creep.
                                ticksToLive < self.creep.ticksToLive))
                        if other_miner:
                            other_miner[LOOK_CREEPS].suicide()
                            del self.memory._move
                self.move_to(sitting_target)
            else:
                self.follow_energy_path(self.home.spawn, sitting_target)
            return False
        elif distance_away > 1:
            creep = cast(
                Optional[Creep],
                _.find(self.room.look_at(LOOK_CREEPS, sitting_target),
                       lambda c: c.my))
            if creep and creep.memory.role == role_support_builder and creep.ticksToLive > 100:
                self.memory.container_pos = None
                sitting_target = target_flag.pos
            self.move_to(sitting_target)
            return False
        if 'container_pos' not in self.memory:
            container = _.find(
                self.room.find_in_range(FIND_STRUCTURES, 1, target_flag.pos),
                lambda s: s.structureType == STRUCTURE_CONTAINER)
            if container:
                self.memory.container_pos = container.pos.x | (
                    container.pos.y << 6)
            else:
                biggest_pile = _.max(
                    self.room.find_in_range(FIND_DROPPED_RESOURCES, 1,
                                            target_flag.pos),
                    lambda e: e.amount)
                if biggest_pile != -Infinity:
                    self.memory.container_pos = biggest_pile.pos.x | (
                        biggest_pile.pos.y << 6)
                else:
                    self.memory.container_pos = None
        if Game.time % 10 == 0 and self.memory.container_pos is not None:
            this_pos_to_check = self.pos.x | self.pos.y << 6  # Transcrypt does this incorrectly in an if statement.
            if this_pos_to_check != self.memory.container_pos:
                pos = __new__(
                    RoomPosition(self.memory.container_pos & 0x3F,
                                 self.memory.container_pos >> 6 & 0x3F,
                                 self.pos.roomName))
                if _.find(
                        self.room.look_at(LOOK_CREEPS,
                                          pos), lambda c: c.my and c.memory.
                        role == role_support_builder and c.ticksToLive > 15):
                    self.memory.container_pos = self.pos.x | self.pos.y << 6
                else:
                    self.basic_move_to(pos)

        wall = cast(
            Structure,
            _.find(target_flag.pos.lookFor(LOOK_STRUCTURES),
                   lambda s: s.structureType != STRUCTURE_ROAD))
        if wall:
            result = self.creep.repair(wall)
        else:
            site = cast(
                ConstructionSite,
                _.find(target_flag.pos.lookFor(LOOK_CONSTRUCTION_SITES)))
            if not site:
                self.log("Remote mining source flag {} has no wall under it!",
                         target_flag.name)
                self.recalc(target_flag)
                return False
            result = self.creep.build(site)

        if Game.time % 50 == 5:
            self.recalc(target_flag)

        if result != OK and result != ERR_NOT_ENOUGH_RESOURCES:
            self.log("Unknown result from mining-creep.repair|build({}): {}",
                     wall, result)
            if result == ERR_NOT_IN_RANGE:
                self.recalc(target_flag)
        return False
Пример #12
0
    def run(self):
        source_flag = cast(
            Flag,
            self.targets.get_existing_target(self, target_support_miner_mine))
        if not source_flag:
            if not self.memory.idle_for:
                self.log("WARNING: Support miner has no target.")
                self.memory.idle_for = 1
            else:
                self.memory.idle_for += 1
                if self.memory.idle_for >= 10:
                    self.log(
                        "Support miner idle for 10 ticks, committing suicide.")
                    self.creep.suicide()
            return

        if self.creep.hits < self.creep.hitsMax:
            if not len(flags.find_flags(self.room.name, RANGED_DEFENSE)) \
                    or not _.some(self.room.find(FIND_CREEPS), lambda creep: creep.hasActiveBodyparts(HEAL)):
                if self.home.defense.healing_capable() and (
                        self.pos.roomName != self.home.name or self.pos.x > 40
                        or self.pos.y > 40 or self.pos.x < 10
                        or self.pos.y < 10):
                    self.follow_energy_path(source_flag, self.home.spawn)
                    return
                elif not self.creep.getActiveBodyparts(WORK):
                    self.creep.suicide()
                    return
        if self.memory.container_pos:
            sitting_target = positions.deserialize_xy_to_pos(
                self.memory.container_pos, source_flag.pos.roomName)
        else:
            sitting_target = source_flag.pos
        distance_away = self.pos.getRangeTo(source_flag)
        if distance_away > 2:
            if self.pos.roomName == source_flag.pos.roomName:
                if distance_away <= 3:
                    total_mass = self.home.mining.get_ideal_miner_workmass_for(
                        source_flag)
                    if self.creep.getActiveBodyparts(WORK) >= total_mass:
                        other_miner = cast(
                            Dict[str, Creep],
                            _.find(
                                self.room.look_for_in_area_around(
                                    LOOK_CREEPS, source_flag.pos,
                                    1), lambda c: c.creep.my and c.creep.memory
                                .role == role_support_miner and c.creep.
                                ticksToLive < self.creep.ticksToLive))
                        if other_miner:
                            other_miner[LOOK_CREEPS].suicide()
                            del self.memory._move
                self.move_to(sitting_target)
            else:
                self.follow_energy_path(self.home.spawn, sitting_target)
            return False
        elif distance_away > 1:
            creep = cast(
                Optional[Creep],
                _.find(self.room.look_at(LOOK_CREEPS, sitting_target),
                       lambda c: c.my))
            if creep and creep.memory.role == role_support_miner and creep.ticksToLive > 100:
                self.memory.container_pos = None
                sitting_target = source_flag.pos
            self.move_to(sitting_target)
            return False
        if 'container_pos' not in self.memory:
            container = _.find(
                self.room.find_in_range(FIND_STRUCTURES, 1, source_flag.pos),
                lambda s: s.structureType == STRUCTURE_CONTAINER)
            if container:
                self.memory.container_pos = container.pos.x | (
                    container.pos.y << 6)
            else:
                biggest_pile = _.max(
                    self.room.find_in_range(FIND_DROPPED_RESOURCES, 1,
                                            source_flag.pos),
                    lambda e: e.amount)
                if biggest_pile != -Infinity:
                    self.memory.container_pos = biggest_pile.pos.x | (
                        biggest_pile.pos.y << 6)
                else:
                    self.memory.container_pos = None
        if Game.time % 10 == 0 and self.memory.container_pos is not None:
            this_pos_to_check = self.pos.x | self.pos.y << 6  # Transcrypt does this incorrectly in an if statement.
            if this_pos_to_check != self.memory.container_pos:
                pos = __new__(
                    RoomPosition(self.memory.container_pos & 0x3F,
                                 self.memory.container_pos >> 6 & 0x3F,
                                 self.pos.roomName))
                if _.find(
                        self.room.look_at(LOOK_CREEPS,
                                          pos), lambda c: c.my and c.memory.
                        role == role_support_miner and c.ticksToLive > 15):
                    self.memory.container_pos = self.pos.x | self.pos.y << 6
                else:
                    self.basic_move_to(pos)

        sources_list = cast(List[Source],
                            source_flag.pos.lookFor(LOOK_SOURCES))
        if not len(sources_list):
            self.log("Remote mining source flag {} has no sources under it!",
                     source_flag.name)
            return False
        source = sources_list[0]

        # if Game.time % 3 == 2:
        #     ideal_work = source.energyCapacity / ENERGY_REGEN_TIME / HARVEST_POWER
        #     current_work = self.creep.getActiveBodyparts(WORK)
        #     extra_work = current_work - ideal_work
        #     if extra_work != 0:
        #         if extra_work < 0:
        #             current_work = _.sum(self.room.find_in_range(FIND_MY_CREEPS, 1, source_flag.pos),
        #                                  lambda c: c.memory.role == role_miner and c.getActiveBodyparts(WORK))
        #         if current_work > source.energy / (source.ticksToRegeneration - 1) / HARVEST_POWER:
        #             return False  # skip a tick, to spread it out
        result = self.creep.harvest(source)
        if result != OK and result != ERR_NOT_ENOUGH_RESOURCES:
            self.log("Unknown result from mining-creep.harvest({}): {}",
                     source, result)

        if self.creep.carryCapacity:
            if 'link' in self.memory:
                if self.memory.link is None:
                    return False
                else:
                    link = cast(StructureLink,
                                Game.getObjectById(self.memory.link))
                    if link is None or not self.pos.isNearTo(link):
                        del self.memory.link
                        return False
            else:
                all_possible_links = cast(
                    List[Union[StructureStorage, StructureLink]],
                    _.filter(
                        self.room.find(FIND_MY_STRUCTURES), lambda s:
                        (s.structureType == STRUCTURE_LINK or s.structureType
                         == STRUCTURE_STORAGE) and abs(
                             s.pos.x - source_flag.pos.x) <= 2 and abs(
                                 s.pos.y - source_flag.pos.y) <= 2))
                best_priority = 0  # 1-3
                best_spot = None
                link = None
                for x in range(source_flag.pos.x - 1, source_flag.pos.x + 2):
                    for y in range(source_flag.pos.y - 1,
                                   source_flag.pos.y + 2):
                        if movement.is_block_empty(self.room, x, y):
                            link_here = _.find(
                                all_possible_links, lambda s: abs(s.pos.x - x)
                                <= 1 and abs(s.pos.y - y) <= 1)
                            if link_here:
                                if not flags.look_for(
                                        self.room,
                                        __new__(
                                            RoomPosition(
                                                x, y, self.pos.roomName)),
                                        UPGRADER_SPOT):
                                    if _.find(
                                            self.room.look_at(
                                                LOOK_STRUCTURES, x,
                                                y), lambda s: s.structureType
                                            == STRUCTURE_RAMPART):
                                        priority_here = 3
                                    else:
                                        priority_here = 2
                                else:
                                    priority_here = 1
                                if priority_here > best_priority:
                                    best_priority = priority_here
                                    best_spot = x | y << 6
                                    link = link_here
                                if best_priority >= 3:
                                    break
                    if best_priority >= 3:
                        break
                if link:
                    self.memory.link = link.id
                    self.memory.container_pos = best_spot
                else:
                    self.memory.link = None
                return False
            if self.creep.carry[
                    RESOURCE_ENERGY] + self.creep.getActiveBodyparts(
                        WORK) > self.creep.carryCapacity:
                if link.structureType == STRUCTURE_LINK:
                    self.home.links.register_target_deposit(
                        link, self, self.creep.carry[RESOURCE_ENERGY], 1)
                self.creep.transfer(link, RESOURCE_ENERGY)

        return False
Пример #13
0
    def run(self):
        if 'goading' not in self.memory:
            self.memory.goading = False
        if self.memory.goading and self.creep.hits < self.creep.hitsMax / 2:
            self.memory.goading = False
            self.targets.untarget_all(self)
        if not self.memory.goading and self.creep.hits >= self.creep.hitsMax:
            self.memory.goading = True
            self.targets.untarget_all(self)
        goad_target = self.targets.get_new_target(self, target_single_flag,
                                                  TD_D_GOAD)
        if not goad_target:
            self.log("TowerDrainer has no target!")
            self.memory.last_role = self.memory.role
            self.memory.role = role_recycling
            return

        def set_max_avoid_regular_matrix(room_name, cost_matrix):
            # type: (str, PathFinder.CostMatrix) -> None
            if room_name == goad_target.pos.roomName:
                for x in range(0, 50):
                    for y in range(0, 50):
                        existing = cost_matrix.get(x, y)
                        if existing == 0:
                            terrain = Game.map.getTerrainAt(x, y, room_name)
                            if terrain[0] == 'p':
                                existing = 2
                            elif terrain[0] == 's':
                                existing = 10
                            else:
                                continue
                        cost_matrix.set(x, y, existing + 20)

        if self.memory.goading:
            if self.pos.isEqualTo(goad_target):
                pass
            elif movement.chebyshev_distance_room_pos(self.pos,
                                                      goad_target) < 50:
                self.move_to(goad_target,
                             {'costCallback': set_max_avoid_regular_matrix})
            else:
                self.follow_military_path(
                    self.home.spawn.pos, goad_target,
                    {'avoid_rooms': [goad_target.pos.roomName]})
        else:
            heal_target = self.targets.get_new_target(self,
                                                      target_single_flag2,
                                                      TD_H_D_STOP)
            if not heal_target:
                if len(flags.find_flags(self.home, RAID_OVER)):
                    self.recycle_me()
                else:
                    self.go_to_depot()
                return
            if self.pos.isEqualTo(heal_target):
                pass
            elif movement.chebyshev_distance_room_pos(self.pos,
                                                      heal_target) < 50:
                # TODO: make a military moveTo method like this
                self.move_to(heal_target,
                             {'costCallback': set_max_avoid_regular_matrix})
            else:
                self.follow_military_path(
                    self.home.spawn.pos, heal_target,
                    {'avoid_rooms': [goad_target.pos.roomName]})

        autoactions.instinct_do_attack(self)
Пример #14
0
    def run(self):
        target = cast(
            Flag,
            self.targets.get_new_target(self, target_single_flag,
                                        REAP_POWER_BANK))
        if not target:
            if len(flags.find_flags(
                    self.home, RAID_OVER)) or self.creep.ticksToLive < 100:
                self.recycle_me()
            else:
                self.log("PowerAttack has no target!")
                self.go_to_depot()
            return
        if self.memory.filling and self.carry_sum(
        ) >= self.creep.carryCapacity:
            self.memory.filling = False

        if not self.memory.filling and self.carry_sum() <= 0:
            self.memory.filling = True

        storage = self.home.room.storage
        if self.memory.filling:
            if self.pos.roomName != target.pos.roomName:
                self.follow_military_path(self.home.spawn.pos, target.pos)
                return

            # TODO: Make some cached memory map of all hostile creeps, and use it to avoid.
            resources = cast(List[Resource],
                             self.room.find(FIND_DROPPED_RESOURCES))
            if len(resources):
                closest = None
                closest_distance = Infinity
                for resource in resources:
                    if len(
                            self.room.find_in_range(FIND_HOSTILE_CREEPS, 3,
                                                    resource.pos)) == 0:

                        if self.memory.last_energy_target:
                            compressed_pos = resource.pos.x | (
                                resource.pos.y << 6)
                            if compressed_pos == self.memory.last_energy_target:
                                closest = resource
                                break
                        if (resource.amount > 50 or len(
                                self.room.find_in_range(
                                    FIND_SOURCES, 1, resource.pos)) == 0):

                            # we've confirmed now that this is a valid target! congrats.
                            distance = movement.distance_squared_room_pos(
                                self.pos, resource.pos)
                            if distance < closest_distance:
                                closest = resource
                                closest_distance = distance
                pile = closest
            else:
                pile = None

            if not pile:
                del self.memory.last_energy_target
                if not _.find(self.room.find(FIND_STRUCTURES),
                              {"structureType": STRUCTURE_POWER_BANK}):
                    if self.carry_sum() >= 0:
                        self.memory.filling = False
                    else:
                        target.remove()
                else:
                    if self.pos.inRangeTo(target, 7):
                        self.move_around(target)
                    else:
                        self.move_to(target)
                return

            self.memory.last_energy_target = pile.pos.x | (pile.pos.y << 6)

            if not self.pos.isNearTo(pile):
                self.move_to(pile)
                return False

            result = self.creep.pickup(pile)

            if result == OK:
                pass
            elif result == ERR_FULL:
                self.memory.filling = False
                return True
            else:
                self.log("Unknown result from cleanup-creep.pickup({}): {}",
                         pile, result)
        else:
            if not storage:
                self.go_to_depot()
                return

            if self.pos.roomName != storage.pos.roomName:
                self.follow_military_path(target.pos, storage.pos)
                return False

            target = storage
            if not self.pos.isNearTo(target):
                self.move_to(target)
                return False

            resource_type = _.find(Object.keys(self.creep.carry),
                                   lambda r: self.creep.carry[r] > 0)
            result = self.creep.transfer(target, resource_type)
            if result == OK:
                pass
            elif result == ERR_NOT_ENOUGH_RESOURCES:
                self.memory.filling = True
                return True
            elif result == ERR_FULL:
                if target == storage:
                    self.log("Storage in room {} full!", storage.room.name)
            else:
                self.log(
                    "Unknown result from cleanup-creep.transfer({}, {}): {}",
                    target, resource_type, result)
Пример #15
0
    def run(self):
        if not self.memory.healing and self.creep.hits < \
                max(ATTACK_POWER * self.creep.getActiveBodyparts(ATTACK), int(self.creep.hitsMax / 2)):
            self.memory.healing = True
            self.targets.untarget_all(self)
        if self.memory.healing and self.creep.hits >= self.creep.hitsMax:
            self.memory.healing = False
            self.targets.untarget_all(self)

        target = cast(
            Flag,
            self.targets.get_new_target(self, target_single_flag,
                                        ATTACK_POWER_BANK))
        if not target:
            if len(flags.find_flags(self.home, RAID_OVER)):
                if self.creep.ticksToLive < 300:
                    self.creep.suicide()
                else:
                    self.recycle_me()
            else:
                self.log("PowerAttack has no target!")
                self.go_to_depot()
            return
        heal_target = self.targets.get_new_target(self, target_single_flag2,
                                                  (TD_H_D_STOP, target.pos))
        if self.memory.healing:
            if not heal_target:
                if len(flags.find_flags(self.home, RAID_OVER)):
                    if self.creep.ticksToLive < 300:
                        self.creep.suicide()
                    else:
                        self.memory.last_role = self.memory.role
                        self.memory.role = role_recycling
                else:
                    self.log("PowerAttack has no healer target!")
                    self.go_to_depot()
                return
            if self.pos.roomName != heal_target.pos.roomName:
                self.creep.moveTo(heal_target)
            else:
                room = self.hive.get_room(heal_target.pos.roomName)
                if room and _.find(room.find(FIND_MY_CREEPS),
                                   lambda c: c.memory.role == role_td_healer):
                    if not self.pos.isEqualTo(heal_target):
                        self.creep.moveTo(heal_target)
                        self.follow_military_path(self.home.spawn.pos,
                                                  heal_target)
                else:
                    self.go_to_depot()
        else:
            if self.pos.isNearTo(target):
                struct = cast(
                    Structure,
                    self.room.look_at(LOOK_STRUCTURES, target.pos)[0])
                if struct:
                    self.creep.attack(struct)
                else:
                    for flag in flags.find_flags(self.room, TD_H_H_STOP):
                        flag.remove()
                    for flag in flags.find_flags(self.room, TD_H_D_STOP):
                        flag.remove()
                    target.remove()
            if not self.pos.isEqualTo(heal_target):
                if self.pos.roomName == target.pos.roomName:
                    result = self.creep.moveTo(heal_target)
                    if result != OK and result != ERR_TIRED:
                        self.log(
                            "Unknown result from creep.moveTo({}): {}".format(
                                target, result))
                else:
                    self.follow_military_path(self.home.spawn.pos, heal_target)
Пример #16
0
    def run(self):
        if self.memory.dismantling and self.creep.hits < self.creep.hitsMax / 2:
            self.memory.dismantling = False
            self.targets.untarget(self, target_single_flag2)
        if not self.memory.dismantling and self.creep.hits >= self.creep.hitsMax:
            self.memory.dismantling = True
            self.targets.untarget(self, target_single_flag2)

        if self.memory.dismantling:
            target = cast(
                Optional[Flag],
                self.targets.get_new_target(self, target_single_flag,
                                            ATTACK_DISMANTLE))
            if not target:
                if len(flags.find_flags(self.home, RAID_OVER)):
                    if self.creep.ticksToLive < 300:
                        self.creep.suicide()
                    else:
                        self.memory.last_role = self.memory.role
                        self.memory.role = role_recycling
                else:
                    self.log("Dismantler has no target!")
                    self.go_to_depot()
                return
            if target.name in Memory.flags and target.memory.civilian:
                self.memory.running = 'idle'
            if self.pos.roomName == target.pos.roomName:
                new_target = False
                dismantled = False
                structure = cast(
                    Optional[Structure],
                    self.room.look_at(LOOK_STRUCTURES, target.pos)[0])
                if structure:
                    new_target, dismantled = self.do_dismantle(structure)
                else:
                    site = cast(
                        Optional[ConstructionSite],
                        self.room.look_at(LOOK_CONSTRUCTION_SITES,
                                          target.pos)[0])
                    if site and not site.my:
                        self.move_to(site)
                    elif self.memory.dt:  # dismantler target
                        mem_pos = positions.deserialize_xy_to_pos(
                            self.memory.dt, target.pos.roomName)
                        structure = cast(
                            Optional[Structure],
                            self.room.look_at(LOOK_STRUCTURES, mem_pos)[0])
                        if structure:
                            new_target, dismantled = self.do_dismantle(
                                structure)
                        else:
                            site = self.room.look_at(LOOK_CONSTRUCTION_SITES,
                                                     mem_pos)[0]
                            if site:
                                self.move_to(site)
                            else:
                                new_target = True
                    else:
                        new_target = True

                if new_target:
                    if target.name in Memory.flags and 'dismantle_all' in target.memory and \
                            not target.memory['dismantle_all']:
                        self.remove_target(target)
                        return
                    structures = self.room.find(FIND_STRUCTURES)
                    sites = self.room.find(FIND_CONSTRUCTION_SITES)
                    best_priority = -Infinity
                    best = None
                    hits_per_tick = DISMANTLE_POWER * self.creep.getActiveBodypartsBoostEquivalent(
                        WORK, 'dismantle')
                    for structure in cast(
                            List[Union[Structure, ConstructionSite]],
                            structures.concat(sites)):
                        stype = structure.structureType
                        if structure.my or stype == STRUCTURE_CONTROLLER or stype == STRUCTURE_PORTAL \
                                or (stype == STRUCTURE_EXTRACTOR and not structure.hits) \
                                or (cast(StructureContainer, structure).store
                                    and _.findKey(cast(StructureContainer, structure).store,
                                                  lambda amount, key: amount > 100
                                                  and (key != RESOURCE_ENERGY or amount > 10 * 1000))):
                            continue
                        distance = movement.chebyshev_distance_room_pos(
                            self.pos, structure.pos)

                        priority = -distance
                        if stype == STRUCTURE_WALL or stype == STRUCTURE_RAMPART:
                            if structure.hits:
                                priority -= structure.hits / hits_per_tick
                        if structure.progressTotal:  # a construction site
                            priority -= 50
                        if stype == STRUCTURE_ROAD and distance > 1:
                            priority -= 500 * distance
                        if priority > best_priority:
                            best_priority = priority
                            best = structure
                    if best:
                        self.memory.dt = positions.serialize_pos_xy(
                            best.pos)  # dismantler target
                        if __pragma__('js',
                                      '(best instanceof ConstructionSite)'):
                            self.move_to(best)
                        elif not dismantled:
                            self.do_dismantle(best)
                        else:
                            self.move_to(best)
                    else:
                        self.remove_target(target)
                        return
            else:
                if self.memory.dt:  # dismantler target
                    target = positions.deserialize_xy_to_pos(
                        self.memory.dt, target.pos.roomName)
                if 'checkpoint' not in self.memory or \
                                movement.chebyshev_distance_room_pos(self.memory.checkpoint, self.pos) > 50:
                    self.memory.checkpoint = self.pos
                if hostile_utils.enemy_owns_room(
                        self.memory.checkpoint.roomName):
                    self.memory.checkpoint = self.home.spawn or movement.find_an_open_space(
                        self.home.name)

                self.follow_military_path(
                    _.create(RoomPosition.prototype, self.memory.checkpoint),
                    target)

        else:
            target = self.targets.get_new_target(self, target_single_flag2,
                                                 TD_H_D_STOP)
            if not target:
                if len(flags.find_flags(self.home, RAID_OVER)):
                    if self.creep.ticksToLive < 300:
                        self.creep.suicide()
                    else:
                        self.recycle_me()
                else:
                    self.log("Dismantler has no healer target!")
                    self.go_to_depot()
                return
            if self.pos.roomName != target.pos.roomName:
                self.creep.moveTo(target)
            else:
                room = self.hive.get_room(target.pos.roomName)
                if room and _.find(room.find(FIND_MY_CREEPS),
                                   lambda c: c.memory.role == role_td_healer):
                    if not self.pos.isEqualTo(target):
                        self.creep.moveTo(target)
                        self.follow_military_path(self.home.spawn.pos, target)
                else:
                    self.go_to_depot()