New restricted shuffle

This implements the new restricted shuffle that does not respect the difference between single and multi-entrance caves. Restricted_legacy is present for the old restricted behavior. Full_cross_worlds is renamed to Crossed, and all listing of shuffles is given a consistent order that pushes all the _legacy variants to the back.
This commit is contained in:
AmazingAmpharos 2018-02-20 14:34:39 -06:00 committed by GitHub
parent 5f07fdceef
commit deccff249b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 99 additions and 33 deletions

View File

@ -268,7 +268,7 @@ class World(object):
marksequence(['standard', 'open', 'swordless'], self.mode)
markbool(self.place_dungeon_items)
marksequence(['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'], self.goal)
marksequence(['vanilla', 'simple', 'restricted', 'full', 'full_cross_worlds', 'full_legacy','insanity_legacy', 'madness_legacy', 'insanity', 'dungeonsfull', 'dungeonssimple'], self.shuffle)
marksequence(['vanilla', 'simple', 'restricted', 'full', 'crossed', 'insanity', 'restricted_legacy', 'full_legacy', 'madness_legacy', 'insanity_legacy', 'dungeonsfull', 'dungeonssimple'], self.shuffle)
marksequence(['easy', 'normal', 'hard', 'expert', 'insane'], self.difficulty)
marksequence(['none', 'display', 'timed', 'timed-ohko', 'timed-countdown', 'ohko'], self.timer)
marksequence(['on', 'off', 'random'], self.progressive)

View File

