TLOZ: Assorted Logic Fixes (#4203)
* TLOZ: Assorded Logic Fixes - Add needing arrows for Pols Voice rule. Not super necessary at the moment since wooden arrows are always accessible in one of the opening shops, but future proofing for future plans - Create Gohma Locations and make sure all Gohma blocked locations have the required rule (was missing at least one location before) - Remove the rule requiring Bow for all locations of level 8 (not sure why that was there, it's theoretically redundant now that Gohma and Pols Voice are properly marked) - Make sure Digdogger locations properly require Recorder, and clean up redundant Level 7 rules as level 7 currently requires Recorder to access the entrance * Update worlds/tloz/Rules.py forgor that has_any exists Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * Remove world = multiworld --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
This commit is contained in:
parent
9c102da901
commit
baf291d7a2
|
@ -108,11 +108,15 @@ sword_cave_locations = [
|
||||||
]
|
]
|
||||||
|
|
||||||
food_locations = [
|
food_locations = [
|
||||||
"Level 7 Map", "Level 7 Boss", "Level 7 Triforce", "Level 7 Key Drop (Goriyas)",
|
"Level 7 Item (Red Candle)", "Level 7 Map", "Level 7 Boss", "Level 7 Triforce", "Level 7 Key Drop (Goriyas)",
|
||||||
"Level 7 Bomb Drop (Moldorms North)", "Level 7 Bomb Drop (Goriyas North)",
|
"Level 7 Bomb Drop (Moldorms North)", "Level 7 Bomb Drop (Goriyas North)",
|
||||||
"Level 7 Bomb Drop (Dodongos)", "Level 7 Rupee Drop (Goriyas North)"
|
"Level 7 Bomb Drop (Dodongos)", "Level 7 Rupee Drop (Goriyas North)"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
gohma_locations = [
|
||||||
|
"Level 6 Boss", "Level 6 Triforce", "Level 8 Item (Magical Key)", "Level 8 Bomb Drop (Darknuts North)"
|
||||||
|
]
|
||||||
|
|
||||||
gleeok_locations = [
|
gleeok_locations = [
|
||||||
"Level 4 Boss", "Level 4 Triforce", "Level 8 Boss", "Level 8 Triforce"
|
"Level 4 Boss", "Level 4 Triforce", "Level 8 Boss", "Level 8 Triforce"
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from worlds.generic.Rules import add_rule
|
from worlds.generic.Rules import add_rule
|
||||||
from .Locations import food_locations, shop_locations, gleeok_locations
|
from .Locations import food_locations, shop_locations, gleeok_locations, gohma_locations
|
||||||
from .ItemPool import dangerous_weapon_locations
|
from .ItemPool import dangerous_weapon_locations
|
||||||
from .Options import StartingPosition
|
from .Options import StartingPosition
|
||||||
|
|
||||||
|
@ -10,13 +10,12 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
def set_rules(tloz_world: "TLoZWorld"):
|
def set_rules(tloz_world: "TLoZWorld"):
|
||||||
player = tloz_world.player
|
player = tloz_world.player
|
||||||
world = tloz_world.multiworld
|
|
||||||
options = tloz_world.options
|
options = tloz_world.options
|
||||||
|
|
||||||
# Boss events for a nicer spoiler log play through
|
# Boss events for a nicer spoiler log play through
|
||||||
for level in range(1, 9):
|
for level in range(1, 9):
|
||||||
boss = world.get_location(f"Level {level} Boss", player)
|
boss = tloz_world.get_location(f"Level {level} Boss")
|
||||||
boss_event = world.get_location(f"Level {level} Boss Status", player)
|
boss_event = tloz_world.get_location(f"Level {level} Boss Status")
|
||||||
status = tloz_world.create_event(f"Boss {level} Defeated")
|
status = tloz_world.create_event(f"Boss {level} Defeated")
|
||||||
boss_event.place_locked_item(status)
|
boss_event.place_locked_item(status)
|
||||||
add_rule(boss_event, lambda state, b=boss: state.can_reach(b, "Location", player))
|
add_rule(boss_event, lambda state, b=boss: state.can_reach(b, "Location", player))
|
||||||
|
@ -26,136 +25,131 @@ def set_rules(tloz_world: "TLoZWorld"):
|
||||||
for location in level.locations:
|
for location in level.locations:
|
||||||
if options.StartingPosition < StartingPosition.option_dangerous \
|
if options.StartingPosition < StartingPosition.option_dangerous \
|
||||||
or location.name not in dangerous_weapon_locations:
|
or location.name not in dangerous_weapon_locations:
|
||||||
add_rule(world.get_location(location.name, player),
|
add_rule(tloz_world.get_location(location.name),
|
||||||
lambda state: state.has_group("weapons", player))
|
lambda state: state.has_group("weapons", player))
|
||||||
# This part of the loop sets up an expected amount of defense needed for each dungeon
|
# This part of the loop sets up an expected amount of defense needed for each dungeon
|
||||||
if i > 0: # Don't need an extra heart for Level 1
|
if i > 0: # Don't need an extra heart for Level 1
|
||||||
add_rule(world.get_location(location.name, player),
|
add_rule(tloz_world.get_location(location.name),
|
||||||
lambda state, hearts=i: state.has("Heart Container", player, hearts) or
|
lambda state, hearts=i: state.has("Heart Container", player, hearts) or
|
||||||
(state.has("Blue Ring", player) and
|
(state.has("Blue Ring", player) and
|
||||||
state.has("Heart Container", player, int(hearts / 2))) or
|
state.has("Heart Container", player, int(hearts / 2))) or
|
||||||
(state.has("Red Ring", player) and
|
(state.has("Red Ring", player) and
|
||||||
state.has("Heart Container", player, int(hearts / 4))))
|
state.has("Heart Container", player, int(hearts / 4))))
|
||||||
if "Pols Voice" in location.name: # This enemy needs specific weapons
|
if "Pols Voice" in location.name: # This enemy needs specific weapons
|
||||||
add_rule(world.get_location(location.name, player),
|
add_rule(tloz_world.get_location(location.name),
|
||||||
lambda state: state.has_group("swords", player) or state.has("Bow", player))
|
lambda state: state.has_group("swords", player) or
|
||||||
|
(state.has("Bow", player) and state.has_group("arrows", player)))
|
||||||
|
|
||||||
# No requiring anything in a shop until we can farm for money
|
# No requiring anything in a shop until we can farm for money
|
||||||
for location in shop_locations:
|
for location in shop_locations:
|
||||||
add_rule(world.get_location(location, player),
|
add_rule(tloz_world.get_location(location),
|
||||||
lambda state: state.has_group("weapons", player))
|
lambda state: state.has_group("weapons", player))
|
||||||
|
|
||||||
# Everything from 4 on up has dark rooms
|
# Everything from 4 on up has dark rooms
|
||||||
for level in tloz_world.levels[4:]:
|
for level in tloz_world.levels[4:]:
|
||||||
for location in level.locations:
|
for location in level.locations:
|
||||||
add_rule(world.get_location(location.name, player),
|
add_rule(tloz_world.get_location(location.name),
|
||||||
lambda state: state.has_group("candles", player)
|
lambda state: state.has_group("candles", player)
|
||||||
or (state.has("Magical Rod", player) and state.has("Book of Magic", player)))
|
or (state.has("Magical Rod", player) and state.has("Book of Magic", player)))
|
||||||
|
|
||||||
# Everything from 5 on up has gaps
|
# Everything from 5 on up has gaps
|
||||||
for level in tloz_world.levels[5:]:
|
for level in tloz_world.levels[5:]:
|
||||||
for location in level.locations:
|
for location in level.locations:
|
||||||
add_rule(world.get_location(location.name, player),
|
add_rule(tloz_world.get_location(location.name),
|
||||||
lambda state: state.has("Stepladder", player))
|
lambda state: state.has("Stepladder", player))
|
||||||
|
|
||||||
add_rule(world.get_location("Level 5 Boss", player),
|
# Level 4 Access
|
||||||
|
for location in tloz_world.levels[4].locations:
|
||||||
|
add_rule(tloz_world.get_location(location.name),
|
||||||
|
lambda state: state.has_any(("Raft", "Recorder"), player))
|
||||||
|
|
||||||
|
# Digdogger boss. Rework this once ER happens
|
||||||
|
add_rule(tloz_world.get_location("Level 5 Boss"),
|
||||||
|
lambda state: state.has("Recorder", player))
|
||||||
|
add_rule(tloz_world.get_location("Level 5 Triforce"),
|
||||||
lambda state: state.has("Recorder", player))
|
lambda state: state.has("Recorder", player))
|
||||||
|
|
||||||
add_rule(world.get_location("Level 6 Boss", player),
|
for location in gohma_locations:
|
||||||
lambda state: state.has("Bow", player) and state.has_group("arrows", player))
|
if options.ExpandedPool or "Drop" not in location:
|
||||||
|
add_rule(tloz_world.get_location(location),
|
||||||
|
lambda state: state.has("Bow", player) and state.has_group("arrows", player))
|
||||||
|
|
||||||
add_rule(world.get_location("Level 7 Item (Red Candle)", player),
|
# Recorder Access for Level 7
|
||||||
lambda state: state.has("Recorder", player))
|
for location in tloz_world.levels[7].locations:
|
||||||
add_rule(world.get_location("Level 7 Boss", player),
|
add_rule(tloz_world.get_location(location.name),
|
||||||
lambda state: state.has("Recorder", player))
|
|
||||||
if options.ExpandedPool:
|
|
||||||
add_rule(world.get_location("Level 7 Key Drop (Stalfos)", player),
|
|
||||||
lambda state: state.has("Recorder", player))
|
|
||||||
add_rule(world.get_location("Level 7 Bomb Drop (Digdogger)", player),
|
|
||||||
lambda state: state.has("Recorder", player))
|
|
||||||
add_rule(world.get_location("Level 7 Rupee Drop (Dodongos)", player),
|
|
||||||
lambda state: state.has("Recorder", player))
|
lambda state: state.has("Recorder", player))
|
||||||
|
|
||||||
for location in food_locations:
|
for location in food_locations:
|
||||||
if options.ExpandedPool or "Drop" not in location:
|
if options.ExpandedPool or "Drop" not in location:
|
||||||
add_rule(world.get_location(location, player),
|
add_rule(tloz_world.get_location(location),
|
||||||
lambda state: state.has("Food", player))
|
lambda state: state.has("Food", player))
|
||||||
|
|
||||||
for location in gleeok_locations:
|
for location in gleeok_locations:
|
||||||
add_rule(world.get_location(location, player),
|
add_rule(tloz_world.get_location(location),
|
||||||
lambda state: state.has_group("swords", player) or state.has("Magical Rod", player))
|
lambda state: state.has_group("swords", player) or state.has("Magical Rod", player))
|
||||||
|
|
||||||
# Candle access for Level 8
|
# Candle access for Level 8
|
||||||
for location in tloz_world.levels[8].locations:
|
for location in tloz_world.levels[8].locations:
|
||||||
add_rule(world.get_location(location.name, player),
|
add_rule(tloz_world.get_location(location.name),
|
||||||
lambda state: state.has_group("candles", player))
|
lambda state: state.has_group("candles", player))
|
||||||
|
|
||||||
add_rule(world.get_location("Level 8 Item (Magical Key)", player),
|
add_rule(tloz_world.get_location("Level 8 Item (Magical Key)"),
|
||||||
lambda state: state.has("Bow", player) and state.has_group("arrows", player))
|
lambda state: state.has("Bow", player) and state.has_group("arrows", player))
|
||||||
if options.ExpandedPool:
|
if options.ExpandedPool:
|
||||||
add_rule(world.get_location("Level 8 Bomb Drop (Darknuts North)", player),
|
add_rule(tloz_world.get_location("Level 8 Bomb Drop (Darknuts North)"),
|
||||||
lambda state: state.has("Bow", player) and state.has_group("arrows", player))
|
lambda state: state.has("Bow", player) and state.has_group("arrows", player))
|
||||||
|
|
||||||
for location in tloz_world.levels[9].locations:
|
for location in tloz_world.levels[9].locations:
|
||||||
add_rule(world.get_location(location.name, player),
|
add_rule(tloz_world.get_location(location.name),
|
||||||
lambda state: state.has("Triforce Fragment", player, 8) and
|
lambda state: state.has("Triforce Fragment", player, 8) and
|
||||||
state.has_group("swords", player))
|
state.has_group("swords", player))
|
||||||
|
|
||||||
# Yes we are looping this range again for Triforce locations. No I can't add it to the boss event loop
|
# Yes we are looping this range again for Triforce locations. No I can't add it to the boss event loop
|
||||||
for level in range(1, 9):
|
for level in range(1, 9):
|
||||||
add_rule(world.get_location(f"Level {level} Triforce", player),
|
add_rule(tloz_world.get_location(f"Level {level} Triforce"),
|
||||||
lambda state, l=level: state.has(f"Boss {l} Defeated", player))
|
lambda state, l=level: state.has(f"Boss {l} Defeated", player))
|
||||||
|
|
||||||
# Sword, raft, and ladder spots
|
# Sword, raft, and ladder spots
|
||||||
add_rule(world.get_location("White Sword Pond", player),
|
add_rule(tloz_world.get_location("White Sword Pond"),
|
||||||
lambda state: state.has("Heart Container", player, 2))
|
lambda state: state.has("Heart Container", player, 2))
|
||||||
add_rule(world.get_location("Magical Sword Grave", player),
|
add_rule(tloz_world.get_location("Magical Sword Grave"),
|
||||||
lambda state: state.has("Heart Container", player, 9))
|
lambda state: state.has("Heart Container", player, 9))
|
||||||
|
|
||||||
stepladder_locations = ["Ocean Heart Container", "Level 4 Triforce", "Level 4 Boss", "Level 4 Map"]
|
stepladder_locations = ["Ocean Heart Container", "Level 4 Triforce", "Level 4 Boss", "Level 4 Map"]
|
||||||
stepladder_locations_expanded = ["Level 4 Key Drop (Keese North)"]
|
stepladder_locations_expanded = ["Level 4 Key Drop (Keese North)"]
|
||||||
for location in stepladder_locations:
|
for location in stepladder_locations:
|
||||||
add_rule(world.get_location(location, player),
|
add_rule(tloz_world.get_location(location),
|
||||||
lambda state: state.has("Stepladder", player))
|
lambda state: state.has("Stepladder", player))
|
||||||
if options.ExpandedPool:
|
if options.ExpandedPool:
|
||||||
for location in stepladder_locations_expanded:
|
for location in stepladder_locations_expanded:
|
||||||
add_rule(world.get_location(location, player),
|
add_rule(tloz_world.get_location(location),
|
||||||
lambda state: state.has("Stepladder", player))
|
lambda state: state.has("Stepladder", player))
|
||||||
|
|
||||||
# Don't allow Take Any Items until we can actually get in one
|
# Don't allow Take Any Items until we can actually get in one
|
||||||
if options.ExpandedPool:
|
if options.ExpandedPool:
|
||||||
add_rule(world.get_location("Take Any Item Left", player),
|
add_rule(tloz_world.get_location("Take Any Item Left"),
|
||||||
lambda state: state.has_group("candles", player) or
|
lambda state: state.has_group("candles", player) or
|
||||||
state.has("Raft", player))
|
state.has("Raft", player))
|
||||||
add_rule(world.get_location("Take Any Item Middle", player),
|
add_rule(tloz_world.get_location("Take Any Item Middle"),
|
||||||
lambda state: state.has_group("candles", player) or
|
lambda state: state.has_group("candles", player) or
|
||||||
state.has("Raft", player))
|
state.has("Raft", player))
|
||||||
add_rule(world.get_location("Take Any Item Right", player),
|
add_rule(tloz_world.get_location("Take Any Item Right"),
|
||||||
lambda state: state.has_group("candles", player) or
|
lambda state: state.has_group("candles", player) or
|
||||||
state.has("Raft", player))
|
state.has("Raft", player))
|
||||||
for location in tloz_world.levels[4].locations:
|
|
||||||
add_rule(world.get_location(location.name, player),
|
|
||||||
lambda state: state.has("Raft", player) or state.has("Recorder", player))
|
|
||||||
for location in tloz_world.levels[7].locations:
|
|
||||||
add_rule(world.get_location(location.name, player),
|
|
||||||
lambda state: state.has("Recorder", player))
|
|
||||||
for location in tloz_world.levels[8].locations:
|
|
||||||
add_rule(world.get_location(location.name, player),
|
|
||||||
lambda state: state.has("Bow", player))
|
|
||||||
|
|
||||||
add_rule(world.get_location("Potion Shop Item Left", player),
|
add_rule(tloz_world.get_location("Potion Shop Item Left"),
|
||||||
lambda state: state.has("Letter", player))
|
lambda state: state.has("Letter", player))
|
||||||
add_rule(world.get_location("Potion Shop Item Middle", player),
|
add_rule(tloz_world.get_location("Potion Shop Item Middle"),
|
||||||
lambda state: state.has("Letter", player))
|
lambda state: state.has("Letter", player))
|
||||||
add_rule(world.get_location("Potion Shop Item Right", player),
|
add_rule(tloz_world.get_location("Potion Shop Item Right"),
|
||||||
lambda state: state.has("Letter", player))
|
lambda state: state.has("Letter", player))
|
||||||
|
|
||||||
add_rule(world.get_location("Shield Shop Item Left", player),
|
add_rule(tloz_world.get_location("Shield Shop Item Left"),
|
||||||
lambda state: state.has_group("candles", player) or
|
lambda state: state.has_group("candles", player) or
|
||||||
state.has("Bomb", player))
|
state.has("Bomb", player))
|
||||||
add_rule(world.get_location("Shield Shop Item Middle", player),
|
add_rule(tloz_world.get_location("Shield Shop Item Middle"),
|
||||||
lambda state: state.has_group("candles", player) or
|
lambda state: state.has_group("candles", player) or
|
||||||
state.has("Bomb", player))
|
state.has("Bomb", player))
|
||||||
add_rule(world.get_location("Shield Shop Item Right", player),
|
add_rule(tloz_world.get_location("Shield Shop Item Right"),
|
||||||
lambda state: state.has_group("candles", player) or
|
lambda state: state.has_group("candles", player) or
|
||||||
state.has("Bomb", player))
|
state.has("Bomb", player))
|
Loading…
Reference in New Issue