Merged in DR v1.4.1.6
This commit is contained in:
377
Rules.py
377
Rules.py
@@ -11,9 +11,13 @@ from OWEdges import OWExitTypes
|
||||
from OverworldGlitchRules import overworld_glitches_rules
|
||||
from UnderworldGlitchRules import underworld_glitches_rules
|
||||
|
||||
from source.logic.Rule import RuleFactory
|
||||
from source.dungeon.EnemyList import EnemySprite, Sprite
|
||||
from source.enemizer.EnemyLogic import special_rules_check, special_rules_for_region, defeat_rule_single
|
||||
from source.enemizer.EnemyLogic import defeat_rule_multiple, and_rule as and_rule_new, or_rule as or_rule_new
|
||||
|
||||
|
||||
def set_rules(world, player):
|
||||
|
||||
if world.logic[player] == 'nologic':
|
||||
logging.getLogger('').info('WARNING! Seeds generated under this logic often require major glitches and may be impossible!')
|
||||
world.get_region('Menu', player).can_reach_private = lambda state: True
|
||||
@@ -54,13 +58,17 @@ def set_rules(world, player):
|
||||
|
||||
bomb_rules(world, player)
|
||||
pot_rules(world, player)
|
||||
drop_rules(world, player)
|
||||
challenge_room_rules(world, player)
|
||||
|
||||
if world.goal[player] == 'dungeons':
|
||||
# require all dungeons to beat ganon
|
||||
add_rule(world.get_location('Ganon', player), lambda state: state.can_reach('Master Sword Pedestal', 'Location', player) and state.has_beaten_aga(player) and state.has('Beat Agahnim 2', player) and state.has_crystals(7, player))
|
||||
elif world.goal[player] == 'ganon':
|
||||
# require aga2 to beat ganon
|
||||
add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player))
|
||||
elif world.goal[player] in ['crystals', 'ganon']:
|
||||
add_rule(world.get_location('Ganon', player), lambda state: state.has_crystals(world.crystals_needed_for_ganon[player], player))
|
||||
if world.goal[player] == 'ganon':
|
||||
# require aga2 to beat ganon
|
||||
add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player))
|
||||
elif world.goal[player] in ['triforcehunt', 'trinity']:
|
||||
for location in world.get_region('Hyrule Castle Courtyard', player).locations:
|
||||
if location.name == 'Murahdahla':
|
||||
@@ -70,6 +78,7 @@ def set_rules(world, player):
|
||||
elif world.goal[player] == 'completionist':
|
||||
add_rule(world.get_location('Ganon', player), lambda state: state.everything(player))
|
||||
|
||||
|
||||
if (world.flute_mode[player] != 'active' and not world.is_tile_swapped(0x18, player)
|
||||
and 'Ocarina (Activated)' not in list(map(str, [i for i in world.precollected_items if i.player == player]))):
|
||||
if not world.is_copied_world:
|
||||
@@ -146,6 +155,14 @@ def set_always_allow(spot, rule):
|
||||
spot.always_allow = rule
|
||||
|
||||
|
||||
def add_rule_new(spot, rule, combine='and'):
|
||||
if combine == 'and':
|
||||
spot.verbose_rule = and_rule_new(*[spot.verbose_rule, rule])
|
||||
else:
|
||||
spot.verbose_rule = or_rule_new(*[spot.verbose_rule, rule])
|
||||
add_rule(spot, rule.rule_lambda, combine)
|
||||
|
||||
|
||||
def add_rule(spot, rule, combine='and'):
|
||||
old_rule = spot.access_rule
|
||||
if combine == 'or':
|
||||
@@ -269,6 +286,7 @@ def global_rules(world, player):
|
||||
|
||||
# underworld rules
|
||||
set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: state.has_Mirror(player)) # can erase block - overridden in noglitches
|
||||
set_rule(world.get_entrance('Old Man Cave Exit (West)', player), lambda state: False) # drop cannot be climbed up
|
||||
set_rule(world.get_entrance('Hookshot Cave Bonk Path', player), lambda state: state.has('Hookshot', player) or state.has('Pegasus Boots', player))
|
||||
set_rule(world.get_entrance('Hookshot Cave Hook Path', player), lambda state: state.has('Hookshot', player))
|
||||
set_rule(world.get_entrance('Bumper Cave Bottom to Top', player), lambda state: state.has('Cape', player))
|
||||
@@ -325,7 +343,7 @@ def global_rules(world, player):
|
||||
set_rule(world.get_entrance('Skull Woods Rock (West)', player), lambda state: state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Skull Woods Rock (East)', player), lambda state: state.can_lift_rocks(player))
|
||||
# this more like an ohko rule - dependent on bird being present too - so enemizer could turn this off?
|
||||
set_rule(world.get_entrance('Bumper Cave Ledge Drop', player), lambda state: (state.has('Cape', player) or state.has('Cane of Byrna', player) or state.has_sword(player)))
|
||||
set_rule(world.get_entrance('Bumper Cave Ledge Drop', player), lambda state: state.has('Cape', player) or state.has('Cane of Byrna', player) or state.has_sword(player))
|
||||
set_rule(world.get_entrance('Bumper Cave Rock (Outer)', player), lambda state: state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Bumper Cave Rock (Inner)', player), lambda state: state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Skull Woods Pass Rock (North)', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||
@@ -399,13 +417,9 @@ def global_rules(world, player):
|
||||
|
||||
# Eastern Palace
|
||||
# Eyegore room needs a bow
|
||||
set_rule(world.get_entrance('Eastern Duo Eyegores NE', player), lambda state: state.can_shoot_arrows(player))
|
||||
set_rule(world.get_entrance('Eastern Single Eyegore NE', player), lambda state: state.can_shoot_arrows(player))
|
||||
# set_rule(world.get_entrance('Eastern Duo Eyegores NE', player), lambda state: state.can_shoot_arrows(player))
|
||||
# set_rule(world.get_entrance('Eastern Single Eyegore NE', player), lambda state: state.can_shoot_arrows(player))
|
||||
set_rule(world.get_entrance('Eastern Map Balcony Hook Path', player), lambda state: state.has('Hookshot', player))
|
||||
if is_trapped('Eastern Single Eyegore ES'):
|
||||
set_rule(world.get_entrance('Eastern Single Eyegore ES', player), lambda state: state.can_shoot_arrows(player))
|
||||
if is_trapped('Eastern Duo Eyegores SE'):
|
||||
set_rule(world.get_entrance('Eastern Duo Eyegores SE', player), lambda state: state.can_shoot_arrows(player))
|
||||
|
||||
# Boss rules. Same as below but no BK or arrow requirement.
|
||||
set_defeat_dungeon_boss_rule(world.get_location('Eastern Palace - Prize', player))
|
||||
@@ -424,24 +438,12 @@ def global_rules(world, player):
|
||||
set_defeat_dungeon_boss_rule(world.get_location('Tower of Hera - Prize', player))
|
||||
|
||||
# Castle Tower
|
||||
set_rule(world.get_entrance('Tower Gold Knights SW', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('Tower Gold Knights EN', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('Tower Dark Archers WN', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('Tower Red Spears WN', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('Tower Red Guards EN', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('Tower Red Guards SW', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('Tower Circle of Pots NW', player), lambda state: state.can_kill_most_things(player))
|
||||
if is_trapped('Tower Circle of Pots ES'):
|
||||
set_rule(world.get_entrance('Tower Circle of Pots ES', player),
|
||||
lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('Tower Altar NW', player), lambda state: state.has_sword(player))
|
||||
set_defeat_dungeon_boss_rule(world.get_location('Agahnim 1', player))
|
||||
|
||||
set_rule(world.get_entrance('PoD Arena Landing Bonk Path', player), lambda state: state.has_Boots(player))
|
||||
set_rule(world.get_entrance('PoD Mimics 1 NW', player), lambda state: state.can_shoot_arrows(player))
|
||||
set_rule(world.get_entrance('PoD Mimics 2 NW', player), lambda state: state.can_shoot_arrows(player))
|
||||
if is_trapped('PoD Mimics 2 SW'):
|
||||
set_rule(world.get_entrance('PoD Mimics 2 SW', player), lambda state: state.can_shoot_arrows(player))
|
||||
# set_rule(world.get_entrance('PoD Mimics 1 NW', player), lambda state: state.can_shoot_arrows(player))
|
||||
# set_rule(world.get_entrance('PoD Mimics 2 NW', player), lambda state: state.can_shoot_arrows(player))
|
||||
set_rule(world.get_entrance('PoD Bow Statue Down Ladder', player), lambda state: state.can_shoot_arrows(player))
|
||||
set_rule(world.get_entrance('PoD Map Balcony Drop Down', player), lambda state: state.has('Hammer', player))
|
||||
set_rule(world.get_entrance('PoD Dark Pegs Landing to Right', player), lambda state: state.has('Hammer', player))
|
||||
@@ -532,6 +534,7 @@ def global_rules(world, player):
|
||||
if is_trapped('Ice Lobby SE'):
|
||||
set_rule(world.get_entrance('Ice Lobby SE', player), lambda state: state.can_melt_things(player))
|
||||
set_rule(world.get_entrance('Ice Hammer Block ES', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
||||
set_rule(world.get_entrance('Ice Right H Path', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
||||
set_rule(world.get_location('Ice Palace - Hammer Block Key Drop', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
||||
set_rule(world.get_location('Ice Palace - Map Chest', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
||||
set_rule(world.get_entrance('Ice Antechamber Hole', player), lambda state: state.can_lift_rocks(player) and state.has('Hammer', player))
|
||||
@@ -577,9 +580,10 @@ def global_rules(world, player):
|
||||
set_rule(world.get_entrance('Mire Tile Room ES', player), lambda state: state.has_fire_source(player))
|
||||
set_rule(world.get_entrance('Mire Attic Hint Hole', player), lambda state: state.has_fire_source(player))
|
||||
set_rule(world.get_entrance('Mire Dark Shooters SW', player), lambda state: state.has('Cane of Somaria', player))
|
||||
if is_trapped('Mire Dark Shooters SE'):
|
||||
set_rule(world.get_entrance('Mire Dark Shooters SE', player),
|
||||
lambda state: state.has('Cane of Somaria', player))
|
||||
# Not: somaria doesn't work here, so this cannot be opened if trapped
|
||||
# if is_trapped('Mire Dark Shooters SE'):
|
||||
# set_rule(world.get_entrance('Mire Dark Shooters SE', player),
|
||||
# lambda state: state.has('Cane of Somaria', player))
|
||||
|
||||
set_defeat_dungeon_boss_rule(world.get_location('Misery Mire - Boss', player))
|
||||
set_defeat_dungeon_boss_rule(world.get_location('Misery Mire - Prize', player))
|
||||
@@ -649,21 +653,12 @@ def global_rules(world, player):
|
||||
set_rule(world.get_entrance('GT Mimics 2 NE', player), lambda state: state.can_shoot_arrows(player))
|
||||
# consider access to refill room - interior doors would need a change
|
||||
set_rule(world.get_entrance('GT Cannonball Bridge SE', player), lambda state: state.has_Boots(player))
|
||||
set_rule(world.get_entrance('GT Gauntlet 1 WN', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Gauntlet 2 EN', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Gauntlet 2 SW', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Gauntlet 3 NW', player), lambda state: state.can_kill_most_things(player))
|
||||
if not world.get_door('GT Gauntlet 3 SW', player).entranceFlag:
|
||||
set_rule(world.get_entrance('GT Gauntlet 3 SW', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Gauntlet 4 NW', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Gauntlet 4 SW', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Gauntlet 5 NW', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Gauntlet 5 WS', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Wizzrobes 1 SW', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Wizzrobes 2 SE', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Wizzrobes 2 NE', player), lambda state: state.can_kill_most_things(player))
|
||||
set_rule(world.get_entrance('GT Lanmolas 2 ES', player), lambda state: world.get_region('GT Lanmolas 2', player).dungeon.bosses['middle'].can_defeat(state))
|
||||
set_rule(world.get_entrance('GT Lanmolas 2 NW', player), lambda state: world.get_region('GT Lanmolas 2', player).dungeon.bosses['middle'].can_defeat(state))
|
||||
# Need cape to safely get past trinexx backwards in this room, makes magic usage tighter
|
||||
# Could not guarantee safety with byrna, not sure why
|
||||
if world.get_region('GT Lanmolas 2', player).dungeon.bosses['middle'].name == 'Trinexx':
|
||||
add_rule(world.get_entrance('GT Quad Pot SW', player), lambda state: state.has('Cape', player))
|
||||
set_rule(world.get_entrance('GT Torch Cross ES', player), lambda state: state.has_fire_source(player))
|
||||
if is_trapped('GT Torch Cross WN'):
|
||||
set_rule(world.get_entrance('GT Torch Cross WN', player), lambda state: state.has_fire_source(player))
|
||||
@@ -763,6 +758,7 @@ def global_rules(world, player):
|
||||
set_rule(world.get_entrance('Ice Bomb Jump Ledge Orange Barrier', player), lambda state: state.can_reach_orange(world.get_region('Ice Bomb Jump Ledge', player), player))
|
||||
set_rule(world.get_entrance('Ice Bomb Jump Catwalk Orange Barrier', player), lambda state: state.can_reach_orange(world.get_region('Ice Bomb Jump Catwalk', player), player))
|
||||
|
||||
set_rule(world.get_entrance('Ice Bomb Drop Path', player), lambda state: state.can_hit_crystal(player))
|
||||
set_rule(world.get_entrance('Ice Conveyor to Crystal', player), lambda state: state.can_hit_crystal(player))
|
||||
set_rule(world.get_entrance('Ice Refill to Crystal', player), lambda state: state.can_hit_crystal(player) or state.can_reach_blue(world.get_region('Ice Refill', player), player))
|
||||
|
||||
@@ -873,9 +869,6 @@ def global_rules(world, player):
|
||||
|
||||
set_rule(world.get_location('Ganon', player), lambda state: state.has_beam_sword(player) and state.has_fire_source(player)
|
||||
and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) or (state.has('Silver Arrows', player) and state.can_shoot_arrows(player)) or state.has('Lamp', player) or state.can_extend_magic(player, 12))) # need to light torch a sufficient amount of times
|
||||
if world.goal[player] != 'ganonhunt':
|
||||
add_rule(world.get_location('Ganon', player), lambda state: state.has_crystals(world.crystals_needed_for_ganon[player], player))
|
||||
|
||||
set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop
|
||||
|
||||
|
||||
@@ -884,7 +877,9 @@ def bomb_rules(world, player):
|
||||
bonkable_doors = ['Two Brothers House Exit (West)', 'Two Brothers House Exit (East)'] # Technically this is incorrectly defined, but functionally the same as what is intended.
|
||||
bombable_doors = ['Ice Rod Cave', 'Light World Bomb Hut', 'Paradox Shop', 'Mini Moldorm Cave',
|
||||
'Hookshot Cave Back to Middle', 'Hookshot Cave Front to Middle', 'Hookshot Cave Middle to Front',
|
||||
'Hookshot Cave Middle to Back', 'Dark Lake Hylia Ledge Fairy', 'Hype Cave', 'Brewery',
|
||||
'Hookshot Cave Middle to Back', 'Hookshot Cave Back to Fairy', 'Hookshot Cave Fairy to Back',
|
||||
'Good Bee Cave Front to Back', 'Good Bee Cave Back to Front', 'Capacity Upgrade East',
|
||||
'Capacity Fairy Pool West', 'Dark Lake Hylia Ledge Fairy', 'Hype Cave', 'Brewery',
|
||||
'Paradox Cave Chest Area NE', 'Blinds Hideout N', 'Kakariko Well (top to back)',
|
||||
'Light Hype Fairy']
|
||||
for entrance in bonkable_doors:
|
||||
@@ -904,81 +899,10 @@ def bomb_rules(world, player):
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_use_bombs(player))
|
||||
add_bunny_rule(world.get_location(location, player), player)
|
||||
|
||||
cave_kill_locations = ['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Left', 'Mini Moldorm Cave - Right', 'Mini Moldorm Cave - Generous Guy', 'Spiral Cave']
|
||||
for location in cave_kill_locations:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_kill_most_things(player) or state.can_use_bombs(player))
|
||||
add_bunny_rule(world.get_location(location, player), player)
|
||||
add_rule(world.get_entrance('Spiral Cave (top to bottom)', player), lambda state: state.can_kill_most_things(player) or state.can_use_bombs(player))
|
||||
add_bunny_rule(world.get_entrance('Spiral Cave (top to bottom)', player), player)
|
||||
|
||||
paradox_switch_chests = ['Paradox Cave Lower - Far Left', 'Paradox Cave Lower - Left', 'Paradox Cave Lower - Right', 'Paradox Cave Lower - Far Right', 'Paradox Cave Lower - Middle']
|
||||
for location in paradox_switch_chests:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_hit_crystal_through_barrier(player))
|
||||
add_bunny_rule(world.get_location(location, player), player)
|
||||
|
||||
# Dungeon bomb logic
|
||||
easy_kill_rooms = [ # Door, bool-bombable
|
||||
('Hyrule Dungeon Armory S', True), # One green guard
|
||||
('Hyrule Dungeon Armory ES', True), # One green guard
|
||||
('Hyrule Dungeon Armory Boomerang WS', True), # One blue guard
|
||||
('Desert Compass NE', True), # Three popos
|
||||
('Desert Four Statues NW', True), # Four popos
|
||||
('Desert Four Statues ES', True), # Four popos
|
||||
('Hera Beetles WS', False), # Three blue beetles and only two pots, and bombs don't work.
|
||||
('Thieves Basement Block WN', True), # One blue and one red zazak and one Stalfos. Two pots. Need to kill the third enemy somehow.
|
||||
('Ice Pengator Trap NE', False), # Five pengators. Bomb-doable?
|
||||
('TR Twin Pokeys EN', False), # Two pokeys
|
||||
('TR Twin Pokeys SW', False), # Two pokeys
|
||||
('GT Petting Zoo SE', False), # Dont make anyone do this room with bombs and/or pots.
|
||||
('GT DMs Room SW', False) # Four red stalfos
|
||||
]
|
||||
conditional_kill_traps = [
|
||||
('Hyrule Dungeon Armory Interior Key Door N', True),
|
||||
('Desert Compass Key Door WN', True),
|
||||
('Thieves Blocked Entry SW', True),
|
||||
('TR Tongue Pull WS', True),
|
||||
('TR Twin Pokeys NW', False),
|
||||
]
|
||||
for killdoor, bombable in easy_kill_rooms:
|
||||
if bombable:
|
||||
add_rule(world.get_entrance(killdoor, player), lambda state: (state.can_use_bombs(player) or state.can_kill_most_things(player)))
|
||||
else:
|
||||
add_rule(world.get_entrance(killdoor, player), lambda state: state.can_kill_most_things(player))
|
||||
for kill_door, bombable in conditional_kill_traps:
|
||||
if world.get_entrance(kill_door, player).door.trapped:
|
||||
if bombable:
|
||||
add_rule(world.get_entrance(kill_door, player),
|
||||
lambda state: (state.can_use_bombs(player) or state.can_kill_most_things(player)))
|
||||
else:
|
||||
add_rule(world.get_entrance(kill_door, player), lambda state: state.can_kill_most_things(player))
|
||||
add_rule(world.get_entrance('Ice Stalfos Hint SE', player), lambda state: state.can_use_bombs(player)) # Need bombs for big stalfos knights
|
||||
add_rule(world.get_entrance('Mire Cross ES', player), lambda state: state.can_kill_most_things(player)) # 4 Sluggulas. Bombs don't work // or (state.can_use_bombs(player) and state.has('Magic Powder'), player)
|
||||
if world.get_entrance('Mire Cross SW', player).door.trapped:
|
||||
add_rule(world.get_entrance('Mire Cross SW', player), lambda state: state.can_kill_most_things(player))
|
||||
|
||||
enemy_kill_drops = [ # Location, bool-bombable
|
||||
('Hyrule Castle - Map Guard Key Drop', True),
|
||||
('Hyrule Castle - Boomerang Guard Key Drop', True),
|
||||
('Hyrule Castle - Key Rat Key Drop', True),
|
||||
# ('Hyrule Castle - Big Key Drop', True), # Pots are available
|
||||
# ('Eastern Palace - Dark Eyegore Key Drop', True), # Pots are available
|
||||
('Castle Tower - Dark Archer Key Drop', True),
|
||||
# ('Castle Tower - Circle of Pots Key Drop', True), # Pots are available
|
||||
# ('Skull Woods - Spike Corner Key Drop', True), # Pots are available
|
||||
('Ice Palace - Jelly Key Drop', True),
|
||||
('Ice Palace - Conveyor Key Drop', True),
|
||||
('Misery Mire - Conveyor Crystal Key Drop', True),
|
||||
('Turtle Rock - Pokey 1 Key Drop', True),
|
||||
('Turtle Rock - Pokey 2 Key Drop', True),
|
||||
# ('Ganons Tower - Mini Helmasaur Key Drop', True) # Pots are available
|
||||
('Castle Tower - Room 03', True), # Two spring soliders
|
||||
('Ice Palace - Compass Chest', True) # Pengators
|
||||
]
|
||||
for location, bombable in enemy_kill_drops:
|
||||
if bombable:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_use_bombs(player) or state.can_kill_most_things(player))
|
||||
else:
|
||||
add_rule(world.get_location(location, player), lambda state: state.can_kill_most_things(player))
|
||||
|
||||
add_rule(world.get_location('Attic Cracked Floor', player), lambda state: state.can_use_bombs(player))
|
||||
bombable_floors = ['PoD Pit Room Bomb Hole', 'Ice Bomb Drop Hole', 'Ice Freezors Bomb Hole', 'GT Bob\'s Room Hole']
|
||||
@@ -1012,8 +936,57 @@ def bomb_rules(world, player):
|
||||
for door in doors_to_bomb_check:
|
||||
if door.kind(world) in [DoorKind.Dashable]:
|
||||
add_rule(door.entrance, lambda state: state.can_use_bombs(player) or state.has_Boots(player))
|
||||
if door.dependents:
|
||||
for dep in door.dependents:
|
||||
add_rule(dep.entrance, lambda state: state.can_use_bombs(player) or state.has_Boots(player))
|
||||
elif door.kind(world) in [DoorKind.Bombable]:
|
||||
add_rule(door.entrance, lambda state: state.can_use_bombs(player))
|
||||
if door.dependents:
|
||||
for dep in door.dependents:
|
||||
add_rule(dep.entrance, lambda state: state.can_use_bombs(player))
|
||||
|
||||
|
||||
def challenge_room_rules(world, player):
|
||||
room_map = world.data_tables[player].uw_enemy_table.room_map
|
||||
stats = world.data_tables[player].enemy_stats
|
||||
for region, data in std_kill_rooms.items():
|
||||
entrances, trap_ables, room_id, enemy_list = data
|
||||
rule = get_challenge_rule(world, player, room_map, stats, room_id, enemy_list, region)
|
||||
for ent in entrances:
|
||||
entrance = world.get_entrance(ent, player)
|
||||
if not entrance.door or not entrance.door.entranceFlag:
|
||||
add_rule_new(entrance, rule)
|
||||
for ent in trap_ables:
|
||||
entrance = world.get_entrance(ent, player)
|
||||
if entrance.door.trapped and not entrance.door.entranceFlag:
|
||||
add_rule_new(entrance, rule)
|
||||
for region, data in kill_chests.items():
|
||||
locations, room_id, enemy_list = data
|
||||
rule = get_challenge_rule(world, player, room_map, stats, room_id, enemy_list, region)
|
||||
for loc in locations:
|
||||
add_rule_new(world.get_location(loc, player), rule)
|
||||
|
||||
|
||||
def get_challenge_rule(world, player, room_map, stats, room_id, enemy_list, region):
|
||||
sprite_list = room_map[room_id]
|
||||
sprite_region_pairs = []
|
||||
for idx, sprite in enumerate(sprite_list):
|
||||
if idx in enemy_list:
|
||||
if not stats[sprite.kind].ignore_for_kill_room:
|
||||
sprite_region_pairs.append((sprite, world.get_region(sprite.region, player)))
|
||||
if region == 'Eastern Stalfos Spawn':
|
||||
stalfos_spawn_exception(sprite_region_pairs, stats, world, player)
|
||||
if sprite_region_pairs:
|
||||
return defeat_rule_multiple(world, player, sprite_region_pairs)
|
||||
return RuleFactory.static_rule(True)
|
||||
|
||||
|
||||
def stalfos_spawn_exception(sprite_region_pairs, stats, world, player):
|
||||
if stats[EnemySprite.Stalfos].health * 4 > 40:
|
||||
for x in range(0, 4):
|
||||
sprite_region_pairs.append((Sprite(0x00a8, EnemySprite.Stalfos, 0, 0, 0, 0, 'Eastern Stalfos Spawn'),
|
||||
world.get_region('Eastern Stalfos Spawn', player)))
|
||||
return sprite_region_pairs
|
||||
|
||||
|
||||
def pot_rules(world, player):
|
||||
@@ -1061,6 +1034,20 @@ def pot_rules(world, player):
|
||||
add_rule(l, lambda state: state.can_hit_crystal(player))
|
||||
|
||||
|
||||
def drop_rules(world, player):
|
||||
data_tables = world.data_tables[player]
|
||||
for super_tile, enemy_list in data_tables.uw_enemy_table.room_map.items():
|
||||
for enemy in enemy_list:
|
||||
if enemy.location:
|
||||
rule = defeat_rule_single(world, player, enemy, enemy.location.parent_region)
|
||||
if enemy.location.parent_region.name in special_rules_check:
|
||||
rule = special_rules_for_region(world, player, enemy.location.parent_region.name,
|
||||
enemy.location, rule)
|
||||
if rule.rule_lambda is None:
|
||||
raise Exception(f'Bad rule for enemy drop. Need to inspect this case: {hex(enemy.kind)}')
|
||||
add_rule_new(enemy.location, rule)
|
||||
|
||||
|
||||
def ow_inverted_rules(world, player):
|
||||
if world.is_atgt_swapped(player):
|
||||
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player))
|
||||
@@ -1304,6 +1291,7 @@ def ow_bunny_rules(world, player):
|
||||
add_bunny_rule(world.get_entrance('Ice Lake Southwest Water Drop', player), player)
|
||||
add_bunny_rule(world.get_entrance('Ice Lake Southeast Water Drop', player), player)
|
||||
add_bunny_rule(world.get_entrance('Ice Lake Iceberg Water Entry', player), player)
|
||||
add_bunny_rule(world.get_entrance('Ice Lake Iceberg Bomb Jump', player), player)
|
||||
add_bunny_rule(world.get_entrance('Shopping Mall Water Drop', player), player)
|
||||
add_bunny_rule(world.get_entrance('Bomber Corner Water Drop', player), player)
|
||||
add_bunny_rule(world.get_entrance('Bomber Corner Waterfall Water Drop', player), player)
|
||||
@@ -1440,7 +1428,8 @@ def add_conditional_lamps(world, player):
|
||||
'Sewers Water': {'sewer': True, 'entrances': ['Sewers Water S', 'Sewers Water W'], 'locations': []},
|
||||
'Sewers Dark Aquabats': {'sewer': True, 'entrances': ['Sewers Dark Aquabats N', 'Sewers Dark Aquabats ES'], 'locations': []},
|
||||
'Sewers Key Rat': {'sewer': True, 'entrances': ['Sewers Key Rat S', 'Sewers Key Rat NE'], 'locations': ['Hyrule Castle - Key Rat Key Drop']},
|
||||
'Old Man Cave': {'sewer': False, 'entrances': ['Old Man Cave Exit (East)']},
|
||||
'Old Man Cave (East)': {'sewer': False, 'entrances': ['Old Man Cave Exit (East)', 'Old Man Cave W']},
|
||||
'Old Man Cave (West)': {'sewer': False, 'entrances': ['Old Man Cave E']},
|
||||
'Old Man House Back': {'sewer': False, 'entrances': ['Old Man House Back to Front', 'Old Man House Exit (Top)']},
|
||||
'Death Mountain Return Cave (left)': {'sewer': False, 'entrances': ['Death Mountain Return Cave E', 'Death Mountain Return Cave Exit (West)']},
|
||||
'Death Mountain Return Cave (right)': {'sewer': False, 'entrances': ['Death Mountain Return Cave Exit (East)', 'Death Mountain Return Cave W']},
|
||||
@@ -1485,7 +1474,7 @@ def swordless_rules(world, player):
|
||||
|
||||
set_rule(world.get_location('Ether Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has('Hammer', player))
|
||||
set_rule(world.get_location('Bombos Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has('Hammer', player))
|
||||
set_rule(world.get_location('Ganon', player), lambda state: state.has('Hammer', player) and state.has_fire_source(player) and state.has('Silver Arrows', player) and state.can_shoot_arrows(player) and state.has_crystals(world.crystals_needed_for_ganon[player], player))
|
||||
set_rule(world.get_location('Ganon', player), lambda state: state.has('Hammer', player) and state.has_fire_source(player) and state.has('Silver Arrows', player) and state.can_shoot_arrows(player))
|
||||
set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has('Hammer', player)) # need to damage ganon to get tiles to drop
|
||||
|
||||
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!)
|
||||
@@ -1494,50 +1483,93 @@ def swordless_rules(world, player):
|
||||
if not world.is_atgt_swapped(player):
|
||||
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player)) # barrier gets removed after killing agahnim, rule for that added later
|
||||
|
||||
# todo: new traps
|
||||
std_kill_rooms = {
|
||||
'Hyrule Dungeon Armory Main': ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory ES'], # One green guard
|
||||
'Hyrule Dungeon Armory Boomerang': ['Hyrule Dungeon Armory Boomerang WS'], # One blue guard
|
||||
'Eastern Stalfos Spawn': ['Eastern Stalfos Spawn ES', 'Eastern Stalfos Spawn NW'], # Can use pots
|
||||
'Desert Compass Room': ['Desert Compass NE'], # Three popos
|
||||
'Desert Four Statues': ['Desert Four Statues NW', 'Desert Four Statues ES'], # Four popos
|
||||
'Hera Beetles': ['Hera Beetles WS'], # Three blue beetles and only two pots, and bombs don't work.
|
||||
'Tower Gold Knights': ['Tower Gold Knights SW', 'Tower Gold Knights EN'], # Two ball and chain
|
||||
'Tower Dark Archers': ['Tower Dark Archers WN'], # Not a kill room
|
||||
'Tower Red Spears': ['Tower Red Spears WN'], # Two spear soldiers
|
||||
'Tower Red Guards': ['Tower Red Guards EN', 'Tower Red Guards SW'], # Two usain bolts
|
||||
'Tower Circle of Pots': ['Tower Circle of Pots NW'], # Two spear soldiers. Plenty of pots.
|
||||
'PoD Turtle Party': ['PoD Turtle Party ES', 'PoD Turtle Party NW'], # Lots of turtles.
|
||||
'Thieves Basement Block': ['Thieves Basement Block WN'], # One blue and one red zazak and one Stalfos. Two pots. Need weapon.
|
||||
'Ice Stalfos Hint': ['Ice Stalfos Hint SE'], # Need bombs for big stalfos knights
|
||||
'Ice Pengator Trap': ['Ice Pengator Trap NE'], # Five pengators. Bomb-doable?
|
||||
'Mire 2': ['Mire 2 NE'], # Wizzrobes. Bombs dont work.
|
||||
'Mire Cross': ['Mire Cross ES'], # 4 Sluggulas. Bombs don't work
|
||||
'TR Twin Pokeys': ['TR Twin Pokeys EN', 'TR Twin Pokeys SW'], # Two pokeys
|
||||
'GT Petting Zoo': ['GT Petting Zoo SE'], # Dont make anyone do this room with bombs.
|
||||
'GT DMs Room': ['GT DMs Room SW'], # Four red stalfos
|
||||
'GT Gauntlet 1': ['GT Gauntlet 1 WN'], # Stalfos/zazaks
|
||||
'GT Gauntlet 2': ['GT Gauntlet 2 EN', 'GT Gauntlet 2 SW'], # Red stalfos
|
||||
'GT Gauntlet 3': ['GT Gauntlet 3 NW', 'GT Gauntlet 3 SW'], # Blue zazaks
|
||||
'GT Gauntlet 4': ['GT Gauntlet 4 NW', 'GT Gauntlet 4 SW'], # Red zazaks
|
||||
'GT Gauntlet 5': ['GT Gauntlet 5 NW', 'GT Gauntlet 5 WS'], # Stalfos and zazak
|
||||
'GT Wizzrobes 1': ['GT Wizzrobes 1 SW'], # Wizzrobes. Bombs don't work
|
||||
'GT Wizzrobes 2': ['GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE'] # Wizzrobes. Bombs don't work
|
||||
} # all trap rooms?
|
||||
'Hyrule Dungeon Armory Main': # One green guard
|
||||
(['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory ES'], ['Hyrule Dungeon Armory Interior Key Door N'],
|
||||
0x71, [0]),
|
||||
'Hyrule Dungeon Armory Boomerang': # One blue guard
|
||||
(['Hyrule Dungeon Armory Boomerang WS'], [], 0x71, [1]),
|
||||
'Eastern Stalfos Spawn': # Can use pots up to a point see stalfos_spawn_exception
|
||||
(['Eastern Stalfos Spawn ES', 'Eastern Stalfos Spawn NW'], [], 0xa8, []),
|
||||
'Eastern Single Eyegore':
|
||||
(['Eastern Single Eyegore NE'], ['Eastern Single Eyegore ES'], 0xd8, [8, 9, 10]),
|
||||
'Eastern Duo Eyegores':
|
||||
(['Eastern Duo Eyegores NE'], ['Eastern Duo Eyegores SE'], 0xd8, [0, 1, 2, 3, 4, 5, 6, 7]),
|
||||
'Desert Compass Room': # Three popos (beamos)
|
||||
(['Desert Compass NE'], ['Desert Compass Key Door WN'], 0x085, [2, 3, 4, 5]),
|
||||
'Desert Four Statues': # Four popos (beamos)
|
||||
(['Desert Four Statues NW', 'Desert Four Statues ES'], [], 0x53, [5, 6, 8, 9, 10]),
|
||||
'Hera Beetles': # Three blue beetles and only two pots, and bombs don't work.
|
||||
(['Hera Beetles WS'], [], 0x31, [7, 8, 10]),
|
||||
'Tower Gold Knights': # Two ball and chain
|
||||
(['Tower Gold Knights SW', 'Tower Gold Knights EN'], [], 0xe0, [0, 1]),
|
||||
'Tower Dark Archers': # Backwards kill room
|
||||
(['Tower Dark Archers WN'], [], 0xc0, [0, 1, 3]),
|
||||
'Tower Red Spears': # Two spear soldiers
|
||||
(['Tower Red Spears WN'], [], 0xb0, [1, 2, 3, 4]),
|
||||
'Tower Red Guards': # Two usain bolts
|
||||
(['Tower Red Guards EN', 'Tower Red Guards SW'], [], 0xb0, [0, 5]),
|
||||
'Tower Circle of Pots': # Two spear soldiers. Plenty of pots.
|
||||
(['Tower Circle of Pots NW'], ['Tower Circle of Pots ES'], 0xb0, [7, 8, 9, 10]),
|
||||
'PoD Mimics 1':
|
||||
(['PoD Mimics 1 NW'], ['PoD Mimics 1 SW'], 0x4b, [0, 3, 4]),
|
||||
'PoD Mimics 2':
|
||||
(['PoD Mimics 2 NW'], ['PoD Mimics 2 SW'], 0x1b, [3, 4, 5]),
|
||||
'PoD Turtle Party': # Lots of turtles.
|
||||
(['PoD Turtle Party ES', 'PoD Turtle Party NW'], [], 0x0b, [4, 5, 6, 7, 8, 9]),
|
||||
'Thieves Basement Block': # One blue and one red zazak and one Stalfos. Two pots. Need weapon.
|
||||
(['Thieves Basement Block WN'], ['Thieves Blocked Entry SW'], 0x45, [1, 2, 3]),
|
||||
'Ice Jelly Key':
|
||||
(['Ice Jelly Key ES'], [], 0x0e, [1, 2, 3]),
|
||||
'Ice Stalfos Hint': # Need bombs for big stalfos knights
|
||||
(['Ice Stalfos Hint SE'], [], 0x3e, [1, 2]),
|
||||
'Ice Pengator Trap': # Five pengators. Bomb-doable?
|
||||
(['Ice Pengator Trap NE'], [], 0x6e, [0, 1, 2, 3, 4]),
|
||||
'Mire 2': # Wizzrobes. Bombs dont work.
|
||||
(['Mire 2 NE'], [], 0xd2, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
|
||||
'Mire Cross': # 4 Sluggulas. Bombs don't work
|
||||
(['Mire Cross ES'], ['Mire Cross SW'], 0xb2, [5, 6, 7, 10, 11]),
|
||||
'TR Twin Pokeys': # Two pokeys
|
||||
(['TR Twin Pokeys EN', 'TR Twin Pokeys SW'], ['TR Twin Pokeys NW'], 0x24, [3, 4, 5, 6]),
|
||||
'TR Tongue Pull': # Kill zols for money
|
||||
(['TR Tongue Pull NE'], ['TR Tongue Pull WS'], 0x04, [9, 13, 14]),
|
||||
'GT Petting Zoo': # Don't make anyone do this room with bombs.
|
||||
(['GT Petting Zoo SE'], [], 0x7d, [4, 5, 6, 7, 8, 10]),
|
||||
'GT DMs Room': # Four red stalfos
|
||||
(['GT DMs Room SW'], [], 0x7b, [2, 3, 4, 5, 8, 9, 10]),
|
||||
'GT Gauntlet 1': # Stalfos/zazaks
|
||||
(['GT Gauntlet 1 WN'], [], 0x5d, [3, 4, 5, 6]),
|
||||
'GT Gauntlet 2': # Red stalfos
|
||||
(['GT Gauntlet 2 EN', 'GT Gauntlet 2 SW'], [], 0x5d, [0, 1, 2, 7]),
|
||||
'GT Gauntlet 3': # Blue zazaks
|
||||
(['GT Gauntlet 3 NW', 'GT Gauntlet 3 SW'], [], 0x5d, [8, 9, 10, 11, 12]),
|
||||
'GT Gauntlet 4': # Red zazaks
|
||||
(['GT Gauntlet 4 NW', 'GT Gauntlet 4 SW'], [], 0x6d, [0, 1, 2, 3]),
|
||||
'GT Gauntlet 5': # Stalfos and zazak
|
||||
(['GT Gauntlet 5 NW', 'GT Gauntlet 5 WS'], [], 0x6d, [4, 5, 6, 7, 8]),
|
||||
'GT Wizzrobes 1': # Wizzrobes. Bombs don't work
|
||||
(['GT Wizzrobes 1 SW'], [], 0xa5, [2, 3, 7]),
|
||||
'GT Wizzrobes 2': # Wizzrobes. Bombs don't work
|
||||
(['GT Wizzrobes 2 SE', 'GT Wizzrobes 2 NE'], [], 0xa5, [0, 1, 4, 5, 6]),
|
||||
'Spiral Cave (Top)': # for traversal in enemizer at low health
|
||||
(['Spiral Cave (top to bottom)'], [], 0xEE, [0, 1, 2, 3, 4]),
|
||||
} # all trap rooms? (Desert Trap Room, Thieves Trap Room currently subtile only)
|
||||
|
||||
std_kill_doors_if_trapped = {
|
||||
'Hyrule Dungeon Armory Main': 'Hyrule Dungeon Armory Interior Key Door N',
|
||||
# 'Eastern Single Eyegore ES', # arrow rule is sufficient
|
||||
# 'Eastern Duo Eyegores S', # arrow rule is sufficient
|
||||
'TR Twin Pokeys': 'TR Twin Pokeys NW',
|
||||
'Thieves Basement Block': 'Thieves Blocked Entry SW',
|
||||
'Desert Compass Room': 'Desert Compass Key Door WN',
|
||||
'Mire Cross': 'Mire Cross SW',
|
||||
'Tower Circle of Pots': 'Tower Circle of Pots ES',
|
||||
# 'Ice Lobby S' # can melt rule is sufficient
|
||||
kill_chests = {
|
||||
'Tower Room 03': (['Castle Tower - Room 03'], 0xe0, [2, 3]),
|
||||
'Ice Compass Room': (['Ice Palace - Compass Chest'], 0x2e, [0, 1, 2, 3, 4, 5]),
|
||||
'Swamp Entrance': (['Swamp Palace - Entrance'], 0x28, [0, 1, 2, 3, 4]),
|
||||
'GT Tile Room': (['Ganons Tower - Tile Room'], 0x8d, [1, 2, 3, 4]),
|
||||
'Mini Moldorm Cave':
|
||||
(['Mini Moldorm Cave - Far Left', 'Mini Moldorm Cave - Far Right', 'Mini Moldorm Cave - Left',
|
||||
'Mini Moldorm Cave - Right', 'Mini Moldorm Cave - Generous Guy'], 0x123, [0, 1, 2, 3]),
|
||||
'Mimic Cave':
|
||||
(['Mimic Cave'], 0x10c, [4, 5, 6, 7]),
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
def add_connection(parent_name, target_name, entrance_name, world, player):
|
||||
parent = world.get_region(parent_name, player)
|
||||
target = world.get_region(target_name, player)
|
||||
@@ -1589,12 +1621,12 @@ def standard_rules(world, player):
|
||||
for loc in region.locations:
|
||||
add_rule(loc, lambda state: standard_escape_rule(state))
|
||||
if region.name in std_kill_rooms:
|
||||
for ent in std_kill_rooms[region.name]:
|
||||
for ent in std_kill_rooms[region.name][0]:
|
||||
add_rule(world.get_entrance(ent, player), lambda state: standard_escape_rule(state))
|
||||
if region.name in std_kill_doors_if_trapped:
|
||||
ent = world.get_entrance(std_kill_doors_if_trapped[region.name], player)
|
||||
if ent.door.trapped:
|
||||
add_rule(ent, lambda state: standard_escape_rule(state))
|
||||
for ent in std_kill_rooms[region.name][1]:
|
||||
entrance = world.get_entrance(ent, player)
|
||||
if entrance.door.trapped:
|
||||
add_rule(entrance, lambda state: standard_escape_rule(state))
|
||||
|
||||
set_rule(world.get_location('Zelda Pickup', player), lambda state: state.has('Big Key (Escape)', player))
|
||||
set_rule(world.get_entrance('Hyrule Castle Tapestry Backwards', player), lambda state: state.has('Zelda Herself', player))
|
||||
@@ -1930,8 +1962,9 @@ bunny_impassible_doors = {
|
||||
'Thieves Hellway Blue Barrier', 'Thieves Hellway Crystal Blue Barrier', 'Thieves Attic ES',
|
||||
'Thieves Basement Block Path', 'Thieves Blocked Entry Path', 'Thieves Conveyor Bridge Block Path',
|
||||
'Thieves Conveyor Block Path', 'Ice Lobby WS', 'Ice Cross Left Push Block', 'Ice Cross Bottom Push Block Left',
|
||||
'Ice Bomb Drop Hole', 'Ice Pengator Switch WS', 'Ice Pengator Switch ES', 'Ice Big Key Push Block', 'Ice Stalfos Hint SE', 'Ice Bomb Jump EN',
|
||||
'Ice Pengator Trap NE', 'Ice Hammer Block ES', 'Ice Tongue Pull WS', 'Ice Freezors Bomb Hole', 'Ice Tall Hint WS',
|
||||
'Ice Bomb Drop Hole', 'Ice Pengator Switch WS', 'Ice Pengator Switch ES', 'Ice Big Key Push Block',
|
||||
'Ice Stalfos Hint SE', 'Ice Bomb Jump EN', 'Ice Pengator Trap NE', 'Ice Hammer Block ES', 'Ice Right H Path',
|
||||
'Ice Bomb Drop Path', 'Ice Tongue Pull WS', 'Ice Freezors Bomb Hole', 'Ice Tall Hint WS',
|
||||
'Ice Hookshot Ledge Path', 'Ice Hookshot Balcony Path', 'Ice Many Pots SW', 'Ice Many Pots WS',
|
||||
'Ice Crystal Right Blue Hole', 'Ice Crystal Left Blue Barrier', 'Ice Big Chest Landing Push Blocks',
|
||||
'Ice Backwards Room Hole', 'Ice Switch Room SE', 'Ice Antechamber NE', 'Ice Antechamber Hole', 'Mire Lobby Gap',
|
||||
@@ -1963,13 +1996,16 @@ bunny_impassible_doors = {
|
||||
'GT Validation Block Path'
|
||||
}
|
||||
|
||||
|
||||
# these should generally match trap_door_exceptions unless the switch is in the open/push block
|
||||
bunny_impassible_if_trapped = {
|
||||
'Hyrule Dungeon Armory Interior Key Door N', 'Eastern Pot Switch WN', 'Eastern Lobby NW',
|
||||
'Eastern Lobby NE', 'Desert Compass Key Door WN', 'Tower Circle of Pots ES', 'PoD Mimics 2 SW',
|
||||
'PoD Middle Cage S', 'Swamp Push Statue S', 'Skull 2 East Lobby WS', 'Skull Torch Room WS',
|
||||
'Thieves Conveyor Maze WN', 'Thieves Conveyor Maze SW', 'Thieves Blocked Entry SW', 'Ice Bomb Jump NW',
|
||||
'Ice Tall Hint EN', 'Ice Switch Room ES', 'Ice Switch Room NE', 'Mire Cross SW',
|
||||
'Mire Tile Room SW', 'Mire Tile Room ES', 'TR Twin Pokeys NW', 'TR Torches WN', 'GT Hope Room WN',
|
||||
'Eastern Lobby NE', 'Eastern Courtyard Ledge S', 'Desert Compass Key Door WN', 'Tower Circle of Pots ES',
|
||||
'PoD Mimics 1 SW', 'PoD Mimics 2 SW', 'PoD Middle Cage S', 'PoD Lobby N', 'Swamp Push Statue S',
|
||||
'Skull 2 East Lobby WS', 'Skull Torch Room WS', 'Thieves Conveyor Maze WN', 'Thieves Conveyor Maze SW',
|
||||
'Thieves Blocked Entry SW', 'Ice Bomb Jump NW',
|
||||
'Ice Tall Hint EN', 'Ice Tall Hint SE', 'Ice Switch Room ES', 'Ice Switch Room NE', 'Mire Cross SW',
|
||||
'Mire Tile Room SW', 'Mire Tile Room ES', 'TR Tongue Pull WS', 'TR Twin Pokeys NW', 'TR Torches WN', 'GT Hope Room WN',
|
||||
'GT Speed Torch NE', 'GT Speed Torch WS', 'GT Torch Cross WN', 'GT Hidden Spikes SE', 'GT Conveyor Cross EN',
|
||||
'GT Speed Torch WN', 'Ice Lobby SE'
|
||||
}
|
||||
@@ -2001,6 +2037,9 @@ def add_key_logic_rules(world, player):
|
||||
forbid_item(location, d_logic.small_key_name, player)
|
||||
for door in d_logic.bk_doors:
|
||||
add_rule(world.get_entrance(door.name, player), create_rule(d_logic.bk_name, player))
|
||||
if door.dependents:
|
||||
for dep in door.dependents:
|
||||
add_rule(dep.entrance, create_rule(d_logic.bk_name, player))
|
||||
for chest in d_logic.bk_chests:
|
||||
big_chest = world.get_location(chest.name, player)
|
||||
add_rule(big_chest, create_rule(d_logic.bk_name, player))
|
||||
|
||||
Reference in New Issue
Block a user