def solve_combat(self, goal: CombatGoal, command: CombatAction,
                     enemies: EnemyData) -> List[CombatAction]:
        disruptor = goal.unit
        goal.ready_to_shoot = False  # Kite away
        time = self.knowledge.ai.time

        relevant_enemies = enemies.close_enemies.not_structure.not_flying

        if time < self.last_used_any + INTERVAL or len(relevant_enemies) < 4:
            return []

        center = relevant_enemies.center

        if self.cd_manager.is_ready(disruptor.tag,
                                    AbilityId.EFFECT_PURIFICATIONNOVA):
            if center.distance_to(disruptor.position) < 11:
                self.last_used_any = time
                return [
                    CombatAction(disruptor, center, False,
                                 AbilityId.EFFECT_PURIFICATIONNOVA)
                ]
            else:
                goal.ready_to_shoot = True
        else:
            backstep: Point2 = disruptor.position.towards(
                enemies.enemy_center, -3)
            return [CombatAction(disruptor, backstep, False)]
        return []
Esempio n. 2
0
    def FinalSolve(self, goal: CombatGoal, command: CombatAction,
                   enemies: EnemyData) -> CombatAction:
        ground_units: Units = enemies.our_units.not_flying
        x: Unit

        healable_targets = enemies.our_units.filter(
            lambda x: (x.health_percentage < 1 and not x.is_flying and (
                x.is_biological or x.type_id == UnitTypeId.HELLIONTANK)))
        if healable_targets.exists:
            return CombatAction(goal.unit,
                                healable_targets.closest_to(goal.unit), False,
                                AbilityId.MEDIVACHEAL_HEAL)
        if ground_units.exists:
            position: Point2 = ground_units.closest_to(goal.unit).position
            medivac: Unit
            for medivac in enemies.our_units(UnitTypeId.MEDIVAC).closer_than(
                    5, goal.unit):
                if medivac.tag != goal.unit.tag:
                    raven_position: Point2 = medivac.position
                    if raven_position == goal.unit.position:
                        position = position.towards_with_random_angle(
                            self.knowledge.own_main_zone.center_location, 4)
                    else:
                        position = position.towards(raven_position, -4)

            return CombatAction(goal.unit, position, False)

        return command
Esempio n. 3
0
    def solve_combat(self, goal: CombatGoal, command: CombatAction, enemies: EnemyData) -> List[CombatAction]:
        time = self.ai.time
        shuffler = goal.unit.tag % 10

        if self.used_dict.get(goal.unit.tag, 0) + self.cooldown > time:
            return [command]  # Skips all else

        if enemies.enemy_power.power > 10:
            best_score = 0
            target: Unit = None
            enemy: Unit
            for enemy in enemies.close_enemies:
                d = enemy.distance_to(goal.unit)
                if d < 9:
                    score = d * 0.2 - enemy.movement_speed + enemy.radius + self.unit_values.power(enemy)
                    score += 0.1 * (enemy.tag % (shuffler + 2))

                    if score > best_score:
                        target = enemy
                        best_score = score

            if target is not None:
                self.used_dict[goal.unit.tag] = time
                return [CombatAction(goal.unit, target.position, False, AbilityId.EFFECT_CORROSIVEBILE)]

        return [command] # Skips all else
    def solve_combat(self, goal: CombatGoal, command: CombatAction,
                     enemies: EnemyData) -> List[CombatAction]:
        relevant_enemies = enemies.close_enemies.not_structure.not_flying

        if relevant_enemies.exists:
            target = relevant_enemies.closest_to(enemies.enemy_center)
        else:
            target = enemies.close_enemies.closest_to(enemies.enemy_center)
        return [CombatAction(goal.unit, target, False)]
Esempio n. 5
0
    def PanicRetreat(self, goal: CombatGoal, command: CombatAction, enemies: EnemyData) -> CombatAction:
        oracle = goal.unit

        time = self.knowledge.ai.time
        if oracle.has_buff(BuffId.ORACLEWEAPON):
            return self.disable_beam(oracle)[0]

        pos = self.knowledge.pathing_manager.find_influence_air_path(oracle.position, goal.target)

        return CombatAction(oracle, pos, False)
