Creating a separate copy_world_limited for OWR/ER purposes
This commit is contained in:
@@ -3,6 +3,7 @@ from collections import defaultdict, OrderedDict
|
|||||||
import RaceRandom as random
|
import RaceRandom as random
|
||||||
from BaseClasses import CollectionState, RegionType
|
from BaseClasses import CollectionState, RegionType
|
||||||
from OverworldShuffle import build_accessible_region_list
|
from OverworldShuffle import build_accessible_region_list
|
||||||
|
from DoorShuffle import find_inaccessible_regions
|
||||||
from OWEdges import OWTileRegions
|
from OWEdges import OWTileRegions
|
||||||
from Utils import stack_size3a
|
from Utils import stack_size3a
|
||||||
|
|
||||||
@@ -831,8 +832,6 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player, must
|
|||||||
"""This works inplace"""
|
"""This works inplace"""
|
||||||
random.shuffle(entrances)
|
random.shuffle(entrances)
|
||||||
random.shuffle(caves)
|
random.shuffle(caves)
|
||||||
|
|
||||||
from DoorShuffle import find_inaccessible_regions
|
|
||||||
|
|
||||||
used_caves = []
|
used_caves = []
|
||||||
required_entrances = 0 # Number of entrances reserved for used_caves
|
required_entrances = 0 # Number of entrances reserved for used_caves
|
||||||
@@ -1274,7 +1273,6 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player):
|
|||||||
dw_entrances.extend([e for e in dungeon_owid_map[owid][0] if e in entrance_pool])
|
dw_entrances.extend([e for e in dungeon_owid_map[owid][0] if e in entrance_pool])
|
||||||
|
|
||||||
# determine must-exit entrances
|
# determine must-exit entrances
|
||||||
from DoorShuffle import find_inaccessible_regions
|
|
||||||
find_inaccessible_regions(world, player)
|
find_inaccessible_regions(world, player)
|
||||||
|
|
||||||
lw_must_exit = list()
|
lw_must_exit = list()
|
||||||
@@ -1442,13 +1440,12 @@ def place_old_man(world, pool, player, ignore_list=[]):
|
|||||||
|
|
||||||
|
|
||||||
def junk_fill_inaccessible(world, player):
|
def junk_fill_inaccessible(world, player):
|
||||||
from Main import copy_world
|
from Main import copy_world_limited
|
||||||
from DoorShuffle import find_inaccessible_regions
|
|
||||||
find_inaccessible_regions(world, player)
|
find_inaccessible_regions(world, player)
|
||||||
|
|
||||||
for p in range(1, world.players + 1):
|
for p in range(1, world.players + 1):
|
||||||
world.key_logic[p] = {}
|
world.key_logic[p] = {}
|
||||||
base_world = copy_world(world, True)
|
base_world = copy_world_limited(world)
|
||||||
base_world.override_bomb_check = True
|
base_world.override_bomb_check = True
|
||||||
|
|
||||||
# remove regions that have a dungeon entrance
|
# remove regions that have a dungeon entrance
|
||||||
@@ -1488,7 +1485,6 @@ def connect_inaccessible_regions(world, lw_entrances, dw_entrances, caves, playe
|
|||||||
random.shuffle(lw_entrances)
|
random.shuffle(lw_entrances)
|
||||||
random.shuffle(dw_entrances)
|
random.shuffle(dw_entrances)
|
||||||
|
|
||||||
from DoorShuffle import find_inaccessible_regions
|
|
||||||
find_inaccessible_regions(world, player)
|
find_inaccessible_regions(world, player)
|
||||||
|
|
||||||
# remove regions that have a dungeon entrance
|
# remove regions that have a dungeon entrance
|
||||||
@@ -1611,12 +1607,12 @@ def unbias_dungeons(Dungeon_Exits):
|
|||||||
|
|
||||||
|
|
||||||
def build_accessible_entrance_list(world, start_region, player, assumed_inventory=[], cross_world=False, region_rules=True, exit_rules=True, include_one_ways=False):
|
def build_accessible_entrance_list(world, start_region, player, assumed_inventory=[], cross_world=False, region_rules=True, exit_rules=True, include_one_ways=False):
|
||||||
from Main import copy_world
|
from Main import copy_world_limited
|
||||||
from Items import ItemFactory
|
from Items import ItemFactory
|
||||||
|
|
||||||
for p in range(1, world.players + 1):
|
for p in range(1, world.players + 1):
|
||||||
world.key_logic[p] = {}
|
world.key_logic[p] = {}
|
||||||
base_world = copy_world(world, True)
|
base_world = copy_world_limited(world)
|
||||||
base_world.override_bomb_check = True
|
base_world.override_bomb_check = True
|
||||||
|
|
||||||
connect_simple(base_world, 'Links House S&Q', start_region, player)
|
connect_simple(base_world, 'Links House S&Q', start_region, player)
|
||||||
@@ -1719,13 +1715,12 @@ def get_distant_entrances(world, start_entrance, player):
|
|||||||
|
|
||||||
|
|
||||||
def can_reach(world, entrance_name, region_name, player):
|
def can_reach(world, entrance_name, region_name, player):
|
||||||
from Main import copy_world
|
from Main import copy_world_limited
|
||||||
from Items import ItemFactory
|
from Items import ItemFactory
|
||||||
from DoorShuffle import find_inaccessible_regions
|
|
||||||
|
|
||||||
for p in range(1, world.players + 1):
|
for p in range(1, world.players + 1):
|
||||||
world.key_logic[p] = {}
|
world.key_logic[p] = {}
|
||||||
base_world = copy_world(world, True)
|
base_world = copy_world_limited(world)
|
||||||
base_world.override_bomb_check = True
|
base_world.override_bomb_check = True
|
||||||
|
|
||||||
entrance = world.get_entrance(entrance_name, player)
|
entrance = world.get_entrance(entrance_name, player)
|
||||||
|
|||||||
139
Main.py
139
Main.py
@@ -396,7 +396,7 @@ def main(args, seed=None, fish=None):
|
|||||||
return world
|
return world
|
||||||
|
|
||||||
|
|
||||||
def copy_world(world, partial_copy=False):
|
def copy_world(world):
|
||||||
# ToDo: Not good yet
|
# ToDo: Not good yet
|
||||||
ret = World(world.players, world.owShuffle, world.owCrossed, world.owMixed, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords,
|
ret = World(world.players, world.owShuffle, world.owCrossed, world.owMixed, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords,
|
||||||
world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm,
|
world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm,
|
||||||
@@ -543,10 +543,9 @@ def copy_world(world, partial_copy=False):
|
|||||||
ret.dungeon_layouts = world.dungeon_layouts
|
ret.dungeon_layouts = world.dungeon_layouts
|
||||||
ret.key_logic = world.key_logic
|
ret.key_logic = world.key_logic
|
||||||
ret.dungeon_portals = world.dungeon_portals
|
ret.dungeon_portals = world.dungeon_portals
|
||||||
if not partial_copy:
|
for player, portals in world.dungeon_portals.items():
|
||||||
for player, portals in world.dungeon_portals.items():
|
for portal in portals:
|
||||||
for portal in portals:
|
connect_portal(portal, ret, player)
|
||||||
connect_portal(portal, ret, player)
|
|
||||||
ret.sanc_portal = world.sanc_portal
|
ret.sanc_portal = world.sanc_portal
|
||||||
|
|
||||||
from OverworldShuffle import categorize_world_regions
|
from OverworldShuffle import categorize_world_regions
|
||||||
@@ -554,10 +553,132 @@ def copy_world(world, partial_copy=False):
|
|||||||
categorize_world_regions(ret, player)
|
categorize_world_regions(ret, player)
|
||||||
set_rules(ret, player)
|
set_rules(ret, player)
|
||||||
|
|
||||||
if partial_copy:
|
return ret
|
||||||
# undo some of the things that unintentionally affect the original world object
|
|
||||||
world.key_logic = {}
|
|
||||||
ret.is_copied_world = True
|
def copy_world_limited(world):
|
||||||
|
# ToDo: Not good yet
|
||||||
|
ret = World(world.players, world.owShuffle, world.owCrossed, world.owMixed, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords,
|
||||||
|
world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm,
|
||||||
|
world.accessibility, world.shuffle_ganon, world.retro, world.custom, world.customitemarray, world.hints)
|
||||||
|
ret.teams = world.teams
|
||||||
|
ret.player_names = copy.deepcopy(world.player_names)
|
||||||
|
ret.remote_items = world.remote_items.copy()
|
||||||
|
ret.required_medallions = world.required_medallions.copy()
|
||||||
|
ret.bottle_refills = world.bottle_refills.copy()
|
||||||
|
ret.swamp_patch_required = world.swamp_patch_required.copy()
|
||||||
|
ret.ganon_at_pyramid = world.ganon_at_pyramid.copy()
|
||||||
|
ret.powder_patch_required = world.powder_patch_required.copy()
|
||||||
|
ret.ganonstower_vanilla = world.ganonstower_vanilla.copy()
|
||||||
|
ret.treasure_hunt_count = world.treasure_hunt_count.copy()
|
||||||
|
ret.treasure_hunt_icon = world.treasure_hunt_icon.copy()
|
||||||
|
ret.sewer_light_cone = world.sewer_light_cone.copy()
|
||||||
|
ret.light_world_light_cone = world.light_world_light_cone
|
||||||
|
ret.dark_world_light_cone = world.dark_world_light_cone
|
||||||
|
ret.seed = world.seed
|
||||||
|
ret.can_access_trock_eyebridge = world.can_access_trock_eyebridge.copy()
|
||||||
|
ret.can_access_trock_front = world.can_access_trock_front.copy()
|
||||||
|
ret.can_access_trock_big_chest = world.can_access_trock_big_chest.copy()
|
||||||
|
ret.can_access_trock_middle = world.can_access_trock_middle.copy()
|
||||||
|
ret.can_take_damage = world.can_take_damage
|
||||||
|
ret.difficulty_requirements = world.difficulty_requirements.copy()
|
||||||
|
ret.fix_fake_world = world.fix_fake_world.copy()
|
||||||
|
ret.lamps_needed_for_dark_rooms = world.lamps_needed_for_dark_rooms
|
||||||
|
ret.mapshuffle = world.mapshuffle.copy()
|
||||||
|
ret.compassshuffle = world.compassshuffle.copy()
|
||||||
|
ret.keyshuffle = world.keyshuffle.copy()
|
||||||
|
ret.bigkeyshuffle = world.bigkeyshuffle.copy()
|
||||||
|
ret.bombbag = world.bombbag.copy()
|
||||||
|
ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy()
|
||||||
|
ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy()
|
||||||
|
ret.crystals_ganon_orig = world.crystals_ganon_orig.copy()
|
||||||
|
ret.crystals_gt_orig = world.crystals_gt_orig.copy()
|
||||||
|
ret.owKeepSimilar = world.owKeepSimilar.copy()
|
||||||
|
ret.owWhirlpoolShuffle = world.owWhirlpoolShuffle.copy()
|
||||||
|
ret.owFluteShuffle = world.owFluteShuffle.copy()
|
||||||
|
ret.shuffle_bonk_drops = world.shuffle_bonk_drops.copy()
|
||||||
|
ret.open_pyramid = world.open_pyramid.copy()
|
||||||
|
ret.boss_shuffle = world.boss_shuffle.copy()
|
||||||
|
ret.enemy_shuffle = world.enemy_shuffle.copy()
|
||||||
|
ret.enemy_health = world.enemy_health.copy()
|
||||||
|
ret.enemy_damage = world.enemy_damage.copy()
|
||||||
|
ret.beemizer = world.beemizer.copy()
|
||||||
|
ret.intensity = world.intensity.copy()
|
||||||
|
ret.experimental = world.experimental.copy()
|
||||||
|
ret.shopsanity = world.shopsanity.copy()
|
||||||
|
ret.dropshuffle = world.dropshuffle.copy()
|
||||||
|
ret.pottery = world.pottery.copy()
|
||||||
|
ret.potshuffle = world.potshuffle.copy()
|
||||||
|
ret.mixed_travel = world.mixed_travel.copy()
|
||||||
|
ret.standardize_palettes = world.standardize_palettes.copy()
|
||||||
|
ret.owswaps = world.owswaps.copy()
|
||||||
|
ret.owflutespots = world.owflutespots.copy()
|
||||||
|
ret.prizes = world.prizes.copy()
|
||||||
|
ret.restrict_boss_items = world.restrict_boss_items.copy()
|
||||||
|
|
||||||
|
ret.is_copied_world = True
|
||||||
|
|
||||||
|
for player in range(1, world.players + 1):
|
||||||
|
create_regions(ret, player)
|
||||||
|
update_world_regions(ret, player)
|
||||||
|
create_flute_exits(ret, player)
|
||||||
|
create_dungeon_regions(ret, player)
|
||||||
|
create_shops(ret, player)
|
||||||
|
create_rooms(ret, player)
|
||||||
|
create_dungeons(ret, player)
|
||||||
|
if world.logic[player] in ('owglitches', 'nologic'):
|
||||||
|
create_owg_connections(ret, player)
|
||||||
|
|
||||||
|
# # there are region references here they must be migrated to preserve integrity
|
||||||
|
# # ret.exp_cache = world.exp_cache.copy()
|
||||||
|
|
||||||
|
# copy_dynamic_regions_and_locations(world, ret)
|
||||||
|
for player in range(1, world.players + 1):
|
||||||
|
if world.mode[player] == 'standard':
|
||||||
|
parent = ret.get_region('Menu', player)
|
||||||
|
target = ret.get_region('Hyrule Castle Secret Entrance', player)
|
||||||
|
connection = Entrance(player, 'Uncle S&Q', parent)
|
||||||
|
parent.exits.append(connection)
|
||||||
|
connection.connect(target)
|
||||||
|
|
||||||
|
# connect copied world
|
||||||
|
copied_locations = {(loc.name, loc.player): loc for loc in ret.get_locations()} # caches all locations
|
||||||
|
for region in world.regions:
|
||||||
|
copied_region = ret.get_region(region.name, region.player)
|
||||||
|
copied_region.is_light_world = region.is_light_world
|
||||||
|
copied_region.is_dark_world = region.is_dark_world
|
||||||
|
copied_region.dungeon = region.dungeon
|
||||||
|
copied_region.locations = [copied_locations[(location.name, location.player)] for location in region.locations]
|
||||||
|
for location in copied_region.locations:
|
||||||
|
location.parent_region = copied_region
|
||||||
|
for entrance in region.entrances:
|
||||||
|
ret.get_entrance(entrance.name, entrance.player).connect(copied_region)
|
||||||
|
|
||||||
|
for item in world.precollected_items:
|
||||||
|
ret.push_precollected(ItemFactory(item.name, item.player))
|
||||||
|
|
||||||
|
# copy progress items in state
|
||||||
|
ret.state.prog_items = world.state.prog_items.copy()
|
||||||
|
ret.state.stale = {player: True for player in range(1, world.players + 1)}
|
||||||
|
|
||||||
|
ret.owedges = world.owedges.copy()
|
||||||
|
ret.doors = world.doors.copy()
|
||||||
|
for door in ret.doors:
|
||||||
|
entrance = ret.check_for_entrance(door.name, door.player)
|
||||||
|
if entrance is not None:
|
||||||
|
entrance.door = door
|
||||||
|
ret.paired_doors = world.paired_doors.copy()
|
||||||
|
ret.rooms = world.rooms.copy()
|
||||||
|
ret.inaccessible_regions = world.inaccessible_regions.copy()
|
||||||
|
ret.dungeon_layouts = world.dungeon_layouts.copy()
|
||||||
|
ret.key_logic = world.key_logic.copy()
|
||||||
|
ret.dungeon_portals = world.dungeon_portals.copy()
|
||||||
|
ret.sanc_portal = world.sanc_portal.copy()
|
||||||
|
|
||||||
|
from OverworldShuffle import categorize_world_regions
|
||||||
|
for player in range(1, world.players + 1):
|
||||||
|
categorize_world_regions(ret, player)
|
||||||
|
set_rules(ret, player)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|||||||
@@ -289,6 +289,8 @@ def link_overworld(world, player):
|
|||||||
for whirlpools in whirlpool_candidates:
|
for whirlpools in whirlpool_candidates:
|
||||||
random.shuffle(whirlpools)
|
random.shuffle(whirlpools)
|
||||||
while len(whirlpools):
|
while len(whirlpools):
|
||||||
|
if len(whirlpools) % 2 == 1:
|
||||||
|
x=0
|
||||||
from_owid, from_whirlpool, from_region = whirlpools.pop()
|
from_owid, from_whirlpool, from_region = whirlpools.pop()
|
||||||
to_owid, to_whirlpool, to_region = whirlpools.pop()
|
to_owid, to_whirlpool, to_region = whirlpools.pop()
|
||||||
connect_simple(world, from_whirlpool, to_region, player)
|
connect_simple(world, from_whirlpool, to_region, player)
|
||||||
@@ -329,7 +331,7 @@ def link_overworld(world, player):
|
|||||||
# layout shuffle
|
# layout shuffle
|
||||||
groups = adjust_edge_groups(world, trimmed_groups, edges_to_swap, player)
|
groups = adjust_edge_groups(world, trimmed_groups, edges_to_swap, player)
|
||||||
|
|
||||||
tries = 20
|
tries = 100
|
||||||
valid_layout = False
|
valid_layout = False
|
||||||
connected_edge_cache = connected_edges.copy()
|
connected_edge_cache = connected_edges.copy()
|
||||||
while not valid_layout and tries > 0:
|
while not valid_layout and tries > 0:
|
||||||
@@ -426,6 +428,7 @@ def link_overworld(world, player):
|
|||||||
flute_pool.remove(owid)
|
flute_pool.remove(owid)
|
||||||
if ignore_proximity:
|
if ignore_proximity:
|
||||||
logging.getLogger('').warning(f'Warning: Adding flute spot within proximity: {hex(owid)}')
|
logging.getLogger('').warning(f'Warning: Adding flute spot within proximity: {hex(owid)}')
|
||||||
|
logging.getLogger('').debug(f'Placing flute at: {hex(owid)}')
|
||||||
new_spots.append(owid)
|
new_spots.append(owid)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -442,6 +445,7 @@ def link_overworld(world, player):
|
|||||||
sector_total -= 1
|
sector_total -= 1
|
||||||
spots_to_place = min(flute_spots - sector_total, max(1, round((sector[0] * (flute_spots - sector_total) / region_total) + 0.5)))
|
spots_to_place = min(flute_spots - sector_total, max(1, round((sector[0] * (flute_spots - sector_total) / region_total) + 0.5)))
|
||||||
target_spots = len(new_spots) + spots_to_place
|
target_spots = len(new_spots) + spots_to_place
|
||||||
|
logging.getLogger('').debug(f'Sector of {sector[0]} regions gets {spots_to_place} spot(s)')
|
||||||
|
|
||||||
if 'Desert Palace Teleporter Ledge' in sector[1] or 'Misery Mire Teleporter Ledge' in sector[1]:
|
if 'Desert Palace Teleporter Ledge' in sector[1] or 'Misery Mire Teleporter Ledge' in sector[1]:
|
||||||
addSpot(0x38, False) # guarantee desert/mire access
|
addSpot(0x38, False) # guarantee desert/mire access
|
||||||
@@ -878,13 +882,13 @@ def can_reach_smith(world, player):
|
|||||||
return found
|
return found
|
||||||
|
|
||||||
def build_sectors(world, player):
|
def build_sectors(world, player):
|
||||||
from Main import copy_world
|
from Main import copy_world_limited
|
||||||
from OWEdges import OWTileRegions
|
from OWEdges import OWTileRegions
|
||||||
|
|
||||||
# perform accessibility check on duplicate world
|
# perform accessibility check on duplicate world
|
||||||
for p in range(1, world.players + 1):
|
for p in range(1, world.players + 1):
|
||||||
world.key_logic[p] = {}
|
world.key_logic[p] = {}
|
||||||
base_world = copy_world(world, True)
|
base_world = copy_world_limited(world)
|
||||||
|
|
||||||
# build lists of contiguous regions accessible with full inventory (excl portals/mirror/flute/entrances)
|
# build lists of contiguous regions accessible with full inventory (excl portals/mirror/flute/entrances)
|
||||||
regions = list(OWTileRegions.copy().keys())
|
regions = list(OWTileRegions.copy().keys())
|
||||||
@@ -928,11 +932,23 @@ def build_sectors(world, player):
|
|||||||
sectors2.append(explored_regions)
|
sectors2.append(explored_regions)
|
||||||
sectors[s] = sectors2
|
sectors[s] = sectors2
|
||||||
|
|
||||||
|
#TODO: Keep largest LW sector for Links House consideration, keep sector containing WDM for Old Man consideration
|
||||||
|
# sector_entrances = list()
|
||||||
|
# for sector in sectors:
|
||||||
|
# entrances = list()
|
||||||
|
# for s2 in sector:
|
||||||
|
# for region_name in s2:
|
||||||
|
# region = world.get_region(region_name, player)
|
||||||
|
# for exit in region.exits:
|
||||||
|
# if exit.spot_type == 'Entrance' and exit.name in entrance_pool:
|
||||||
|
# entrances.append(exit.name)
|
||||||
|
# sector_entrances.append(entrances)
|
||||||
|
|
||||||
return sectors
|
return sectors
|
||||||
|
|
||||||
def build_accessible_region_list(world, start_region, player, build_copy_world=False, cross_world=False, region_rules=True, ignore_ledges = False):
|
def build_accessible_region_list(world, start_region, player, build_copy_world=False, cross_world=False, region_rules=True, ignore_ledges = False):
|
||||||
from Main import copy_world
|
|
||||||
from BaseClasses import CollectionState
|
from BaseClasses import CollectionState
|
||||||
|
from Main import copy_world_limited
|
||||||
from Items import ItemFactory
|
from Items import ItemFactory
|
||||||
from Utils import stack_size3a
|
from Utils import stack_size3a
|
||||||
|
|
||||||
@@ -959,7 +975,7 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F
|
|||||||
if build_copy_world:
|
if build_copy_world:
|
||||||
for p in range(1, world.players + 1):
|
for p in range(1, world.players + 1):
|
||||||
world.key_logic[p] = {}
|
world.key_logic[p] = {}
|
||||||
base_world = copy_world(world, True)
|
base_world = copy_world_limited(world)
|
||||||
base_world.override_bomb_check = True
|
base_world.override_bomb_check = True
|
||||||
else:
|
else:
|
||||||
base_world = world
|
base_world = world
|
||||||
@@ -1015,7 +1031,7 @@ def validate_layout(world, player):
|
|||||||
entrance_connectors['Bumper Cave Entrance'] = ['West Dark Death Mountain (Bottom)']
|
entrance_connectors['Bumper Cave Entrance'] = ['West Dark Death Mountain (Bottom)']
|
||||||
entrance_connectors['Mountain Entry Entrance'] = ['Mountain Entry Ledge']
|
entrance_connectors['Mountain Entry Entrance'] = ['Mountain Entry Ledge']
|
||||||
|
|
||||||
from Main import copy_world
|
from Main import copy_world_limited
|
||||||
from Utils import stack_size3a
|
from Utils import stack_size3a
|
||||||
from EntranceShuffle import default_dungeon_connections, default_connector_connections, default_item_connections, default_shop_connections, default_drop_connections, default_dropexit_connections
|
from EntranceShuffle import default_dungeon_connections, default_connector_connections, default_item_connections, default_shop_connections, default_drop_connections, default_dropexit_connections
|
||||||
|
|
||||||
@@ -1048,7 +1064,7 @@ def validate_layout(world, player):
|
|||||||
|
|
||||||
for p in range(1, world.players + 1):
|
for p in range(1, world.players + 1):
|
||||||
world.key_logic[p] = {}
|
world.key_logic[p] = {}
|
||||||
base_world = copy_world(world, True)
|
base_world = copy_world_limited(world)
|
||||||
explored_regions = list()
|
explored_regions = list()
|
||||||
|
|
||||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not world.shufflelinks[player]:
|
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not world.shufflelinks[player]:
|
||||||
|
|||||||
Reference in New Issue
Block a user