Some ER generation improvements
Attempt at Attic Hint Tile Stonewall detection improved by not excluding drops
This commit is contained in:
@@ -9,10 +9,10 @@ from functools import reduce
|
|||||||
from BaseClasses import RegionType, Door, DoorType, Direction, Sector, CrystalBarrier
|
from BaseClasses import RegionType, Door, DoorType, Direction, Sector, CrystalBarrier
|
||||||
from Regions import key_only_locations
|
from Regions import key_only_locations
|
||||||
from Dungeons import dungeon_regions, region_starts, split_region_starts, flexible_starts
|
from Dungeons import dungeon_regions, region_starts, split_region_starts, flexible_starts
|
||||||
from Dungeons import drop_entrances, dungeon_bigs, dungeon_keys, dungeon_hints
|
from Dungeons import dungeon_bigs, dungeon_keys, dungeon_hints
|
||||||
from Items import ItemFactory
|
from Items import ItemFactory
|
||||||
from RoomData import DoorKind, PairedDoor
|
from RoomData import DoorKind, PairedDoor
|
||||||
from DungeonGenerator import ExplorationState, convert_regions, generate_dungeon, validate_tr
|
from DungeonGenerator import ExplorationState, convert_regions, generate_dungeon, pre_validate
|
||||||
from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder
|
from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder
|
||||||
from KeyDoorShuffle import analyze_dungeon, validate_vanilla_key_logic, build_key_layout, validate_key_layout
|
from KeyDoorShuffle import analyze_dungeon, validate_vanilla_key_logic, build_key_layout, validate_key_layout
|
||||||
|
|
||||||
@@ -150,11 +150,10 @@ def vanilla_key_logic(world, player):
|
|||||||
|
|
||||||
origin_list = list(entrances_map[builder.name])
|
origin_list = list(entrances_map[builder.name])
|
||||||
find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, builder.name)
|
find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, builder.name)
|
||||||
origin_list_sans_drops = remove_drop_origins(origin_list)
|
if len(origin_list) <= 0:
|
||||||
if len(origin_list_sans_drops) <= 0:
|
|
||||||
if last_key == builder.name or loops > 1000:
|
if last_key == builder.name or loops > 1000:
|
||||||
origin_name = world.get_region(origin_list[0], player).entrances[0].parent_region.name
|
origin_name = world.get_region(origin_list[0], player).entrances[0].parent_region.name if len(origin_list) > 0 else 'no origin'
|
||||||
raise Exception('Infinite loop detected for "%s" located at %s' % builder.name, origin_name)
|
raise Exception('Infinite loop detected for "%s" located at %s' % (builder.name, origin_name))
|
||||||
sector_queue.append(builder)
|
sector_queue.append(builder)
|
||||||
last_key = builder.name
|
last_key = builder.name
|
||||||
loops += 1
|
loops += 1
|
||||||
@@ -366,17 +365,16 @@ def main_dungeon_generation(dungeon_builders, recombinant_builders, connections_
|
|||||||
name = ' '.join(builder.name.split(' ')[:-1])
|
name = ' '.join(builder.name.split(' ')[:-1])
|
||||||
origin_list = list(builder.entrance_list)
|
origin_list = list(builder.entrance_list)
|
||||||
find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, name)
|
find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, name)
|
||||||
origin_list_sans_drops = remove_drop_origins(origin_list)
|
if len(origin_list) <= 0 or not pre_validate(builder, origin_list, world, player):
|
||||||
if len(origin_list_sans_drops) <= 0 or name == "Turtle Rock" and not validate_tr(builder, origin_list_sans_drops, world, player):
|
|
||||||
if last_key == builder.name or loops > 1000:
|
if last_key == builder.name or loops > 1000:
|
||||||
origin_name = world.get_region(origin_list[0], player).entrances[0].parent_region.name
|
origin_name = world.get_region(origin_list[0], player).entrances[0].parent_region.name if len(origin_list) > 0 else 'no origin'
|
||||||
raise Exception('Infinite loop detected for "%s" located at %s' % builder.name, origin_name)
|
raise Exception('Infinite loop detected for "%s" located at %s' % (builder.name, origin_name))
|
||||||
sector_queue.append(builder)
|
sector_queue.append(builder)
|
||||||
last_key = builder.name
|
last_key = builder.name
|
||||||
loops += 1
|
loops += 1
|
||||||
else:
|
else:
|
||||||
logging.getLogger('').info('%s: %s', world.fish.translate("cli","cli","generating.dungeon"), builder.name)
|
logging.getLogger('').info('%s: %s', world.fish.translate("cli","cli","generating.dungeon"), builder.name)
|
||||||
ds = generate_dungeon(builder, origin_list_sans_drops, split_dungeon, world, player)
|
ds = generate_dungeon(builder, origin_list, split_dungeon, world, player)
|
||||||
find_new_entrances(ds, entrances_map, connections, potentials, enabled_entrances, world, player)
|
find_new_entrances(ds, entrances_map, connections, potentials, enabled_entrances, world, player)
|
||||||
ds.name = name
|
ds.name = name
|
||||||
builder.master_sector = ds
|
builder.master_sector = ds
|
||||||
@@ -430,22 +428,18 @@ def find_enabled_origins(sectors, enabled, entrance_list, entrance_map, key):
|
|||||||
entrance_map[key].append(region.name)
|
entrance_map[key].append(region.name)
|
||||||
|
|
||||||
|
|
||||||
def remove_drop_origins(entrance_list):
|
|
||||||
return [x for x in entrance_list if x not in drop_entrances]
|
|
||||||
|
|
||||||
|
|
||||||
def find_new_entrances(sector, entrances_map, connections, potentials, enabled, world, player):
|
def find_new_entrances(sector, entrances_map, connections, potentials, enabled, world, player):
|
||||||
for region in sector.regions:
|
for region in sector.regions:
|
||||||
if region.name in connections.keys() and (connections[region.name] in potentials.keys() or connections[region.name].name in world.inaccessible_regions[player]):
|
if region.name in connections.keys() and (connections[region.name] in potentials.keys() or connections[region.name].name in world.inaccessible_regions[player]):
|
||||||
enable_new_entrances(region, connections, potentials, enabled, world, player)
|
enable_new_entrances(region, connections, potentials, enabled, world, player, region)
|
||||||
inverted_aga_check(entrances_map, connections, potentials, enabled, world, player)
|
inverted_aga_check(entrances_map, connections, potentials, enabled, world, player)
|
||||||
|
|
||||||
|
|
||||||
def enable_new_entrances(region, connections, potentials, enabled, world, player):
|
def enable_new_entrances(region, connections, potentials, enabled, world, player, region_enabler):
|
||||||
new_region = connections[region.name]
|
new_region = connections[region.name]
|
||||||
if new_region in potentials.keys():
|
if new_region in potentials.keys():
|
||||||
for potential in potentials.pop(new_region):
|
for potential in potentials.pop(new_region):
|
||||||
enabled[potential] = (region.name, region.dungeon)
|
enabled[potential] = (region_enabler.name, region_enabler.dungeon)
|
||||||
# see if this unexplored region connects elsewhere
|
# see if this unexplored region connects elsewhere
|
||||||
queue = deque(new_region.exits)
|
queue = deque(new_region.exits)
|
||||||
visited = set()
|
visited = set()
|
||||||
@@ -467,9 +461,10 @@ def inverted_aga_check(entrances_map, connections, potentials, enabled, world, p
|
|||||||
if 'Agahnims Tower' in entrances_map.keys() or aga_tower_enabled(enabled):
|
if 'Agahnims Tower' in entrances_map.keys() or aga_tower_enabled(enabled):
|
||||||
for region in list(potentials.keys()):
|
for region in list(potentials.keys()):
|
||||||
if region.name == 'Hyrule Castle Ledge':
|
if region.name == 'Hyrule Castle Ledge':
|
||||||
|
enabler = world.get_region('Tower Agahnim 1', player)
|
||||||
for r_name in potentials[region]:
|
for r_name in potentials[region]:
|
||||||
new_region = world.get_region(r_name, player)
|
new_region = world.get_region(r_name, player)
|
||||||
enable_new_entrances(new_region, connections, potentials, enabled, world, player)
|
enable_new_entrances(new_region, connections, potentials, enabled, world, player, enabler)
|
||||||
|
|
||||||
|
|
||||||
def aga_tower_enabled(enabled):
|
def aga_tower_enabled(enabled):
|
||||||
@@ -1374,6 +1369,8 @@ logical_connections = [
|
|||||||
('Thieves Hellway Crystal Orange Barrier', 'Thieves Hellway'),
|
('Thieves Hellway Crystal Orange Barrier', 'Thieves Hellway'),
|
||||||
('Thieves Hellway Blue Barrier', 'Thieves Hellway N Crystal'),
|
('Thieves Hellway Blue Barrier', 'Thieves Hellway N Crystal'),
|
||||||
('Thieves Hellway Crystal Blue Barrier', 'Thieves Hellway'),
|
('Thieves Hellway Crystal Blue Barrier', 'Thieves Hellway'),
|
||||||
|
('Thieves Attic Orange Barrier', 'Thieves Attic Hint'),
|
||||||
|
('Thieves Attic Hint Orange Barrier', 'Thieves Attic'),
|
||||||
('Thieves Basement Block Path', 'Thieves Blocked Entry'),
|
('Thieves Basement Block Path', 'Thieves Blocked Entry'),
|
||||||
('Thieves Blocked Entry Path', 'Thieves Basement Block'),
|
('Thieves Blocked Entry Path', 'Thieves Basement Block'),
|
||||||
('Thieves Conveyor Bridge Block Path', 'Thieves Conveyor Block'),
|
('Thieves Conveyor Bridge Block Path', 'Thieves Conveyor Block'),
|
||||||
|
|||||||
5
Doors.py
5
Doors.py
@@ -588,6 +588,8 @@ def create_doors(world, player):
|
|||||||
create_door(player, 'Thieves Spike Switch Up Stairs', Sprl).dir(Up, 0xab, 0, HTH).ss(Z, 0x1a, 0x6c, True, True).small_key().pos(0),
|
create_door(player, 'Thieves Spike Switch Up Stairs', Sprl).dir(Up, 0xab, 0, HTH).ss(Z, 0x1a, 0x6c, True, True).small_key().pos(0),
|
||||||
create_door(player, 'Thieves Attic Down Stairs', Sprl).dir(Dn, 0x64, 0, HTH).ss(Z, 0x11, 0x80, True, True),
|
create_door(player, 'Thieves Attic Down Stairs', Sprl).dir(Dn, 0x64, 0, HTH).ss(Z, 0x11, 0x80, True, True),
|
||||||
create_door(player, 'Thieves Attic ES', Intr).dir(Ea, 0x64, Bot, High).pos(0),
|
create_door(player, 'Thieves Attic ES', Intr).dir(Ea, 0x64, Bot, High).pos(0),
|
||||||
|
create_door(player, 'Thieves Attic Orange Barrier', Lgcl),
|
||||||
|
create_door(player, 'Thieves Attic Hint Orange Barrier', Lgcl),
|
||||||
create_door(player, 'Thieves Cricket Hall Left WS', Intr).dir(We, 0x64, Bot, High).pos(0),
|
create_door(player, 'Thieves Cricket Hall Left WS', Intr).dir(We, 0x64, Bot, High).pos(0),
|
||||||
create_door(player, 'Thieves Cricket Hall Left Edge', Open).dir(Ea, 0x64, None, High).edge(0, X, 0x30),
|
create_door(player, 'Thieves Cricket Hall Left Edge', Open).dir(Ea, 0x64, None, High).edge(0, X, 0x30),
|
||||||
create_door(player, 'Thieves Cricket Hall Right Edge', Open).dir(We, 0x65, None, High).edge(0, Z, 0x30),
|
create_door(player, 'Thieves Cricket Hall Right Edge', Open).dir(We, 0x65, None, High).edge(0, Z, 0x30),
|
||||||
@@ -1136,6 +1138,9 @@ def create_doors(world, player):
|
|||||||
world.get_door('Thieves Triple Bypass EN', player).barrier(CrystalBarrier.Blue)
|
world.get_door('Thieves Triple Bypass EN', player).barrier(CrystalBarrier.Blue)
|
||||||
world.get_door('Thieves Hellway Orange Barrier', player).barrier(CrystalBarrier.Orange)
|
world.get_door('Thieves Hellway Orange Barrier', player).barrier(CrystalBarrier.Orange)
|
||||||
world.get_door('Thieves Hellway Crystal Orange Barrier', player).barrier(CrystalBarrier.Orange)
|
world.get_door('Thieves Hellway Crystal Orange Barrier', player).barrier(CrystalBarrier.Orange)
|
||||||
|
world.get_door('Thieves Hellway Crystal Orange Barrier', player).barrier(CrystalBarrier.Orange)
|
||||||
|
world.get_door('Thieves Attic Orange Barrier', player).barrier(CrystalBarrier.Orange)
|
||||||
|
world.get_door('Thieves Attic Hint Orange Barrier', player).barrier(CrystalBarrier.Orange)
|
||||||
|
|
||||||
world.get_door('Ice Bomb Drop SE', player).c_switch()
|
world.get_door('Ice Bomb Drop SE', player).c_switch()
|
||||||
world.get_door('Ice Conveyor SW', player).c_switch()
|
world.get_door('Ice Conveyor SW', player).c_switch()
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ class GraphPiece:
|
|||||||
self.possible_bk_locations = set()
|
self.possible_bk_locations = set()
|
||||||
|
|
||||||
|
|
||||||
# Turtle Rock shouldn't be generated until the Big Chest entrance is reachable
|
# Dungeons shouldn't be generated until all entrances are appropriately accessible
|
||||||
def validate_tr(builder, entrance_region_names, world, player):
|
def pre_validate(builder, entrance_region_names, world, player):
|
||||||
entrance_regions = convert_regions(entrance_region_names, world, player)
|
entrance_regions = convert_regions(entrance_region_names, world, player)
|
||||||
proposed_map = {}
|
proposed_map = {}
|
||||||
doors_to_connect = {}
|
doors_to_connect = {}
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ thieves_regions = [
|
|||||||
'Thieves Big Chest Nook', 'Thieves Hallway', 'Thieves Boss', 'Thieves Pot Alcove Mid', 'Thieves Pot Alcove Bottom',
|
'Thieves Big Chest Nook', 'Thieves Hallway', 'Thieves Boss', 'Thieves Pot Alcove Mid', 'Thieves Pot Alcove Bottom',
|
||||||
'Thieves Pot Alcove Top', 'Thieves Conveyor Maze', 'Thieves Spike Track', 'Thieves Hellway',
|
'Thieves Pot Alcove Top', 'Thieves Conveyor Maze', 'Thieves Spike Track', 'Thieves Hellway',
|
||||||
'Thieves Hellway N Crystal', 'Thieves Hellway S Crystal', 'Thieves Triple Bypass', 'Thieves Spike Switch',
|
'Thieves Hellway N Crystal', 'Thieves Hellway S Crystal', 'Thieves Triple Bypass', 'Thieves Spike Switch',
|
||||||
'Thieves Attic', 'Thieves Cricket Hall Left', 'Thieves Cricket Hall Right', 'Thieves Attic Window',
|
'Thieves Attic', 'Thieves Attic Hint', 'Thieves Cricket Hall Left', 'Thieves Cricket Hall Right', 'Thieves Attic Window',
|
||||||
'Thieves Basement Block', 'Thieves Blocked Entry', 'Thieves Lonely Zazak', 'Thieves Blind\'s Cell',
|
'Thieves Basement Block', 'Thieves Blocked Entry', 'Thieves Lonely Zazak', 'Thieves Blind\'s Cell',
|
||||||
'Thieves Conveyor Bridge', 'Thieves Conveyor Block', 'Thieves Big Chest Room', 'Thieves Trap'
|
'Thieves Conveyor Bridge', 'Thieves Conveyor Block', 'Thieves Big Chest Room', 'Thieves Trap'
|
||||||
]
|
]
|
||||||
@@ -347,10 +347,6 @@ flexible_starts = {
|
|||||||
'Skull Woods': ['Skull Left Drop', 'Skull Pinball']
|
'Skull Woods': ['Skull Left Drop', 'Skull Pinball']
|
||||||
}
|
}
|
||||||
|
|
||||||
drop_entrances = [
|
|
||||||
'Sewers Rat Path', 'Skull Pinball', 'Skull Left Drop', 'Sanctuary' # Pot circle, Back drop have unique access
|
|
||||||
]
|
|
||||||
|
|
||||||
dungeon_keys = {
|
dungeon_keys = {
|
||||||
'Hyrule Castle': 'Small Key (Escape)',
|
'Hyrule Castle': 'Small Key (Escape)',
|
||||||
'Eastern Palace': 'Small Key (Eastern Palace)',
|
'Eastern Palace': 'Small Key (Eastern Palace)',
|
||||||
|
|||||||
2
Main.py
2
Main.py
@@ -24,7 +24,7 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute
|
|||||||
from ItemList import generate_itempool, difficulties, fill_prizes
|
from ItemList import generate_itempool, difficulties, fill_prizes
|
||||||
from Utils import output_path, parse_player_names
|
from Utils import output_path, parse_player_names
|
||||||
|
|
||||||
__version__ = '0.1.0.0-u'
|
__version__ = '0.1.0.1-u'
|
||||||
|
|
||||||
class EnemizerError(RuntimeError):
|
class EnemizerError(RuntimeError):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
# New Features
|
# New Features
|
||||||
|
|
||||||
* None yet
|
### Experimental features
|
||||||
|
|
||||||
|
* Open "Edge" transitions can now be linked with normal doors
|
||||||
|
* "Straight" staircases (the ones similar to normal doors) can be linked with both normal doors and edges
|
||||||
|
|
||||||
# Bug Fixes
|
# Bug Fixes
|
||||||
|
|
||||||
* Crossed Dungeon generation improvements
|
* Crossed Dungeon generation improvements
|
||||||
* Fix for Animated Tiles in crossed dungeon
|
* Fix for Animated Tiles in crossed dungeon
|
||||||
|
* Stonewall hardlock no longer reachable from certain drops (Sewer Drop, some Skull Woods drops) that were previously possible
|
||||||
|
|
||||||
|
##### In Progress
|
||||||
|
|
||||||
|
* ~~TT Attic Hint tile should have a crystal switch accessible now~~
|
||||||
@@ -473,7 +473,8 @@ def create_dungeon_regions(world, player):
|
|||||||
create_dungeon_region(player, 'Thieves Hellway S Crystal', 'Thieves\' Town', None, ['Thieves Hellway Crystal Orange Barrier', 'Thieves Hellway Crystal ES']),
|
create_dungeon_region(player, 'Thieves Hellway S Crystal', 'Thieves\' Town', None, ['Thieves Hellway Crystal Orange Barrier', 'Thieves Hellway Crystal ES']),
|
||||||
create_dungeon_region(player, 'Thieves Triple Bypass', 'Thieves\' Town', None, ['Thieves Triple Bypass WN', 'Thieves Triple Bypass EN', 'Thieves Triple Bypass SE']),
|
create_dungeon_region(player, 'Thieves Triple Bypass', 'Thieves\' Town', None, ['Thieves Triple Bypass WN', 'Thieves Triple Bypass EN', 'Thieves Triple Bypass SE']),
|
||||||
create_dungeon_region(player, 'Thieves Spike Switch', 'Thieves\' Town', ['Thieves\' Town - Spike Switch Pot Key'], ['Thieves Spike Switch SW', 'Thieves Spike Switch Up Stairs']),
|
create_dungeon_region(player, 'Thieves Spike Switch', 'Thieves\' Town', ['Thieves\' Town - Spike Switch Pot Key'], ['Thieves Spike Switch SW', 'Thieves Spike Switch Up Stairs']),
|
||||||
create_dungeon_region(player, 'Thieves Attic', 'Thieves\' Town', None, ['Thieves Attic Down Stairs', 'Thieves Attic ES']),
|
create_dungeon_region(player, 'Thieves Attic', 'Thieves\' Town', None, ['Thieves Attic Down Stairs', 'Thieves Attic ES', 'Thieves Attic Orange Barrier']),
|
||||||
|
create_dungeon_region(player, 'Thieves Attic Hint', 'Thieves\' Town', None, ['Thieves Attic Hint Orange Barrier']),
|
||||||
create_dungeon_region(player, 'Thieves Cricket Hall Left', 'Thieves\' Town', None, ['Thieves Cricket Hall Left WS', 'Thieves Cricket Hall Left Edge']),
|
create_dungeon_region(player, 'Thieves Cricket Hall Left', 'Thieves\' Town', None, ['Thieves Cricket Hall Left WS', 'Thieves Cricket Hall Left Edge']),
|
||||||
create_dungeon_region(player, 'Thieves Cricket Hall Right', 'Thieves\' Town', None, ['Thieves Cricket Hall Right Edge', 'Thieves Cricket Hall Right ES']),
|
create_dungeon_region(player, 'Thieves Cricket Hall Right', 'Thieves\' Town', None, ['Thieves Cricket Hall Right Edge', 'Thieves Cricket Hall Right ES']),
|
||||||
create_dungeon_region(player, 'Thieves Attic Window', 'Thieves\' Town', ['Thieves\' Town - Attic', 'Attic Cracked Floor'], ['Thieves Attic Window WS']),
|
create_dungeon_region(player, 'Thieves Attic Window', 'Thieves\' Town', ['Thieves\' Town - Attic', 'Attic Cracked Floor'], ['Thieves Attic Window WS']),
|
||||||
|
|||||||
Reference in New Issue
Block a user