Merge branch 'OverworldShuffleDev' into OverworldShuffle

This commit is contained in:
codemann8
2022-11-03 13:47:55 -05:00
11 changed files with 216 additions and 171 deletions

View File

@@ -2,12 +2,12 @@ import RaceRandom as random, logging, copy
from collections import OrderedDict, defaultdict
from DungeonGenerator import GenerationException
from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSlot, Entrance
from Regions import mark_dark_world_regions, mark_light_world_regions
from Regions import mark_light_dark_world_regions
from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitTypes, OpenStd, parallel_links, IsParallel
from OverworldGlitchRules import create_owg_connections
from Utils import bidict
version_number = '0.2.11.0'
version_number = '0.2.11.1'
# branch indicator is intentionally different across branches
version_branch = ''
@@ -73,7 +73,7 @@ def link_overworld(world, player):
raise Exception('Cannot move a parallel edge without the other')
new_mode = OpenStd.Open
if tuple((OpenStd.Open, WorldType((int(wrld) + 1) % 2), dir, terrain, parallel, count)) not in new_groups.keys():
# when Links House tile is swapped, the DW edges need to get put into existing Standard group
# when Links House tile is flipped, the DW edges need to get put into existing Standard group
new_mode = OpenStd.Standard
new_groups[(new_mode, WorldType((int(wrld) + 1) % 2), dir, terrain, parallel, count)][0].append(forward_set)
new_groups[(new_mode, WorldType((int(wrld) + 1) % 2), dir, terrain, parallel, count)][1].append(back_set)
@@ -103,7 +103,7 @@ def link_overworld(world, player):
else:
raise NotImplementedError('Cannot move one side of a non-parallel connection')
else:
raise NotImplementedError('Invalid OW Edge swap scenario')
raise NotImplementedError('Invalid OW Edge flip scenario')
return new_groups
tile_groups = define_tile_groups(world, player, False)
@@ -143,7 +143,7 @@ def link_overworld(world, player):
trimmed_groups = reorganize_groups(world, trimmed_groups, player)
# tile shuffle
logging.getLogger('').debug('Swapping overworld tiles')
logging.getLogger('').debug('Flipping overworld tiles')
if world.owMixed[player]:
swapped_edges = shuffle_tiles(world, tile_groups, world.owswaps[player], False, player)
@@ -199,8 +199,8 @@ def link_overworld(world, player):
if world.owCrossed[player] in ['grouped', 'limited'] or (world.owShuffle[player] == 'vanilla' and world.owCrossed[player] == 'chaos'):
if world.owCrossed[player] == 'grouped':
# the idea is to XOR the new swaps with the ones from Mixed so that non-parallel edges still work
# Polar corresponds to Grouped with no swaps in ow_crossed_tiles_mask
# the idea is to XOR the new flips with the ones from Mixed so that non-parallel edges still work
# Polar corresponds to Grouped with no flips in ow_crossed_tiles_mask
ow_crossed_tiles_mask = [[],[],[]]
crossed_edges = shuffle_tiles(world, define_tile_groups(world, player, True), ow_crossed_tiles_mask, True, player)
ow_crossed_tiles = [i for i in range(0x82) if (i in world.owswaps[player][0]) != (i in ow_crossed_tiles_mask[0])]
@@ -252,7 +252,7 @@ def link_overworld(world, player):
elif edge in parallel_links_new.inverse:
crossed_edges.append(parallel_links_new.inverse[edge][0])
# after tile swap and crossed, determine edges that need to swap
# after tile flip and crossed, determine edges that need to flip
edges_to_swap = [e for e in swapped_edges+crossed_edges if (e not in swapped_edges) or (e not in crossed_edges)]
# whirlpool shuffle
@@ -307,9 +307,9 @@ def link_overworld(world, player):
logging.getLogger('').debug('Shuffling overworld layout')
if world.owShuffle[player] == 'vanilla':
# apply outstanding swaps
# apply outstanding flips
trimmed_groups = performSwap(trimmed_groups, edges_to_swap)
assert len(edges_to_swap) == 0, 'Not all edges were swapped successfully: ' + ', '.join(edges_to_swap)
assert len(edges_to_swap) == 0, 'Not all edges were flipped successfully: ' + ', '.join(edges_to_swap)
# vanilla transitions
groups = list(trimmed_groups.values())
@@ -619,8 +619,8 @@ def shuffle_tiles(world, groups, result_list, do_grouped, player):
attempts = 1000
while True:
if attempts == 0: # expected to only occur with custom swaps
raise GenerationException('Could not find valid tile swaps')
if attempts == 0: # expected to only occur with custom flips
raise GenerationException('Could not find valid tile flips')
# tile shuffle happens here
removed = list()
@@ -702,7 +702,7 @@ def define_tile_groups(world, player, do_grouped):
if world.mode[player] == 'standard' and (0x1b in group or 0x2b in group or 0x2c in group):
return False
# sanctuary/chapel should not be swapped if S+Q guaranteed to output on that screen
# sanctuary/chapel should not be flipped if S+Q guaranteed to output on that screen
if 0x13 in group and ((world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] \
and (world.mode[player] in ['standard', 'inverted'] or world.doorShuffle[player] != 'crossed' or world.intensity[player] < 3)) \
or (world.shuffle[player] in ['lite', 'lean'] and world.mode[player] == 'inverted')):
@@ -843,8 +843,7 @@ def categorize_world_regions(world, player):
for exitname in OWExitTypes[type]:
world.get_entrance(exitname, player).spot_type = type
mark_light_world_regions(world, player)
mark_dark_world_regions(world, player)
mark_light_dark_world_regions(world, player)
def update_world_regions(world, player):
if world.owMixed[player]:
@@ -904,13 +903,13 @@ def can_reach_smith(world, player):
return found
def build_sectors(world, player):
from Main import copy_world_limited
from Main import copy_world_premature
from OWEdges import OWTileRegions
# perform accessibility check on duplicate world
for p in range(1, world.players + 1):
world.key_logic[p] = {}
base_world = copy_world_limited(world)
base_world = copy_world_premature(world, player)
# build lists of contiguous regions accessible with full inventory (excl portals/mirror/flute/entrances)
regions = list(OWTileRegions.copy().keys())
@@ -970,7 +969,7 @@ def build_sectors(world, player):
def build_accessible_region_list(world, start_region, player, build_copy_world=False, cross_world=False, region_rules=True, ignore_ledges = False):
from BaseClasses import CollectionState
from Main import copy_world_limited
from Main import copy_world_premature
from Items import ItemFactory
from Utils import stack_size3a
@@ -997,7 +996,7 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F
if build_copy_world:
for p in range(1, world.players + 1):
world.key_logic[p] = {}
base_world = copy_world_limited(world)
base_world = copy_world_premature(world, player)
base_world.override_bomb_check = True
else:
base_world = world
@@ -1040,7 +1039,7 @@ def validate_layout(world, player):
'Pyramid Area': ['Pyramid Exit Ledge']
}
from Main import copy_world_limited
from Main import copy_world_premature
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
@@ -1073,7 +1072,7 @@ def validate_layout(world, player):
for p in range(1, world.players + 1):
world.key_logic[p] = {}
base_world = copy_world_limited(world)
base_world = copy_world_premature(world, player)
explored_regions = list()
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not world.shufflelinks[player]: