Moved OW sector and region search to OW class

This commit is contained in:
codemann8
2021-11-27 06:25:30 -06:00
parent 745c82d957
commit 7861b4e8a7
2 changed files with 97 additions and 95 deletions

View File

@@ -1,7 +1,8 @@
import logging import logging
from collections import defaultdict from collections import defaultdict
import RaceRandom as random import RaceRandom as random
from BaseClasses import CollectionState, RegionType, Terrain from BaseClasses import CollectionState, RegionType
from OverworldShuffle import build_accessible_region_list
from OWEdges import OWTileRegions from OWEdges import OWTileRegions
entrance_pool = list() entrance_pool = list()
@@ -28,6 +29,7 @@ def link_entrances(world, player):
Old_Man_House = Old_Man_House_Base.copy() Old_Man_House = Old_Man_House_Base.copy()
Cave_Three_Exits = Cave_Three_Exits_Base.copy() Cave_Three_Exits = Cave_Three_Exits_Base.copy()
from OverworldShuffle import build_sectors
sectors = build_sectors(world, player) sectors = build_sectors(world, player)
# modifications to lists # modifications to lists
@@ -1634,100 +1636,6 @@ def unbias_dungeons(Dungeon_Exits):
tuplize_lists_in_list(Dungeon_Exits) tuplize_lists_in_list(Dungeon_Exits)
def build_sectors(world, player):
from Main import copy_world
from OWEdges import OWTileRegions
# perform accessibility check on duplicate world
for player in range(1, world.players + 1):
world.key_logic[player] = {}
base_world = copy_world(world)
world.key_logic = {}
# build lists of contiguous regions accessible with full inventory (excl portals/mirror/flute/entrances)
regions = list(OWTileRegions.copy().keys())
sectors = list()
while(len(regions) > 0):
explored_regions = build_accessible_region_list(base_world, regions[0], player, False, False, False, False)
regions = [r for r in regions if r not in explored_regions]
unique_regions = [_ for i in range(len(sectors)) for _ in sectors[i]]
if (any(r in unique_regions for r in explored_regions)):
for s in range(len(sectors)):
if (any(r in sectors[s] for r in explored_regions)):
sectors[s] = set(list(sectors[s]) + list(explored_regions))
break
else:
sectors.append(explored_regions)
# remove water regions if Flippers not in starting inventory
if not any(map(lambda i: i.name == 'Flippers', world.precollected_items)):
for s in range(len(sectors)):
terrains = list()
for regionname in sectors[s]:
region = world.get_region(regionname, player)
if region.terrain == Terrain.Land:
terrains.append(regionname)
sectors[s] = terrains
# within each group, split into contiguous regions accessible only with starting inventory
for s in range(len(sectors)):
regions = list(sectors[s]).copy()
sectors2 = list()
while(len(regions) > 0):
explored_regions = build_accessible_region_list(base_world, regions[0], player, False, False, True, False)
regions = [r for r in regions if r not in explored_regions]
unique_regions = [_ for i in range(len(sectors2)) for _ in sectors2[i]]
if (any(r in unique_regions for r in explored_regions)):
for s2 in range(len(sectors2)):
if (any(r in sectors2[s2] for r in explored_regions)):
sectors2[s2] = set(list(sectors2[s2]) + list(explored_regions))
break
else:
sectors2.append(explored_regions)
sectors[s] = sectors2
return sectors
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 Items import ItemFactory
def explore_region(region_name, region=None):
explored_regions.add(region_name)
if not region:
region = base_world.get_region(region_name, player)
for exit in region.exits:
if exit.connected_region is not None:
if any(map(lambda i: i.name == 'Ocarina', base_world.precollected_items)) and exit.spot_type == 'Flute':
fluteregion = exit.connected_region
for flutespot in fluteregion.exits:
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:
explore_region(flutespot.connected_region.name, flutespot.connected_region)
elif exit.connected_region.name not in explored_regions \
and (exit.connected_region.type == region.type or (cross_world and exit.connected_region.type in [RegionType.LightWorld, RegionType.DarkWorld])) \
and (not region_rules or exit.access_rule(blank_state)) and (not ignore_ledges or exit.spot_type != 'Ledge'):
explore_region(exit.connected_region.name, exit.connected_region)
if build_copy_world:
for player in range(1, world.players + 1):
world.key_logic[player] = {}
base_world = copy_world(world)
base_world.override_bomb_check = True
world.key_logic = {}
else:
base_world = world
connect_simple(base_world, 'Links House S&Q', start_region, player)
blank_state = CollectionState(base_world)
if base_world.mode[player] == 'standard':
blank_state.collect(ItemFactory('Zelda Delivered', player), True)
explored_regions = set()
explore_region(start_region)
return explored_regions
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
from Items import ItemFactory from Items import ItemFactory

