def do_some_unit_property_tests(attacker: Unit, defender: Unit): """ Some tests that are not covered by test_pickled_data.py """ # TODO move unit unrelated tests elsewhere self.step_time self.units_created self.structure_type_build_progress(attacker.type_id) self.structure_type_build_progress(defender.type_id) self.tech_requirement_progress(attacker.type_id) self.tech_requirement_progress(defender.type_id) self.in_map_bounds(attacker.position) self.in_map_bounds(defender.position) self.get_terrain_z_height(attacker.position) self.get_terrain_z_height(defender.position) for unit in [attacker, defender]: unit.shield_percentage unit.shield_health_percentage unit.energy_percentage unit.age_in_frames unit.age unit.is_memory unit.is_snapshot unit.cloak unit.is_revealed unit.can_be_attacked unit.buff_duration_remain unit.buff_duration_max unit.order_target unit.is_transforming unit.has_techlab unit.has_reactor unit.add_on_position unit.health_percentage unit.bonus_damage unit.air_dps attacker.target_in_range(defender) defender.target_in_range(attacker) attacker.calculate_dps_vs_target(defender) defender.calculate_dps_vs_target(attacker) attacker.is_facing(defender) defender.is_facing(attacker) attacker == defender defender == attacker
def in_attack_range_of(self, unit: Unit, bonus_distance: Union[int, float] = 0) -> Units: """ Filters units that are in attack range of the given unit. This uses the unit and target unit.radius when calculating the distance, so it should be accurate. Caution: This may not work well for static structures (bunker, sieged tank, planetary fortress, photon cannon, spine and spore crawler) because it seems attack ranges differ for static / immovable units. Example:: enemy_zerglings = self.enemy_units(UnitTypeId.ZERGLING) my_marine = next((unit for unit in self.units if unit.type_id == UnitTypeId.MARINE), None) if my_marine: all_zerglings_my_marine_can_attack = enemy_zerglings.in_attack_range_of(my_marine) Example:: enemy_mutalisks = self.enemy_units(UnitTypeId.MUTALISK) my_marauder = next((unit for unit in self.units if unit.type_id == UnitTypeId.MARAUDER), None) if my_marauder: all_mutalisks_my_marauder_can_attack = enemy_mutaliskss.in_attack_range_of(my_marauder) # Is empty because mutalisk are flying and marauder cannot attack air :param unit: :param bonus_distance:""" return self.filter(lambda x: unit.target_in_range(x, bonus_distance=bonus_distance))
def one_of_targets_in_range(self, unit: Unit, targets: Units): for target in targets: if unit.target_in_range(target): return True return False