Individual settings: mode
This commit is contained in:
parent
79786c7c9e
commit
ab28858a8f
|
@ -12,7 +12,7 @@ class World(object):
|
|||
self.players = players
|
||||
self.shuffle = shuffle
|
||||
self.logic = logic.copy()
|
||||
self.mode = mode
|
||||
self.mode = mode.copy()
|
||||
self.swords = swords
|
||||
self.difficulty = difficulty
|
||||
self.difficulty_adjustments = difficulty_adjustments
|
||||
|
@ -39,7 +39,7 @@ class World(object):
|
|||
self.powder_patch_required = {player: False for player in range(1, players + 1)}
|
||||
self.ganon_at_pyramid = {player: True for player in range(1, players + 1)}
|
||||
self.ganonstower_vanilla = {player: True for player in range(1, players + 1)}
|
||||
self.sewer_light_cone = mode == 'standard'
|
||||
self.sewer_light_cone = {player: mode[player] == 'standard' for player in range(1, players + 1)}
|
||||
self.light_world_light_cone = False
|
||||
self.dark_world_light_cone = False
|
||||
self.treasure_hunt_count = 0
|
||||
|
@ -48,7 +48,7 @@ class World(object):
|
|||
self.rupoor_cost = 10
|
||||
self.aga_randomness = True
|
||||
self.lock_aga_door_in_escape = False
|
||||
self.fix_trock_doors = self.shuffle != 'vanilla' or self.mode == 'inverted'
|
||||
self.fix_trock_doors = {player: self.shuffle != 'vanilla' or self.mode[player] == 'inverted' for player in range(1, players + 1)}
|
||||
self.save_and_quit_from_boss = True
|
||||
self.accessibility = accessibility
|
||||
self.fix_skullwoods_exit = self.shuffle not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']
|
||||
|
@ -74,7 +74,7 @@ class World(object):
|
|||
self.difficulty_requirements = None
|
||||
self.fix_fake_world = True
|
||||
self.boss_shuffle = boss_shuffle
|
||||
self.escape_assist = []
|
||||
self.escape_assist = {player: [] for player in range(1, players + 1)}
|
||||
self.hints = hints
|
||||
self.crystals_needed_for_ganon = 7
|
||||
self.crystals_needed_for_gt = 7
|
||||
|
@ -499,7 +499,7 @@ class CollectionState(object):
|
|||
if self.has_Pearl(player):
|
||||
return True
|
||||
|
||||
return region.is_light_world if self.world.mode != 'inverted' else region.is_dark_world
|
||||
return region.is_light_world if self.world.mode[player] != 'inverted' else region.is_dark_world
|
||||
|
||||
def can_reach_light_world(self, player):
|
||||
if True in [i.is_light_world for i in self.reachable_regions[player]]:
|
||||
|
@ -689,7 +689,7 @@ class Region(object):
|
|||
or (item.bigkey and not self.world.bigkeyshuffle)
|
||||
or (item.map and not self.world.mapshuffle)
|
||||
or (item.compass and not self.world.compassshuffle))
|
||||
sewer_hack = self.world.mode == 'standard' and item.name == 'Small Key (Escape)'
|
||||
sewer_hack = self.world.mode[item.player] == 'standard' and item.name == 'Small Key (Escape)'
|
||||
if sewer_hack or inside_dungeon_item:
|
||||
return self.dungeon and self.dungeon.is_dungeon_item(item) and item.player == self.player
|
||||
|
||||
|
@ -1025,7 +1025,7 @@ class Spoiler(object):
|
|||
self.bosses[str(player)]["Ice Palace"] = self.world.get_dungeon("Ice Palace", player).boss.name
|
||||
self.bosses[str(player)]["Misery Mire"] = self.world.get_dungeon("Misery Mire", player).boss.name
|
||||
self.bosses[str(player)]["Turtle Rock"] = self.world.get_dungeon("Turtle Rock", player).boss.name
|
||||
if self.world.mode != 'inverted':
|
||||
if self.world.mode[player] != 'inverted':
|
||||
self.bosses[str(player)]["Ganons Tower Basement"] = self.world.get_dungeon('Ganons Tower', player).bosses['bottom'].name
|
||||
self.bosses[str(player)]["Ganons Tower Middle"] = self.world.get_dungeon('Ganons Tower', player).bosses['middle'].name
|
||||
self.bosses[str(player)]["Ganons Tower Top"] = self.world.get_dungeon('Ganons Tower', player).bosses['top'].name
|
||||
|
|
|
@ -141,7 +141,7 @@ def place_bosses(world, player):
|
|||
if world.boss_shuffle == 'none':
|
||||
return
|
||||
# Most to least restrictive order
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
boss_locations = [
|
||||
['Ganons Tower', 'top'],
|
||||
['Tower of Hera', None],
|
||||
|
|
|
@ -27,7 +27,7 @@ def create_dungeons(world, player):
|
|||
MM = make_dungeon('Misery Mire', 'Vitreous', ['Misery Mire (Entrance)', 'Misery Mire (Main)', 'Misery Mire (West)', 'Misery Mire (Final Area)', 'Misery Mire (Vitreous)'], ItemFactory('Big Key (Misery Mire)', player), ItemFactory(['Small Key (Misery Mire)'] * 3, player), ItemFactory(['Map (Misery Mire)', 'Compass (Misery Mire)'], player))
|
||||
TR = make_dungeon('Turtle Rock', 'Trinexx', ['Turtle Rock (Entrance)', 'Turtle Rock (First Section)', 'Turtle Rock (Chain Chomp Room)', 'Turtle Rock (Second Section)', 'Turtle Rock (Big Chest)', 'Turtle Rock (Crystaroller Room)', 'Turtle Rock (Dark Room)', 'Turtle Rock (Eye Bridge)', 'Turtle Rock (Trinexx)'], ItemFactory('Big Key (Turtle Rock)', player), ItemFactory(['Small Key (Turtle Rock)'] * 4, player), ItemFactory(['Map (Turtle Rock)', 'Compass (Turtle Rock)'], player))
|
||||
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
AT = make_dungeon('Agahnims Tower', 'Agahnim', ['Agahnims Tower', 'Agahnim 1'], None, ItemFactory(['Small Key (Agahnims Tower)'] * 2, player), [])
|
||||
GT = make_dungeon('Ganons Tower', 'Agahnim2', ['Ganons Tower (Entrance)', 'Ganons Tower (Tile Room)', 'Ganons Tower (Compass Room)', 'Ganons Tower (Hookshot Room)', 'Ganons Tower (Map Room)', 'Ganons Tower (Firesnake Room)', 'Ganons Tower (Teleport Room)', 'Ganons Tower (Bottom)', 'Ganons Tower (Top)', 'Ganons Tower (Before Moldorm)', 'Ganons Tower (Moldorm)', 'Agahnim 2'], ItemFactory('Big Key (Ganons Tower)', player), ItemFactory(['Small Key (Ganons Tower)'] * 4, player), ItemFactory(['Map (Ganons Tower)', 'Compass (Ganons Tower)'], player))
|
||||
else:
|
||||
|
|
|
@ -286,6 +286,7 @@ def parse_arguments(argv, no_defaults=False):
|
|||
getattr(ret, name)[player] = value
|
||||
|
||||
set_player_arg("logic")
|
||||
set_player_arg("mode")
|
||||
|
||||
return ret
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ def link_entrances(world, player):
|
|||
lw_entrances = list(LW_Dungeon_Entrances)
|
||||
dw_entrances = list(DW_Dungeon_Entrances)
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# must connect front of hyrule castle to do escape
|
||||
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
else:
|
||||
|
@ -52,7 +52,7 @@ def link_entrances(world, player):
|
|||
dw_entrances.append('Ganons Tower')
|
||||
dungeon_exits.append('Ganons Tower Exit')
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# rest of hyrule castle must be in light world, so it has to be the one connected to east exit of desert
|
||||
connect_mandatory_exits(world, lw_entrances, [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], list(LW_Dungeon_Entrances_Must_Exit), player)
|
||||
else:
|
||||
|
@ -273,7 +273,7 @@ def link_entrances(world, player):
|
|||
# tavern back door cannot be shuffled yet
|
||||
connect_doors(world, ['Tavern North'], ['Tavern'], player)
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# must connect front of hyrule castle to do escape
|
||||
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
else:
|
||||
|
@ -309,7 +309,7 @@ def link_entrances(world, player):
|
|||
pass
|
||||
else: #if the cave wasn't placed we get here
|
||||
connect_caves(world, lw_entrances, [], old_man_house, player)
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# rest of hyrule castle must be in light world
|
||||
connect_caves(world, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player)
|
||||
|
||||
|
@ -376,7 +376,7 @@ def link_entrances(world, player):
|
|||
# tavern back door cannot be shuffled yet
|
||||
connect_doors(world, ['Tavern North'], ['Tavern'], player)
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# must connect front of hyrule castle to do escape
|
||||
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
else:
|
||||
|
@ -392,7 +392,7 @@ def link_entrances(world, player):
|
|||
#place must-exit caves
|
||||
connect_mandatory_exits(world, entrances, caves, must_exits, player)
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# rest of hyrule castle must be dealt with
|
||||
connect_caves(world, entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player)
|
||||
|
||||
|
@ -451,7 +451,7 @@ def link_entrances(world, player):
|
|||
blacksmith_doors = list(Blacksmith_Single_Cave_Doors)
|
||||
door_targets = list(Single_Cave_Targets)
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# must connect front of hyrule castle to do escape
|
||||
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
else:
|
||||
|
@ -471,7 +471,7 @@ def link_entrances(world, player):
|
|||
else:
|
||||
connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player)
|
||||
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player)
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# rest of hyrule castle must be in light world
|
||||
connect_caves(world, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player)
|
||||
|
||||
|
@ -552,7 +552,7 @@ def link_entrances(world, player):
|
|||
('Lumberjack Tree Exit', 'Lumberjack Tree (top)'),
|
||||
(('Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'), 'Skull Woods Second Section (Drop)')]
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# cannot move uncle cave
|
||||
connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player)
|
||||
connect_exit(world, 'Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance Stairs', player)
|
||||
|
@ -606,7 +606,7 @@ def link_entrances(world, player):
|
|||
connect_entrance(world, hole, target, player)
|
||||
|
||||
# hyrule castle handling
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# must connect front of hyrule castle to do escape
|
||||
connect_entrance(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
connect_exit(world, 'Hyrule Castle Exit (South)', 'Hyrule Castle Entrance (South)', player)
|
||||
|
@ -792,7 +792,7 @@ def link_entrances(world, player):
|
|||
# tavern back door cannot be shuffled yet
|
||||
connect_doors(world, ['Tavern North'], ['Tavern'], player)
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# cannot move uncle cave
|
||||
connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player)
|
||||
connect_exit(world, 'Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance Stairs', player)
|
||||
|
@ -825,7 +825,7 @@ def link_entrances(world, player):
|
|||
connect_entrance(world, hole, hole_targets.pop(), player)
|
||||
|
||||
# hyrule castle handling
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# must connect front of hyrule castle to do escape
|
||||
connect_entrance(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
connect_exit(world, 'Hyrule Castle Exit (South)', 'Hyrule Castle Entrance (South)', player)
|
||||
|
@ -927,7 +927,7 @@ def link_entrances(world, player):
|
|||
hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Woods Second Section (Drop)',
|
||||
'Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)']
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# cannot move uncle cave
|
||||
connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player)
|
||||
connect_exit(world, 'Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance Stairs', player)
|
||||
|
@ -960,7 +960,7 @@ def link_entrances(world, player):
|
|||
connect_entrance(world, hole, hole_targets.pop(), player)
|
||||
|
||||
# hyrule castle handling
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# must connect front of hyrule castle to do escape
|
||||
connect_entrance(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
connect_exit(world, 'Hyrule Castle Exit (South)', 'Hyrule Castle Entrance (South)', player)
|
||||
|
@ -1831,7 +1831,7 @@ def scramble_holes(world, player):
|
|||
else:
|
||||
hole_targets.append(('Pyramid Exit', 'Pyramid'))
|
||||
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
# cannot move uncle cave
|
||||
connect_two_way(world, 'Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', player)
|
||||
connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player)
|
||||
|
@ -1931,11 +1931,11 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player, dp_m
|
|||
if len(cave) == 2:
|
||||
entrance = entrances.pop()
|
||||
# ToDo Better solution, this is a hot fix. Do not connect both sides of trock/desert ledge only to each other
|
||||
if world.mode != 'inverted' and entrance == 'Dark Death Mountain Ledge (West)':
|
||||
if world.mode[player] != 'inverted' and entrance == 'Dark Death Mountain Ledge (West)':
|
||||
new_entrance = entrances.pop()
|
||||
entrances.append(entrance)
|
||||
entrance = new_entrance
|
||||
if world.mode == 'inverted' and entrance == dp_must_exit:
|
||||
if world.mode[player] == 'inverted' and entrance == dp_must_exit:
|
||||
new_entrance = entrances.pop()
|
||||
entrances.append(entrance)
|
||||
entrance = new_entrance
|
||||
|
@ -2006,7 +2006,7 @@ def simple_shuffle_dungeons(world, player):
|
|||
dungeon_entrances = ['Eastern Palace', 'Tower of Hera', 'Thieves Town', 'Skull Woods Final Section', 'Palace of Darkness', 'Ice Palace', 'Misery Mire', 'Swamp Palace']
|
||||
dungeon_exits = ['Eastern Palace Exit', 'Tower of Hera Exit', 'Thieves Town Exit', 'Skull Woods Final Section Exit', 'Palace of Darkness Exit', 'Ice Palace Exit', 'Misery Mire Exit', 'Swamp Palace Exit']
|
||||
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
if not world.shuffle_ganon:
|
||||
connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player)
|
||||
else:
|
||||
|
@ -2021,13 +2021,13 @@ def simple_shuffle_dungeons(world, player):
|
|||
|
||||
# mix up 4 door dungeons
|
||||
multi_dungeons = ['Desert', 'Turtle Rock']
|
||||
if world.mode == 'open' or (world.mode == 'inverted' and world.shuffle_ganon):
|
||||
if world.mode[player] == 'open' or (world.mode[player] == 'inverted' and world.shuffle_ganon):
|
||||
multi_dungeons.append('Hyrule Castle')
|
||||
random.shuffle(multi_dungeons)
|
||||
|
||||
dp_target = multi_dungeons[0]
|
||||
tr_target = multi_dungeons[1]
|
||||
if world.mode not in ['open', 'inverted'] or (world.mode == 'inverted' and world.shuffle_ganon is False):
|
||||
if world.mode[player] not in ['open', 'inverted'] or (world.mode[player] == 'inverted' and world.shuffle_ganon is False):
|
||||
# place hyrule castle as intended
|
||||
hc_target = 'Hyrule Castle'
|
||||
else:
|
||||
|
@ -2035,7 +2035,7 @@ def simple_shuffle_dungeons(world, player):
|
|||
|
||||
# ToDo improve this?
|
||||
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
if hc_target == 'Hyrule Castle':
|
||||
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
connect_two_way(world, 'Hyrule Castle Entrance (East)', 'Hyrule Castle Exit (East)', player)
|
||||
|
|
4
Fill.py
4
Fill.py
|
@ -239,8 +239,8 @@ def distribute_items_restrictive(world, gftower_trash_count=0, fill_locations=No
|
|||
fill_locations.reverse()
|
||||
|
||||
# Make sure the escape small key is placed first in standard with key shuffle to prevent running out of spots
|
||||
if world.keyshuffle and world.mode == 'standard':
|
||||
progitempool.sort(key=lambda item: 1 if item.name == 'Small Key (Escape)' else 0)
|
||||
if world.keyshuffle:
|
||||
progitempool.sort(key=lambda item: 1 if item.name == 'Small Key (Escape)' and world.mode[item.player] == 'standard' else 0)
|
||||
|
||||
fill_restrictive(world, world.state, fill_locations, progitempool)
|
||||
|
||||
|
|
|
@ -344,10 +344,10 @@ def _create_region(player, name, type, hint='Hyrule', locations=None, exits=None
|
|||
ret.locations.append(Location(player, location, address, crystal, hint_text, ret, player_address))
|
||||
return ret
|
||||
|
||||
def mark_dark_world_regions(world):
|
||||
def mark_dark_world_regions(world, player):
|
||||
# cross world caves may have some sections marked as both in_light_world, and in_dark_work.
|
||||
# That is ok. the bunny logic will check for this case and incorporate special rules.
|
||||
queue = collections.deque(region for region in world.regions if region.type == RegionType.DarkWorld)
|
||||
queue = collections.deque(region for region in world.get_regions(player) if region.type == RegionType.DarkWorld)
|
||||
seen = set(queue)
|
||||
while queue:
|
||||
current = queue.popleft()
|
||||
|
@ -360,7 +360,7 @@ def mark_dark_world_regions(world):
|
|||
seen.add(exit.connected_region)
|
||||
queue.append(exit.connected_region)
|
||||
|
||||
queue = collections.deque(region for region in world.regions if region.type == RegionType.LightWorld)
|
||||
queue = collections.deque(region for region in world.get_regions(player) if region.type == RegionType.LightWorld)
|
||||
seen = set(queue)
|
||||
while queue:
|
||||
current = queue.popleft()
|
||||
|
|
12
ItemList.py
12
ItemList.py
|
@ -126,7 +126,7 @@ difficulties = {
|
|||
|
||||
def generate_itempool(world, player):
|
||||
if (world.difficulty not in ['normal', 'hard', 'expert'] or world.goal not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals']
|
||||
or world.mode not in ['open', 'standard', 'inverted'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']):
|
||||
or world.mode[player] not in ['open', 'standard', 'inverted'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']):
|
||||
raise NotImplementedError('Not supported yet')
|
||||
|
||||
if world.timer in ['ohko', 'timed-ohko']:
|
||||
|
@ -138,7 +138,7 @@ def generate_itempool(world, player):
|
|||
world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False)
|
||||
|
||||
if world.goal in ['triforcehunt']:
|
||||
if world.mode == 'inverted':
|
||||
if world.mode[player] == 'inverted':
|
||||
region = world.get_region('Light World',player)
|
||||
else:
|
||||
region = world.get_region('Hyrule Castle Courtyard', player)
|
||||
|
@ -177,15 +177,15 @@ def generate_itempool(world, player):
|
|||
|
||||
# set up item pool
|
||||
if world.custom:
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode, world.swords, world.retro, world.customitemarray)
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode[player], world.swords, world.retro, world.customitemarray)
|
||||
world.rupoor_cost = min(world.customitemarray[69], 9999)
|
||||
else:
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode, world.swords, world.retro)
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode[player], world.swords, world.retro)
|
||||
|
||||
for item in precollected_items:
|
||||
world.push_precollected(ItemFactory(item, player))
|
||||
|
||||
if world.mode == 'standard' and not world.state.has_blunt_weapon(player) and "Link's Uncle" not in placed_items:
|
||||
if world.mode[player] == 'standard' and not world.state.has_blunt_weapon(player) and "Link's Uncle" not in placed_items:
|
||||
found_sword = False
|
||||
found_bow = False
|
||||
possible_weapons = []
|
||||
|
@ -261,7 +261,7 @@ take_any_locations = [
|
|||
'Dark Lake Hylia Ledge Spike Cave', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Dark Desert Hint']
|
||||
|
||||
def set_up_take_anys(world, player):
|
||||
if world.mode == 'inverted' and 'Dark Sanctuary Hint' in take_any_locations:
|
||||
if world.mode[player] == 'inverted' and 'Dark Sanctuary Hint' in take_any_locations:
|
||||
take_any_locations.remove('Dark Sanctuary Hint')
|
||||
|
||||
regions = random.sample(take_any_locations, 5)
|
||||
|
|
44
Main.py
44
Main.py
|
@ -56,30 +56,26 @@ def main(args, seed=None):
|
|||
logger.info('ALttP Entrance Randomizer Version %s - Seed: %s\n\n', __version__, world.seed)
|
||||
|
||||
world.difficulty_requirements = difficulties[world.difficulty]
|
||||
if world.mode == 'standard' and (args.shuffleenemies != 'none' or args.enemy_health not in ['default', 'easy']):
|
||||
world.escape_assist.append(['bombs']) # enemized escape assumes infinite bombs available and will likely be unbeatable without it
|
||||
|
||||
if world.mode != 'inverted':
|
||||
for player in range(1, world.players + 1):
|
||||
for player in range(1, world.players + 1):
|
||||
if world.mode[player] == 'standard' and (args.shuffleenemies != 'none' or args.enemy_health not in ['default', 'easy']):
|
||||
world.escape_assist[player].append(['bombs']) # enemized escape assumes infinite bombs available and will likely be unbeatable without it
|
||||
|
||||
if world.mode[player] != 'inverted':
|
||||
create_regions(world, player)
|
||||
create_dungeons(world, player)
|
||||
else:
|
||||
for player in range(1, world.players + 1):
|
||||
else:
|
||||
create_inverted_regions(world, player)
|
||||
create_dungeons(world, player)
|
||||
create_dungeons(world, player)
|
||||
|
||||
logger.info('Shuffling the World about.')
|
||||
|
||||
if world.mode != 'inverted':
|
||||
for player in range(1, world.players + 1):
|
||||
for player in range(1, world.players + 1):
|
||||
if world.mode[player] != 'inverted':
|
||||
link_entrances(world, player)
|
||||
|
||||
mark_light_world_regions(world)
|
||||
else:
|
||||
for player in range(1, world.players + 1):
|
||||
mark_light_world_regions(world, player)
|
||||
else:
|
||||
link_inverted_entrances(world, player)
|
||||
|
||||
mark_dark_world_regions(world)
|
||||
mark_dark_world_regions(world, player)
|
||||
|
||||
logger.info('Generating Item Pool.')
|
||||
|
||||
|
@ -189,7 +185,7 @@ def main(args, seed=None):
|
|||
outfilesuffix = ('%s%s_%s_%s-%s-%s-%s%s_%s-%s%s%s%s%s' % (f'_P{player}' if world.players > 1 else '',
|
||||
f'_{player_names[player]}' if player in player_names else '',
|
||||
world.logic[player], world.difficulty, world.difficulty_adjustments,
|
||||
world.mode, world.goal,
|
||||
world.mode[player], world.goal,
|
||||
"" if world.timer in ['none', 'display'] else "-" + world.timer,
|
||||
world.shuffle, world.algorithm, mcsb_name,
|
||||
"-retro" if world.retro else "",
|
||||
|
@ -232,7 +228,7 @@ def copy_world(world):
|
|||
ret.ganonstower_vanilla = world.ganonstower_vanilla.copy()
|
||||
ret.treasure_hunt_count = world.treasure_hunt_count
|
||||
ret.treasure_hunt_icon = world.treasure_hunt_icon
|
||||
ret.sewer_light_cone = world.sewer_light_cone
|
||||
ret.sewer_light_cone = world.sewer_light_cone.copy()
|
||||
ret.light_world_light_cone = world.light_world_light_cone
|
||||
ret.dark_world_light_cone = world.dark_world_light_cone
|
||||
ret.seed = world.seed
|
||||
|
@ -251,14 +247,12 @@ def copy_world(world):
|
|||
ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon
|
||||
ret.crystals_needed_for_gt = world.crystals_needed_for_gt
|
||||
|
||||
if world.mode != 'inverted':
|
||||
for player in range(1, world.players + 1):
|
||||
for player in range(1, world.players + 1):
|
||||
if world.mode[player] != 'inverted':
|
||||
create_regions(ret, player)
|
||||
create_dungeons(ret, player)
|
||||
else:
|
||||
for player in range(1, world.players + 1):
|
||||
else:
|
||||
create_inverted_regions(ret, player)
|
||||
create_dungeons(ret, player)
|
||||
create_dungeons(ret, player)
|
||||
|
||||
copy_dynamic_regions_and_locations(world, ret)
|
||||
|
||||
|
@ -436,7 +430,7 @@ def create_playthrough(world):
|
|||
old_world.spoiler.paths.update({ str(location) : get_path(state, location.parent_region) for sphere in collection_spheres for location in sphere if location.player == player})
|
||||
for _, path in dict(old_world.spoiler.paths).items():
|
||||
if any(exit == 'Pyramid Fairy' for (_, exit) in path):
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
old_world.spoiler.paths[str(world.get_region('Big Bomb Shop', player))] = get_path(state, world.get_region('Big Bomb Shop', player))
|
||||
else:
|
||||
old_world.spoiler.paths[str(world.get_region('Inverted Big Bomb Shop', player))] = get_path(state, world.get_region('Inverted Big Bomb Shop', player))
|
||||
|
|
|
@ -116,7 +116,7 @@ def fill_world(world, plando, text_patches):
|
|||
tr_medallion = medallionstr.strip()
|
||||
elif line.startswith('!mode'):
|
||||
_, modestr = line.split(':', 1)
|
||||
world.mode = modestr.strip()
|
||||
world.mode = {1: modestr.strip()}
|
||||
elif line.startswith('!logic'):
|
||||
_, logicstr = line.split(':', 1)
|
||||
world.logic = {1: logicstr.strip()}
|
||||
|
@ -125,7 +125,7 @@ def fill_world(world, plando, text_patches):
|
|||
world.goal = goalstr.strip()
|
||||
elif line.startswith('!light_cone_sewers'):
|
||||
_, sewerstr = line.split(':', 1)
|
||||
world.sewer_light_cone = sewerstr.strip().lower() == 'true'
|
||||
world.sewer_light_cone = {1: sewerstr.strip().lower() == 'true'}
|
||||
elif line.startswith('!light_cone_lw'):
|
||||
_, lwconestr = line.split(':', 1)
|
||||
world.light_world_light_cone = lwconestr.strip().lower() == 'true'
|
||||
|
@ -134,7 +134,7 @@ def fill_world(world, plando, text_patches):
|
|||
world.dark_world_light_cone = dwconestr.strip().lower() == 'true'
|
||||
elif line.startswith('!fix_trock_doors'):
|
||||
_, trdstr = line.split(':', 1)
|
||||
world.fix_trock_doors = trdstr.strip().lower() == 'true'
|
||||
world.fix_trock_doors = {1: trdstr.strip().lower() == 'true'}
|
||||
elif line.startswith('!fix_trock_exit'):
|
||||
_, trfstr = line.split(':', 1)
|
||||
world.fix_trock_exit = trfstr.strip().lower() == 'true'
|
||||
|
|
|
@ -335,10 +335,10 @@ def _create_region(player, name, type, hint='Hyrule', locations=None, exits=None
|
|||
ret.locations.append(Location(player, location, address, crystal, hint_text, ret, player_address))
|
||||
return ret
|
||||
|
||||
def mark_light_world_regions(world):
|
||||
def mark_light_world_regions(world, player):
|
||||
# cross world caves may have some sections marked as both in_light_world, and in_dark_work.
|
||||
# That is ok. the bunny logic will check for this case and incorporate special rules.
|
||||
queue = collections.deque(region for region in world.regions if region.type == RegionType.LightWorld)
|
||||
queue = collections.deque(region for region in world.get_regions(player) if region.type == RegionType.LightWorld)
|
||||
seen = set(queue)
|
||||
while queue:
|
||||
current = queue.popleft()
|
||||
|
@ -351,7 +351,7 @@ def mark_light_world_regions(world):
|
|||
seen.add(exit.connected_region)
|
||||
queue.append(exit.connected_region)
|
||||
|
||||
queue = collections.deque(region for region in world.regions if region.type == RegionType.DarkWorld)
|
||||
queue = collections.deque(region for region in world.get_regions(player) if region.type == RegionType.DarkWorld)
|
||||
seen = set(queue)
|
||||
while queue:
|
||||
current = queue.popleft()
|
||||
|
|
44
Rom.py
44
Rom.py
|
@ -248,7 +248,7 @@ def get_enemizer_patch(world, player, rom, baserom_path, enemizercli, shuffleene
|
|||
}
|
||||
}
|
||||
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
options['ManualBosses']['GanonsTower1'] = world.get_dungeon('Ganons Tower', player).bosses['bottom'].enemizer_name
|
||||
options['ManualBosses']['GanonsTower2'] = world.get_dungeon('Ganons Tower', player).bosses['middle'].enemizer_name
|
||||
options['ManualBosses']['GanonsTower3'] = world.get_dungeon('Ganons Tower', player).bosses['top'].enemizer_name
|
||||
|
@ -550,7 +550,7 @@ def patch_rom(world, player, rom, enemized):
|
|||
else:
|
||||
# patch door table
|
||||
rom.write_byte(0xDBB73 + exit.addresses, exit.target)
|
||||
if world.mode == 'inverted':
|
||||
if world.mode[player] == 'inverted':
|
||||
patch_shuffled_dark_sanc(world, rom, player)
|
||||
|
||||
write_custom_shops(rom, world, player)
|
||||
|
@ -578,11 +578,11 @@ def patch_rom(world, player, rom, enemized):
|
|||
rom.write_byte(0x51DE, 0x00)
|
||||
|
||||
# set open mode:
|
||||
if world.mode in ['open', 'inverted']:
|
||||
if world.mode[player] in ['open', 'inverted']:
|
||||
rom.write_byte(0x180032, 0x01) # open mode
|
||||
if world.mode == 'inverted':
|
||||
if world.mode[player] == 'inverted':
|
||||
set_inverted_mode(world, rom)
|
||||
elif world.mode == 'standard':
|
||||
elif world.mode[player] == 'standard':
|
||||
rom.write_byte(0x180032, 0x00) # standard mode
|
||||
|
||||
uncle_location = world.get_location('Link\'s Uncle', player)
|
||||
|
@ -600,7 +600,7 @@ def patch_rom(world, player, rom, enemized):
|
|||
rom.write_bytes(0x6D323, [0x00, 0x00, 0xe4, 0xff, 0x08, 0x0E])
|
||||
|
||||
# set light cones
|
||||
rom.write_byte(0x180038, 0x01 if world.sewer_light_cone else 0x00)
|
||||
rom.write_byte(0x180038, 0x01 if world.sewer_light_cone[player] else 0x00)
|
||||
rom.write_byte(0x180039, 0x01 if world.light_world_light_cone else 0x00)
|
||||
rom.write_byte(0x18003A, 0x01 if world.dark_world_light_cone else 0x00)
|
||||
|
||||
|
@ -892,7 +892,7 @@ def patch_rom(world, player, rom, enemized):
|
|||
# assorted fixes
|
||||
rom.write_byte(0x1800A2, 0x01) # remain in real dark world when dying in dark world dungeon before killing aga1
|
||||
rom.write_byte(0x180169, 0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence.
|
||||
if world.mode == 'inverted':
|
||||
if world.mode[player] == 'inverted':
|
||||
rom.write_byte(0x180169, 0x02) # lock aga/ganon tower door with crystals in inverted
|
||||
rom.write_byte(0x180171, 0x01 if world.ganon_at_pyramid[player] else 0x00) # Enable respawning on pyramid after ganon death
|
||||
rom.write_byte(0x180173, 0x01) # Bob is enabled
|
||||
|
@ -930,18 +930,18 @@ def patch_rom(world, player, rom, enemized):
|
|||
else:
|
||||
raise RuntimeError("Unsupported pre-collected item: {}".format(item))
|
||||
|
||||
rom.write_byte(0x18004A, 0x00 if world.mode != 'inverted' else 0x01) # Inverted mode
|
||||
rom.write_byte(0x18004A, 0x00 if world.mode[player] != 'inverted' else 0x01) # Inverted mode
|
||||
rom.write_byte(0x18005D, 0x00) # Hammer always breaks barrier
|
||||
rom.write_byte(0x2AF79, 0xD0 if world.mode != 'inverted' else 0xF0) # vortexes: Normal (D0=light to dark, F0=dark to light, 42 = both)
|
||||
rom.write_byte(0x3A943, 0xD0 if world.mode != 'inverted' else 0xF0) # Mirror: Normal (D0=Dark to Light, F0=light to dark, 42 = both)
|
||||
rom.write_byte(0x3A96D, 0xF0 if world.mode != 'inverted' else 0xD0) # Residual Portal: Normal (F0= Light Side, D0=Dark Side, 42 = both (Darth Vader))
|
||||
rom.write_byte(0x2AF79, 0xD0 if world.mode[player] != 'inverted' else 0xF0) # vortexes: Normal (D0=light to dark, F0=dark to light, 42 = both)
|
||||
rom.write_byte(0x3A943, 0xD0 if world.mode[player] != 'inverted' else 0xF0) # Mirror: Normal (D0=Dark to Light, F0=light to dark, 42 = both)
|
||||
rom.write_byte(0x3A96D, 0xF0 if world.mode[player] != 'inverted' else 0xD0) # Residual Portal: Normal (F0= Light Side, D0=Dark Side, 42 = both (Darth Vader))
|
||||
rom.write_byte(0x3A9A7, 0xD0) # Residual Portal: Normal (D0= Light Side, F0=Dark Side, 42 = both (Darth Vader))
|
||||
|
||||
rom.write_bytes(0x180080, [50, 50, 70, 70]) # values to fill for Capacity Upgrades (Bomb5, Bomb10, Arrow5, Arrow10)
|
||||
|
||||
rom.write_byte(0x18004D, ((0x01 if 'arrows' in world.escape_assist else 0x00) |
|
||||
(0x02 if 'bombs' in world.escape_assist else 0x00) |
|
||||
(0x04 if 'magic' in world.escape_assist else 0x00))) # Escape assist
|
||||
rom.write_byte(0x18004D, ((0x01 if 'arrows' in world.escape_assist[player] else 0x00) |
|
||||
(0x02 if 'bombs' in world.escape_assist[player] else 0x00) |
|
||||
(0x04 if 'magic' in world.escape_assist[player] else 0x00))) # Escape assist
|
||||
|
||||
if world.goal in ['pedestal', 'triforcehunt']:
|
||||
rom.write_byte(0x18003E, 0x01) # make ganon invincible
|
||||
|
@ -954,7 +954,7 @@ def patch_rom(world, player, rom, enemized):
|
|||
|
||||
rom.write_byte(0x18005E, world.crystals_needed_for_gt)
|
||||
rom.write_byte(0x18005F, world.crystals_needed_for_ganon)
|
||||
rom.write_byte(0x18008A, 0x01 if world.mode == "standard" else 0x00) # block HC upstairs doors in rain state in standard mode
|
||||
rom.write_byte(0x18008A, 0x01 if world.mode[player] == "standard" else 0x00) # block HC upstairs doors in rain state in standard mode
|
||||
|
||||
rom.write_byte(0x18016A, 0x10 | ((0x01 if world.keyshuffle else 0x00)
|
||||
| (0x02 if world.compassshuffle else 0x00)
|
||||
|
@ -1031,7 +1031,7 @@ def patch_rom(world, player, rom, enemized):
|
|||
rom.write_bytes(0x180185, [0,0,0]) # Uncle respawn refills (magic, bombs, arrows)
|
||||
rom.write_bytes(0x180188, [0,0,0]) # Zelda respawn refills (magic, bombs, arrows)
|
||||
rom.write_bytes(0x18018B, [0,0,0]) # Mantle respawn refills (magic, bombs, arrows)
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
if uncle_location.item is not None and uncle_location.item.name in ['Bow', 'Progressive Bow']:
|
||||
rom.write_byte(0x18004E, 1) # Escape Fill (arrows)
|
||||
write_int16(rom, 0x180183, 300) # Escape fill rupee bow
|
||||
|
@ -1068,7 +1068,7 @@ def patch_rom(world, player, rom, enemized):
|
|||
rom.write_byte(0x4E3BB, 0xEB)
|
||||
|
||||
# fix trock doors for reverse entrances
|
||||
if world.fix_trock_doors:
|
||||
if world.fix_trock_doors[player]:
|
||||
rom.write_byte(0xFED31, 0x0E) # preopen bombable exit
|
||||
rom.write_byte(0xFEE41, 0x0E) # preopen bombable exit
|
||||
# included unconditionally in base2current
|
||||
|
@ -1375,7 +1375,7 @@ def write_strings(rom, world, player):
|
|||
entrances_to_hint = {}
|
||||
entrances_to_hint.update(InconvenientDungeonEntrances)
|
||||
if world.shuffle_ganon:
|
||||
if world.mode == 'inverted':
|
||||
if world.mode[player] == 'inverted':
|
||||
entrances_to_hint.update({'Inverted Ganons Tower': 'The sealed castle door'})
|
||||
else:
|
||||
entrances_to_hint.update({'Ganons Tower': 'Ganon\'s Tower'})
|
||||
|
@ -1408,14 +1408,14 @@ def write_strings(rom, world, player):
|
|||
if world.shuffle not in ['simple', 'restricted', 'restricted_legacy']:
|
||||
entrances_to_hint.update(ConnectorEntrances)
|
||||
entrances_to_hint.update(DungeonEntrances)
|
||||
if world.mode == 'inverted':
|
||||
if world.mode[player] == 'inverted':
|
||||
entrances_to_hint.update({'Inverted Agahnims Tower': 'The dark mountain tower'})
|
||||
else:
|
||||
entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'})
|
||||
elif world.shuffle == 'restricted':
|
||||
entrances_to_hint.update(ConnectorEntrances)
|
||||
entrances_to_hint.update(OtherEntrances)
|
||||
if world.mode == 'inverted':
|
||||
if world.mode[player] == 'inverted':
|
||||
entrances_to_hint.update({'Inverted Dark Sanctuary': 'The dark sanctuary cave'})
|
||||
entrances_to_hint.update({'Inverted Big Bomb Shop': 'The old hero\'s dark home'})
|
||||
entrances_to_hint.update({'Inverted Links House': 'The old hero\'s light home'})
|
||||
|
@ -1425,7 +1425,7 @@ def write_strings(rom, world, player):
|
|||
if world.shuffle in ['insanity', 'madness_legacy', 'insanity_legacy']:
|
||||
entrances_to_hint.update(InsanityEntrances)
|
||||
if world.shuffle_ganon:
|
||||
if world.mode == 'inverted':
|
||||
if world.mode[player] == 'inverted':
|
||||
entrances_to_hint.update({'Inverted Pyramid Entrance': 'The extra castle passage'})
|
||||
else:
|
||||
entrances_to_hint.update({'Pyramid Ledge': 'The pyramid ledge'})
|
||||
|
@ -1592,7 +1592,7 @@ def write_strings(rom, world, player):
|
|||
tt['tablet_bombos_book'] = bombos_text
|
||||
|
||||
# inverted spawn menu changes
|
||||
if world.mode == 'inverted':
|
||||
if world.mode[player] == 'inverted':
|
||||
tt['menu_start_2'] = "{MENU}\n{SPEED0}\n≥@'s house\n Dark Chapel\n{CHOICE3}"
|
||||
tt['menu_start_3'] = "{MENU}\n{SPEED0}\n≥@'s house\n Dark Chapel\n Mountain Cave\n{CHOICE2}"
|
||||
tt['intro_main'] = CompressedTextMapper.convert(
|
||||
|
|
24
Rules.py
24
Rules.py
|
@ -7,7 +7,7 @@ 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!')
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
world.get_region('Links House', player).can_reach_private = lambda state: True
|
||||
world.get_region('Sanctuary', player).can_reach_private = lambda state: True
|
||||
old_rule = world.get_region('Old Man House', player).can_reach
|
||||
|
@ -22,14 +22,14 @@ def set_rules(world, player):
|
|||
return
|
||||
|
||||
global_rules(world, player)
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
default_rules(world, player)
|
||||
|
||||
if world.mode == 'open':
|
||||
if world.mode[player] == 'open':
|
||||
open_rules(world, player)
|
||||
elif world.mode == 'standard':
|
||||
elif world.mode[player] == 'standard':
|
||||
standard_rules(world, player)
|
||||
elif world.mode == 'inverted':
|
||||
elif world.mode[player] == 'inverted':
|
||||
open_rules(world, player)
|
||||
inverted_rules(world, player)
|
||||
else:
|
||||
|
@ -49,7 +49,7 @@ def set_rules(world, player):
|
|||
# require aga2 to beat ganon
|
||||
add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player))
|
||||
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
set_big_bomb_rules(world, player)
|
||||
else:
|
||||
set_inverted_big_bomb_rules(world, player)
|
||||
|
@ -58,7 +58,7 @@ def set_rules(world, player):
|
|||
if not world.swamp_patch_required[player]:
|
||||
add_rule(world.get_entrance('Swamp Palace Moat', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
set_bunny_rules(world, player)
|
||||
else:
|
||||
set_inverted_bunny_rules(world, player)
|
||||
|
@ -345,7 +345,7 @@ def global_rules(world, player):
|
|||
|
||||
|
||||
def default_rules(world, player):
|
||||
if world.mode == 'standard':
|
||||
if world.mode[player] == 'standard':
|
||||
world.get_region('Hyrule Castle Secret Entrance', player).can_reach_private = lambda state: True
|
||||
old_rule = world.get_region('Links House', player).can_reach_private
|
||||
world.get_region('Links House', player).can_reach_private = lambda state: state.can_reach('Sanctuary', 'Region', player) or old_rule(state)
|
||||
|
@ -621,7 +621,7 @@ def inverted_rules(world, player):
|
|||
set_rule(world.get_entrance('Inverted Ganons Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt, player))
|
||||
|
||||
def no_glitches_rules(world, player):
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
set_rule(world.get_entrance('Zoras River', player), lambda state: state.has('Flippers', player) or state.can_lift_rocks(player))
|
||||
set_rule(world.get_entrance('Lake Hylia Central Island Pier', player), lambda state: state.has('Flippers', player)) # can be fake flippered to
|
||||
set_rule(world.get_entrance('Hobo Bridge', player), lambda state: state.has('Flippers', player))
|
||||
|
@ -672,7 +672,7 @@ def no_glitches_rules(world, player):
|
|||
add_conditional_lamp('Palace of Darkness Maze Door', 'Palace of Darkness (Entrance)', 'Entrance')
|
||||
add_conditional_lamp('Palace of Darkness - Dark Basement - Left', 'Palace of Darkness (Entrance)', 'Location')
|
||||
add_conditional_lamp('Palace of Darkness - Dark Basement - Right', 'Palace of Darkness (Entrance)', 'Location')
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
add_conditional_lamp('Agahnim 1', 'Agahnims Tower', 'Entrance')
|
||||
add_conditional_lamp('Castle Tower - Dark Maze', 'Agahnims Tower', 'Location')
|
||||
else:
|
||||
|
@ -688,7 +688,7 @@ def no_glitches_rules(world, player):
|
|||
add_conditional_lamp('Eastern Palace - Boss', 'Eastern Palace', 'Location')
|
||||
add_conditional_lamp('Eastern Palace - Prize', 'Eastern Palace', 'Location')
|
||||
|
||||
if not world.sewer_light_cone:
|
||||
if not world.sewer_light_cone[player]:
|
||||
add_lamp_requirement(world.get_location('Sewers - Dark Cross', player), player)
|
||||
add_lamp_requirement(world.get_entrance('Sewers Back Door', player), player)
|
||||
add_lamp_requirement(world.get_entrance('Throne Room', player), player)
|
||||
|
@ -709,7 +709,7 @@ def swordless_rules(world, 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))
|
||||
set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has('Hammer', player)) # need to damage ganon to get tiles to drop
|
||||
|
||||
if world.mode != 'inverted':
|
||||
if world.mode[player] != 'inverted':
|
||||
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has('Hammer', player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle
|
||||
set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_Pearl(player) and state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword not required to use medallion for opening in swordless (!)
|
||||
set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_Pearl(player) and state.has_misery_mire_medallion(player)) # sword not required to use medallion for opening in swordless (!)
|
||||
|
|
Loading…
Reference in New Issue