@ -120,25 +120,27 @@ def start():
slightly biased to placing progression items with
less restrictions.
''')
parser.add_argument('--shuffle', default='full', const='full', nargs='?', choices=['vanilla', 'simple', 'restricted', 'full','full_cross_worlds','full_legacy', 'insanity_legacy', 'madness_legacy', 'insanity', 'dungeonsfull', 'dungeonssimple'],
parser.add_argument('--shuffle', default='full', const='full', nargs='?', choices=['vanilla', 'simple', 'restricted', 'full', 'crossed', 'insanity', 'restricted_legacy', 'full_legacy', 'madness_legacy', 'insanity_legacy', 'dungeonsfull', 'dungeonssimple'],
help='''\
Select Entrance Shuffling Algorithm. (default: %(default)s)
Full: Mix cave and dungeon entrances freely.
Full: Mix cave and dungeon entrances freely while limiting
multi-entrance caves to one world.
Simple: Shuffle Dungeon Entrances/Exits between each other
and keep all 4-entrance dungeons confined to one
location. All caves outside of death mountain are
shuffled in pairs.
shuffled in pairs and matched by original type.
Restricted: Use Dungeons shuffling from Simple but freely
connect remaining entrances.
Madness: Decouple entrances and exits from each other and
shuffle them freely, only ensuring that no fake
Light/Dark World happens and all locations are
reachable.
Insanity: Madness without the world restrictions. Mirror and
Pearl are provided early to ensure Filling algorithm
works properly. Deal with Fake LW/DW at your
discretion.
Experimental.
Crossed: Mix cave and dungeon entrances freely while allowing
caves to cross between worlds.
Insanity: Decouple entrances and exits from each other and
shuffle them freely. Caves that used to be single
entrance will still exit to the same location from
which they are entered.
Vanilla: All entrances are in the same locations they were
in the base game.
Legacy shuffles preserve behavior from older versions of the
entrance randomizer including significant technical limitations.
The dungeon variants only mix up dungeons and keep the rest of
the overworld vanilla.
''')

View File

@ -121,12 +121,79 @@ def link_entrances(world):
# place remaining doors
connect_doors(world, single_doors, door_targets)
elif world.shuffle == 'new_restricted':
# TODO
raise NotImplementedError()
elif world.shuffle == 'restricted':
simple_shuffle_dungeons(world)
lw_entrances = list(LW_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances)
dw_entrances = list(DW_Entrances + DW_Single_Cave_Doors)
dw_must_exits = list(DW_Entrances_Must_Exit)
old_man_entrances = list(Old_Man_Entrances)
caves = list(Cave_Exits + Cave_Three_Exits)
single_doors = list(Single_Cave_Doors)
bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors + Bomb_Shop_Multi_Cave_Doors)
blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors)
door_targets = list(Single_Cave_Targets)
# tavern back door cannot be shuffled yet
connect_doors(world, ['Tavern North'], ['Tavern'])
# in restricted, the only mandatory exits are in dark world
connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits)
# place old man, has limited options
# exit has to come from specific set of doors, the entrance is free to move about
old_man_entrances = [door for door in old_man_entrances if door in lw_entrances]
random.shuffle(old_man_entrances)
old_man_exit = old_man_entrances.pop()
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)')
lw_entrances.remove(old_man_exit)
# place blacksmith, has limited options
all_entrances = lw_entrances + dw_entrances
# cannot place it anywhere already taken (or that are otherwise not eligable for placement)
blacksmith_doors = [door for door in blacksmith_doors if door in all_entrances]
random.shuffle(blacksmith_doors)
blacksmith_hut = blacksmith_doors.pop()
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut')
if blacksmith_hut in lw_entrances:
lw_entrances.remove(blacksmith_hut)
if blacksmith_hut in dw_entrances:
dw_entrances.remove(blacksmith_hut)
bomb_shop_doors.extend(blacksmith_doors)
# place dam and pyramid fairy, have limited options
all_entrances = lw_entrances + dw_entrances
# cannot place it anywhere already taken (or that are otherwise not eligable for placement)
bomb_shop_doors = [door for door in bomb_shop_doors if door in all_entrances]
random.shuffle(bomb_shop_doors)
bomb_shop = bomb_shop_doors.pop()
connect_entrance(world, bomb_shop, 'Big Bomb Shop')
if bomb_shop in lw_entrances:
lw_entrances.remove(bomb_shop)
if bomb_shop in dw_entrances:
dw_entrances.remove(bomb_shop)
# place the old man cave's entrance somewhere in the light world
random.shuffle(lw_entrances)
old_man_entrance = lw_entrances.pop()
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)')
# place Old Man House in Light World, so using the s&q point does not cause fake dark world
connect_caves(world, lw_entrances, [], [('Old Man House Exit (Bottom)', 'Old Man House Exit (Top)')])
# now scramble the rest
connect_caves(world, lw_entrances, dw_entrances, caves)
# scramble holes
scramble_holes(world)
doors = lw_entrances + dw_entrances
# place remaining doors
connect_doors(world, doors, door_targets)
elif world.shuffle == 'restricted_legacy':
simple_shuffle_dungeons(world)
lw_entrances = list(LW_Entrances)
dw_entrances = list(DW_Entrances)
dw_must_exits = list(DW_Entrances_Must_Exit)
@ -271,7 +338,7 @@ def link_entrances(world):
# place remaining doors
connect_doors(world, doors, door_targets)
elif world.shuffle == 'full_cross_worlds':
elif world.shuffle == 'crossed':
skull_woods_shuffle(world)
entrances = list(LW_Entrances + LW_Dungeon_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances + DW_Entrances + DW_Dungeon_Entrances + DW_Single_Cave_Doors)

2
Gui.py
View File

@ -194,7 +194,7 @@ def guiMain(args=None):
shuffleFrame = Frame(drowDownFrame)
shuffleVar = StringVar()
shuffleVar.set('full')
shuffleOptionMenu = OptionMenu(shuffleFrame, shuffleVar, 'vanilla', 'simple', 'restricted', 'full', 'full_cross_worlds', 'full_legacy', 'insanity', 'madness_legacy', 'insanity_legacy', 'dungeonsfull', 'dungeonssimple')
shuffleOptionMenu = OptionMenu(shuffleFrame, shuffleVar, 'vanilla', 'simple', 'restricted', 'full', 'crossed', 'insanity', 'restricted_legacy', 'full_legacy', 'madness_legacy', 'insanity_legacy', 'dungeonsfull', 'dungeonssimple')
shuffleOptionMenu.pack(side=RIGHT)
shuffleLabel = Label(shuffleFrame, text='Entrance shuffle algorithm')
shuffleLabel.pack(side=LEFT)

View File

@ -209,29 +209,26 @@ Is the Vanilla layout.
Shuffles Dungeon Entrances/Exits between each other and keeps all 4-entrance dungeons confined to one location. Outside Light World Death Mountain, interiors are shuffled but still connect the same points
on the overworld. On Death Mountain, entrances are connected more freely.
### Full
Mixes cave and dungeon entrances freely. Caves and dungeons with multiple entrances will be confined to one world.
### Full_Cross_Worlds
Mixes cave and dungeon entrances freely, but now connector caves and dungeons can link Light World and Dark World.
### Full_Legacy
Mixes cave and dungeon entrances freely, but the distinction between single entrance and multi-entrance caves from older versions of the randomizer is maintained.
### Restricted
Uses Dungeons shuffling from Simple but freely connects remaining entrances.
### Madness
### Full
Decouples entrances and exits from each other and shuffles them freely, only ensuring that no fake Light/Dark World happens and all locations are reachable.
Mixes cave and dungeon entrances freely. Caves and dungeons with multiple entrances will be confined to one world.
### Crossed
Mixes cave and dungeon entrances freely, but now connector caves and dungeons can link Light World and Dark World.
### Insanity
Madness, but without the light/dark world restrictions. Gives access to Mirror and Moon Pearl from the start.
Decouples entrances and exits from each other and shuffles them freely. Caves that were single entrance in vanilla still can only exit to the same location from which they were entered.
### Legacy Variants
Similar to the base shuffles, but the distinction between single entrance and multi-entrance caves from older versions of the randomizer is maintained.
Madness_Legacy is the more similar to the modern Insanity. Insanity_Legacy has fake worlds and guaranteed Moon Pearl and Magic Mirror for a very different experience.
### Dungeon Variants