Skip to content
Merged
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
7 changes: 4 additions & 3 deletions logic/dungeon7.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def __init__(self, options, world_setup, r):
# floor 2 north
after_a_stairs.connect(ball_access, POWER_BRACELET, back=False)
after_a_stairs.connect(ne_pillar, POWER_BRACELET, back=None) # intended method is to pull lever
after_a_stairs.connect(pegs_before_ball, "SWITCH7B_RANGE", back=False)
after_a_stairs.connect(pegs_before_ball, OR("SWITCH7A", "SWITCH7B_RANGE"), back=False) # SWITCH7A here might eventually cause trouble with stairs shuffle?
after_b_stairs.connect(ne_pillar, "SWITCH7A", back=OR("SWITCH7B_RANGE", "SWITCH7C"))
ne_pillar.connect(ne_pillar_chest5, POWER_BRACELET, back=False)
ne_pillar.connect(ne_pillar_fall, "D7_BALL", back=False)
Expand All @@ -120,7 +120,8 @@ def __init__(self, options, world_setup, r):
after_d_stairs.connect(tile_room, back=False)
after_d_stairs.connect(after_d_stairs_drop2, r.miniboss_requirements["HINOX"], back=False)
after_d_stairs.connect(sw_pillar_toak_clear, r.enemy_requirements["THREE_OF_A_KIND"], back=False) #NOTE: add bracelet method if rom patched
after_d_stairs.connect((se_pillar_switch_midrange, se_pillar_switch_range), OR(BOOMERANG, BOW, BOMB, MAGIC_ROD), back=False)
after_d_stairs.connect(se_pillar_switch_midrange, OR(BOOMERANG, BOW, BOMB, MAGIC_ROD), back=False)
after_d_stairs.connect(se_pillar_switch_range, OR(BOOMERANG, BOW, BOMB), back=False) # hit switch and get on pegs by east exit
after_d_stairs.connect(pegs_before_ball, "SWITCH7C_RANGE", back=None)

@dragonc0 dragonc0 Aug 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to have the SWITCH7C_RANGE path defined here now that SWITCH7C_RANGE is no longer accessible outside of hard logic or higher? It is easier on the code to not have to separate the back path from the front path, I just wonder if it looks weird

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm I'd also say that BOMB should be normal logic still, throwing a bomb over the ledge and walking to the pegs seems normal enough

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to only magic rod being hard difficulty like I think you were suggesting on Discord - makes sense to me.

after_d_stairs.connect(keylock_ledge, FOUND(KEY7, 3))
keylock_ledge.connect((se_pillar, pegs_before_ball, after_d_stairs), back=False)
Expand Down Expand Up @@ -172,7 +173,7 @@ def __init__(self, options, world_setup, r):
after_c_stairs.connect(after_c_stairs_chest2, BOMB, back=False)
after_c_stairs.connect(spike_corridor, r.damage_boost) # forced damage so this cannot be in normal logic
after_d_stairs.connect(se_pillar_switch_midrange, AND(FEATHER, SWORD), back=False) # jump and swing sword from below rail NOTE: add bracelet method if rom patched
after_d_stairs.connect(se_pillar_switch_range, OR(BOOMERANG, BOW, BOMB, MAGIC_ROD), back=False) # hit switch and get on pegs by east exit
after_d_stairs.connect(se_pillar_switch_range, MAGIC_ROD, back=False) # hit switch and get on pegs by east exit
after_d_stairs.connect(sw_pillar_toak_clear, "D7_BALL", back=False) # throw the ball to solve three-of-a-kind and spawn the chest
for location in (after_d_stairs, bombwall_pit, sw_pillar):
location.connect(sw_pillar_toak_clear, BOMB, back=False) # push a block if needed and solve the three-of-a-kind puzzle with bombs
Expand Down
6 changes: 5 additions & 1 deletion logic/overworld.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ def __init__(self, options, world_setup, r):
Location().add(FishingMinigame()).connect(mabe_village, AND(r.bush, FOUND("RUPEES", 50))) # fishing game, heart piece is directly done by the minigame.
Location().add(Seashell(0x0A3)).connect(mabe_village, r.bush) # bushes below the shop
Location().add(Seashell(0x0D2)).connect(mabe_village, PEGASUS_BOOTS) # smash into tree next to lv1
Location().add(Song(0x092)).connect(mabe_village, OCARINA) # Marins song
marin_song = Location().add(Song(0x092))
mabe_village.connect(marin_song, OCARINA, back=False)
Location().add(KeyHole(0x0D3, TAIL_CAVE_OPENED)).connect(mabe_village, TAIL_KEY) # Marins song
rooster_cave = Location("Rooster Cave")
Location().add(DroppedKey(0x1E4)).connect(rooster_cave, AND(OCARINA, SONG3))
Expand Down Expand Up @@ -286,6 +287,7 @@ def __init__(self, options, world_setup, r):

