Lobby logic improvements
Cutoff entrance rug re-work
This commit is contained in:
@@ -1186,6 +1186,7 @@ class Door(object):
|
|||||||
self.deadEnd = False
|
self.deadEnd = False
|
||||||
self.passage = True
|
self.passage = True
|
||||||
self.dungeonLink = None
|
self.dungeonLink = None
|
||||||
|
self.bk_shuffle_req = False
|
||||||
# self.incognitoPos = -1
|
# self.incognitoPos = -1
|
||||||
# self.sectorLink = False
|
# self.sectorLink = False
|
||||||
|
|
||||||
@@ -1328,6 +1329,13 @@ class Door(object):
|
|||||||
self.portalAble = True
|
self.portalAble = True
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def dead_end(self, allowPassage=False):
|
||||||
|
self.deadEnd = True
|
||||||
|
if allowPassage:
|
||||||
|
self.passage = True
|
||||||
|
else:
|
||||||
|
self.passage = False
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return isinstance(other, self.__class__) and self.name == other.name
|
return isinstance(other, self.__class__) and self.name == other.name
|
||||||
|
|
||||||
@@ -1552,6 +1560,12 @@ class Portal(object):
|
|||||||
else:
|
else:
|
||||||
return 0x12
|
return 0x12
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.__unicode__())
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return f'{self.name}:{self.door.name}'
|
||||||
|
|
||||||
|
|
||||||
class DungeonInfo(object):
|
class DungeonInfo(object):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ def link_doors(world, player):
|
|||||||
for entrance, ext in straight_staircases:
|
for entrance, ext in straight_staircases:
|
||||||
connect_two_way(world, entrance, ext, player)
|
connect_two_way(world, entrance, ext, player)
|
||||||
|
|
||||||
choose_portals(world, player)
|
if world.intensity[player] >= 3:
|
||||||
|
choose_portals(world, player)
|
||||||
|
|
||||||
if world.doorShuffle[player] == 'vanilla':
|
if world.doorShuffle[player] == 'vanilla':
|
||||||
for entrance, ext in open_edges:
|
for entrance, ext in open_edges:
|
||||||
@@ -312,6 +313,7 @@ def choose_portals(world, player):
|
|||||||
|
|
||||||
if world.doorShuffle[player] in ['basic', 'crossed']:
|
if world.doorShuffle[player] in ['basic', 'crossed']:
|
||||||
cross_flag = world.doorShuffle[player] == 'crossed'
|
cross_flag = world.doorShuffle[player] == 'crossed'
|
||||||
|
bk_shuffle = world.bigkeyshuffle[player]
|
||||||
# roast incognito doors
|
# roast incognito doors
|
||||||
world.get_room(0x60, player).delete(5)
|
world.get_room(0x60, player).delete(5)
|
||||||
world.get_room(0x60, player).change(2, DoorKind.DungeonEntrance)
|
world.get_room(0x60, player).change(2, DoorKind.DungeonEntrance)
|
||||||
@@ -350,13 +352,15 @@ def choose_portals(world, player):
|
|||||||
sanc.destination = True
|
sanc.destination = True
|
||||||
clean_up_portal_assignment(portal_assignment, dungeon, sanc, master_door_list, outstanding_portals)
|
clean_up_portal_assignment(portal_assignment, dungeon, sanc, master_door_list, outstanding_portals)
|
||||||
for target_region, possible_portals in info.required_passage.items():
|
for target_region, possible_portals in info.required_passage.items():
|
||||||
candidates = find_portal_candidates(master_door_list, dungeon, need_passage=True, crossed=cross_flag)
|
candidates = find_portal_candidates(master_door_list, dungeon, need_passage=True, crossed=cross_flag,
|
||||||
|
bk_shuffle=bk_shuffle)
|
||||||
choice, portal = assign_portal(candidates, possible_portals, world, player)
|
choice, portal = assign_portal(candidates, possible_portals, world, player)
|
||||||
portal.destination = True
|
portal.destination = True
|
||||||
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
||||||
dead_end_choices = info.total - 1 - len(portal_assignment[dungeon])
|
dead_end_choices = info.total - 1 - len(portal_assignment[dungeon])
|
||||||
for i in range(0, dead_end_choices):
|
for i in range(0, dead_end_choices):
|
||||||
candidates = find_portal_candidates(master_door_list, dungeon, dead_end_allowed=True, crossed=cross_flag)
|
candidates = find_portal_candidates(master_door_list, dungeon, dead_end_allowed=True,
|
||||||
|
crossed=cross_flag, bk_shuffle=bk_shuffle)
|
||||||
possible_portals = outstanding_portals if not info.sole_entrance else [x for x in outstanding_portals if x != info.sole_entrance]
|
possible_portals = outstanding_portals if not info.sole_entrance else [x for x in outstanding_portals if x != info.sole_entrance]
|
||||||
choice, portal = assign_portal(candidates, possible_portals, world, player)
|
choice, portal = assign_portal(candidates, possible_portals, world, player)
|
||||||
if choice.deadEnd:
|
if choice.deadEnd:
|
||||||
@@ -364,7 +368,8 @@ def choose_portals(world, player):
|
|||||||
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
||||||
the_rest = info.total - len(portal_assignment[dungeon])
|
the_rest = info.total - len(portal_assignment[dungeon])
|
||||||
for i in range(0, the_rest):
|
for i in range(0, the_rest):
|
||||||
candidates = find_portal_candidates(master_door_list, dungeon, crossed=cross_flag)
|
candidates = find_portal_candidates(master_door_list, dungeon, crossed=cross_flag,
|
||||||
|
bk_shuffle=bk_shuffle)
|
||||||
choice, portal = assign_portal(candidates, outstanding_portals, world, player)
|
choice, portal = assign_portal(candidates, outstanding_portals, world, player)
|
||||||
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
||||||
|
|
||||||
@@ -408,23 +413,23 @@ def connect_portal(portal, world, player):
|
|||||||
world.regions.remove(placeholder)
|
world.regions.remove(placeholder)
|
||||||
|
|
||||||
|
|
||||||
def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allowed=False, crossed=False):
|
def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allowed=False, crossed=False, bk_shuffle=False):
|
||||||
|
filter_list = [x for x in door_list if bk_shuffle or not x.bk_shuffle_req]
|
||||||
if need_passage:
|
if need_passage:
|
||||||
if crossed:
|
if crossed:
|
||||||
ret = [x for x in door_list if x.passage and not x.deadEnd]
|
return [x for x in filter_list if x.passage and (x.dungeonLink is None or x.entrance.parent_region.dungeon.name == dungeon)]
|
||||||
return [x for x in ret if x.dungeonLink is None or x.entrance.parent_region.dungeon.name == dungeon]
|
|
||||||
else:
|
else:
|
||||||
return [x for x in door_list if x.passage and x.entrance.parent_region.dungeon.name == dungeon and not x.deadEnd]
|
return [x for x in filter_list if x.passage and x.entrance.parent_region.dungeon.name == dungeon]
|
||||||
elif dead_end_allowed:
|
elif dead_end_allowed:
|
||||||
if crossed:
|
if crossed:
|
||||||
return [x for x in door_list if x.dungeonLink is None or x.entrance.parent_region.dungeon.name == dungeon]
|
return [x for x in filter_list if x.dungeonLink is None or x.entrance.parent_region.dungeon.name == dungeon]
|
||||||
else:
|
else:
|
||||||
return [x for x in door_list if x.entrance.parent_region.dungeon.name == dungeon]
|
return [x for x in filter_list if x.entrance.parent_region.dungeon.name == dungeon]
|
||||||
else:
|
else:
|
||||||
if crossed:
|
if crossed:
|
||||||
return [x for x in door_list if (not x.dungeonLink or x.entrance.parent_region.dungeon.name == dungeon) and not x.deadEnd]
|
return [x for x in filter_list if (not x.dungeonLink or x.entrance.parent_region.dungeon.name == dungeon) and not x.deadEnd]
|
||||||
else:
|
else:
|
||||||
return [x for x in door_list if x.entrance.parent_region.dungeon.name == dungeon and not x.deadEnd]
|
return [x for x in filter_list if x.entrance.parent_region.dungeon.name == dungeon and not x.deadEnd]
|
||||||
|
|
||||||
|
|
||||||
def assign_portal(candidates, possible_portals, world, player):
|
def assign_portal(candidates, possible_portals, world, player):
|
||||||
@@ -765,7 +770,7 @@ def cross_dungeon(world, player):
|
|||||||
possible_portals = []
|
possible_portals = []
|
||||||
for portal_name in dungeon_portals[d_name]:
|
for portal_name in dungeon_portals[d_name]:
|
||||||
portal = world.get_portal(portal_name, player)
|
portal = world.get_portal(portal_name, player)
|
||||||
if portal.door == 'Sanctuary S':
|
if portal.door.name == 'Sanctuary S':
|
||||||
possible_portals.clear()
|
possible_portals.clear()
|
||||||
possible_portals.append(portal)
|
possible_portals.append(portal)
|
||||||
break
|
break
|
||||||
@@ -1499,7 +1504,7 @@ def determine_init_crystal(initial, state, start_regions):
|
|||||||
elif start_region in state.visited_orange:
|
elif start_region in state.visited_orange:
|
||||||
return CrystalBarrier.Orange
|
return CrystalBarrier.Orange
|
||||||
else:
|
else:
|
||||||
raise Exception('Can\'t get to %s from initial state', start_region.name)
|
raise Exception(f'Can\'t get to {start_region.name} from initial state')
|
||||||
|
|
||||||
|
|
||||||
def explore_state(state, world, player):
|
def explore_state(state, world, player):
|
||||||
|
|||||||
34
Doors.py
34
Doors.py
@@ -1295,33 +1295,41 @@ def create_doors(world, player):
|
|||||||
]
|
]
|
||||||
world.dungeon_portals[player] += dungeon_portals
|
world.dungeon_portals[player] += dungeon_portals
|
||||||
|
|
||||||
world.get_door('Sanctuary S', player).deadEnd = True
|
world.get_door('Sanctuary S', player).dead_end(allowPassage=True)
|
||||||
world.get_door('TR Big Chest Entrance SE', player).passage = False
|
world.get_door('TR Big Chest Entrance SE', player).passage = False
|
||||||
world.get_door('Sewers Secret Room Key Door S', player).dungeonLink = 'Hyrule Castle'
|
world.get_door('Sewers Secret Room Key Door S', player).dungeonLink = 'Hyrule Castle'
|
||||||
world.get_door('Desert Cannonball S', player).deadEnd = True
|
world.get_door('Desert Cannonball S', player).dead_end()
|
||||||
world.get_door('Desert Boss SW', player).deadEnd = True
|
world.get_door('Desert Boss SW', player).dead_end()
|
||||||
world.get_door('Desert Boss SW', player).dungeonLink = 'Desert Palace'
|
world.get_door('Desert Boss SW', player).dungeonLink = 'Desert Palace'
|
||||||
world.get_door('Skull 1 Lobby S', player).dungeonLink = 'Skull Woods'
|
world.get_door('Skull 1 Lobby S', player).dungeonLink = 'Skull Woods'
|
||||||
world.get_door('Skull Map Room SE', player).dungeonLink = 'Skull Woods'
|
world.get_door('Skull Map Room SE', player).dungeonLink = 'Skull Woods'
|
||||||
world.get_door('Skull Spike Corner SW', player).dungeonLink = 'Skull Woods'
|
world.get_door('Skull Spike Corner SW', player).dungeonLink = 'Skull Woods'
|
||||||
world.get_door('Skull Spike Corner SW', player).deadEnd = True
|
world.get_door('Skull Spike Corner SW', player).dead_end()
|
||||||
world.get_door('Thieves Pot Alcove Bottom SW', player).deadEnd = True
|
world.get_door('Thieves Pot Alcove Bottom SW', player).dead_end()
|
||||||
world.get_door('Ice Conveyor SW', player).deadEnd = True
|
world.get_door('Ice Conveyor SW', player).dead_end(allowPassage=True)
|
||||||
world.get_door('Mire Right Bridge SE', player).deadEnd = True
|
world.get_door('Mire Right Bridge SE', player).dead_end(allowPassage=True)
|
||||||
world.get_door('TR Roller Room SW', player).deadEnd = True
|
world.get_door('TR Roller Room SW', player).dead_end()
|
||||||
world.get_door('TR Tile Room SE', player).deadEnd = True
|
world.get_door('TR Tile Room SE', player).dead_end()
|
||||||
world.get_door('TR Boss SW', player).deadEnd = True
|
world.get_door('TR Boss SW', player).dead_end()
|
||||||
world.get_door('TR Boss SW', player).dungeonLink = 'Turtle Rock'
|
world.get_door('TR Boss SW', player).dungeonLink = 'Turtle Rock'
|
||||||
world.get_door('GT Petting Zoo SE', player).deadEnd = True
|
world.get_door('GT Petting Zoo SE', player).dead_end()
|
||||||
world.get_door('GT DMs Room SW', player).deadEnd = True
|
world.get_door('GT DMs Room SW', player).dead_end()
|
||||||
world.get_door("GT Bob\'s Room SE", player).passage = False
|
world.get_door("GT Bob\'s Room SE", player).passage = False
|
||||||
|
world.get_door('PoD Mimics 2 SW', player).bk_shuffle_req = True
|
||||||
|
world.get_door('Desert Tiles 2 SE', player).bk_shuffle_req = True # key-drop note (todo)
|
||||||
|
|
||||||
# can't unlink from boss right now
|
# can't unlink from boss right now
|
||||||
world.get_door("Hera Lobby S", player).dungeonLink = 'Tower of Hera'
|
world.get_door('Hera Lobby S', player).dungeonLink = 'Tower of Hera'
|
||||||
|
# can't unlink from skull woods right now
|
||||||
|
world.get_door('Skull 2 West Lobby S', player).dungeonLink = 'Skull Woods'
|
||||||
|
|
||||||
world.get_door('Ice Spike Cross SE', player).dungeonLink = 'linkIceFalls'
|
world.get_door('Ice Spike Cross SE', player).dungeonLink = 'linkIceFalls'
|
||||||
world.get_door('Ice Tall Hint SE', player).dungeonLink = 'linkIceFalls'
|
world.get_door('Ice Tall Hint SE', player).dungeonLink = 'linkIceFalls'
|
||||||
world.get_door('Ice Switch Room SE', player).dungeonLink = 'linkIceFalls'
|
world.get_door('Ice Switch Room SE', player).dungeonLink = 'linkIceFalls'
|
||||||
|
|
||||||
|
world.get_door('Ice Cross Bottom SE', player).dungeonLink = 'linkIceFalls2'
|
||||||
|
world.get_door('Ice Conveyor SW', player).dungeonLink = 'linkIceFalls2'
|
||||||
|
|
||||||
|
|
||||||
def create_paired_doors(world, player):
|
def create_paired_doors(world, player):
|
||||||
world.paired_doors[player] = [
|
world.paired_doors[player] = [
|
||||||
|
|||||||
@@ -193,11 +193,12 @@ def gen_dungeon_info(name, available_sectors, entrance_regions, all_regions, pro
|
|||||||
start = ExplorationState(dungeon=name)
|
start = ExplorationState(dungeon=name)
|
||||||
start.big_key_special = bk_special
|
start.big_key_special = bk_special
|
||||||
group_flags, door_map = find_bk_groups(name, available_sectors, proposed_map, bk_special)
|
group_flags, door_map = find_bk_groups(name, available_sectors, proposed_map, bk_special)
|
||||||
|
bk_flag = False if world.bigkeyshuffle[player] and not bk_special else bk_needed
|
||||||
|
|
||||||
def exception(d):
|
def exception(d):
|
||||||
return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS'
|
return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS'
|
||||||
original_state = extend_reachable_state_improved(entrance_regions, start, proposed_map, all_regions,
|
original_state = extend_reachable_state_improved(entrance_regions, start, proposed_map, all_regions,
|
||||||
valid_doors, bk_needed, world, player, exception)
|
valid_doors, bk_flag, world, player, exception)
|
||||||
dungeon['Origin'] = create_graph_piece_from_state(None, original_state, original_state, proposed_map, exception)
|
dungeon['Origin'] = create_graph_piece_from_state(None, original_state, original_state, proposed_map, exception)
|
||||||
either_crystal = True # if all hooks from the origin are either, explore all bits with either
|
either_crystal = True # if all hooks from the origin are either, explore all bits with either
|
||||||
for hook, crystal in dungeon['Origin'].hooks.items():
|
for hook, crystal in dungeon['Origin'].hooks.items():
|
||||||
@@ -396,13 +397,14 @@ def check_valid(name, dungeon, hangers, hooks, proposed_map, doors_to_connect, a
|
|||||||
if len(dungeon.keys()) <= 1 and len(proposed_map.keys()) < len(doors_to_connect):
|
if len(dungeon.keys()) <= 1 and len(proposed_map.keys()) < len(doors_to_connect):
|
||||||
return False
|
return False
|
||||||
# origin has no more hooks, but not all doors have been proposed
|
# origin has no more hooks, but not all doors have been proposed
|
||||||
possible_bks = len(dungeon['Origin'].possible_bk_locations)
|
if not world.bigkeyshuffle[player]:
|
||||||
true_origin_hooks = [x for x in dungeon['Origin'].hooks.keys() if not x.bigKey or possible_bks > 0 or not bk_needed]
|
possible_bks = len(dungeon['Origin'].possible_bk_locations)
|
||||||
if len(true_origin_hooks) == 0 and len(proposed_map.keys()) < len(doors_to_connect):
|
true_origin_hooks = [x for x in dungeon['Origin'].hooks.keys() if not x.bigKey or possible_bks > 0 or not bk_needed]
|
||||||
return False
|
if len(true_origin_hooks) == 0 and len(proposed_map.keys()) < len(doors_to_connect):
|
||||||
if len(true_origin_hooks) == 0 and bk_needed and possible_bks == 0 and len(proposed_map.keys()) == len(
|
return False
|
||||||
doors_to_connect):
|
if len(true_origin_hooks) == 0 and bk_needed and possible_bks == 0 and len(proposed_map.keys()) == len(
|
||||||
return False
|
doors_to_connect):
|
||||||
|
return False
|
||||||
for key in hangers.keys():
|
for key in hangers.keys():
|
||||||
if len(hooks[key]) > 0 and len(hangers[key]) == 0:
|
if len(hooks[key]) > 0 and len(hangers[key]) == 0:
|
||||||
return False
|
return False
|
||||||
@@ -428,7 +430,7 @@ def check_valid(name, dungeon, hangers, hooks, proposed_map, doors_to_connect, a
|
|||||||
if len(outstanding_doors[key]) > 0 and len(hangers[key]) == 0 and len(hooks[opp_key]) == 0:
|
if len(outstanding_doors[key]) > 0 and len(hangers[key]) == 0 and len(hooks[opp_key]) == 0:
|
||||||
return False
|
return False
|
||||||
all_visited = set()
|
all_visited = set()
|
||||||
bk_possible = not bk_needed
|
bk_possible = not bk_needed or (world.bigkeyshuffle[player] and not bk_special)
|
||||||
for piece in dungeon.values():
|
for piece in dungeon.values():
|
||||||
all_visited.update(piece.visited_regions)
|
all_visited.update(piece.visited_regions)
|
||||||
if not bk_possible and len(piece.possible_bk_locations) > 0:
|
if not bk_possible and len(piece.possible_bk_locations) > 0:
|
||||||
@@ -501,11 +503,12 @@ def valid_path(name, starting_regions, target, valid_doors, proposed_map, all_re
|
|||||||
|
|
||||||
start = ExplorationState(dungeon=name)
|
start = ExplorationState(dungeon=name)
|
||||||
start.big_key_special = bk_special
|
start.big_key_special = bk_special
|
||||||
|
bk_flag = False if world.bigkeyshuffle[player] and not bk_special else bk_needed
|
||||||
|
|
||||||
def exception(d):
|
def exception(d):
|
||||||
return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS'
|
return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS'
|
||||||
original_state = extend_reachable_state_improved(starting_regions, start, proposed_map, all_regions,
|
original_state = extend_reachable_state_improved(starting_regions, start, proposed_map, all_regions,
|
||||||
valid_doors, bk_needed, world, player, exception)
|
valid_doors, bk_flag, world, player, exception)
|
||||||
|
|
||||||
for exp_door in original_state.unattached_doors:
|
for exp_door in original_state.unattached_doors:
|
||||||
if not exp_door.door.blocked:
|
if not exp_door.door.blocked:
|
||||||
|
|||||||
@@ -1141,10 +1141,13 @@ def check_rules_deep(original_counter, key_layout, world, player):
|
|||||||
big_avail = counter.big_key_opened
|
big_avail = counter.big_key_opened
|
||||||
big_maybe_not_found = not counter.big_key_opened
|
big_maybe_not_found = not counter.big_key_opened
|
||||||
if not key_layout.big_key_special and not big_avail:
|
if not key_layout.big_key_special and not big_avail:
|
||||||
for location in counter.free_locations:
|
if world.bigkeyshuffle[player]:
|
||||||
if location not in key_logic.bk_restricted:
|
big_avail = True
|
||||||
big_avail = True
|
else:
|
||||||
break
|
for location in counter.free_locations:
|
||||||
|
if location not in key_logic.bk_restricted:
|
||||||
|
big_avail = True
|
||||||
|
break
|
||||||
outstanding_big_locs = {x for x in big_locations if x not in counter.free_locations}
|
outstanding_big_locs = {x for x in big_locations if x not in counter.free_locations}
|
||||||
if big_maybe_not_found:
|
if big_maybe_not_found:
|
||||||
if len(outstanding_big_locs) == 0:
|
if len(outstanding_big_locs) == 0:
|
||||||
|
|||||||
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-dev'
|
__version__ = '0.2.0.0-u'
|
||||||
|
|
||||||
class EnemizerError(RuntimeError):
|
class EnemizerError(RuntimeError):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -680,13 +680,13 @@ def create_dungeon_regions(world, player):
|
|||||||
create_dungeon_region(player, 'GT Hookshot East Platform', 'Ganon\'s Tower', None, ['GT Hookshot EN', 'GT Hookshot East-North Path', 'GT Hookshot East-South Path']),
|
create_dungeon_region(player, 'GT Hookshot East Platform', 'Ganon\'s Tower', None, ['GT Hookshot EN', 'GT Hookshot East-North Path', 'GT Hookshot East-South Path']),
|
||||||
create_dungeon_region(player, 'GT Hookshot North Platform', 'Ganon\'s Tower', None, ['GT Hookshot NW', 'GT Hookshot North-East Path', 'GT Hookshot North-South Path']),
|
create_dungeon_region(player, 'GT Hookshot North Platform', 'Ganon\'s Tower', None, ['GT Hookshot NW', 'GT Hookshot North-East Path', 'GT Hookshot North-South Path']),
|
||||||
create_dungeon_region(player, 'GT Hookshot South Platform', 'Ganon\'s Tower', None, ['GT Hookshot ES', 'GT Hookshot South-East Path', 'GT Hookshot South-North Path', 'GT Hookshot Platform Blue Barrier']),
|
create_dungeon_region(player, 'GT Hookshot South Platform', 'Ganon\'s Tower', None, ['GT Hookshot ES', 'GT Hookshot South-East Path', 'GT Hookshot South-North Path', 'GT Hookshot Platform Blue Barrier']),
|
||||||
create_dungeon_region(player, 'GT Hookshot South Entry', 'Ganon\'s Tower', None, ['GT Hookshot SW', 'GT Hookshot Entry Blue Barrier', ]),
|
create_dungeon_region(player, 'GT Hookshot South Entry', 'Ganon\'s Tower', None, ['GT Hookshot SW', 'GT Hookshot Entry Blue Barrier', 'GT Hookshot Entry Boomerang Path']),
|
||||||
create_dungeon_region(player, 'GT Map Room', 'Ganon\'s Tower', ['Ganons Tower - Map Chest'], ['GT Map Room WS']),
|
create_dungeon_region(player, 'GT Map Room', 'Ganon\'s Tower', ['Ganons Tower - Map Chest'], ['GT Map Room WS']),
|
||||||
create_dungeon_region(player, 'GT Double Switch Entry', 'Ganon\'s Tower', None, ['GT Double Switch NW', 'GT Double Switch Orange Barrier', 'GT Double Switch Orange Barrier 2']),
|
create_dungeon_region(player, 'GT Double Switch Entry', 'Ganon\'s Tower', None, ['GT Double Switch NW', 'GT Double Switch Orange Barrier', 'GT Double Switch Orange Barrier 2']),
|
||||||
create_dungeon_region(player, 'GT Double Switch Switches', 'Ganon\'s Tower', None, ['GT Double Switch Blue Path', 'GT Double Switch Orange Path']),
|
create_dungeon_region(player, 'GT Double Switch Switches', 'Ganon\'s Tower', None, ['GT Double Switch Blue Path', 'GT Double Switch Orange Path']),
|
||||||
create_dungeon_region(player, 'GT Double Switch Transition', 'Ganon\'s Tower', None, ['GT Double Switch Transition Blue']),
|
create_dungeon_region(player, 'GT Double Switch Transition', 'Ganon\'s Tower', None, ['GT Double Switch Transition Blue']),
|
||||||
create_dungeon_region(player, 'GT Double Switch Key Spot', 'Ganon\'s Tower', ['Ganons Tower - Double Switch Pot Key'], ['GT Double Switch Key Blue Path', 'GT Double Switch Key Orange Path']),
|
create_dungeon_region(player, 'GT Double Switch Key Spot', 'Ganon\'s Tower', ['Ganons Tower - Double Switch Pot Key'], ['GT Double Switch Key Blue Path', 'GT Double Switch Key Orange Path']),
|
||||||
create_dungeon_region(player, 'GT Double Switch Exit', 'Ganon\'s Tower', None, ['GT Double Switch EN', 'GT Double Switch Blue Barrier', 'GT Hookshot Entry Boomerang Path']),
|
create_dungeon_region(player, 'GT Double Switch Exit', 'Ganon\'s Tower', None, ['GT Double Switch EN', 'GT Double Switch Blue Barrier']),
|
||||||
create_dungeon_region(player, 'GT Spike Crystals', 'Ganon\'s Tower', None, ['GT Spike Crystals WN', 'GT Spike Crystals Warp']),
|
create_dungeon_region(player, 'GT Spike Crystals', 'Ganon\'s Tower', None, ['GT Spike Crystals WN', 'GT Spike Crystals Warp']),
|
||||||
create_dungeon_region(player, 'GT Warp Maze - Left Section', 'Ganon\'s Tower', None, ['GT Warp Maze - Left Section Warp']),
|
create_dungeon_region(player, 'GT Warp Maze - Left Section', 'Ganon\'s Tower', None, ['GT Warp Maze - Left Section Warp']),
|
||||||
create_dungeon_region(player, 'GT Warp Maze - Mid Section', 'Ganon\'s Tower', None, ['GT Warp Maze - Mid Section Left Warp', 'GT Warp Maze - Mid Section Right Warp']),
|
create_dungeon_region(player, 'GT Warp Maze - Mid Section', 'Ganon\'s Tower', None, ['GT Warp Maze - Mid Section Left Warp', 'GT Warp Maze - Mid Section Right Warp']),
|
||||||
@@ -736,7 +736,7 @@ def create_dungeon_regions(world, player):
|
|||||||
create_dungeon_region(player, 'GT Staredown', 'Ganon\'s Tower', None, ['GT Staredown WS', 'GT Staredown Up Ladder']),
|
create_dungeon_region(player, 'GT Staredown', 'Ganon\'s Tower', None, ['GT Staredown WS', 'GT Staredown Up Ladder']),
|
||||||
create_dungeon_region(player, 'GT Falling Torches', 'Ganon\'s Tower', None, ['GT Falling Torches Down Ladder', 'GT Falling Torches NE', 'GT Falling Torches Hole']),
|
create_dungeon_region(player, 'GT Falling Torches', 'Ganon\'s Tower', None, ['GT Falling Torches Down Ladder', 'GT Falling Torches NE', 'GT Falling Torches Hole']),
|
||||||
create_dungeon_region(player, 'GT Mini Helmasaur Room', 'Ganon\'s Tower', ['Ganons Tower - Mini Helmasaur Room - Left',
|
create_dungeon_region(player, 'GT Mini Helmasaur Room', 'Ganon\'s Tower', ['Ganons Tower - Mini Helmasaur Room - Left',
|
||||||
'Ganons Tower - Mini Helmasaur Room - Right', 'Ganons Tower - Mini Helmasuar Key Drop'], ['GT Mini Helmasaur Room SE', 'GT Mini Helmasaur Room WN']),
|
'Ganons Tower - Mini Helmasaur Room - Right', 'Ganons Tower - Mini Helmasaur Key Drop'], ['GT Mini Helmasaur Room SE', 'GT Mini Helmasaur Room WN']),
|
||||||
create_dungeon_region(player, 'GT Bomb Conveyor', 'Ganon\'s Tower', None, ['GT Bomb Conveyor EN', 'GT Bomb Conveyor SW']),
|
create_dungeon_region(player, 'GT Bomb Conveyor', 'Ganon\'s Tower', None, ['GT Bomb Conveyor EN', 'GT Bomb Conveyor SW']),
|
||||||
create_dungeon_region(player, 'GT Crystal Circles', 'Ganon\'s Tower', ['Ganons Tower - Pre-Moldorm Chest'], ['GT Crystal Circles NW', 'GT Crystal Circles SW']),
|
create_dungeon_region(player, 'GT Crystal Circles', 'Ganon\'s Tower', ['Ganons Tower - Pre-Moldorm Chest'], ['GT Crystal Circles NW', 'GT Crystal Circles SW']),
|
||||||
create_dungeon_region(player, 'GT Left Moldorm Ledge', 'Ganon\'s Tower', None, ['GT Left Moldorm Ledge Drop Down', 'GT Left Moldorm Ledge NW']),
|
create_dungeon_region(player, 'GT Left Moldorm Ledge', 'Ganon\'s Tower', None, ['GT Left Moldorm Ledge Drop Down', 'GT Left Moldorm Ledge NW']),
|
||||||
@@ -909,7 +909,7 @@ key_only_locations = {
|
|||||||
'Ganons Tower - Conveyor Cross Pot Key': 'Small Key (Ganons Tower)',
|
'Ganons Tower - Conveyor Cross Pot Key': 'Small Key (Ganons Tower)',
|
||||||
'Ganons Tower - Double Switch Pot Key': 'Small Key (Ganons Tower)',
|
'Ganons Tower - Double Switch Pot Key': 'Small Key (Ganons Tower)',
|
||||||
'Ganons Tower - Conveyor Star Pits Pot Key': 'Small Key (Ganons Tower)',
|
'Ganons Tower - Conveyor Star Pits Pot Key': 'Small Key (Ganons Tower)',
|
||||||
'Ganons Tower - Mini Helmasuar Key Drop': 'Small Key (Ganons Tower)'
|
'Ganons Tower - Mini Helmasaur Key Drop': 'Small Key (Ganons Tower)'
|
||||||
}
|
}
|
||||||
|
|
||||||
dungeon_events = [
|
dungeon_events = [
|
||||||
|
|||||||
4
Rom.py
4
Rom.py
@@ -22,7 +22,7 @@ from EntranceShuffle import door_addresses, exit_ids
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = 'b9e578ef0af231041070bd9049a55646'
|
RANDOMIZERBASEHASH = '98e8426901b441858631ae444c12d4fc'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -2167,7 +2167,7 @@ def patch_shuffled_dark_sanc(world, rom, player):
|
|||||||
# 24B118 and 20BB32
|
# 24B118 and 20BB32
|
||||||
compass_r_addr = 0x123118 # a9 90 24 8f 9a c7 7e
|
compass_r_addr = 0x123118 # a9 90 24 8f 9a c7 7e
|
||||||
# compass_w_addr = 0x103b32 # e2 20 ad 0c 04 c9 00 d0
|
# compass_w_addr = 0x103b32 # e2 20 ad 0c 04 c9 00 d0
|
||||||
compass_w_addr = 0x103b42 # e2 20 ad 0c 04 c9 00 d0
|
compass_w_addr = 0x103b53 # e2 20 ad 0c 04 c9 00 d0
|
||||||
|
|
||||||
|
|
||||||
def compass_code_good(rom):
|
def compass_code_good(rom):
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ nop : stz $0dd0, X : rts
|
|||||||
org $20820E
|
org $20820E
|
||||||
jsl MirrorCheckOverride2
|
jsl MirrorCheckOverride2
|
||||||
;org $208270
|
;org $208270
|
||||||
org $208278
|
org $20827C
|
||||||
jsl MirrorCheckOverride2
|
jsl MirrorCheckOverride2
|
||||||
org $07a955 ; <- Bank07.asm : around 6564 (JP is a bit different) (STZ $05FC : STZ $05FD)
|
org $07a955 ; <- Bank07.asm : around 6564 (JP is a bit different) (STZ $05FC : STZ $05FD)
|
||||||
jsl BlockEraseFix
|
jsl BlockEraseFix
|
||||||
@@ -134,7 +134,7 @@ jsl SuctionOverworldFix
|
|||||||
; also rando's hooks.asm line 1360
|
; also rando's hooks.asm line 1360
|
||||||
; 106e4e -> goes to a0ee4e
|
; 106e4e -> goes to a0ee4e
|
||||||
;org $a0ee8a ; <- 6FC4C - headsup_display.asm : 836 (LDA $7EF36E : AND.w #$00FF : ADD.w #$0007 : AND.w #$FFF8 : TAX)
|
;org $a0ee8a ; <- 6FC4C - headsup_display.asm : 836 (LDA $7EF36E : AND.w #$00FF : ADD.w #$0007 : AND.w #$FFF8 : TAX)
|
||||||
org $a0ee9a
|
org $a0eeab
|
||||||
jsl DrHudOverride
|
jsl DrHudOverride
|
||||||
org $0ded04 ; <- rando's hooks.asm line 2192 - 6ED04 - equipment.asm : 1963 (REP #$30)
|
org $0ded04 ; <- rando's hooks.asm line 2192 - 6ED04 - equipment.asm : 1963 (REP #$30)
|
||||||
jsl DrHudDungeonItemsAdditions
|
jsl DrHudDungeonItemsAdditions
|
||||||
|
|||||||
@@ -87,22 +87,28 @@ SuctionOverworldFix:
|
|||||||
stz $49
|
stz $49
|
||||||
+ rtl
|
+ rtl
|
||||||
|
|
||||||
CutoffEntranceRug:
|
; TT Alcove, Mire bridges, pod falling, SW torch room, TR Pipe room, Bob's Room, Ice Many Pots, Mire Hub
|
||||||
pha
|
; swamp waterfall
|
||||||
lda.l DRMode : beq +
|
CutoffRooms:
|
||||||
lda $04 : cmp #$000A : bne +
|
db $bc, $a2, $1a, $49, $14, $8c, $9f, $c2
|
||||||
lda $a0 : cmp #$00BC : beq .check ;; TT Alcove
|
db $66
|
||||||
cmp #$00A2 : beq .check ; Mire Bridges
|
|
||||||
cmp #$001A : beq .check ; pod falling
|
CutoffEntranceRug:
|
||||||
cmp #$0049 : beq .check ; SW torch room
|
pha : phx
|
||||||
cmp #$0014 : beq .check ; TR Pipe room
|
lda.l DRMode : beq .norm
|
||||||
cmp #$00C2 : bne + ; Mire Hub
|
lda $04 : cmp #$000A : beq +
|
||||||
.check
|
cmp #$000C : bne .norm
|
||||||
lda $0c : cmp #$0006 : !bge .skip
|
+ lda $a0 : sep #$20 : ldx #$0000
|
||||||
lda $0e : cmp #$0008 : !bge .skip
|
- cmp.l CutoffRooms, x : beq .check
|
||||||
cmp #$0004 : !blt .skip
|
inx : cpx #$0009 : !blt - ; CutoffRoom Count is here!
|
||||||
bra +
|
rep #$20
|
||||||
.skip pla : rtl
|
.norm plx : pla : lda $9B52, y : sta $7E2000, x ; what we wrote over
|
||||||
+ pla : lda $9B52, y : sta $7E2000, x ; what we wrote over
|
rtl
|
||||||
rtl
|
.check
|
||||||
|
rep #$20
|
||||||
|
lda $0c : cmp #$0006 : !bge .skip
|
||||||
|
lda $0e : cmp #$0008 : !bge .skip
|
||||||
|
cmp #$0004 : !blt .skip
|
||||||
|
bra .norm
|
||||||
|
.skip plx : pla : rtl
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user