From ed721dd0c14aec3cb332a010f52bca43fddc2886 Mon Sep 17 00:00:00 2001 From: Alex Nordstrom Date: Sat, 30 Nov 2024 22:58:10 -0500 Subject: [PATCH] LADX: Implement various upstream adjustments (#3829) * magnifying lens changes https://github.com/daid/LADXR/pull/156 * restore enemy visibility in mermaid statue cave https://github.com/daid/LADXR/pull/155 * mermaid statue scale bugfix https://github.com/daid/LADXR/pull/163 * restore vanilla map when rooster is an item https://github.com/daid/LADXR/pull/132 * fix * fixes to magnifying lens changes * load marin singing even if you have marin date https://github.com/daid/LADXR/commit/4feb3099a3f3a144739094f88a4024def6f79767 * Revert "load marin singing even if you have marin date" This reverts commit a7a546ed3f7a2b9c9bcb095984cc64319a4f7855. * always patch tradequest not upstream, but included in this PR because it touches the same parts of the code. https://discord.com/channels/731205301247803413/1227373762412937347 * marin date fix * fix logic --- worlds/ladx/LADXR/generator.py | 10 ++- worlds/ladx/LADXR/locations/birdKey.py | 17 ------ worlds/ladx/LADXR/locations/boomerangGuy.py | 5 -- worlds/ladx/LADXR/logic/overworld.py | 45 ++++++++------ worlds/ladx/LADXR/logic/requirements.py | 3 + worlds/ladx/LADXR/patches/maptweaks.py | 13 ++++ worlds/ladx/LADXR/patches/songs.py | 4 ++ worlds/ladx/LADXR/patches/tradeSequence.py | 68 ++++++++++++++++++--- worlds/ladx/Options.py | 2 +- 9 files changed, 110 insertions(+), 57 deletions(-) diff --git a/worlds/ladx/LADXR/generator.py b/worlds/ladx/LADXR/generator.py index 69e856f3..f0f042c6 100644 --- a/worlds/ladx/LADXR/generator.py +++ b/worlds/ladx/LADXR/generator.py @@ -153,7 +153,9 @@ def generateRom(args, world: "LinksAwakeningWorld"): if world.ladxr_settings.witch: patches.witch.updateWitch(rom) patches.softlock.fixAll(rom) - patches.maptweaks.tweakMap(rom) + if not world.ladxr_settings.rooster: + patches.maptweaks.tweakMap(rom) + patches.maptweaks.tweakBirdKeyRoom(rom) patches.chest.fixChests(rom) patches.shop.fixShop(rom) patches.rooster.patchRooster(rom) @@ -176,11 +178,7 @@ def generateRom(args, world: "LinksAwakeningWorld"): patches.songs.upgradeMarin(rom) patches.songs.upgradeManbo(rom) patches.songs.upgradeMamu(rom) - if world.ladxr_settings.tradequest: - patches.tradeSequence.patchTradeSequence(rom, world.ladxr_settings.boomerang) - else: - # Monkey bridge patch, always have the bridge there. - rom.patch(0x00, 0x333D, assembler.ASM("bit 4, e\njr Z, $05"), b"", fill_nop=True) + patches.tradeSequence.patchTradeSequence(rom, world.ladxr_settings) patches.bowwow.fixBowwow(rom, everywhere=world.ladxr_settings.bowwow != 'normal') if world.ladxr_settings.bowwow != 'normal': patches.bowwow.bowwowMapPatches(rom) diff --git a/worlds/ladx/LADXR/locations/birdKey.py b/worlds/ladx/LADXR/locations/birdKey.py index 12418c61..0dbdd865 100644 --- a/worlds/ladx/LADXR/locations/birdKey.py +++ b/worlds/ladx/LADXR/locations/birdKey.py @@ -1,23 +1,6 @@ from .droppedKey import DroppedKey -from ..roomEditor import RoomEditor -from ..assembler import ASM class BirdKey(DroppedKey): def __init__(self): super().__init__(0x27A) - - def patch(self, rom, option, *, multiworld=None): - super().patch(rom, option, multiworld=multiworld) - - re = RoomEditor(rom, self.room) - - # Make the bird key accessible without the rooster - re.removeObject(1, 6) - re.removeObject(2, 6) - re.removeObject(3, 5) - re.removeObject(3, 6) - re.moveObject(1, 5, 2, 6) - re.moveObject(2, 5, 3, 6) - re.addEntity(3, 5, 0x9D) - re.store(rom) diff --git a/worlds/ladx/LADXR/locations/boomerangGuy.py b/worlds/ladx/LADXR/locations/boomerangGuy.py index 92d76ceb..23fcc867 100644 --- a/worlds/ladx/LADXR/locations/boomerangGuy.py +++ b/worlds/ladx/LADXR/locations/boomerangGuy.py @@ -24,11 +24,6 @@ class BoomerangGuy(ItemInfo): # But SHIELD, BOMB and MAGIC_POWDER would most likely break things. # SWORD and POWER_BRACELET would most likely introduce the lv0 shield/bracelet issue def patch(self, rom, option, *, multiworld=None): - # Always have the boomerang trade guy enabled (normally you need the magnifier) - rom.patch(0x19, 0x05EC, ASM("ld a, [wTradeSequenceItem]\ncp $0E"), ASM("ld a, $0E\ncp $0E"), fill_nop=True) # show the guy - rom.patch(0x00, 0x3199, ASM("ld a, [wTradeSequenceItem]\ncp $0E"), ASM("ld a, $0E\ncp $0E"), fill_nop=True) # load the proper room layout - rom.patch(0x19, 0x05F4, ASM("ld a, [wTradeSequenceItem2]\nand a"), ASM("xor a"), fill_nop=True) - if self.setting == 'trade': inv = INVENTORY_MAP[option] # Patch the check if you traded back the boomerang (so traded twice) diff --git a/worlds/ladx/LADXR/logic/overworld.py b/worlds/ladx/LADXR/logic/overworld.py index 551cf835..39727960 100644 --- a/worlds/ladx/LADXR/logic/overworld.py +++ b/worlds/ladx/LADXR/logic/overworld.py @@ -61,9 +61,9 @@ class World: self._addEntrance("banana_seller", sword_beach, banana_seller, r.bush) boomerang_cave = Location("Boomerang Cave") if options.boomerang == 'trade': - Location().add(BoomerangGuy()).connect(boomerang_cave, OR(BOOMERANG, HOOKSHOT, MAGIC_ROD, PEGASUS_BOOTS, FEATHER, SHOVEL)) + Location().add(BoomerangGuy()).connect(boomerang_cave, AND(r.shuffled_magnifier, OR(BOOMERANG, HOOKSHOT, MAGIC_ROD, PEGASUS_BOOTS, FEATHER, SHOVEL))) elif options.boomerang == 'gift': - Location().add(BoomerangGuy()).connect(boomerang_cave, None) + Location().add(BoomerangGuy()).connect(boomerang_cave, r.shuffled_magnifier) self._addEntrance("boomerang_cave", sword_beach, boomerang_cave, BOMB) self._addEntranceRequirementExit("boomerang_cave", None) # if exiting, you do not need bombs @@ -167,7 +167,9 @@ class World: prairie_island_seashell = Location().add(Seashell(0x0A6)).connect(ukuku_prairie, AND(FLIPPERS, r.bush)) # next to lv3 Location().add(Seashell(0x08B)).connect(ukuku_prairie, r.bush) # next to seashell house Location().add(Seashell(0x0A4)).connect(ukuku_prairie, PEGASUS_BOOTS) # smash into tree next to phonehouse - self._addEntrance("castle_jump_cave", ukuku_prairie, Location().add(Chest(0x1FD)), OR(AND(FEATHER, PEGASUS_BOOTS), ROOSTER)) # left of the castle, 5 holes turned into 3 + self._addEntrance("castle_jump_cave", ukuku_prairie, Location().add(Chest(0x1FD)), ROOSTER) + if not options.rooster: + self._addEntranceRequirement("castle_jump_cave", AND(FEATHER, PEGASUS_BOOTS)) # left of the castle, 5 holes turned into 3 Location().add(Seashell(0x0B9)).connect(ukuku_prairie, POWER_BRACELET) # under the rock left_bay_area = Location() @@ -353,7 +355,7 @@ class World: self._addEntrance("d4", d4_entrance, None, ANGLER_KEY) self._addEntranceRequirementExit("d4", FLIPPERS) # if exiting, you can leave with flippers without opening the dungeon mambo = Location().connect(Location().add(Song(0x2FD)), AND(OCARINA, FLIPPERS)) # Manbo's Mambo - self._addEntrance("mambo", d4_entrance, mambo, FLIPPERS) + self._addEntrance("mambo", d4_entrance, mambo, FLIPPERS) # Raft game. raft_house = Location("Raft House") @@ -379,7 +381,9 @@ class World: self._addEntrance("rooster_house", outside_rooster_house, None, None) bird_cave = Location() bird_key = Location().add(BirdKey()) - bird_cave.connect(bird_key, OR(AND(FEATHER, COUNT(POWER_BRACELET, 2)), ROOSTER)) + bird_cave.connect(bird_key, ROOSTER) + if not options.rooster: + bird_cave.connect(bird_key, AND(FEATHER, COUNT(POWER_BRACELET, 2))) # elephant statue added if options.logic != "casual": bird_cave.connect(lower_right_taltal, None, one_way=True) # Drop in a hole at bird cave self._addEntrance("bird_cave", outside_rooster_house, bird_cave, None) @@ -468,7 +472,7 @@ class World: swamp.connect(writes_hut_outside, HOOKSHOT, one_way=True) # hookshot the sign in front of writes hut graveyard_heartpiece.connect(graveyard_cave_right, FEATHER) # jump to the bottom right tile around the blocks graveyard_heartpiece.connect(graveyard_cave_right, OR(HOOKSHOT, BOOMERANG)) # push bottom block, wall clip and hookshot/boomerang corner to grab item - + self._addEntranceRequirement("mamu", AND(FEATHER, POWER_BRACELET)) # can clear the gaps at the start with just feather, can reach bottom left sign with a well timed jump while wall clipped self._addEntranceRequirement("prairie_madbatter_connector_entrance", AND(OR(FEATHER, ROOSTER), OR(MAGIC_POWDER, BOMB))) # use bombs or powder to get rid of a bush on the other side by jumping across and placing the bomb/powder before you fall into the pit fisher_under_bridge.connect(bay_water, AND(TRADING_ITEM_FISHING_HOOK, FLIPPERS)) # can talk to the fisherman from the water when the boat is low (requires swimming up out of the water a bit) @@ -476,9 +480,10 @@ class World: castle_inside.connect(kanalet_chain_trooper, BOOMERANG, one_way=True) # kill the ball and chain trooper from the left side, then use boomerang to grab the dropped item animal_village_bombcave_heartpiece.connect(animal_village_bombcave, AND(PEGASUS_BOOTS, FEATHER)) # jump across horizontal 4 gap to heart piece desert_lanmola.connect(desert, BOMB) # use bombs to kill lanmola - + d6_connector_left.connect(d6_connector_right, AND(OR(FLIPPERS, PEGASUS_BOOTS), FEATHER)) # jump the gap in underground passage to d6 left side to skip hookshot - bird_key.connect(bird_cave, COUNT(POWER_BRACELET, 2)) # corner walk past the one pit on the left side to get to the elephant statue + if not options.rooster: + bird_key.connect(bird_cave, COUNT(POWER_BRACELET, 2)) # corner walk past the one pit on the left side to get to the elephant statue fire_cave_bottom.connect(fire_cave_top, PEGASUS_BOOTS, one_way=True) # flame skip if options.logic == 'glitched' or options.logic == 'hell': @@ -502,9 +507,9 @@ class World: tiny_island.connect(left_bay_area, AND(FEATHER, r.bush)) # jesus jump around bay_madbatter_connector_exit.connect(bay_madbatter_connector_entrance, FEATHER, one_way=True) # jesus jump (3 screen) through the underground passage leading to martha's bay mad batter self._addEntranceRequirement("prairie_madbatter_connector_entrance", AND(FEATHER, POWER_BRACELET)) # villa buffer into the top side of the bush, then pick it up - + ukuku_prairie.connect(richard_maze, OR(BOMB, BOOMERANG, MAGIC_POWDER, MAGIC_ROD, SWORD), one_way=True) # break bushes on north side of the maze, and 1 pit buffer into the maze - fisher_under_bridge.connect(bay_water, AND(BOMB, FLIPPERS)) # can bomb trigger the item without having the hook + fisher_under_bridge.connect(bay_water, AND(BOMB, FLIPPERS)) # can bomb trigger the item without having the hook animal_village.connect(ukuku_prairie, FEATHER) # jesus jump below_right_taltal.connect(next_to_castle, FEATHER) # jesus jump (north of kanalet castle phonebooth) animal_village_connector_right.connect(animal_village_connector_left, FEATHER) # text clip past the obstacles (can go both ways), feather to wall clip the obstacle without triggering text or shaq jump in bottom right corner if text is off @@ -519,12 +524,12 @@ class World: obstacle_cave_inside_chest.connect(obstacle_cave_inside, FEATHER) # jump to the rightmost pits + 1 pit buffer to jump across obstacle_cave_exit.connect(obstacle_cave_inside, FEATHER) # 1 pit buffer above boots crystals to get past lower_right_taltal.connect(hibiscus_item, AND(TRADING_ITEM_PINEAPPLE, BOMB), one_way=True) # bomb trigger papahl from below ledge, requires pineapple - + self._addEntranceRequirement("heartpiece_swim_cave", FEATHER) # jesus jump into the cave entrance after jumping down the ledge, can jesus jump back to the ladder 1 screen below self._addEntranceRequirement("mambo", FEATHER) # jesus jump from (unlocked) d4 entrance to mambo's cave entrance outside_raft_house.connect(below_right_taltal, FEATHER, one_way=True) # jesus jump from the ledge at raft to the staircase 1 screen south - self._addEntranceRequirement("multichest_left", FEATHER) # jesus jump past staircase leading up the mountain + self._addEntranceRequirement("multichest_left", FEATHER) # jesus jump past staircase leading up the mountain outside_rooster_house.connect(lower_right_taltal, FEATHER) # jesus jump (1 or 2 screen depending if angler key is used) to staircase leading up the mountain d7_platau.connect(water_cave_hole, None, one_way=True) # use save and quit menu to gain control while falling to dodge the water cave hole mountain_bridge_staircase.connect(outside_rooster_house, AND(PEGASUS_BOOTS, FEATHER)) # cross bridge to staircase with pit buffer to clip bottom wall and jump across @@ -547,7 +552,7 @@ class World: graveyard.connect(forest, OR(PEGASUS_BOOTS, HOOKSHOT)) # boots bonk witches hut, or hookshot spam across the pit graveyard_cave_left.connect(graveyard_cave_right, HOOKSHOT) # hookshot spam over the pit graveyard_cave_right.connect(graveyard_cave_left, PEGASUS_BOOTS, one_way=True) # boots bonk off the cracked block - + self._addEntranceRequirementEnter("mamu", AND(PEGASUS_BOOTS, POWER_BRACELET)) # can clear the gaps at the start with multiple pit buffers, can reach bottom left sign with bonking along the bottom wall self._addEntranceRequirement("castle_jump_cave", PEGASUS_BOOTS) # pit buffer to clip bottom wall and boots bonk across prairie_cave_secret_exit.connect(prairie_cave, AND(BOMB, OR(PEGASUS_BOOTS, HOOKSHOT))) # hookshot spam or boots bonk across pits can go from left to right by pit buffering on top of the bottom wall then boots bonk across @@ -563,15 +568,15 @@ class World: animal_village.connect(bay_water, FEATHER) # jesus jump (can always reach bay_water with jesus jumping from every way to enter bay_water, so no one_way) ukuku_prairie.connect(bay_water, FEATHER, one_way=True) # jesus jump bay_water.connect(d5_entrance, FEATHER) # jesus jump into d5 entrance (wall clip), wall clip + jesus jump to get out - + crow_gold_leaf.connect(castle_courtyard, BOMB) # bird on tree at left side kanalet, place a bomb against the tree and the crow flies off. With well placed second bomb the crow can be killed mermaid_statue.connect(animal_village, AND(TRADING_ITEM_SCALE, FEATHER)) # early mermaid statue by buffering on top of the right ledge, then superjumping to the left (horizontal pixel perfect) animal_village_bombcave_heartpiece.connect(animal_village_bombcave, PEGASUS_BOOTS) # boots bonk across bottom wall (both at entrance and in item room) d6_armos_island.connect(ukuku_prairie, FEATHER) # jesus jump (3 screen) from seashell mansion to armos island - armos_fairy_entrance.connect(d6_armos_island, PEGASUS_BOOTS, one_way=True) # jesus jump from top (fairy bomb cave) to armos island with fast falling + armos_fairy_entrance.connect(d6_armos_island, PEGASUS_BOOTS, one_way=True) # jesus jump from top (fairy bomb cave) to armos island with fast falling d6_connector_right.connect(d6_connector_left, PEGASUS_BOOTS) # boots bonk across bottom wall at water and pits (can do both ways) - + obstacle_cave_entrance.connect(obstacle_cave_inside, OR(HOOKSHOT, AND(FEATHER, PEGASUS_BOOTS, OR(SWORD, MAGIC_ROD, BOW)))) # get past crystal rocks by hookshotting into top pushable block, or boots dashing into top wall where the pushable block is to superjump down obstacle_cave_entrance.connect(obstacle_cave_inside, AND(PEGASUS_BOOTS, ROOSTER)) # get past crystal rocks pushing the top pushable block, then boots dashing up picking up the rooster before bonking. Pause buffer until rooster is fully picked up then throw it down before bonking into wall d4_entrance.connect(below_right_taltal, FEATHER) # jesus jump a long way @@ -583,7 +588,7 @@ class World: mountain_bridge_staircase.connect(outside_rooster_house, OR(PEGASUS_BOOTS, FEATHER)) # cross bridge to staircase with pit buffer to clip bottom wall and jump or boots bonk across left_right_connector_cave_entrance.connect(left_right_connector_cave_exit, AND(PEGASUS_BOOTS, FEATHER), one_way=True) # boots jump to bottom left corner of pits, pit buffer and jump to left left_right_connector_cave_exit.connect(left_right_connector_cave_entrance, AND(ROOSTER, OR(PEGASUS_BOOTS, SWORD, BOW, MAGIC_ROD)), one_way=True) # pass through the passage in reverse using a boots rooster hop or rooster superjump in the one way passage area - + self.start = start_house self.egg = windfish_egg self.nightmare = nightmare @@ -659,7 +664,7 @@ class EntranceExterior: self.requirement = requirement self.one_way_enter_requirement = one_way_enter_requirement self.one_way_exit_requirement = one_way_exit_requirement - + def addRequirement(self, new_requirement): self.requirement = OR(self.requirement, new_requirement) @@ -674,9 +679,9 @@ class EntranceExterior: self.one_way_enter_requirement = new_requirement else: self.one_way_enter_requirement = OR(self.one_way_enter_requirement, new_requirement) - + def enterIsSet(self): return self.one_way_enter_requirement != "UNSET" - + def exitIsSet(self): return self.one_way_exit_requirement != "UNSET" diff --git a/worlds/ladx/LADXR/logic/requirements.py b/worlds/ladx/LADXR/logic/requirements.py index acc969ba..a8e57327 100644 --- a/worlds/ladx/LADXR/logic/requirements.py +++ b/worlds/ladx/LADXR/logic/requirements.py @@ -265,6 +265,7 @@ class RequirementsSettings: self.rear_attack_range = OR(MAGIC_ROD, BOW) # mimic self.fire = OR(MAGIC_POWDER, MAGIC_ROD) # torches self.push_hardhat = OR(SHIELD, SWORD, HOOKSHOT, BOOMERANG) + self.shuffled_magnifier = TRADING_ITEM_MAGNIFYING_GLASS self.boss_requirements = [ SWORD, # D1 boss @@ -293,6 +294,8 @@ class RequirementsSettings: } # Adjust for options + if not options.tradequest: + self.shuffled_magnifier = True if options.bowwow != 'normal': # We cheat in bowwow mode, we pretend we have the sword, as bowwow can pretty much do all what the sword ca$ # Except for taking out bushes (and crystal pillars are removed) self.bush.remove(SWORD) diff --git a/worlds/ladx/LADXR/patches/maptweaks.py b/worlds/ladx/LADXR/patches/maptweaks.py index c25dd83d..8a5171b3 100644 --- a/worlds/ladx/LADXR/patches/maptweaks.py +++ b/worlds/ladx/LADXR/patches/maptweaks.py @@ -25,3 +25,16 @@ def addBetaRoom(rom): re.store(rom) rom.room_sprite_data_indoor[0x0FC] = rom.room_sprite_data_indoor[0x1A1] + + +def tweakBirdKeyRoom(rom): + # Make the bird key accessible without the rooster + re = RoomEditor(rom, 0x27A) + re.removeObject(1, 6) + re.removeObject(2, 6) + re.removeObject(3, 5) + re.removeObject(3, 6) + re.moveObject(1, 5, 2, 6) + re.moveObject(2, 5, 3, 6) + re.addEntity(3, 5, 0x9D) + re.store(rom) diff --git a/worlds/ladx/LADXR/patches/songs.py b/worlds/ladx/LADXR/patches/songs.py index 59ca01c4..b080cf06 100644 --- a/worlds/ladx/LADXR/patches/songs.py +++ b/worlds/ladx/LADXR/patches/songs.py @@ -72,6 +72,10 @@ def upgradeMarin(rom): rst 8 """), fill_nop=True) + # Load marin singing even if you have the marin date + rom.patch(0x03, 0x0A91, ASM("jp nz, $3F8D"), "", fill_nop=True) + rom.patch(0x05, 0x0E6E, ASM("jp nz, $7B4B"), "", fill_nop=True) + def upgradeManbo(rom): # Instead of checking if we have the song, check if we have a specific room flag set diff --git a/worlds/ladx/LADXR/patches/tradeSequence.py b/worlds/ladx/LADXR/patches/tradeSequence.py index 5b608977..0eb46ae2 100644 --- a/worlds/ladx/LADXR/patches/tradeSequence.py +++ b/worlds/ladx/LADXR/patches/tradeSequence.py @@ -1,7 +1,7 @@ from ..assembler import ASM -def patchTradeSequence(rom, boomerang_option): +def patchTradeSequence(rom, settings): patchTrendy(rom) patchPapahlsWife(rom) patchYipYip(rom) @@ -16,7 +16,7 @@ def patchTradeSequence(rom, boomerang_option): patchMermaid(rom) patchMermaidStatue(rom) patchSharedCode(rom) - patchVarious(rom, boomerang_option) + patchVarious(rom, settings) patchInventoryMenu(rom) @@ -265,8 +265,11 @@ def patchMermaidStatue(rom): and $10 ; scale ret z ldh a, [$F8] - and $20 + and $20 ; ROOM_STATUS_EVENT_2 ret nz + + ld hl, wTradeSequenceItem2 + res 4, [hl] ; take the trade item """), fill_nop=True) @@ -317,7 +320,7 @@ notSideScroll: rom.patch(0x07, 0x3F7F, "00" * 7, ASM("ldh a, [$F8]\nor $20\nldh [$F8], a\nret")) -def patchVarious(rom, boomerang_option): +def patchVarious(rom, settings): # Make the zora photo work with the magnifier rom.patch(0x18, 0x09F3, 0x0A02, ASM(""" ld a, [wTradeSequenceItem2] @@ -330,22 +333,71 @@ def patchVarious(rom, boomerang_option): jp z, $3F8D ; UnloadEntity """), fill_nop=True) # Mimic invisibility - rom.patch(0x18, 0x2AC8, 0x2ACE, "", fill_nop=True) + rom.patch(0x19, 0x2AC0, ASM(""" + cp $97 + jr z, mermaidStatueCave + cp $98 + jr nz, visible + mermaidStatueCave: + ld a, [$DB7F] + and a + jr nz, 6 + visible: + """), ASM(""" + dec a ; save one byte by only doing one cp + or $01 + cp $97 + jr nz, visible + mermaidStatueCave: + ld a, [wTradeSequenceItem2] + and $20 ; MAGNIFYING_GLASS + jr z, 6 + visible: + """)) + # Zol invisibility + rom.patch(0x06, 0x3BE9, ASM(""" + cp $97 + jr z, mermaidStatueCave + cp $98 + ret nz ; visible + mermaidStatueCave: + ld a, [$DB7F] + and a + ret z + """), ASM(""" + dec a ; save one byte by only doing one cp + or $01 + cp $97 + ret nz ; visible + mermaidStatueCave: + ld a, [wTradeSequenceItem2] + and $20 ; MAGNIFYING_GLASS + ret nz + """)) # Ignore trade quest state for marin at beach rom.patch(0x18, 0x219E, 0x21A6, "", fill_nop=True) # Shift the magnifier 8 pixels rom.patch(0x03, 0x0F68, 0x0F6F, ASM(""" ldh a, [$F6] ; map room - cp $97 ; check if we are in the maginfier room + cp $97 ; check if we are in the magnifier room jp z, $4F83 """), fill_nop=True) # Something with the photographer rom.patch(0x36, 0x0948, 0x0950, "", fill_nop=True) - if boomerang_option not in {'trade', 'gift'}: # Boomerang cave is not patched, so adjust it + # Boomerang trade guy + # if settings.boomerang not in {'trade', 'gift'} or settings.overworld in {'normal', 'nodungeons'}: + if settings.tradequest: + # Update magnifier checks rom.patch(0x19, 0x05EC, ASM("ld a, [wTradeSequenceItem]\ncp $0E\njp nz, $7E61"), ASM("ld a, [wTradeSequenceItem2]\nand $20\njp z, $7E61")) # show the guy rom.patch(0x00, 0x3199, ASM("ld a, [wTradeSequenceItem]\ncp $0E\njr nz, $06"), ASM("ld a, [wTradeSequenceItem2]\nand $20\njr z, $06")) # load the proper room layout - rom.patch(0x19, 0x05F4, 0x05FB, "", fill_nop=True) + else: + # Monkey bridge patch, always have the bridge there. + rom.patch(0x00, 0x333D, ASM("bit 4, e\njr Z, $05"), b"", fill_nop=True) + # Always have the boomerang trade guy enabled (magnifier not needed) + rom.patch(0x19, 0x05EC, ASM("ld a, [wTradeSequenceItem]\ncp $0E"), ASM("ld a, $0E\ncp $0E"), fill_nop=True) # show the guy + rom.patch(0x00, 0x3199, ASM("ld a, [wTradeSequenceItem]\ncp $0E"), ASM("ld a, $0E\ncp $0E"), fill_nop=True) # load the proper room layout + rom.patch(0x19, 0x05F4, ASM("ld a, [wTradeSequenceItem2]\nand a"), ASM("xor a"), fill_nop=True) def patchInventoryMenu(rom): diff --git a/worlds/ladx/Options.py b/worlds/ladx/Options.py index c5dcc080..6c0b866b 100644 --- a/worlds/ladx/Options.py +++ b/worlds/ladx/Options.py @@ -58,7 +58,7 @@ class TextShuffle(DefaultOffToggle): class Rooster(DefaultOnToggle, LADXROption): """ [On] Adds the rooster to the item pool. - [Off] The rooster spot is still a check giving an item. But you will never find the rooster. Any rooster spot is accessible without rooster by other means. + [Off] The rooster spot is still a check giving an item. But you will never find the rooster. In that case, any rooster spot is accessible without rooster by other means. """ display_name = "Rooster" ladxr_name = "rooster"