Esempio n. 6
0
    def solve_combat(self, goal: CombatGoal, command: CombatAction,
                     enemies: EnemyData) -> List[CombatAction]:
        if enemies.enemy_power.power > 10 and goal.unit.energy >= 50:
            enemy: Unit
            for enemy in enemies.close_enemies:
                if enemy.is_psionic or enemy.is_mechanical and enemy.distance_to(
                        goal.unit) < 9.5:
                    return [
                        CombatAction(goal.unit, enemy, False,
                                     AbilityId.EFFECT_INTERFERENCEMATRIX)
                    ]

            if goal.unit.energy >= 75 and enemies.closest.distance_to(
                    goal.unit) < 9.5:
                return [
                    CombatAction(goal.unit, enemies.closest, False,
                                 AbilityId.EFFECT_ANTIARMORMISSILE)
                ]

        return [command]  # Skips all else
    def FinalSolve(self, goal: CombatGoal, command: CombatAction,
                   enemies: EnemyData) -> CombatAction:
        bc = goal.unit
        if bc.health < 50 and self.cd_manager.is_ready(
                bc.tag, AbilityId.EFFECT_TACTICALJUMP, self.cooldown):
            zones = self.knowledge.our_zones_with_minerals
            if zones:
                position = zones[0].behind_mineral_position_center
                self.cd_manager.used_ability(bc.tag,
                                             AbilityId.EFFECT_TACTICALJUMP)
                return CombatAction(bc, position, False,
                                    AbilityId.EFFECT_TACTICALJUMP)

        if not self.cd_manager.is_ready(
                bc.tag, AbilityId.EFFECT_TACTICALJUMP,
                self.cooldown) and bc.health_percentage < 0.9:
            scvs: Units = self.knowledge.unit_cache.own(UnitTypeId.SCV)
            if len(scvs) > 0 and scvs.closest_distance_to(bc) < 4:
                # Stay put!
                return CombatAction(bc, bc.position, False)

        return command
Esempio n. 8
0
    def solve_combat(self, goal: CombatGoal, command: CombatAction,
                     enemies: EnemyData) -> List[CombatAction]:
        if not enemies.powered_enemies.exists:
            return []

        stalker = goal.unit

        if self.cd_manager.is_ready(stalker.tag,
                                    AbilityId.EFFECT_BLINK_STALKER,
                                    self.cooldown):
            if enemies.our_power.is_enough_for(enemies.enemy_power, 1.3):
                # We have the advantage, enable offensive blink
                distance = enemies.closest.distance_to(stalker)
                own_range = self.unit_values.real_range(
                    stalker, enemies.closest, self.knowledge)
                enemy_range = self.unit_values.real_range(
                    stalker, enemies.closest, self.knowledge)

                if distance > own_range and own_range < enemy_range and distance < own_range + 5:
                    # Blink to tanks, colossi and tempest
                    self.cd_manager.used_ability(
                        stalker.tag, AbilityId.EFFECT_BLINK_STALKER)
                    target = stalker.position.towards(enemies.closest.position,
                                                      8)
                    return [
                        CombatAction(stalker, target, False,
                                     AbilityId.EFFECT_BLINK_STALKER)
                    ]

            if stalker.shield_percentage < 0.1:
                self.cd_manager.used_ability(stalker.tag,
                                             AbilityId.EFFECT_BLINK_STALKER)
                target = stalker.position.towards(enemies.enemy_center, -8)
                return [
                    CombatAction(stalker, target, False,
                                 AbilityId.EFFECT_BLINK_STALKER)
                ]

        return []
