Skip to content
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
34 changes: 29 additions & 5 deletions worlds/gstla/BizClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class _MemDomain(str, Enum):
ROM = 'ROM'

class _DataLocations(IntEnum):
IN_GAME = (0x428, 0x2, 0x0, _MemDomain.EWRAM)
MAP_ID = (0x428, 0x2, 0x0, _MemDomain.EWRAM)
ENTRANCE_ID = (0x42A, 0x2, 0x0, _MemDomain.EWRAM)
DJINN_FLAGS = (FLAG_START + (0x30 >> 3), 0x0A, 0x30, _MemDomain.EWRAM)
AP_ITEM_SLOT = (0xA96, 0x2, 0x0, _MemDomain.EWRAM)
# two unused bytes in save data
Expand Down Expand Up @@ -293,6 +294,8 @@ def __init__(self):
self.coop: int = 0
self.remote_blacklist: Set[int] = remote_blacklist
self.goals = GoalManager()
self.last_map: int = 0
self.last_entrance: int = 0

async def validate_rom(self, ctx: 'BizHawkClientContext'):
from worlds._bizhawk.context import TextCategory
Expand Down Expand Up @@ -338,10 +341,9 @@ async def _load_djinn(self, ctx: 'BizHawkClientContext') -> None:
self.djinn_ram_to_rom[rom_flag] = djinn_flag

def _is_in_game(self, data: List[bytes]) -> bool:
# What the emo tracker pack does; seems like it also verifies the player
# has opened a save file
flag = int.from_bytes(data[_DataLocations.IN_GAME], 'little')
return flag > 1
# Map ID 0x00 and 0x01 are Title Screen and Clear Data respectively, everything greater is safe
current_map = int.from_bytes(data[_DataLocations.MAP_ID], 'little')
return current_map > 1

def get_goal_flags_key(self, ctx: 'BizHawkClientContext') -> str:
return f"gstla_goal_flags_status_{ctx.slot}_{ctx.team}"
Expand All @@ -355,6 +357,9 @@ def get_djinn_location_key(self, ctx: 'BizHawkClientContext') -> str:
def get_djinn_possessed_key(self, ctx: 'BizHawkClientContext') -> str:
return f"gstla_djinn_held_{ctx.slot}_{ctx.team}"

def get_map_info_key(self, ctx: 'BizHawkClientContext') -> str:
return f"gstla_map_info_{ctx.slot}_{ctx.team}"

def check_summon_count(self, ctx: "BizHawkClientContext") -> None:
if self.summon_item_index >= len(ctx.items_received):
return
Expand Down Expand Up @@ -606,6 +611,25 @@ async def game_watcher(self, ctx: 'BizHawkClientContext') -> None:

await self.goals.check_goals(self, ctx)

current_map = int.from_bytes(result[_DataLocations.MAP_ID], 'little')
current_entrance = int.from_bytes(result[_DataLocations.ENTRANCE_ID], 'little')
if current_map != self.last_map or current_entrance != self.last_entrance:
self.last_map = current_map
self.last_entrance = current_entrance
await ctx.send_msgs([{
"cmd": "Set",
"key": self.get_map_info_key(ctx),
"default": {},
"want_reply": False,
"operations": [{
"operation": "replace",
"value": {
"map": current_map,
"entrance": current_entrance
}
}]
}])

if not ctx.finished_game and self.goals.is_done(self, ctx):
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])
ctx.finished_game = True
8 changes: 6 additions & 2 deletions worlds/gstla/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,9 +617,13 @@ class AutoRun(Toggle):

class Coop(Choice):
"""Enables cooping a seed by making local items the same as remote items, enabling
your friends to receive items you pick up. Also helpful if trying to play a world from multiple devices.
your friends to receive items you pick up. Also helpful if trying to play a world from multiple devices.
You will still need to pickup djinn the other person picks up.
off - vanilla

Note: Due to current limitations, if you are enabling this to coop a seed and you want to use this game's PopTracker pack,
you should turn automatic tabbing off in the pack's settings to avoid constant map changes.

off - Vanilla
progression - Only progression items are treated as remote items
prog_useful - Progression and useful items are treated as remote items
all - All items are treated as remote items
Expand Down