Skip to content

Commit

Permalink
feat: anti bane micro
Browse files Browse the repository at this point in the history
  • Loading branch information
raspersc2 committed Dec 3, 2024
1 parent b061800 commit 5f39207
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 11 deletions.
43 changes: 38 additions & 5 deletions bot/combat/generic_engagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@
from typing import TYPE_CHECKING, Union

import numpy as np
from sc2.data import Race
from sc2.ids.ability_id import AbilityId
from sc2.ids.unit_typeid import UnitTypeId as UnitID
from sc2.position import Point2

from ares import ManagerMediator
from ares.behaviors.combat.individual import CombatIndividualBehavior
from ares.behaviors.combat.individual import CombatIndividualBehavior, KeepUnitSafe
from ares.consts import ALL_STRUCTURES
from ares.behaviors.combat.individual import (
AMove,
StutterUnitBack,
StutterUnitForward,
UseAbility,
)
from cython_extensions import cy_closest_to
from cython_extensions import cy_closest_to, cy_distance_to
from sc2.unit import Unit
from sc2.units import Units

Expand Down Expand Up @@ -101,6 +102,18 @@ def execute(
grid: np.ndarray = mediator.get_ground_grid
if unit.is_flying:
grid = mediator.get_air_grid

if (
unit.type_id != UnitID.BANELING
and unit.is_light
and [
e
for e in self.nearby_targets
if e.type_id == UnitID.BANELING
and cy_distance_to(unit.position, e.position) < 3.8
]
):
return KeepUnitSafe(unit, grid).execute(ai, config, mediator)
if self.unit.ground_range < 3.0:
return AMove(unit=unit, target=enemy_target).execute(
ai, config, mediator
Expand All @@ -119,6 +132,26 @@ def execute(
target=safe_spot,
).execute(ai, config, mediator)
else:
return StutterUnitBack(
unit=unit, target=enemy_target, grid=grid
).execute(ai, config, mediator)
# low health, but we are faster and have more range
# always stay out of danger where possible
enemy_speed: float = enemy_target.movement_speed
if ai.enemy_race == Race.Zerg and ai.has_creep(
enemy_target.position
):
enemy_speed *= 1.3
own_speed: float = unit.movement_speed
if ai.race == Race.Zerg and ai.has_creep(unit.position):
own_speed *= 1.3
if (
not enemy_target.is_flying
and own_speed > enemy_speed
and unit.ground_range > enemy_target.ground_range
and unit.shield_health_percentage < 0.25
and cy_distance_to(unit.position, enemy_target.position)
< enemy_target.ground_range + enemy_target.radius + unit.radius
):
return KeepUnitSafe(unit, grid).execute(ai, config, mediator)
else:
return StutterUnitBack(
unit=unit, target=enemy_target, grid=grid
).execute(ai, config, mediator)
47 changes: 41 additions & 6 deletions bot/combat_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

import numpy as np
from sc2.ids.ability_id import AbilityId
from sc2.ids.unit_typeid import UnitTypeId as UnitID
from sc2.ids.unit_typeid import UnitTypeId as UnitID, UnitTypeId
from sc2.data import Race
from sc2.position import Point2
from sc2.unit import Unit
from sc2.units import Units

from ares import ManagerMediator
from ares.behaviors.combat import CombatManeuver
from ares.behaviors.combat.individual import StutterUnitBack, UseAbility
from ares.behaviors.combat.individual import StutterUnitBack, UseAbility, AttackTarget
from ares.consts import UnitRole, UnitTreeQueryType
from cython_extensions import cy_distance_to, cy_closest_to
from cython_extensions import cy_distance_to, cy_closest_to, cy_in_attack_range

from bot.combat.base_combat import BaseCombat
from bot.combat.generic_engagement import GenericEngagement
Expand Down Expand Up @@ -57,6 +57,8 @@ def __init__(self, ai: "AresBot", config: dict, mediator: ManagerMediator):
self._unreachable_cells = None
self._transfused_tags: set[int] = set()

self._unit_tag_to_bane_tag: dict = dict()

@property
def attack_target(self) -> Point2:
attack_target: Point2 = self.ai.game_info.map_center
Expand Down Expand Up @@ -125,17 +127,26 @@ def execute(self):

def _new_micro_arena_combat(self) -> None:
self._transfused_tags = set()

# TODO: stutter forward
for unit in self.ai.units:
all_close_enemy: Units = Units([], self.ai)
if self.ai.units:
all_close_enemy: Units = self.mediator.get_units_in_range(
start_points=[self.ai.units.center],
distances=100.2,
query_tree=UnitTreeQueryType.AllEnemy,
)[0]

if all_close_enemy:
self._assign_units_to_banes(all_close_enemy)

# TODO: stutter forward
for unit in self.ai.units:
if all_close_enemy:
maneuver: CombatManeuver = CombatManeuver()
if unit.tag in self._unit_tag_to_bane_tag:
bane_tag: int = self._unit_tag_to_bane_tag[unit.tag]
if bane := self.ai.unit_tag_dict.get(bane_tag):
maneuver.add(AttackTarget(unit, bane))

# work out if all enemy are melee
all_enemy_melee: bool = all(
[
Expand Down Expand Up @@ -303,3 +314,27 @@ def _calculate_high_ground_spots(self) -> None:
closest = point
dist = d
self._close_high_ground_spots.append(closest)

def _assign_units_to_banes(self, all_close_enemy: Units) -> None:
if not self.ai.units:
return
banes: Units = all_close_enemy(UnitID.BANELING)

for bane in banes:
assigned_bane_tags: set[int] = set(self._unit_tag_to_bane_tag.values())
if bane.tag not in assigned_bane_tags:
for unit in self.ai.units:
if (
unit.type_id != UnitTypeId.BANELING
and unit.is_light
and unit.tag not in self._unit_tag_to_bane_tag
):
self._unit_tag_to_bane_tag[unit.tag] = bane.tag
break
to_remove: list[int] = []
for unit_tag in self._unit_tag_to_bane_tag:
if not self.ai.unit_tag_dict.get(unit_tag):
to_remove.append(unit_tag)

for tag in to_remove:
del self._unit_tag_to_bane_tag[tag]

0 comments on commit 5f39207

Please sign in to comment.