From 397693c8a896c84c02f59cfdfab79fdabaad4062 Mon Sep 17 00:00:00 2001 From: MarioSpore Date: Mon, 4 Aug 2025 23:03:31 -0400 Subject: [PATCH] Psuedocoding client stuff that includes the ram address & hex for the rom's name. --- worlds/grinch/Client.py | 51 ++++++++++++++++++++++++++++++++++++++++ worlds/grinch/Options.py | 44 ++++++++++++++++++---------------- worlds/grinch/Rules.py | 4 ++-- 3 files changed, 77 insertions(+), 22 deletions(-) diff --git a/worlds/grinch/Client.py b/worlds/grinch/Client.py index e69de29b..000805d2 100644 --- a/worlds/grinch/Client.py +++ b/worlds/grinch/Client.py @@ -0,0 +1,51 @@ +from typing import TYPE_CHECKING + +from NetUtils import ClientStatus + +import worlds._bizhawk as bizhawk +from worlds._bizhawk.client import BizHawkClient +from worlds.Files import APDeltaPatch +if TYPE_CHECKING: + from worlds._bizhawk.context import BizHawkClientContext + + +class GrinchClient(BizHawkClient): + game = "The Grinch" + system = "PSX" + patch_suffix = ".apgrinch" + + async def validate_rom(self, ctx: "BizHawkClientContext") -> bool: + grinch_identifier_ram_address: int = 0x00928C + bytes_expected: bytes = bytes.fromhex("53554C533131305F3B37392E") + try: + bytes_actual: bytes = (await bizhawk.read(ctx.bizhawk_ctx, [( + grinch_identifier_ram_address, len(bytes_expected), "MainRAM" + )]))[0] + except Exception(): + return True + + async def game_watcher(self, ctx: "BizHawkClientContext") -> None: + try: + # Read save data + save_data = await bizhawk.read( + ctx.bizhawk_ctx, + [(0x3000100, 20, "System Bus")] + )[0] + + # Check locations + if save_data[2] & 0x04: + await ctx.send_msgs([{ + "cmd": "LocationChecks", + "locations": [23] + }]) + + # Send game clear + if not ctx.finished_game and (save_data[5] & 0x01): + await ctx.send_msgs([{ + "cmd": "StatusUpdate", + "status": ClientStatus.CLIENT_GOAL + }]) + + except bizhawk.RequestFailedError: + # The connector didn't respond. Exit handler and return to main loop to reconnect + pass \ No newline at end of file diff --git a/worlds/grinch/Options.py b/worlds/grinch/Options.py index b614ae1f..7d90b07f 100644 --- a/worlds/grinch/Options.py +++ b/worlds/grinch/Options.py @@ -28,31 +28,31 @@ class Missionsanity(Choice): option_both = 3 default = 1 -# class StartingArea(Choice): -# """ -# Here, you can select which area you'll start the game with. -# Whichever one you pick is the region you'll have access to at the start of the Multiworld. -# """ -# option_whoville = 0 -# option_who_forest = 1 -# option_who_dump = 2 -# option_who_lake = 3 -# default = 0 -# display_name = "Starting Area" +class StartingArea(Choice): + """ + Here, you can select which area you'll start the game with. + Whichever one you pick is the region you'll have access to at the start of the Multiworld. + """ + option_whoville = 0 + option_who_forest = 1 + option_who_dump = 2 + option_who_lake = 3 + default = 0 + display_name = "Starting Area" -# class Supadow(Toggle): -# """Enables completing minigames through the Supadows in Mount Crumpit as checks. (9 locations) [NOT IMPLEMENTED]""" -# display_name = "Supadow Minigame Locations"# +class Supadow(Toggle): + """Enables completing minigames through the Supadows in Mount Crumpit as checks. (9 locations) [NOT IMPLEMENTED]""" + display_name = "Supadow Minigame Locations"# -# class Gifts(Toggle): -# """Missions that require you to squash every present in a level. (4 locations) [NOT IMPLEMENTED]""" -# display_name = "Gift Collection Locations" +class Gifts(Toggle): + """Missions that require you to squash every present in a level. (4 locations) [NOT IMPLEMENTED]""" + display_name = "Gift Collection Locations" -# class Movesanity(Toggle): -# """Randomizes Grinch's moveset along with randomizing max into the pool. [NOT IMPLEMENTED]""" -# display_name = "Movesanity" +class Movesanity(Toggle): + """Randomizes Grinch's moveset along with randomizing max into the pool. [NOT IMPLEMENTED]""" + display_name = "Movesanity" class UnlimitedRottenEggs(Toggle): @@ -72,3 +72,7 @@ class GrinchOptions(PerGameCommonOptions):#DeathLinkMixin unlimited_rotten_eggs: UnlimitedRottenEggs ring_link: RingLinkOption trap_link: TrapLinkOption + minigamesanity: Supadow + giftsanity: Gifts + movesanity: Movesanity + starting_area: StartingArea diff --git a/worlds/grinch/Rules.py b/worlds/grinch/Rules.py index a0816527..be531ef9 100644 --- a/worlds/grinch/Rules.py +++ b/worlds/grinch/Rules.py @@ -63,10 +63,10 @@ rules_dict: dict[str,list[list[str]]] = { "Enter the Mayor's Villa": [ [] ], - "Smashing Snowmen": [ + "Shuffling The Mail": [ [] ], - "Shuffling The Mail": [ + "Smashing Snowmen": [ [] ], "Painting The Mayor's Posters": [