Skip to content
Closed
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
45 changes: 43 additions & 2 deletions sc2/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from s2clientprotocol import raw_pb2 as raw_pb
from s2clientprotocol import sc2api_pb2 as sc_pb
from s2clientprotocol import spatial_pb2 as spatial_pb
from s2clientprotocol import ui_pb2 as ui_pb

from sc2.action import combine_actions
from sc2.data import ActionResult, ChatChannel, Race, Result, Status
Expand Down Expand Up @@ -44,8 +45,9 @@ def __init__(self, ws, save_replay_path: str = None):
self._debug_spheres = []

self._renderer = None
self.raw_affects_selection = False

self.raw_affects_selection = True
self.enable_feature_layer = True

@property
def in_game(self) -> bool:
return self._status in {Status.in_game, Status.in_replay}
Expand Down Expand Up @@ -118,7 +120,46 @@ async def leave(self):
except (ProtocolError, ConnectionAlreadyClosed):
if is_resign:
raise

async def unload_unit(self, transporter_unit: Unit, cargo_unit: Unit = False):
"""
Unloads single unit passed by cargo_unit or first unit in transporter if not cargo_unit passed
transporter_unit includes all units, which can unload cargo:
warp prism, medivac, bunker, command center, command center flying, planetary fortress, droppenlord, nydlus

Usage:
self.client.unload_unit(transporter_unit, cargo_unit)
self.client.unload_unit(transporter_unit) # unloads first one
Comment on lines +131 to +132
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would you prefer this function to be in the client.py instead of bot_ai.py?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bot_ai.py would be my second choice
In my first comment I list why client.py is my choice, what are arguments in favor of bot_ai.py?


"""
assert isinstance(transporter_unit, Unit)
assert isinstance(cargo_unit, (bool, Unit))

if not transporter_unit.passengers:
return

if isinstance(cargo_unit, bool):
unload_unit_index = 0
if isinstance(cargo_unit, Unit):
unload_unit_index = next((index for index, unit in enumerate(transporter_unit._proto.passengers) if unit.tag == cargo_unit.tag), 0)

await self._execute(
action=sc_pb.RequestAction(
actions=[
sc_pb.Action(
action_raw=raw_pb.ActionRaw(
unit_command=raw_pb.ActionRawUnitCommand(ability_id=0, unit_tags=[transporter_unit.tag])
)
),
sc_pb.Action(
action_ui=ui_pb.ActionUI(
cargo_panel=ui_pb.ActionCargoPanelUnload(unit_index=unload_unit_index)
)
),
]
)
)
Comment on lines +146 to +161
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This executes the command instantly. Is there a better way to bundle it with other unit commands?
Currently actions such as unit.move(position) and structure.train(unittype) are collected and sent once to the API at the end of the step. Is it also possible with this?

Copy link
Contributor Author

@SamOgon-one SamOgon-one Oct 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be rare situation where someone use more than one unload command in same frame over a game.
The most usage I have seen is a bot that has 4 prisms and with human eye his unloads aren't synchronized.


async def save_replay(self, path):
logger.debug("Requesting replay from server")
result = await self._execute(save_replay=sc_pb.RequestSaveReplay())
Expand Down