diff --git a/MultiClient.py b/MultiClient.py index 7ef16b02..e91f6f7e 100644 --- a/MultiClient.py +++ b/MultiClient.py @@ -19,7 +19,7 @@ import shutil from random import randrange import Shops -from Utils import get_item_name_from_id, get_location_name_from_address, ReceivedItem +from Utils import get_item_name_from_id, get_location_name_from_address, ReceivedItem, int16_as_bytes exit_func = atexit.register(input, "Press enter to close.") @@ -67,6 +67,8 @@ class Context(): self.forfeit_mode = '' self.remaining_mode = '' self.hint_points = 0 + self.treasure_count = 0 + self.requires_treasure_count = None # End WebUI Stuff self.exit_event = asyncio.Event() @@ -990,6 +992,20 @@ async def process_server_cmd(ctx: Context, cmd, args): elif cmd == 'HintPointUpdate': ctx.hint_points = args[0] + elif cmd == 'TreasureCount': + try: + print(ctx.requires_treasure_count, 'OKAY') + if ctx.requires_treasure_count is None: + ctx.requires_treasure_count = (await snes_read(ctx, 0x180165, size=1))[0] >= 0x80 + print(ctx.requires_treasure_count, ctx.treasure_count, args[0]) + if ctx.requires_treasure_count and ctx.treasure_count < args[0]: + ctx.treasure_count = args[0] + print(int16_as_bytes(ctx.treasure_count)) + snes_buffered_write(ctx, WRAM_START + 0xF418, bytes(int16_as_bytes(ctx.treasure_count))) + await snes_flush_writes(ctx) + except Exception as e: + print(e) + else: logger.debug(f"unknown command {args}") diff --git a/MultiServer.py b/MultiServer.py index ed423689..168aefb5 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -93,6 +93,7 @@ class Context(Node): self.hint_cost = hint_cost self.location_check_points = location_check_points self.hints_used = collections.defaultdict(int) + self.treasure_count = collections.defaultdict(int) self.hints: typing.Dict[typing.Tuple[int, int], typing.Set[Utils.Hint]] = collections.defaultdict(set) self.forfeit_mode: str = forfeit_mode self.remaining_mode: str = remaining_mode @@ -228,6 +229,7 @@ class Context(Node): d = { "rom_names": list(self.rom_names.items()), "received_items": tuple((k, v) for k, v in self.received_items.items()), + "treasure_count": tuple((k, v) for k, v in self.treasure_count.items()), "hints_used": tuple((key, value) for key, value in self.hints_used.items()), "hints": tuple( (key, list(hint.re_check(self, key[0]) for hint in value)) for key, value in self.hints.items()), @@ -256,6 +258,8 @@ class Context(Node): return received_items = {tuple(k): [ReceivedItem(*i) for i in v] for k, v in savedata["received_items"]} + print(savedata["treasure_count"]) + self.treasure_count = {tuple(k): v for k, v in savedata["treasure_count"]} self.received_items = received_items self.hints_used.update({tuple(key): value for key, value in savedata["hints_used"]}) @@ -505,7 +509,6 @@ def register_location_checks(ctx: Context, team: int, slot: int, locations): if recvd_item.location == location and recvd_item.player == slot: found = True break - if not found: new_item = ReceivedItem(target_item, location, slot) recvd_items.append(new_item) @@ -521,6 +524,15 @@ def register_location_checks(ctx: Context, team: int, slot: int, locations): if client.team == team and client.wants_item_notification: asyncio.create_task( ctx.send_msgs(client, [['ItemFound', (target_item, location, slot)]])) + try: + print('TRY', target_item, get_item_name_from_id(target_item)) + if 'Triforce Piece' in get_item_name_from_id(target_item): + print('PIECE', team, slot, ctx.treasure_count.get(team), 'No Pieces') + ctx.treasure_count[team] = ctx.treasure_count.get(team, 0) + 1 + print('NOW', ctx.treasure_count[(team, slot)]) + ctx.broadcast_team(team, [['TreasureCount', (ctx.treasure_count[team],)]]) + except Exception as e: + print(e) ctx.location_checks[team, slot] |= known_locations send_new_items(ctx) @@ -1046,6 +1058,11 @@ async def process_client_cmd(ctx: Context, client: Client, cmd, args): if items: reply.append(['ReceivedItems', (0, tuplize_received_items(items))]) client.send_index = len(items) + try: + if ctx.treasure_count.get(client.team): + ctx.broadcast_team(team, [['TreasureCount', (ctx.treasure_count[client.team],)]]) + except Exception as e: + print(e) await ctx.send_msgs(client, reply) await on_client_joined(ctx, client) @@ -1055,6 +1072,12 @@ async def process_client_cmd(ctx: Context, client: Client, cmd, args): if items: client.send_index = len(items) await ctx.send_msgs(client, [['ReceivedItems', (0, tuplize_received_items(items))]]) + try: + print('TRY2') + if ctx.treasure_count.get((team)): + ctx.broadcast_team(team, [['TreasureCount', (ctx.treasure_count[team],)]]) + except Exception as e: + print(e) elif cmd == 'LocationChecks': if type(args) is not list: diff --git a/Rom.py b/Rom.py index 19143a87..d19230d7 100644 --- a/Rom.py +++ b/Rom.py @@ -1105,7 +1105,11 @@ def patch_rom(world, rom, player, team, enemized): # set up goals for treasure hunt rom.write_bytes(0x180163, [0x0E, 0x28] if world.treasure_hunt_icon[player] == 'Triforce Piece' else [0x0D, 0x28]) - rom.write_byte(0x180166, world.treasure_hunt_count[player] % 999) + rom.write_int16(0x180166, world.treasure_hunt_count[player]) + if 'local' in world.goal[player]: + total_treasures = sum([world.treasure_hunt_count[x] for x in range(1, world.players + 1)]) + rom.write_byte(0x180165, rom.read_byte(0x180165) | 0x80) + rom.write_int16(0x180166, total_treasures) rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled) rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed @@ -1660,7 +1664,8 @@ def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, tri rom.write_byte(0x65561, {'red': 0x05, 'blue': 0x0D, 'green': 0x19, 'yellow': 0x09}[color]) # set triforcehud - rom.write_byte(0x180165, {'normal': 0x00, 'hide_goal': 0x01, 'hide_total': 0x02, 'hide_both': 0x03}[triforcehud]) + triforce_flag = (rom.read_byte(0x180165) & 0x80) | {'normal': 0x00, 'hide_goal': 0x01, 'hide_total': 0x02, 'hide_both': 0x03}[triforcehud] + rom.write_byte(0x180165, triforce_flag) if z3pr: def buildAndRandomize(option_name, mode):