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
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
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
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)
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
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)
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
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
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)))
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))
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
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
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)
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)
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)
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()