animal_village = Location("Animal Village")
animal_village.connect(Location().add(TradeSequenceItem(0x0CD, TRADING_ITEM_FISHING_HOOK)), TRADING_ITEM_BROOM)
animal_village.connect(marin_song, OCARINA, back=False)
cookhouse = Location("Bear Chef's House")
cookhouse.connect(Location().add(TradeSequenceItem(0x2D7, TRADING_ITEM_PINEAPPLE)), TRADING_ITEM_HONEYCOMB)
goathouse = Location("Goat's House")
Expand Down Expand Up @@ -629,6 +631,8 @@ def __init__(self, options, world_setup, r):
self._addEntranceRequirement("castle_jump_cave", r.pit_buffer_boots) # pit buffer to clip bottom wall and boots bonk across
prairie_cave_secret_exit.connect(prairie_cave, AND(BOMB, OR(r.boots_bonk_pit, r.hookshot_spam_pit))) # 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
richard_cave_chest.connect(richard_cave, r.damage_boost) # use the zol on the other side of the pit to damage boost across (requires damage from pit + zol)
richard_cave_chest.connect(richard_cave, r.boots_bonk) # bonk over the pit instead of damage boosting
ukuku_prairie.connect(dungeon3_entrance, AND(r.jesus_buffer, r.jesus_buffer_hookshot), back=False) # boots bonk from the right into a jesus buffer down to the bottom wall, then bonk all the way across. Hookshot is needed to restart the buffer after transitions
castle_secret_entrance_right.connect(castle_secret_entrance_left, OR(r.boots_bonk_2d_spikepit, r.bracelet_bounce_2d_spikepit, r.toadstool_bounce_2d_spikepit)) # use bracelet or toadstool to damage boost off of spikes and get through passageway. Also need to hold A button when bouncing off spikes or goombas
left_bay_area.connect(ghost_hut_outside, r.pit_buffer_boots) # multiple pit buffers to bonk across the bottom wall
left_bay_area.connect(ukuku_prairie, r.hookshot_clip_block, back=False) # clip through the donuts blocking the path next to prairie plateau cave by hookshotting up and killing the two moblins that way which clips you further up two times. This is enough to move right
Expand Down
28 changes: 27 additions & 1 deletion logic/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ def __repr__(self) -> str:
def remove(self, item) -> None:
if item in self.__items:
self.__items.remove(item)
elif item in self.__children:
self.__children.remove(item)

def add(self, item) -> None:
if isinstance(item, str):
if item not in self.__items:
self.__items.append(item)
else:
if item not in self.__children:
self.__children.append(item)

def test(self, inventory) -> bool:
for item in self.__items:
Expand Down Expand Up @@ -70,6 +80,16 @@ def __repr__(self) -> str:
def remove(self, item) -> None:
if item in self.__items:
self.__items.remove(item)
elif item in self.__children:
self.__children.remove(item)

def add(self, item) -> None:
if isinstance(item, str):
if item not in self.__items:
self.__items.append(item)
else:
if item not in self.__children:
self.__children.append(item)

def test(self, inventory) -> bool:
for item in self.__items:
Expand Down Expand Up @@ -374,11 +394,17 @@ def __init__(self, options):
if options.hardmode == "ohko":
self.miniboss_requirements["ROLLING_BONES"] = OR(BOW, MAGIC_ROD, BOOMERANG, AND(FEATHER, self.attack_hookshot)) # should not deal with roller damage
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)
# We cheat in bowwow mode, we pretend we have the sword, as bowwow can pretty much do all what the sword can
# Except for taking out bushes (and crystal pillars are removed)
self.bush.remove(SWORD)
self.pit_bush.remove(SWORD)
self.hit_switch.remove(SWORD)
self.hit_switch_color.remove(SWORD)
# 2 swords means we picked up a real one
self.bush.add(COUNT(SWORD, 2))
self.pit_bush.add(COUNT(SWORD, 2))
self.hit_switch.add(COUNT(SWORD, 2))
self.hit_switch_color.add(COUNT(SWORD, 2))
if options.logic == "casual":
# In casual mode, remove the more complex kill methods
self.bush.remove(MAGIC_POWDER)
Expand Down
Loading