Esempio n. 9
0
    def FinalSolve(self, goal: CombatGoal, command: CombatAction,
                   enemies: EnemyData) -> CombatAction:
        is_fighter = goal.unit.type_id == UnitTypeId.VIKINGFIGHTER
        if not enemies.enemies_exist:
            if is_fighter:
                return command
            else:
                return CombatAction(goal.unit, None, False,
                                    AbilityId.MORPH_VIKINGFIGHTERMODE)

        if is_fighter:
            if (not enemies.close_enemies(UnitTypeId.COLOSSUS).exists
                    and not enemies.close_enemies.flying.exists
                    and enemies.close_enemies.not_flying.exists):
                return CombatAction(goal.unit, None, False,
                                    AbilityId.MORPH_VIKINGASSAULTMODE)
        else:
            if enemies.enemy_power.air_presence > 0 or enemies.close_enemies(
                    UnitTypeId.COLOSSUS).exists:
                return CombatAction(goal.unit, None, False,
                                    AbilityId.MORPH_VIKINGFIGHTERMODE)

        return command
Esempio n. 10
0
    def FinalSolve(self, goal: CombatGoal, command: CombatAction,
                   enemies: EnemyData) -> CombatAction:
        phoenix: Unit = goal.unit

        if command.is_attack and isinstance(command.target, Unit):
            range = self.unit_values.real_range(phoenix, command.target,
                                                self.knowledge)
            check_point = (phoenix.position + command.target.position) * 0.5
            pathing_result = self.knowledge.pathing_manager.find_weak_influence_air(
                check_point, 4)
            direction = sc2math.point_normalize(pathing_result -
                                                command.target.position)
            destination = command.target.position + direction * (range - 0.5)
            return CombatAction(phoenix, destination, False)

        return super().FinalSolve(goal, command, enemies)
Esempio n. 11
0
    def solve_combat(self, goal: CombatGoal, command: CombatAction, enemies: EnemyData) -> List[CombatAction]:
        time = self.ai.time
        voidray = goal.unit

        if (goal.move_type == MoveType.SearchAndDestroy or goal.move_type == MoveType.Assault):
            if self.cd_manager.is_ready(voidray.tag, AbilityId.EFFECT_VOIDRAYPRISMATICALIGNMENT, self.cooldown):
                close_enemies = enemies.close_enemies.closer_than(7, voidray)

                if close_enemies.exists:
                    for enemy in close_enemies:
                        if enemy.is_armored:
                            # there is a armored enemy in the vicinity
                            self.cd_manager.used_ability(voidray.tag, AbilityId.EFFECT_VOIDRAYPRISMATICALIGNMENT)
                            return [CombatAction(voidray, None, False, AbilityId.EFFECT_VOIDRAYPRISMATICALIGNMENT)]

        return [command]  # Skips all else
Esempio n. 12
0
    def relay_order(self, tank: Unit, order: AbilityId,
                    time: float) -> List[CombatAction]:
        if order is None:
            self.clear_order()
            return []

        if self.requested_status == order:
            # Do the change when delay matches request
            delay = self.delay
            if order == AbilityId.SIEGEMODE_SIEGEMODE:
                delay = delay * 0.25

            if time > self.requested_time + delay:
                return [CombatAction(tank, None, False, self.requested_status)]
        else:
            self.requested_status = order
            self.requested_time = time
        return []
Esempio n. 13
0
    def solve_combat(self, goal: CombatGoal, command: CombatAction,
                     enemies: EnemyData) -> List[CombatAction]:
        if not self.knowledge.known_enemy_units.exists:
            return []

        for adept in self.ai.units(sc2.UnitTypeId.ADEPT).tags_not_in(
                self.knowledge.roles.roles[UnitTask.Scouting.value].tags):
            if adept.shield_percentage < 0.75:
                if self.tag_shift_used_dict.get(
                        adept.tag, 0) + self.cooldown < self.ai.time:
                    self.tag_shift_used_dict[adept.tag] = self.ai.time
                    target = adept.position.towards(
                        self.knowledge.known_enemy_units.closest_to(
                            adept.position), -10)
                    return [
                        CombatAction(goal.unit, target, False,
                                     AbilityId.ADEPTPHASESHIFT_ADEPTPHASESHIFT)
                    ]

        return []
