def baneling_burrowed(self, unit): closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy and closest_enemy.distance_to(unit) <= 2.2: ability = AbilityId.EXPLODE_EXPLODE if ability in unit.abilities: return [unit(ability)] filtered_units = self.units.filter(lambda _unit: hasattr( _unit, 'total_strength') and _unit.total_strength) closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: if filtered_units: strongest_army_unit = max(filtered_units, key=lambda _unit: _unit.total_strength) if strongest_army_unit: if not hasattr(strongest_army_unit, 'is_retreating' ) or not strongest_army_unit.is_retreating: if unit.distance_to(closest_enemy) > unit.sight_range: ability = AbilityId.BURROWDOWN_BANELING if ability in unit.abilities: return [unit(ability)] # burrow up if no one is around return []
def warp_prism(self, unit): actions = [] closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: closest_ally_to_enemy = get_closest_unit(self, closest_enemy, self.units_that_can_attack) if closest_ally_to_enemy: ability = AbilityId.MOVE_MOVE if ability in unit.abilities: return [unit(ability, closest_ally_to_enemy.position)] return actions
async def queen(self, unit): actions = [] closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: creep_target = closest_enemy else: creep_target = random.choice(self.enemy_start_locations_keys) creep_generators = self.structures( UnitTypeId.CREEPTUMOR) + self.structures( UnitTypeId.CREEPTUMORBURROWED) + self.structures( UnitTypeId.HATCHERY) closest_creep_structure = get_closest_unit(self, creep_target, creep_generators) if closest_creep_structure: free_queens = self.units( UnitTypeId.QUEEN).filter(lambda queen: not hasattr( queen, 'reserved_for_task') or not queen.reserved_for_task) closest_queen = free_queens.closest_to( closest_creep_structure.position) if closest_queen.tag == unit.tag: ability = AbilityId.BUILD_CREEPTUMOR_QUEEN if ability in unit.abilities: if closest_creep_structure.type_id == UnitTypeId.HATCHERY: creep_range = 12.5 else: creep_range = 10 range_to_place = list( np.arange(creep_range, closest_creep_structure.radius, -1)) for step in range_to_place: position = closest_creep_structure.position.towards_with_random_angle( creep_target.position, step) # if position: return [unit(ability, position)] # get units in range. for _unit in self.units_and_structures: hurt_units_in_range = [] distance = _unit.distance_to(unit) if distance < 7 and _unit.health_percentage < 1.0 and _unit.build_progress == 1.0: hurt_units_in_range.append(_unit) if hurt_units_in_range: max_hurt_ally = max(hurt_units_in_range, key=lambda _unit: _unit.health_max - _unit.health) if max_hurt_ally: ability = AbilityId.TRANSFUSION_TRANSFUSION if ability in unit.abilities: return [unit(ability, max_hurt_ally)] ability = AbilityId.BURROWDOWN_QUEEN actions += burrow(self, unit, ability) return actions
def observer(self, unit): closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: if unit.distance_to(closest_enemy) < unit.sight_range: ability = AbilityId.MORPH_SURVEILLANCEMODE if ability in unit.abilities: return [unit(ability)] closest_ally_to_enemy = get_closest_unit(self, closest_enemy, self.units_and_structures) if closest_ally_to_enemy: ability = AbilityId.MOVE_MOVE if ability in unit.abilities: return [unit(ability, closest_ally_to_enemy.position)] return []
def supply_depot(self, unit): # if ally closer drop closest_ally = get_closest_unit(self, unit, self.units_and_structures) closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy and closest_ally: if unit.position.distance_to(closest_ally) < unit.position.distance_to( closest_enemy): ability = AbilityId.MORPH_SUPPLYDEPOT_LOWER if ability in unit.abilities: return [unit(ability)] else: ability = AbilityId.MORPH_SUPPLYDEPOT_RAISE if ability in unit.abilities: return [unit(ability)] return []
async def boost_production(self): actions = [] if self.townhalls: ability = AbilityId.EFFECT_CHRONOBOOSTENERGYCOST random_townhall = random.choice(self.townhalls) if ability in random_townhall.abilities: random_building = random.choice(self.structures) if not random_building.has_buff(BuffId.CHRONOBOOSTENERGYCOST): if not random_building.is_idle: actions += [random_townhall(ability, random_building)] queens = self.units(UnitTypeId.QUEEN) if queens: ability = AbilityId.EFFECT_INJECTLARVA for townhall in self.townhalls: closest_queen = get_closest_unit(self, townhall, queens) found_index = next( (index for (index, d) in enumerate(self.reserved_for_task) if d.tag == closest_queen.tag), -1) if found_index < 0 and len(self.reserved_for_task) < len( self.townhalls): self.reserved_for_task.append(closest_queen) closest_queen.reserved_for_task = True if not townhall.has_buff(BuffId.QUEENSPAWNLARVATIMER): actions += [closest_queen(ability, townhall)] return actions
def adept_phase_shift(self, unit): closest_ally = get_closest_unit(self, unit, self.units) if closest_ally and hasattr( closest_ally, 'is_retreating') and closest_ally.is_retreating: ability = AbilityId.CANCEL_ADEPTSHADEPHASESHIFT if ability in unit.abilities: return [unit(ability)] return []
def decide_action_on_created(self, unit): if (unit.type_id == UnitTypeId.OVERLORD): return [unit(AbilityId.MOVE_MOVE, Point2(select_random_point(self)))] if (unit.type_id == UnitTypeId.BROODLING): if self.enemy_units_and_structures: closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) return [unit(AbilityId.ATTACK_ATTACK, closest_enemy)] return []
def spore_crawler(self, unit): closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: creep_target = closest_enemy else: creep_target = random.choice(self.enemy_start_locations_keys) creep_generators = self.structures( UnitTypeId.CREEPTUMOR) + self.structures(UnitTypeId.HATCHERY).ready closest_creep_structure = get_closest_unit(self, creep_target, creep_generators) if closest_creep_structure: if unit.distance_to( creep_target) > closest_creep_structure.distance_to( creep_target): ability = AbilityId.SPORECRAWLERUPROOT_SPORECRAWLERUPROOT if ability in unit.abilities: return [unit(ability)] return []
def observer_siege_mode(self, unit): actions = [] closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: if unit.distance_to(closest_enemy) > unit.sight_range: ability = AbilityId.MORPH_OBSERVERMODE if ability in unit.abilities: return [unit(ability)] return actions
def scv(self, unit): actions = [] closest_attackable_enemy = get_closest_attackable_enemy(self, unit) if closest_attackable_enemy: actions += worker_decisions(self, unit, closest_attackable_enemy) if hasattr(unit, 'is_retreating') and unit.is_retreating: # if closest_attackable_enemy.movement_speed > unit.movement_speed: closest_townhall = get_closest_unit(self, unit, self.townhalls) if unit.distance_to(closest_townhall) < unit.sight_range: ability = AbilityId.LOADALL_COMMANDCENTER if ability in closest_townhall.abilities: return [closest_townhall(ability, unit)] return actions
def widow_mine_burrowed(self, unit): closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: if closest_enemy.distance_to(unit) > unit.sight_range: ability = AbilityId.BURROWUP_WIDOWMINE if ability in unit.abilities: return [unit(ability)] if closest_enemy.distance_to( unit) < unit.sight_range and unit.weapon_cooldown > 0: ability = AbilityId.BURROWUP_WIDOWMINE if ability in unit.abilities: return [unit(ability)] return []
def sentry(self, unit): closest_attackable_enemy = get_closest_attackable_enemy(self, unit) if closest_attackable_enemy: return [] ability = AbilityId.FORCEFIELD_FORCEFIELD if ability in unit.abilities: closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy and not closest_enemy.is_flying: if unit.is_retreating: position = closest_enemy.position.towards(unit.position, 1) else: position = closest_enemy.position.towards(unit.position, -1) return [unit(ability, position)] return []
def spore_crawler_uprooted(self, unit): # move to closest building towards enemy. closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: creep_target = closest_enemy else: creep_target = random.choice(self.enemy_start_locations_keys) creep_generators = self.structures( UnitTypeId.CREEPTUMOR) + self.structures(UnitTypeId.HATCHERY).ready closest_creep_structure = get_closest_unit(self, creep_target, creep_generators) if closest_creep_structure: if unit.distance_to( creep_target) > closest_creep_structure.distance_to( creep_target): position = closest_creep_structure.position.towards( creep_target.position, 4) return [unit(AbilityId.MOVE_MOVE, position)] else: ability = AbilityId.SPORECRAWLERROOT_SPORECRAWLERROOT if ability in unit.abilities: return [unit(ability, unit.position)] return []
def barracks(self, unit): actions = [] if unit.health_max > unit.health: closest_scv_or_mule = get_closest_unit( self, unit, self.workers + self.units(UnitTypeId.MULE)) if closest_scv_or_mule: if closest_scv_or_mule.type_id == UnitTypeId.SCV: ability = AbilityId.EFFECT_REPAIR_SCV if ability in closest_scv_or_mule.abilities: actions.append(closest_scv_or_mule(ability, unit)) elif closest_scv_or_mule.type_id == UnitTypeId.MULE: ability = AbilityId.EFFECT_REPAIR_MULE if ability in closest_scv_or_mule.abilities: actions.append(closest_scv_or_mule(ability, unit)) ability = AbilityId.LIFT_BARRACKS actions.extend(lift_building(self, unit, ability)) return actions
def update_attack_and_retreat(self): actions = [] attacking_units = self.units.filter(lambda unit: unit.is_attacking) retreating_units = self.units.filter( lambda unit: hasattr(unit, 'is_retreating') and unit.is_retreating) if attacking_units: for unit in attacking_units: if not hasattr(unit, 'reserved_for_task') or not unit.reserved_for_task: actions += attack(self, unit) if retreating_units: for unit in retreating_units: closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) _range = unit.sight_range if unit.sight_range > closest_enemy.sight_range else closest_enemy.sight_range actions += retreat(self, unit, closest_enemy, _range) return actions
def widow_mine(self, unit): closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: if closest_enemy.distance_to(unit) <= unit.sight_range: ability = AbilityId.BURROWDOWN_WIDOWMINE if ability in unit.abilities: return [unit(ability)] filtered_units = self.units.filter(lambda _unit: hasattr( _unit, 'total_strength') and _unit.total_strength) if filtered_units: strongest_army_unit = max(filtered_units, key=lambda _unit: _unit.total_strength) if strongest_army_unit: ability = AbilityId.MOVE_MOVE if ability in unit.abilities: return [unit(ability, strongest_army_unit.position)] return []
def baneling(self, unit): actions = [] # move to closest ally to closest enemy filtered_units = self.units.filter(lambda _unit: hasattr( _unit, 'total_strength') and _unit.total_strength) closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if closest_enemy: if filtered_units: strongest_army_unit = max(filtered_units, key=lambda _unit: _unit.total_strength) if strongest_army_unit: if hasattr( strongest_army_unit, 'is_retreating') and strongest_army_unit.is_retreating: if unit.distance_to( strongest_army_unit) < unit.sight_range: if unit.distance_to(closest_enemy) > unit.sight_range: ability = AbilityId.BURROWDOWN_BANELING if ability in unit.abilities: return [unit(ability)] ability = AbilityId.MOVE_MOVE if ability in unit.abilities: return [unit(ability, strongest_army_unit.position)] if closest_enemy.is_structure: ability = AbilityId.BEHAVIOR_BUILDINGATTACKON if ability in unit.abilities: actions.extend([unit(ability)]) else: ability = AbilityId.BEHAVIOR_BUILDINGATTACKOFF if ability in unit.abilities: actions.extend([unit(ability)]) if closest_enemy.distance_to(unit) <= 2.2: ability = AbilityId.EXPLODE_EXPLODE if ability in unit.abilities: return [unit(ability)] return actions
def retreat(self, unit, enemy_unit, _range): actions = [] unit.is_retreating = True assign_damage_vs_target_and_group_health(self, unit, enemy_unit) stronger_army = self.units.filter( lambda _unit: hasattr(_unit, 'total_strength' ) and _unit.total_strength > unit.total_strength) target = get_closest_unit(self, unit, stronger_army, _range) closest_bunker = get_closest_unit(self, unit, self.units(UnitTypeId.BUNKER)) closest_command_center = get_closest_unit( self, unit, self.units(UnitTypeId.COMMANDCENTER)) if closest_bunker and closest_bunker.distance_to(unit) < unit.sight_range: if unit.type_id in [ UnitTypeId.SCV, UnitTypeId.MARINES, UnitTypeId.REAPER, UnitTypeId.MARAUDER ]: ability = AbilityId.LOAD_BUNKER if ability in unit.abilities: return [closest_bunker(ability, unit)] if closest_command_center and closest_command_center.distance_to( unit) < unit.sight_range: if unit.type_id in [UnitTypeId.SCV]: ability = AbilityId.LOADALL_COMMANDCENTER if ability in unit.abilities: return [closest_command_center(ability, unit)] if not target: target = get_closest_unit(self, unit, self.units_that_can_attack, _range) if not target: target = get_closest_unit(self, unit, self.structures, _range) if not target: target = get_closest_unit(self, unit, self.units_and_structures, _range) if not target: return attack(self, unit) actions += [unit(AbilityId.MOVE_MOVE, target.position)] return actions
def micro_units(self, unit, enemy_unit, current_distance): actions = [] in_range_enemy = get_range(self, unit) if can_attack(in_range_enemy, unit): enemy_range = in_range_enemy.ground_range + in_range_enemy.radius + unit.radius unit_range = unit.ground_range + unit.radius + enemy_unit.radius larger_sight_range = unit.sight_range if unit.sight_range > enemy_unit.sight_range else enemy_unit.sight_range speed = unit.movement_speed # enemy_speed = enemy_unit.movement_speed enemy_speed = in_range_enemy.movement_speed closest_ally = get_closest_unit(self, unit, self.units_and_structures, enemy_unit.sight_range) closest_enemy = get_closest_unit(self, unit, self.enemy_units_and_structures) if larger_sight_range > current_distance: if unit_range > enemy_range: if current_distance > unit_range: if speed >= enemy_speed: actions += attack(self, unit) if speed < enemy_speed: attack_or_regroup(self, unit, enemy_unit, larger_sight_range) if current_distance == unit_range: actions += attack(self, unit) if current_distance < unit_range: actions += micro(self, unit, closest_ally, enemy_unit) if current_distance <= enemy_range + 1: if speed > enemy_speed: actions += retreat(self, unit, enemy_unit, larger_sight_range) if speed == enemy_speed: actions += retreat(self, unit, enemy_unit, larger_sight_range) if speed < enemy_speed: actions += micro(self, unit, closest_ally, enemy_unit) elif unit_range == enemy_range: if current_distance > unit_range: actions += attack_or_regroup(self, unit, enemy_unit, larger_sight_range) if current_distance <= unit_range: if speed > enemy_speed: assign_damage_vs_target_and_group_health( self, unit, enemy_unit) if unit.group_damage_vs_target * unit.group_health > enemy_unit.group_damage_vs_target * enemy_unit.group_health: actions += micro(self, unit, closest_ally, enemy_unit) else: actions += retreat(self, unit, enemy_unit, larger_sight_range) if speed == enemy_speed: assign_damage_vs_target_and_group_health( self, unit, enemy_unit) if unit.group_damage_vs_target * unit.group_health > enemy_unit.group_damage_vs_target * enemy_unit.group_health: actions += micro(self, unit, closest_ally, enemy_unit) else: actions += retreat(self, unit, enemy_unit, larger_sight_range) if speed < enemy_speed: actions += micro(self, unit, closest_ally, enemy_unit) elif unit_range < enemy_range: if current_distance > enemy_range: actions += attack_or_regroup(self, unit, enemy_unit, larger_sight_range) if current_distance <= enemy_range: if current_distance > unit_range: if speed > enemy_speed: actions += attack_or_regroup( self, unit, enemy_unit, larger_sight_range) if speed == enemy_speed: actions += attack_or_regroup( self, unit, enemy_unit, larger_sight_range) if speed < enemy_speed: actions += micro(self, unit, closest_enemy, enemy_unit) if current_distance <= unit_range: if speed > enemy_speed: actions += attack_or_regroup( self, unit, enemy_unit, larger_sight_range) if speed == enemy_speed: actions += attack_or_regroup( self, unit, enemy_unit, larger_sight_range) if speed < enemy_speed: actions += micro(self, unit, closest_enemy, enemy_unit) return actions