Merge branch 'OverworldShuffleDev' into OverworldShuffle
This commit is contained in:
@@ -1100,7 +1100,7 @@ class CollectionState(object):
|
|||||||
new_locations = True
|
new_locations = True
|
||||||
while new_locations:
|
while new_locations:
|
||||||
reachable_events = [location for location in locations if location.event and
|
reachable_events = [location for location in locations if location.event and
|
||||||
(not key_only or (self.world.keyshuffle[location.item.player] in ['none', 'district'] and location.item.smallkey) or (self.world.bigkeyshuffle[location.item.player] in ['none', 'district'] and location.item.bigkey))
|
(not key_only or (self.world.keyshuffle[location.item.player] in ['none', 'nearby'] and location.item.smallkey) or (self.world.bigkeyshuffle[location.item.player] in ['none', 'nearby'] and location.item.bigkey))
|
||||||
and location.can_reach(self)]
|
and location.can_reach(self)]
|
||||||
reachable_events = self._do_not_flood_the_keys(reachable_events)
|
reachable_events = self._do_not_flood_the_keys(reachable_events)
|
||||||
new_locations = False
|
new_locations = False
|
||||||
@@ -2806,11 +2806,11 @@ class Item(object):
|
|||||||
or (self.map and world.mapshuffle[self.player] == 'none'))
|
or (self.map and world.mapshuffle[self.player] == 'none'))
|
||||||
|
|
||||||
def is_near_dungeon_item(self, world):
|
def is_near_dungeon_item(self, world):
|
||||||
return ((self.prize and world.prizeshuffle[self.player] == 'district')
|
return ((self.prize and world.prizeshuffle[self.player] == 'nearby')
|
||||||
or (self.smallkey and world.keyshuffle[self.player] == 'district')
|
or (self.smallkey and world.keyshuffle[self.player] == 'nearby')
|
||||||
or (self.bigkey and world.bigkeyshuffle[self.player] == 'district')
|
or (self.bigkey and world.bigkeyshuffle[self.player] == 'nearby')
|
||||||
or (self.compass and world.compassshuffle[self.player] == 'district')
|
or (self.compass and world.compassshuffle[self.player] == 'nearby')
|
||||||
or (self.map and world.mapshuffle[self.player] == 'district'))
|
or (self.map and world.mapshuffle[self.player] == 'nearby'))
|
||||||
|
|
||||||
def get_map_location(self):
|
def get_map_location(self):
|
||||||
if self.location:
|
if self.location:
|
||||||
@@ -2820,7 +2820,7 @@ class Item(object):
|
|||||||
def explore_region(region):
|
def explore_region(region):
|
||||||
explored_regions.append(region.name)
|
explored_regions.append(region.name)
|
||||||
for ent in region.entrances:
|
for ent in region.entrances:
|
||||||
if ent.parent_region is not None and ent.spot_type != 'OWG':
|
if ent.parent_region is not None and ent.spot_type not in ['OWG', 'HMG']:
|
||||||
if ent.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld]:
|
if ent.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld]:
|
||||||
return ent
|
return ent
|
||||||
elif ent.parent_region.name not in explored_regions:
|
elif ent.parent_region.name not in explored_regions:
|
||||||
@@ -3644,10 +3644,10 @@ counter_mode = {"default": 0, "off": 1, "on": 2, "pickup": 3}
|
|||||||
access_mode = {"items": 0, "locations": 1, "none": 2}
|
access_mode = {"items": 0, "locations": 1, "none": 2}
|
||||||
|
|
||||||
# byte 7: MMCC SSBB (maps, compass, small, big)
|
# byte 7: MMCC SSBB (maps, compass, small, big)
|
||||||
mapshuffle_mode = {'none': 0, 'off': 0, 'district': 2, 'wild': 3, 'on': 3}
|
mapshuffle_mode = {'none': 0, 'off': 0, 'nearby': 2, 'wild': 3, 'on': 3}
|
||||||
compassshuffle_mode = {'none': 0, 'off': 0, 'district': 2, 'wild': 3, 'on': 3}
|
compassshuffle_mode = {'none': 0, 'off': 0, 'nearby': 2, 'wild': 3, 'on': 3}
|
||||||
keyshuffle_mode = {'none': 0, 'off': 0, 'universal': 1, 'district': 2, 'wild': 3, 'on': 3}
|
keyshuffle_mode = {'none': 0, 'off': 0, 'universal': 1, 'nearby': 2, 'wild': 3, 'on': 3}
|
||||||
bigkeyshuffle_mode = {'none': 0, 'off': 0, 'district': 2, 'wild': 3, 'on': 3}
|
bigkeyshuffle_mode = {'none': 0, 'off': 0, 'nearby': 2, 'wild': 3, 'on': 3}
|
||||||
|
|
||||||
# byte 8: HHHD DPEE (enemy_health, enemy_dmg, potshuffle, enemies)
|
# byte 8: HHHD DPEE (enemy_health, enemy_dmg, potshuffle, enemies)
|
||||||
e_health = {"default": 0, "easy": 1, "normal": 2, "hard": 3, "expert": 4}
|
e_health = {"default": 0, "easy": 1, "normal": 2, "hard": 3, "expert": 4}
|
||||||
@@ -3673,7 +3673,7 @@ flutespot_mode = {"vanilla": 0, "balanced": 1, "random": 2}
|
|||||||
flute_mode = {'normal': 0, 'active': 1}
|
flute_mode = {'normal': 0, 'active': 1}
|
||||||
bow_mode = {'progressive': 0, 'silvers': 1, 'retro': 2, 'retro_silvers': 3} # reserved 8 modes?
|
bow_mode = {'progressive': 0, 'silvers': 1, 'retro': 2, 'retro_silvers': 3} # reserved 8 modes?
|
||||||
take_any_mode = {'none': 0, 'random': 1, 'fixed': 2}
|
take_any_mode = {'none': 0, 'random': 1, 'fixed': 2}
|
||||||
prizeshuffle_mode = {'none': 0, 'dungeon': 1, 'district': 2, 'wild': 3}
|
prizeshuffle_mode = {'none': 0, 'dungeon': 1, 'nearby': 2, 'wild': 3}
|
||||||
|
|
||||||
# additions
|
# additions
|
||||||
# byte 14: POOT TKKK (pseudoboots, overworld_map, trap_door_mode, key_logic_algo)
|
# byte 14: POOT TKKK (pseudoboots, overworld_map, trap_door_mode, key_logic_algo)
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.5.1.2
|
||||||
|
- Many fixes to HMG logic, generation, key collection issues
|
||||||
|
- Fixed issue with In-Dungeon Prizes getting placed in the same dungeon
|
||||||
|
- Fixed issue with Old Man getting placed outside of DM in glitched modes
|
||||||
|
- Fixed issue with Free Terrain water transitions not checking for Pearl requirement
|
||||||
|
|
||||||
## 0.5.1.0 (+ Hotfix 0.5.1.1)
|
## 0.5.1.0 (+ Hotfix 0.5.1.1)
|
||||||
- New "Nearby" Dungeon Item Shuffle option
|
- New "Nearby" Dungeon Item Shuffle option
|
||||||
- Fixed issue with smith follower getting deleted incorrectly on s+q
|
- Fixed issue with smith follower getting deleted incorrectly on s+q
|
||||||
|
|||||||
44
Fill.py
44
Fill.py
@@ -36,18 +36,21 @@ def dungeon_tracking(world):
|
|||||||
for dungeon in world.dungeons:
|
for dungeon in world.dungeons:
|
||||||
layout = world.dungeon_layouts[dungeon.player][dungeon.name]
|
layout = world.dungeon_layouts[dungeon.player][dungeon.name]
|
||||||
layout.dungeon_items = len([i for i in dungeon.all_items if i.is_inside_dungeon_item(world)])
|
layout.dungeon_items = len([i for i in dungeon.all_items if i.is_inside_dungeon_item(world)])
|
||||||
|
if world.prizeshuffle[dungeon.player] in ['dungeon', 'nearby'] and not dungeon.prize:
|
||||||
|
from Dungeons import dungeon_table
|
||||||
|
if dungeon_table[dungeon.name].prize:
|
||||||
|
layout.dungeon_items += 1
|
||||||
layout.free_items = layout.location_cnt - layout.dungeon_items
|
layout.free_items = layout.location_cnt - layout.dungeon_items
|
||||||
|
|
||||||
|
|
||||||
def fill_dungeons_restrictive(world, shuffled_locations):
|
def fill_dungeons_restrictive(world, shuffled_locations):
|
||||||
|
|
||||||
# with shuffled dungeon items they are distributed as part of the normal item pool
|
# with shuffled dungeon items they are distributed as part of the normal item pool
|
||||||
for item in world.get_items():
|
for item in world.get_items():
|
||||||
if ((item.prize and world.prizeshuffle[item.player] != 'none')
|
if ((item.prize and world.prizeshuffle[item.player] != 'none')
|
||||||
or (item.smallkey and world.keyshuffle[item.player] != 'none')
|
or (item.smallkey and world.keyshuffle[item.player] != 'none')
|
||||||
or (item.bigkey and world.bigkeyshuffle[item.player] != 'none')):
|
or (item.bigkey and world.bigkeyshuffle[item.player] != 'none')):
|
||||||
item.advancement = True
|
item.advancement = True
|
||||||
elif (item.map and world.mapshuffle[item.player] not in ['none', 'district']) or (item.compass and world.compassshuffle[item.player] not in ['none', 'district']):
|
elif (item.map and world.mapshuffle[item.player] not in ['none', 'nearby']) or (item.compass and world.compassshuffle[item.player] not in ['none', 'nearby']):
|
||||||
item.priority = True
|
item.priority = True
|
||||||
|
|
||||||
dungeon_items = [item for item in get_dungeon_item_pool(world) if item.is_inside_dungeon_item(world) or item.is_near_dungeon_item(world)]
|
dungeon_items = [item for item in get_dungeon_item_pool(world) if item.is_inside_dungeon_item(world) or item.is_near_dungeon_item(world)]
|
||||||
@@ -56,13 +59,46 @@ def fill_dungeons_restrictive(world, shuffled_locations):
|
|||||||
(bigs if i.bigkey else smalls if i.smallkey else prizes if i.prize else others).append(i)
|
(bigs if i.bigkey else smalls if i.smallkey else prizes if i.prize else others).append(i)
|
||||||
unplaced_smalls = list(smalls)
|
unplaced_smalls = list(smalls)
|
||||||
for i in world.itempool:
|
for i in world.itempool:
|
||||||
if i.smallkey and world.keyshuffle[i.player] != 'none':
|
if i.smallkey and world.keyshuffle[i.player] not in ['none', 'nearby']:
|
||||||
unplaced_smalls.append(i)
|
unplaced_smalls.append(i)
|
||||||
|
|
||||||
def fill(base_state, items, locations, key_pool=None):
|
def fill(base_state, items, locations, key_pool=None):
|
||||||
fill_restrictive(world, base_state, locations, items, key_pool, True)
|
fill_restrictive(world, base_state, locations, items, key_pool, True)
|
||||||
|
|
||||||
all_state_base = world.get_all_state()
|
all_state_base = world.get_all_state()
|
||||||
|
for player in range(1, world.players + 1):
|
||||||
|
if world.logic[player] == 'hybridglitches' and world.keyshuffle[i.player] in ['none', 'nearby'] \
|
||||||
|
and world.pottery[player] not in ['none', 'cave']:
|
||||||
|
# remove 2 keys from main pool
|
||||||
|
count_to_remove = 2
|
||||||
|
to_remove = []
|
||||||
|
for wix, wi in enumerate(smalls):
|
||||||
|
if wi.name == 'Small Key (Swamp Palace)' and wi.player == player:
|
||||||
|
to_remove.append(wix)
|
||||||
|
if count_to_remove == len(to_remove):
|
||||||
|
break
|
||||||
|
for wix in reversed(to_remove):
|
||||||
|
del smalls[wix]
|
||||||
|
|
||||||
|
# remove 2 swamp locations from pool
|
||||||
|
hybrid_locations = []
|
||||||
|
to_remove = []
|
||||||
|
for i, loc in enumerate(shuffled_locations):
|
||||||
|
if loc.name in ['Swamp Palace - Trench 1 Pot Key', 'Swamp Palace - Pot Row Pot Key'] and loc.player == player:
|
||||||
|
to_remove.append(i)
|
||||||
|
hybrid_locations.append(loc)
|
||||||
|
if count_to_remove == len(to_remove):
|
||||||
|
break
|
||||||
|
for i in reversed(to_remove):
|
||||||
|
shuffled_locations.pop(i)
|
||||||
|
|
||||||
|
# place 2 HMG keys
|
||||||
|
hybrid_state_base = all_state_base.copy()
|
||||||
|
for x in bigs + smalls + prizes + others:
|
||||||
|
hybrid_state_base.collect(x, True)
|
||||||
|
hybrid_smalls = [ItemFactory('Small Key (Swamp Palace)', player)] * 2
|
||||||
|
fill(hybrid_state_base, hybrid_smalls, hybrid_locations, unplaced_smalls)
|
||||||
|
|
||||||
big_state_base = all_state_base.copy()
|
big_state_base = all_state_base.copy()
|
||||||
for x in smalls + prizes + others:
|
for x in smalls + prizes + others:
|
||||||
big_state_base.collect(x, True)
|
big_state_base.collect(x, True)
|
||||||
@@ -77,7 +113,7 @@ def fill_dungeons_restrictive(world, shuffled_locations):
|
|||||||
for attempt in range(15):
|
for attempt in range(15):
|
||||||
try:
|
try:
|
||||||
for player in range(1, world.players + 1):
|
for player in range(1, world.players + 1):
|
||||||
if world.prizeshuffle[player] == 'district':
|
if world.prizeshuffle[player] == 'nearby':
|
||||||
dungeon_pool = []
|
dungeon_pool = []
|
||||||
for dungeon in world.dungeons:
|
for dungeon in world.dungeons:
|
||||||
from Dungeons import dungeon_table
|
from Dungeons import dungeon_table
|
||||||
|
|||||||
@@ -114,6 +114,10 @@ class InitialSram:
|
|||||||
equip[0x37B] = 1
|
equip[0x37B] = 1
|
||||||
starting_magic = 0x80
|
starting_magic = 0x80
|
||||||
|
|
||||||
|
if world.mode[player] == 'standard' and world.logic[player] not in ['noglitches', 'minorglitches']:
|
||||||
|
if startingstate.has('Ocarina (Activated)', player):
|
||||||
|
self.pre_set_overworld_flag(0x18, 0x20)
|
||||||
|
|
||||||
if startingstate.has('Return Old Man', player):
|
if startingstate.has('Return Old Man', player):
|
||||||
self._initial_sram_bytes[0x410] |= 0x01
|
self._initial_sram_bytes[0x410] |= 0x01
|
||||||
|
|
||||||
|
|||||||
26
ItemList.py
26
ItemList.py
@@ -272,7 +272,8 @@ def generate_itempool(world, player):
|
|||||||
for _ in range(0, amt):
|
for _ in range(0, amt):
|
||||||
pool.append('Rupees (20)')
|
pool.append('Rupees (20)')
|
||||||
|
|
||||||
if world.logic[player] == 'hybridglitches' and world.pottery[player] not in ['none', 'cave']:
|
if world.logic[player] == 'hybridglitches' and world.pottery[player] not in ['none', 'cave'] \
|
||||||
|
and world.keyshuffle[player] not in ['none', 'nearby']:
|
||||||
# In HMG force swamp smalls in pots to allow getting out of swamp palace
|
# In HMG force swamp smalls in pots to allow getting out of swamp palace
|
||||||
placed_items['Swamp Palace - Trench 1 Pot Key'] = 'Small Key (Swamp Palace)'
|
placed_items['Swamp Palace - Trench 1 Pot Key'] = 'Small Key (Swamp Palace)'
|
||||||
placed_items['Swamp Palace - Pot Row Pot Key'] = 'Small Key (Swamp Palace)'
|
placed_items['Swamp Palace - Pot Row Pot Key'] = 'Small Key (Swamp Palace)'
|
||||||
@@ -348,11 +349,11 @@ def generate_itempool(world, player):
|
|||||||
world.treasure_hunt_icon[player] = 'Triforce Piece'
|
world.treasure_hunt_icon[player] = 'Triforce Piece'
|
||||||
|
|
||||||
world.itempool.extend([item for item in get_dungeon_item_pool(world) if item.player == player
|
world.itempool.extend([item for item in get_dungeon_item_pool(world) if item.player == player
|
||||||
and ((item.prize and world.prizeshuffle[player] not in ['none', 'dungeon', 'district'])
|
and ((item.prize and world.prizeshuffle[player] not in ['none', 'dungeon', 'nearby'])
|
||||||
or (item.smallkey and world.keyshuffle[player] not in ['none', 'district'])
|
or (item.smallkey and world.keyshuffle[player] not in ['none', 'nearby'])
|
||||||
or (item.bigkey and world.bigkeyshuffle[player] not in ['none', 'district'])
|
or (item.bigkey and world.bigkeyshuffle[player] not in ['none', 'nearby'])
|
||||||
or (item.map and world.mapshuffle[player] not in ['none', 'district'])
|
or (item.map and world.mapshuffle[player] not in ['none', 'nearby'])
|
||||||
or (item.compass and world.compassshuffle[player] not in ['none', 'district']))])
|
or (item.compass and world.compassshuffle[player] not in ['none', 'nearby']))])
|
||||||
|
|
||||||
if world.logic[player] == 'hybridglitches' and world.pottery[player] not in ['none', 'cave']:
|
if world.logic[player] == 'hybridglitches' and world.pottery[player] not in ['none', 'cave']:
|
||||||
keys_to_remove = 2
|
keys_to_remove = 2
|
||||||
@@ -365,19 +366,6 @@ def generate_itempool(world, player):
|
|||||||
for wix in reversed(to_remove):
|
for wix in reversed(to_remove):
|
||||||
del world.itempool[wix]
|
del world.itempool[wix]
|
||||||
|
|
||||||
if world.logic[player] == 'hybridglitches' and world.pottery[player] not in ['none', 'cave']:
|
|
||||||
# In HMG force swamp smalls in pots to allow getting out of swamp palace
|
|
||||||
loc = world.get_location('Swamp Palace - Trench 1 Pot Key', player)
|
|
||||||
world.push_item(loc, ItemFactory('Small Key (Swamp Palace)', player), False)
|
|
||||||
loc.event = True
|
|
||||||
loc.locked = True
|
|
||||||
loc = world.get_location('Swamp Palace - Pot Row Pot Key', player)
|
|
||||||
world.push_item(loc, ItemFactory('Small Key (Swamp Palace)', player), False)
|
|
||||||
loc.event = True
|
|
||||||
loc.locked = True
|
|
||||||
world.itempool.remove(ItemFactory('Small Key (Swamp Palace)', player))
|
|
||||||
world.itempool.remove(ItemFactory('Small Key (Swamp Palace)', player))
|
|
||||||
|
|
||||||
# logic has some branches where having 4 hearts is one possible requirement (of several alternatives)
|
# logic has some branches where having 4 hearts is one possible requirement (of several alternatives)
|
||||||
# rather than making all hearts/heart pieces progression items (which slows down generation considerably)
|
# rather than making all hearts/heart pieces progression items (which slows down generation considerably)
|
||||||
# We mark one random heart container as an advancement item (or 4 heart pieces in expert mode)
|
# We mark one random heart container as an advancement item (or 4 heart pieces in expert mode)
|
||||||
|
|||||||
2
Main.py
2
Main.py
@@ -619,6 +619,7 @@ def copy_world(world):
|
|||||||
ret.inaccessible_regions = world.inaccessible_regions.copy()
|
ret.inaccessible_regions = world.inaccessible_regions.copy()
|
||||||
ret.damage_table = world.damage_table
|
ret.damage_table = world.damage_table
|
||||||
ret.data_tables = world.data_tables # can be changed...
|
ret.data_tables = world.data_tables # can be changed...
|
||||||
|
ret.settings = world.settings
|
||||||
|
|
||||||
for player in range(1, world.players + 1):
|
for player in range(1, world.players + 1):
|
||||||
create_regions(ret, player)
|
create_regions(ret, player)
|
||||||
@@ -832,6 +833,7 @@ def copy_world_premature(world, player):
|
|||||||
ret.damage_table = world.damage_table
|
ret.damage_table = world.damage_table
|
||||||
ret.data_tables = world.data_tables # can be changed...
|
ret.data_tables = world.data_tables # can be changed...
|
||||||
ret.key_logic = world.key_logic.copy()
|
ret.key_logic = world.key_logic.copy()
|
||||||
|
ret.settings = world.settings
|
||||||
|
|
||||||
ret.is_copied_world = True
|
ret.is_copied_world = True
|
||||||
|
|
||||||
|
|||||||
@@ -1384,11 +1384,10 @@ def can_reach_smith(world, player):
|
|||||||
region = world.get_region(region_name, player)
|
region = world.get_region(region_name, player)
|
||||||
for exit in region.exits:
|
for exit in region.exits:
|
||||||
if not found and exit.connected_region is not None:
|
if not found and exit.connected_region is not None:
|
||||||
if exit.spot_type == 'Flute':
|
if starting_flute and exit.spot_type == 'Flute':
|
||||||
if any(map(lambda i: i.name == 'Ocarina (Activated)' and i.player == player, world.precollected_items)):
|
for flutespot in exit.connected_region.exits:
|
||||||
for flutespot in exit.connected_region.exits:
|
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:
|
||||||
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:
|
explore_region(flutespot.connected_region.name, flutespot.connected_region)
|
||||||
explore_region(flutespot.connected_region.name, flutespot.connected_region)
|
|
||||||
elif exit.connected_region.name == 'Blacksmiths Hut' and exit.access_rule(blank_state):
|
elif exit.connected_region.name == 'Blacksmiths Hut' and exit.access_rule(blank_state):
|
||||||
found = True
|
found = True
|
||||||
return
|
return
|
||||||
@@ -1410,6 +1409,7 @@ def can_reach_smith(world, player):
|
|||||||
|
|
||||||
found = False
|
found = False
|
||||||
explored_regions = list()
|
explored_regions = list()
|
||||||
|
starting_flute = any(map(lambda i: i.name == 'Ocarina (Activated)' and i.player == player, world.precollected_items))
|
||||||
if not world.is_bombshop_start(player):
|
if not world.is_bombshop_start(player):
|
||||||
start_region = 'Links House'
|
start_region = 'Links House'
|
||||||
else:
|
else:
|
||||||
@@ -1479,7 +1479,7 @@ def build_sectors(world, player):
|
|||||||
|
|
||||||
return sectors
|
return sectors
|
||||||
|
|
||||||
def build_accessible_region_list(world, start_region, player, build_copy_world=False, cross_world=False, region_rules=True, ignore_ledges = False):
|
def build_accessible_region_list(world, start_region, player, build_copy_world=False, cross_world=False, region_rules=True, ignore_ledges=False, restrictive_follower=False):
|
||||||
from BaseClasses import CollectionState
|
from BaseClasses import CollectionState
|
||||||
from Main import copy_world_premature
|
from Main import copy_world_premature
|
||||||
from Items import ItemFactory
|
from Items import ItemFactory
|
||||||
@@ -1494,15 +1494,17 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F
|
|||||||
region = base_world.get_region(region_name, player)
|
region = base_world.get_region(region_name, player)
|
||||||
for exit in region.exits:
|
for exit in region.exits:
|
||||||
if exit.connected_region is not None:
|
if exit.connected_region is not None:
|
||||||
if any(map(lambda i: i.name == 'Ocarina (Activated)' and i.player == player, base_world.precollected_items)) and exit.spot_type == 'Flute':
|
if starting_flute and exit.spot_type == 'Flute':
|
||||||
fluteregion = exit.connected_region
|
fluteregion = exit.connected_region
|
||||||
for flutespot in fluteregion.exits:
|
for flutespot in fluteregion.exits:
|
||||||
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:
|
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:
|
||||||
explore_region(flutespot.connected_region.name, flutespot.connected_region)
|
explore_region(flutespot.connected_region.name, flutespot.connected_region)
|
||||||
elif exit.connected_region.name not in explored_regions \
|
elif exit.connected_region.name not in explored_regions \
|
||||||
and (exit.connected_region.type == region.type
|
and (exit.connected_region.type == region.type or exit.name in OWExitTypes['OWEdge']
|
||||||
or exit.name in OWExitTypes['OWEdge'] or (cross_world and exit.name in (OWExitTypes['Portal'] + OWExitTypes['Mirror']))) \
|
or (cross_world and exit.name in (OWExitTypes['Portal'] + OWExitTypes['Mirror']))) \
|
||||||
and (not region_rules or exit.access_rule(blank_state)) and (not ignore_ledges or exit.name not in (OWExitTypes['Ledge'] + OWExitTypes['OWG'])):
|
and (not region_rules or exit.access_rule(blank_state)) \
|
||||||
|
and (not restrictive_follower or exit.spot_type != 'OWG') \
|
||||||
|
and (not ignore_ledges or not (exit.spot_type == 'OWG' or exit.name in OWExitTypes['Ledge'])):
|
||||||
explore_region(exit.connected_region.name, exit.connected_region)
|
explore_region(exit.connected_region.name, exit.connected_region)
|
||||||
|
|
||||||
if build_copy_world:
|
if build_copy_world:
|
||||||
@@ -1518,6 +1520,7 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F
|
|||||||
if base_world.mode[player] == 'standard':
|
if base_world.mode[player] == 'standard':
|
||||||
blank_state.collect(ItemFactory('Zelda Delivered', player), True)
|
blank_state.collect(ItemFactory('Zelda Delivered', player), True)
|
||||||
explored_regions = list()
|
explored_regions = list()
|
||||||
|
starting_flute = any(map(lambda i: i.name == 'Ocarina (Activated)' and i.player == player, base_world.precollected_items))
|
||||||
explore_region(start_region)
|
explore_region(start_region)
|
||||||
|
|
||||||
return explored_regions
|
return explored_regions
|
||||||
|
|||||||
24
Rom.py
24
Rom.py
@@ -43,7 +43,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = '1fde4fa24bc9d3efe450c3bc30e4cf2c'
|
RANDOMIZERBASEHASH = 'a84f59e5e76492f6a5693835823e6292'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -439,6 +439,8 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
location.pot.item = valid_pot_items[location.item.name]
|
location.pot.item = valid_pot_items[location.item.name]
|
||||||
else:
|
else:
|
||||||
code = itemid
|
code = itemid
|
||||||
|
if world.pottery[player] == 'none' or location.locked:
|
||||||
|
code = handle_native_dungeon(location, itemid)
|
||||||
standing_item_flag = 0x80
|
standing_item_flag = 0x80
|
||||||
if location.item.player != player:
|
if location.item.player != player:
|
||||||
standing_item_flag |= 0x40
|
standing_item_flag |= 0x40
|
||||||
@@ -1276,28 +1278,28 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
# m - enabled for inside maps
|
# m - enabled for inside maps
|
||||||
# c - enabled for inside compasses
|
# c - enabled for inside compasses
|
||||||
# s - enabled for inside small keys
|
# s - enabled for inside small keys
|
||||||
free_item_text = 0x40 if 'district' in [world.mapshuffle[player], world.compassshuffle[player], world.keyshuffle[player], world.bigkeyshuffle[player]] else 0x00
|
free_item_text = 0x40 if 'nearby' in [world.mapshuffle[player], world.compassshuffle[player], world.keyshuffle[player], world.bigkeyshuffle[player]] else 0x00
|
||||||
rom.write_byte(0x18016A, free_item_text | 0x10 | ((0x20 if world.prizeshuffle[player] not in ['none', 'dungeon'] else 0x00)
|
rom.write_byte(0x18016A, free_item_text | 0x10 | ((0x20 if world.prizeshuffle[player] not in ['none', 'dungeon'] else 0x00)
|
||||||
| (0x01 if world.keyshuffle[player] not in ['none', 'universal'] else 0x00)
|
| (0x01 if world.keyshuffle[player] not in ['none', 'universal'] else 0x00)
|
||||||
| (0x02 if world.compassshuffle[player] != 'none' else 0x00)
|
| (0x02 if world.compassshuffle[player] != 'none' else 0x00)
|
||||||
| (0x04 if world.mapshuffle[player] != 'none' else 0x00)
|
| (0x04 if world.mapshuffle[player] != 'none' else 0x00)
|
||||||
| (0x08 if world.bigkeyshuffle[player] != 'none' else 0x00))) # free roaming item text boxes
|
| (0x08 if world.bigkeyshuffle[player] != 'none' else 0x00))) # free roaming item text boxes
|
||||||
rom.write_byte(0x18003B, 0x01 if world.mapshuffle[player] not in ['none', 'district'] else 0x00) # maps showing crystals on overworld
|
rom.write_byte(0x18003B, 0x01 if world.mapshuffle[player] not in ['none', 'nearby'] else 0x00) # maps showing crystals on overworld
|
||||||
|
|
||||||
# compasses showing dungeon count
|
# compasses showing dungeon count
|
||||||
compass_mode = 0x80 if world.compassshuffle[player] not in ['none', 'district'] else 0x00
|
compass_mode = 0x80 if world.compassshuffle[player] not in ['none', 'nearby'] else 0x00
|
||||||
if world.clock_mode != 'none' or world.dungeon_counters[player] == 'off':
|
if world.clock_mode != 'none' or world.dungeon_counters[player] == 'off':
|
||||||
pass
|
pass
|
||||||
elif world.dungeon_counters[player] == 'on':
|
elif world.dungeon_counters[player] == 'on':
|
||||||
compass_mode |= 0x02 # always on
|
compass_mode |= 0x02 # always on
|
||||||
elif (world.compassshuffle[player] not in ['none', 'district'] or world.doorShuffle[player] != 'vanilla' or world.dropshuffle[player] != 'none'
|
elif (world.compassshuffle[player] not in ['none', 'nearby'] or world.doorShuffle[player] != 'vanilla' or world.dropshuffle[player] != 'none'
|
||||||
or world.dungeon_counters[player] == 'pickup' or world.pottery[player] not in ['none', 'cave']):
|
or world.dungeon_counters[player] == 'pickup' or world.pottery[player] not in ['none', 'cave']):
|
||||||
compass_mode |= 0x01 # show on pickup
|
compass_mode |= 0x01 # show on pickup
|
||||||
if world.overworld_map[player] == 'map':
|
if world.overworld_map[player] == 'map':
|
||||||
compass_mode |= 0x10 # show icon if map is collected
|
compass_mode |= 0x10 # show icon if map is collected
|
||||||
elif world.overworld_map[player] == 'compass':
|
elif world.overworld_map[player] == 'compass':
|
||||||
compass_mode |= 0x20 # show icon if compass is collected
|
compass_mode |= 0x20 # show icon if compass is collected
|
||||||
if world.prizeshuffle[player] not in ['none', 'dungeon', 'district']:
|
if world.prizeshuffle[player] not in ['none', 'dungeon', 'nearby']:
|
||||||
compass_mode |= 0x40 # show icon if boss is defeated, hide if collected
|
compass_mode |= 0x40 # show icon if boss is defeated, hide if collected
|
||||||
rom.write_byte(0x18003C, compass_mode)
|
rom.write_byte(0x18003C, compass_mode)
|
||||||
|
|
||||||
@@ -1333,7 +1335,7 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
map_index = max(0, dungeon_index - 2)
|
map_index = max(0, dungeon_index - 2)
|
||||||
|
|
||||||
# write out dislocated coords
|
# write out dislocated coords
|
||||||
if map_index >= 0x02 and map_index < 0x18 and (world.overworld_map[player] != 'default' or world.prizeshuffle[player] not in ['none', 'dungeon', 'district']):
|
if map_index >= 0x02 and map_index < 0x18 and (world.overworld_map[player] != 'default' or world.prizeshuffle[player] not in ['none', 'dungeon', 'nearby']):
|
||||||
owid_map = [0x1E, 0x30, 0xFF, 0x7B, 0x5E, 0x70, 0x40, 0x75, 0x03, 0x58, 0x47]
|
owid_map = [0x1E, 0x30, 0xFF, 0x7B, 0x5E, 0x70, 0x40, 0x75, 0x03, 0x58, 0x47]
|
||||||
x_map_position_generic = [0x03c0, 0x0740, 0xff00, 0x03c0, 0x01c0, 0x0bc0, 0x05c0, 0x09c0, 0x0ac0, 0x07c0, 0x0dc0]
|
x_map_position_generic = [0x03c0, 0x0740, 0xff00, 0x03c0, 0x01c0, 0x0bc0, 0x05c0, 0x09c0, 0x0ac0, 0x07c0, 0x0dc0]
|
||||||
y_map_position_generic = [0xff00, 0xff00, 0xff00, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0xff00, 0x0fc0, 0x0fc0]
|
y_map_position_generic = [0xff00, 0xff00, 0xff00, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0x0fc0, 0xff00, 0x0fc0, 0x0fc0]
|
||||||
@@ -1347,7 +1349,7 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
write_int16(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+6, y_map_position_generic[idx])
|
write_int16(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+6, y_map_position_generic[idx])
|
||||||
|
|
||||||
# write out icon coord data
|
# write out icon coord data
|
||||||
if world.prizeshuffle[player] not in ['none', 'dungeon', 'district'] and dungeon_table[dungeon].prize:
|
if world.prizeshuffle[player] not in ['none', 'dungeon', 'nearby'] and dungeon_table[dungeon].prize:
|
||||||
dungeon_obj = world.get_dungeon(dungeon, player)
|
dungeon_obj = world.get_dungeon(dungeon, player)
|
||||||
entrance = dungeon_obj.prize.get_map_location()
|
entrance = dungeon_obj.prize.get_map_location()
|
||||||
coords = get_entrance_coords(entrance)
|
coords = get_entrance_coords(entrance)
|
||||||
@@ -1387,7 +1389,7 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
|
|
||||||
# figure out compass entrances and what world (light/dark)
|
# figure out compass entrances and what world (light/dark)
|
||||||
write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6), coords)
|
write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6), coords)
|
||||||
if world.prizeshuffle[player] in ['none', 'dungeon', 'district'] and dungeon_table[dungeon].prize:
|
if world.prizeshuffle[player] in ['none', 'dungeon', 'nearby'] and dungeon_table[dungeon].prize:
|
||||||
# prize location
|
# prize location
|
||||||
write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+8, coords)
|
write_int16s(rom, snes_to_pc(0x0ABE2E)+(map_index*6)+8, coords)
|
||||||
|
|
||||||
@@ -1426,7 +1428,7 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
# b - Big Key
|
# b - Big Key
|
||||||
# a - Small Key
|
# a - Small Key
|
||||||
#
|
#
|
||||||
enable_menu_map_check = (world.overworld_map[player] != 'default' and world.shuffle[player] != 'vanilla') or world.prizeshuffle[player] not in ['none', 'dungeon', 'district']
|
enable_menu_map_check = (world.overworld_map[player] != 'default' and world.shuffle[player] != 'vanilla') or world.prizeshuffle[player] not in ['none', 'dungeon', 'nearby']
|
||||||
rom.write_byte(0x180045, ((0x01 if world.keyshuffle[player] not in ['none', 'universal'] else 0x00)
|
rom.write_byte(0x180045, ((0x01 if world.keyshuffle[player] not in ['none', 'universal'] else 0x00)
|
||||||
| (0x02 if world.bigkeyshuffle[player] != 'none' else 0x00)
|
| (0x02 if world.bigkeyshuffle[player] != 'none' else 0x00)
|
||||||
| (0x04 if world.mapshuffle[player] != 'none' or enable_menu_map_check else 0x00)
|
| (0x04 if world.mapshuffle[player] != 'none' or enable_menu_map_check else 0x00)
|
||||||
@@ -2329,7 +2331,7 @@ def write_strings(rom, world, player, team):
|
|||||||
(crystal5, crystal6, greenpendant) = tuple([x.parent_region.dungeon.name for x in [crystal5, crystal6, greenpendant]])
|
(crystal5, crystal6, greenpendant) = tuple([x.parent_region.dungeon.name for x in [crystal5, crystal6, greenpendant]])
|
||||||
tt['bomb_shop'] = 'Big Bomb?\nMy supply is blocked until you clear %s and %s.' % (crystal5, crystal6)
|
tt['bomb_shop'] = 'Big Bomb?\nMy supply is blocked until you clear %s and %s.' % (crystal5, crystal6)
|
||||||
tt['sahasrahla_bring_courage'] = 'I lost my family heirloom in %s' % greenpendant
|
tt['sahasrahla_bring_courage'] = 'I lost my family heirloom in %s' % greenpendant
|
||||||
elif world.prizeshuffle[player] == 'district':
|
elif world.prizeshuffle[player] == 'nearby':
|
||||||
(crystal5, crystal6, greenpendant) = tuple([x.item.dungeon_object.name for x in [crystal5, crystal6, greenpendant]])
|
(crystal5, crystal6, greenpendant) = tuple([x.item.dungeon_object.name for x in [crystal5, crystal6, greenpendant]])
|
||||||
tt['bomb_shop'] = 'Big Bomb?\nThe crystals can be found near %s and %s.' % (crystal5, crystal6)
|
tt['bomb_shop'] = 'Big Bomb?\nThe crystals can be found near %s and %s.' % (crystal5, crystal6)
|
||||||
tt['sahasrahla_bring_courage'] = 'I lost my family heirloom near %s' % greenpendant
|
tt['sahasrahla_bring_courage'] = 'I lost my family heirloom near %s' % greenpendant
|
||||||
|
|||||||
2
Rules.py
2
Rules.py
@@ -1306,7 +1306,7 @@ def ow_terrain_rules(world, player):
|
|||||||
ent = world.get_entrance(edge.name, player)
|
ent = world.get_entrance(edge.name, player)
|
||||||
if edge.terrain == Terrain.Land:
|
if edge.terrain == Terrain.Land:
|
||||||
set_rule(ent, lambda state: state.has('Flippers', player))
|
set_rule(ent, lambda state: state.has('Flippers', player))
|
||||||
if ent.parent_region.is_light_world == (world.mode[player] != 'inverted') and ent.connected_region.is_dark_world == (world.mode[player] != 'inverted'):
|
if ent.connected_region.is_dark_world == (world.mode[player] != 'inverted'):
|
||||||
add_rule(ent, lambda state: state.has_Pearl(player))
|
add_rule(ent, lambda state: state.has_Pearl(player))
|
||||||
|
|
||||||
for whirlpool_name in OWExitTypes['Whirlpool']:
|
for whirlpool_name in OWExitTypes['Whirlpool']:
|
||||||
|
|||||||
@@ -173,20 +173,21 @@ def dungeon_reentry_rules(
|
|||||||
def underworld_glitches_rules(world, player):
|
def underworld_glitches_rules(world, player):
|
||||||
def mire_clip(state):
|
def mire_clip(state):
|
||||||
torches = world.get_region("Mire Torches Top", player)
|
torches = world.get_region("Mire Torches Top", player)
|
||||||
return state.can_dash_clip(torches, player) or (
|
return (state.can_dash_clip(torches, player)
|
||||||
state.can_bomb_clip(torches, player) and state.has_fire_source(player)
|
or (state.can_bomb_clip(torches, player) and state.has_fire_source(player))
|
||||||
)
|
) and state.can_reach(torches, player)
|
||||||
|
|
||||||
def hera_clip(state):
|
def hera_clip(state):
|
||||||
hera = world.get_region("Hera 4F", player)
|
hera = world.get_region("Hera 4F", player)
|
||||||
return state.can_bomb_clip(hera, player) or state.can_dash_clip(hera, player)
|
return (state.can_bomb_clip(hera, player) or state.can_dash_clip(hera, player)) \
|
||||||
|
and state.has("Flippers", player) and state.can_reach(hera) and mire_clip(state)
|
||||||
|
|
||||||
# We use these plus functool.partial because lambdas don't work in loops properly.
|
# We use these plus functool.partial because lambdas don't work in loops properly.
|
||||||
def bomb_clip(state, region, player):
|
def bomb_clip(state, region, player):
|
||||||
return state.can_bomb_clip(region, player)
|
return state.can_bomb_clip(region, player) and state.can_reach(region, player)
|
||||||
|
|
||||||
def dash_clip(state, region, player):
|
def dash_clip(state, region, player):
|
||||||
return state.can_dash_clip(region, player)
|
return state.can_dash_clip(region, player) and state.can_reach(region, player)
|
||||||
# Bomb clips
|
# Bomb clips
|
||||||
for clip in (
|
for clip in (
|
||||||
kikiskip_spots
|
kikiskip_spots
|
||||||
@@ -233,18 +234,24 @@ def underworld_glitches_rules(world, player):
|
|||||||
# Allow mire big key to be used in Hera
|
# Allow mire big key to be used in Hera
|
||||||
Rules.add_rule(
|
Rules.add_rule(
|
||||||
world.get_entrance("Hera Startile Corner NW", player),
|
world.get_entrance("Hera Startile Corner NW", player),
|
||||||
lambda state: mire_clip(state) and state.has("Big Key (Misery Mire)", player),
|
lambda state: state.has("Big Key (Misery Mire)", player) and mire_clip(state),
|
||||||
combine="or",
|
combine="or",
|
||||||
)
|
)
|
||||||
Rules.add_rule(
|
Rules.add_rule(
|
||||||
world.get_location("Tower of Hera - Big Chest", player),
|
world.get_location("Tower of Hera - Big Chest", player),
|
||||||
lambda state: mire_clip(state) and state.has("Big Key (Misery Mire)", player),
|
lambda state: state.has("Big Key (Misery Mire)", player) and mire_clip(state),
|
||||||
combine="or",
|
combine="or",
|
||||||
)
|
)
|
||||||
# This uses the mire clip because it's always expected to come from mire
|
# This uses the mire clip because it's always expected to come from mire
|
||||||
Rules.set_rule(
|
Rules.set_rule(
|
||||||
world.get_entrance("Hera to Swamp Clip", player),
|
world.get_entrance("Hera to Swamp Clip", player),
|
||||||
lambda state: mire_clip(state) and state.has("Flippers", player),
|
lambda state: state.has("Flippers", player) and mire_clip(state),
|
||||||
|
)
|
||||||
|
Rules.add_rule(
|
||||||
|
world.get_location("Swamp Palace - Big Chest", player),
|
||||||
|
lambda state: (state.has("Big Key (Misery Mire)", player) or state.has("Big Key (Tower of Hera)", player)) \
|
||||||
|
and state.has("Flippers", player) and mire_clip(state),
|
||||||
|
combine="or",
|
||||||
)
|
)
|
||||||
# We need to set _all_ swamp doors to be openable with mire keys, otherwise the small key can't be behind them - 6 keys because of Pots
|
# We need to set _all_ swamp doors to be openable with mire keys, otherwise the small key can't be behind them - 6 keys because of Pots
|
||||||
# Flippers required for all of these doors to prevent locks when flooding
|
# Flippers required for all of these doors to prevent locks when flooding
|
||||||
@@ -263,9 +270,9 @@ def underworld_glitches_rules(world, player):
|
|||||||
]:
|
]:
|
||||||
Rules.add_rule(
|
Rules.add_rule(
|
||||||
world.get_entrance(door, player),
|
world.get_entrance(door, player),
|
||||||
lambda state: mire_clip(state)
|
lambda state: state.has("Flippers", player)
|
||||||
and state.has("Small Key (Misery Mire)", player, count=6)
|
and state.has("Small Key (Misery Mire)", player, count=6)
|
||||||
and state.has("Flippers", player),
|
and mire_clip(state),
|
||||||
combine="or",
|
combine="or",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -311,8 +318,8 @@ def underworld_glitches_rules(world, player):
|
|||||||
return (
|
return (
|
||||||
state.can_reach("Old Man S&Q", "Entrance", player)
|
state.can_reach("Old Man S&Q", "Entrance", player)
|
||||||
and state.has("Flippers", player)
|
and state.has("Flippers", player)
|
||||||
and mire_clip(state)
|
|
||||||
and (hera_rule(state) or gt_rule(state))
|
and (hera_rule(state) or gt_rule(state))
|
||||||
|
and mire_clip(state)
|
||||||
)
|
)
|
||||||
|
|
||||||
Rules.add_rule(
|
Rules.add_rule(
|
||||||
|
|||||||
Binary file not shown.
@@ -151,7 +151,7 @@
|
|||||||
prize_shuffle:
|
prize_shuffle:
|
||||||
none: 1
|
none: 1
|
||||||
dungeon: 1
|
dungeon: 1
|
||||||
district: 1
|
nearby: 1
|
||||||
wild: 1
|
wild: 1
|
||||||
dungeon_items:
|
dungeon_items:
|
||||||
standard: 10
|
standard: 10
|
||||||
@@ -162,20 +162,20 @@
|
|||||||
# for use when you aren't using the dungeon_items above
|
# for use when you aren't using the dungeon_items above
|
||||||
# map_shuffle:
|
# map_shuffle:
|
||||||
# none: 1
|
# none: 1
|
||||||
# district: 1
|
# nearby: 1
|
||||||
# wild: 1
|
# wild: 1
|
||||||
# compass_shuffle:
|
# compass_shuffle:
|
||||||
# none: 1
|
# none: 1
|
||||||
# district: 1
|
# nearby: 1
|
||||||
# wild: 1
|
# wild: 1
|
||||||
# smallkey_shuffle:
|
# smallkey_shuffle:
|
||||||
# none: 5
|
# none: 5
|
||||||
# district: 1
|
# nearby: 1
|
||||||
# wild: 1
|
# wild: 1
|
||||||
# universal: 1
|
# universal: 1
|
||||||
# bigkey_shuffle:
|
# bigkey_shuffle:
|
||||||
# none: 1
|
# none: 1
|
||||||
# district: 1
|
# nearby: 1
|
||||||
# wild: 1
|
# wild: 1
|
||||||
dungeon_counters:
|
dungeon_counters:
|
||||||
on: 5
|
on: 5
|
||||||
|
|||||||
@@ -558,6 +558,10 @@ class Sprite(object):
|
|||||||
if self.location is not None:
|
if self.location is not None:
|
||||||
item_id = self.location.item.code if self.location.item is not None else 0x5A
|
item_id = self.location.item.code if self.location.item is not None else 0x5A
|
||||||
code = 0xF9 if self.location.item.player != self.location.player else 0xF8
|
code = 0xF9 if self.location.item.player != self.location.player else 0xF8
|
||||||
|
if code == 0xF8:
|
||||||
|
world = self.location.parent_region.world
|
||||||
|
if world.dropshuffle[self.location.player] == 'none' or self.location.locked:
|
||||||
|
item_id = handle_native_dungeon(self.location, item_id)
|
||||||
data.append(item_id)
|
data.append(item_id)
|
||||||
data.append(0 if code == 0xF8 else self.location.item.player)
|
data.append(0 if code == 0xF8 else self.location.item.player)
|
||||||
data.append(code)
|
data.append(code)
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ def do_old_man_cave_exit(entrances, exits, avail, cross_world):
|
|||||||
region_name = 'West Death Mountain (Top)'
|
region_name = 'West Death Mountain (Top)'
|
||||||
else:
|
else:
|
||||||
region_name = 'West Dark Death Mountain (Top)'
|
region_name = 'West Dark Death Mountain (Top)'
|
||||||
om_cave_options = list(get_accessible_entrances(region_name, avail, [], cross_world, True, True, True))
|
om_cave_options = list(get_accessible_entrances(region_name, avail, [], cross_world, True, True, True, True))
|
||||||
om_cave_options = [e for e in om_cave_options if e in entrances and e != 'Old Man House (Bottom)']
|
om_cave_options = [e for e in om_cave_options if e in entrances and e != 'Old Man House (Bottom)']
|
||||||
if avail.swapped:
|
if avail.swapped:
|
||||||
om_cave_options = [e for e in om_cave_options if e not in Forbidden_Swap_Entrances]
|
om_cave_options = [e for e in om_cave_options if e not in Forbidden_Swap_Entrances]
|
||||||
@@ -863,7 +863,7 @@ def get_nearby_entrances(avail, start_region):
|
|||||||
return candidates
|
return candidates
|
||||||
|
|
||||||
|
|
||||||
def get_accessible_entrances(start_region, avail, assumed_inventory=[], cross_world=False, region_rules=True, exit_rules=True, include_one_ways=False):
|
def get_accessible_entrances(start_region, avail, assumed_inventory=[], cross_world=False, region_rules=True, exit_rules=True, include_one_ways=False, restrictive_follower=False):
|
||||||
from Main import copy_world_premature
|
from Main import copy_world_premature
|
||||||
from BaseClasses import CollectionState
|
from BaseClasses import CollectionState
|
||||||
from Items import ItemFactory
|
from Items import ItemFactory
|
||||||
@@ -878,10 +878,12 @@ def get_accessible_entrances(start_region, avail, assumed_inventory=[], cross_wo
|
|||||||
blank_state = CollectionState(base_world)
|
blank_state = CollectionState(base_world)
|
||||||
if base_world.mode[avail.player] == 'standard':
|
if base_world.mode[avail.player] == 'standard':
|
||||||
blank_state.collect(ItemFactory('Zelda Delivered', avail.player), True)
|
blank_state.collect(ItemFactory('Zelda Delivered', avail.player), True)
|
||||||
|
if base_world.logic[avail.player] in ['owglitches', 'hybridglitches', 'nologic']:
|
||||||
|
blank_state.collect(ItemFactory('Pegasus Boots', avail.player), True)
|
||||||
for item in assumed_inventory:
|
for item in assumed_inventory:
|
||||||
blank_state.collect(ItemFactory(item, avail.player), True)
|
blank_state.collect(ItemFactory(item, avail.player), True)
|
||||||
|
|
||||||
explored_regions = list(build_accessible_region_list(base_world, start_region, avail.player, False, cross_world, region_rules, False))
|
explored_regions = list(build_accessible_region_list(base_world, start_region, avail.player, False, cross_world, region_rules, False, restrictive_follower))
|
||||||
|
|
||||||
if include_one_ways:
|
if include_one_ways:
|
||||||
new_regions = list()
|
new_regions = list()
|
||||||
@@ -1284,8 +1286,9 @@ def handle_skull_woods_drops(avail, pool, mode_cfg):
|
|||||||
keep_together = mode_cfg['keep_drops_together'] == 'on' if 'keep_drops_together' in mode_cfg else True
|
keep_together = mode_cfg['keep_drops_together'] == 'on' if 'keep_drops_together' in mode_cfg else True
|
||||||
if keep_together:
|
if keep_together:
|
||||||
for drop in ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)']:
|
for drop in ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)']:
|
||||||
target = drop_map[drop]
|
if drop in avail.entrances:
|
||||||
connect_entrance(drop, target, avail)
|
target = drop_map[drop]
|
||||||
|
connect_entrance(drop, target, avail)
|
||||||
|
|
||||||
|
|
||||||
def handle_skull_woods_entrances(avail, pool):
|
def handle_skull_woods_entrances(avail, pool):
|
||||||
|
|||||||
Reference in New Issue
Block a user