Skip to content

Commit

Permalink
LADX: upstream logic updates (#3963)
Browse files Browse the repository at this point in the history
* Fully updates requirements.py to live LADXR (#19)

* Updates dungeon2.py to LADXR-Live (#20)

No logic changes or bugfix are in this file. It is only code cleanup.

* Update dungeon1.py (#21)

- The Three of a Kind with Bomb is moved from Normal to Hard Logic

The rest is code cleanup.

lines 22-25 | 22-26 & 33 | 34 remain different in AP | Upstream with no effective difference

* Fully updates dungeon3.py to LADXR-live (#22)

Logic Changes:
- Hard mode now considers killing the enemies in the top room with pot

Everything else is cleanup.

* Fully update dungeon4.py to LADXR-live logic (#23)

Logic Changes:
- Hard Logic: Removes Feather requirement from grabbing the Pit Key
- Hell logic: new hookshot clip (line 64)
- Hell logic: hookshot spam over the first pit of crossroads, then buffer down (line 69)
- Hell logic: push block left of keyblock up, then shaq jump off the left wall and pause buffer to land on keyblock.
- Hell logic: split zol for more entities, and clip through the block left of keyblock by hookshot spam

The rest is code cleanup

* Updates dungeon5.py mostly to LADXR-Live Logic (#24)

Logic Changes:
- Hell logic: use zoomerang dashing left to get an unclipped boots superjump off the right wall over the block. reverse is push block (line 69)

The rest is cleanup.

The upstream splits the post_gohma region into pre_gohma, gohma and post_gohma. I did not implement this yet as I do not know the implications. To port this the following lines need to be changed (AP | LADXR):
18 | 18-20;
55 | 58;
65 | 68-69

* Fully update dungeon6.py logic (#25)

Logic Changes:
- Hard logic: allow damage boosting past the mini thwomps
- Glitched logic: bomb triggering elephants in two cases

Everything else is cleanup

* Fully update dungeon7.py to LADXR-live logic (#26)

Logic Changes:
- Hard logic: Three of a Kind is now possible with bombs only

Everything else is code cleanup

* Fully updates dungeon8.py to LADXR-live (#27)

Logic change:
- Hard logic: allows to drop the Gibdos into holes as a way to kill them
- Glitched logic: underground section with fire balls jumping up out of lava. Use boots superjump off left wall to jump over the pot blocking the way


The rest is code cleanup

* Fully update dungeonColor.py to LADXR-live (#28)

Logic changes:
- Normal logic: Karakoros now need power bracelet to put them into their holes
- Hard logic: Karakoros without power bracelet but with weapon
- Hell logic: Karakoros with only bombs

Everything else is code cleanup

* Updating overworld.py (#29)

* Updating overworld.py

This tries to update all logic of the Overworld.

Logic changes include:
- Normal logic: requires hookshot or shield to traverse Armos Cave
- Hard logic: Traverse Armos Cave with nothing (formerly normal logic)
- Hard logic: get the animal village bomb cave check with jump and boomerang
- Hard logic: use rooster to go to D7
- Lots of Jesus Rooster Jumps

I stopped counting and need to go over this again.

Also, please investigate line 474 AP because it's removed in LADXR-Upstream and I don't know why.

* remove featherless fisher under bridge from hard

it was moved to hell upstream and its already present in our code

---------

Co-authored-by: Alex Nordstrom <a.l.nordstrom@gmail.com>

* fixes

* add test messages

* Adds Pegasus Boots to the test (#31)

* Fix d6 boss_key logic (#30)

* restore hardmode logic

* higher logic fixes

* add bush requirement to the raft
in case the player needs to farm rupees to play again

---------

Co-authored-by: palex00 <32203971+palex00@users.noreply.github.com>
  • Loading branch information
threeandthreee and palex00 authored Dec 5, 2024
1 parent 4d42814 commit 203d89d
Show file tree
Hide file tree
Showing 12 changed files with 399 additions and 270 deletions.
15 changes: 8 additions & 7 deletions worlds/ladx/LADXR/logic/dungeon1.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def __init__(self, options, world_setup, r):
entrance.add(DungeonChest(0x113), DungeonChest(0x115), DungeonChest(0x10E))
Location(dungeon=1).add(DroppedKey(0x116)).connect(entrance, OR(BOMB, r.push_hardhat)) # hardhat beetles (can kill with bomb)
Location(dungeon=1).add(DungeonChest(0x10D)).connect(entrance, OR(r.attack_hookshot_powder, SHIELD)) # moldorm spawn chest
stalfos_keese_room = Location(dungeon=1).add(DungeonChest(0x114)).connect(entrance, r.attack_hookshot) # 2 stalfos 2 keese room
stalfos_keese_room = Location(dungeon=1).add(DungeonChest(0x114)).connect(entrance, AND(OR(r.attack_skeleton, SHIELD),r.attack_hookshot_powder)) # 2 stalfos 2 keese room
Location(dungeon=1).add(DungeonChest(0x10C)).connect(entrance, BOMB) # hidden seashell room
dungeon1_upper_left = Location(dungeon=1).connect(entrance, AND(KEY1, FOUND(KEY1, 3)))
if options.owlstatues == "both" or options.owlstatues == "dungeon":
Expand All @@ -19,21 +19,22 @@ def __init__(self, options, world_setup, r):
dungeon1_right_side = Location(dungeon=1).connect(entrance, AND(KEY1, FOUND(KEY1, 3)))
if options.owlstatues == "both" or options.owlstatues == "dungeon":
Location(dungeon=1).add(OwlStatue(0x10A)).connect(dungeon1_right_side, STONE_BEAK1)
Location(dungeon=1).add(DungeonChest(0x10A)).connect(dungeon1_right_side, OR(r.attack_hookshot, SHIELD)) # three of a kind, shield stops the suit from changing
dungeon1_3_of_a_kind = Location(dungeon=1).add(DungeonChest(0x10A)).connect(dungeon1_right_side, OR(r.attack_hookshot_no_bomb, SHIELD)) # three of a kind, shield stops the suit from changing
dungeon1_miniboss = Location(dungeon=1).connect(dungeon1_right_side, AND(r.miniboss_requirements[world_setup.miniboss_mapping[0]], FEATHER))
dungeon1_boss = Location(dungeon=1).connect(dungeon1_miniboss, NIGHTMARE_KEY1)
Location(dungeon=1).add(HeartContainer(0x106), Instrument(0x102)).connect(dungeon1_boss, r.boss_requirements[world_setup.boss_mapping[0]])
boss = Location(dungeon=1).add(HeartContainer(0x106), Instrument(0x102)).connect(dungeon1_boss, r.boss_requirements[world_setup.boss_mapping[0]])

if options.logic not in ('normal', 'casual'):
if options.logic == 'hard' or options.logic == 'glitched' or options.logic == 'hell':
stalfos_keese_room.connect(entrance, r.attack_hookshot_powder) # stalfos jump away when you press a button.

dungeon1_3_of_a_kind.connect(dungeon1_right_side, BOMB) # use timed bombs to match the 3 of a kinds

if options.logic == 'glitched' or options.logic == 'hell':
boss_key.connect(entrance, FEATHER) # super jump
boss_key.connect(entrance, r.super_jump_feather) # super jump
dungeon1_miniboss.connect(dungeon1_right_side, r.miniboss_requirements[world_setup.miniboss_mapping[0]]) # damage boost or buffer pause over the pit to cross or mushroom

if options.logic == 'hell':
feather_chest.connect(dungeon1_upper_left, SWORD) # keep slashing the spiked beetles until they keep moving 1 pixel close towards you and the pit, to get them to fall
boss_key.connect(entrance, FOUND(KEY1,3)) # damage boost off the hardhat to cross the pit
boss_key.connect(entrance, AND(r.damage_boost, FOUND(KEY1,3))) # damage boost off the hardhat to cross the pit

self.entrance = entrance

Expand Down
14 changes: 7 additions & 7 deletions worlds/ladx/LADXR/logic/dungeon2.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def __init__(self, options, world_setup, r):
Location(dungeon=2).add(DungeonChest(0x137)).connect(dungeon2_r2, AND(KEY2, FOUND(KEY2, 5), OR(r.rear_attack, r.rear_attack_range))) # compass chest
if options.owlstatues == "both" or options.owlstatues == "dungeon":
Location(dungeon=2).add(OwlStatue(0x133)).connect(dungeon2_r2, STONE_BEAK2)
dungeon2_r3 = Location(dungeon=2).add(DungeonChest(0x138)).connect(dungeon2_r2, r.attack_hookshot) # first chest with key, can hookshot the switch in previous room
dungeon2_r3 = Location(dungeon=2).add(DungeonChest(0x138)).connect(dungeon2_r2, r.hit_switch) # first chest with key, can hookshot the switch in previous room
dungeon2_r4 = Location(dungeon=2).add(DungeonChest(0x139)).connect(dungeon2_r3, FEATHER) # button spawn chest
if options.logic == "casual":
shyguy_key_drop = Location(dungeon=2).add(DroppedKey(0x134)).connect(dungeon2_r3, AND(FEATHER, OR(r.rear_attack, r.rear_attack_range))) # shyguy drop key
Expand All @@ -39,16 +39,16 @@ def __init__(self, options, world_setup, r):

if options.logic == 'glitched' or options.logic == 'hell':
dungeon2_ghosts_chest.connect(dungeon2_ghosts_room, SWORD) # use sword to spawn ghosts on other side of the room so they run away (logically irrelevant because of torches at start)
dungeon2_r6.connect(miniboss, FEATHER) # superjump to staircase next to hinox.
dungeon2_r6.connect(miniboss, r.super_jump_feather) # superjump to staircase next to hinox.

if options.logic == 'hell':
dungeon2_map_chest.connect(dungeon2_l2, AND(r.attack_hookshot_powder, PEGASUS_BOOTS)) # use boots to jump over the pits
dungeon2_r4.connect(dungeon2_r3, OR(PEGASUS_BOOTS, HOOKSHOT)) # can use both pegasus boots bonks or hookshot spam to cross the pit room
dungeon2_map_chest.connect(dungeon2_l2, AND(r.attack_hookshot_powder, r.boots_bonk_pit)) # use boots to jump over the pits
dungeon2_r4.connect(dungeon2_r3, OR(r.boots_bonk_pit, r.hookshot_spam_pit)) # can use both pegasus boots bonks or hookshot spam to cross the pit room
dungeon2_r4.connect(shyguy_key_drop, r.rear_attack_range, one_way=True) # adjust for alternate requirements for dungeon2_r4
miniboss.connect(dungeon2_r5, AND(PEGASUS_BOOTS, r.miniboss_requirements[world_setup.miniboss_mapping[1]])) # use boots to dash over the spikes in the 2d section
miniboss.connect(dungeon2_r5, AND(r.boots_dash_2d, r.miniboss_requirements[world_setup.miniboss_mapping[1]])) # use boots to dash over the spikes in the 2d section
dungeon2_pre_stairs_boss.connect(dungeon2_r6, AND(HOOKSHOT, OR(BOW, BOMB, MAGIC_ROD, AND(OCARINA, SONG1)), FOUND(KEY2, 5))) # hookshot clip through the pot using both pol's voice
dungeon2_post_stairs_boss.connect(dungeon2_pre_stairs_boss, OR(BOMB, AND(PEGASUS_BOOTS, FEATHER))) # use a bomb to lower the last platform, or boots + feather to cross over top (only relevant in hell logic)
dungeon2_pre_boss.connect(dungeon2_post_stairs_boss, AND(PEGASUS_BOOTS, HOOKSHOT)) # boots bonk off bottom wall + hookshot spam across the two 1 tile pits vertically
dungeon2_post_stairs_boss.connect(dungeon2_pre_stairs_boss, OR(BOMB, r.boots_jump)) # use a bomb to lower the last platform, or boots + feather to cross over top (only relevant in hell logic)
dungeon2_pre_boss.connect(dungeon2_post_stairs_boss, AND(r.boots_bonk_pit, r.hookshot_spam_pit)) # boots bonk off bottom wall + hookshot spam across the two 1 tile pits vertically

self.entrance = entrance

Expand Down
38 changes: 20 additions & 18 deletions worlds/ladx/LADXR/logic/dungeon3.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def __init__(self, options, world_setup, r):
Location(dungeon=3).add(OwlStatue(0x154)).connect(area_up, STONE_BEAK3)
dungeon3_raised_blocks_north = Location(dungeon=3).add(DungeonChest(0x14C)) # chest locked behind raised blocks near staircase
dungeon3_raised_blocks_east = Location(dungeon=3).add(DungeonChest(0x150)) # chest locked behind raised blocks next to slime chest
area_up.connect(dungeon3_raised_blocks_north, r.attack_hookshot, one_way=True) # hit switch to reach north chest
area_up.connect(dungeon3_raised_blocks_east, r.attack_hookshot, one_way=True) # hit switch to reach east chest
area_up.connect(dungeon3_raised_blocks_north, r.hit_switch, one_way=True) # hit switch to reach north chest
area_up.connect(dungeon3_raised_blocks_east, r.hit_switch, one_way=True) # hit switch to reach east chest

area_left = Location(dungeon=3).connect(area3, AND(KEY3, FOUND(KEY3, 8)))
area_left_key_drop = Location(dungeon=3).add(DroppedKey(0x155)).connect(area_left, r.attack_hookshot) # west key drop (no longer requires feather to get across hole), can use boomerang to knock owls into pit
Expand Down Expand Up @@ -54,28 +54,30 @@ def __init__(self, options, world_setup, r):

if options.logic == 'hard' or options.logic == 'glitched' or options.logic == 'hell':
dungeon3_3_bombite_room.connect(area_right, BOOMERANG) # 3 bombite room from the left side, grab item with boomerang
dungeon3_reverse_eye.connect(entrance, HOOKSHOT) # hookshot the chest to get to the right side
dungeon3_north_key_drop.connect(area_up, POWER_BRACELET) # use pots to kill the enemies
dungeon3_south_key_drop.connect(area_down, POWER_BRACELET) # use pots to kill enemies
dungeon3_reverse_eye.connect(entrance, r.hookshot_over_pit) # hookshot the chest to get to the right side
dungeon3_north_key_drop.connect(area_up, r.throw_pot) # use pots to kill the enemies
dungeon3_south_key_drop.connect(area_down, r.throw_pot) # use pots to kill enemies
area_up.connect(dungeon3_raised_blocks_north, r.throw_pot, one_way=True) # use pots to hit the switch
area_up.connect(dungeon3_raised_blocks_east, AND(r.throw_pot, r.attack_hookshot_powder), one_way=True) # use pots to hit the switch

if options.logic == 'glitched' or options.logic == 'hell':
area2.connect(dungeon3_raised_blocks_east, AND(r.attack_hookshot_powder, FEATHER), one_way=True) # use superjump to get over the bottom left block
area3.connect(dungeon3_raised_blocks_north, AND(OR(PEGASUS_BOOTS, HOOKSHOT), FEATHER), one_way=True) # use shagjump (unclipped superjump next to movable block) from north wall to get on the blocks. Instead of boots can also get to that area with a hookshot clip past the movable block
area3.connect(dungeon3_zol_stalfos, HOOKSHOT, one_way=True) # hookshot clip through the northern push block next to raised blocks chest to get to the zol
dungeon3_nightmare_key_chest.connect(area_right, AND(FEATHER, BOMB)) # superjump to right side 3 gap via top wall and jump the 2 gap
dungeon3_post_dodongo_chest.connect(area_right, AND(FEATHER, FOUND(KEY3, 6))) # superjump from keyblock path. use 2 keys to open enough blocks TODO: nag messages to skip a key
area2.connect(dungeon3_raised_blocks_east, AND(r.attack_hookshot_powder, r.super_jump_feather), one_way=True) # use superjump to get over the bottom left block
area3.connect(dungeon3_raised_blocks_north, AND(OR(PEGASUS_BOOTS, r.hookshot_clip_block), r.shaq_jump), one_way=True) # use shagjump (unclipped superjump next to movable block) from north wall to get on the blocks. Instead of boots can also get to that area with a hookshot clip past the movable block
area3.connect(dungeon3_zol_stalfos, r.hookshot_clip_block, one_way=True) # hookshot clip through the northern push block next to raised blocks chest to get to the zol
dungeon3_nightmare_key_chest.connect(area_right, AND(r.super_jump_feather, BOMB)) # superjump to right side 3 gap via top wall and jump the 2 gap
dungeon3_post_dodongo_chest.connect(area_right, AND(r.super_jump_feather, FOUND(KEY3, 6))) # superjump from keyblock path. use 2 keys to open enough blocks TODO: nag messages to skip a key

if options.logic == 'hell':
area2.connect(dungeon3_raised_blocks_east, AND(PEGASUS_BOOTS, OR(BOW, MAGIC_ROD)), one_way=True) # use boots superhop to get over the bottom left block
area3.connect(dungeon3_raised_blocks_north, AND(PEGASUS_BOOTS, OR(BOW, MAGIC_ROD)), one_way=True) # use boots superhop off top wall or left wall to get on raised blocks
area_up.connect(dungeon3_zol_stalfos, AND(FEATHER, OR(BOW, MAGIC_ROD, SWORD)), one_way=True) # use superjump near top blocks chest to get to zol without boots, keep wall clip on right wall to get a clip on left wall or use obstacles
area_left_key_drop.connect(area_left, SHIELD) # knock everything into the pit including the teleporting owls
dungeon3_south_key_drop.connect(area_down, SHIELD) # knock everything into the pit including the teleporting owls
dungeon3_nightmare_key_chest.connect(area_right, AND(FEATHER, SHIELD)) # superjump into jumping stalfos and shield bump to right ledge
dungeon3_nightmare_key_chest.connect(area_right, AND(BOMB, PEGASUS_BOOTS, HOOKSHOT)) # boots bonk across the pits with pit buffering and hookshot to the chest
area2.connect(dungeon3_raised_blocks_east, r.boots_superhop, one_way=True) # use boots superhop to get over the bottom left block
area3.connect(dungeon3_raised_blocks_north, r.boots_superhop, one_way=True) # use boots superhop off top wall or left wall to get on raised blocks
area_up.connect(dungeon3_zol_stalfos, AND(r.super_jump_feather, r.attack_skeleton), one_way=True) # use superjump near top blocks chest to get to zol without boots, keep wall clip on right wall to get a clip on left wall or use obstacles
area_left_key_drop.connect(area_left, r.shield_bump) # knock everything into the pit including the teleporting owls
dungeon3_south_key_drop.connect(area_down, r.shield_bump) # knock everything into the pit including the teleporting owls
dungeon3_nightmare_key_chest.connect(area_right, AND(r.super_jump_feather, r.shield_bump)) # superjump into jumping stalfos and shield bump to right ledge
dungeon3_nightmare_key_chest.connect(area_right, AND(BOMB, r.pit_buffer_boots, HOOKSHOT)) # boots bonk across the pits with pit buffering and hookshot to the chest
compass_chest.connect(dungeon3_3_bombite_room, OR(BOW, MAGIC_ROD, AND(OR(FEATHER, PEGASUS_BOOTS), OR(SWORD, MAGIC_POWDER))), one_way=True) # 3 bombite room from the left side, use a bombite to blow open the wall without bombs
pre_boss.connect(towards_boss4, AND(r.attack_no_boomerang, FEATHER, POWER_BRACELET)) # use bracelet super bounce glitch to pass through first part underground section
pre_boss.connect(towards_boss4, AND(r.attack_no_boomerang, PEGASUS_BOOTS, "MEDICINE2")) # use medicine invulnerability to pass through the 2d section with a boots bonk to reach the staircase
pre_boss.connect(towards_boss4, AND(r.attack_no_boomerang, r.boots_bonk_2d_spikepit)) # use medicine invulnerability to pass through the 2d section with a boots bonk to reach the staircase

self.entrance = entrance

Expand Down
Loading

0 comments on commit 203d89d

Please sign in to comment.