156 lines
4.6 KiB
Python
156 lines
4.6 KiB
Python
"""
|
|
This class is very experimental and probably not up to date and needs to be refurbished.
|
|
If it works, you can watch replays with it.
|
|
"""
|
|
|
|
# pylint: disable=W0201,W0212
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, List, Union
|
|
|
|
from .bot_ai_internal import BotAIInternal
|
|
from .data import Alert, Result
|
|
from .game_data import GameData
|
|
from .position import Point2
|
|
from .unit import Unit
|
|
from .units import Units
|
|
|
|
if TYPE_CHECKING:
|
|
from .client import Client
|
|
from .game_info import GameInfo
|
|
|
|
|
|
class ObserverAI(BotAIInternal):
|
|
"""Base class for bots."""
|
|
|
|
@property
|
|
def time(self) -> float:
|
|
""" Returns time in seconds, assumes the game is played on 'faster' """
|
|
return self.state.game_loop / 22.4 # / (1/1.4) * (1/16)
|
|
|
|
@property
|
|
def time_formatted(self) -> str:
|
|
""" Returns time as string in min:sec format """
|
|
t = self.time
|
|
return f"{int(t // 60):02}:{int(t % 60):02}"
|
|
|
|
@property
|
|
def game_info(self) -> GameInfo:
|
|
""" See game_info.py """
|
|
return self._game_info
|
|
|
|
@property
|
|
def game_data(self) -> GameData:
|
|
""" See game_data.py """
|
|
return self._game_data
|
|
|
|
@property
|
|
def client(self) -> Client:
|
|
""" See client.py """
|
|
return self._client
|
|
|
|
def alert(self, alert_code: Alert) -> bool:
|
|
"""
|
|
Check if alert is triggered in the current step.
|
|
Possible alerts are listed here https://github.com/Blizzard/s2client-proto/blob/e38efed74c03bec90f74b330ea1adda9215e655f/s2clientprotocol/sc2api.proto#L679-L702
|
|
|
|
Example use:
|
|
|
|
from sc2.data import Alert
|
|
if self.alert(Alert.AddOnComplete):
|
|
print("Addon Complete")
|
|
|
|
Alert codes::
|
|
|
|
AlertError
|
|
AddOnComplete
|
|
BuildingComplete
|
|
BuildingUnderAttack
|
|
LarvaHatched
|
|
MergeComplete
|
|
MineralsExhausted
|
|
MorphComplete
|
|
MothershipComplete
|
|
MULEExpired
|
|
NuclearLaunchDetected
|
|
NukeComplete
|
|
NydusWormDetected
|
|
ResearchComplete
|
|
TrainError
|
|
TrainUnitComplete
|
|
TrainWorkerComplete
|
|
TransformationComplete
|
|
UnitUnderAttack
|
|
UpgradeComplete
|
|
VespeneExhausted
|
|
WarpInComplete
|
|
|
|
:param alert_code:
|
|
"""
|
|
assert isinstance(alert_code, Alert), f"alert_code {alert_code} is no Alert"
|
|
return alert_code.value in self.state.alerts
|
|
|
|
@property
|
|
def start_location(self) -> Point2:
|
|
"""
|
|
Returns the spawn location of the bot, using the position of the first created townhall.
|
|
This will be None if the bot is run on an arcade or custom map that does not feature townhalls at game start.
|
|
"""
|
|
return self.game_info.player_start_location
|
|
|
|
@property
|
|
def enemy_start_locations(self) -> List[Point2]:
|
|
"""Possible start locations for enemies."""
|
|
return self.game_info.start_locations
|
|
|
|
async def on_unit_destroyed(self, unit_tag: int):
|
|
"""
|
|
Override this in your bot class.
|
|
This will event will be called when a unit (or structure, friendly or enemy) dies.
|
|
For enemy units, this only works if the enemy unit was in vision on death.
|
|
|
|
:param unit_tag:
|
|
"""
|
|
|
|
async def on_unit_created(self, unit: Unit):
|
|
"""Override this in your bot class. This function is called when a unit is created.
|
|
|
|
:param unit:"""
|
|
|
|
async def on_building_construction_started(self, unit: Unit):
|
|
"""
|
|
Override this in your bot class.
|
|
This function is called when a building construction has started.
|
|
|
|
:param unit:
|
|
"""
|
|
|
|
async def on_building_construction_complete(self, unit: Unit):
|
|
"""
|
|
Override this in your bot class. This function is called when a building
|
|
construction is completed.
|
|
|
|
:param unit:
|
|
"""
|
|
|
|
async def on_start(self):
|
|
"""
|
|
Override this in your bot class. This function is called after "on_start".
|
|
At this point, game_data, game_info and the first iteration of game_state (self.state) are available.
|
|
"""
|
|
|
|
async def on_step(self, iteration: int):
|
|
"""
|
|
You need to implement this function!
|
|
Override this in your bot class.
|
|
This function is called on every game step (looped in realtime mode).
|
|
|
|
:param iteration:
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
async def on_end(self, game_result: Result):
|
|
"""Override this in your bot class. This function is called at the end of a game.
|
|
|
|
:param game_result:"""
|