Trap door refinement with "optional" value versus "vanilla"
Slight balance of chaos mode Warping Pool trap no longer shuffled
This commit is contained in:
@@ -146,7 +146,7 @@ class World(object):
|
||||
set_player_attr('pot_pool', {})
|
||||
set_player_attr('decoupledoors', False)
|
||||
set_player_attr('door_type_mode', 'original')
|
||||
set_player_attr('trap_door_mode', 'vanilla')
|
||||
set_player_attr('trap_door_mode', 'optional')
|
||||
set_player_attr('key_logic_algorithm', 'default')
|
||||
|
||||
set_player_attr('shopsanity', False)
|
||||
@@ -1905,6 +1905,9 @@ class Door(object):
|
||||
return world.get_room(self.roomIndex, self.player).kind(self)
|
||||
return None
|
||||
|
||||
def dungeon_name(self):
|
||||
return self.entrance.parent_region.dungeon.name if self.entrance.parent_region.dungeon else 'Cave'
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, self.__class__) and self.name == other.name
|
||||
|
||||
@@ -2962,7 +2965,7 @@ bow_mode = {'progressive': 0, 'silvers': 1, 'retro': 2, 'retro_silvers': 3}
|
||||
# additions
|
||||
# byte 12: POOT TKKK (pseudoboots, overworld_map, trap_door_mode, key_logic_algo)
|
||||
overworld_map_mode = {'default': 0, 'compass': 1, 'map': 2}
|
||||
trap_door_mode = {'vanilla': 0, 'boss': 1, 'oneway': 2}
|
||||
trap_door_mode = {'vanilla': 0, 'optional': 1, 'boss': 2, 'oneway': 3}
|
||||
key_logic_algo = {'default': 0, 'partial': 1, 'strict': 2}
|
||||
|
||||
# sfx_shuffle and other adjust items does not affect settings code
|
||||
|
||||
2
CLI.py
2
CLI.py
@@ -215,7 +215,7 @@ def parse_settings():
|
||||
'door_shuffle': 'vanilla',
|
||||
'intensity': 2,
|
||||
'door_type_mode': 'original',
|
||||
'trap_door_mode': 'vanilla',
|
||||
'trap_door_mode': 'optional',
|
||||
'key_logic_algorithm': 'default',
|
||||
'decoupledoors': False,
|
||||
'experimental': False,
|
||||
|
||||
@@ -1760,12 +1760,12 @@ class DoorTypePool:
|
||||
self.tricky += counts[6]
|
||||
|
||||
def chaos_shuffle(self, counts):
|
||||
weights = [1, 2, 4, 3, 2, 1]
|
||||
weights = [1, 2, 4, 3, 2]
|
||||
return [random.choices(self.get_choices(counts[i]), weights=weights)[0] for i, c in enumerate(counts)]
|
||||
|
||||
@staticmethod
|
||||
def get_choices(number):
|
||||
return [max(number+i, 0) for i in range(-1, 5)]
|
||||
return [max(number+i, 0) for i in range(-1, 4)]
|
||||
|
||||
|
||||
class BuilderDoorCandidates:
|
||||
@@ -1801,14 +1801,17 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player)
|
||||
ttl = 0
|
||||
suggestion_map, trap_map, flex_map = {}, {}, {}
|
||||
remaining = door_type_pool.traps
|
||||
if player in world.custom_door_types:
|
||||
if player in world.custom_door_types and 'Trap Door' in world.custom_door_types[player]:
|
||||
custom_trap_doors = world.custom_door_types[player]['Trap Door']
|
||||
else:
|
||||
custom_trap_doors = defaultdict(list)
|
||||
|
||||
for dungeon in pool:
|
||||
builder = world.dungeon_layouts[player][dungeon]
|
||||
find_trappable_candidates(builder, world, player) # todo:
|
||||
if 'Mire Warping Pool' in builder.master_sector.region_set():
|
||||
custom_trap_doors[dungeon].append(world.get_door('Mire Warping Pool ES', player))
|
||||
world.custom_door_types[player]['Trap Door'] = custom_trap_doors
|
||||
find_trappable_candidates(builder, world, player)
|
||||
if custom_trap_doors[dungeon]:
|
||||
builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, custom_trap_doors[dungeon])
|
||||
remaining -= len(custom_trap_doors[dungeon])
|
||||
@@ -1852,6 +1855,10 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player)
|
||||
# time to re-assign
|
||||
else:
|
||||
trap_map = {dungeon: [] for dungeon in pool}
|
||||
for dungeon in pool:
|
||||
builder = world.dungeon_layouts[player][dungeon]
|
||||
if 'Mire Warping Pool' in builder.master_sector.region_set():
|
||||
trap_map[dungeon].append(world.get_door('Mire Warping Pool ES', player))
|
||||
reassign_trap_doors(trap_map, world, player)
|
||||
for name, traps in trap_map.items():
|
||||
used_doors.update(traps)
|
||||
@@ -1863,7 +1870,7 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world,
|
||||
ttl = 0
|
||||
suggestion_map, bk_map, flex_map = {}, {}, {}
|
||||
remaining = door_type_pool.bigs
|
||||
if player in world.custom_door_types:
|
||||
if player in world.custom_door_types and 'Big Key Door' in world.custom_door_types[player]:
|
||||
custom_bk_doors = world.custom_door_types[player]['Big Key Door']
|
||||
else:
|
||||
custom_bk_doors = defaultdict(list)
|
||||
@@ -1925,7 +1932,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl
|
||||
suggestion_map, small_map, flex_map = {}, {}, {}
|
||||
remaining = door_type_pool.smalls
|
||||
total_keys = remaining
|
||||
if player in world.custom_door_types:
|
||||
if player in world.custom_door_types and 'Key Door' in world.custom_door_types[player]:
|
||||
custom_key_doors = world.custom_door_types[player]['Key Door']
|
||||
else:
|
||||
custom_key_doors = defaultdict(list)
|
||||
@@ -2025,7 +2032,7 @@ def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, worl
|
||||
remaining_bomb = door_type_pool.bombable
|
||||
remaining_dash = door_type_pool.dashable
|
||||
|
||||
if player in world.custom_door_types:
|
||||
if player in world.custom_door_types and 'Bomb Door' in world.custom_door_types[player]:
|
||||
custom_bomb_doors = world.custom_door_types[player]['Bomb Door']
|
||||
custom_dash_doors = world.custom_door_types[player]['Dash Door']
|
||||
else:
|
||||
@@ -2164,7 +2171,7 @@ def find_trappable_candidates(builder, world, player):
|
||||
def find_valid_trap_combination(builder, suggested, start_regions, paths, world, player, drop=True):
|
||||
trap_door_pool = builder.candidates.trap
|
||||
trap_doors_needed = suggested
|
||||
if player in world.custom_door_types:
|
||||
if player in world.custom_door_types and 'Trap Door' in world.custom_door_types[player]:
|
||||
custom_trap_doors = world.custom_door_types[player]['Trap Door'][builder.name]
|
||||
else:
|
||||
custom_trap_doors = []
|
||||
@@ -2319,20 +2326,16 @@ def reassign_trap_doors(trap_map, world, player):
|
||||
d.blocked = False
|
||||
for d in traps:
|
||||
change_door_to_trap(d, world, player)
|
||||
world.spoiler.set_door_type(d.name, 'Trap Door', player)
|
||||
logger.debug('Trap Door: %s', d.name)
|
||||
world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', 'Trap Door', player)
|
||||
logger.debug(f'Trap Door: {d.name} ({d.dungeon_name()})')
|
||||
|
||||
|
||||
def exclude_boss_traps(d):
|
||||
return ' Boss ' not in d.name and ' Agahnim ' not in d.name and d.name not in ['Skull Spike Corner SW',
|
||||
'Mire Warping Pool ES']
|
||||
|
||||
def exclude_logic_traps(d):
|
||||
return d.name != 'Mire Warping Pool ES'
|
||||
return ' Boss ' not in d.name and ' Agahnim ' not in d.name and d.name not in ['Skull Spike Corner SW']
|
||||
|
||||
|
||||
def find_current_trap_doors(builder, world, player):
|
||||
checker = exclude_boss_traps if world.trap_door_mode[player] == 'vanilla' else exclude_logic_traps
|
||||
checker = exclude_boss_traps if world.trap_door_mode[player] in ['vanilla', 'optional'] else (lambda x: True)
|
||||
current_doors = []
|
||||
for region in builder.master_sector.regions:
|
||||
for ext in region.exits:
|
||||
@@ -2452,7 +2455,7 @@ def find_big_key_door_candidates(region, checked, used, world, player):
|
||||
def find_valid_bk_combination(builder, suggested, start_regions, world, player, drop=True):
|
||||
bk_door_pool = builder.candidates.big
|
||||
bk_doors_needed = suggested
|
||||
if player in world.custom_door_types:
|
||||
if player in world.custom_door_types and 'Big Key Door' in world.custom_door_types[player]:
|
||||
custom_bk_doors = world.custom_door_types[player]['Big Key Door'][builder.name]
|
||||
else:
|
||||
custom_bk_doors = []
|
||||
@@ -2527,8 +2530,8 @@ def reassign_big_key_doors(bk_map, world, player):
|
||||
world.paired_doors[player].append(PairedDoor(d1.name, d2.name))
|
||||
change_door_to_big_key(d1, world, player)
|
||||
change_door_to_big_key(d2, world, player)
|
||||
world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Big Key Door', player)
|
||||
logger.debug(f'Big Key Door: {d1.name} <-> {d2.name}')
|
||||
world.spoiler.set_door_type(f'{d1.name} <-> {d2.name} ({d1.dungeon_name()})', 'Big Key Door', player)
|
||||
logger.debug(f'Big Key Door: {d1.name} <-> {d2.name} ({d1.dungeon_name()})')
|
||||
else:
|
||||
d = obj
|
||||
if d.type is DoorType.Interior:
|
||||
@@ -2545,8 +2548,8 @@ def reassign_big_key_doors(bk_map, world, player):
|
||||
if stateful_door(d.dest, dest_room.kind(d.dest)):
|
||||
change_door_to_big_key(d.dest, world, player)
|
||||
add_pair(d, d.dest, world, player)
|
||||
world.spoiler.set_door_type(d.name, 'Big Key Door', player)
|
||||
logger.debug(f'Big Key Door: {d.name}')
|
||||
world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', 'Big Key Door', player)
|
||||
logger.debug(f'Big Key Door: {d.name} ({d.dungeon_name()})')
|
||||
|
||||
|
||||
def change_door_to_big_key(d, world, player):
|
||||
@@ -2596,7 +2599,7 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k
|
||||
logger = logging.getLogger('')
|
||||
key_door_pool = list(builder.candidates.small)
|
||||
key_doors_needed = target
|
||||
if player in world.custom_door_types:
|
||||
if player in world.custom_door_types and 'Key Door' in world.custom_door_types[player]:
|
||||
custom_key_doors = world.custom_door_types[player]['Key Door'][builder.name]
|
||||
else:
|
||||
custom_key_doors = []
|
||||
@@ -2724,7 +2727,7 @@ def find_valid_bd_combination(builder, suggested, world, player):
|
||||
bd_door_pool = builder.candidates.bomb_dash
|
||||
bomb_doors_needed, dash_doors_needed = suggested
|
||||
ttl_needed = bomb_doors_needed + dash_doors_needed
|
||||
if player in world.custom_door_types:
|
||||
if player in world.custom_door_types and 'Bomb Door' in world.custom_door_types[player]:
|
||||
custom_bomb_doors = world.custom_door_types[player]['Bomb Door'][builder.name]
|
||||
custom_dash_doors = world.custom_door_types[player]['Dash Door'][builder.name]
|
||||
else:
|
||||
@@ -2800,7 +2803,7 @@ def do_bombable_dashable(proposal, kind, world, player):
|
||||
change_door_to_kind(d1, kind, world, player)
|
||||
change_door_to_kind(d2, kind, world, player)
|
||||
spoiler_type = 'Bomb Door' if kind == DoorKind.Bombable else 'Dash Door'
|
||||
world.spoiler.set_door_type(d1.name+' <-> '+d2.name, spoiler_type, player)
|
||||
world.spoiler.set_door_type(f'{d1.name} <-> {d2.name} ({d1.dungeon_name()})', spoiler_type, player)
|
||||
else:
|
||||
d = obj
|
||||
if d.type is DoorType.Interior:
|
||||
@@ -2814,7 +2817,7 @@ def do_bombable_dashable(proposal, kind, world, player):
|
||||
change_door_to_kind(d.dest, kind, world, player)
|
||||
add_pair(d, d.dest, world, player)
|
||||
spoiler_type = 'Bomb Door' if kind == DoorKind.Bombable else 'Dash Door'
|
||||
world.spoiler.set_door_type(d.name, spoiler_type, player)
|
||||
world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', spoiler_type, player)
|
||||
|
||||
|
||||
def find_current_bd_doors(builder, world):
|
||||
@@ -3017,8 +3020,8 @@ def reassign_key_doors(small_map, world, player):
|
||||
world.paired_doors[player].append(PairedDoor(d1.name, d2.name))
|
||||
change_door_to_small_key(d1, world, player)
|
||||
change_door_to_small_key(d2, world, player)
|
||||
world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Key Door', player)
|
||||
logger.debug('Key Door: %s', d1.name+' <-> '+d2.name)
|
||||
world.spoiler.set_door_type(f'{d1.name} <-> {d2.name} ({d1.dungeon_name()})', 'Key Door', player)
|
||||
logger.debug(f'Key Door: {d1.name} <-> {d2.name} ({d1.dungeon_name()})')
|
||||
else:
|
||||
d = obj
|
||||
if d.type is DoorType.Interior:
|
||||
@@ -3034,8 +3037,8 @@ def reassign_key_doors(small_map, world, player):
|
||||
if stateful_door(d.dest, dest_room.kind(d.dest)):
|
||||
change_door_to_small_key(d.dest, world, player)
|
||||
add_pair(d, d.dest, world, player)
|
||||
world.spoiler.set_door_type(d.name, 'Key Door', player)
|
||||
logger.debug('Key Door: %s', d.name)
|
||||
world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', 'Key Door', player)
|
||||
logger.debug(f'Key Door: {d.name} ({d.dungeon_name()})')
|
||||
|
||||
|
||||
def change_door_to_small_key(d, world, player):
|
||||
@@ -3225,7 +3228,7 @@ def change_pair_type(door, new_type, world, player):
|
||||
room_b.change(door.dest.doorListPos, new_type)
|
||||
add_pair(door, door.dest, world, player)
|
||||
spoiler_type = 'Bomb Door' if new_type == DoorKind.Bombable else 'Dash Door'
|
||||
world.spoiler.set_door_type(door.name + ' <-> ' + door.dest.name, spoiler_type, player)
|
||||
world.spoiler.set_door_type(f'{door.name} <-> {door.dest.name} ({door.dungeon_name()})', spoiler_type, player)
|
||||
|
||||
|
||||
def remove_pair_type_if_present(door, world, player):
|
||||
@@ -4578,7 +4581,7 @@ door_type_counts = {
|
||||
'Agahnims Tower': (4, 0, 1, 0, 0, 1, 0),
|
||||
'Swamp Palace': (6, 0, 0, 2, 0, 0, 0),
|
||||
'Palace of Darkness': (6, 1, 1, 3, 2, 0, 0),
|
||||
'Misery Mire': (6, 3, 4, 2, 0, 0, 0),
|
||||
'Misery Mire': (6, 3, 5, 2, 0, 0, 0),
|
||||
'Skull Woods': (5, 0, 1, 2, 0, 1, 0),
|
||||
'Ice Palace': (6, 1, 3, 0, 0, 0, 0),
|
||||
'Tower of Hera': (1, 1, 0, 0, 0, 0, 0),
|
||||
|
||||
@@ -3565,7 +3565,7 @@ def check_for_valid_layout(builder, sector_list, builder_info):
|
||||
builder.exception_list = list(sector_list)
|
||||
return True, {}, package
|
||||
except (GenerationException, NeutralizingException, OtherGenException) as e:
|
||||
logging.getLogger('').info(f'Bailing on this layout for', e)
|
||||
logging.getLogger('').info(f'Bailing on this layout for {builder.name}', exc_info=1)
|
||||
builder.split_dungeon_map = None
|
||||
builder.valid_proposal = None
|
||||
if temp_builder.name == 'Hyrule Castle' and temp_builder.throne_door:
|
||||
|
||||
2
Main.py
2
Main.py
@@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new
|
||||
from source.tools.BPS import create_bps_from_data
|
||||
from source.classes.CustomSettings import CustomSettings
|
||||
|
||||
__version__ = '1.2.0.7-u'
|
||||
__version__ = '1.2.0.8-u'
|
||||
|
||||
from source.classes.BabelFish import BabelFish
|
||||
|
||||
|
||||
17
README.md
17
README.md
@@ -139,20 +139,25 @@ Four options here, and all of them only take effect if Dungeon Door Shuffle is n
|
||||
|
||||
* Small Key Doors, Bomb Doors, Dash Doors: This is what was normally shuffled previously
|
||||
* Adds Big Keys Doors: Big key doors are now shuffled in addition to those above, and Big Key doors are enabled to be on in both vertical directions thanks to a graphic that ended up on the cutting room floor. This does change
|
||||
* Adds Trap Doors: All trap doors that are permanently shut in vanilla are shuffled.
|
||||
* Adds Trap Doors: All trap doors that are permanently shut in vanilla are shuffled, excluding those by bosses.
|
||||
* Increases all Door Types: This is a chaos mode where each door type per dungeon is randomized between 1 less and 4 more.
|
||||
|
||||
CLI: `--door_type_mode [original|big|all|chaos]`
|
||||
|
||||
### Trap Door Removal
|
||||
|
||||
Three options here for making dungeon traversal nicer. Only applies if door shuffle is not vanilla.
|
||||
Options here for making dungeon traversal nicer. Only applies if door shuffle is not vanilla.
|
||||
|
||||
* Normal: This does not remove any trap doors. Note that boss trap doors are never shuffled in this mode.
|
||||
* Remove Boss Traps: Boss traps are removed this includes the one near Mothula.
|
||||
* Remove All Annoying Traps: This removes all trap doors that are annoying, including boss traps. Note, that the trap door near the mire cutscene chest is left alone because it enforces the use of fire to get to the chest.
|
||||
* No Removal: This does not remove any trap doors.
|
||||
* Removed If Blocking Path: Dungeon generation is relaxed to allow annoying trap doors to be removed if necessary. Note that boss trap doors are never shuffled in this mode.
|
||||
* Remove Boss Traps: Boss traps are removed, this includes the one near Mothula.
|
||||
* Remove All Annoying Traps: This removes all trap doors that are annoying, including boss traps.
|
||||
|
||||
CLI: `--trap_door_mode [vanilla|boss|oneway]`
|
||||
If trap doors are shuffled the first two option behave the same. The last option overrides the shuffle because there is nothing left to shuffle. Boss traps are never shuffled.
|
||||
|
||||
In all cases, that the trap door near the mire cutscene chest (Mire Warping Pool ES) is left alone because it enforces the use of fire to get to the chest.
|
||||
|
||||
CLI: `--trap_door_mode [vanilla|optional|boss|oneway]`
|
||||
|
||||
### Key Logic Algorithm
|
||||
|
||||
|
||||
@@ -109,6 +109,12 @@ These are now independent of retro mode and have three options: None, Random, an
|
||||
|
||||
# Bug Fixes and Notes
|
||||
* 1.2.0.8-u
|
||||
* New Features: trap_door_mode and key_logic_algorithm
|
||||
* Change S&Q in door shuffle + standard during escape to spawn as Uncle
|
||||
* Fix for vanilla doors + certain ER modes
|
||||
* Fix for unintentional decoupled door in standard
|
||||
* Fix a problem with BK doors being one-sided
|
||||
* Change to how wilds keys are placed in standard, better randomization
|
||||
* Removed a Triforce text
|
||||
* Fix for Desert Tiles 1 key door
|
||||
* 1.2.0.7-u
|
||||
|
||||
@@ -7,12 +7,30 @@ algorithm:
|
||||
district: 1
|
||||
door_shuffle:
|
||||
vanilla: 1
|
||||
basic: 2
|
||||
basic: 1
|
||||
partitioned: 1
|
||||
crossed: 3 # crossed yield more errors so is preferred
|
||||
intensity:
|
||||
1: 1
|
||||
2: 1
|
||||
3: 2 # intensity 3 usually yield more errors
|
||||
door_type_mode:
|
||||
original: 2
|
||||
big: 2
|
||||
all: 1
|
||||
chaos: 1
|
||||
trap_door_mode:
|
||||
vanilla: 3 # more errors
|
||||
optional: 1
|
||||
boss: 1
|
||||
oneway: 1
|
||||
key_logic_algorithm:
|
||||
default: 1
|
||||
partial: 0
|
||||
strict: 0
|
||||
decoupledoors:
|
||||
off: 9 # more strict
|
||||
on: 1
|
||||
dropshuffle:
|
||||
on: 1
|
||||
off: 1
|
||||
|
||||
@@ -196,6 +196,7 @@
|
||||
"trap_door_mode": {
|
||||
"choices": [
|
||||
"vanilla",
|
||||
"optional",
|
||||
"boss",
|
||||
"oneway"
|
||||
]
|
||||
|
||||
@@ -242,8 +242,9 @@
|
||||
"trap_door_mode" : [
|
||||
"Trap Door Removal (default: %(default)s)",
|
||||
"vanilla: No trap door removal",
|
||||
"boss: Remove boss traps",
|
||||
"oneway: Remove annoying trap doors"
|
||||
"optional: Trap doors removed if blocking",
|
||||
"boss: Also remove boss traps",
|
||||
"oneway: Remove all annoying trap doors"
|
||||
],
|
||||
"key_logic_algorithm": [
|
||||
"Key Logic Algorithm (default: %(default)s)",
|
||||
|
||||
@@ -93,8 +93,9 @@
|
||||
|
||||
"randomizer.dungeon.trap_door_mode": "Trap Door Removal",
|
||||
"randomizer.dungeon.trap_door_mode.vanilla": "No Removal",
|
||||
"randomizer.dungeon.trap_door_mode.boss": "Remove Boss Traps",
|
||||
"randomizer.dungeon.trap_door_mode.oneway": "Remove Annoying Traps",
|
||||
"randomizer.dungeon.trap_door_mode.optional": "Removed If Blocking Path",
|
||||
"randomizer.dungeon.trap_door_mode.boss": "Also Remove Boss Traps",
|
||||
"randomizer.dungeon.trap_door_mode.oneway": "Remove All Annoying Traps",
|
||||
|
||||
"randomizer.dungeon.key_logic_algorithm": "Key Logic Algorithm",
|
||||
"randomizer.dungeon.key_logic_algorithm.default": "Default",
|
||||
|
||||
@@ -46,12 +46,16 @@
|
||||
},
|
||||
"trap_door_mode": {
|
||||
"type": "selectbox",
|
||||
"default": "vanilla",
|
||||
"default": "optional",
|
||||
"options": [
|
||||
"vanilla",
|
||||
"optional",
|
||||
"boss",
|
||||
"oneway"
|
||||
]
|
||||
],
|
||||
"config": {
|
||||
"width": 30
|
||||
}
|
||||
},
|
||||
"key_logic_algorithm": {
|
||||
"type": "selectbox",
|
||||
|
||||
@@ -631,6 +631,7 @@ class ExplorationState(object):
|
||||
elif not self.in_door_list(door, self.avail_doors):
|
||||
self.append_door_to_list(door, self.avail_doors, flag)
|
||||
|
||||
# same as above but traps are ignored, and flag is not used
|
||||
def add_all_doors_check_proposed_2(self, region, proposed_map, valid_doors, world, player):
|
||||
for door in get_doors(world, region, player):
|
||||
if door in proposed_map and door.name in valid_doors:
|
||||
@@ -651,6 +652,27 @@ class ExplorationState(object):
|
||||
elif not self.in_door_list(door, self.avail_doors):
|
||||
self.append_door_to_list(door, self.avail_doors)
|
||||
|
||||
# same as above but traps are checked for
|
||||
def add_all_doors_check_proposed_3(self, region, proposed_map, valid_doors, world, player):
|
||||
for door in get_doors(world, region, player):
|
||||
if door in proposed_map and door.name in valid_doors:
|
||||
self.visited_doors.add(door)
|
||||
if self.can_traverse(door):
|
||||
if door.controller is not None:
|
||||
door = door.controller
|
||||
if door.dest is None and door not in proposed_map.keys() and door.name in valid_doors:
|
||||
if not self.in_door_list_ic(door, self.unattached_doors):
|
||||
self.append_door_to_list(door, self.unattached_doors)
|
||||
else:
|
||||
other = self.find_door_in_list(door, self.unattached_doors)
|
||||
if self.crystal != other.crystal:
|
||||
other.crystal = CrystalBarrier.Either
|
||||
elif door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door,
|
||||
self.event_doors):
|
||||
self.append_door_to_list(door, self.event_doors)
|
||||
elif not self.in_door_list(door, self.avail_doors):
|
||||
self.append_door_to_list(door, self.avail_doors)
|
||||
|
||||
def add_all_doors_check_proposed_traps(self, region, proposed_traps, world, player):
|
||||
for door in get_doors(world, region, player):
|
||||
if self.can_traverse_ignore_traps(door) and door not in proposed_traps:
|
||||
@@ -837,6 +859,9 @@ def extend_reachable_state_lenient(search_regions, state, proposed_map, all_regi
|
||||
local_state = state.copy()
|
||||
for region in search_regions:
|
||||
local_state.visit_region(region)
|
||||
if world.trap_door_mode[player] == 'vanilla':
|
||||
local_state.add_all_doors_check_proposed_3(region, proposed_map, valid_doors, world, player)
|
||||
else:
|
||||
local_state.add_all_doors_check_proposed_2(region, proposed_map, valid_doors, world, player)
|
||||
while len(local_state.avail_doors) > 0:
|
||||
explorable_door = local_state.next_avail_door()
|
||||
@@ -848,6 +873,9 @@ def extend_reachable_state_lenient(search_regions, state, proposed_map, all_regi
|
||||
if (valid_region_to_explore_in_regions(connect_region, all_regions, world, player)
|
||||
and not local_state.visited(connect_region)):
|
||||
local_state.visit_region(connect_region)
|
||||
if world.trap_door_mode[player] == 'vanilla':
|
||||
local_state.add_all_doors_check_proposed_3(connect_region, proposed_map, valid_doors, world, player)
|
||||
else:
|
||||
local_state.add_all_doors_check_proposed_2(connect_region, proposed_map, valid_doors, world, player)
|
||||
return local_state
|
||||
|
||||
|
||||
Reference in New Issue
Block a user