Fix conflicts
This commit is contained in:
@@ -14,7 +14,7 @@ class World(object):
|
||||
def __init__(self, players, shuffle, doorShuffle, logic, mode, swords, difficulty, difficulty_adjustments, timer, progressive, goal, algorithm, accessibility, shuffle_ganon, quickswap, fastmenu, disable_music, retro, custom, customitemarray, hints):
|
||||
self.players = players
|
||||
self.shuffle = shuffle.copy()
|
||||
self.doorShuffle = doorShuffle.copy()
|
||||
self.doorShuffle = doorShuffle
|
||||
self.logic = logic.copy()
|
||||
self.mode = mode.copy()
|
||||
self.swords = swords.copy()
|
||||
@@ -45,9 +45,9 @@ class World(object):
|
||||
self.lock_aga_door_in_escape = False
|
||||
self.save_and_quit_from_boss = True
|
||||
self.accessibility = accessibility.copy()
|
||||
self.fix_skullwoods_exit = self.shuffle not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] or self.doorShuffle not in ['vanilla']
|
||||
self.fix_palaceofdarkness_exit = self.shuffle not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']
|
||||
self.fix_trock_exit = self.shuffle not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']
|
||||
self.fix_skullwoods_exit = {}
|
||||
self.fix_palaceofdarkness_exit = {}
|
||||
self.fix_trock_exit = {}
|
||||
self.shuffle_ganon = shuffle_ganon
|
||||
self.fix_gtower_exit = self.shuffle_ganon
|
||||
self.quickswap = quickswap
|
||||
|
||||
@@ -127,7 +127,7 @@ def vanilla_key_logic(world, player):
|
||||
raise Exception('Vanilla key layout not valid %s' % builder.name)
|
||||
if player not in world.key_logic.keys():
|
||||
world.key_logic[player] = {}
|
||||
key_layout = analyze_dungeon(key_layout, world, player)
|
||||
analyze_dungeon(key_layout, world, player)
|
||||
world.key_logic[player][builder.name] = key_layout.key_logic
|
||||
validate_vanilla_key_logic(world, player)
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ def parse_arguments(argv, no_defaults=False):
|
||||
The dungeon variants only mix up dungeons and keep the rest of
|
||||
the overworld vanilla.
|
||||
''')
|
||||
parser.add_argument('--door_shuffle', default=defvalue('vanilla'), const='vanilla', nargs='?', choices=['vanilla', 'basic', 'crossed', 'experimental'],
|
||||
parser.add_argument('--door_shuffle', default=defval('vanilla'), const='vanilla', nargs='?', choices=['vanilla', 'basic', 'crossed', 'experimental'],
|
||||
help='''\
|
||||
Select Door Shuffling Algorithm. (default: %(default)s)
|
||||
Basic: Doors are mixed within a single dungeon.
|
||||
|
||||
4
Fill.py
4
Fill.py
@@ -194,7 +194,7 @@ def fill_restrictive(world, base_state, locations, itempool, single_player_place
|
||||
spot_to_fill = None
|
||||
|
||||
for location in locations:
|
||||
if item_to_place.key: # a better test to see if a key can go there
|
||||
if item_to_place.smallkey or item_to_place.bigkey: # a better test to see if a key can go there
|
||||
location.item = item_to_place
|
||||
test_state = maximum_exploration_state.copy()
|
||||
test_state.stale[item_to_place.player] = True
|
||||
@@ -204,7 +204,7 @@ def fill_restrictive(world, base_state, locations, itempool, single_player_place
|
||||
and location.can_fill(test_state, item_to_place, perform_access_check):
|
||||
spot_to_fill = location
|
||||
break
|
||||
elif item_to_place.key:
|
||||
elif item_to_place.smallkey or item_to_place.bigkey:
|
||||
location.item = None
|
||||
|
||||
if spot_to_fill is None:
|
||||
|
||||
3
Gui.py
3
Gui.py
@@ -11,7 +11,7 @@ from urllib.parse import urlparse
|
||||
from urllib.request import urlopen
|
||||
|
||||
from AdjusterMain import adjust
|
||||
from EntranceRandomizer import parse_arguments
|
||||
from DungeonRandomizer import parse_arguments
|
||||
from GuiUtils import ToolTips, set_icon, BackgroundTaskProgress
|
||||
from Main import main, __version__ as ESVersion
|
||||
from Rom import Sprite
|
||||
@@ -329,7 +329,6 @@ def guiMain(args=None):
|
||||
shuffleFrame.pack(expand=True, anchor=E)
|
||||
doorShuffleFrame.pack(expand=True, anchor=E)
|
||||
|
||||
swordsFrame.pack(expand=True, anchor=E)
|
||||
difficultyFrame.pack(expand=True, anchor=E)
|
||||
itemfunctionFrame.pack(expand=True, anchor=E)
|
||||
timerFrame.pack(expand=True, anchor=E)
|
||||
|
||||
@@ -114,7 +114,7 @@ def analyze_dungeon(key_layout, world, player):
|
||||
while len(queue) > 0:
|
||||
queue = collections.deque(sorted(queue, key=queue_sorter))
|
||||
parent_door, key_counter = queue.popleft()
|
||||
chest_keys = available_chest_small_keys(key_counter, world)
|
||||
chest_keys = available_chest_small_keys(key_counter, world, player)
|
||||
raw_avail = chest_keys + len(key_counter.key_only_locations)
|
||||
available = raw_avail - key_counter.used_keys
|
||||
possible_smalls = count_unique_small_doors(key_counter, key_layout.flat_prop)
|
||||
@@ -135,10 +135,10 @@ def analyze_dungeon(key_layout, world, player):
|
||||
while len(child_queue) > 0:
|
||||
child, odd_counter = child_queue.popleft()
|
||||
if not child.bigKey:
|
||||
best_counter = find_best_counter(child, odd_counter, key_counter, key_layout, world, False)
|
||||
rule = create_rule(best_counter, key_counter, key_layout, world)
|
||||
best_counter = find_best_counter(child, odd_counter, key_counter, key_layout, world, player, False)
|
||||
rule = create_rule(best_counter, key_counter, key_layout, world, player)
|
||||
check_for_self_lock_key(rule, child, best_counter, key_layout, world)
|
||||
bk_restricted_rules(rule, child, odd_counter, key_counter, key_layout, world)
|
||||
bk_restricted_rules(rule, child, odd_counter, key_counter, key_layout, world, player)
|
||||
key_logic.door_rules[child.name] = rule
|
||||
doors_completed.add(child)
|
||||
next_counter = find_next_counter(child, key_counter, key_layout)
|
||||
@@ -217,7 +217,7 @@ def unique_child_door(child, key_counter):
|
||||
return True
|
||||
|
||||
|
||||
def find_best_counter(door, odd_counter, key_counter, key_layout, world, skip_bk): # try to waste as many keys as possible?
|
||||
def find_best_counter(door, odd_counter, key_counter, key_layout, world, player, skip_bk): # try to waste as many keys as possible?
|
||||
ignored_doors = {door, door.dest} if door is not None else {}
|
||||
finished = False
|
||||
opened_doors = dict(key_counter.open_doors)
|
||||
@@ -238,7 +238,7 @@ def find_best_counter(door, odd_counter, key_counter, key_layout, world, skip_bk
|
||||
if relative_empty_counter(odd_counter, new_counter):
|
||||
ignored_doors.add(new_door)
|
||||
else:
|
||||
if not key_wasted(new_door, last_counter, new_counter, key_layout, world):
|
||||
if not key_wasted(new_door, last_counter, new_counter, key_layout, world, player):
|
||||
ignored_doors.add(new_door)
|
||||
else:
|
||||
last_counter = new_counter
|
||||
@@ -266,12 +266,12 @@ def find_potential_open_doors(key_counter, ignored_doors, key_layout, skip_bk):
|
||||
return small_doors + big_doors
|
||||
|
||||
|
||||
def key_wasted(new_door, old_counter, new_counter, key_layout, world):
|
||||
def key_wasted(new_door, old_counter, new_counter, key_layout, world, player):
|
||||
if new_door.bigKey: # big keys are not wastes - it uses up a location
|
||||
return True
|
||||
chest_keys = available_chest_small_keys(old_counter, world)
|
||||
chest_keys = available_chest_small_keys(old_counter, world, player)
|
||||
old_avail = chest_keys + len(old_counter.key_only_locations) - old_counter.used_keys
|
||||
new_chest_keys = available_chest_small_keys(new_counter, world)
|
||||
new_chest_keys = available_chest_small_keys(new_counter, world, player)
|
||||
new_avail = new_chest_keys + len(new_counter.key_only_locations) - new_counter.used_keys
|
||||
if new_avail < old_avail:
|
||||
return True
|
||||
@@ -285,7 +285,7 @@ def key_wasted(new_door, old_counter, new_counter, key_layout, world):
|
||||
proposed_doors = {**opened_doors, **dict.fromkeys([new_child, new_child.dest])}
|
||||
bk_open = bk_opened or new_door.bigKey
|
||||
new_counter = find_counter(proposed_doors, bk_open, key_layout)
|
||||
if key_wasted(new_child, current_counter, new_counter, key_layout, world):
|
||||
if key_wasted(new_child, current_counter, new_counter, key_layout, world, player):
|
||||
return True # waste is possible
|
||||
return False
|
||||
|
||||
@@ -303,16 +303,16 @@ def check_special_locations(locations):
|
||||
return False
|
||||
|
||||
|
||||
def calc_avail_keys(key_counter, world):
|
||||
chest_keys = available_chest_small_keys(key_counter, world)
|
||||
def calc_avail_keys(key_counter, world, player):
|
||||
chest_keys = available_chest_small_keys(key_counter, world, player)
|
||||
raw_avail = chest_keys + len(key_counter.key_only_locations)
|
||||
return raw_avail - key_counter.used_keys
|
||||
|
||||
|
||||
def create_rule(key_counter, prev_counter, key_layout, world):
|
||||
def create_rule(key_counter, prev_counter, key_layout, world, player):
|
||||
# prev_chest_keys = available_chest_small_keys(prev_counter, world)
|
||||
# prev_avail = prev_chest_keys + len(prev_counter.key_only_locations)
|
||||
chest_keys = available_chest_small_keys(key_counter, world)
|
||||
chest_keys = available_chest_small_keys(key_counter, world, player)
|
||||
key_gain = len(key_counter.key_only_locations) - len(prev_counter.key_only_locations)
|
||||
raw_avail = chest_keys + len(key_counter.key_only_locations)
|
||||
available = raw_avail - key_counter.used_keys
|
||||
@@ -405,8 +405,8 @@ def self_lock_possible(counter):
|
||||
return len(counter.free_locations) <= 1 and len(counter.key_only_locations) == 0 and not counter.important_location
|
||||
|
||||
|
||||
def available_chest_small_keys(key_counter, world):
|
||||
if not world.keysanity and world.mode != 'retro':
|
||||
def available_chest_small_keys(key_counter, world, player):
|
||||
if not world.keyshuffle[player] and not world.retro[player]:
|
||||
cnt = 0
|
||||
for loc in key_counter.free_locations:
|
||||
if key_counter.big_key_opened or '- Big Chest' not in loc.name:
|
||||
@@ -416,11 +416,11 @@ def available_chest_small_keys(key_counter, world):
|
||||
return key_counter.max_chests
|
||||
|
||||
|
||||
def bk_restricted_rules(rule, door, odd_counter, key_counter, key_layout, world):
|
||||
def bk_restricted_rules(rule, door, odd_counter, key_counter, key_layout, world, player):
|
||||
if key_counter.big_key_opened:
|
||||
return
|
||||
best_counter = find_best_counter(door, odd_counter, key_counter, key_layout, world, True)
|
||||
bk_number = create_rule(best_counter, key_counter, key_layout, world).small_key_num
|
||||
best_counter = find_best_counter(door, odd_counter, key_counter, key_layout, world, player, True)
|
||||
bk_number = create_rule(best_counter, key_counter, key_layout, world, player).small_key_num
|
||||
if bk_number == rule.small_key_num:
|
||||
return
|
||||
door_open = find_next_counter(door, best_counter, key_layout)
|
||||
@@ -649,8 +649,8 @@ def validate_key_layout_sub_loop(key_layout, state, checked_states, flat_proposa
|
||||
if not smalls_avail and num_bigs == 0:
|
||||
return True # I think that's the end
|
||||
ttl_locations = state.ttl_locations if state.big_key_opened else count_locations_exclude_big_chest(state)
|
||||
available_small_locations = cnt_avail_small_locations(key_layout, ttl_locations, state, world)
|
||||
available_big_locations = cnt_avail_big_locations(ttl_locations, state, world)
|
||||
available_small_locations = cnt_avail_small_locations(key_layout, ttl_locations, state, world, player)
|
||||
available_big_locations = cnt_avail_big_locations(ttl_locations, state, world, player)
|
||||
if (not smalls_avail or available_small_locations == 0) and (state.big_key_opened or num_bigs == 0 or available_big_locations == 0):
|
||||
return False
|
||||
else:
|
||||
@@ -683,14 +683,14 @@ def validate_key_layout_sub_loop(key_layout, state, checked_states, flat_proposa
|
||||
return True
|
||||
|
||||
|
||||
def cnt_avail_small_locations(key_layout, ttl_locations, state, world):
|
||||
if not world.keysanity and world.mode != 'retro':
|
||||
def cnt_avail_small_locations(key_layout, ttl_locations, state, world, player):
|
||||
if not world.keyshuffle[player] and not world.retro[player]:
|
||||
return min(ttl_locations - state.used_locations, state.key_locations - state.used_smalls)
|
||||
return key_layout.max_chests + state.key_locations - state.used_smalls
|
||||
|
||||
|
||||
def cnt_avail_big_locations(ttl_locations, state, world):
|
||||
if not world.keysanity:
|
||||
def cnt_avail_big_locations(ttl_locations, state, world, player):
|
||||
if not world.bigkeyshuffle[player]:
|
||||
return ttl_locations - state.used_locations if not state.big_key_special else 0
|
||||
return 1 if not state.big_key_special else 0
|
||||
|
||||
|
||||
8
Main.py
8
Main.py
@@ -35,7 +35,7 @@ def main(args, seed=None):
|
||||
start = time.perf_counter()
|
||||
|
||||
# initialize the world
|
||||
world = World(args.multi, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords, args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm, args.accessibility, args.shuffleganon, args.quickswap, args.fastmenu, args.disablemusic, args.retro, args.custom, args.customitemarray, args.shufflebosses, args.hints)
|
||||
world = World(args.multi, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords, args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm, args.accessibility, args.shuffleganon, args.quickswap, args.fastmenu, args.disablemusic, args.retro, args.custom, args.customitemarray, args.hints)
|
||||
logger = logging.getLogger('')
|
||||
if seed is None:
|
||||
random.seed(None)
|
||||
@@ -72,8 +72,7 @@ def main(args, seed=None):
|
||||
create_doors(world, player)
|
||||
create_rooms(world, player)
|
||||
create_dungeons(world, player)
|
||||
else:
|
||||
for player in range(1, world.players + 1):
|
||||
else:
|
||||
create_inverted_regions(world, player) # todo: port all the dungeon region work
|
||||
create_doors(world, player)
|
||||
create_rooms(world, player)
|
||||
@@ -84,7 +83,6 @@ def main(args, seed=None):
|
||||
for player in range(1, world.players + 1):
|
||||
if world.mode[player] != 'inverted':
|
||||
link_entrances(world, player)
|
||||
for player in range(1, world.players + 1):
|
||||
else:
|
||||
link_inverted_entrances(world, player)
|
||||
|
||||
@@ -246,7 +244,7 @@ def main(args, seed=None):
|
||||
|
||||
def copy_world(world):
|
||||
# ToDo: Not good yet
|
||||
ret = World(world.players, 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.quickswap, world.fastmenu, world.disable_music, world.retro, world.custom, world.customitemarray, world.boss_shuffle, world.hints)
|
||||
ret = World(world.players, 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.quickswap, world.fastmenu, world.disable_music, world.retro, world.custom, world.customitemarray, world.hints)
|
||||
ret.required_medallions = world.required_medallions.copy()
|
||||
ret.swamp_patch_required = world.swamp_patch_required.copy()
|
||||
ret.ganon_at_pyramid = world.ganon_at_pyramid.copy()
|
||||
|
||||
13
Regions.py
13
Regions.py
@@ -744,10 +744,10 @@ def _create_region(player, name, type, hint='Hyrule', locations=None, exits=None
|
||||
ret.exits.append(Entrance(player, exit, ret))
|
||||
for location in locations:
|
||||
if location in key_only_locations:
|
||||
ret.locations.append(Location(player, location, None, False, None, ret, key_only_locations[location], player_address))
|
||||
ret.locations.append(Location(player, location, None, False, None, ret, key_only_locations[location]))
|
||||
else:
|
||||
address, crystal, hint_text = location_table[location]
|
||||
ret.locations.append(Location(player, location, address, crystal, hint_text, ret, player_address))
|
||||
address, player_address, crystal, hint_text = location_table[location]
|
||||
ret.locations.append(Location(player, location, address, crystal, hint_text, ret, None, player_address))
|
||||
return ret
|
||||
|
||||
def mark_light_world_regions(world, player):
|
||||
@@ -1086,6 +1086,13 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'),
|
||||
'Frog': (None, None, False, None),
|
||||
'Missing Smith': (None, None, False, None),
|
||||
'Dark Blacksmith Ruins': (None, None, False, None),
|
||||
'Trench 1 Switch': (None, None, False, None),
|
||||
'Trench 2 Switch': (None, None, False, None),
|
||||
'Swamp Drain': (None, None, False, None),
|
||||
'Attic Cracked Floor': (None, None, False, None),
|
||||
'Suspicious Maiden': (None, None, False, None),
|
||||
'Revealing Light': (None, None, False, None),
|
||||
'Ice Block Drop': (None, None, False, None),
|
||||
'Eastern Palace - Prize': ([0x1209D, 0x53EF8, 0x53EF9, 0x180052, 0x18007C, 0xC6FE], None, True, 'Eastern Palace'),
|
||||
'Desert Palace - Prize': ([0x1209E, 0x53F1C, 0x53F1D, 0x180053, 0x180078, 0xC6FF], None, True, 'Desert Palace'),
|
||||
'Tower of Hera - Prize': ([0x120A5, 0x53F0A, 0x53F0B, 0x18005A, 0x18007A, 0xC706], None, True, 'Tower of Hera'),
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user