Esempio n. 14
0
    def FinalSolve(self, goal: CombatGoal, command: CombatAction,
                   enemies: EnemyData) -> CombatAction:
        ground_units: Units = enemies.our_units.not_flying
        x: Unit

        if ground_units.exists:
            position: Point2 = ground_units.closest_to(goal.unit).position
            observer: Unit
            for observer in enemies.our_units(UnitTypeId.OBSERVER).closer_than(
                    5, goal.unit):
                if observer.tag != goal.unit.tag:
                    observer_position: Point2 = observer.position
                    if observer_position == goal.unit.position:
                        position = position.towards_with_random_angle(
                            self.knowledge.own_main_zone.center_location, 4)
                    else:
                        position = position.towards(observer_position, -4)

            return CombatAction(goal.unit, position, False)

        return command
Esempio n. 15
0
    def FinalSolve(self, goal: CombatGoal, command: CombatAction,
                   enemies: EnemyData) -> CombatAction:
        ground_units: Units = enemies.our_units.not_flying
        x: Unit

        if command.ability is not None:
            return command

        if ground_units.exists:
            position: Point2 = ground_units.closest_to(goal.unit).position
            raven: Unit
            for raven in enemies.our_units(UnitTypeId.RAVEN).closer_than(
                    5, goal.unit):
                if raven.tag != goal.unit.tag:
                    raven_position: Point2 = raven.position
                    if raven_position == goal.unit.position:
                        position = position.towards_with_random_angle(
                            self.knowledge.own_main_zone.center_location, 4)
                    else:
                        position = position.towards(raven_position, -4)

            return CombatAction(goal.unit, position, False)

        return command
Esempio n. 16
0
    def solve_combat(self, goal: CombatGoal, command: CombatAction, enemies: EnemyData) -> List[CombatAction]:
        oracle = goal.unit

        if not oracle.has_buff(BuffId.ORACLEWEAPON):
            goal.ready_to_shoot = False

        air_shooter_enemies = Units([], self.ai)
        enemy: Unit

        power = ExtendedPower(self.unit_values)

        for enemy in enemies.close_enemies:
            if self.unit_values.air_range(enemy) < enemy.distance_to(oracle) + 1:
                air_shooter_enemies.append(enemy)
                power.add_unit(enemy)
                if self.unit_values.is_static_air_defense(enemy):
                    power.add(5) # can't beat turrets with oracle

        enemy_center = enemies.close_enemies.center

        for air_shooter in air_shooter_enemies:  # type: Unit
            if air_shooter.is_light and not air_shooter.is_flying:
                power.add_units(air_shooter_enemies)
            else:
                power.add_units(air_shooter_enemies * 2)

        time = self.knowledge.ai.time
        if goal.move_type == MoveType.PanicRetreat and oracle.has_buff(BuffId.ORACLEWEAPON):
            return self.disable_beam(oracle)

        possible_targets = enemies.close_enemies.filter(lambda u: not u.is_flying and not u.is_structure and u.is_light)

        if possible_targets.exists:
            if oracle.energy > 50 and possible_targets.closest_distance_to(oracle) < 5 and not oracle.has_buff(BuffId.ORACLEWEAPON):
                return self.enable_beam(oracle)

        if  power.air_power > 0 and power.air_power <= 3:
            target = air_shooter_enemies.closest_to(oracle)
            if target.is_light or target.health_percentage < 0.5:
                if not oracle.has_buff(BuffId.ORACLEWEAPON):
                    return self.enable_beam(oracle)
                # Kill the target
                return [CombatAction(oracle, target, True)]

            #target_pos = self.knowledge.pathing_manager.find_weak_influence_air(goal.target, 7)
            #move_step = self.knowledge.pathing_manager.find_influence_air_path(oracle.position, target_pos)
            return [CombatAction(oracle, target.position, True)]
        elif goal.ready_to_shoot and possible_targets:
            return [CombatAction(oracle, possible_targets.closest_to(oracle), True)]
        elif power.air_power > 12:
            # Panic retreat to whatever direction
            if goal.move_type in offensive:
                new_target: Point2 = self.knowledge.pathing_manager.find_weak_influence_air(goal.target, 7)
                step = self.knowledge.pathing_manager.find_influence_air_path(oracle.position, new_target)
                # backstep: Point2 = self.knowledge.pathing_manager.find_weak_influence_air(oracle.position, 7)
                move_action = CombatAction(oracle, step, False)
            else:
                backstep = self.knowledge.pathing_manager.find_influence_air_path(oracle.position, goal.target)
                move_action = CombatAction(oracle, backstep, False)

            # Todo disable beam?
            return [move_action]

        elif power.air_power > 3:
            # Try kiting while killing the target
            target = self.knowledge.pathing_manager.find_weak_influence_air(goal.target, 7)
            backstep = self.knowledge.pathing_manager.find_influence_air_path(oracle.position, target)

            if goal.move_type in offensive:
                move_action = CombatAction(oracle, backstep, False)
            else:
                move_action = CombatAction(oracle, backstep, False)

            if oracle.has_buff(BuffId.ORACLEWEAPON):
                if possible_targets:
                    closest = possible_targets.closest_to(oracle)
                    if closest.distance_to(oracle) < 5:
                        return [CombatAction(oracle, closest, True)]
                return [CombatAction(oracle, command.target, True), move_action]
            else:
                return [move_action]


        if possible_targets.exists:
            return [CombatAction(oracle, command.target, True)]
        else:
            return [CombatAction(oracle, command.target, False)]
