implement secrets.SystemRandom() for --race
This commit is contained in:
parent
59a71dbb05
commit
93ecf5988b
|
@ -10,6 +10,10 @@ from EntranceShuffle import door_addresses, indirect_connections
|
|||
from Utils import int16_as_bytes
|
||||
from typing import Union
|
||||
|
||||
import secrets
|
||||
import random
|
||||
|
||||
|
||||
class World(object):
|
||||
debug_types = False
|
||||
player_names: list
|
||||
|
@ -28,6 +32,8 @@ class World(object):
|
|||
setattr(self, name[7:], method)
|
||||
logging.debug(f"Set {self}.{name[7:]} to {method}")
|
||||
self.get_location = self._debug_get_location
|
||||
self.random = random.Random() # world-local random state is saved in case of future use a
|
||||
# persistently running program with multiple worlds rolling concurrently
|
||||
self.players = players
|
||||
self.teams = 1
|
||||
self.shuffle = shuffle.copy()
|
||||
|
@ -116,6 +122,9 @@ class World(object):
|
|||
set_player_attr('triforce_pieces_available', 30)
|
||||
set_player_attr('triforce_pieces_required', 20)
|
||||
|
||||
def secure(self):
|
||||
self.random = secrets.SystemRandom()
|
||||
|
||||
@property
|
||||
def player_ids(self):
|
||||
yield from range(1, self.players + 1)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import logging
|
||||
import random
|
||||
|
||||
from BaseClasses import Boss
|
||||
from Fill import FillError
|
||||
|
@ -193,11 +192,11 @@ def place_bosses(world, player):
|
|||
if world.boss_shuffle[player] == "basic": # vanilla bosses shuffled
|
||||
bosses = placeable_bosses + ['Armos Knights', 'Lanmolas', 'Moldorm']
|
||||
else: # all bosses present, the three duplicates chosen at random
|
||||
bosses = all_bosses + [random.choice(placeable_bosses) for _ in range(3)]
|
||||
bosses = all_bosses + [world.random.choice(placeable_bosses) for _ in range(3)]
|
||||
|
||||
logging.getLogger('').debug('Bosses chosen %s', bosses)
|
||||
|
||||
random.shuffle(bosses)
|
||||
world.random.shuffle(bosses)
|
||||
for [loc, level] in boss_locations:
|
||||
loc_text = loc + (' ('+level+')' if level else '')
|
||||
boss = next((b for b in bosses if can_place_boss(world, player, b, loc, level)), None)
|
||||
|
@ -211,7 +210,8 @@ def place_bosses(world, player):
|
|||
for [loc, level] in boss_locations:
|
||||
loc_text = loc + (' ('+level+')' if level else '')
|
||||
try:
|
||||
boss = random.choice([b for b in placeable_bosses if can_place_boss(world, player, b, loc, level)])
|
||||
boss = world.random.choice(
|
||||
[b for b in placeable_bosses if can_place_boss(world, player, b, loc, level)])
|
||||
except IndexError:
|
||||
raise FillError('Could not place boss for location %s' % loc_text)
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import random
|
||||
|
||||
from BaseClasses import Dungeon
|
||||
from Bosses import BossFactory
|
||||
from Fill import fill_restrictive
|
||||
|
@ -58,7 +56,7 @@ def fill_dungeons(world):
|
|||
dungeon_regions, big_key, small_keys, dungeon_items = dungeons.pop(0)
|
||||
# this is what we need to fill
|
||||
dungeon_locations = [location for location in world.get_unfilled_locations() if location.parent_region.name in dungeon_regions]
|
||||
random.shuffle(dungeon_locations)
|
||||
world.random.shuffle(dungeon_locations)
|
||||
|
||||
all_state = all_state_base.copy()
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ import argparse
|
|||
import copy
|
||||
import os
|
||||
import logging
|
||||
import random
|
||||
import textwrap
|
||||
import shlex
|
||||
import sys
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import random
|
||||
|
||||
# ToDo: With shuffle_ganon option, prevent gtower from linking to an exit only location through a 2 entrance cave.
|
||||
from collections import defaultdict
|
||||
|
||||
|
@ -13,7 +11,7 @@ def link_entrances(world, player):
|
|||
Old_Man_House = Old_Man_House_Base.copy()
|
||||
Cave_Three_Exits = Cave_Three_Exits_Base.copy()
|
||||
|
||||
unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits)
|
||||
unbias_some_entrances(world, Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits)
|
||||
|
||||
# setup mandatory connections
|
||||
for exitname, regionname in mandatory_connections:
|
||||
|
@ -75,8 +73,8 @@ def link_entrances(world, player):
|
|||
# we shuffle all 2 entrance caves as pairs as a start
|
||||
# start with the ones that need to be directed
|
||||
two_door_caves = list(Two_Door_Caves_Directional)
|
||||
random.shuffle(two_door_caves)
|
||||
random.shuffle(caves)
|
||||
world.random.shuffle(two_door_caves)
|
||||
world.random.shuffle(caves)
|
||||
while two_door_caves:
|
||||
entrance1, entrance2 = two_door_caves.pop()
|
||||
exit1, exit2 = caves.pop()
|
||||
|
@ -85,7 +83,7 @@ def link_entrances(world, player):
|
|||
|
||||
# now the remaining pairs
|
||||
two_door_caves = list(Two_Door_Caves)
|
||||
random.shuffle(two_door_caves)
|
||||
world.random.shuffle(two_door_caves)
|
||||
while two_door_caves:
|
||||
entrance1, entrance2 = two_door_caves.pop()
|
||||
exit1, exit2 = caves.pop()
|
||||
|
@ -96,10 +94,10 @@ def link_entrances(world, player):
|
|||
# place old man, has limited options
|
||||
remaining_entrances = ['Old Man Cave (West)', 'Old Man House (Bottom)', 'Death Mountain Return Cave (West)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)',
|
||||
'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)']
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
remaining_entrances.extend(old_man_entrances)
|
||||
random.shuffle(remaining_entrances)
|
||||
world.random.shuffle(remaining_entrances)
|
||||
old_man_entrance = remaining_entrances.pop()
|
||||
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
|
@ -115,13 +113,13 @@ def link_entrances(world, player):
|
|||
scramble_holes(world, player)
|
||||
|
||||
# place blacksmith, has limited options
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
bomb_shop_doors.extend(blacksmith_doors)
|
||||
|
||||
# place bomb shop, has limited options
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
single_doors.extend(bomb_shop_doors)
|
||||
|
@ -153,7 +151,7 @@ def link_entrances(world, player):
|
|||
# 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)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
lw_entrances.remove(old_man_exit)
|
||||
|
@ -162,7 +160,7 @@ def link_entrances(world, player):
|
|||
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)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
if blacksmith_hut in lw_entrances:
|
||||
|
@ -175,7 +173,7 @@ def link_entrances(world, player):
|
|||
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)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
if bomb_shop in lw_entrances:
|
||||
|
@ -184,7 +182,7 @@ def link_entrances(world, player):
|
|||
dw_entrances.remove(bomb_shop)
|
||||
|
||||
# place the old man cave's entrance somewhere in the light world
|
||||
random.shuffle(lw_entrances)
|
||||
world.random.shuffle(lw_entrances)
|
||||
old_man_entrance = lw_entrances.pop()
|
||||
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
|
||||
|
||||
|
@ -223,10 +221,10 @@ def link_entrances(world, player):
|
|||
|
||||
# place old man, has limited options
|
||||
# exit has to come from specific set of doors, the entrance is free to move about
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
lw_entrances.extend(old_man_entrances)
|
||||
random.shuffle(lw_entrances)
|
||||
world.random.shuffle(lw_entrances)
|
||||
old_man_entrance = lw_entrances.pop()
|
||||
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
|
@ -241,13 +239,13 @@ def link_entrances(world, player):
|
|||
scramble_holes(world, player)
|
||||
|
||||
# place blacksmith, has limited options
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
bomb_shop_doors.extend(blacksmith_doors)
|
||||
|
||||
# place dam and pyramid fairy, have limited options
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
single_doors.extend(bomb_shop_doors)
|
||||
|
@ -278,7 +276,8 @@ def link_entrances(world, player):
|
|||
# must connect front of hyrule castle to do escape
|
||||
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
else:
|
||||
caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3)))
|
||||
caves.append(tuple(world.random.sample(
|
||||
['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3)))
|
||||
lw_entrances.append('Hyrule Castle Entrance (South)')
|
||||
|
||||
if not world.shuffle_ganon:
|
||||
|
@ -290,7 +289,7 @@ def link_entrances(world, player):
|
|||
|
||||
# we randomize which world requirements we fulfill first so we get better dungeon distribution
|
||||
#we also places the Old Man House at this time to make sure he can be connected to the desert one way
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
caves += old_man_house
|
||||
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player)
|
||||
try:
|
||||
|
@ -317,7 +316,7 @@ def link_entrances(world, player):
|
|||
# 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)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
lw_entrances.remove(old_man_exit)
|
||||
|
@ -326,7 +325,7 @@ def link_entrances(world, player):
|
|||
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)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
if blacksmith_hut in lw_entrances:
|
||||
|
@ -339,7 +338,7 @@ def link_entrances(world, player):
|
|||
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)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
if bomb_shop in lw_entrances:
|
||||
|
@ -381,7 +380,8 @@ def link_entrances(world, player):
|
|||
# must connect front of hyrule castle to do escape
|
||||
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
else:
|
||||
caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3)))
|
||||
caves.append(tuple(world.random.sample(
|
||||
['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3)))
|
||||
entrances.append('Hyrule Castle Entrance (South)')
|
||||
|
||||
if not world.shuffle_ganon:
|
||||
|
@ -400,7 +400,7 @@ def link_entrances(world, player):
|
|||
# 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 entrances]
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
entrances.remove(old_man_exit)
|
||||
|
@ -408,7 +408,7 @@ def link_entrances(world, player):
|
|||
# place blacksmith, has limited options
|
||||
# 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 entrances]
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
entrances.remove(blacksmith_hut)
|
||||
|
@ -418,14 +418,14 @@ def link_entrances(world, player):
|
|||
|
||||
# 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 entrances]
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
entrances.remove(bomb_shop)
|
||||
|
||||
|
||||
# place the old man cave's entrance somewhere
|
||||
random.shuffle(entrances)
|
||||
world.random.shuffle(entrances)
|
||||
old_man_entrance = entrances.pop()
|
||||
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
|
||||
|
||||
|
@ -456,7 +456,8 @@ def link_entrances(world, player):
|
|||
# must connect front of hyrule castle to do escape
|
||||
connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player)
|
||||
else:
|
||||
caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3)))
|
||||
caves.append(tuple(world.random.sample(
|
||||
['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3)))
|
||||
lw_entrances.append('Hyrule Castle Entrance (South)')
|
||||
|
||||
if not world.shuffle_ganon:
|
||||
|
@ -466,7 +467,7 @@ def link_entrances(world, player):
|
|||
caves.append('Ganons Tower Exit')
|
||||
|
||||
# we randomize which world requirements we fulfill first so we get better dungeon distribution
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player)
|
||||
connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player)
|
||||
else:
|
||||
|
@ -479,11 +480,11 @@ def link_entrances(world, player):
|
|||
# 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)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
lw_entrances.remove(old_man_exit)
|
||||
|
||||
random.shuffle(lw_entrances)
|
||||
world.random.shuffle(lw_entrances)
|
||||
old_man_entrance = lw_entrances.pop()
|
||||
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
|
@ -498,13 +499,13 @@ def link_entrances(world, player):
|
|||
scramble_holes(world, player)
|
||||
|
||||
# place blacksmith, has limited options
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
bomb_shop_doors.extend(blacksmith_doors)
|
||||
|
||||
# place bomb shop, has limited options
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
single_doors.extend(bomb_shop_doors)
|
||||
|
@ -520,18 +521,28 @@ def link_entrances(world, player):
|
|||
dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances)
|
||||
dw_entrances_must_exits = list(DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit)
|
||||
|
||||
lw_doors = list(LW_Entrances + LW_Dungeon_Entrances + LW_Dungeon_Entrances_Must_Exit) + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump',
|
||||
'Lumberjack Tree Cave'] + list(Old_Man_Entrances)
|
||||
dw_doors = list(DW_Entrances + DW_Dungeon_Entrances + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit) + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)']
|
||||
lw_doors = list(LW_Entrances + LW_Dungeon_Entrances + LW_Dungeon_Entrances_Must_Exit) + ['Kakariko Well Cave',
|
||||
'Bat Cave Cave',
|
||||
'North Fairy Cave',
|
||||
'Sanctuary',
|
||||
'Lost Woods Hideout Stump',
|
||||
'Lumberjack Tree Cave'] + list(
|
||||
Old_Man_Entrances)
|
||||
dw_doors = list(
|
||||
DW_Entrances + DW_Dungeon_Entrances + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit) + [
|
||||
'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)',
|
||||
'Skull Woods Second Section Door (West)']
|
||||
|
||||
random.shuffle(lw_doors)
|
||||
random.shuffle(dw_doors)
|
||||
world.random.shuffle(lw_doors)
|
||||
world.random.shuffle(dw_doors)
|
||||
|
||||
dw_entrances_must_exits.append('Skull Woods Second Section Door (West)')
|
||||
dw_entrances.append('Skull Woods Second Section Door (East)')
|
||||
dw_entrances.append('Skull Woods First Section Door')
|
||||
|
||||
lw_entrances.extend(['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave'])
|
||||
lw_entrances.extend(
|
||||
['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump',
|
||||
'Lumberjack Tree Cave'])
|
||||
|
||||
lw_entrances_must_exits = list(LW_Dungeon_Entrances_Must_Exit)
|
||||
|
||||
|
@ -576,19 +587,20 @@ def link_entrances(world, player):
|
|||
dw_entrances_must_exits.append('Pyramid Entrance')
|
||||
dw_doors.extend(['Ganons Tower', 'Pyramid Entrance'])
|
||||
|
||||
random.shuffle(lw_hole_entrances)
|
||||
random.shuffle(dw_hole_entrances)
|
||||
random.shuffle(hole_targets)
|
||||
world.random.shuffle(lw_hole_entrances)
|
||||
world.random.shuffle(dw_hole_entrances)
|
||||
world.random.shuffle(hole_targets)
|
||||
|
||||
# decide if skull woods first section should be in light or dark world
|
||||
sw_light = random.randint(0, 1) == 0
|
||||
sw_light = world.random.randint(0, 1) == 0
|
||||
if sw_light:
|
||||
sw_hole_pool = lw_hole_entrances
|
||||
mandatory_light_world.append('Skull Woods First Section Exit')
|
||||
else:
|
||||
sw_hole_pool = dw_hole_entrances
|
||||
mandatory_dark_world.append('Skull Woods First Section Exit')
|
||||
for target in ['Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)']:
|
||||
for target in ['Skull Woods First Section (Left)', 'Skull Woods First Section (Right)',
|
||||
'Skull Woods First Section (Top)']:
|
||||
connect_entrance(world, sw_hole_pool.pop(), target, player)
|
||||
|
||||
# sanctuary has to be in light world
|
||||
|
@ -619,7 +631,7 @@ def link_entrances(world, player):
|
|||
|
||||
# now let's deal with mandatory reachable stuff
|
||||
def extract_reachable_exit(cavelist):
|
||||
random.shuffle(cavelist)
|
||||
world.random.shuffle(cavelist)
|
||||
candidate = None
|
||||
for cave in cavelist:
|
||||
if isinstance(cave, tuple) and len(cave) > 1:
|
||||
|
@ -636,7 +648,7 @@ def link_entrances(world, player):
|
|||
|
||||
def connect_reachable_exit(entrance, general, worldspecific, worldoors):
|
||||
# select which one is the primary option
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
primary = general
|
||||
secondary = worldspecific
|
||||
else:
|
||||
|
@ -656,7 +668,7 @@ def link_entrances(world, player):
|
|||
worldspecific.append(cave)
|
||||
|
||||
# we randomize which world requirements we fulfill first so we get better dungeon distribution
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
for entrance in lw_entrances_must_exits:
|
||||
connect_reachable_exit(entrance, caves, mandatory_light_world, lw_doors)
|
||||
for entrance in dw_entrances_must_exits:
|
||||
|
@ -670,7 +682,7 @@ def link_entrances(world, player):
|
|||
# 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 = [entrance for entrance in old_man_entrances if entrance in lw_entrances]
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
lw_entrances.remove(old_man_exit)
|
||||
|
||||
|
@ -708,7 +720,7 @@ def link_entrances(world, player):
|
|||
cave_candidate = (i, len(cave))
|
||||
cave = caves.pop(cave_candidate[0])
|
||||
|
||||
place_lightworld = random.randint(0, 1) == 0
|
||||
place_lightworld = world.random.randint(0, 1) == 0
|
||||
if place_lightworld:
|
||||
target_doors = lw_doors
|
||||
target_entrances = lw_entrances
|
||||
|
@ -740,13 +752,13 @@ def link_entrances(world, player):
|
|||
door_targets = list(Single_Cave_Targets)
|
||||
|
||||
# place blacksmith, has limited options
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
bomb_shop_doors.extend(blacksmith_doors)
|
||||
|
||||
# place dam and pyramid fairy, have limited options
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
single_doors.extend(bomb_shop_doors)
|
||||
|
@ -774,7 +786,7 @@ def link_entrances(world, player):
|
|||
blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Blacksmith_Multi_Cave_Doors)
|
||||
door_targets = list(Single_Cave_Targets)
|
||||
|
||||
random.shuffle(doors)
|
||||
world.random.shuffle(doors)
|
||||
|
||||
old_man_entrances = list(Old_Man_Entrances) + ['Tower of Hera']
|
||||
|
||||
|
@ -817,9 +829,9 @@ def link_entrances(world, player):
|
|||
entrances_must_exits.append('Pyramid Entrance')
|
||||
doors.extend(['Ganons Tower', 'Pyramid Entrance'])
|
||||
|
||||
random.shuffle(hole_entrances)
|
||||
random.shuffle(hole_targets)
|
||||
random.shuffle(entrances)
|
||||
world.random.shuffle(hole_entrances)
|
||||
world.random.shuffle(hole_targets)
|
||||
world.random.shuffle(entrances)
|
||||
|
||||
# fill up holes
|
||||
for hole in hole_entrances:
|
||||
|
@ -838,7 +850,7 @@ def link_entrances(world, player):
|
|||
|
||||
# now let's deal with mandatory reachable stuff
|
||||
def extract_reachable_exit(cavelist):
|
||||
random.shuffle(cavelist)
|
||||
world.random.shuffle(cavelist)
|
||||
candidate = None
|
||||
for cave in cavelist:
|
||||
if isinstance(cave, tuple) and len(cave) > 1:
|
||||
|
@ -870,7 +882,7 @@ def link_entrances(world, player):
|
|||
# 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 = [entrance for entrance in old_man_entrances if entrance in entrances]
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
entrances.remove(old_man_exit)
|
||||
|
||||
|
@ -880,14 +892,14 @@ def link_entrances(world, player):
|
|||
|
||||
# place blacksmith, has limited options
|
||||
blacksmith_doors = [door for door in blacksmith_doors if door in doors]
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
doors.remove(blacksmith_hut)
|
||||
|
||||
# place dam and pyramid fairy, have limited options
|
||||
bomb_shop_doors = [door for door in bomb_shop_doors if door in doors]
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
doors.remove(bomb_shop)
|
||||
|
@ -913,7 +925,7 @@ def link_entrances(world, player):
|
|||
doors = LW_Entrances + LW_Dungeon_Entrances + LW_Dungeon_Entrances_Must_Exit + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave'] + Old_Man_Entrances +\
|
||||
DW_Entrances + DW_Dungeon_Entrances + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)']
|
||||
|
||||
random.shuffle(doors)
|
||||
world.random.shuffle(doors)
|
||||
|
||||
old_man_entrances = list(Old_Man_Entrances) + ['Tower of Hera']
|
||||
|
||||
|
@ -952,9 +964,9 @@ def link_entrances(world, player):
|
|||
entrances_must_exits.append('Pyramid Entrance')
|
||||
doors.extend(['Ganons Tower', 'Pyramid Entrance'])
|
||||
|
||||
random.shuffle(hole_entrances)
|
||||
random.shuffle(hole_targets)
|
||||
random.shuffle(entrances)
|
||||
world.random.shuffle(hole_entrances)
|
||||
world.random.shuffle(hole_targets)
|
||||
world.random.shuffle(entrances)
|
||||
|
||||
# fill up holes
|
||||
for hole in hole_entrances:
|
||||
|
@ -973,7 +985,7 @@ def link_entrances(world, player):
|
|||
|
||||
# now let's deal with mandatory reachable stuff
|
||||
def extract_reachable_exit(cavelist):
|
||||
random.shuffle(cavelist)
|
||||
world.random.shuffle(cavelist)
|
||||
candidate = None
|
||||
for cave in cavelist:
|
||||
if isinstance(cave, tuple) and len(cave) > 1:
|
||||
|
@ -1005,7 +1017,7 @@ def link_entrances(world, player):
|
|||
# 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 = [entrance for entrance in old_man_entrances if entrance in entrances]
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
entrances.remove(old_man_exit)
|
||||
|
||||
|
@ -1030,13 +1042,13 @@ def link_entrances(world, player):
|
|||
door_targets = list(Single_Cave_Targets)
|
||||
|
||||
# place blacksmith, has limited options
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
bomb_shop_doors.extend(blacksmith_doors)
|
||||
|
||||
# place dam and pyramid fairy, have limited options
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||
single_doors.extend(bomb_shop_doors)
|
||||
|
@ -1073,7 +1085,7 @@ def link_inverted_entrances(world, player):
|
|||
Old_Man_House = Old_Man_House_Base.copy()
|
||||
Cave_Three_Exits = Cave_Three_Exits_Base.copy()
|
||||
|
||||
unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits)
|
||||
unbias_some_entrances(world, Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits)
|
||||
|
||||
# setup mandatory connections
|
||||
for exitname, regionname in inverted_mandatory_connections:
|
||||
|
@ -1102,7 +1114,7 @@ def link_inverted_entrances(world, player):
|
|||
dw_entrances = list(Inverted_DW_Dungeon_Entrances)
|
||||
|
||||
# randomize which desert ledge door is a must-exit
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
lw_dungeon_entrances_must_exit.append('Desert Palace Entrance (North)')
|
||||
lw_entrances.append('Desert Palace Entrance (West)')
|
||||
else:
|
||||
|
@ -1123,14 +1135,14 @@ def link_inverted_entrances(world, player):
|
|||
# shuffle aga door first. If it's on HC ledge, remaining HC ledge door must be must-exit
|
||||
all_entrances_aga = lw_entrances + dw_entrances
|
||||
aga_doors = [i for i in all_entrances_aga]
|
||||
random.shuffle(aga_doors)
|
||||
world.random.shuffle(aga_doors)
|
||||
aga_door = aga_doors.pop()
|
||||
|
||||
if aga_door in hc_ledge_entrances:
|
||||
lw_entrances.remove(aga_door)
|
||||
hc_ledge_entrances.remove(aga_door)
|
||||
|
||||
random.shuffle(hc_ledge_entrances)
|
||||
world.random.shuffle(hc_ledge_entrances)
|
||||
hc_ledge_must_exit = hc_ledge_entrances.pop()
|
||||
lw_entrances.remove(hc_ledge_must_exit)
|
||||
lw_dungeon_entrances_must_exit.append(hc_ledge_must_exit)
|
||||
|
@ -1162,8 +1174,8 @@ def link_inverted_entrances(world, player):
|
|||
# we shuffle all 2 entrance caves as pairs as a start
|
||||
# start with the ones that need to be directed
|
||||
two_door_caves = list(Inverted_Two_Door_Caves_Directional)
|
||||
random.shuffle(two_door_caves)
|
||||
random.shuffle(caves)
|
||||
world.random.shuffle(two_door_caves)
|
||||
world.random.shuffle(caves)
|
||||
while two_door_caves:
|
||||
entrance1, entrance2 = two_door_caves.pop()
|
||||
exit1, exit2 = caves.pop()
|
||||
|
@ -1172,7 +1184,7 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# now the remaining pairs
|
||||
two_door_caves = list(Inverted_Two_Door_Caves)
|
||||
random.shuffle(two_door_caves)
|
||||
world.random.shuffle(two_door_caves)
|
||||
while two_door_caves:
|
||||
entrance1, entrance2 = two_door_caves.pop()
|
||||
exit1, exit2 = caves.pop()
|
||||
|
@ -1180,8 +1192,9 @@ def link_inverted_entrances(world, player):
|
|||
connect_two_way(world, entrance2, exit2, player)
|
||||
|
||||
# place links house
|
||||
links_house_doors = [i for i in bomb_shop_doors + blacksmith_doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = random.choice(list(links_house_doors))
|
||||
links_house_doors = [i for i in bomb_shop_doors + blacksmith_doors if
|
||||
i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = world.random.choice(list(links_house_doors))
|
||||
connect_two_way(world, links_house, 'Inverted Links House Exit', player)
|
||||
if links_house in bomb_shop_doors:
|
||||
bomb_shop_doors.remove(links_house)
|
||||
|
@ -1192,7 +1205,7 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# place dark sanc
|
||||
sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in bomb_shop_doors]
|
||||
sanc_door = random.choice(sanc_doors)
|
||||
sanc_door = world.random.choice(sanc_doors)
|
||||
bomb_shop_doors.remove(sanc_door)
|
||||
|
||||
connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player)
|
||||
|
@ -1205,7 +1218,7 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# place old man, bumper cave bottom to DDM entrances not in east bottom
|
||||
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
connect_two_way(world, 'Bumper Cave (Bottom)', 'Old Man Cave Exit (West)', player)
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
|
@ -1225,14 +1238,14 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# place blacksmith, has limited options
|
||||
blacksmith_doors = [door for door in blacksmith_doors[:]]
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
bomb_shop_doors.extend(blacksmith_doors)
|
||||
|
||||
# place bomb shop, has limited options
|
||||
bomb_shop_doors = [door for door in bomb_shop_doors[:]]
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player)
|
||||
single_doors.extend(bomb_shop_doors)
|
||||
|
@ -1257,8 +1270,9 @@ def link_inverted_entrances(world, player):
|
|||
door_targets = list(Inverted_Single_Cave_Targets)
|
||||
|
||||
# place links house
|
||||
links_house_doors = [i for i in lw_entrances + dw_entrances + lw_must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = random.choice(list(links_house_doors))
|
||||
links_house_doors = [i for i in lw_entrances + dw_entrances + lw_must_exits if
|
||||
i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = world.random.choice(list(links_house_doors))
|
||||
connect_two_way(world, links_house, 'Inverted Links House Exit', player)
|
||||
if links_house in lw_entrances:
|
||||
lw_entrances.remove(links_house)
|
||||
|
@ -1269,7 +1283,7 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# place dark sanc
|
||||
sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in dw_entrances]
|
||||
sanc_door = random.choice(sanc_doors)
|
||||
sanc_door = world.random.choice(sanc_doors)
|
||||
dw_entrances.remove(sanc_door)
|
||||
connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player)
|
||||
world.get_entrance('Inverted Dark Sanctuary Exit', player).connect(world.get_entrance(sanc_door, player).parent_region)
|
||||
|
@ -1283,7 +1297,7 @@ def link_inverted_entrances(world, player):
|
|||
# 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 dw_entrances]
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
dw_entrances.remove(old_man_exit)
|
||||
|
@ -1292,7 +1306,7 @@ def link_inverted_entrances(world, player):
|
|||
all_entrances = lw_entrances + dw_entrances
|
||||
# cannot place it anywhere already taken (or that are otherwise not eligible for placement)
|
||||
blacksmith_doors = [door for door in blacksmith_doors if door in all_entrances]
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
if blacksmith_hut in lw_entrances:
|
||||
|
@ -1305,7 +1319,7 @@ def link_inverted_entrances(world, player):
|
|||
all_entrances = lw_entrances + dw_entrances
|
||||
# cannot place it anywhere already taken (or that are otherwise not eligible for placement)
|
||||
bomb_shop_doors = [door for door in bomb_shop_doors if door in all_entrances]
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player)
|
||||
if bomb_shop in lw_entrances:
|
||||
|
@ -1314,7 +1328,7 @@ def link_inverted_entrances(world, player):
|
|||
dw_entrances.remove(bomb_shop)
|
||||
|
||||
# place the old man cave's entrance somewhere in the dark world
|
||||
random.shuffle(dw_entrances)
|
||||
world.random.shuffle(dw_entrances)
|
||||
old_man_entrance = dw_entrances.pop()
|
||||
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
|
||||
|
||||
|
@ -1341,7 +1355,7 @@ def link_inverted_entrances(world, player):
|
|||
old_man_house = list(Old_Man_House)
|
||||
|
||||
# randomize which desert ledge door is a must-exit
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
lw_must_exits.append('Desert Palace Entrance (North)')
|
||||
lw_entrances.append('Desert Palace Entrance (West)')
|
||||
else:
|
||||
|
@ -1351,7 +1365,8 @@ def link_inverted_entrances(world, player):
|
|||
# tavern back door cannot be shuffled yet
|
||||
connect_doors(world, ['Tavern North'], ['Tavern'], player)
|
||||
|
||||
caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3)))
|
||||
caves.append(tuple(world.random.sample(
|
||||
['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3)))
|
||||
lw_entrances.append('Hyrule Castle Entrance (South)')
|
||||
|
||||
|
||||
|
@ -1366,14 +1381,14 @@ def link_inverted_entrances(world, player):
|
|||
# shuffle aga door first. if it's on hc ledge, then one other hc ledge door has to be must_exit
|
||||
all_entrances_aga = lw_entrances + dw_entrances
|
||||
aga_doors = [i for i in all_entrances_aga]
|
||||
random.shuffle(aga_doors)
|
||||
world.random.shuffle(aga_doors)
|
||||
aga_door = aga_doors.pop()
|
||||
|
||||
if aga_door in hc_ledge_entrances:
|
||||
lw_entrances.remove(aga_door)
|
||||
hc_ledge_entrances.remove(aga_door)
|
||||
|
||||
random.shuffle(hc_ledge_entrances)
|
||||
world.random.shuffle(hc_ledge_entrances)
|
||||
hc_ledge_must_exit = hc_ledge_entrances.pop()
|
||||
lw_entrances.remove(hc_ledge_must_exit)
|
||||
lw_must_exits.append(hc_ledge_must_exit)
|
||||
|
@ -1387,8 +1402,9 @@ def link_inverted_entrances(world, player):
|
|||
caves.remove('Inverted Agahnims Tower Exit')
|
||||
|
||||
# place links house
|
||||
links_house_doors = [i for i in lw_entrances + dw_entrances + lw_must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = random.choice(list(links_house_doors))
|
||||
links_house_doors = [i for i in lw_entrances + dw_entrances + lw_must_exits if
|
||||
i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = world.random.choice(list(links_house_doors))
|
||||
connect_two_way(world, links_house, 'Inverted Links House Exit', player)
|
||||
if links_house in lw_entrances:
|
||||
lw_entrances.remove(links_house)
|
||||
|
@ -1399,14 +1415,14 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# place dark sanc
|
||||
sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in dw_entrances]
|
||||
sanc_door = random.choice(sanc_doors)
|
||||
sanc_door = world.random.choice(sanc_doors)
|
||||
dw_entrances.remove(sanc_door)
|
||||
connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player)
|
||||
world.get_entrance('Inverted Dark Sanctuary Exit', player).connect(world.get_entrance(sanc_door, player).parent_region)
|
||||
|
||||
# place old man house
|
||||
# no dw must exits in inverted, but we randomize whether cave is in light or dark world
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
caves += old_man_house
|
||||
connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player)
|
||||
try:
|
||||
|
@ -1422,7 +1438,7 @@ def link_inverted_entrances(world, player):
|
|||
# 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 dw_entrances + lw_entrances]
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
if old_man_exit in dw_entrances:
|
||||
|
@ -1436,7 +1452,7 @@ def link_inverted_entrances(world, player):
|
|||
all_entrances = lw_entrances + dw_entrances
|
||||
# cannot place it anywhere already taken (or that are otherwise not eligible for placement)
|
||||
blacksmith_doors = [door for door in blacksmith_doors if door in all_entrances]
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
if blacksmith_hut in lw_entrances:
|
||||
|
@ -1449,7 +1465,7 @@ def link_inverted_entrances(world, player):
|
|||
all_entrances = lw_entrances + dw_entrances
|
||||
# cannot place it anywhere already taken (or that are otherwise not eligible for placement)
|
||||
bomb_shop_doors = [door for door in bomb_shop_doors if door in all_entrances]
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player)
|
||||
if bomb_shop in lw_entrances:
|
||||
|
@ -1459,11 +1475,11 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# place the old man cave's entrance somewhere in the same world he'll exit from
|
||||
if old_man_world == 'light':
|
||||
random.shuffle(lw_entrances)
|
||||
world.random.shuffle(lw_entrances)
|
||||
old_man_entrance = lw_entrances.pop()
|
||||
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
|
||||
elif old_man_world == 'dark':
|
||||
random.shuffle(dw_entrances)
|
||||
world.random.shuffle(dw_entrances)
|
||||
old_man_entrance = dw_entrances.pop()
|
||||
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
|
||||
|
||||
|
@ -1490,14 +1506,15 @@ def link_inverted_entrances(world, player):
|
|||
door_targets = list(Inverted_Single_Cave_Targets)
|
||||
|
||||
# randomize which desert ledge door is a must-exit
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
must_exits.append('Desert Palace Entrance (North)')
|
||||
entrances.append('Desert Palace Entrance (West)')
|
||||
else:
|
||||
must_exits.append('Desert Palace Entrance (West)')
|
||||
entrances.append('Desert Palace Entrance (North)')
|
||||
|
||||
caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3)))
|
||||
caves.append(tuple(world.random.sample(
|
||||
['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'], 3)))
|
||||
entrances.append('Hyrule Castle Entrance (South)')
|
||||
|
||||
if not world.shuffle_ganon:
|
||||
|
@ -1509,12 +1526,12 @@ def link_inverted_entrances(world, player):
|
|||
hc_ledge_entrances = ['Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower']
|
||||
|
||||
# shuffle aga door. if it's on hc ledge, then one other hc ledge door has to be must_exit
|
||||
aga_door = random.choice(list(entrances))
|
||||
aga_door = world.random.choice(list(entrances))
|
||||
|
||||
if aga_door in hc_ledge_entrances:
|
||||
hc_ledge_entrances.remove(aga_door)
|
||||
|
||||
random.shuffle(hc_ledge_entrances)
|
||||
world.random.shuffle(hc_ledge_entrances)
|
||||
hc_ledge_must_exit = hc_ledge_entrances.pop()
|
||||
entrances.remove(hc_ledge_must_exit)
|
||||
must_exits.append(hc_ledge_must_exit)
|
||||
|
@ -1525,8 +1542,9 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
|
||||
# place links house
|
||||
links_house_doors = [i for i in entrances + must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = random.choice(list(links_house_doors))
|
||||
links_house_doors = [i for i in entrances + must_exits if
|
||||
i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = world.random.choice(list(links_house_doors))
|
||||
connect_two_way(world, links_house, 'Inverted Links House Exit', player)
|
||||
if links_house in entrances:
|
||||
entrances.remove(links_house)
|
||||
|
@ -1535,7 +1553,7 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# place dark sanc
|
||||
sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in entrances]
|
||||
sanc_door = random.choice(sanc_doors)
|
||||
sanc_door = world.random.choice(sanc_doors)
|
||||
entrances.remove(sanc_door)
|
||||
connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player)
|
||||
world.get_entrance('Inverted Dark Sanctuary Exit', player).connect(world.get_entrance(sanc_door, player).parent_region)
|
||||
|
@ -1551,7 +1569,7 @@ def link_inverted_entrances(world, player):
|
|||
# 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 entrances]
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player)
|
||||
entrances.remove(old_man_exit)
|
||||
|
@ -1559,7 +1577,7 @@ def link_inverted_entrances(world, player):
|
|||
# place blacksmith, has limited options
|
||||
# cannot place it anywhere already taken (or that are otherwise not eligible for placement)
|
||||
blacksmith_doors = [door for door in blacksmith_doors if door in entrances]
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
entrances.remove(blacksmith_hut)
|
||||
|
@ -1568,13 +1586,13 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# cannot place it anywhere already taken (or that are otherwise not eligible for placement)
|
||||
bomb_shop_doors = [door for door in bomb_shop_doors if door in entrances]
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player)
|
||||
entrances.remove(bomb_shop)
|
||||
|
||||
# place the old man cave's entrance somewhere
|
||||
random.shuffle(entrances)
|
||||
world.random.shuffle(entrances)
|
||||
old_man_entrance = entrances.pop()
|
||||
connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player)
|
||||
|
||||
|
@ -1597,7 +1615,7 @@ def link_inverted_entrances(world, player):
|
|||
Inverted_LW_Single_Cave_Doors + Inverted_DW_Single_Cave_Doors + ['Desert Palace Entrance (West)', 'Desert Palace Entrance (North)']
|
||||
|
||||
# randomize which desert ledge door is a must-exit
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
entrances_must_exits.append('Desert Palace Entrance (North)')
|
||||
entrances.append('Desert Palace Entrance (West)')
|
||||
else:
|
||||
|
@ -1612,7 +1630,7 @@ def link_inverted_entrances(world, player):
|
|||
blacksmith_doors = list(Blacksmith_Single_Cave_Doors + Inverted_Blacksmith_Multi_Cave_Doors)
|
||||
door_targets = list(Inverted_Single_Cave_Targets)
|
||||
|
||||
random.shuffle(doors)
|
||||
world.random.shuffle(doors)
|
||||
|
||||
old_man_entrances = list(Inverted_Old_Man_Entrances + Old_Man_Entrances) + ['Tower of Hera', 'Inverted Agahnims Tower']
|
||||
|
||||
|
@ -1646,9 +1664,9 @@ def link_inverted_entrances(world, player):
|
|||
hole_targets.append('Pyramid')
|
||||
doors.extend(['Inverted Ganons Tower', 'Inverted Pyramid Entrance'])
|
||||
|
||||
random.shuffle(hole_entrances)
|
||||
random.shuffle(hole_targets)
|
||||
random.shuffle(entrances)
|
||||
world.random.shuffle(hole_entrances)
|
||||
world.random.shuffle(hole_targets)
|
||||
world.random.shuffle(entrances)
|
||||
|
||||
# fill up holes
|
||||
for hole in hole_entrances:
|
||||
|
@ -1658,8 +1676,9 @@ def link_inverted_entrances(world, player):
|
|||
caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'))
|
||||
|
||||
# place links house and dark sanc
|
||||
links_house_doors = [i for i in entrances + entrances_must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = random.choice(list(links_house_doors))
|
||||
links_house_doors = [i for i in entrances + entrances_must_exits if
|
||||
i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||
links_house = world.random.choice(list(links_house_doors))
|
||||
connect_two_way(world, links_house, 'Inverted Links House Exit', player)
|
||||
if links_house in entrances:
|
||||
entrances.remove(links_house)
|
||||
|
@ -1668,7 +1687,7 @@ def link_inverted_entrances(world, player):
|
|||
doors.remove(links_house)
|
||||
|
||||
sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in entrances]
|
||||
sanc_door = random.choice(sanc_doors)
|
||||
sanc_door = world.random.choice(sanc_doors)
|
||||
entrances.remove(sanc_door)
|
||||
doors.remove(sanc_door)
|
||||
connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player)
|
||||
|
@ -1676,7 +1695,7 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# now let's deal with mandatory reachable stuff
|
||||
def extract_reachable_exit(cavelist):
|
||||
random.shuffle(cavelist)
|
||||
world.random.shuffle(cavelist)
|
||||
candidate = None
|
||||
for cave in cavelist:
|
||||
if isinstance(cave, tuple) and len(cave) > 1:
|
||||
|
@ -1708,7 +1727,7 @@ def link_inverted_entrances(world, player):
|
|||
# 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 = [entrance for entrance in old_man_entrances if entrance in entrances]
|
||||
random.shuffle(old_man_entrances)
|
||||
world.random.shuffle(old_man_entrances)
|
||||
old_man_exit = old_man_entrances.pop()
|
||||
entrances.remove(old_man_exit)
|
||||
|
||||
|
@ -1718,14 +1737,14 @@ def link_inverted_entrances(world, player):
|
|||
|
||||
# place blacksmith, has limited options
|
||||
blacksmith_doors = [door for door in blacksmith_doors if door in doors]
|
||||
random.shuffle(blacksmith_doors)
|
||||
world.random.shuffle(blacksmith_doors)
|
||||
blacksmith_hut = blacksmith_doors.pop()
|
||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||
doors.remove(blacksmith_hut)
|
||||
|
||||
# place dam and pyramid fairy, have limited options
|
||||
bomb_shop_doors = [door for door in bomb_shop_doors if door in doors]
|
||||
random.shuffle(bomb_shop_doors)
|
||||
world.random.shuffle(bomb_shop_doors)
|
||||
bomb_shop = bomb_shop_doors.pop()
|
||||
connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player)
|
||||
doors.remove(bomb_shop)
|
||||
|
@ -1843,14 +1862,14 @@ def scramble_holes(world, player):
|
|||
if world.shuffle[player] == 'crossed':
|
||||
hole_targets.append(('Sanctuary Exit', 'Sewer Drop'))
|
||||
if world.shuffle_ganon:
|
||||
random.shuffle(hole_targets)
|
||||
world.random.shuffle(hole_targets)
|
||||
exit, target = hole_targets.pop()
|
||||
connect_two_way(world, 'Pyramid Entrance', exit, player)
|
||||
connect_entrance(world, 'Pyramid Hole', target, player)
|
||||
if world.shuffle[player] != 'crossed':
|
||||
hole_targets.append(('Sanctuary Exit', 'Sewer Drop'))
|
||||
|
||||
random.shuffle(hole_targets)
|
||||
world.random.shuffle(hole_targets)
|
||||
for entrance, drop in hole_entrances:
|
||||
exit, target = hole_targets.pop()
|
||||
connect_two_way(world, entrance, exit, player)
|
||||
|
@ -1885,14 +1904,14 @@ def scramble_inverted_holes(world, player):
|
|||
if world.shuffle[player] == 'crossed':
|
||||
hole_targets.append(('Sanctuary Exit', 'Sewer Drop'))
|
||||
if world.shuffle_ganon:
|
||||
random.shuffle(hole_targets)
|
||||
world.random.shuffle(hole_targets)
|
||||
exit, target = hole_targets.pop()
|
||||
connect_two_way(world, 'Inverted Pyramid Entrance', exit, player)
|
||||
connect_entrance(world, 'Inverted Pyramid Hole', target, player)
|
||||
if world.shuffle[player] != 'crossed':
|
||||
hole_targets.append(('Sanctuary Exit', 'Sewer Drop'))
|
||||
|
||||
random.shuffle(hole_targets)
|
||||
world.random.shuffle(hole_targets)
|
||||
for entrance, drop in hole_entrances:
|
||||
exit, target = hole_targets.pop()
|
||||
connect_two_way(world, entrance, exit, player)
|
||||
|
@ -1900,7 +1919,7 @@ def scramble_inverted_holes(world, player):
|
|||
|
||||
def connect_random(world, exitlist, targetlist, player, two_way=False):
|
||||
targetlist = list(targetlist)
|
||||
random.shuffle(targetlist)
|
||||
world.random.shuffle(targetlist)
|
||||
|
||||
for exit, target in zip(exitlist, targetlist):
|
||||
if two_way:
|
||||
|
@ -1927,15 +1946,17 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player):
|
|||
entrances.append(entrance)
|
||||
|
||||
"""This works inplace"""
|
||||
random.shuffle(entrances)
|
||||
random.shuffle(caves)
|
||||
world.random.shuffle(entrances)
|
||||
world.random.shuffle(caves)
|
||||
|
||||
# Handle inverted Aga Tower - if it depends on connections, then so does Hyrule Castle Ledge
|
||||
if world.mode[player] == 'inverted':
|
||||
for entrance in invalid_connections:
|
||||
if world.get_entrance(entrance, player).connected_region == world.get_region('Inverted Agahnims Tower', player):
|
||||
if world.get_entrance(entrance, player).connected_region == world.get_region('Inverted Agahnims Tower',
|
||||
player):
|
||||
for exit in invalid_connections[entrance]:
|
||||
invalid_connections[exit] = invalid_connections[exit].union({'Inverted Ganons Tower', 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'})
|
||||
invalid_connections[exit] = invalid_connections[exit].union(
|
||||
{'Inverted Ganons Tower', 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'})
|
||||
break
|
||||
|
||||
used_caves = []
|
||||
|
@ -1984,7 +2005,7 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player):
|
|||
else:
|
||||
required_entrances += len(cave)-1
|
||||
caves.append(cave[0:-1])
|
||||
random.shuffle(caves)
|
||||
world.random.shuffle(caves)
|
||||
used_caves.append(cave[0:-1])
|
||||
invalid_cave_connections[tuple(cave[0:-1])] = invalid_cave_connections[tuple(cave)].union(invalid_connections[exit])
|
||||
caves.remove(cave)
|
||||
|
@ -2000,9 +2021,9 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player):
|
|||
|
||||
def connect_caves(world, lw_entrances, dw_entrances, caves, player):
|
||||
"""This works inplace"""
|
||||
random.shuffle(lw_entrances)
|
||||
random.shuffle(dw_entrances)
|
||||
random.shuffle(caves)
|
||||
world.random.shuffle(lw_entrances)
|
||||
world.random.shuffle(dw_entrances)
|
||||
world.random.shuffle(caves)
|
||||
while caves:
|
||||
# connect highest exit count caves first, prevent issue where we have 2 or 3 exits accross worlds left to fill
|
||||
cave_candidate = (None, 0)
|
||||
|
@ -2013,7 +2034,7 @@ def connect_caves(world, lw_entrances, dw_entrances, caves, player):
|
|||
cave_candidate = (i, len(cave))
|
||||
cave = caves.pop(cave_candidate[0])
|
||||
|
||||
target = lw_entrances if random.randint(0, 1) == 0 else dw_entrances
|
||||
target = lw_entrances if world.random.randint(0, 1) == 0 else dw_entrances
|
||||
if isinstance(cave, str):
|
||||
cave = (cave,)
|
||||
|
||||
|
@ -2028,8 +2049,8 @@ def connect_caves(world, lw_entrances, dw_entrances, caves, player):
|
|||
|
||||
def connect_doors(world, doors, targets, player):
|
||||
"""This works inplace"""
|
||||
random.shuffle(doors)
|
||||
random.shuffle(targets)
|
||||
world.random.shuffle(doors)
|
||||
world.random.shuffle(targets)
|
||||
while doors:
|
||||
door = doors.pop()
|
||||
target = targets.pop()
|
||||
|
@ -2066,7 +2087,7 @@ def simple_shuffle_dungeons(world, player):
|
|||
multi_dungeons = ['Desert', 'Turtle Rock']
|
||||
if world.mode[player] == 'open' or (world.mode[player] == 'inverted' and world.shuffle_ganon):
|
||||
multi_dungeons.append('Hyrule Castle')
|
||||
random.shuffle(multi_dungeons)
|
||||
world.random.shuffle(multi_dungeons)
|
||||
|
||||
dp_target = multi_dungeons[0]
|
||||
tr_target = multi_dungeons[1]
|
||||
|
@ -2175,11 +2196,12 @@ def simple_shuffle_dungeons(world, player):
|
|||
connect_two_way(world, 'Dark Death Mountain Ledge (West)', 'Turtle Rock Ledge Exit (West)', player)
|
||||
connect_two_way(world, 'Dark Death Mountain Ledge (East)', 'Turtle Rock Ledge Exit (East)', player)
|
||||
|
||||
def unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits):
|
||||
|
||||
def unbias_some_entrances(world, Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits):
|
||||
def shuffle_lists_in_list(ls):
|
||||
for i, item in enumerate(ls):
|
||||
if isinstance(item, list):
|
||||
ls[i] = random.sample(item, len(item))
|
||||
ls[i] = world.random.sample(item, len(item))
|
||||
|
||||
def tuplize_lists_in_list(ls):
|
||||
for i, item in enumerate(ls):
|
||||
|
@ -2193,7 +2215,7 @@ def unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_E
|
|||
|
||||
# paradox fixup
|
||||
if Cave_Three_Exits[1][0] == "Paradox Cave Exit (Bottom)":
|
||||
i = random.randint(1,2)
|
||||
i = world.random.randint(1, 2)
|
||||
Cave_Three_Exits[1][0] = Cave_Three_Exits[1][i]
|
||||
Cave_Three_Exits[1][i] = "Paradox Cave Exit (Bottom)"
|
||||
|
||||
|
|
39
Fill.py
39
Fill.py
|
@ -1,4 +1,3 @@
|
|||
import random
|
||||
import logging
|
||||
|
||||
from BaseClasses import CollectionState
|
||||
|
@ -10,10 +9,10 @@ class FillError(RuntimeError):
|
|||
def distribute_items_cutoff(world, cutoffrate=0.33):
|
||||
# get list of locations to fill in
|
||||
fill_locations = world.get_unfilled_locations()
|
||||
random.shuffle(fill_locations)
|
||||
world.random.shuffle(fill_locations)
|
||||
|
||||
# get items to distribute
|
||||
random.shuffle(world.itempool)
|
||||
world.random.shuffle(world.itempool)
|
||||
itempool = world.itempool
|
||||
|
||||
total_advancement_items = len([item for item in itempool if item.advancement])
|
||||
|
@ -83,10 +82,10 @@ def distribute_items_cutoff(world, cutoffrate=0.33):
|
|||
def distribute_items_staleness(world):
|
||||
# get list of locations to fill in
|
||||
fill_locations = world.get_unfilled_locations()
|
||||
random.shuffle(fill_locations)
|
||||
world.random.shuffle(fill_locations)
|
||||
|
||||
# get items to distribute
|
||||
random.shuffle(world.itempool)
|
||||
world.random.shuffle(world.itempool)
|
||||
itempool = world.itempool
|
||||
|
||||
progress_done = False
|
||||
|
@ -131,7 +130,7 @@ def distribute_items_staleness(world):
|
|||
spot_to_fill = None
|
||||
for location in fill_locations:
|
||||
# increase likelyhood of skipping a location if it has been found stale
|
||||
if not progress_done and random.randint(0, location.staleness_count) > 2:
|
||||
if not progress_done and world.random.randint(0, location.staleness_count) > 2:
|
||||
continue
|
||||
|
||||
if location.can_fill(world.state, item_to_place):
|
||||
|
@ -215,10 +214,10 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
|||
# If not passed in, then get a shuffled list of locations to fill in
|
||||
if not fill_locations:
|
||||
fill_locations = world.get_unfilled_locations()
|
||||
random.shuffle(fill_locations)
|
||||
world.random.shuffle(fill_locations)
|
||||
|
||||
# get items to distribute
|
||||
random.shuffle(world.itempool)
|
||||
world.random.shuffle(world.itempool)
|
||||
progitempool = []
|
||||
localprioitempool = {player: [] for player in range(1, world.players + 1)}
|
||||
localrestitempool = {player: [] for player in range(1, world.players + 1)}
|
||||
|
@ -244,17 +243,17 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
|||
continue
|
||||
|
||||
gftower_trash_count = (
|
||||
random.randint(15, 50) if 'triforcehunt' in world.goal[player]
|
||||
else random.randint(0, 15))
|
||||
world.random.randint(15, 50) if 'triforcehunt' in world.goal[player]
|
||||
else world.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)
|
||||
world.random.shuffle(gtower_locations)
|
||||
trashcnt = 0
|
||||
localrest = localrestitempool[player]
|
||||
if localrest:
|
||||
gt_item_pool = restitempool + localrest
|
||||
random.shuffle(gt_item_pool)
|
||||
world.random.shuffle(gt_item_pool)
|
||||
else:
|
||||
gt_item_pool = restitempool.copy()
|
||||
|
||||
|
@ -269,7 +268,7 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
|||
fill_locations.remove(spot_to_fill)
|
||||
trashcnt += 1
|
||||
|
||||
random.shuffle(fill_locations)
|
||||
world.random.shuffle(fill_locations)
|
||||
fill_locations.reverse()
|
||||
|
||||
# Make sure the escape small key is placed first in standard with key shuffle to prevent running out of spots
|
||||
|
@ -283,20 +282,20 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
|
|||
localprioitempool.values() or localrestitempool.values()): # we need to make sure some fills are limited to certain worlds
|
||||
for player, items in localprioitempool.items(): # items already shuffled
|
||||
local_locations = [location for location in fill_locations if location.player == player]
|
||||
random.shuffle(local_locations)
|
||||
world.random.shuffle(local_locations)
|
||||
for item_to_place in items:
|
||||
spot_to_fill = local_locations.pop()
|
||||
world.push_item(spot_to_fill, item_to_place, False)
|
||||
fill_locations.remove(spot_to_fill)
|
||||
for player, items in localrestitempool.items(): # items already shuffled
|
||||
local_locations = [location for location in fill_locations if location.player == player]
|
||||
random.shuffle(local_locations)
|
||||
world.random.shuffle(local_locations)
|
||||
for item_to_place in items:
|
||||
spot_to_fill = local_locations.pop()
|
||||
world.push_item(spot_to_fill, item_to_place, False)
|
||||
fill_locations.remove(spot_to_fill)
|
||||
|
||||
random.shuffle(fill_locations)
|
||||
world.random.shuffle(fill_locations)
|
||||
|
||||
fast_fill(world, prioitempool, fill_locations)
|
||||
|
||||
|
@ -314,7 +313,7 @@ def fast_fill(world, item_pool, fill_locations):
|
|||
|
||||
def flood_items(world):
|
||||
# get items to distribute
|
||||
random.shuffle(world.itempool)
|
||||
world.random.shuffle(world.itempool)
|
||||
itempool = world.itempool
|
||||
progress_done = False
|
||||
|
||||
|
@ -324,7 +323,7 @@ def flood_items(world):
|
|||
# fill world from top of itempool while we can
|
||||
while not progress_done:
|
||||
location_list = world.get_unfilled_locations()
|
||||
random.shuffle(location_list)
|
||||
world.random.shuffle(location_list)
|
||||
spot_to_fill = None
|
||||
for location in location_list:
|
||||
if location.can_fill(world.state, itempool[0]):
|
||||
|
@ -360,7 +359,7 @@ def flood_items(world):
|
|||
|
||||
# find item to replace with progress item
|
||||
location_list = world.get_reachable_locations()
|
||||
random.shuffle(location_list)
|
||||
world.random.shuffle(location_list)
|
||||
for location in location_list:
|
||||
if location.item is not None and not location.item.advancement and not location.item.priority and not location.item.smallkey and not location.item.bigkey:
|
||||
# safe to replace
|
||||
|
@ -380,7 +379,7 @@ def balance_multiworld_progression(world):
|
|||
state = CollectionState(world)
|
||||
checked_locations = []
|
||||
unchecked_locations = world.get_locations().copy()
|
||||
random.shuffle(unchecked_locations)
|
||||
world.random.shuffle(unchecked_locations)
|
||||
|
||||
reachable_locations_count = {player: 0 for player in range(1, world.players + 1)}
|
||||
|
||||
|
|
62
ItemList.py
62
ItemList.py
|
@ -1,6 +1,5 @@
|
|||
from collections import namedtuple
|
||||
import logging
|
||||
import random
|
||||
|
||||
from BaseClasses import Region, RegionType, Shop, ShopType, Location
|
||||
from Bosses import place_bosses
|
||||
|
@ -181,10 +180,7 @@ def generate_itempool(world, player):
|
|||
# set up item pool
|
||||
if world.custom:
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon,
|
||||
lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive[player], world.shuffle[player],
|
||||
world.difficulty[player], world.timer[player], world.goal[player],
|
||||
world.mode[player], world.swords[player],
|
||||
world.retro[player], world.customitemarray)
|
||||
lamps_needed_for_dark_rooms) = make_custom_item_pool(world, player)
|
||||
world.rupoor_cost = min(world.customitemarray[69], 9999)
|
||||
else:
|
||||
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon,
|
||||
|
@ -209,7 +205,7 @@ def generate_itempool(world, player):
|
|||
if item in ['Hammer', 'Bombs (10)', 'Fire Rod', 'Cane of Somaria', 'Cane of Byrna']:
|
||||
if item not in possible_weapons:
|
||||
possible_weapons.append(item)
|
||||
starting_weapon = random.choice(possible_weapons)
|
||||
starting_weapon = world.random.choice(possible_weapons)
|
||||
placed_items["Link's Uncle"] = starting_weapon
|
||||
pool.remove(starting_weapon)
|
||||
if placed_items["Link's Uncle"] in ['Bow', 'Progressive Bow', 'Bombs (10)', 'Cane of Somaria', 'Cane of Byrna'] and world.enemy_health[player] not in ['default', 'easy']:
|
||||
|
@ -255,13 +251,14 @@ def generate_itempool(world, player):
|
|||
4: {'trap': 100}}
|
||||
def beemizer(item):
|
||||
if world.beemizer[item.player] and not item.advancement and not item.priority and not item.type:
|
||||
choice = random.choices(list(beeweights[world.beemizer[item.player]].keys()), weights=list(beeweights[world.beemizer[item.player]].values()))[0]
|
||||
choice = world.random.choices(list(beeweights[world.beemizer[item.player]].keys()),
|
||||
weights=list(beeweights[world.beemizer[item.player]].values()))[0]
|
||||
return item if not choice else ItemFactory("Bee Trap", player) if choice == 'trap' else ItemFactory("Bee", player)
|
||||
return item
|
||||
|
||||
progressionitems = [item for item in items if item.advancement or item.priority or item.type]
|
||||
nonprogressionitems = [beemizer(item) for item in items if not item.advancement and not item.priority and not item.type]
|
||||
random.shuffle(nonprogressionitems)
|
||||
world.random.shuffle(nonprogressionitems)
|
||||
|
||||
triforce_pieces = world.triforce_pieces_available[player]
|
||||
if 'triforcehunt' in world.goal[player] and triforce_pieces > 30:
|
||||
|
@ -271,8 +268,8 @@ def generate_itempool(world, player):
|
|||
world.itempool += progressionitems + nonprogressionitems
|
||||
|
||||
# shuffle medallions
|
||||
mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)]
|
||||
tr_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)]
|
||||
mm_medallion = ['Ether', 'Quake', 'Bombos'][world.random.randint(0, 2)]
|
||||
tr_medallion = ['Ether', 'Quake', 'Bombos'][world.random.randint(0, 2)]
|
||||
world.required_medallions[player] = (mm_medallion, tr_medallion)
|
||||
|
||||
place_bosses(world, player)
|
||||
|
@ -297,7 +294,7 @@ def set_up_take_anys(world, player):
|
|||
if world.mode[player] == 'inverted' and 'Dark Sanctuary Hint' in take_any_locations:
|
||||
take_any_locations.remove('Dark Sanctuary Hint')
|
||||
|
||||
regions = random.sample(take_any_locations, 5)
|
||||
regions = world.random.sample(take_any_locations, 5)
|
||||
|
||||
old_man_take_any = Region("Old Man Sword Cave", RegionType.Cave, 'the sword cave', player)
|
||||
world.regions.append(old_man_take_any)
|
||||
|
@ -312,7 +309,7 @@ def set_up_take_anys(world, player):
|
|||
|
||||
swords = [item for item in world.itempool if item.type == 'Sword' and item.player == player]
|
||||
if swords:
|
||||
sword = random.choice(swords)
|
||||
sword = world.random.choice(swords)
|
||||
world.itempool.remove(sword)
|
||||
world.itempool.append(ItemFactory('Rupees (20)', player))
|
||||
old_man_take_any.shop.add_inventory(0, sword.name, 0, 0, create_location=True)
|
||||
|
@ -324,7 +321,7 @@ def set_up_take_anys(world, player):
|
|||
world.regions.append(take_any)
|
||||
world.dynamic_regions.append(take_any)
|
||||
|
||||
target, room_id = random.choice([(0x58, 0x0112), (0x60, 0x010F), (0x46, 0x011F)])
|
||||
target, room_id = world.random.choice([(0x58, 0x0112), (0x60, 0x010F), (0x46, 0x011F)])
|
||||
reg = regions.pop()
|
||||
entrance = world.get_region(reg, player).entrances[0]
|
||||
connect_entrance(world, entrance.name, take_any.name, player)
|
||||
|
@ -368,8 +365,8 @@ def fill_prizes(world, attempts=15):
|
|||
try:
|
||||
prizepool = list(unplaced_prizes)
|
||||
prize_locs = list(empty_crystal_locations)
|
||||
random.shuffle(prizepool)
|
||||
random.shuffle(prize_locs)
|
||||
world.random.shuffle(prizepool)
|
||||
world.random.shuffle(prize_locs)
|
||||
fill_restrictive(world, all_state, prize_locs, prizepool, True)
|
||||
except FillError as e:
|
||||
logging.getLogger('').exception("Failed to place dungeon prizes (%s). Will retry %s more times", e,
|
||||
|
@ -389,7 +386,9 @@ def set_up_shops(world, player):
|
|||
rss = world.get_region('Red Shield Shop', player).shop
|
||||
if not rss.locked:
|
||||
rss.add_inventory(2, 'Single Arrow', 80)
|
||||
for shop in 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):
|
||||
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
|
||||
shop.add_inventory(0, 'Single Arrow', 80)
|
||||
shop.add_inventory(1, 'Small Key (Universal)', 100)
|
||||
|
@ -422,7 +421,7 @@ def get_pool_core(world, player: int):
|
|||
placed_items[loc] = item
|
||||
|
||||
def want_progressives():
|
||||
return random.choice([True, False]) if progressive == 'random' else progressive == 'on'
|
||||
return world.random.choice([True, False]) if progressive == 'random' else progressive == 'on'
|
||||
|
||||
# provide boots to major glitch dependent seeds
|
||||
if logic in {'owglitches', 'nologic'} and world.glitch_boots[player]:
|
||||
|
@ -455,10 +454,10 @@ def get_pool_core(world, player: int):
|
|||
# expert+ difficulties produce the same contents for
|
||||
# all bottles, since only one bottle is available
|
||||
if diff.same_bottle:
|
||||
thisbottle = random.choice(diff.bottles)
|
||||
thisbottle = world.random.choice(diff.bottles)
|
||||
for _ in range(diff.bottle_count):
|
||||
if not diff.same_bottle:
|
||||
thisbottle = random.choice(diff.bottles)
|
||||
thisbottle = world.random.choice(diff.bottles)
|
||||
pool.append(thisbottle)
|
||||
|
||||
if want_progressives():
|
||||
|
@ -482,7 +481,7 @@ def get_pool_core(world, player: int):
|
|||
pool.extend(diff.swordless)
|
||||
elif swords == 'vanilla':
|
||||
swords_to_use = diff.progressivesword.copy() if want_progressives() else diff.basicsword.copy()
|
||||
random.shuffle(swords_to_use)
|
||||
world.random.shuffle(swords_to_use)
|
||||
|
||||
place_item('Link\'s Uncle', swords_to_use.pop())
|
||||
place_item('Blacksmith', swords_to_use.pop())
|
||||
|
@ -535,13 +534,24 @@ def get_pool_core(world, player: int):
|
|||
pool = [item.replace('Arrow Upgrade (+10)','Rupees (5)') for item in pool]
|
||||
pool.extend(diff.retro)
|
||||
if mode == 'standard':
|
||||
key_location = random.choice(['Secret Passage', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest', 'Sewers - Dark Cross'])
|
||||
key_location = world.random.choice(
|
||||
['Secret Passage', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest',
|
||||
'Hyrule Castle - Zelda\'s Chest', 'Sewers - Dark Cross'])
|
||||
place_item(key_location, 'Small Key (Universal)')
|
||||
else:
|
||||
pool.extend(['Small Key (Universal)'])
|
||||
return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms)
|
||||
|
||||
def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, customitemarray):
|
||||
|
||||
def make_custom_item_pool(world, player):
|
||||
shuffle = world.shuffle[player]
|
||||
difficulty = world.difficulty[player]
|
||||
timer = world.timer[player]
|
||||
goal = world.goal[player]
|
||||
mode = world.mode[player]
|
||||
retro = world.retro[player]
|
||||
customitemarray = world.customitemarray[player]
|
||||
|
||||
pool = []
|
||||
placed_items = {}
|
||||
precollected_items = []
|
||||
|
@ -636,10 +646,10 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
|||
# expert+ difficulties produce the same contents for
|
||||
# all bottles, since only one bottle is available
|
||||
if diff.same_bottle:
|
||||
thisbottle = random.choice(diff.bottles)
|
||||
thisbottle = world.random.choice(diff.bottles)
|
||||
for _ in range(customitemarray[18]):
|
||||
if not diff.same_bottle:
|
||||
thisbottle = random.choice(diff.bottles)
|
||||
thisbottle = world.random.choice(diff.bottles)
|
||||
pool.append(thisbottle)
|
||||
|
||||
if customitemarray[66] > 0 or customitemarray[67] > 0:
|
||||
|
@ -664,7 +674,9 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s
|
|||
|
||||
if mode == 'standard':
|
||||
if retro:
|
||||
key_location = random.choice(['Secret Passage', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest', 'Sewers - Dark Cross'])
|
||||
key_location = world.random.choice(
|
||||
['Secret Passage', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest',
|
||||
'Hyrule Castle - Zelda\'s Chest', 'Sewers - Dark Cross'])
|
||||
place_item(key_location, 'Small Key (Universal)')
|
||||
pool.extend(['Small Key (Universal)'] * max((customitemarray[70] - 1), 0))
|
||||
else:
|
||||
|
|
18
Main.py
18
Main.py
|
@ -43,17 +43,25 @@ def main(args, seed=None):
|
|||
world = World(args.multi, args.shuffle, args.logic, args.mode, args.swords, args.difficulty,
|
||||
args.item_functionality, args.timer, args.progressive.copy(), args.goal, args.algorithm,
|
||||
args.accessibility, args.shuffleganon, args.retro, args.custom, args.customitemarray, args.hints)
|
||||
|
||||
logger = logging.getLogger('')
|
||||
world.seed = get_seed(seed)
|
||||
random.seed(world.seed)
|
||||
if args.race:
|
||||
world.secure()
|
||||
else:
|
||||
world.random.seed(world.seed)
|
||||
|
||||
world.remote_items = args.remote_items.copy()
|
||||
world.mapshuffle = args.mapshuffle.copy()
|
||||
world.compassshuffle = args.compassshuffle.copy()
|
||||
world.keyshuffle = args.keyshuffle.copy()
|
||||
world.bigkeyshuffle = args.bigkeyshuffle.copy()
|
||||
world.crystals_needed_for_ganon = {player: random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(args.crystals_ganon[player]) for player in range(1, world.players + 1)}
|
||||
world.crystals_needed_for_gt = {player: random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) for player in range(1, world.players + 1)}
|
||||
world.crystals_needed_for_ganon = {
|
||||
player: world.random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(
|
||||
args.crystals_ganon[player]) for player in range(1, world.players + 1)}
|
||||
world.crystals_needed_for_gt = {
|
||||
player: world.random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player])
|
||||
for player in range(1, world.players + 1)}
|
||||
world.open_pyramid = args.openpyramid.copy()
|
||||
world.boss_shuffle = args.shufflebosses.copy()
|
||||
world.enemy_shuffle = args.shuffleenemies.copy()
|
||||
|
@ -69,7 +77,7 @@ def main(args, seed=None):
|
|||
world.triforce_pieces_required = args.triforce_pieces_required.copy()
|
||||
world.progression_balancing = {player: not balance for player, balance in args.skip_progression_balancing.items()}
|
||||
|
||||
world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)}
|
||||
world.rom_seeds = {player: world.random.randint(0, 999999999) for player in range(1, world.players + 1)}
|
||||
|
||||
logger.info('ALttP Berserker\'s Multiworld Version %s - Seed: %s\n', __version__, world.seed)
|
||||
|
||||
|
@ -134,7 +142,7 @@ def main(args, seed=None):
|
|||
if args.algorithm in ['balanced', 'vt26'] or any(list(args.mapshuffle.values()) + list(args.compassshuffle.values()) +
|
||||
list(args.keyshuffle.values()) + list(args.bigkeyshuffle.values())):
|
||||
shuffled_locations = world.get_unfilled_locations()
|
||||
random.shuffle(shuffled_locations)
|
||||
world.random.shuffle(shuffled_locations)
|
||||
fill_dungeons_restrictive(world, shuffled_locations)
|
||||
else:
|
||||
fill_dungeons(world)
|
||||
|
|
|
@ -12,6 +12,7 @@ import inspect
|
|||
import weakref
|
||||
import datetime
|
||||
import threading
|
||||
import random
|
||||
|
||||
import ModuleUpdate
|
||||
|
||||
|
@ -830,7 +831,6 @@ class ClientMessageProcessor(CommonCommandProcessor):
|
|||
can_pay = points_available // self.ctx.hint_cost
|
||||
else:
|
||||
can_pay = 1000
|
||||
import random
|
||||
|
||||
random.shuffle(not_found_hints)
|
||||
|
||||
|
|
|
@ -56,6 +56,9 @@ def main(args=None):
|
|||
seed = get_seed(args.seed)
|
||||
random.seed(seed)
|
||||
|
||||
if args.race:
|
||||
random.seed() # reset to time-based random source
|
||||
|
||||
seedname = "M" + (f"{random.randint(0, pow(10, seeddigits) - 1)}".zfill(seeddigits))
|
||||
print(f"Generating mystery for {args.multi} player{'s' if args.multi > 1 else ''}, {seedname} Seed {seed}")
|
||||
|
||||
|
|
86
Rom.py
86
Rom.py
|
@ -236,8 +236,9 @@ def patch_enemizer(world, player: int, rom: LocalRom, enemizercli, random_sprite
|
|||
'BeesLevel': 0,
|
||||
'RandomizeTileTrapPattern': world.enemy_shuffle[player] == 'chaos',
|
||||
'RandomizeTileTrapFloorTile': False,
|
||||
'AllowKillableThief': bool(random.randint(0, 1)) if 'thieves' in world.enemy_shuffle[player] else
|
||||
'AllowKillableThief': bool(world.random.randint(0, 1)) if 'thieves' in world.enemy_shuffle[player] else
|
||||
world.enemy_shuffle[player] != 'none',
|
||||
# TODO: this is currently non-deterministic due to being called in a thread
|
||||
'RandomizeSpriteOnHit': random_sprite_on_hit,
|
||||
'DebugMode': False,
|
||||
'DebugForceEnemy': False,
|
||||
|
@ -289,7 +290,7 @@ def patch_enemizer(world, player: int, rom: LocalRom, enemizercli, random_sprite
|
|||
if sprites:
|
||||
while len(sprites) < 32:
|
||||
sprites.extend(sprites)
|
||||
random.shuffle(sprites)
|
||||
world.random.shuffle(sprites)
|
||||
|
||||
for i, path in enumerate(sprites[:32]):
|
||||
sprite = Sprite(path)
|
||||
|
@ -1606,9 +1607,9 @@ def write_strings(rom, world, player, team):
|
|||
if world.hints[player]:
|
||||
tt['sign_north_of_links_house'] = '> Randomizer The telepathic tiles can have hints!'
|
||||
hint_locations = HintLocations.copy()
|
||||
random.shuffle(hint_locations)
|
||||
world.random.shuffle(hint_locations)
|
||||
all_entrances = [entrance for entrance in world.get_entrances() if entrance.player == player]
|
||||
random.shuffle(all_entrances)
|
||||
world.random.shuffle(all_entrances)
|
||||
|
||||
#First we take care of the one inconvenient dungeon in the appropriately simple shuffles.
|
||||
entrances_to_hint = {}
|
||||
|
@ -1683,12 +1684,12 @@ def write_strings(rom, world, player, team):
|
|||
locations_to_hint = InconvenientLocations.copy()
|
||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
|
||||
locations_to_hint.extend(InconvenientVanillaLocations)
|
||||
random.shuffle(locations_to_hint)
|
||||
world.random.shuffle(locations_to_hint)
|
||||
hint_count = 3 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 5
|
||||
del locations_to_hint[hint_count:]
|
||||
for location in locations_to_hint:
|
||||
if location == 'Swamp Left':
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
first_item = hint_text(world.get_location('Swamp Palace - West Chest', player).item)
|
||||
second_item = hint_text(world.get_location('Swamp Palace - Big Key Chest', player).item)
|
||||
else:
|
||||
|
@ -1697,7 +1698,7 @@ def write_strings(rom, world, player, team):
|
|||
this_hint = ('The westmost chests in Swamp Palace contain ' + first_item + ' and ' + second_item + '.')
|
||||
tt[hint_locations.pop(0)] = this_hint
|
||||
elif location == 'Mire Left':
|
||||
if random.randint(0, 1) == 0:
|
||||
if world.random.randint(0, 1) == 0:
|
||||
first_item = hint_text(world.get_location('Misery Mire - Compass Chest', player).item)
|
||||
second_item = hint_text(world.get_location('Misery Mire - Big Key Chest', player).item)
|
||||
else:
|
||||
|
@ -1736,12 +1737,12 @@ def write_strings(rom, world, player, team):
|
|||
items_to_hint.extend(SmallKeys)
|
||||
if world.bigkeyshuffle[player]:
|
||||
items_to_hint.extend(BigKeys)
|
||||
random.shuffle(items_to_hint)
|
||||
world.random.shuffle(items_to_hint)
|
||||
hint_count = 5 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 8
|
||||
while hint_count > 0:
|
||||
this_item = items_to_hint.pop(0)
|
||||
this_location = world.find_items(this_item, player)
|
||||
random.shuffle(this_location)
|
||||
world.random.shuffle(this_location)
|
||||
#This looks dumb but prevents hints for Skull Woods Pinball Room's key safely with any item pool.
|
||||
if this_location:
|
||||
if this_location[0].name == 'Skull Woods - Pinball Room':
|
||||
|
@ -1753,7 +1754,7 @@ def write_strings(rom, world, player, team):
|
|||
|
||||
# All remaining hint slots are filled with junk hints. It is done this way to ensure the same junk hint isn't selected twice.
|
||||
junk_hints = junk_texts.copy()
|
||||
random.shuffle(junk_hints)
|
||||
world.random.shuffle(junk_hints)
|
||||
for location in hint_locations:
|
||||
tt[location] = junk_hints.pop(0)
|
||||
|
||||
|
@ -1761,7 +1762,7 @@ def write_strings(rom, world, player, team):
|
|||
|
||||
|
||||
silverarrows = world.find_items('Silver Bow', player)
|
||||
random.shuffle(silverarrows)
|
||||
world.random.shuffle(silverarrows)
|
||||
silverarrow_hint = (' %s?' % hint_text(silverarrows[0]).replace('Ganon\'s', 'my')) if silverarrows else '?\nI think not!'
|
||||
tt['ganon_phase_3_no_silvers'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||
tt['ganon_phase_3_no_silvers_alt'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||
|
@ -1775,7 +1776,8 @@ def write_strings(rom, world, player, team):
|
|||
tt['ganon_phase_3_no_silvers'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||
|
||||
if any(prog_bow_locs):
|
||||
silverarrow_hint = (' %s?' % hint_text(random.choice(prog_bow_locs)).replace('Ganon\'s', 'my')) if progressive_silvers else '?\nI think not!'
|
||||
silverarrow_hint = (' %s?' % hint_text(world.random.choice(prog_bow_locs)).replace('Ganon\'s',
|
||||
'my')) if progressive_silvers else '?\nI think not!'
|
||||
tt['ganon_phase_3_no_silvers_alt'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||
|
||||
|
||||
|
@ -1786,19 +1788,23 @@ def write_strings(rom, world, player, team):
|
|||
greenpendant = world.find_items('Green Pendant', player)[0]
|
||||
tt['sahasrahla_bring_courage'] = 'I lost my family heirloom in %s' % greenpendant.hint_text
|
||||
|
||||
tt['sign_ganons_tower'] = ('You need %d crystal to enter.' if world.crystals_needed_for_gt[player] == 1 else 'You need %d crystals to enter.') % world.crystals_needed_for_gt[player]
|
||||
tt['sign_ganon'] = ('You need %d crystal to beat Ganon.' if world.crystals_needed_for_ganon[player] == 1 else 'You need %d crystals to beat Ganon.') % world.crystals_needed_for_ganon[player]
|
||||
tt['sign_ganons_tower'] = ('You need %d crystal to enter.' if world.crystals_needed_for_gt[
|
||||
player] == 1 else 'You need %d crystals to enter.') % \
|
||||
world.crystals_needed_for_gt[player]
|
||||
tt['sign_ganon'] = ('You need %d crystal to beat Ganon.' if world.crystals_needed_for_ganon[
|
||||
player] == 1 else 'You need %d crystals to beat Ganon.') % \
|
||||
world.crystals_needed_for_ganon[player]
|
||||
|
||||
if world.goal[player] in ['dungeons']:
|
||||
tt['sign_ganon'] = 'You need to complete all the dungeons.'
|
||||
|
||||
tt['uncle_leaving_text'] = Uncle_texts[random.randint(0, len(Uncle_texts) - 1)]
|
||||
tt['end_triforce'] = "{NOBORDER}\n" + Triforce_texts[random.randint(0, len(Triforce_texts) - 1)]
|
||||
tt['bomb_shop_big_bomb'] = BombShop2_texts[random.randint(0, len(BombShop2_texts) - 1)]
|
||||
tt['uncle_leaving_text'] = Uncle_texts[world.random.randint(0, len(Uncle_texts) - 1)]
|
||||
tt['end_triforce'] = "{NOBORDER}\n" + Triforce_texts[world.random.randint(0, len(Triforce_texts) - 1)]
|
||||
tt['bomb_shop_big_bomb'] = BombShop2_texts[world.random.randint(0, len(BombShop2_texts) - 1)]
|
||||
|
||||
# this is what shows after getting the green pendant item in rando
|
||||
tt['sahasrahla_quest_have_master_sword'] = Sahasrahla2_texts[random.randint(0, len(Sahasrahla2_texts) - 1)]
|
||||
tt['blind_by_the_light'] = Blind_texts[random.randint(0, len(Blind_texts) - 1)]
|
||||
tt['sahasrahla_quest_have_master_sword'] = Sahasrahla2_texts[world.random.randint(0, len(Sahasrahla2_texts) - 1)]
|
||||
tt['blind_by_the_light'] = Blind_texts[world.random.randint(0, len(Blind_texts) - 1)]
|
||||
|
||||
if world.goal[player] in ['triforcehunt', 'localtriforcehunt']:
|
||||
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Get the Triforce Pieces.'
|
||||
|
@ -1807,14 +1813,15 @@ def write_strings(rom, world, player, team):
|
|||
tt['sign_ganon'] = 'Go find the Triforce pieces with your friends... Ganon is invincible!'
|
||||
else:
|
||||
tt['sign_ganon'] = 'Go find the Triforce pieces... Ganon is invincible!'
|
||||
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." % \
|
||||
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." % \
|
||||
world.treasure_hunt_count[player]
|
||||
elif world.goal[player] in ['pedestal']:
|
||||
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Your goal is at the pedestal.'
|
||||
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:
|
||||
tt['ganon_fall_in'] = Ganon1_texts[random.randint(0, len(Ganon1_texts) - 1)]
|
||||
tt['ganon_fall_in'] = Ganon1_texts[world.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!'
|
||||
if world.goal[player] == 'ganontriforcehunt' and world.players > 1:
|
||||
|
@ -1822,7 +1829,7 @@ def write_strings(rom, world, player, team):
|
|||
elif world.goal[player] in ['ganontriforcehunt', 'localganontriforcehunt']:
|
||||
tt['sign_ganon'] = 'You need to find %d Triforce pieces to defeat Ganon.' % world.treasure_hunt_count[player]
|
||||
|
||||
tt['kakariko_tavern_fisherman'] = TavernMan_texts[random.randint(0, len(TavernMan_texts) - 1)]
|
||||
tt['kakariko_tavern_fisherman'] = TavernMan_texts[world.random.randint(0, len(TavernMan_texts) - 1)]
|
||||
|
||||
pedestalitem = world.get_location('Master Sword Pedestal', player).item
|
||||
pedestal_text = 'Some Hot Air' if pedestalitem is None else hint_text(pedestalitem, True) if pedestalitem.pedestal_hint_text is not None else 'Unknown Item'
|
||||
|
@ -1853,33 +1860,38 @@ def write_strings(rom, world, player, team):
|
|||
credits = Credits()
|
||||
|
||||
sickkiditem = world.get_location('Sick Kid', player).item
|
||||
sickkiditem_text = random.choice(SickKid_texts) if sickkiditem is None or sickkiditem.sickkid_credit_text is None else sickkiditem.sickkid_credit_text
|
||||
sickkiditem_text = world.random.choice(
|
||||
SickKid_texts) if sickkiditem is None or sickkiditem.sickkid_credit_text is None else sickkiditem.sickkid_credit_text
|
||||
|
||||
zoraitem = world.get_location('King Zora', player).item
|
||||
zoraitem_text = random.choice(Zora_texts) if zoraitem is None or zoraitem.zora_credit_text is None else zoraitem.zora_credit_text
|
||||
zoraitem_text = world.random.choice(
|
||||
Zora_texts) if zoraitem is None or zoraitem.zora_credit_text is None else zoraitem.zora_credit_text
|
||||
|
||||
magicshopitem = world.get_location('Potion Shop', player).item
|
||||
magicshopitem_text = random.choice(MagicShop_texts) if magicshopitem is None or magicshopitem.magicshop_credit_text is None else magicshopitem.magicshop_credit_text
|
||||
magicshopitem_text = world.random.choice(
|
||||
MagicShop_texts) if magicshopitem is None or magicshopitem.magicshop_credit_text is None else magicshopitem.magicshop_credit_text
|
||||
|
||||
fluteboyitem = world.get_location('Flute Spot', player).item
|
||||
fluteboyitem_text = random.choice(FluteBoy_texts) if fluteboyitem is None or fluteboyitem.fluteboy_credit_text is None else fluteboyitem.fluteboy_credit_text
|
||||
fluteboyitem_text = world.random.choice(
|
||||
FluteBoy_texts) if fluteboyitem is None or fluteboyitem.fluteboy_credit_text is None else fluteboyitem.fluteboy_credit_text
|
||||
|
||||
credits.update_credits_line('castle', 0, random.choice(KingsReturn_texts))
|
||||
credits.update_credits_line('sanctuary', 0, random.choice(Sanctuary_texts))
|
||||
credits.update_credits_line('castle', 0, world.random.choice(KingsReturn_texts))
|
||||
credits.update_credits_line('sanctuary', 0, world.random.choice(Sanctuary_texts))
|
||||
|
||||
credits.update_credits_line('kakariko', 0, random.choice(Kakariko_texts).format(random.choice(Sahasrahla_names)))
|
||||
credits.update_credits_line('desert', 0, random.choice(DesertPalace_texts))
|
||||
credits.update_credits_line('hera', 0, random.choice(MountainTower_texts))
|
||||
credits.update_credits_line('house', 0, random.choice(LinksHouse_texts))
|
||||
credits.update_credits_line('kakariko', 0,
|
||||
world.random.choice(Kakariko_texts).format(world.random.choice(Sahasrahla_names)))
|
||||
credits.update_credits_line('desert', 0, world.random.choice(DesertPalace_texts))
|
||||
credits.update_credits_line('hera', 0, world.random.choice(MountainTower_texts))
|
||||
credits.update_credits_line('house', 0, world.random.choice(LinksHouse_texts))
|
||||
credits.update_credits_line('zora', 0, zoraitem_text)
|
||||
credits.update_credits_line('witch', 0, magicshopitem_text)
|
||||
credits.update_credits_line('lumberjacks', 0, random.choice(Lumberjacks_texts))
|
||||
credits.update_credits_line('lumberjacks', 0, world.random.choice(Lumberjacks_texts))
|
||||
credits.update_credits_line('grove', 0, fluteboyitem_text)
|
||||
credits.update_credits_line('well', 0, random.choice(WishingWell_texts))
|
||||
credits.update_credits_line('smithy', 0, random.choice(Blacksmiths_texts))
|
||||
credits.update_credits_line('well', 0, world.random.choice(WishingWell_texts))
|
||||
credits.update_credits_line('smithy', 0, world.random.choice(Blacksmiths_texts))
|
||||
credits.update_credits_line('kakariko2', 0, sickkiditem_text)
|
||||
credits.update_credits_line('bridge', 0, random.choice(DeathMountain_texts))
|
||||
credits.update_credits_line('woods', 0, random.choice(LostWoods_texts))
|
||||
credits.update_credits_line('bridge', 0, world.random.choice(DeathMountain_texts))
|
||||
credits.update_credits_line('woods', 0, world.random.choice(LostWoods_texts))
|
||||
credits.update_credits_line('pedestal', 0, pedestal_credit_text)
|
||||
|
||||
(pointers, data) = credits.get_bytes()
|
||||
|
|
Loading…
Reference in New Issue