예제 #1
0
    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)
예제 #2
0
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
예제 #3
0
    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
예제 #4
0
    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))
예제 #5
0
    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
예제 #6
0
    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 []
예제 #7
0
    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
예제 #8
0
 def has_stim(self, unit: Unit) -> bool:
     return unit.has_buff(BuffId.STIMPACK) or unit.has_buff(
         BuffId.STIMPACKMARAUDER)
예제 #9
0
 def is_locked_on(self, unit: Unit) -> bool:
     if unit.has_buff(BuffId.LOCKON):
         return True
     return False