Esempio n. 17
0
 def disable_beam(self, oracle):
     self.knowledge.print("[ORACLE] beam disabled")
     return [CombatAction(oracle, None, False, AbilityId.BEHAVIOR_PULSARBEAMOFF)]
Esempio n. 18
0
    def solve_combat(self, goal: CombatGoal, command: CombatAction,
                     enemies: EnemyData) -> List[CombatAction]:
        actions: List[CombatAction] = []
        phoenix: Unit = goal.unit

        # def is_beam_target_type(unit: Unit) -> bool:
        #     if unit.type_id in self.always_ignore:
        #         return False
        #
        #     if phoenix.energy_percentage > 0.95:
        #         # Anything but ignored types are fine with full energy
        #         return True
        #
        #     return unit.type_id in self.lift_priority

        friends: Units = self.combat_manager.ai.units.closer_than(8, phoenix)
        half_not_beaming = friends.amount / 2 > len(
            self.combat_manager.beaming_phoenix_tags)

        has_energy = phoenix.energy > GRAVITON_BEAM_ENERGY
        best_target: Optional[Unit] = None
        best_score: float = 0

        for enemy in enemies.close_enemies:  # type: Unit
            if enemy.has_buff(BuffId.GRAVITONBEAM):
                continue

            pos: Point2 = enemy.position
            score = self.lift_priority.get(
                enemy.type_id, -1) + (1 - pos.distance_to(phoenix) / 10)
            if score > best_score:
                best_target = enemy
                best_score = score

        # Use Graviton Beam
        if has_energy and half_not_beaming and best_target:
            if best_score > 5 or not enemies.close_enemies.flying.exists:
                self.print(
                    f"Phoenix at {phoenix.position} lifting {best_target.type_id} at {best_target.position}"
                )

                if phoenix.distance_to(best_target) > 8:
                    destination = self.knowledge.pathing_manager.find_influence_air_path(
                        phoenix.position, best_target.position)
                    return [CombatAction(phoenix, destination, False)]
                return [
                    CombatAction(phoenix,
                                 best_target,
                                 False,
                                 ability=AbilityId.GRAVITONBEAM_GRAVITONBEAM)
                ]

        if enemies.close_enemies.closer_than(
                11, phoenix.position
        ).exists and not enemies.close_enemies.flying.exists:
            # There is an enemy close by, but it doesn't fly so let's run away !
            pathing_result = self.path_finder_air.lowest_influence_in_grid(
                enemies.our_median, 8)
            backstep = Point2(pathing_result[0])
            #backstep: Point2 = phoenix.position.towards(enemies.enemy_center, -3)
            return [CombatAction(phoenix, backstep, False)]

        # Do you normal stuff
        return actions
