Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Micro for ghosts #107

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions sharpy/combat/micro_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,18 @@

class MicroRules(Component):
handle_groups_func: Callable[["GroupCombatManager", Point2, MoveType], None]
init_group_func: Callable[[MicroStep, CombatUnits, Units, List[CombatUnits], MoveType], None]
init_group_func: Callable[
[MicroStep, CombatUnits, Units, List[CombatUnits], MoveType], None
]
group_solve_combat_func: Callable[[MicroStep, Units, Action], Action]
unit_solve_combat_func: Callable[[MicroStep, Unit, Action], Action]
ready_to_shoot_func: Callable[[MicroStep, Unit], bool]
focus_fire_func: Callable[[MicroStep, Unit, Action, Optional[Dict[UnitTypeId, int]]], Action]
melee_focus_fire_func: Callable[[MicroStep, Unit, Action, Optional[Dict[UnitTypeId, int]]], Action]
focus_fire_func: Callable[
[MicroStep, Unit, Action, Optional[Dict[UnitTypeId, int]]], Action
]
melee_focus_fire_func: Callable[
[MicroStep, Unit, Action, Optional[Dict[UnitTypeId, int]]], Action
]
generic_micro: MicroStep

def __init__(self) -> None:
Expand All @@ -52,9 +58,13 @@ def load_default_methods(self):
self.handle_groups_func = DefaultMicroMethods.handle_groups
self.init_group_func = DefaultMicroMethods.init_micro_group
# Pass command
self.group_solve_combat_func = lambda step, units, current_command: current_command
self.group_solve_combat_func = (
lambda step, units, current_command: current_command
)
# Pass command
self.unit_solve_combat_func = lambda step, unit, current_command: current_command
self.unit_solve_combat_func = (
lambda step, unit, current_command: current_command
)

self.ready_to_shoot_func = DefaultMicroMethods.ready_to_shoot

Expand Down Expand Up @@ -106,6 +116,7 @@ def load_default_micro(self):
self.unit_micros[UnitTypeId.MARINE] = MicroBio()
self.unit_micros[UnitTypeId.MARAUDER] = MicroBio()
self.unit_micros[UnitTypeId.BATTLECRUISER] = MicroBattleCruisers()
self.unit_micros[UnitTypeId.GHOST] = MicroGhosts()
self.unit_micros[UnitTypeId.RAVEN] = MicroRavens()
self.unit_micros[UnitTypeId.MEDIVAC] = MicroMedivacs()
self.unit_micros[UnitTypeId.LIBERATOR] = MicroLiberators()
Expand Down
1 change: 1 addition & 0 deletions sharpy/combat/terran/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from .micro_medivacs import MicroMedivacs
from .micro_liberators import MicroLiberators
from .micro_reaper import MicroReaper
from .micro_ghosts import MicroGhosts
85 changes: 85 additions & 0 deletions sharpy/combat/terran/micro_ghosts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from typing import *

from sc2.ids.buff_id import BuffId
from sc2.ids.unit_typeid import UnitTypeId
from sc2.position import Point2
from sc2.units import Units
from sharpy.combat import *
from sc2.ids.ability_id import AbilityId
from sc2.unit import Unit
from sharpy.interfaces.combat_manager import MoveType


class MicroGhosts(GenericMicro):
def __init__(self):
super().__init__()
self.snipes = {}
self.emp_available = 0

def init_group(
self,
rules: "MicroRules",
group: CombatUnits,
units: Units,
enemy_groups: List[CombatUnits],
move_type: MoveType,
original_target: Point2,
):
super().init_group(
rules, group, units, enemy_groups, move_type, original_target
)

def group_solve_combat(self, units: Units, current_command: Action) -> Action:
return current_command

def unit_solve_combat(self, unit: Unit, current_command: Action) -> Action:
# There no reason to cloak if near only structures
enemy_units = self.cache.enemy_in_range(unit.position, 10).filter(lambda u: not u.is_structure and not u.type_id == UnitTypeId.LARVA)
if unit.energy > 120 and len(enemy_units) > 0 and self.our_power.power < 3:
return Action(None, False, AbilityId.BEHAVIOR_CLOAKON_GHOST)

if unit.energy < 50 and len(enemy_units) == 0 and self.our_power.power > 3:
return Action(None, False, AbilityId.BEHAVIOR_CLOAKOFF_GHOST)

if self.cd_manager.is_ready(unit.tag, AbilityId.EFFECT_GHOSTSNIPE):
snipe_enemies = self.cache.enemy_in_range(unit.position, 10).filter(
lambda u: u.is_biological and not u.is_structure and (u.is_armored or u.shield > 0 or u.type_id == UnitTypeId.HELLIONTANK)
)
if snipe_enemies:
best_target = snipe_enemies.closest_to(unit)
snipe_count = self.snipes.get(best_target.tag, 0)
if best_target.health > snipe_count * 170:
self.snipes[best_target.tag] = snipe_count + 1
return Action(best_target, False, AbilityId.EFFECT_GHOSTSNIPE)
else:
return current_command

if (
self.emp_available < self.ai.time
and self.cd_manager.is_ready(unit.tag, AbilityId.EMP_EMP)
and self.engaged_power.power > 4
):
best_score = 2
target: Optional[Unit] = None
enemy: Unit

for enemy in self.enemies_near_by:
d = enemy.distance_to(unit)
if (
d < 11
and self.unit_values.power(enemy) > 0.5
and not enemy.has_buff(BuffId.EMPDECLOAK)
and (enemy.energy > 50 or enemy.shield > 50)
):
score = self.cache.enemy_in_range(enemy.position, 2).filter(
lambda u: (u.shield > 0 or u.energy > 0) and not u.is_structure
).amount
if score > best_score:
target = enemy
best_score = score

if target is not None:
self.emp_available = self.ai.time + 2
return Action(target.position, False, AbilityId.EMP_EMP)

return super().unit_solve_combat(unit, current_command)