def unit_solve_combat(self, unit: Unit, current_command: Action) -> Action: if isinstance(current_command.target, Unit): target_pos = current_command.target.position else: target_pos = current_command.target if self.move_type == MoveType.PanicRetreat or self.move_type == MoveType.DefensiveRetreat: if unit.has_buff(BuffId.ORACLEWEAPON): return Action(None, False, AbilityId.BEHAVIOR_PULSARBEAMOFF) target = self.pather.find_influence_air_path( unit.position, target_pos) return Action(target, False) if self.move_type == MoveType.Harass: targets = self.cache.enemy(self.knowledge.enemy_worker_type) if targets: close_to_me = targets.closer_than(8, unit.position) close_to_target = targets.closer_than(10, target_pos) if close_to_me: targets = close_to_me elif close_to_target: targets = close_to_target else: targets = self.cache.enemy_in_range( unit.position, 10).filter(lambda u: u.is_light and not u.is_flying) if targets: closest = targets.closest_to(unit) distance = closest.distance_to(unit) if distance > 40 and unit.has_buff(BuffId.ORACLEWEAPON): return Action(None, False, AbilityId.BEHAVIOR_PULSARBEAMOFF) if distance < 5: if not unit.has_buff(BuffId.ORACLEWEAPON): if unit.energy > 40: return Action(None, False, AbilityId.BEHAVIOR_PULSARBEAMON) else: target = self.pather.find_weak_influence_air( unit.position, 10) return Action(target, False) else: return Action(closest, True) target = self.pather.find_weak_influence_air(closest.position, 10) target = self.pather.find_influence_air_path(unit.position, target) return Action(target, False) else: if unit.has_buff(BuffId.ORACLEWEAPON): return Action(None, False, AbilityId.BEHAVIOR_PULSARBEAMOFF) target = self.pather.find_influence_air_path(unit.position, target_pos) return Action(target, False)
def is_valid_chrono_target(unit: Unit): # do not chrono idle buildings or buildings that already have chrono if unit.is_idle or unit.has_buff( BuffId.CHRONOBOOSTENERGYCOST): # what a terrible ID for this return False else: # just to make it clear return True
def real_range(self, unit: Unit, other: Unit) -> float: """Returns real range for a unit and against another unit, taking both units radius into account.""" if other.is_flying or other.has_buff(BuffId.GRAVITONBEAM): corrected_range = self.air_range(unit) else: corrected_range = self.ground_range(unit) if corrected_range <= 0: return corrected_range # eg. stalker.radius + stalker.range + marine.radius return unit.radius + corrected_range + other.radius
def assign_to_work(self, worker: Unit, work: Unit): if worker.has_buff(BuffId.ORACLESTASISTRAPTARGET): return # Worker is in stasis and cannot move self.roles.set_task(UnitTask.Gathering, worker) townhalls = self.ai.townhalls.ready if worker.is_carrying_resource and townhalls: closest = townhalls.closest_to(worker) self.do(worker(AbilityId.SMART, closest)) self.do(worker.gather(work, queue=True)) else: self.do(worker.gather(work))
def unit_solve_combat(self, unit: Unit, current_command: Action) -> Action: if unit.has_buff(BuffId.CHARGING): return NoAction() ground_units = self.enemies_near_by.not_flying if not ground_units: current_command.is_attack = False return current_command # if self.knowledge.enemy_race == Race.Protoss: # if self.engage_percentage < 0.25: # buildings = self.enemies_near_by.sorted_by_distance_to(unit) # if buildings: # if buildings.first.health + buildings.first.shield < 200: # return Action(buildings.first, True) # pylons = buildings(UnitTypeId.PYLON) # if pylons: # return Action(buildings.first, True) return current_command
def use_guardian_shield(self, enemies: EnemyData, sentry: Unit, time: float): if sentry.has_buff(BuffId.GUARDIANSHIELD): return [] if self.tag_shield_used_dict.get(sentry.tag, 0) + self.shield_cooldown < time: for key, value in self.tag_shield_used_dict.items(): if value + 3 < time: # Another sentry just used it's shield, wait a while return [] enemies_at_close_range = enemies.close_enemies.closer_than(GUARDIAN_SHIELD_TRIGGER_RANGE, sentry.position) shooter_power = 0 for enemy in enemies_at_close_range: enemy: Unit = enemy if self.unit_values.is_ranged_unit(enemy): shooter_power += self.unit_values.power(enemy) if shooter_power > 3: self.tag_shield_used_dict[sentry.tag] = time return [CombatAction(sentry, None, False, ability=AbilityId.GUARDIANSHIELD_GUARDIANSHIELD)] return []
async def up_and_down(self, harass_prism: Unit): self.knowledge.roles.set_task(UnitTask.Reserved, harass_prism) if harass_prism.has_buff(BuffId.LOCKON): cyclones = self.knowledge.unit_cache.enemy_in_range( harass_prism.position3d, 20).of_type(UnitTypeId.CYCLONE) if cyclones: closest_cyclone = cyclones.closest_to(harass_prism) position = harass_prism.position.towards(closest_cyclone, -18) self.do(harass_prism.move(position)) return True if harass_prism.health_percentage <= 0.2: self.do( harass_prism(AbilityId.UNLOADALLAT_WARPPRISM, harass_prism.position)) return True if harass_prism.distance_to(self.get_enemy_main_platform()) <= 12 and \ (not self.is_revealed_by_enemy(harass_prism)) and \ harass_prism.cargo_used > 0: self.do( harass_prism(AbilityId.UNLOADALLAT_WARPPRISM, harass_prism.position)) return True target = self.get_enemy_main_platform() dts = self.knowledge.unit_cache.by_tags( [self.ninja_dt_1_tag, self.ninja_dt_2_tag]) if dts.exists and harass_prism.cargo_used < 4: target = dts.center for dt in dts: if self.is_revealed_by_enemy(dt): self.do(harass_prism.move(dt.position)) return True self.prism_evasive_move_to(harass_prism, target) return True
def has_stim(self, unit: Unit) -> bool: return unit.has_buff(BuffId.STIMPACK) or unit.has_buff( BuffId.STIMPACKMARAUDER)
def is_locked_on(self, unit: Unit) -> bool: if unit.has_buff(BuffId.LOCKON): return True return False