Esempio n. 19
0
    def FinalSolve(self, goal: CombatGoal, command: CombatAction, enemies: EnemyData) -> CombatAction:
        prism = goal.unit
        warpgates: Units = self.knowledge.unit_cache.own(UnitTypeId.WARPGATE)

        count = len(warpgates)
        ready = 0
        for gate in warpgates:  # type: Unit
            if gate.is_transforming or self.cd_manager.is_ready(gate.tag, AbilityId.WARPGATETRAIN_ZEALOT):
                ready += 1

        if (ready > 2 and ready >= count and goal.unit.type_id == UnitTypeId.WARPPRISM and self.ai.supply_left > 3
                and self.cd_manager.is_ready(prism.tag, AbilityId.MORPH_WARPPRISMTRANSPORTMODE, 6)):
            # TODO: Is it safe to warp in?
            self.cd_manager.used_ability(prism.tag, AbilityId.MORPH_WARPPRISMPHASINGMODE)
            return CombatAction(goal.unit, None, False, AbilityId.MORPH_WARPPRISMPHASINGMODE)
        elif goal.unit.type_id == UnitTypeId.WARPPRISMPHASING:
            not_ready = self.knowledge.unit_cache.own(UnitValue.gate_types).not_ready
            if self.cd_manager.is_ready(prism.tag, AbilityId.MORPH_WARPPRISMPHASINGMODE, 2.5) \
                    and (len(not_ready) < 1 or not_ready.closest_distance_to(prism) > 4):
                self.cd_manager.used_ability(prism.tag, AbilityId.MORPH_WARPPRISMTRANSPORTMODE)
                return CombatAction(goal.unit, None, False, AbilityId.MORPH_WARPPRISMTRANSPORTMODE)

        if prism.cargo_used:
            for passenger in prism.passengers:  # type: Unit
                if self.release_tags.get(passenger.tag, 0) < self.ai.time:
                    if (not self.ai.in_pathing_grid(prism)):
                        break

                    stop_drop = False

                    for enemy in enemies.close_enemies:  # type: Unit
                        if enemy.radius + 1 > prism.distance_to(enemy):
                            stop_drop = True
                            break

                    if stop_drop:
                        break

                    #return CombatAction(prism, passenger, False, AbilityId.UNLOADALLAT_WARPPRISM)
                    return CombatAction(prism, prism, False, AbilityId.UNLOADALLAT_WARPPRISM)

        if not enemies.powered_enemies.exists:
            return command

        # Let's find the safest position that's closest to enemies

        best_danger = self.knowledge.enemy_units_manager.danger_value(goal.unit, enemies.our_median)
        best_position = enemies.our_median

        if prism.cargo_left and prism.shield > 0 and prism.shield + prism.health > 50:
            best_score = 0
            best_unit = None
            for own_unit in enemies.our_units:  # type: Unit
                if own_unit.cargo_size > prism.cargo_left:
                    continue
                if own_unit.shield:
                    continue
                if own_unit.weapon_cooldown < 2:
                    continue
                if own_unit.distance_to(prism) > 12:
                    continue

                score = self.unit_values.ground_range(own_unit, self.knowledge) * (1.1 - own_unit.health_percentage) \
                        * self.unit_values.power(own_unit) - 1

                if score > best_score:
                    best_score = score
                    best_unit = own_unit

            if best_unit is not None:
                self.release_tags[best_unit.tag] = self.ai.time + best_unit.weapon_cooldown / 22.4
                return CombatAction(goal.unit, best_unit, False, AbilityId.SMART)

        priority_units = enemies.our_units.of_type([UnitTypeId.COLOSSUS, UnitTypeId.IMMORTAL, UnitTypeId.ARCHON, UnitTypeId.HIGHTEMPLAR])

        for vector in self.grid_vectors:
            position: Point2 = goal.unit.position + vector * 3
            if position.distance_to_point2(enemies.our_median) > 8:
                # Don't go too far away from our units
                continue

            danger = self.knowledge.enemy_units_manager.danger_value(goal.unit, position)
            coverage = 0
            for unit in priority_units:  # type: Unit
                if unit.distance_to(vector) < 6:
                    coverage += self.unit_values.power_by_type(unit.type_id) * 10

            if danger < best_danger - coverage:
                best_danger = danger
                best_position = position

        return CombatAction(goal.unit, best_position, False)