make "universal" small key shuffle a thing and split it out of retro
also make retro usable independently from the other world modes in mystery
This commit is contained in:
parent
bea54d91de
commit
685ff49711
|
@ -516,17 +516,13 @@ class CollectionState(object):
|
|||
def has_key(self, item, player, count: int = 1):
|
||||
if self.world.logic[player] == 'nologic':
|
||||
return True
|
||||
if self.world.retro[player]:
|
||||
if self.world.keyshuffle[player] == "universal":
|
||||
return self.can_buy_unlimited('Small Key (Universal)', player)
|
||||
if count == 1:
|
||||
return (item, player) in self.prog_items
|
||||
return self.prog_items[item, player] >= count
|
||||
|
||||
def can_buy_unlimited(self, item: str, player: int) -> bool:
|
||||
for shop in self.world.shops:
|
||||
if shop.region.player == player and shop.has_unlimited(item) and shop.region.can_reach(self):
|
||||
return True
|
||||
return False
|
||||
return any(shop.region.player == player and shop.has_unlimited(item) and shop.region.can_reach(self) for
|
||||
shop in self.world.shops)
|
||||
|
||||
def item_count(self, item, player: int) -> int:
|
||||
return self.prog_items[item, player]
|
||||
|
@ -619,9 +615,10 @@ class CollectionState(object):
|
|||
)
|
||||
|
||||
def has_sword(self, player: int) -> bool:
|
||||
return self.has('Fighter Sword', player) or self.has('Master Sword', player) or self.has('Tempered Sword',
|
||||
player) or self.has(
|
||||
'Golden Sword', player)
|
||||
return self.has('Fighter Sword', player) \
|
||||
or self.has('Master Sword', player) \
|
||||
or self.has('Tempered Sword', player) \
|
||||
or self.has('Golden Sword', player)
|
||||
|
||||
def has_beam_sword(self, player: int) -> bool:
|
||||
return self.has('Master Sword', player) or self.has('Tempered Sword', player) or self.has('Golden Sword', player)
|
||||
|
@ -1267,7 +1264,9 @@ class Spoiler(object):
|
|||
def to_file(self, filename):
|
||||
self.parse_data()
|
||||
|
||||
def bool_to_text(variable: bool) -> str:
|
||||
def bool_to_text(variable: Union[bool, str]) -> str:
|
||||
if type(variable) == str:
|
||||
return variable
|
||||
return 'Yes' if variable else 'No'
|
||||
|
||||
with open(filename, 'w', encoding="utf-8-sig") as outfile:
|
||||
|
@ -1312,7 +1311,7 @@ class Spoiler(object):
|
|||
outfile.write('Compass shuffle: %s\n' % (
|
||||
'Yes' if self.metadata['compassshuffle'][player] else 'No'))
|
||||
outfile.write(
|
||||
'Small Key shuffle: %s\n' % ('Yes' if self.metadata['keyshuffle'][player] else 'No'))
|
||||
'Small Key shuffle: %s\n' % (bool_to_text(self.metadata['keyshuffle'][player])))
|
||||
outfile.write('Big Key shuffle: %s\n' % (
|
||||
'Yes' if self.metadata['bigkeyshuffle'][player] else 'No'))
|
||||
outfile.write('Boss shuffle: %s\n' % self.metadata['boss_shuffle'][player])
|
||||
|
|
|
@ -6,7 +6,8 @@ from Items import ItemFactory
|
|||
|
||||
def create_dungeons(world, player):
|
||||
def make_dungeon(name, default_boss, dungeon_regions, big_key, small_keys, dungeon_items):
|
||||
dungeon = Dungeon(name, dungeon_regions, big_key, [] if world.retro[player] else small_keys, dungeon_items, player)
|
||||
dungeon = Dungeon(name, dungeon_regions, big_key, [] if world.keyshuffle[player] == "universal" else small_keys,
|
||||
dungeon_items, player)
|
||||
dungeon.boss = BossFactory(default_boss, player)
|
||||
for region in dungeon.regions:
|
||||
world.get_region(region, player).dungeon = dungeon
|
||||
|
|
|
@ -231,17 +231,27 @@ def parse_arguments(argv, no_defaults=False):
|
|||
--seed given will produce the same 10 (different) roms each
|
||||
time).
|
||||
''', type=int)
|
||||
parser.add_argument('--fastmenu', default=defval('normal'), const='normal', nargs='?', choices=['normal', 'instant', 'double', 'triple', 'quadruple', 'half'],
|
||||
parser.add_argument('--fastmenu', default=defval('normal'), const='normal', nargs='?',
|
||||
choices=['normal', 'instant', 'double', 'triple', 'quadruple', 'half'],
|
||||
help='''\
|
||||
Select the rate at which the menu opens and closes.
|
||||
(default: %(default)s)
|
||||
''')
|
||||
parser.add_argument('--quickswap', help='Enable quick item swapping with L and R.', action='store_true')
|
||||
parser.add_argument('--disablemusic', help='Disables game music.', action='store_true')
|
||||
parser.add_argument('--mapshuffle', default=defval(False), help='Maps are no longer restricted to their dungeons, but can be anywhere', action='store_true')
|
||||
parser.add_argument('--compassshuffle', default=defval(False), help='Compasses are no longer restricted to their dungeons, but can be anywhere', action='store_true')
|
||||
parser.add_argument('--keyshuffle', default=defval(False), help='Small Keys are no longer restricted to their dungeons, but can be anywhere', action='store_true')
|
||||
parser.add_argument('--bigkeyshuffle', default=defval(False), help='Big Keys are no longer restricted to their dungeons, but can be anywhere', action='store_true')
|
||||
parser.add_argument('--mapshuffle', default=defval(False),
|
||||
help='Maps are no longer restricted to their dungeons, but can be anywhere',
|
||||
action='store_true')
|
||||
parser.add_argument('--compassshuffle', default=defval(False),
|
||||
help='Compasses are no longer restricted to their dungeons, but can be anywhere',
|
||||
action='store_true')
|
||||
parser.add_argument('--keyshuffle', default=defval("off"), help='\
|
||||
on: Small Keys are no longer restricted to their dungeons, but can be anywhere.\
|
||||
universal: Makes all Small Keys usable in any dungeon and places shops to buy more keys.',
|
||||
choices=["on", "universal", "off"])
|
||||
parser.add_argument('--bigkeyshuffle', default=defval(False),
|
||||
help='Big Keys are no longer restricted to their dungeons, but can be anywhere',
|
||||
action='store_true')
|
||||
parser.add_argument('--keysanity', default=defval(False), help=argparse.SUPPRESS, action='store_true')
|
||||
parser.add_argument('--retro', default=defval(False), help='''\
|
||||
Keys are universal, shooting arrows costs rupees,
|
||||
|
@ -326,9 +336,13 @@ def parse_arguments(argv, no_defaults=False):
|
|||
ret.dungeon_counters = True
|
||||
elif ret.dungeon_counters == 'off':
|
||||
ret.dungeon_counters = False
|
||||
if ret.keysanity:
|
||||
ret.mapshuffle, ret.compassshuffle, ret.keyshuffle, ret.bigkeyshuffle = [True] * 4
|
||||
|
||||
if ret.keysanity:
|
||||
ret.mapshuffle = ret.compassshuffle = ret.keyshuffle = ret.bigkeyshuffle = True
|
||||
elif ret.keyshuffle == "on":
|
||||
ret.keyshuffle = True
|
||||
elif ret.keyshuffle == "off":
|
||||
ret.keyshuffle = False
|
||||
if multiargs.multi:
|
||||
defaults = copy.deepcopy(ret)
|
||||
for player in range(1, multiargs.multi + 1):
|
||||
|
|
8
Fill.py
8
Fill.py
|
@ -203,7 +203,13 @@ def fill_restrictive(world, base_state: CollectionState, locations, itempool, si
|
|||
logging.warning(
|
||||
f'Not all items placed. Game beatable anyway. (Could not place {item_to_place})')
|
||||
continue
|
||||
raise FillError(f'No more spots to place {item_to_place}, locations {locations} are invalid')
|
||||
placements = []
|
||||
for region in world.regions:
|
||||
for location in region.locations:
|
||||
if location.item and not location.event:
|
||||
placements.append(location)
|
||||
raise FillError(f'No more spots to place {item_to_place}, locations {locations} are invalid. '
|
||||
f'\nAlready placed {len(placements)}: {", ".join(placements)}')
|
||||
|
||||
world.push_item(spot_to_fill, item_to_place, False)
|
||||
locations.remove(spot_to_fill)
|
||||
|
|
21
Gui.py
21
Gui.py
|
@ -67,16 +67,27 @@ def guiMain(args=None):
|
|||
openpyramidCheckbutton = Checkbutton(checkBoxFrame, text="Pre-open Pyramid Hole", variable=openpyramidVar)
|
||||
mcsbshuffleFrame = Frame(checkBoxFrame)
|
||||
mcsbLabel = Label(mcsbshuffleFrame, text="Shuffle: ")
|
||||
|
||||
mapshuffleVar = IntVar()
|
||||
mapshuffleCheckbutton = Checkbutton(mcsbshuffleFrame, text="Maps", variable=mapshuffleVar)
|
||||
|
||||
compassshuffleVar = IntVar()
|
||||
compassshuffleCheckbutton = Checkbutton(mcsbshuffleFrame, text="Compasses", variable=compassshuffleVar)
|
||||
keyshuffleVar = IntVar()
|
||||
keyshuffleCheckbutton = Checkbutton(mcsbshuffleFrame, text="Keys", variable=keyshuffleVar)
|
||||
|
||||
bigkeyshuffleVar = IntVar()
|
||||
bigkeyshuffleCheckbutton = Checkbutton(mcsbshuffleFrame, text="BigKeys", variable=bigkeyshuffleVar)
|
||||
|
||||
keyshuffleFrame = Frame(checkBoxFrame)
|
||||
keyshuffleVar = StringVar()
|
||||
keyshuffleVar.set('off')
|
||||
modeOptionMenu = OptionMenu(keyshuffleFrame, keyshuffleVar, 'off', 'universal', 'on')
|
||||
modeOptionMenu.pack(side=LEFT)
|
||||
modeLabel = Label(keyshuffleFrame, text='Key Shuffle')
|
||||
modeLabel.pack(side=LEFT)
|
||||
|
||||
retroVar = IntVar()
|
||||
retroCheckbutton = Checkbutton(checkBoxFrame, text="Retro mode (universal keys)", variable=retroVar)
|
||||
retroCheckbutton = Checkbutton(checkBoxFrame, text="Retro mode", variable=retroVar)
|
||||
|
||||
shuffleGanonVar = IntVar()
|
||||
shuffleGanonVar.set(1) # set default
|
||||
shuffleGanonCheckbutton = Checkbutton(checkBoxFrame, text="Include Ganon's Tower and Pyramid Hole in shuffle pool",
|
||||
|
@ -99,8 +110,8 @@ def guiMain(args=None):
|
|||
mcsbLabel.grid(row=0, column=0)
|
||||
mapshuffleCheckbutton.grid(row=0, column=1)
|
||||
compassshuffleCheckbutton.grid(row=0, column=2)
|
||||
keyshuffleCheckbutton.grid(row=0, column=3)
|
||||
bigkeyshuffleCheckbutton.grid(row=0, column=4)
|
||||
keyshuffleFrame.pack(expand=True, anchor=W)
|
||||
retroCheckbutton.pack(expand=True, anchor=W)
|
||||
shuffleGanonCheckbutton.pack(expand=True, anchor=W)
|
||||
hintsCheckbutton.pack(expand=True, anchor=W)
|
||||
|
@ -476,7 +487,7 @@ def guiMain(args=None):
|
|||
guiargs.openpyramid = bool(openpyramidVar.get())
|
||||
guiargs.mapshuffle = bool(mapshuffleVar.get())
|
||||
guiargs.compassshuffle = bool(compassshuffleVar.get())
|
||||
guiargs.keyshuffle = bool(keyshuffleVar.get())
|
||||
guiargs.keyshuffle = {"on": True, "universal": "universal", "off": False}[keyshuffleVar.get()]
|
||||
guiargs.bigkeyshuffle = bool(bigkeyshuffleVar.get())
|
||||
guiargs.retro = bool(retroVar.get())
|
||||
guiargs.quickswap = bool(quickSwapVar.get())
|
||||
|
|
36
ItemPool.py
36
ItemPool.py
|
@ -43,7 +43,7 @@ Difficulty = namedtuple('Difficulty',
|
|||
['baseitems', 'bottles', 'bottle_count', 'same_bottle', 'progressiveshield',
|
||||
'basicshield', 'progressivearmor', 'basicarmor', 'swordless', 'progressivemagic', 'basicmagic',
|
||||
'progressivesword', 'basicsword', 'progressivebow', 'basicbow', 'timedohko', 'timedother',
|
||||
'triforcehunt', 'retro',
|
||||
'triforcehunt', 'universal_keys',
|
||||
'extras', 'progressive_sword_limit', 'progressive_shield_limit',
|
||||
'progressive_armor_limit', 'progressive_bottle_limit',
|
||||
'progressive_bow_limit', 'heart_piece_limit', 'boss_heart_container_limit'])
|
||||
|
@ -70,7 +70,7 @@ difficulties = {
|
|||
timedohko=['Green Clock'] * 25,
|
||||
timedother=['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt=['Triforce Piece'] * 30,
|
||||
retro=['Small Key (Universal)'] * 28,
|
||||
universal_keys=['Small Key (Universal)'] * 28,
|
||||
extras=[easyfirst15extra, easysecond15extra, easythird10extra, easyfourth5extra, easyfinal25extra],
|
||||
progressive_sword_limit=8,
|
||||
progressive_shield_limit=6,
|
||||
|
@ -99,15 +99,15 @@ difficulties = {
|
|||
timedohko=['Green Clock'] * 25,
|
||||
timedother=['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt=['Triforce Piece'] * 30,
|
||||
retro=['Small Key (Universal)'] * 18 + ['Rupees (20)'] * 10,
|
||||
universal_keys=['Small Key (Universal)'] * 18 + ['Rupees (20)'] * 10,
|
||||
extras=[normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
|
||||
progressive_sword_limit=4,
|
||||
progressive_shield_limit=3,
|
||||
progressive_armor_limit=2,
|
||||
progressive_bow_limit=2,
|
||||
progressive_bottle_limit = 4,
|
||||
boss_heart_container_limit = 10,
|
||||
heart_piece_limit = 24,
|
||||
progressive_bottle_limit=4,
|
||||
boss_heart_container_limit=10,
|
||||
heart_piece_limit=24,
|
||||
),
|
||||
'hard': Difficulty(
|
||||
baseitems = normalbaseitems,
|
||||
|
@ -128,7 +128,7 @@ difficulties = {
|
|||
timedohko=['Green Clock'] * 25,
|
||||
timedother=['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt=['Triforce Piece'] * 30,
|
||||
retro=['Small Key (Universal)'] * 12 + ['Rupees (5)'] * 16,
|
||||
universal_keys=['Small Key (Universal)'] * 12 + ['Rupees (5)'] * 16,
|
||||
extras=[normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
|
||||
progressive_sword_limit=3,
|
||||
progressive_shield_limit=2,
|
||||
|
@ -158,7 +158,7 @@ difficulties = {
|
|||
timedohko=['Green Clock'] * 20 + ['Red Clock'] * 5,
|
||||
timedother=['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
|
||||
triforcehunt=['Triforce Piece'] * 30,
|
||||
retro=['Small Key (Universal)'] * 12 + ['Rupees (5)'] * 16,
|
||||
universal_keys=['Small Key (Universal)'] * 12 + ['Rupees (5)'] * 16,
|
||||
extras=[normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
|
||||
progressive_sword_limit=2,
|
||||
progressive_shield_limit=1,
|
||||
|
@ -425,21 +425,26 @@ def fill_prizes(world, attempts=15):
|
|||
raise FillError('Unable to place dungeon prizes')
|
||||
|
||||
|
||||
def set_up_shops(world, player):
|
||||
# TODO: move hard+ mode changes for sheilds here, utilizing the new shops
|
||||
def set_up_shops(world, player: int):
|
||||
# TODO: move hard+ mode changes for shields here, utilizing the new shops
|
||||
|
||||
if world.retro[player]:
|
||||
rss = world.get_region('Red Shield Shop', player).shop
|
||||
if not rss.locked:
|
||||
rss.add_inventory(2, 'Single Arrow', 80)
|
||||
rss.locked = True
|
||||
|
||||
if world.keyshuffle[player] == "universal":
|
||||
for shop in world.random.sample([s for s in world.shops if
|
||||
s.custom and not s.locked and s.type == ShopType.Shop and s.region.player == player],
|
||||
5):
|
||||
shop.locked = True
|
||||
if world.retro[player]:
|
||||
shop.add_inventory(0, 'Single Arrow', 80)
|
||||
else:
|
||||
shop.add_inventory(0, "Red Potion", 150)
|
||||
shop.add_inventory(1, 'Small Key (Universal)', 100)
|
||||
shop.add_inventory(2, 'Bombs (10)', 50)
|
||||
rss.locked = True
|
||||
|
||||
|
||||
def get_pool_core(world, player: int):
|
||||
|
@ -592,7 +597,8 @@ def get_pool_core(world, player: int):
|
|||
pool = [item.replace('Arrows (10)', 'Rupees (5)') for item in pool]
|
||||
pool = [item.replace('Arrow Upgrade (+5)', 'Rupees (5)') for item in pool]
|
||||
pool = [item.replace('Arrow Upgrade (+10)', 'Rupees (5)') for item in pool]
|
||||
pool.extend(diff.retro)
|
||||
if world.keyshuffle[player] == "universal":
|
||||
pool.extend(diff.universal_keys)
|
||||
if mode == 'standard':
|
||||
key_location = world.random.choice(
|
||||
['Secret Passage', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest',
|
||||
|
@ -609,7 +615,6 @@ def make_custom_item_pool(world, player):
|
|||
timer = world.timer[player]
|
||||
goal = world.goal[player]
|
||||
mode = world.mode[player]
|
||||
retro = world.retro[player]
|
||||
customitemarray = world.customitemarray[player]
|
||||
|
||||
pool = []
|
||||
|
@ -726,7 +731,7 @@ def make_custom_item_pool(world, player):
|
|||
itemtotal = itemtotal + 1
|
||||
|
||||
if mode == 'standard':
|
||||
if retro:
|
||||
if world.keyshuffle == "universal":
|
||||
key_location = world.random.choice(
|
||||
['Secret Passage', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest',
|
||||
'Hyrule Castle - Zelda\'s Chest', 'Sewers - Dark Cross'])
|
||||
|
@ -749,9 +754,10 @@ def make_custom_item_pool(world, player):
|
|||
pool.extend(['Magic Mirror'] * customitemarray[22])
|
||||
pool.extend(['Moon Pearl'] * customitemarray[28])
|
||||
|
||||
if retro:
|
||||
if world.keyshuffle == "universal":
|
||||
itemtotal = itemtotal - 28 # Corrects for small keys not being in item pool in Retro Mode
|
||||
if itemtotal < total_items_to_place:
|
||||
pool.extend(['Nothing'] * (total_items_to_place - itemtotal))
|
||||
logging.warning(f"Pool was filled up with {total_items_to_place - itemtotal} Nothing's for player {player}")
|
||||
|
||||
return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon)
|
||||
|
|
|
@ -278,7 +278,8 @@ def roll_settings(weights):
|
|||
|
||||
ret.mapshuffle = get_choice('map_shuffle', weights, 'm' in dungeon_items)
|
||||
ret.compassshuffle = get_choice('compass_shuffle', weights, 'c' in dungeon_items)
|
||||
ret.keyshuffle = get_choice('smallkey_shuffle', weights, 's' in dungeon_items)
|
||||
ret.keyshuffle = get_choice('smallkey_shuffle', weights,
|
||||
'universal' if 'u' in dungeon_items else 's' in dungeon_items)
|
||||
ret.bigkeyshuffle = get_choice('bigkey_shuffle', weights, 'b' in dungeon_items)
|
||||
|
||||
ret.accessibility = get_choice('accessibility', weights)
|
||||
|
@ -309,10 +310,13 @@ def roll_settings(weights):
|
|||
ret.triforce_pieces_required = get_choice('triforce_pieces_required', weights, 20)
|
||||
ret.triforce_pieces_required = min(max(1, int(ret.triforce_pieces_required)), 90)
|
||||
|
||||
ret.mode = get_choice('world_state', weights)
|
||||
ret.mode = get_choice('world_state', weights, None) # legacy support
|
||||
if ret.mode == 'retro':
|
||||
ret.mode = 'open'
|
||||
ret.retro = True
|
||||
elif ret.mode is None:
|
||||
ret.mode = get_choice("mode", weights)
|
||||
ret.retro = get_choice("retro", weights)
|
||||
|
||||
ret.hints = get_choice('hints', weights)
|
||||
|
||||
|
|
2
Rom.py
2
Rom.py
|
@ -1237,7 +1237,7 @@ def patch_rom(world, rom, player, team, enemized):
|
|||
write_int16(rom, 0x18017A, get_reveal_bytes('Green Pendant') if world.mapshuffle[player] else 0x0000) # Sahasrahla reveal
|
||||
write_int16(rom, 0x18017C, get_reveal_bytes('Crystal 5')|get_reveal_bytes('Crystal 6') if world.mapshuffle[player] else 0x0000) # Bomb Shop Reveal
|
||||
|
||||
rom.write_byte(0x180172, 0x01 if world.retro[player] else 0x00) # universal keys
|
||||
rom.write_byte(0x180172, int(world.keyshuffle == "universal")) # universal keys
|
||||
rom.write_byte(0x180175, 0x01 if world.retro[player] else 0x00) # rupee bow
|
||||
rom.write_byte(0x180176, 0x0A if world.retro[player] else 0x00) # wood arrow cost
|
||||
rom.write_byte(0x180178, 0x32 if world.retro[player] else 0x00) # silver arrow cost
|
||||
|
|
10
Rules.py
10
Rules.py
|
@ -206,8 +206,9 @@ def global_rules(world, player):
|
|||
set_rule(world.get_location('Hookshot Cave - Bottom Left', player), lambda state: state.has('Hookshot', player))
|
||||
|
||||
set_rule(world.get_entrance('Sewers Door', player),
|
||||
lambda state: state.has_key('Small Key (Hyrule Castle)', player) or (world.retro[player] and world.mode[
|
||||
player] == 'standard')) # standard retro cannot access the shop
|
||||
lambda state: state.has_key('Small Key (Hyrule Castle)', player) or (
|
||||
world.keyshuffle[player] == "universal" and world.mode[
|
||||
player] == 'standard')) # standard universal small keys cannot access the shop
|
||||
set_rule(world.get_entrance('Sewers Back Door', player),
|
||||
lambda state: state.has_key('Small Key (Hyrule Castle)', player))
|
||||
set_rule(world.get_entrance('Agahnim 1', player),
|
||||
|
@ -896,7 +897,7 @@ def set_trock_key_rules(world, player):
|
|||
return 4
|
||||
|
||||
# If TR is only accessible from the middle, the big key must be further restricted to prevent softlock potential
|
||||
if not can_reach_front and not world.keyshuffle[player] and not world.retro[player]:
|
||||
if not can_reach_front and not world.keyshuffle[player]:
|
||||
# Must not go in the Big Key Chest - only 1 other chest available and 2+ keys required for all other chests
|
||||
forbid_item(world.get_location('Turtle Rock - Big Key Chest', player), 'Big Key (Turtle Rock)', player)
|
||||
if not can_reach_big_chest:
|
||||
|
@ -905,7 +906,8 @@ def set_trock_key_rules(world, player):
|
|||
if world.accessibility[player] == 'locations':
|
||||
if world.bigkeyshuffle[player] and can_reach_big_chest:
|
||||
# Must not go in the dungeon - all 3 available chests (Chomps, Big Chest, Crystaroller) must be keys to access laser bridge, and the big key is required first
|
||||
for location in ['Turtle Rock - Chain Chomps', 'Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left', 'Turtle Rock - Roller Room - Right']:
|
||||
for location in ['Turtle Rock - Chain Chomps', 'Turtle Rock - Compass Chest',
|
||||
'Turtle Rock - Roller Room - Left', 'Turtle Rock - Roller Room - Right']:
|
||||
forbid_item(world.get_location(location, player), 'Big Key (Turtle Rock)', player)
|
||||
else:
|
||||
# A key is required in the Big Key Chest to prevent a possible softlock. Place an extra key to ensure 100% locations still works
|
||||
|
|
|
@ -38,6 +38,7 @@ compass_shuffle: # Shuffle compasses into the world and other dungeons, includin
|
|||
off: 1
|
||||
smallkey_shuffle: # Shuffle small keys into the world and other dungeons, including other players' worlds
|
||||
on: 0
|
||||
universal: 0 # allows small keys to be used in any dungeon and adds shops to buy more
|
||||
off: 1
|
||||
bigkey_shuffle: # Shuffle big keys into the world and other dungeons, including other players' worlds
|
||||
on: 0
|
||||
|
@ -50,6 +51,8 @@ dungeon_items: # Alternative to the 4 shuffles and local_keys above this, does n
|
|||
none: 1 # Shuffle none of the 4
|
||||
mcsb: 0 # Shuffle all of the 4, any combination of m, c, s and b will shuffle the respective item, or not if it's missing, so you can add more options here
|
||||
lmcsb: 0 # Like mcsb above, but with keys kept local to your world. l is what makes your keys local, or not if it's missing
|
||||
ub: 0 # universal small keys and shuffled big keys
|
||||
# you can add more combos of these letters here
|
||||
dungeon_counters:
|
||||
on: 0 # Always display amount of items checked in a dungeon
|
||||
pickup: 1 # Show when compass is picked up
|
||||
|
@ -119,11 +122,13 @@ ganon_open: # Crystals required to hurt Ganon
|
|||
'6': 2
|
||||
'7': 1
|
||||
random: 0
|
||||
world_state:
|
||||
mode:
|
||||
standard: 1 # Begin the game by rescuing Zelda from her cell and escorting her to the Sanctuary
|
||||
open: 1 # Begin the game from your choice of Link's House or the Sanctuary
|
||||
inverted: 0 # Begin in the Dark World. The Moon Pearl is required to avoid bunny-state in Light World, and the Light World game map is altered
|
||||
retro: 0 # Small keys are universal, you must buy a quiver, take-any caves and an old-man cave are added to the world. You may need to find your sword from the old man's cave
|
||||
retro:
|
||||
on: 0 # you must buy a quiver to use the bow, take-any caves and an old-man cave are added to the world. You may need to find your sword from the old man's cave
|
||||
off: 1
|
||||
hints:
|
||||
'on': 1 # Hint tiles sometimes give item location hints
|
||||
'off': 0 # Hint tiles provide gameplay tips
|
||||
|
|
Loading…
Reference in New Issue