diff --git a/worlds/grinch/Client.py b/worlds/grinch/Client.py index 20c9e7f2..d20df495 100644 --- a/worlds/grinch/Client.py +++ b/worlds/grinch/Client.py @@ -5,7 +5,7 @@ import NetUtils import copy import uuid import Utils -from worlds.grinch.RamHandler import UpdateMethod +from worlds.grinch.RamHandler import GrinchRamData, UpdateMethod from .Locations import grinch_locations, GrinchLocation from .Items import ( ALL_ITEMS_TABLE, @@ -143,6 +143,48 @@ class GrinchClient(BizHawkClient): async def set_auth(self, ctx: "BizHawkClientContext") -> None: await ctx.get_username() + async def read_ram_address(self, ctx: "BizHawkClientContext", data: GrinchRamData) -> int: + return int.from_bytes( + ( + await bizhawk.read( + ctx.bizhawk_ctx, + [ + ( + data.ram_address, + data.byte_size, + data.ram_area, + ) + ], + ) + )[0], + data.endian, + ) + + async def write_ram_address(self, ctx: "BizHawkClientContext", data: GrinchRamData, current_ram_address_value, ram_addr_dict: dict[int, list[int]]) -> None: + is_binary = True if not data.binary_bit_pos is None else False + + if is_binary: + current_ram_address_value = current_ram_address_value | (1 << data.binary_bit_pos) + + elif data.update_method == UpdateMethod.SET: + current_ram_address_value = data.value + + elif data.update_method == UpdateMethod.ADD: + # min() gets the lowest of a set, so we can't go over the max_count + current_ram_address_value += data.value + current_ram_address_value = min(current_ram_address_value, data.max_count) + + elif data.update_method == UpdateMethod.SUBTRACT: + # max() gets the highest of a set, so we can't go under the min_count + current_ram_address_value += data.value + current_ram_address_value = max(current_ram_address_value, data.min_count) + + # Write the updated value back into RAM + ram_addr_dict[data.ram_address] = [ + current_ram_address_value, + data.byte_size, + ] + async def game_watcher(self, ctx: "BizHawkClientContext") -> None: from CommonClient import logger @@ -260,51 +302,15 @@ class GrinchClient(BizHawkClient): ) continue - grinch_item_ram_data = ALL_ITEMS_TABLE[local_item] + grinch_item_data = ALL_ITEMS_TABLE[local_item] - for addr_to_update in grinch_item_ram_data.update_ram_addr: - is_binary = True if not addr_to_update.binary_bit_pos is None else False - - if addr_to_update.ram_address in ram_addr_dict.keys(): - current_ram_address_value = ram_addr_dict[addr_to_update.ram_address][0] + for data in grinch_item_data.ram_data: + if data.ram_address in ram_addr_dict.keys(): + current_ram_address_value = ram_addr_dict[data.ram_address][0] else: - current_ram_address_value = int.from_bytes( - ( - await bizhawk.read( - ctx.bizhawk_ctx, - [ - ( - addr_to_update.ram_address, - addr_to_update.byte_size, - addr_to_update.ram_area, - ) - ], - ) - )[0], - addr_to_update.endian, - ) + current_ram_address_value = self.read_ram_address(ctx, data) - if is_binary: - current_ram_address_value = current_ram_address_value | (1 << addr_to_update.binary_bit_pos) - - elif addr_to_update.update_method == UpdateMethod.SET: - current_ram_address_value = addr_to_update.value - - elif addr_to_update.update_method == UpdateMethod.ADD: - # min() gets the lowest of a set, so we can't go over the max_count - current_ram_address_value += addr_to_update.value - current_ram_address_value = min(current_ram_address_value, addr_to_update.max_count) - - elif addr_to_update.update_method == UpdateMethod.SUBTRACT: - # max() gets the highest of a set, so we can't go under the min_count - current_ram_address_value += addr_to_update.value - current_ram_address_value = max(current_ram_address_value, addr_to_update.min_count) - - # Write the updated value back into RAM - ram_addr_dict[addr_to_update.ram_address] = [ - current_ram_address_value, - addr_to_update.byte_size, - ] + self.write_ram_address(ctx, data, current_ram_address_value, ram_addr_dict) self.last_received_index += 1 diff --git a/worlds/grinch/Items.py b/worlds/grinch/Items.py index 45613b48..81387366 100644 --- a/worlds/grinch/Items.py +++ b/worlds/grinch/Items.py @@ -11,7 +11,7 @@ class GrinchItemData(NamedTuple): item_group: list[str] # arbituary that can be whatever it can be, basically the field/property for item groups id: Optional[int] classification: IC - update_ram_addr: list[GrinchRamData] + ram_data: list[GrinchRamData] class GrinchItem(Item): diff --git a/worlds/grinch/Rules.py b/worlds/grinch/Rules.py index 99a164b2..d2863022 100644 --- a/worlds/grinch/Rules.py +++ b/worlds/grinch/Rules.py @@ -10,9 +10,11 @@ from .Items import grinch_items # Adds all rules from access_rules_dict to locations def set_location_rules(world: World): all_locations = world.get_locations() + for location in all_locations: loc_rules = rules_dict[location.name] rule_list = interpret_rule(loc_rules, world.player) + for access_rule in rule_list: if rule_list.index(access_rule) == 0: add_rule(location, access_rule)