unit = self.ai_data.bot.units.find_by_tag(self.ai_data.unit_tag) if unit is None: return py_trees.common.Status.FAILURE # Wybierz jednostki oraz budynki wroga, które jednostka widzi enemy_units = self.ai_data.bot.enemy_units.filter( lambda enemy: unit.distance_to(enemy) <= unit.sight_range and enemy.can_be_attacked ) enemy_structures = self.ai_data.bot.enemy_structures.filter( lambda enemy: unit.distance_to(enemy) <= unit.sight_range ) # Preferuj jednostki, które atakują oraz są blisko visible_enemies = enemy_units + enemy_structures.filter(lambda enemy: enemy.can_attack) visible_enemies.sort(key=lambda enemy: unit.distance_to(enemy)) enemies_in_range = visible_enemies.in_attack_range_of(unit, bonus_distance=unit.sight_range * 0.15) enemies = visible_enemies if len(enemies_in_range) > 0: enemies = enemies_in_range # Wybierz jednostkę, która jest najbardziej ranna. Jeśli wśród niebezpiecznych jednostek nikogo nie udało się # znaleźć, zaatakuj inne, nie niebezpieczne cele. best_target = min(enemies, key=lambda enemy: (enemy.health + enemy.shield) / (enemy.health_max + enemy.shield_max + self.ai_data.eps), default=None) if best_target is None and enemy_structures.exists: best_target = enemy_structures.closest_to(unit) if best_target is not None: if not (unit.is_attacking and unit.order_target == best_target.tag): if unit.type_id == UnitTypeId.SENTRY: unit(AbilityId.GUARDIANSHIELD_GUARDIANSHIELD) unit.attack(best_target) return py_trees.common.Status.SUCCESS return py_trees.common.Status.RUNNING