Merge branch 'OverworldShuffleDev' into OverworldShuffle
This commit is contained in:
@@ -299,6 +299,9 @@ class World(object):
|
||||
return edge
|
||||
return None
|
||||
|
||||
def is_tile_swapped(self, owid, player):
|
||||
return (self.mode[player] == 'inverted') != (owid in self.owswaps[player][0] and self.owMixed[player])
|
||||
|
||||
def check_for_door(self, doorname, player):
|
||||
if isinstance(doorname, Door):
|
||||
return doorname
|
||||
@@ -2831,6 +2834,12 @@ class Spoiler(object):
|
||||
'triforcepool': self.world.treasure_hunt_total,
|
||||
'code': {p: Settings.make_code(self.world, p) for p in range(1, self.world.players + 1)}
|
||||
}
|
||||
for p in range(1, self.world.players + 1):
|
||||
from ItemList import set_default_triforce
|
||||
if self.world.custom and p in self.world.customitemarray:
|
||||
self.metadata['triforcegoal'][p], self.metadata['triforcepool'][p] = set_default_triforce(self.metadata['goal'][p], self.world.customitemarray[p]["triforcepiecesgoal"], self.world.customitemarray[p]["triforcepieces"])
|
||||
else:
|
||||
self.metadata['triforcegoal'][p], self.metadata['triforcepool'][p] = set_default_triforce(self.metadata['goal'][p], 0, 0)
|
||||
|
||||
def parse_data(self):
|
||||
self.medallions = OrderedDict()
|
||||
@@ -2965,7 +2974,7 @@ class Spoiler(object):
|
||||
outfile.write('Retro:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['retro'][player] else 'No'))
|
||||
outfile.write('Swords:'.ljust(line_width) + '%s\n' % self.metadata['weapons'][player])
|
||||
outfile.write('Goal:'.ljust(line_width) + '%s\n' % self.metadata['goal'][player])
|
||||
if self.metadata['goal'][player] == 'triforcehunt':
|
||||
if self.metadata['goal'][player] in ['triforcehunt', 'trinity']:
|
||||
outfile.write('Triforce Pieces Required:'.ljust(line_width) + '%s\n' % self.metadata['triforcegoal'][player])
|
||||
outfile.write('Triforce Pieces Total:'.ljust(line_width) + '%s\n' % self.metadata['triforcepool'][player])
|
||||
outfile.write('Crystals Required for GT:'.ljust(line_width) + '%s\n' % str(self.world.crystals_gt_orig[player]))
|
||||
@@ -2986,6 +2995,7 @@ class Spoiler(object):
|
||||
if self.metadata['shuffle'][player] != 'vanilla':
|
||||
outfile.write('Shuffle GT/Ganon:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['shuffleganon'][player] else 'No'))
|
||||
outfile.write('Shuffle Links:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['shufflelinks'][player] else 'No'))
|
||||
if self.metadata['goal'][player] != 'trinity':
|
||||
outfile.write('Pyramid Hole Pre-opened:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No'))
|
||||
outfile.write('Door Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['door_shuffle'][player])
|
||||
if self.metadata['door_shuffle'][player] != 'vanilla':
|
||||
@@ -3212,7 +3222,7 @@ world_mode = {"open": 0, "standard": 1, "inverted": 2}
|
||||
sword_mode = {"random": 0, "assured": 1, "swordless": 2, "vanilla": 3}
|
||||
|
||||
# byte 2: GGGD DFFH (goal, diff, item_func, hints)
|
||||
goal_mode = {"ganon": 0, "pedestal": 1, "dungeons": 2, "triforcehunt": 3, "crystals": 4}
|
||||
goal_mode = {"ganon": 0, "pedestal": 1, "dungeons": 2, "triforcehunt": 3, "crystals": 4, "trinity": 5}
|
||||
diff_mode = {"normal": 0, "hard": 1, "expert": 2}
|
||||
func_mode = {"normal": 0, "hard": 1, "expert": 2}
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
### 0.2.3.6
|
||||
- Added Trinity goal (8/10 default TF pieces)
|
||||
- Many improvements to TFH pool allocation
|
||||
- Fixed some issues with Multiworld generation with Custom Item Pools
|
||||
|
||||
### 0.2.3.5
|
||||
- Fixed issue with multiworld generation
|
||||
- Added infinite loop detection
|
||||
|
||||
@@ -89,11 +89,11 @@ def link_doors_main(world, player):
|
||||
if world.mode[player] == 'standard':
|
||||
world.get_portal('Sanctuary', player).destination = True
|
||||
world.get_portal('Desert East', player).destination = True
|
||||
if (world.mode[player] == 'inverted') != (0x30 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x30, player):
|
||||
world.get_portal('Desert West', player).destination = True
|
||||
if (world.mode[player] == 'inverted') == (0x00 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x00, player):
|
||||
world.get_portal('Skull 2 West', player).destination = True
|
||||
if (world.mode[player] == 'inverted') == (0x05 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x05, player):
|
||||
world.get_portal('Turtle Rock Lazy Eyes', player).destination = True
|
||||
world.get_portal('Turtle Rock Eye Bridge', player).destination = True
|
||||
else:
|
||||
@@ -1837,7 +1837,7 @@ def find_inaccessible_regions(world, player):
|
||||
if connect.type is not RegionType.Dungeon or connect.name.endswith(' Portal'):
|
||||
queue.append(connect)
|
||||
world.inaccessible_regions[player].extend([r.name for r in all_regions if r not in visited_regions and valid_inaccessible_region(r)])
|
||||
if (world.mode[player] == 'inverted') != (0x1b in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x1b, player):
|
||||
ledge = world.get_region('Hyrule Castle Ledge', player)
|
||||
if any(x for x in ledge.exits if x.connected_region and x.connected_region.name == 'Agahnims Tower Portal'):
|
||||
world.inaccessible_regions[player].append('Hyrule Castle Ledge')
|
||||
@@ -1857,7 +1857,7 @@ def find_accessible_entrances(world, player, builder):
|
||||
start_regions = ['Links House', 'Sanctuary']
|
||||
else:
|
||||
start_regions = ['Links House', 'Dark Sanctuary Hint']
|
||||
if (world.mode[player] == 'inverted') != (0x1b in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x1b, player):
|
||||
start_regions.append('Hyrule Castle Ledge')
|
||||
regs = convert_regions(start_regions, world, player)
|
||||
visited_regions = set()
|
||||
@@ -1873,7 +1873,7 @@ def find_accessible_entrances(world, player, builder):
|
||||
while len(queue) > 0:
|
||||
next_region = queue.popleft()
|
||||
visited_regions.add(next_region)
|
||||
if (world.mode[player] == 'inverted') != (0x1b in world.owswaps[player][0] and world.owMixed[player]) and next_region.name == 'Tower Agahnim 1':
|
||||
if world.is_tile_swapped(0x1b, player) and next_region.name == 'Tower Agahnim 1':
|
||||
connect = world.get_region('Hyrule Castle Ledge', player)
|
||||
if connect not in queue and connect not in visited_regions:
|
||||
queue.append(connect)
|
||||
|
||||
@@ -34,7 +34,7 @@ def link_entrances(world, player):
|
||||
world.owsectors[player] = build_sectors(world, player)
|
||||
|
||||
# modifications to lists
|
||||
if invFlag == (0x1b in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x1b, player):
|
||||
drop_connections.append(tuple(('Pyramid Hole', 'Pyramid')))
|
||||
dropexit_connections.append(tuple(('Pyramid Entrance', 'Pyramid Exit')))
|
||||
connect_simple(world, 'Other World S&Q', 'Pyramid Area', player)
|
||||
@@ -47,7 +47,7 @@ def link_entrances(world, player):
|
||||
dropexit_connections.append(tuple(('Inverted Pyramid Entrance', 'Pyramid Exit')))
|
||||
connect_simple(world, 'Other World S&Q', 'Hyrule Castle Ledge', player)
|
||||
|
||||
if invFlag == (0x03 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x03, player):
|
||||
connect_simple(world, 'Old Man S&Q', 'Old Man House', player)
|
||||
else:
|
||||
connect_simple(world, 'Old Man S&Q', 'West Dark Death Mountain (Bottom)', player)
|
||||
@@ -89,18 +89,16 @@ def link_entrances(world, player):
|
||||
# inverted entrance mods
|
||||
ignore_pool = True
|
||||
for owid in swapped_connections.keys():
|
||||
if invFlag != (owid in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(owid, player):
|
||||
for (entrancename, exitname) in swapped_connections[owid]:
|
||||
try:
|
||||
connect_two_way(world, entrancename, exitname, player)
|
||||
except RuntimeError:
|
||||
connect_entrance(world, entrancename, exitname, player)
|
||||
|
||||
if invFlag != (0x03 in world.owswaps[player][0] and world.owMixed[player]) and \
|
||||
invFlag == (0x0a in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x03, player) and not world.is_tile_swapped(0x0a, player):
|
||||
connect_entrance(world, 'Death Mountain Return Cave (West)', 'Dark Death Mountain Healer Fairy', player)
|
||||
elif invFlag != (0x0a in world.owswaps[player][0] and world.owMixed[player]) and \
|
||||
invFlag == (0x03 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
elif world.is_tile_swapped(0x0a, player) and not world.is_tile_swapped(0x03, player):
|
||||
connect_two_way(world, 'Bumper Cave (Top)', 'Death Mountain Return Cave Exit (West)', player)
|
||||
ignore_pool = False
|
||||
|
||||
@@ -144,15 +142,15 @@ def link_entrances(world, player):
|
||||
Two_Door_Caves_Directional = list()
|
||||
Two_Door_Caves = [('Elder House (East)', 'Elder House (West)'),
|
||||
('Superbunny Cave (Bottom)', 'Superbunny Cave (Top)')]
|
||||
if invFlag == (0x0a in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x0a, player):
|
||||
Two_Door_Caves_Directional.append(tuple({'Bumper Cave (Bottom)', 'Bumper Cave (Top)'}))
|
||||
else:
|
||||
Two_Door_Caves_Directional.append(tuple({'Old Man Cave (West)', 'Death Mountain Return Cave (West)'}))
|
||||
if invFlag == (0x05 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x05, player):
|
||||
Two_Door_Caves_Directional.append(tuple({'Hookshot Cave', 'Hookshot Cave Back Entrance'}))
|
||||
else:
|
||||
Two_Door_Caves.append(tuple({'Hookshot Cave', 'Hookshot Cave Back Entrance'}))
|
||||
if invFlag == (0x28 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x28, player):
|
||||
Two_Door_Caves.append(tuple({'Two Brothers House (East)', 'Two Brothers House (West)'}))
|
||||
else:
|
||||
Two_Door_Caves_Directional.append(tuple({'Two Brothers House (East)', 'Two Brothers House (West)'}))
|
||||
@@ -181,14 +179,14 @@ def link_entrances(world, player):
|
||||
caves.extend(list(Old_Man_House))
|
||||
caves.extend(list(three_exit_caves))
|
||||
|
||||
if invFlag == (0x18 in world.owswaps[player][0] and world.owMixed[player]) or invFlag == (0x03 in world.owswaps[player][0] and world.owMixed[player]): # ability to activate flute in LW
|
||||
if (not world.is_tile_swapped(0x18, player)) or (not world.is_tile_swapped(0x03, player)): # ability to activate flute in LW
|
||||
candidates = [e for e in lw_wdm_entrances if e != 'Old Man House (Bottom)']
|
||||
random.shuffle(candidates)
|
||||
old_man_exit = candidates.pop()
|
||||
lw_wdm_entrances.remove(old_man_exit)
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
|
||||
if invFlag == (0x0a in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x0a, player):
|
||||
lw_wdm_entrances.extend(['Old Man Cave (West)', 'Death Mountain Return Cave (West)'])
|
||||
else:
|
||||
lw_wdm_entrances.extend(['Bumper Cave (Bottom)', 'Bumper Cave (Top)'])
|
||||
@@ -213,7 +211,7 @@ def link_entrances(world, player):
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
|
||||
# place old man, bumper cave bottom to DDM entrances not in east bottom
|
||||
if invFlag == (0x0a in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x0a, player):
|
||||
connect_two_way(world, 'Old Man Cave (West)', 'Old Man Cave Exit (West)', player)
|
||||
else:
|
||||
connect_two_way(world, 'Bumper Cave (Bottom)', 'Old Man Cave Exit (West)', player)
|
||||
@@ -223,7 +221,7 @@ def link_entrances(world, player):
|
||||
connect_caves(world, lw_wdm_entrances + lw_edm_entrances, [], caves, player)
|
||||
else:
|
||||
# place Old Man House in WDM if not swapped
|
||||
if invFlag == (0x03 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x03, player):
|
||||
connect_caves(world, lw_wdm_entrances, [], list(Old_Man_House), player)
|
||||
else:
|
||||
connect_caves(world, lw_edm_entrances, [], list(Old_Man_House), player)
|
||||
@@ -258,7 +256,7 @@ def link_entrances(world, player):
|
||||
|
||||
# place bomb shop, has limited options
|
||||
bomb_shop_doors = list(entrance_pool)
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or (invFlag != (0x1b in world.owswaps[player][0] and world.owMixed[player])):
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
|
||||
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
|
||||
bomb_shop = random.choice(bomb_shop_doors)
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
@@ -303,7 +301,7 @@ def link_entrances(world, player):
|
||||
|
||||
# place bomb shop, has limited options
|
||||
bomb_shop_doors = list(entrance_pool)
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or (invFlag != (0x1b in world.owswaps[player][0] and world.owMixed[player])):
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
|
||||
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
|
||||
bomb_shop = random.choice(bomb_shop_doors)
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
@@ -360,7 +358,7 @@ def link_entrances(world, player):
|
||||
|
||||
# place bomb shop, has limited options
|
||||
bomb_shop_doors = [e for e in entrance_pool if e not in list(zip(*drop_connections + dropexit_connections))[0]]
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or (invFlag != (0x1b in world.owswaps[player][0] and world.owMixed[player])):
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
|
||||
bomb_shop_doors = [e for e in bomb_shop_doors if e not in ['Pyramid Fairy']]
|
||||
bomb_shop = random.choice(bomb_shop_doors)
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
@@ -462,7 +460,7 @@ def link_entrances(world, player):
|
||||
|
||||
# place bomb shop, has limited options
|
||||
bomb_shop_doors = list(entrance_pool)
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or (invFlag != (0x1b in world.owswaps[player][0] and world.owMixed[player])):
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
|
||||
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
|
||||
bomb_shop = random.choice(bomb_shop_doors)
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
@@ -516,7 +514,7 @@ def link_entrances(world, player):
|
||||
|
||||
# place bomb shop, has limited options
|
||||
bomb_shop_doors = list(entrance_pool)
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or (invFlag != (0x1b in world.owswaps[player][0] and world.owMixed[player])):
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
|
||||
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
|
||||
bomb_shop = random.choice(bomb_shop_doors)
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
@@ -565,7 +563,7 @@ def link_entrances(world, player):
|
||||
|
||||
# place bomb shop, has limited options
|
||||
bomb_shop_doors = list(entrance_pool)
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or (invFlag != (0x1b in world.owswaps[player][0] and world.owMixed[player])):
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
|
||||
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
|
||||
bomb_shop = random.choice(bomb_shop_doors)
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
@@ -604,11 +602,11 @@ def link_entrances(world, player):
|
||||
|
||||
if not world.shuffle_ganon:
|
||||
connect_two_way(world, 'Ganons Tower' if not invFlag else 'Agahnims Tower', 'Ganons Tower Exit', player)
|
||||
connect_two_way(world, 'Pyramid Entrance' if invFlag == (0x1b in world.owswaps[player][0] and world.owMixed[player]) else 'Inverted Pyramid Entrance', 'Pyramid Exit', player)
|
||||
connect_entrance(world, 'Pyramid Hole' if invFlag == (0x1b in world.owswaps[player][0] and world.owMixed[player]) else 'Inverted Pyramid Hole', 'Pyramid', player)
|
||||
connect_two_way(world, 'Pyramid Entrance' if not world.is_tile_swapped(0x1b, player) else 'Inverted Pyramid Entrance', 'Pyramid Exit', player)
|
||||
connect_entrance(world, 'Pyramid Hole' if not world.is_tile_swapped(0x1b, player) else 'Inverted Pyramid Hole', 'Pyramid', player)
|
||||
else:
|
||||
caves.extend(['Ganons Tower Exit', 'Pyramid Exit'])
|
||||
hole_entrances.append('Pyramid Hole' if invFlag == (0x1b in world.owswaps[player][0] and world.owMixed[player]) else 'Inverted Pyramid Hole')
|
||||
hole_entrances.append('Pyramid Hole' if not world.is_tile_swapped(0x1b, player) else 'Inverted Pyramid Hole')
|
||||
hole_targets.append('Pyramid')
|
||||
|
||||
# shuffle holes
|
||||
@@ -648,7 +646,7 @@ def link_entrances(world, player):
|
||||
|
||||
# place bomb shop, has limited options
|
||||
bomb_shop_doors = list(entrance_pool)
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or (invFlag != (0x1b in world.owswaps[player][0] and world.owMixed[player])):
|
||||
if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player):
|
||||
bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']]
|
||||
random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
@@ -693,7 +691,7 @@ def link_entrances(world, player):
|
||||
world.powder_patch_required[player] = True
|
||||
|
||||
# check for ganon location
|
||||
if world.get_entrance('Pyramid Hole' if invFlag == (0x1b in world.owswaps[player][0] and world.owMixed[player]) else 'Inverted Pyramid Hole', player).connected_region.name != 'Pyramid':
|
||||
if world.get_entrance('Pyramid Hole' if not world.is_tile_swapped(0x1b, player) else 'Inverted Pyramid Hole', player).connected_region.name != 'Pyramid':
|
||||
world.ganon_at_pyramid[player] = False
|
||||
|
||||
# check for Ganon's Tower location
|
||||
@@ -1074,7 +1072,7 @@ def scramble_holes(world, player):
|
||||
hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance'))
|
||||
|
||||
if world.shuffle_ganon:
|
||||
hole_entrances.append(('Pyramid Entrance', 'Pyramid Hole') if invFlag == (0x1b in world.owswaps[player][0] and world.owMixed[player]) else ('Inverted Pyramid Entrance', 'Inverted Pyramid Hole'))
|
||||
hole_entrances.append(('Pyramid Entrance', 'Pyramid Hole') if not world.is_tile_swapped(0x1b, player) else ('Inverted Pyramid Entrance', 'Inverted Pyramid Hole'))
|
||||
hole_targets.append(('Pyramid Exit', 'Pyramid'))
|
||||
|
||||
# shuffle sanctuary hole in same world as other HC entrances
|
||||
@@ -1099,11 +1097,11 @@ def scramble_holes(world, player):
|
||||
else:
|
||||
# checks if drop candidates exist in LW
|
||||
drop_owids = [ 0x00, 0x02, 0x13, 0x15, 0x18, 0x1b, 0x22 ]
|
||||
hc_in_lw = any([invFlag == (owid in world.owswaps[player][0] and world.owMixed[player]) for owid in drop_owids])
|
||||
hc_in_lw = any([not world.is_tile_swapped(owid, player) for owid in drop_owids])
|
||||
|
||||
candidate_drops = list()
|
||||
for door, drop in hole_entrances:
|
||||
if hc_in_lw == (drop_owid_map[door][1] == (invFlag == (drop_owid_map[door][0] in world.owswaps[player][0] and world.owMixed[player]))):
|
||||
if hc_in_lw == (drop_owid_map[door][1] == (not world.is_tile_swapped(drop_owid_map[door][0], player))):
|
||||
candidate_drops.append(tuple((door, drop)))
|
||||
|
||||
random.shuffle(candidate_drops)
|
||||
@@ -1117,7 +1115,7 @@ def scramble_holes(world, player):
|
||||
# place pyramid hole
|
||||
if not world.shuffle_ganon:
|
||||
exit, target = ('Pyramid Exit', 'Pyramid')
|
||||
if invFlag == (0x1b in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x1b, player):
|
||||
connect_two_way(world, 'Pyramid Entrance', exit, player)
|
||||
connect_entrance(world, 'Pyramid Hole', target, player)
|
||||
else:
|
||||
@@ -1183,16 +1181,16 @@ def simple_shuffle_dungeons(world, player):
|
||||
|
||||
# checks if drop candidates exist in LW
|
||||
drop_owids = [ 0x00, 0x02, 0x13, 0x15, 0x18, 0x1b, 0x22 ]
|
||||
drops_in_light_world = any([invFlag == (owid in world.owswaps[player][0] and world.owMixed[player]) for owid in drop_owids])
|
||||
drops_in_light_world = any([not world.is_tile_swapped(owid, player) for owid in drop_owids])
|
||||
|
||||
# placing HC in guaranteed same-world as available dropdowns
|
||||
if not drops_in_light_world or not invFlag:
|
||||
candidate_dungeons = list()
|
||||
for d in multi_dungeons:
|
||||
if not drops_in_light_world and dungeon_owid_map[d][1] == (invFlag != (dungeon_owid_map[d][0] in world.owswaps[player][0] and world.owMixed[player])):
|
||||
if not drops_in_light_world and dungeon_owid_map[d][1] == world.is_tile_swapped(dungeon_owid_map[d][0], player):
|
||||
# only adding DW candidates
|
||||
candidate_dungeons.append(d)
|
||||
elif not invFlag and dungeon_owid_map[d][1] == (invFlag == (dungeon_owid_map[d][0] in world.owswaps[player][0] and world.owMixed[player])):
|
||||
elif not invFlag and dungeon_owid_map[d][1] == (not world.is_tile_swapped(dungeon_owid_map[d][0], player)):
|
||||
# only adding LW candidates
|
||||
candidate_dungeons.append(d)
|
||||
random.shuffle(candidate_dungeons)
|
||||
@@ -1218,7 +1216,7 @@ def simple_shuffle_dungeons(world, player):
|
||||
elif hc_target == 'Turtle Rock':
|
||||
connect_two_way(world, 'Turtle Rock', 'Hyrule Castle Exit (South)', player)
|
||||
connect_two_way(world, 'Dark Death Mountain Ledge (West)', 'Hyrule Castle Exit (West)', player)
|
||||
if invFlag == (0x45 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x45, player):
|
||||
connect_two_way(world, 'Turtle Rock Isolated Ledge Entrance', 'Hyrule Castle Exit (East)', player)
|
||||
connect_two_way(world, 'Dark Death Mountain Ledge (East)', at_door, player)
|
||||
else:
|
||||
@@ -1302,7 +1300,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player):
|
||||
lw_entrances = list()
|
||||
dw_entrances = list()
|
||||
for owid in dungeon_owid_map.keys():
|
||||
if dungeon_owid_map[owid][1] == (invFlag == (owid in world.owswaps[player][0] and world.owMixed[player])):
|
||||
if dungeon_owid_map[owid][1] == (not world.is_tile_swapped(owid, player)):
|
||||
lw_entrances.extend([e for e in dungeon_owid_map[owid][0] if e in entrance_pool])
|
||||
else:
|
||||
dw_entrances.extend([e for e in dungeon_owid_map[owid][0] if e in entrance_pool])
|
||||
@@ -1315,7 +1313,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player):
|
||||
dw_must_exit = list()
|
||||
lw_related = list()
|
||||
dw_related = list()
|
||||
if invFlag == (0x45 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x45, player):
|
||||
dw_entrances.remove('Turtle Rock Isolated Ledge Entrance')
|
||||
dw_must_exit.append('Turtle Rock Isolated Ledge Entrance')
|
||||
if 'Dark Death Mountain Ledge' in world.inaccessible_regions[player]:
|
||||
@@ -1324,7 +1322,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player):
|
||||
random.shuffle(ledge)
|
||||
dw_must_exit.append(ledge.pop())
|
||||
dw_related.extend(ledge)
|
||||
if invFlag == (0x30 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x30, player):
|
||||
if 'Desert Palace Mouth' in world.inaccessible_regions[player]:
|
||||
lw_entrances.remove('Desert Palace Entrance (East)')
|
||||
lw_must_exit.append('Desert Palace Entrance (East)')
|
||||
@@ -1337,7 +1335,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player):
|
||||
random.shuffle(ledge)
|
||||
dw_must_exit.append(ledge.pop())
|
||||
dw_related.extend(ledge)
|
||||
if invFlag == (0x1b in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x1b, player):
|
||||
if 'Hyrule Castle Ledge' in world.inaccessible_regions[player]:
|
||||
ledge = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower']
|
||||
lw_entrances = [e for e in lw_entrances if e not in ledge]
|
||||
@@ -1352,7 +1350,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player):
|
||||
hyrule_castle_exits = list([tuple(e for e in hyrule_castle_exits if e in exit_pool)])
|
||||
hyrule_castle_exits.extend([e for e in dungeon_exits if isinstance(e, str)])
|
||||
dungeon_exits = [e for e in dungeon_exits if not isinstance(e, str)]
|
||||
if invFlag == (0x13 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x13, player):
|
||||
connect_mandatory_exits(world, lw_entrances, hyrule_castle_exits, lw_must_exit, player, False)
|
||||
dungeon_exits.extend([e for e in hyrule_castle_exits if isinstance(e, str)])
|
||||
hyrule_castle_exits = [e for e in hyrule_castle_exits if not isinstance(e, str)]
|
||||
@@ -1444,7 +1442,7 @@ def place_blacksmith(world, links_house, player):
|
||||
|
||||
def place_old_man(world, pool, player, ignore_list=[]):
|
||||
# exit has to come from specific set of doors, the entrance is free to move about
|
||||
if (world.mode[player] == 'inverted') == (0x03 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x03, player):
|
||||
region_name = 'West Death Mountain (Top)'
|
||||
else:
|
||||
region_name = 'West Dark Death Mountain (Top)'
|
||||
@@ -1537,7 +1535,7 @@ def connect_inaccessible_regions(world, lw_entrances, dw_entrances, caves, playe
|
||||
for region_name in inaccessible_regions.copy():
|
||||
region = world.get_region(region_name, player)
|
||||
if region.type not in [RegionType.LightWorld, RegionType.DarkWorld] or not any((not exit.connected_region and exit.spot_type == 'Entrance') for exit in region.exits) \
|
||||
or (region_name == 'Pyramid Exit Ledge' and world.shuffle[player] != 'insanity' or invFlag != (0x1b in world.owswaps[player][0] and world.owMixed[player])):
|
||||
or (region_name == 'Pyramid Exit Ledge' and world.shuffle[player] != 'insanity' or world.is_tile_swapped(0x1b, player)):
|
||||
inaccessible_regions.remove(region_name)
|
||||
elif region.type == (RegionType.LightWorld if not invFlag else RegionType.DarkWorld):
|
||||
must_exit_regions.append(region_name)
|
||||
|
||||
4
Fill.py
4
Fill.py
@@ -358,7 +358,7 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
||||
if not gftower_trash or not world.ganonstower_vanilla[player] or world.doorShuffle[player] == 'crossed' or world.logic[player] in ['owglitches', 'nologic']:
|
||||
continue
|
||||
|
||||
gftower_trash_count = (random.randint(15, 50) if world.goal[player] == 'triforcehunt' else random.randint(0, 15))
|
||||
gftower_trash_count = (random.randint(15, 50) if world.goal[player] in ['triforcehunt', 'trinity'] else random.randint(0, 15))
|
||||
|
||||
gtower_locations = [location for location in fill_locations if 'Ganons Tower' in location.name and location.player == player]
|
||||
random.shuffle(gtower_locations)
|
||||
@@ -701,7 +701,7 @@ def balance_money_progression(world):
|
||||
sphere_locations = get_sphere_locations(state, unchecked_locations)
|
||||
checked_locations = []
|
||||
for player in range(1, world.players+1):
|
||||
kiki_payable = state.prog_items[('Moon Pearl', player)] > 0 or (world.mode[player] == 'inverted') != (0x1e in world.owswaps[player][0] and world.owMixed[player])
|
||||
kiki_payable = state.prog_items[('Moon Pearl', player)] > 0 or world.is_tile_swapped(0x1e, player)
|
||||
if kiki_payable and world.get_region('Palace of Darkness Area', player) in state.reachable_regions[player]:
|
||||
if not kiki_paid[player]:
|
||||
kiki_check[player] = True
|
||||
|
||||
66
ItemList.py
66
ItemList.py
@@ -178,7 +178,7 @@ def get_custom_array_key(item):
|
||||
|
||||
|
||||
def generate_itempool(world, player):
|
||||
if (world.difficulty[player] not in ['normal', 'hard', 'expert'] or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals']
|
||||
if (world.difficulty[player] not in ['normal', 'hard', 'expert'] or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'trinity', 'crystals']
|
||||
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')
|
||||
|
||||
@@ -190,7 +190,7 @@ def generate_itempool(world, player):
|
||||
else:
|
||||
world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False)
|
||||
|
||||
if world.goal[player] in ['triforcehunt']:
|
||||
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||
region = world.get_region('Hyrule Castle Courtyard',player)
|
||||
|
||||
loc = Location(player, "Murahdahla", parent=region)
|
||||
@@ -262,8 +262,8 @@ def generate_itempool(world, player):
|
||||
world.get_location('Zelda Drop Off', player).locked = True
|
||||
|
||||
# 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[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray)
|
||||
if world.custom and player in world.customitemarray:
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_total, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray[player])
|
||||
world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999)
|
||||
else:
|
||||
(pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player])
|
||||
@@ -337,14 +337,9 @@ def generate_itempool(world, player):
|
||||
if clock_mode is not None:
|
||||
world.clock_mode = clock_mode
|
||||
|
||||
if world.goal[player] == 'triforcehunt':
|
||||
if world.treasure_hunt_count[player] == 0:
|
||||
world.treasure_hunt_count[player] = 20
|
||||
if world.treasure_hunt_total[player] == 0:
|
||||
world.treasure_hunt_total[player] = 30
|
||||
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||
world.treasure_hunt_count[player], world.treasure_hunt_total[player] = set_default_triforce(world.goal[player], world.treasure_hunt_count[player], world.treasure_hunt_total[player])
|
||||
world.treasure_hunt_icon[player] = 'Triforce Piece'
|
||||
if world.custom:
|
||||
world.treasure_hunt_count[player] = treasure_hunt_count
|
||||
|
||||
world.itempool.extend([item for item in get_dungeon_item_pool(world) if item.player == player
|
||||
and ((item.smallkey and world.keyshuffle[player])
|
||||
@@ -355,9 +350,9 @@ def generate_itempool(world, player):
|
||||
# logic has some branches where having 4 hearts is one possible requirement (of several alternatives)
|
||||
# rather than making all hearts/heart pieces progression items (which slows down generation considerably)
|
||||
# We mark one random heart container as an advancement item (or 4 heart pieces in expert mode)
|
||||
if world.difficulty[player] in ['normal', 'hard'] and not (world.custom and world.customitemarray[player]["heartcontainer"] == 0):
|
||||
if world.difficulty[player] in ['normal', 'hard'] and not (world.custom and player in world.customitemarray and world.customitemarray[player]["heartcontainer"] == 0):
|
||||
next(item for item in items if item.name == 'Boss Heart Container').advancement = True
|
||||
elif world.difficulty[player] in ['expert'] and not (world.custom and world.customitemarray[player]["heartpiece"] < 4):
|
||||
elif world.difficulty[player] in ['expert'] and not (world.custom and player in world.customitemarray and world.customitemarray[player]["heartpiece"] < 4):
|
||||
adv_heart_pieces = (item for item in items if item.name == 'Piece of Heart')
|
||||
for i in range(4):
|
||||
next(adv_heart_pieces).advancement = True
|
||||
@@ -414,7 +409,7 @@ def set_up_take_anys(world, player):
|
||||
if world.mode[player] == 'inverted':
|
||||
if 'Dark Sanctuary Hint' in take_any_locations:
|
||||
take_any_locations.remove('Dark Sanctuary Hint')
|
||||
if (world.mode[player] == 'inverted') != (0x29 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x29, player):
|
||||
if 'Archery Game' in take_any_locations:
|
||||
take_any_locations.remove('Archery Game')
|
||||
|
||||
@@ -759,7 +754,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
placed_items = {}
|
||||
precollected_items = []
|
||||
clock_mode = None
|
||||
if goal == 'triforcehunt':
|
||||
if goal in ['triforcehunt', 'trinity']:
|
||||
if treasure_hunt_total == 0:
|
||||
treasure_hunt_total = 30
|
||||
triforcepool = ['Triforce Piece'] * int(treasure_hunt_total)
|
||||
@@ -841,7 +836,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
place_item('Link\'s Uncle', swords_to_use.pop())
|
||||
place_item('Blacksmith', swords_to_use.pop())
|
||||
place_item('Pyramid Fairy - Left', swords_to_use.pop())
|
||||
if goal != 'pedestal':
|
||||
if goal not in ['pedestal', 'trinity']:
|
||||
place_item('Master Sword Pedestal', swords_to_use.pop())
|
||||
else:
|
||||
place_item('Master Sword Pedestal', 'Triforce')
|
||||
@@ -866,7 +861,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
pool.extend(diff.timedohko)
|
||||
extraitems -= len(diff.timedohko)
|
||||
clock_mode = 'countdown-ohko'
|
||||
if goal == 'triforcehunt':
|
||||
if goal in ['triforcehunt', 'trinity']:
|
||||
pool.extend(triforcepool)
|
||||
extraitems -= len(triforcepool)
|
||||
|
||||
@@ -877,7 +872,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
pool.extend(extra)
|
||||
extraitems -= len(extra)
|
||||
|
||||
if goal == 'pedestal' and swords != 'vanilla':
|
||||
if goal in ['pedestal', 'trinity'] and swords != 'vanilla':
|
||||
place_item('Master Sword Pedestal', 'Triforce')
|
||||
if retro:
|
||||
pool = [item.replace('Single Arrow','Rupees (5)') for item in pool]
|
||||
@@ -901,13 +896,12 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
|
||||
return (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms)
|
||||
|
||||
def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, bombbag, customitemarray):
|
||||
if isinstance(customitemarray,dict) and 1 in customitemarray:
|
||||
customitemarray = customitemarray[1]
|
||||
pool = []
|
||||
placed_items = {}
|
||||
precollected_items = []
|
||||
clock_mode = None
|
||||
treasure_hunt_count = None
|
||||
treasure_hunt_total = None
|
||||
treasure_hunt_icon = None
|
||||
|
||||
def place_item(loc, item):
|
||||
@@ -916,7 +910,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
||||
|
||||
# Correct for insanely oversized item counts and take initial steps to handle undersized pools.
|
||||
# Bow to Silver Arrows Upgrade, including Generic Keys & Rupoors
|
||||
for x in [*range(0, 66 + 1), 68, 69]:
|
||||
for x in [*range(0, 69)]:
|
||||
key = CONST.CUSTOMITEMS[x]
|
||||
if customitemarray[key] > total_items_to_place:
|
||||
customitemarray[key] = total_items_to_place
|
||||
@@ -925,6 +919,10 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
||||
if customitemarray["triforce"] > total_items_to_place:
|
||||
customitemarray["triforce"] = total_items_to_place
|
||||
|
||||
# Triforce Pieces
|
||||
if goal in ['triforcehunt', 'trinity']:
|
||||
customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"] = set_default_triforce(goal, customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"])
|
||||
|
||||
itemtotal = 0
|
||||
# Bow to Silver Arrows Upgrade, including Generic Keys & Rupoors
|
||||
for x in [*range(0, 66 + 1), 68, 69]:
|
||||
@@ -955,13 +953,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
||||
pool.append(thisbottle)
|
||||
|
||||
if customitemarray["triforcepieces"] > 0 or customitemarray["triforcepiecesgoal"] > 0:
|
||||
treasure_hunt_count = max(min(customitemarray["triforcepiecesgoal"], 99), 1) #To display, count must be between 1 and 99.
|
||||
treasure_hunt_icon = 'Triforce Piece'
|
||||
# Ensure game is always possible to complete here, force sufficient pieces if the player is unwilling.
|
||||
if (customitemarray["triforcepieces"] < treasure_hunt_count) and (goal == 'triforcehunt') and (customitemarray["triforce"] == 0):
|
||||
extrapieces = treasure_hunt_count - customitemarray["triforcepieces"]
|
||||
pool.extend(['Triforce Piece'] * extrapieces)
|
||||
itemtotal = itemtotal + extrapieces
|
||||
|
||||
if timer in ['display', 'timed', 'timed-countdown']:
|
||||
clock_mode = 'countdown' if timer == 'timed-countdown' else 'stopwatch'
|
||||
@@ -970,7 +962,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
||||
elif timer == 'ohko':
|
||||
clock_mode = 'ohko'
|
||||
|
||||
if goal == 'pedestal':
|
||||
if goal in ['pedestal', 'trinity']:
|
||||
place_item('Master Sword Pedestal', 'Triforce')
|
||||
itemtotal = itemtotal + 1
|
||||
|
||||
@@ -1003,12 +995,24 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
||||
# print("Placing " + str(nothings) + " Nothings")
|
||||
pool.extend(['Nothing'] * nothings)
|
||||
|
||||
return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms)
|
||||
return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_total, treasure_hunt_icon, lamps_needed_for_dark_rooms)
|
||||
|
||||
def set_default_triforce(goal, custom_goal, custom_total):
|
||||
triforce_goal, triforce_total = 0, 0
|
||||
if goal == 'triforcehunt':
|
||||
triforce_goal, triforce_total = 20, 30
|
||||
elif goal == 'trinity':
|
||||
triforce_goal, triforce_total = 8, 10
|
||||
if custom_goal > 0:
|
||||
triforce_goal = max(min(custom_goal, 128), 1)
|
||||
if custom_total > 0 or custom_goal > 0:
|
||||
triforce_total = max(min(custom_total, 128), triforce_goal) #128 max to ensure other progression can fit.
|
||||
return (triforce_goal, triforce_total)
|
||||
|
||||
# A quick test to ensure all combinations generate the correct amount of items.
|
||||
def test():
|
||||
for difficulty in ['normal', 'hard', 'expert']:
|
||||
for goal in ['ganon', 'triforcehunt', 'pedestal']:
|
||||
for goal in ['ganon', 'triforcehunt', 'pedestal', 'trinity']:
|
||||
for timer in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown']:
|
||||
for mode in ['open', 'standard', 'inverted', 'retro']:
|
||||
for swords in ['random', 'assured', 'swordless', 'vanilla']:
|
||||
@@ -1022,7 +1026,7 @@ def test():
|
||||
count = len(out[0]) + len(out[1])
|
||||
|
||||
correct_count = total_items_to_place
|
||||
if goal == 'pedestal' and swords != 'vanilla':
|
||||
if goal in ['pedestal', 'trinity'] and swords != 'vanilla':
|
||||
# pedestal goals generate one extra item
|
||||
correct_count += 1
|
||||
if retro:
|
||||
|
||||
@@ -1970,7 +1970,7 @@ def val_mire(key_logic, world, player):
|
||||
|
||||
def val_turtle(key_logic, world, player):
|
||||
# todo: check vanilla key logic when TR back doors are accessible
|
||||
if world.shuffle[player] == 'vanilla' and (world.mode[player] == 'inverted') == (0x05 in world.owswaps[player][0] and world.owMixed[player]) and world.logic[player] in ('noglitches', 'minorglitches'):
|
||||
if world.shuffle[player] == 'vanilla' and (not world.is_tile_swapped(0x05, player)) and world.logic[player] in ('noglitches', 'minorglitches'):
|
||||
val_rule(key_logic.door_rules['TR Hub NW'], 1)
|
||||
val_rule(key_logic.door_rules['TR Pokey 1 NW'], 2)
|
||||
val_rule(key_logic.door_rules['TR Chain Chomps Down Stairs'], 3)
|
||||
|
||||
@@ -179,9 +179,10 @@ def roll_settings(weights):
|
||||
'fast_ganon': 'crystals',
|
||||
'dungeons': 'dungeons',
|
||||
'pedestal': 'pedestal',
|
||||
'triforce-hunt': 'triforcehunt'
|
||||
'triforce-hunt': 'triforcehunt',
|
||||
'trinity': 'trinity'
|
||||
}[goal]
|
||||
ret.openpyramid = goal == 'fast_ganon' if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
|
||||
ret.openpyramid = goal in ['fast_ganon', 'trinity'] if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
|
||||
|
||||
ret.shuffleganon = get_choice('shuffleganon') == 'on'
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import RaceRandom as random, logging, copy
|
||||
from collections import OrderedDict
|
||||
from DungeonGenerator import GenerationException
|
||||
from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSlot, Entrance
|
||||
from Regions import mark_dark_world_regions, mark_light_world_regions
|
||||
from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel
|
||||
|
||||
__version__ = '0.2.3.5-u'
|
||||
__version__ = '0.2.3.6-u'
|
||||
|
||||
def link_overworld(world, player):
|
||||
# setup mandatory connections
|
||||
@@ -159,7 +160,7 @@ def link_overworld(world, player):
|
||||
|
||||
# apply tile logical connections
|
||||
for owid in ow_connections.keys():
|
||||
if (world.mode[player] == 'inverted') == (owid in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(owid, player):
|
||||
for (exitname, regionname) in ow_connections[owid][0]:
|
||||
connect_simple(world, exitname, regionname, player)
|
||||
else:
|
||||
@@ -342,7 +343,7 @@ def link_overworld(world, player):
|
||||
for o in range(0, len(flute_destinations)):
|
||||
owslot = flute_destinations[o]
|
||||
regions = flute_data[owslot][0]
|
||||
if (world.mode[player] == 'inverted') == (flute_data[owslot][1] in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(flute_data[owslot][1], player):
|
||||
connect_simple(world, 'Flute Spot ' + str(o + 1), regions[0], player)
|
||||
else:
|
||||
connect_simple(world, 'Flute Spot ' + str(o + 1), regions[1], player)
|
||||
@@ -364,7 +365,7 @@ def link_overworld(world, player):
|
||||
new_ignored.add(exit.connected_region.name)
|
||||
getIgnored(exit.connected_region.name, base_owid, OWTileRegions[exit.connected_region.name])
|
||||
|
||||
if (world.mode[player] == 'inverted') == (flute_data[owid][1] in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(flute_data[owid][1], player):
|
||||
new_region = flute_data[owid][0][0]
|
||||
else:
|
||||
new_region = flute_data[owid][0][1]
|
||||
|
||||
@@ -136,6 +136,12 @@ New flute spots are chosen at random, with restrictions that limit the promixity
|
||||
|
||||
New flute spots are chosen at random with minimum bias.
|
||||
|
||||
## New Goal Options (--goal)
|
||||
|
||||
### Trinity
|
||||
|
||||
This goal gives you the choice between 3 goals, only one of which the player needs to complete: Defeat Ganon (no Aga2), Pulling Pedestal, or turn in TF pieces to Murahdulah. By default, you need to find 8 of 10 total TF pieces but this can be changed with a Custom Item Pool. It is recommended to set GT Entry to 7 crystals and Ganon to 5 crystals or Random crystals, although the player can flexibly change these settings as they seem fit.
|
||||
|
||||
## New Entrance Shuffle Options (--shuffle)
|
||||
|
||||
### Lite
|
||||
|
||||
42
Rom.py
42
Rom.py
@@ -624,7 +624,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
offset = 0
|
||||
data = flute_data[owslot]
|
||||
|
||||
if (world.mode[player] == 'inverted') != (data[1] in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(data[1], player):
|
||||
offset = 0x40
|
||||
|
||||
write_int16(rom, snes_to_pc(0x02E849 + (o * 2)), data[1] + offset) # owid
|
||||
@@ -755,7 +755,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' else DROptions.Town_Portal
|
||||
if world.doorShuffle[player] == 'crossed':
|
||||
dr_flags |= DROptions.Map_Info
|
||||
if world.experimental[player] and world.goal[player] != 'triforcehunt':
|
||||
if world.experimental[player] and world.goal[player] not in ['triforcehunt', 'trinity']:
|
||||
dr_flags |= DROptions.Debug
|
||||
if world.doorShuffle[player] == 'crossed' and world.logic[player] != 'nologic'\
|
||||
and world.mixed_travel[player] == 'prevent':
|
||||
@@ -1235,7 +1235,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
|
||||
# set up goals for treasure hunt
|
||||
rom.write_bytes(0x180165, [0x0E, 0x28] if world.treasure_hunt_icon[player] == 'Triforce Piece' else [0x0D, 0x28])
|
||||
if world.goal[player] == 'triforcehunt':
|
||||
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||
rom.write_byte(0x180167, int(world.treasure_hunt_count[player]) % 256)
|
||||
rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled)
|
||||
|
||||
@@ -1261,7 +1261,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
rom.write_bytes(0x50563, [0x3F, 0x14]) # disable below ganon chest
|
||||
rom.write_byte(0x50599, 0x00) # disable below ganon chest
|
||||
rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest
|
||||
rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] else 0x00) # pre-open Pyramid Hole
|
||||
rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] or world.goal[player] == 'trinity' else 0x00) # pre-open Pyramid Hole
|
||||
rom.write_byte(0x18008C, 0x01 if world.crystals_needed_for_gt[player] == 0 else 0x00) # GT pre-opened if crystal requirement is 0
|
||||
rom.write_byte(0xF5D73, 0xF0) # bees are catchable
|
||||
rom.write_byte(0xF5F10, 0xF0) # bees are catchable
|
||||
@@ -1446,7 +1446,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
rom.write_byte(0x18003E, 0x01) # make ganon invincible
|
||||
elif world.goal[player] in ['dungeons']:
|
||||
rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat
|
||||
elif world.goal[player] in ['crystals']:
|
||||
elif world.goal[player] in ['crystals', 'trinity']:
|
||||
rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals
|
||||
else:
|
||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
||||
@@ -2186,7 +2186,7 @@ def write_strings(rom, world, player, team):
|
||||
elif world.shopsanity[player]:
|
||||
entrances_to_hint.update(ShopEntrances)
|
||||
if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
|
||||
if world.mode[player] == 'inverted' != (0x2c in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x2c, player):
|
||||
entrances_to_hint.update({'Links House': 'The hero\'s old residence'})
|
||||
if world.shufflelinks[player]:
|
||||
entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'})
|
||||
@@ -2198,7 +2198,7 @@ def write_strings(rom, world, player, team):
|
||||
if world.shuffle[player] in ['insanity', 'madness_legacy', 'insanity_legacy']:
|
||||
entrances_to_hint.update(InsanityEntrances)
|
||||
if world.shuffle_ganon:
|
||||
if world.mode[player] == 'inverted' != (0x1b in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x1b, player):
|
||||
entrances_to_hint.update({'Inverted Pyramid Entrance': 'The extra castle passage'})
|
||||
else:
|
||||
entrances_to_hint.update({'Pyramid Entrance': 'The pyramid ledge'})
|
||||
@@ -2374,6 +2374,10 @@ def write_strings(rom, world, player, team):
|
||||
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
||||
tt['sign_ganon'] = 'You need to get to the pedestal... Ganon is invincible!'
|
||||
else:
|
||||
if world.goal[player] in ['trinity']:
|
||||
trinity_crystal_text = ('%d crystal to beat Ganon.' if world.crystals_needed_for_ganon[player] == 1 else '%d crystals to beat Ganon.') % world.crystals_needed_for_ganon[player]
|
||||
tt['sign_ganon'] = 'Three ways to victory! %s Get to it!' % trinity_crystal_text
|
||||
tt['murahdahla'] = "Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\nhidden in a hollow tree. If you bring\n%d triforce pieces, I can reassemble it." % int(world.treasure_hunt_count[player])
|
||||
tt['ganon_fall_in'] = Ganon1_texts[random.randint(0, len(Ganon1_texts) - 1)]
|
||||
tt['ganon_fall_in_alt'] = 'You cannot defeat me until you finish your goal!'
|
||||
tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!'
|
||||
@@ -2495,9 +2499,9 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
|
||||
write_int16(rom, 0x15AEE + 2*0x38, 0x00E0)
|
||||
write_int16(rom, 0x15AEE + 2*0x25, 0x000C)
|
||||
|
||||
if (world.mode[player] == 'inverted') != (0x03 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x03, player):
|
||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] \
|
||||
or (world.shuffle[player] == 'simple' and (world.mode[player] == 'inverted' != (0x05 in world.owswaps[player][0] and world.owMixed[player]))):
|
||||
or (world.shuffle[player] == 'simple' and world.is_tile_swapped(0x05, player)):
|
||||
rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) # mountain cave starts on OW
|
||||
|
||||
write_int16(rom, snes_to_pc(0x02D8DE), 0x00F1) # change mountain cave spawn point to just outside old man cave
|
||||
@@ -2519,20 +2523,20 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
|
||||
rom.write_byte(snes_to_pc(0x02D9B8), 0x12)
|
||||
|
||||
rom.write_bytes(0x180247, [0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00]) # indicates the overworld door being used for the single entrance spawn point
|
||||
if (world.mode[player] == 'inverted') != (0x05 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x05, player):
|
||||
rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) # add warp under rock
|
||||
rom.write_byte(snes_to_pc(0x1BC428), 0x00) # remove secret portal
|
||||
if (world.mode[player] == 'inverted') != (0x07 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x07, player):
|
||||
rom.write_bytes(snes_to_pc(0x1BC387), [0xDD, 0xD1]) # add warps under rocks
|
||||
rom.write_bytes(snes_to_pc(0x1BD1DD), [0xA4, 0x06, 0x82, 0x9E, 0x06, 0x82, 0xFF, 0xFF]) # add warps under rocks
|
||||
rom.write_byte(0x180089, 0x01) # open TR after exit
|
||||
rom.write_bytes(0x0086E, [0x5C, 0x00, 0xA0, 0xA1]) # TR tail
|
||||
if world.shuffle[player] in ['vanilla']:
|
||||
world.fix_trock_doors[player] = True
|
||||
if (world.mode[player] == 'inverted') != (0x10 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x10, player):
|
||||
rom.write_bytes(snes_to_pc(0x1BC67A), [0x2E, 0x0B, 0x82]) # add warp under rock
|
||||
rom.write_byte(snes_to_pc(0x1BC43A), 0x00) # remove secret portal
|
||||
if (world.mode[player] == 'inverted') != (0x1B in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x1b, player):
|
||||
write_int16(rom, 0x15AEE + 2 * 0x06, 0x0020) # post aga hyrule castle spawn
|
||||
rom.write_byte(0x15B8C + 0x06, 0x1B)
|
||||
write_int16(rom, 0x15BDB + 2 * 0x06, 0x00AE)
|
||||
@@ -2637,24 +2641,24 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
|
||||
rom.write_byte(0x1607C + 0x37, 0x0A)
|
||||
write_int16(rom, 0x160CB + 2 * 0x37, 0x0000)
|
||||
write_int16(rom, 0x16169 + 2 * 0x37, 0x811C)
|
||||
if (world.mode[player] == 'inverted') != (0x29 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x29, player):
|
||||
rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact
|
||||
if (world.mode[player] == 'inverted') != (0x2C in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x2c, player):
|
||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
|
||||
rom.write_byte(0x15B8C, 0x6C) # exit links at bomb shop area
|
||||
rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house
|
||||
rom.write_byte(0xDBB73 + 0x52, 0x01)
|
||||
if (world.mode[player] == 'inverted') != (0x2F in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x2f, player):
|
||||
rom.write_bytes(snes_to_pc(0x1BC80D), [0xB2, 0x0B, 0x82]) # add warp under rock
|
||||
rom.write_byte(snes_to_pc(0x1BC590), 0x00) # remove secret portal
|
||||
if (world.mode[player] == 'inverted') != (0x30 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x30, player):
|
||||
rom.write_bytes(snes_to_pc(0x1BC81E), [0x94, 0x1D, 0x82]) # add warp under rock
|
||||
rom.write_byte(snes_to_pc(0x1BC5A1), 0x00) # remove secret portal
|
||||
if (world.mode[player] == 'inverted') != (0x33 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x33, player):
|
||||
rom.write_bytes(snes_to_pc(0x1BC3DF), [0xD8, 0xD1]) # add warp under rock
|
||||
rom.write_bytes(snes_to_pc(0x1BD1D8), [0xA8, 0x02, 0x82, 0xFF, 0xFF]) # add warp under rock
|
||||
rom.write_byte(snes_to_pc(0x1BC5B1), 0x00) # remove secret portal
|
||||
if (world.mode[player] == 'inverted') != (0x35 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if world.is_tile_swapped(0x35, player):
|
||||
rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) # add warp under rock
|
||||
rom.write_byte(snes_to_pc(0x1BC5C7), 0x00) # remove secret portal
|
||||
|
||||
|
||||
88
Rules.py
88
Rules.py
@@ -55,7 +55,7 @@ def set_rules(world, 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] == 'triforcehunt':
|
||||
if world.goal[player] in ['triforcehunt', 'trinity']:
|
||||
if ('Murahdahla', player) in world._location_cache:
|
||||
add_rule(world.get_location('Murahdahla', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player]))
|
||||
|
||||
@@ -860,7 +860,7 @@ def ow_rules(world, player):
|
||||
else:
|
||||
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x00 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x00, player):
|
||||
set_rule(world.get_entrance('Lost Woods East Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Lost Woods Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Lost Woods Pedestal Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -875,12 +875,12 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Skull Woods Forgotten (Middle) Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Skull Woods Front Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x02 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x02, player):
|
||||
set_rule(world.get_entrance('Lumberjack Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Dark Lumberjack Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x03 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x03, player):
|
||||
set_rule(world.get_entrance('West Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Spectacle Rock Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
@@ -888,7 +888,7 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Bubble Boy Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('West Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x05 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x05, player):
|
||||
set_rule(world.get_entrance('East Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('East Death Mountain (Top East) Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Mimic Cave Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -910,7 +910,7 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Dark Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Dark Death Mountain Teleporter (East)', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x07 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x07, player):
|
||||
set_rule(world.get_entrance('TR Pegs Area Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('TR Pegs Teleporter', player), lambda state: state.has('Hammer', player))
|
||||
else:
|
||||
@@ -918,7 +918,7 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Turtle Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_heavy_rocks(player) and state.has_Pearl(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x0a in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x0a, player):
|
||||
set_rule(world.get_entrance('Mountain Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Mountain Entry Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Mountain Entry Entrance Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -927,12 +927,12 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Bumper Cave Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x0f in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x0f, player):
|
||||
set_rule(world.get_entrance('Zora Waterfall Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Catfish Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x10 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x10, player):
|
||||
set_rule(world.get_entrance('Lost Woods Pass West Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Lost Woods Pass East Top Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Lost Woods Pass Portal Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -944,24 +944,24 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Skull Woods Pass Portal Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Skull Woods Pass East Bottom Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x11 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x11, player):
|
||||
set_rule(world.get_entrance('Kakariko Fortune Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Outcast Fortune Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x12 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x12, player):
|
||||
set_rule(world.get_entrance('Kakariko Pond Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Outcast Pond Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x13 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x13, player):
|
||||
set_rule(world.get_entrance('Sanctuary Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Bonk Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Dark Chapel Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Dark Chapel Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x14 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x14, player):
|
||||
set_rule(world.get_entrance('Graveyard Ledge Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player))
|
||||
else:
|
||||
@@ -971,28 +971,28 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Dark Graveyard Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Dark Graveyard Grave Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x15 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x15, player):
|
||||
set_rule(world.get_entrance('River Bend Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('River Bend East Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Qirn Jump Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Qirn Jump East Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x16 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x16, player):
|
||||
set_rule(world.get_entrance('Potion Shop Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Potion Shop Northeast Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Dark Witch Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Dark Witch Northeast Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x17 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x17, player):
|
||||
set_rule(world.get_entrance('Zora Approach Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Zora Approach Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Catfish Approach Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Catfish Approach Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x18 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x18, player):
|
||||
set_rule(world.get_entrance('Kakariko Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Kakariko Grass Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
@@ -1000,16 +1000,16 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Village of Outcasts Southwest Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Hammer House Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x1a in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x1a, player):
|
||||
set_rule(world.get_entrance('Forgotton Forest Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Forgotton Forest Fence Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Shield Shop Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x1b in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x1b, player):
|
||||
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: False)
|
||||
set_rule(world.get_entrance('Inverted Pyramid Entrance', player), lambda state: False)
|
||||
set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player])
|
||||
set_rule(world.get_entrance('Pyramid Hole', player), lambda state: world.open_pyramid[player] or world.goal[player] == 'trinity' or state.has('Beat Agahnim 2', player))
|
||||
|
||||
set_rule(world.get_entrance('HC Area Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('HC Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -1020,8 +1020,8 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Top of Pyramid', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||
set_rule(world.get_entrance('Top of Pyramid (Inner)', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player])
|
||||
add_rule(world.get_entrance('Pyramid Hole', player), lambda state: False)
|
||||
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: world.open_pyramid[player] or world.goal[player] == 'trinity' or state.has('Beat Agahnim 2', player))
|
||||
set_rule(world.get_entrance('Pyramid Hole', player), lambda state: False)
|
||||
set_rule(world.get_entrance('Pyramid Entrance', player), lambda state: False)
|
||||
|
||||
set_rule(world.get_entrance('Pyramid Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -1032,7 +1032,7 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Pyramid Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Post Aga Inverted Teleporter', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x1d in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x1d, player):
|
||||
set_rule(world.get_entrance('Wooden Bridge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Wooden Bridge Northeast Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Wooden Bridge West Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -1041,12 +1041,12 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Broken Bridge East Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Broken Bridge Northeast Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x1e in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x1e, player):
|
||||
set_rule(world.get_entrance('Eastern Palace Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Palace of Darkness Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x22 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x22, player):
|
||||
set_rule(world.get_entrance('Blacksmith Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Blacksmith Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Bat Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -1054,19 +1054,19 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Hammer Pegs Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Hammer Pegs Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x25 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x25, player):
|
||||
set_rule(world.get_entrance('Sand Dunes Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Dark Dunes Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x28 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x28, player):
|
||||
set_rule(world.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Maze Race Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Dig Game Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Dig Game Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x29 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x29, player):
|
||||
set_rule(world.get_entrance('Kakariko Suburb Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Kakariko Suburb South Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
@@ -1074,24 +1074,24 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Frog Prison Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Archery Game Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x2a in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x2a, player):
|
||||
set_rule(world.get_entrance('Flute Boy Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Flute Boy Pass Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Stumpy Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Stumpy Pass Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x2b in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x2b, player):
|
||||
set_rule(world.get_entrance('Central Bonk Rocks Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Dark Bonk Rocks Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x2c in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x2c, player):
|
||||
set_rule(world.get_entrance('Links House Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Big Bomb Shop Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x2d in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x2d, player):
|
||||
set_rule(world.get_entrance('Stone Bridge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Stone Bridge South Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Hobo Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player))
|
||||
@@ -1100,19 +1100,19 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Hammer Bridge South Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Dark Hobo Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x2e in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x2e, player):
|
||||
set_rule(world.get_entrance('Tree Line Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Dark Tree Line Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x2f in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x2f, player):
|
||||
set_rule(world.get_entrance('Eastern Nook Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||
else:
|
||||
set_rule(world.get_entrance('Darkness Nook Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x30 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x30, player):
|
||||
set_rule(world.get_entrance('Checkerboard Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Desert Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Desert Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
@@ -1127,14 +1127,14 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Misery Mire Main Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Misery Mire Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x32 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x32, player):
|
||||
set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Flute Boy Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Stumpy Approach Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Stumpy Bush Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x33 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x33, player):
|
||||
set_rule(world.get_entrance('C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('C Whirlpool Outer Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer
|
||||
@@ -1145,12 +1145,12 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player))
|
||||
set_rule(world.get_entrance('South Teleporter Cliff Ledge Drop', player), lambda state: state.can_lift_rocks(player) and state.has_Pearl(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x34 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x34, player):
|
||||
set_rule(world.get_entrance('Statues Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Hype Cave Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x35 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x35, player):
|
||||
set_rule(world.get_entrance('Lake Hylia Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Lake Hylia Northeast Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Lake Hylia Island Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player))
|
||||
@@ -1167,12 +1167,12 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Ice Palace Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Ice Palace Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x37 in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x37, player):
|
||||
set_rule(world.get_entrance('Ice Cave Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Shopping Mall Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x3a in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x3a, player):
|
||||
set_rule(world.get_entrance('Desert Pass Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Desert Pass Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
@@ -1180,17 +1180,17 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Swamp Nook Southeast Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Swamp Nook Pegs Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x3b in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x3b, player):
|
||||
set_rule(world.get_entrance('Dam Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Swamp Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x3c in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x3c, player):
|
||||
set_rule(world.get_entrance('South Pass Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Dark South Pass Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
if (world.mode[player] == 'inverted') == (0x3f in world.owswaps[player][0] and world.owMixed[player]):
|
||||
if not world.is_tile_swapped(0x3f, player):
|
||||
set_rule(world.get_entrance('Octoballoon Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Bomber Corner Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
dungeons: 1
|
||||
pedestal: 2
|
||||
triforce-hunt: 2
|
||||
trinity: 1
|
||||
triforce_goal_min: 10
|
||||
triforce_goal_max: 30
|
||||
triforce_pool_min: 20
|
||||
|
||||
@@ -103,7 +103,9 @@
|
||||
"All Dungeons: Collect all crystals, pendants, beat both",
|
||||
" Agahnim fights and then defeat Ganon.",
|
||||
"Triforce Hunt: Places 30 Triforce Pieces in the world, collect",
|
||||
" 20 of them to beat the game."
|
||||
" 20 of them to beat the game.",
|
||||
"Trinity: Can beat the game by defeating Ganon, pulling",
|
||||
" Pedestal, or delivering Triforce Pieces."
|
||||
],
|
||||
"difficulty": [
|
||||
"Select game difficulty. Affects available itempool. (default: %(default)s)",
|
||||
|
||||
@@ -238,6 +238,7 @@
|
||||
"randomizer.item.goal.pedestal": "Master Sword Pedestal",
|
||||
"randomizer.item.goal.dungeons": "All Dungeons",
|
||||
"randomizer.item.goal.triforcehunt": "Triforce Hunt",
|
||||
"randomizer.item.goal.trinity": "Trinity",
|
||||
"randomizer.item.goal.crystals": "Crystals",
|
||||
|
||||
"randomizer.item.crystals_gt": "Crystals to open GT",
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"pedestal",
|
||||
"dungeons",
|
||||
"triforcehunt",
|
||||
"trinity",
|
||||
"crystals"
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user