View File

@@ -820,6 +820,100 @@ def can_reach_smith(world, player):
explore_region('Dark Sanctuary Hint') explore_region('Dark Sanctuary Hint')
return found return found
def build_sectors(world, player):
from Main import copy_world
from OWEdges import OWTileRegions
# perform accessibility check on duplicate world
for player in range(1, world.players + 1):
world.key_logic[player] = {}
base_world = copy_world(world)
world.key_logic = {}
# build lists of contiguous regions accessible with full inventory (excl portals/mirror/flute/entrances)
regions = list(OWTileRegions.copy().keys())
sectors = list()
while(len(regions) > 0):
explored_regions = build_accessible_region_list(base_world, regions[0], player, False, False, False, False)
regions = [r for r in regions if r not in explored_regions]
unique_regions = [_ for i in range(len(sectors)) for _ in sectors[i]]
if (any(r in unique_regions for r in explored_regions)):
for s in range(len(sectors)):
if (any(r in sectors[s] for r in explored_regions)):
sectors[s] = set(list(sectors[s]) + list(explored_regions))
break
else:
sectors.append(explored_regions)
# remove water regions if Flippers not in starting inventory
if not any(map(lambda i: i.name == 'Flippers', world.precollected_items)):
for s in range(len(sectors)):
terrains = list()
for regionname in sectors[s]:
region = world.get_region(regionname, player)
if region.terrain == Terrain.Land:
terrains.append(regionname)
sectors[s] = terrains
# within each group, split into contiguous regions accessible only with starting inventory
for s in range(len(sectors)):
regions = list(sectors[s]).copy()
sectors2 = list()
while(len(regions) > 0):
explored_regions = build_accessible_region_list(base_world, regions[0], player, False, False, True, False)
regions = [r for r in regions if r not in explored_regions]
unique_regions = [_ for i in range(len(sectors2)) for _ in sectors2[i]]
if (any(r in unique_regions for r in explored_regions)):
for s2 in range(len(sectors2)):
if (any(r in sectors2[s2] for r in explored_regions)):
sectors2[s2] = set(list(sectors2[s2]) + list(explored_regions))
break
else:
sectors2.append(explored_regions)
sectors[s] = sectors2
return sectors
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 Items import ItemFactory
from Utils import stack_size3a
def explore_region(region_name, region=None):
explored_regions.add(region_name)
if not region:
region = base_world.get_region(region_name, player)
for exit in region.exits:
if exit.connected_region is not None:
if any(map(lambda i: i.name == 'Ocarina', base_world.precollected_items)) and exit.spot_type == 'Flute':
fluteregion = exit.connected_region
for flutespot in fluteregion.exits:
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:
explore_region(flutespot.connected_region.name, flutespot.connected_region)
elif exit.connected_region.name not in explored_regions \
and (exit.connected_region.type == region.type or (cross_world and exit.connected_region.type in [RegionType.LightWorld, RegionType.DarkWorld])) \
and (not region_rules or exit.access_rule(blank_state)) and (not ignore_ledges or exit.spot_type != 'Ledge'):
explore_region(exit.connected_region.name, exit.connected_region)
if build_copy_world:
for player in range(1, world.players + 1):
world.key_logic[player] = {}
base_world = copy_world(world)
base_world.override_bomb_check = True
world.key_logic = {}
else:
base_world = world
connect_simple(base_world, 'Links House S&Q', start_region, player)
blank_state = CollectionState(base_world)
if base_world.mode[player] == 'standard':
blank_state.collect(ItemFactory('Zelda Delivered', player), True)
explored_regions = set()
explore_region(start_region)
return explored_regions
test_connections = [ test_connections = [
#('Links House ES', 'Octoballoon WS'), #('Links House ES', 'Octoballoon WS'),
#('Links House NE', 'Lost Woods Pass SW') #('Links House NE', 'Lost Woods Pass SW')