Merge branch 'OverworldShuffleDev' into OverworldShuffle
This commit is contained in:
@@ -147,7 +147,7 @@ class World(object):
|
||||
set_player_attr('crystals_needed_for_gt', 7)
|
||||
set_player_attr('crystals_ganon_orig', {})
|
||||
set_player_attr('crystals_gt_orig', {})
|
||||
set_player_attr('open_pyramid', False)
|
||||
set_player_attr('open_pyramid', 'auto')
|
||||
set_player_attr('treasure_hunt_icon', 'Triforce Piece')
|
||||
set_player_attr('treasure_hunt_count', 0)
|
||||
set_player_attr('treasure_hunt_total', 0)
|
||||
@@ -317,6 +317,19 @@ class World(object):
|
||||
def is_bombshop_start(self, player):
|
||||
return self.is_tile_swapped(0x2c, player) and (self.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not self.shufflelinks[player])
|
||||
|
||||
def is_pyramid_open(self, player):
|
||||
if self.open_pyramid[player] == 'yes':
|
||||
return True
|
||||
elif self.open_pyramid[player] == 'no':
|
||||
return False
|
||||
else:
|
||||
if self.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
|
||||
return False
|
||||
elif self.goal[player] in ['crystals', 'trinity']:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def check_for_door(self, doorname, player):
|
||||
if isinstance(doorname, Door):
|
||||
return doorname
|
||||
@@ -1265,7 +1278,7 @@ class CollectionState(object):
|
||||
|
||||
# In the future, this can be used to check if the player starts without bombs
|
||||
def can_use_bombs(self, player):
|
||||
return (not self.world.bombbag[player] or self.has('Bomb Upgrade (+10)', player)) and ((hasattr(self.world,"override_bomb_check") and self.world.override_bomb_check) or self.can_farm_bombs(player))
|
||||
return (not self.world.bombbag[player] or self.has('Bomb Upgrade (+10)', player) or self.has('Bomb Upgrade (+5)', player, 2)) and ((hasattr(self.world,"override_bomb_check") and self.world.override_bomb_check) or self.can_farm_bombs(player))
|
||||
|
||||
def can_hit_crystal(self, player):
|
||||
return (self.can_use_bombs(player)
|
||||
@@ -2225,7 +2238,6 @@ class Door(object):
|
||||
class WorldType(IntEnum):
|
||||
Light = 0
|
||||
Dark = 1
|
||||
Special = 2
|
||||
|
||||
|
||||
@unique
|
||||
@@ -2241,6 +2253,8 @@ class OWEdge(object):
|
||||
self.type = DoorType.Open
|
||||
self.direction = direction
|
||||
self.terrain = terrain
|
||||
self.specialEntrance = False
|
||||
self.specialExit = False
|
||||
self.deadEnd = False
|
||||
|
||||
# rom properties
|
||||
@@ -2254,6 +2268,7 @@ class OWEdge(object):
|
||||
self.zeroHzCam = False
|
||||
self.zeroVtCam = False
|
||||
self.edge_id = edge_id
|
||||
self.specialID = 0x0
|
||||
|
||||
self.midpoint = 0x0
|
||||
self.linkOpp = 0x0
|
||||
@@ -2265,12 +2280,10 @@ class OWEdge(object):
|
||||
self.unknownX = 0x0
|
||||
self.unknownY = 0x0
|
||||
|
||||
if self.owIndex < 0x40:
|
||||
if self.owIndex < 0x40 or self.owIndex >= 0x80:
|
||||
self.worldType = WorldType.Light
|
||||
elif self.owIndex < 0x80:
|
||||
self.worldType = WorldType.Dark
|
||||
else:
|
||||
self.worldType = WorldType.Special
|
||||
self.worldType = WorldType.Dark
|
||||
|
||||
# logical properties
|
||||
# self.connected = False # combine with Dest?
|
||||
@@ -2288,7 +2301,7 @@ class OWEdge(object):
|
||||
return base_address[self.direction] + (self.edge_id * 16)
|
||||
|
||||
def getTarget(self):
|
||||
return self.dest.edge_id
|
||||
return self.dest.specialID if self.dest.specialExit else self.dest.edge_id
|
||||
|
||||
def dead_end(self):
|
||||
self.deadEnd = True
|
||||
@@ -2298,6 +2311,16 @@ class OWEdge(object):
|
||||
self.vramLoc = vram_loc
|
||||
return self
|
||||
|
||||
def special_entrance(self, special_id):
|
||||
self.specialEntrance = True
|
||||
self.specialID = special_id
|
||||
return self
|
||||
|
||||
def special_exit(self, special_id):
|
||||
self.specialExit = True
|
||||
self.specialID = special_id
|
||||
return self
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, self.__class__) and self.name == other.name
|
||||
|
||||
@@ -3045,7 +3068,7 @@ class Spoiler(object):
|
||||
if self.metadata['shuffle'][player] != 'vanilla' or self.metadata['ow_mixed'][player]:
|
||||
outfile.write('Overworld Map:'.ljust(line_width) + '%s\n' % self.metadata['overworld_map'][player])
|
||||
if self.metadata['goal'][player] != 'trinity':
|
||||
outfile.write('Pyramid Hole Pre-opened:'.ljust(line_width) + '%s\n' % yn(self.metadata['open_pyramid'][player]))
|
||||
outfile.write('Pyramid Hole Pre-opened:'.ljust(line_width) + '%s\n' % self.metadata['open_pyramid'][player])
|
||||
outfile.write('Door Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['door_shuffle'][player])
|
||||
if self.metadata['door_shuffle'][player] != 'vanilla':
|
||||
outfile.write('Intensity:'.ljust(line_width) + '%s\n' % self.metadata['intensity'][player])
|
||||
@@ -3338,7 +3361,7 @@ class Settings(object):
|
||||
| (counter_mode[w.dungeon_counters[p]] << 1) | (1 if w.experimental[p] else 0),
|
||||
|
||||
((8 if w.crystals_ganon_orig[p] == "random" else int(w.crystals_ganon_orig[p])) << 3)
|
||||
| (0x4 if w.open_pyramid[p] else 0) | access_mode[w.accessibility[p]],
|
||||
| (0x4 if w.is_pyramid_open(p) else 0) | access_mode[w.accessibility[p]],
|
||||
|
||||
(0x80 if w.bigkeyshuffle[p] else 0) | (0x40 if w.keyshuffle[p] else 0)
|
||||
| (0x20 if w.mapshuffle[p] else 0) | (0x10 if w.compassshuffle[p] else 0)
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
### 0.2.7.2
|
||||
- Special OW Area are now shuffled in Layout Shuffle (Zora/Hobo/Pedestal)
|
||||
- Fixed some broken water region graph modelling, fixed some reachability logic
|
||||
- Some minor code simplifications
|
||||
|
||||
### 0.2.7.1
|
||||
- Map checks in Mixed OWR now will show the proper tile images when screens are swapped (ie. Pyramid shows in the LW if that screen is swapped)
|
||||
- Added mystery seed number to spoiler log, so it is easier to match a spoiler log to a rom filename
|
||||
|
||||
2
CLI.py
2
CLI.py
@@ -144,7 +144,7 @@ def parse_settings():
|
||||
"restrict_boss_items": "none",
|
||||
|
||||
# Shuffle Ganon defaults to TRUE
|
||||
"openpyramid": False,
|
||||
"openpyramid": "auto",
|
||||
"shuffleganon": True,
|
||||
"ow_shuffle": "vanilla",
|
||||
"ow_crossed": "none",
|
||||
|
||||
@@ -1668,7 +1668,7 @@ def get_starting_entrances(world, player, force_starting_world=True):
|
||||
# get entrances from list of regions
|
||||
entrances = list()
|
||||
for region_name in regions:
|
||||
if world.shuffle[player] == 'simple' and region_name in OWTileRegions and OWTileRegions[region_name] in [0x03, 0x05, 0x07]:
|
||||
if world.shuffle[player] == 'simple' and region_name in OWTileRegions.keys() and OWTileRegions[region_name] in [0x03, 0x05, 0x07]:
|
||||
continue
|
||||
region = world.get_region(region_name, player)
|
||||
if not force_starting_world or region.type == (RegionType.LightWorld if not invFlag else RegionType.DarkWorld):
|
||||
@@ -1710,7 +1710,7 @@ def get_distant_entrances(world, start_entrance, player):
|
||||
# get entrances from remaining regions
|
||||
candidates = list()
|
||||
for region_name in [r for r in regions if r not in explored_regions]:
|
||||
if OWTileRegions[region_name] in [0x03, 0x05, 0x07]:
|
||||
if region_name in OWTileRegions.keys() and OWTileRegions[region_name] in [0x03, 0x05, 0x07]:
|
||||
continue
|
||||
region = world.get_region(region_name, player)
|
||||
for exit in region.exits:
|
||||
|
||||
@@ -184,7 +184,6 @@ def roll_settings(weights):
|
||||
if ret.dungeon_counters == 'default':
|
||||
ret.dungeon_counters = 'pickup' if ret.door_shuffle != 'vanilla' or ret.compassshuffle == 'on' else 'off'
|
||||
|
||||
ret.shufflelinks = get_choice('shufflelinks') == 'on'
|
||||
ret.pseudoboots = get_choice('pseudoboots') == 'on'
|
||||
ret.shopsanity = get_choice('shopsanity') == 'on'
|
||||
ret.keydropshuffle = get_choice('keydropshuffle') == 'on'
|
||||
@@ -200,12 +199,13 @@ def roll_settings(weights):
|
||||
'triforce-hunt': 'triforcehunt',
|
||||
'trinity': 'trinity'
|
||||
}[goal]
|
||||
ret.openpyramid = goal in ['fast_ganon', 'trinity'] if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
|
||||
|
||||
ret.openpyramid = get_choice('open_pyramid') if 'open_pyramid' in weights else 'auto'
|
||||
|
||||
ret.shuffleganon = get_choice('shuffleganon') == 'on'
|
||||
ret.shufflelinks = get_choice('shufflelinks') == 'on'
|
||||
|
||||
ret.crystals_gt = get_choice('tower_open')
|
||||
|
||||
ret.crystals_ganon = get_choice('ganon_open')
|
||||
|
||||
goal_min = get_choice_default('triforce_goal_min', default=20)
|
||||
|
||||
60
OWEdges.py
60
OWEdges.py
@@ -38,7 +38,7 @@ NP = IsParallel.No
|
||||
def create_owedges(world, player):
|
||||
edges = [
|
||||
# name, owID,dir,type,edge_id,(owSlot) vram
|
||||
create_owedge(player, 'Lost Woods NW', 0x00, No, Ld, 0x00) .coordInfo(0x00a0, 0x0284),
|
||||
create_owedge(player, 'Lost Woods NW', 0x00, No, Ld, 0x00) .coordInfo(0x00a0, 0x0284).special_entrance(0x80),
|
||||
create_owedge(player, 'Lost Woods SW', 0x00, So, Ld, 0x01, 0x08).coordInfo(0x0058, 0x2000),
|
||||
create_owedge(player, 'Lost Woods SC', 0x00, So, Ld, 0x02, 0x08).coordInfo(0x0178, 0x2020),
|
||||
create_owedge(player, 'Lost Woods SE', 0x00, So, Ld, 0x03, 0x09).coordInfo(0x0388, 0x2060),
|
||||
@@ -53,7 +53,7 @@ def create_owedges(world, player):
|
||||
create_owedge(player, 'Death Mountain TR Pegs WN', 0x07, We, Ld, 0x02) .coordInfo(0x0078, 0x00e0),
|
||||
create_owedge(player, 'Mountain Entry NW', 0x0a, No, Ld, 0x01) .coordInfo(0x04cc, 0x180a),
|
||||
create_owedge(player, 'Mountain Entry SE', 0x0a, So, Ld, 0x04) .coordInfo(0x0518, 0x1012),
|
||||
create_owedge(player, 'Zora Waterfall NE', 0x0f, No, Ld, 0x02) .coordInfo(0x0f80, 0x009a),
|
||||
create_owedge(player, 'Zora Waterfall NE', 0x0f, No, Ld, 0x02) .coordInfo(0x0f80, 0x009a).special_entrance(0x82),
|
||||
create_owedge(player, 'Zora Waterfall SE', 0x0f, So, Ld, 0x05) .coordInfo(0x0f80, 0x1020),
|
||||
create_owedge(player, 'Lost Woods Pass NW', 0x10, No, Ld, 0x03) .coordInfo(0x0058, 0x1800),
|
||||
create_owedge(player, 'Lost Woods Pass NE', 0x10, No, Ld, 0x04) .coordInfo(0x0178, 0x181e),
|
||||
@@ -132,7 +132,7 @@ def create_owedges(world, player):
|
||||
create_owedge(player, 'Links House ES', 0x2c, Ea, Ld, 0x17) .coordInfo(0x0b80, 0x08c0),
|
||||
create_owedge(player, 'Stone Bridge NC', 0x2d, No, Ld, 0x14) .coordInfo(0x0af0, 0x180e),
|
||||
create_owedge(player, 'Stone Bridge SC', 0x2d, So, Ld, 0x19) .coordInfo(0x0ae0, 0x100c),
|
||||
create_owedge(player, 'Stone Bridge WC', 0x2d, We, Wr, 0x17) .coordInfo(0x0b1c, 0x061c),
|
||||
create_owedge(player, 'Stone Bridge WC', 0x2d, We, Wr, 0x17) .coordInfo(0x0b1c, 0x061c).special_entrance(0x81),
|
||||
create_owedge(player, 'Stone Bridge WS', 0x2d, We, Ld, 0x18) .coordInfo(0x0b80, 0x08e0),
|
||||
create_owedge(player, 'Stone Bridge EN', 0x2d, Ea, Ld, 0x18) .coordInfo(0x0a90, 0x01c0),
|
||||
create_owedge(player, 'Stone Bridge EC', 0x2d, Ea, Wr, 0x19) .coordInfo(0x0b3c, 0x0640),
|
||||
@@ -317,9 +317,9 @@ def create_owedges(world, player):
|
||||
create_owedge(player, 'Bomber Corner NE', 0x7f, No, Ld, 0x41) .coordInfo(0x0f50, 0x181c),
|
||||
create_owedge(player, 'Bomber Corner WC', 0x7f, We, Wr, 0x49) .coordInfo(0x0f30, 0x05e0),
|
||||
create_owedge(player, 'Bomber Corner WS', 0x7f, We, Ld, 0x4a) .coordInfo(0x0f94, 0x0860),
|
||||
create_owedge(player, 'Master Sword Meadow SC', 0x80, So, Ld, 0x40) .coordInfo(0x0080, 0x0000),
|
||||
create_owedge(player, 'Hobo EC', 0x80, Ea, Wr, 0x4a) .coordInfo(0x008c, 0x0020),
|
||||
create_owedge(player, 'Zoras Domain SW', 0x81, So, Ld, 0x41, 0x89).coordInfo(0x02a4, 0x1782)
|
||||
create_owedge(player, 'Master Sword Meadow SC', 0x80, So, Ld, 0x40) .coordInfo(0x0080, 0x0000).special_exit(0x80),
|
||||
create_owedge(player, 'Hobo EC', 0x80, Ea, Wr, 0x4a) .coordInfo(0x008c, 0x0020).special_exit(0x81),
|
||||
create_owedge(player, 'Zoras Domain SW', 0x81, So, Ld, 0x41, 0x89).coordInfo(0x02a4, 0x1782).special_exit(0x82)
|
||||
]
|
||||
|
||||
world.owedges += edges
|
||||
@@ -439,16 +439,16 @@ OWEdgeGroups = {
|
||||
['Octoballoon NE']
|
||||
]
|
||||
),
|
||||
# (Op, LW, Vt, Ld, NP, 1): (
|
||||
# [
|
||||
# ['Master Sword Meadow SC'],
|
||||
# ['Zoras Domain SW']
|
||||
# ],
|
||||
# [
|
||||
# ['Lost Woods NW'],
|
||||
# ['Zora Waterfall NE']
|
||||
# ]
|
||||
# ),
|
||||
(Op, LW, Vt, Ld, NP, 1): (
|
||||
[
|
||||
['Master Sword Meadow SC'],
|
||||
['Zoras Domain SW']
|
||||
],
|
||||
[
|
||||
['Lost Woods NW'],
|
||||
['Zora Waterfall NE']
|
||||
]
|
||||
),
|
||||
(Op, LW, Hz, Ld, PL, 2): (
|
||||
[
|
||||
['Kakariko Fortune EN', 'Kakariko Fortune ES'],
|
||||
@@ -505,14 +505,14 @@ OWEdgeGroups = {
|
||||
['Statues WC']
|
||||
]
|
||||
),
|
||||
# (Op, LW, Hz, Wr, NP, 1): (
|
||||
# [
|
||||
# ['Hobo EC']
|
||||
# ],
|
||||
# [
|
||||
# ['Stone Bridge WC']
|
||||
# ]
|
||||
# ),
|
||||
(Op, LW, Hz, Wr, NP, 1): (
|
||||
[
|
||||
['Hobo EC']
|
||||
],
|
||||
[
|
||||
['Stone Bridge WC']
|
||||
]
|
||||
),
|
||||
(Op, LW, Vt, Wr, PL, 1): (
|
||||
[
|
||||
['Tree Line SC'],
|
||||
@@ -627,6 +627,10 @@ OWEdgeGroups = {
|
||||
['Hype Cave WN', 'Hype Cave WS']
|
||||
]
|
||||
),
|
||||
(Op, DW, Vt, Ld, NP, 1): (
|
||||
[ ],
|
||||
[ ]
|
||||
),
|
||||
(Op, DW, Hz, Ld, NP, 2): (
|
||||
[
|
||||
['Dig Game EC', 'Dig Game ES']
|
||||
@@ -675,6 +679,10 @@ OWEdgeGroups = {
|
||||
['Hype Cave WC']
|
||||
]
|
||||
),
|
||||
(Op, DW, Hz, Wr, NP, 1): (
|
||||
[ ],
|
||||
[ ]
|
||||
),
|
||||
(Op, DW, Vt, Wr, PL, 1): (
|
||||
[
|
||||
['Dark Tree Line SC'],
|
||||
@@ -1585,7 +1593,8 @@ OWExitTypes = {
|
||||
'Lake Hylia West Pier',
|
||||
'Lake Hylia Northeast Water Drop',
|
||||
'Lake Hylia East Pier',
|
||||
'Lake Hylia Water D Entry',
|
||||
'Lake Hylia Water D Approach',
|
||||
'Lake Hylia Water D Leave',
|
||||
'Desert Pass Ladder (South)',
|
||||
'Desert Pass Rocks (North)',
|
||||
'Desert Pass Rocks (South)',
|
||||
@@ -1854,6 +1863,7 @@ OWExitTypes = {
|
||||
'South Shore East Mirror Spot',
|
||||
'Lake Hylia Island Mirror Spot',
|
||||
'Lake Hylia Water Mirror Spot',
|
||||
'Lake Hylia Water D Mirror Spot',
|
||||
'Lake Hylia Central Island Mirror Spot',
|
||||
'Ice Cave Mirror Spot',
|
||||
'Desert Pass Ledge Mirror Spot',
|
||||
|
||||
@@ -5,7 +5,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl
|
||||
from Regions import mark_dark_world_regions, mark_light_world_regions
|
||||
from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel
|
||||
|
||||
version_number = '0.2.7.1'
|
||||
version_number = '0.2.7.2'
|
||||
version_branch = ''
|
||||
__version__ = '%s%s' % (version_number, version_branch)
|
||||
|
||||
@@ -13,8 +13,6 @@ def link_overworld(world, player):
|
||||
# setup mandatory connections
|
||||
for exitname, regionname in mandatory_connections:
|
||||
connect_simple(world, exitname, regionname, player)
|
||||
for exitname, destname in temporary_mandatory_connections:
|
||||
connect_two_way(world, exitname, destname, player)
|
||||
|
||||
def performSwap(groups, swaps):
|
||||
def getParallel(edgename):
|
||||
@@ -290,7 +288,7 @@ def link_overworld(world, player):
|
||||
trimmed_groups = remove_reserved(world, trimmed_groups, connected_edges, player)
|
||||
groups = reorganize_groups(world, trimmed_groups, player)
|
||||
|
||||
tries = 10
|
||||
tries = 20
|
||||
valid_layout = False
|
||||
connected_edge_cache = connected_edges.copy()
|
||||
while not valid_layout and tries > 0:
|
||||
@@ -541,18 +539,13 @@ def shuffle_tiles(world, groups, result_list, player):
|
||||
exist_dw_regions.extend(new_results[2])
|
||||
|
||||
# replace LW edges with DW
|
||||
ignore_list = list() #TODO: Remove ignore_list when special OW areas are included in pool
|
||||
for edgeset in temporary_mandatory_connections:
|
||||
for edge in edgeset:
|
||||
ignore_list.append(edge)
|
||||
|
||||
if world.owCrossed[player] != 'polar':
|
||||
# in polar, the actual edge connections remain vanilla
|
||||
def getSwappedEdges(world, lst, player):
|
||||
for regionname in lst:
|
||||
region = world.get_region(regionname, player)
|
||||
for exit in region.exits:
|
||||
if exit.spot_type == 'OWEdge' and exit.name not in ignore_list:
|
||||
if exit.spot_type == 'OWEdge':
|
||||
swapped_edges.append(exit.name)
|
||||
|
||||
getSwappedEdges(world, result_list[1], player)
|
||||
@@ -561,7 +554,17 @@ def shuffle_tiles(world, groups, result_list, player):
|
||||
return swapped_edges
|
||||
|
||||
def reorganize_tile_groups(world, player):
|
||||
def can_shuffle_group(name, groupType):
|
||||
def get_group_key(group):
|
||||
#(name, groupType, whirlpoolGroup) = group
|
||||
new_group = list(group)
|
||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted']:
|
||||
new_group[1] = None
|
||||
if not world.owWhirlpoolShuffle[player] and world.owCrossed[player] == 'none':
|
||||
new_group[2] = None
|
||||
return tuple(new_group)
|
||||
|
||||
def can_shuffle_group(group):
|
||||
(name, groupType, whirlpoolGroup) = group
|
||||
return name not in ['Castle', 'Links', 'Central Bonk Rocks'] \
|
||||
or (world.mode[player] != 'standard' and (name != 'Castle' \
|
||||
or world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] \
|
||||
@@ -570,60 +573,22 @@ def reorganize_tile_groups(world, player):
|
||||
or (world.mode[player] == 'standard' and world.shuffle[player] in ['lean', 'crossed', 'insanity'] and name == 'Castle' and groupType == 'Entrance')
|
||||
|
||||
groups = {}
|
||||
for (name, groupType, whirlpoolGroup) in OWTileGroups.keys():
|
||||
if can_shuffle_group(name, groupType):
|
||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted']:
|
||||
if world.owWhirlpoolShuffle[player] or world.owCrossed[player] != 'none':
|
||||
groups[(name, whirlpoolGroup)] = ([], [], [])
|
||||
else:
|
||||
groups[(name,)] = ([], [], [])
|
||||
else:
|
||||
if world.owWhirlpoolShuffle[player] or world.owCrossed[player] != 'none':
|
||||
groups[(name, groupType, whirlpoolGroup)] = ([], [], [])
|
||||
else:
|
||||
groups[(name, groupType)] = ([], [], [])
|
||||
for group in OWTileGroups.keys():
|
||||
if can_shuffle_group(group):
|
||||
groups[get_group_key(group)] = ([], [], [])
|
||||
|
||||
for group in OWTileGroups.keys():
|
||||
if can_shuffle_group(group):
|
||||
(lw_owids, dw_owids) = OWTileGroups[group]
|
||||
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[get_group_key(group)]
|
||||
exist_owids.extend(lw_owids)
|
||||
exist_owids.extend(dw_owids)
|
||||
for owid in lw_owids:
|
||||
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
||||
for owid in dw_owids:
|
||||
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
||||
groups[get_group_key(group)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
||||
|
||||
for (name, groupType, whirlpoolGroup) in OWTileGroups.keys():
|
||||
if can_shuffle_group(name, groupType):
|
||||
(lw_owids, dw_owids) = OWTileGroups[(name, groupType, whirlpoolGroup)]
|
||||
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted']:
|
||||
if world.owWhirlpoolShuffle[player] or world.owCrossed[player] != 'none':
|
||||
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name, whirlpoolGroup)]
|
||||
exist_owids.extend(lw_owids)
|
||||
exist_owids.extend(dw_owids)
|
||||
for owid in lw_owids:
|
||||
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
||||
for owid in dw_owids:
|
||||
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
||||
groups[(name, whirlpoolGroup)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
||||
else:
|
||||
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name,)]
|
||||
exist_owids.extend(lw_owids)
|
||||
exist_owids.extend(dw_owids)
|
||||
for owid in lw_owids:
|
||||
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
||||
for owid in dw_owids:
|
||||
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
||||
groups[(name,)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
||||
else:
|
||||
if world.owWhirlpoolShuffle[player] or world.owCrossed[player] != 'none':
|
||||
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name, groupType, whirlpoolGroup)]
|
||||
exist_owids.extend(lw_owids)
|
||||
exist_owids.extend(dw_owids)
|
||||
for owid in lw_owids:
|
||||
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
||||
for owid in dw_owids:
|
||||
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
||||
groups[(name, groupType, whirlpoolGroup)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
||||
else:
|
||||
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name, groupType)]
|
||||
exist_owids.extend(lw_owids)
|
||||
exist_owids.extend(dw_owids)
|
||||
for owid in lw_owids:
|
||||
exist_lw_regions.extend(OWTileRegions.inverse[owid])
|
||||
for owid in dw_owids:
|
||||
exist_dw_regions.extend(OWTileRegions.inverse[owid])
|
||||
groups[(name, groupType)] = (exist_owids, exist_lw_regions, exist_dw_regions)
|
||||
return groups
|
||||
|
||||
def remove_reserved(world, groupedlist, connected_edges, player):
|
||||
@@ -661,158 +626,37 @@ def remove_reserved(world, groupedlist, connected_edges, player):
|
||||
return new_grouping
|
||||
|
||||
def reorganize_groups(world, groups, player):
|
||||
def get_group_key(group):
|
||||
#(std, region, axis, terrain, parallel, count) = group
|
||||
new_group = list(group)
|
||||
if world.mode[player] != "standard":
|
||||
new_group[0] = None
|
||||
if world.owShuffle[player] != 'parallel':
|
||||
new_group[4] = None
|
||||
if not world.owKeepSimilar[player]:
|
||||
new_group[5] = None
|
||||
return tuple(new_group)
|
||||
|
||||
# predefined shuffle groups get reorganized here
|
||||
# this restructures the candidate pool based on the chosen settings
|
||||
if world.owShuffle[player] == 'full':
|
||||
if world.owKeepSimilar[player]:
|
||||
if world.mode[player] == 'standard':
|
||||
# tuple goes to (A,B,C,D,_,F)
|
||||
for grouping in (groups,):
|
||||
new_grouping = {}
|
||||
for grouping in (groups,):
|
||||
new_grouping = {}
|
||||
|
||||
for group in grouping.keys():
|
||||
(std, region, axis, terrain, _, count) = group
|
||||
new_grouping[(std, region, axis, terrain, count)] = ([], [])
|
||||
for group in grouping.keys():
|
||||
new_grouping[get_group_key(group)] = ([], [])
|
||||
|
||||
for group in grouping.keys():
|
||||
(std, region, axis, terrain, _, count) = group
|
||||
(forward_edges, back_edges) = grouping[group]
|
||||
(exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, count)]
|
||||
exist_forward_edges.extend(forward_edges)
|
||||
exist_back_edges.extend(back_edges)
|
||||
new_grouping[(std, region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges)
|
||||
for group in grouping.keys():
|
||||
new_group = get_group_key(group)
|
||||
(forward_edges, back_edges) = grouping[group]
|
||||
if not world.owKeepSimilar[player]:
|
||||
forward_edges = [[i] for l in forward_edges for i in l]
|
||||
back_edges = [[i] for l in back_edges for i in l]
|
||||
(exist_forward_edges, exist_back_edges) = new_grouping[new_group]
|
||||
exist_forward_edges.extend(forward_edges)
|
||||
exist_back_edges.extend(back_edges)
|
||||
new_grouping[new_group] = (exist_forward_edges, exist_back_edges)
|
||||
|
||||
return list(new_grouping.values())
|
||||
else:
|
||||
# tuple goes to (_,B,C,D,_,F)
|
||||
for grouping in (groups,):
|
||||
new_grouping = {}
|
||||
|
||||
for group in grouping.keys():
|
||||
(_, region, axis, terrain, _, count) = group
|
||||
new_grouping[(region, axis, terrain, count)] = ([], [])
|
||||
|
||||
for group in grouping.keys():
|
||||
(_, region, axis, terrain, _, count) = group
|
||||
(forward_edges, back_edges) = grouping[group]
|
||||
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, count)]
|
||||
exist_forward_edges.extend(forward_edges)
|
||||
exist_back_edges.extend(back_edges)
|
||||
new_grouping[(region, axis, terrain, count)] = (exist_forward_edges, exist_back_edges)
|
||||
|
||||
return list(new_grouping.values())
|
||||
else:
|
||||
if world.mode[player] == 'standard':
|
||||
# tuple goes to (A,B,C,D,_,_)
|
||||
for grouping in (groups,):
|
||||
new_grouping = {}
|
||||
|
||||
for group in grouping.keys():
|
||||
(std, region, axis, terrain, _, _) = group
|
||||
new_grouping[(std, region, axis, terrain)] = ([], [])
|
||||
|
||||
for group in grouping.keys():
|
||||
(std, region, axis, terrain, _, _) = group
|
||||
(forward_edges, back_edges) = grouping[group]
|
||||
forward_edges = [[i] for l in forward_edges for i in l]
|
||||
back_edges = [[i] for l in back_edges for i in l]
|
||||
|
||||
(exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain)]
|
||||
exist_forward_edges.extend(forward_edges)
|
||||
exist_back_edges.extend(back_edges)
|
||||
new_grouping[(std, region, axis, terrain)] = (exist_forward_edges, exist_back_edges)
|
||||
|
||||
return list(new_grouping.values())
|
||||
else:
|
||||
# tuple goes to (_,B,C,D,_,_)
|
||||
for grouping in (groups,):
|
||||
new_grouping = {}
|
||||
|
||||
for group in grouping.keys():
|
||||
(_, region, axis, terrain, _, _) = group
|
||||
new_grouping[(region, axis, terrain)] = ([], [])
|
||||
|
||||
for group in grouping.keys():
|
||||
(_, region, axis, terrain, _, _) = group
|
||||
(forward_edges, back_edges) = grouping[group]
|
||||
forward_edges = [[i] for l in forward_edges for i in l]
|
||||
back_edges = [[i] for l in back_edges for i in l]
|
||||
|
||||
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain)]
|
||||
exist_forward_edges.extend(forward_edges)
|
||||
exist_back_edges.extend(back_edges)
|
||||
new_grouping[(region, axis, terrain)] = (exist_forward_edges, exist_back_edges)
|
||||
|
||||
return list(new_grouping.values())
|
||||
elif world.owShuffle[player] == 'parallel':
|
||||
if world.owKeepSimilar[player]:
|
||||
if world.mode[player] == 'standard':
|
||||
# tuple stays (A,B,C,D,E,F)
|
||||
for grouping in (groups,):
|
||||
return list(grouping.values())
|
||||
else:
|
||||
# tuple goes to (_,B,C,D,E,F)
|
||||
for grouping in (groups,):
|
||||
new_grouping = {}
|
||||
|
||||
for group in grouping.keys():
|
||||
(_, region, axis, terrain, parallel, count) = group
|
||||
new_grouping[(region, axis, terrain, parallel, count)] = ([], [])
|
||||
|
||||
for group in grouping.keys():
|
||||
(_, region, axis, terrain, parallel, count) = group
|
||||
(forward_edges, back_edges) = grouping[group]
|
||||
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel, count)]
|
||||
exist_forward_edges.extend(forward_edges)
|
||||
exist_back_edges.extend(back_edges)
|
||||
new_grouping[(region, axis, terrain, parallel, count)] = (exist_forward_edges, exist_back_edges)
|
||||
|
||||
return list(new_grouping.values())
|
||||
else:
|
||||
if world.mode[player] == 'standard':
|
||||
# tuple goes to (A,B,C,D,E,_)
|
||||
for grouping in (groups,):
|
||||
new_grouping = {}
|
||||
|
||||
for group in grouping.keys():
|
||||
(std, region, axis, terrain, parallel, _) = group
|
||||
new_grouping[(std, region, axis, terrain, parallel)] = ([], [])
|
||||
|
||||
for group in grouping.keys():
|
||||
(std, region, axis, terrain, parallel, _) = group
|
||||
(forward_edges, back_edges) = grouping[group]
|
||||
forward_edges = [[i] for l in forward_edges for i in l]
|
||||
back_edges = [[i] for l in back_edges for i in l]
|
||||
|
||||
(exist_forward_edges, exist_back_edges) = new_grouping[(std, region, axis, terrain, parallel)]
|
||||
exist_forward_edges.extend(forward_edges)
|
||||
exist_back_edges.extend(back_edges)
|
||||
new_grouping[(std, region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges)
|
||||
|
||||
return list(new_grouping.values())
|
||||
else:
|
||||
# tuple goes to (_,B,C,D,E,_)
|
||||
for grouping in (groups,):
|
||||
new_grouping = {}
|
||||
|
||||
for group in grouping.keys():
|
||||
(_, region, axis, terrain, parallel, _) = group
|
||||
new_grouping[(region, axis, terrain, parallel)] = ([], [])
|
||||
|
||||
for group in grouping.keys():
|
||||
(_, region, axis, terrain, parallel, _) = group
|
||||
(forward_edges, back_edges) = grouping[group]
|
||||
forward_edges = [[i] for l in forward_edges for i in l]
|
||||
back_edges = [[i] for l in back_edges for i in l]
|
||||
|
||||
(exist_forward_edges, exist_back_edges) = new_grouping[(region, axis, terrain, parallel)]
|
||||
exist_forward_edges.extend(forward_edges)
|
||||
exist_back_edges.extend(back_edges)
|
||||
new_grouping[(region, axis, terrain, parallel)] = (exist_forward_edges, exist_back_edges)
|
||||
|
||||
return list(new_grouping.values())
|
||||
else:
|
||||
raise NotImplementedError('Shuffling not supported yet')
|
||||
return list(new_grouping.values())
|
||||
|
||||
def create_flute_exits(world, player):
|
||||
for region in (r for r in world.regions if r.player == player and r.terrain == Terrain.Land and r.name not in ['Zoras Domain', 'Master Sword Meadow', 'Hobo Bridge']):
|
||||
@@ -1095,12 +939,10 @@ def validate_layout(world, player):
|
||||
while unreachable_count != len(unreachable_regions):
|
||||
# find unreachable regions
|
||||
unreachable_regions = {}
|
||||
flat_sectors = [[r for l in s for r in l] for s in world.owsectors[player]]
|
||||
for sector in flat_sectors:
|
||||
for region_name in sector:
|
||||
if region_name not in explored_regions and region_name not in isolated_regions:
|
||||
region = base_world.get_region(region_name, player)
|
||||
unreachable_regions[region_name] = region
|
||||
for region_name in list(OWTileRegions.copy().keys()):
|
||||
if region_name not in explored_regions and region_name not in isolated_regions:
|
||||
region = base_world.get_region(region_name, player)
|
||||
unreachable_regions[region_name] = region
|
||||
|
||||
# loop thru unreachable regions to check if some can be excluded
|
||||
unreachable_count = len(unreachable_regions)
|
||||
@@ -1142,13 +984,6 @@ test_connections = [
|
||||
#('Links House NE', 'Lost Woods Pass SW')
|
||||
]
|
||||
|
||||
temporary_mandatory_connections = [
|
||||
# Special OW Areas
|
||||
('Lost Woods NW', 'Master Sword Meadow SC'),
|
||||
('Zora Waterfall NE', 'Zoras Domain SW'),
|
||||
('Stone Bridge WC', 'Hobo EC'),
|
||||
]
|
||||
|
||||
# these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions
|
||||
mandatory_connections = [# Intra-tile OW Connections
|
||||
('Lost Woods Bush (West)', 'Lost Woods East Area'), #pearl
|
||||
@@ -1245,7 +1080,8 @@ mandatory_connections = [# Intra-tile OW Connections
|
||||
('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'),
|
||||
('Lake Hylia West Pier', 'Lake Hylia Area'),
|
||||
('Lake Hylia East Pier', 'Lake Hylia Northeast Bank'),
|
||||
('Lake Hylia Water D Entry', 'Lake Hylia Water'), #flippers
|
||||
('Lake Hylia Water D Approach', 'Lake Hylia Water D'),
|
||||
('Lake Hylia Water D Leave', 'Lake Hylia Water'), #flippers
|
||||
('Desert Pass Ledge Drop', 'Desert Pass Area'),
|
||||
('Desert Pass Rocks (North)', 'Desert Pass Southeast'), #glove
|
||||
('Desert Pass Rocks (South)', 'Desert Pass Area'), #glove
|
||||
@@ -1704,6 +1540,7 @@ ow_connections = {
|
||||
('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'),
|
||||
('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'),
|
||||
('Lake Hylia Water Mirror Spot', 'Lake Hylia Water'),
|
||||
('Lake Hylia Water D Mirror Spot', 'Lake Hylia Water D'),
|
||||
('Lake Hylia Teleporter', 'Ice Palace Area')
|
||||
], [
|
||||
('Lake Hylia Island Pier', 'Lake Hylia Island'),
|
||||
@@ -1752,14 +1589,14 @@ parallelsimilar_connections = [('Maze Race ES', 'Kakariko Suburb WS'),
|
||||
]
|
||||
|
||||
# non shuffled overworld
|
||||
default_connections = [#('Lost Woods NW', 'Master Sword Meadow SC'),
|
||||
default_connections = [('Lost Woods NW', 'Master Sword Meadow SC'),
|
||||
('Lost Woods SW', 'Lost Woods Pass NW'),
|
||||
('Lost Woods SC', 'Lost Woods Pass NE'),
|
||||
('Lost Woods SE', 'Kakariko Fortune NE'),
|
||||
('Lost Woods EN', 'Lumberjack WN'),
|
||||
('Lumberjack SW', 'Mountain Entry NW'),
|
||||
('Mountain Entry SE', 'Kakariko Pond NE'),
|
||||
#('Zora Waterfall NE', 'Zoras Domain SW'),
|
||||
('Zora Waterfall NE', 'Zoras Domain SW'),
|
||||
('Lost Woods Pass SW', 'Kakariko NW'),
|
||||
('Lost Woods Pass SE', 'Kakariko NC'),
|
||||
('Kakariko Fortune SC', 'Kakariko NE'),
|
||||
@@ -1808,7 +1645,7 @@ default_connections = [#('Lost Woods NW', 'Master Sword Meadow SC'),
|
||||
('Stone Bridge SC', 'Lake Hylia NW'),
|
||||
('Stone Bridge EN', 'Tree Line WN'),
|
||||
('Stone Bridge EC', 'Tree Line WC'),
|
||||
#('Stone Bridge WC', 'Hobo EC'),
|
||||
('Stone Bridge WC', 'Hobo EC'),
|
||||
('Tree Line SC', 'Lake Hylia NC'),
|
||||
('Tree Line SE', 'Lake Hylia NE'),
|
||||
('Desert EC', 'Desert Pass WC'),
|
||||
|
||||
@@ -111,8 +111,8 @@ def create_regions(world, player):
|
||||
create_lw_region(player, 'Lake Hylia Northeast Bank', None, ['Lake Hylia Northeast Water Drop', 'Ice Lake Northeast Mirror Spot', 'Lake Hylia NE']),
|
||||
create_lw_region(player, 'Lake Hylia Central Island', None, ['Lake Hylia Central Water Drop', 'Capacity Upgrade', 'Ice Palace Mirror Spot', 'Lake Hylia Teleporter']),
|
||||
create_lw_region(player, 'Lake Hylia Island', ['Lake Hylia Island'], ['Lake Hylia Island Water Drop']),
|
||||
create_lw_region(player, 'Lake Hylia Water', None, ['Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia West Pier', 'Lake Hylia East Pier', 'Lake Hylia NC', 'Lake Hylia EC', 'Lake Hylia Whirlpool'], 'Light World', Terrain.Water),
|
||||
create_lw_region(player, 'Lake Hylia Water D', None, ['Lake Hylia Water D Entry', 'Ice Lake Moat Mirror Spot'], 'Light World', Terrain.Water),
|
||||
create_lw_region(player, 'Lake Hylia Water', None, ['Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia West Pier', 'Lake Hylia East Pier', 'Lake Hylia Water D Approach', 'Lake Hylia NC', 'Lake Hylia EC', 'Lake Hylia Whirlpool'], 'Light World', Terrain.Water),
|
||||
create_lw_region(player, 'Lake Hylia Water D', None, ['Lake Hylia Water D Leave', 'Ice Lake Moat Mirror Spot'], 'Light World', Terrain.Water),
|
||||
create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Shopping Mall Mirror Spot', 'Ice Cave SE', 'Ice Cave SW']),
|
||||
create_lw_region(player, 'Desert Pass Area', ['Middle Aged Man'], ['Desert Pass Ladder (South)', 'Middle Aged Man', 'Desert Fairy', '50 Rupee Cave', 'Swamp Nook Mirror Spot', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']),
|
||||
create_lw_region(player, 'Middle Aged Man', ['Purple Chest'], None),
|
||||
@@ -213,7 +213,7 @@ def create_regions(world, player):
|
||||
create_dw_region(player, 'Ice Lake Ledge (West)', None, ['Ice Lake Southwest Water Drop', 'South Shore Mirror Spot', 'Ice Lake WS']),
|
||||
create_dw_region(player, 'Ice Lake Ledge (East)', None, ['Ice Lake Southeast Water Drop', 'South Shore East Mirror Spot', 'Ice Lake ES']),
|
||||
create_dw_region(player, 'Ice Lake Water', None, ['Ice Lake Northeast Pier', 'Ice Lake Moat Bomb Jump', 'Lake Hylia Island Mirror Spot', 'Ice Lake NC', 'Ice Lake EC'], 'Dark World', Terrain.Water),
|
||||
create_dw_region(player, 'Ice Lake Moat', None, ['Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Hop', 'Lake Hylia Water Mirror Spot']),
|
||||
create_dw_region(player, 'Ice Lake Moat', None, ['Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Hop', 'Lake Hylia Water Mirror Spot', 'Lake Hylia Water D Mirror Spot']),
|
||||
create_dw_region(player, 'Ice Palace Area', None, ['Ice Palace', 'Ice Palace Teleporter', 'Lake Hylia Central Island Mirror Spot']),
|
||||
create_dw_region(player, 'Shopping Mall Area', None, ['Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'Ice Cave Mirror Spot', 'Shopping Mall SW', 'Shopping Mall SE']),
|
||||
create_dw_region(player, 'Swamp Nook Area', None, ['Desert Pass Ledge Mirror Spot', 'Desert Pass Mirror Spot', 'Swamp Nook EC', 'Swamp Nook ES']),
|
||||
|
||||
11
Rom.py
11
Rom.py
@@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx
|
||||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = '4a1dfc4fa793b8659a95d579f6a5a925'
|
||||
RANDOMIZERBASEHASH = '538bf256ff03bb7576991114395eeccc'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
@@ -698,9 +698,9 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
inverted_buffer[b] ^= 0x1
|
||||
|
||||
# set world flag
|
||||
world_flag = 0x00 if b >= 0x40 else 0x40
|
||||
world_flag = 0x00 if b >= 0x40 and b < 0x80 else 0x40
|
||||
rom.write_byte(0x153A00 + b, world_flag)
|
||||
if b % 0x40 in megatiles:
|
||||
if b & 0xBF in megatiles:
|
||||
rom.write_byte(0x153A00 + b + 1, world_flag)
|
||||
rom.write_byte(0x153A00 + b + 8, world_flag)
|
||||
rom.write_byte(0x153A00 + b + 9, world_flag)
|
||||
@@ -708,7 +708,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
for edge in world.owedges:
|
||||
if edge.dest is not None and isinstance(edge.dest, OWEdge) and edge.player == player:
|
||||
write_int16(rom, edge.getAddress() + 0x0a, edge.vramLoc)
|
||||
write_int16(rom, edge.getAddress() + 0x0e, edge.getTarget())
|
||||
if not edge.specialExit:
|
||||
rom.write_byte(0x1539e0 + (edge.specialID - 0x80) * 2 if edge.specialEntrance else edge.getAddress() + 0x0e, edge.getTarget())
|
||||
|
||||
write_int16(rom, 0x150002, owMode)
|
||||
write_int16(rom, 0x150004, owFlags)
|
||||
@@ -1287,7 +1288,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
||||
rom.write_bytes(0x50563, [0x3F, 0x14]) # disable below ganon chest
|
||||
rom.write_byte(0x50599, 0x00) # disable below ganon chest
|
||||
rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest
|
||||
rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] or world.goal[player] == 'trinity' else 0x00) # pre-open Pyramid Hole
|
||||
rom.write_byte(0x18008B, 0x01 if world.is_pyramid_open(player) else 0x00) # pre-open Pyramid Hole
|
||||
rom.write_byte(0x18008C, 0x01 if world.crystals_needed_for_gt[player] == 0 else 0x00) # GT pre-opened if crystal requirement is 0
|
||||
rom.write_byte(0x18008F, 0x01 if world.is_atgt_swapped(player) else 0x00) # AT/GT swapped
|
||||
rom.write_byte(0xF5D73, 0xF0) # bees are catchable
|
||||
|
||||
5
Rules.py
5
Rules.py
@@ -844,7 +844,7 @@ def default_rules(world, player):
|
||||
set_rule(world.get_entrance('Lake Hylia Northeast Water Drop', player), lambda state: state.has('Flippers', player))
|
||||
set_rule(world.get_entrance('Lake Hylia Central Water Drop', player), lambda state: state.has('Flippers', player))
|
||||
set_rule(world.get_entrance('Lake Hylia Island Water Drop', player), lambda state: state.has('Flippers', player))
|
||||
set_rule(world.get_entrance('Lake Hylia Water D Entry', player), lambda state: state.has('Flippers', player))
|
||||
set_rule(world.get_entrance('Lake Hylia Water D Leave', player), lambda state: state.has('Flippers', player))
|
||||
set_rule(world.get_entrance('Ice Cave SW', player), lambda state: state.has('Flippers', player))
|
||||
set_rule(world.get_entrance('Octoballoon Water Drop', player), lambda state: state.has('Flippers', player))
|
||||
set_rule(world.get_entrance('Octoballoon Waterfall Water Drop', player), lambda state: state.has('Flippers', player))
|
||||
@@ -1046,7 +1046,7 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Top of Pyramid', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||
set_rule(world.get_entrance('Top of Pyramid (Inner)', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||
else:
|
||||
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: world.open_pyramid[player] or world.goal[player] == 'trinity' or state.has('Beat Agahnim 2', player))
|
||||
set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: world.is_pyramid_open(player) or state.has('Beat Agahnim 2', player))
|
||||
set_rule(world.get_entrance('Pyramid Hole', player), lambda state: False)
|
||||
set_rule(world.get_entrance('Pyramid Entrance', player), lambda state: False)
|
||||
|
||||
@@ -1186,6 +1186,7 @@ def ow_rules(world, player):
|
||||
set_rule(world.get_entrance('Lake Hylia Island Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player))
|
||||
set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Lake Hylia Water Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Lake Hylia Water D Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('South Shore Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('South Shore East Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||
set_rule(world.get_entrance('Lake Hylia Teleporter', player), lambda state: state.can_lift_heavy_rocks(player))
|
||||
|
||||
40
Text.py
40
Text.py
@@ -94,44 +94,44 @@ Triforce_texts = [
|
||||
'This was meant to be a trapezoid',
|
||||
# these ones are from web randomizer
|
||||
"\n G G",
|
||||
"All your base\nare belong\nto us.",
|
||||
"You have ended\nthe domination\nof Dr. Wily",
|
||||
" All your base\n are belong\n to us.",
|
||||
" You have ended\n the domination\n of Dr. Wily",
|
||||
" Thanks for\n playing!!!",
|
||||
"\n You Win!",
|
||||
" Thank you!\n Your quest\n is over.",
|
||||
" A winner\n is you!",
|
||||
"\n WINNER!!",
|
||||
"\n I'm sorry\n\n but your\n princess is in\n another castle",
|
||||
"\n I'm sorry\n\nbut our princess is\n in another castle",
|
||||
"\n Success!",
|
||||
" Whelp…\n that just\n happened",
|
||||
" Oh hey…\n it's you",
|
||||
"\n Wheeeeee!!",
|
||||
" Time for\n another one?",
|
||||
"and\n\n scene",
|
||||
" And\n\n scene",
|
||||
"\n GOT EM!!",
|
||||
"\nTHE VALUUUE!!!",
|
||||
"Cool seed,\n\nright?",
|
||||
"\n THE VALUUUE!!!",
|
||||
" Cool seed,\n\n right?",
|
||||
"\n We did it!",
|
||||
" Spam those\n emotes in\n wilds chat",
|
||||
"\n O M G",
|
||||
" Hello. Will\n you be my\n friend?",
|
||||
" Hello. Will you\n you be my friend?",
|
||||
" Beetorp\n was\n here!",
|
||||
"The Wind Fish\nwill wake\nsoon. Hoot!",
|
||||
"Meow Meow Meow\nMeow Meow Meow\n Oh My God!",
|
||||
"Ahhhhhhhhh\nYa ya yaaaah\nYa ya yaaah",
|
||||
".done\n\n.comment lol",
|
||||
"You get to\ndrink from\nthe firehose",
|
||||
"Do you prefer\n bacon, pork,\n or ham?",
|
||||
"You get one\nwish. Choose\nwisely, hero!",
|
||||
"Can you please\nbreak us three\nup? Thanks.",
|
||||
" The Wind Fish\n will wake soon.\n Hoot!",
|
||||
" Meow Meow Meow\n Meow Meow Meow\n Oh My God!",
|
||||
" Ahhhhhhhhh\n Ya ya yaaaah\n Ya ya yaaah",
|
||||
" .done\n\n .comment lol",
|
||||
" You get to\n drink from\n the firehose",
|
||||
" Do you prefer\n bacon, pork,\n or ham?",
|
||||
" You get one\n wish. Choose\n wisely, hero!",
|
||||
" Can you please\n break us three\n up? Thanks.",
|
||||
" Pick us up\n before we\n get dizzy!",
|
||||
"Thank you,\nMikey. You’re\n2 minutes late",
|
||||
"This was a\n7000 series\ntrain.",
|
||||
" Thank you,\n Mikey. You’re\n 2 minutes late",
|
||||
" This was a\n 7000 series\n train.",
|
||||
" I'd buy\n that for\n a rupee!",
|
||||
" Did you like\n that bow\n placement?",
|
||||
"I promise the\nnext seed will\nbe better.",
|
||||
"\n Honk.",
|
||||
"Breakfast\nis served!",
|
||||
" I promise the\n next seed will\n be better.",
|
||||
"\n Honk.",
|
||||
" Breakfast\n is served!",
|
||||
]
|
||||
BombShop2_texts = ['Bombs!\nBombs!\nBiggest!\nBestest!\nGreatest!\nBoomest!']
|
||||
Sahasrahla2_texts = ['You already got my item, idiot.', 'Why are you still talking to me?', 'This text won\'t change.', 'Have you met my brother, Hasarahshla?']
|
||||
|
||||
242
asm/owrando.asm
242
asm/owrando.asm
@@ -9,10 +9,35 @@ OWReserved:
|
||||
dw 0
|
||||
|
||||
;Hooks
|
||||
org $02a929
|
||||
OWDetectTransitionReturn:
|
||||
|
||||
org $02a939
|
||||
OverworldHandleTransitions_SpecialTrigger:
|
||||
JSL OWDetectEdgeTransition
|
||||
BCS OWDetectTransitionReturn
|
||||
|
||||
org $02a999
|
||||
jsl OWEdgeTransition : nop #4 ;LDA $02A4E3,X : ORA $7EF3CA
|
||||
;org $02e238 ;LDX #$9E : - DEX : DEX : CMP $DAEE,X : BNE -
|
||||
;jsl OWSpecialTransition : nop #5
|
||||
|
||||
org $04e8ae
|
||||
JSL OWDetectSpecialTransition
|
||||
RTL : NOP
|
||||
|
||||
org $02e809
|
||||
JSL OWSpecialExit
|
||||
|
||||
org $02bfe8
|
||||
JSL OWAdjustExitPosition
|
||||
|
||||
org $02c1a9
|
||||
JSL OWEndScrollTransition
|
||||
|
||||
org $04E881
|
||||
Overworld_LoadSpecialOverworld_RoomId:
|
||||
org $04E8B4
|
||||
Overworld_LoadSpecialOverworld:
|
||||
|
||||
|
||||
org $05af75
|
||||
jsl OWPreserveMirrorSprite : nop #2 ; LDA $7EF3CA : BNE $05AFDF
|
||||
@@ -107,10 +132,14 @@ org $1bed95 ; < ? - palettes.asm:748 ()
|
||||
jsl.l OWWorldCheck16 : nop
|
||||
|
||||
org $02b16e ; AND #$3F : ORA 7EF3CA
|
||||
and #$7f : eor #$40 : nop #2 ; something to do with mirroring and simply toggling world to opposite one: TODO: better comment
|
||||
and #$7f : eor #$40 : nop #2
|
||||
|
||||
;Code
|
||||
org $aa8800
|
||||
OWTransitionDirection:
|
||||
dw 3, 2, 1, 0 ; $02 after $02A932
|
||||
OWEdgeDataOffset:
|
||||
dw OWSouthEdges, OWEastEdges, OWSouthEdges
|
||||
OWCoordIndex: ; Horizontal 1st
|
||||
db 2, 2, 0, 0 ; Coordinate Index $20-$23
|
||||
OWOppCoordIndex: ; Horizontal 1st
|
||||
@@ -304,47 +333,99 @@ LoadMapDarkOrMixed:
|
||||
dw $0C00-$01F0 ; top right
|
||||
dw 0,0,0,0,0,0
|
||||
dw $0800+$01F0 ; bottom left
|
||||
dw $0400+$0210 ; bottom
|
||||
dw $0400+$0210 ; bottom right
|
||||
}
|
||||
|
||||
org $aa9000
|
||||
OWDetectEdgeTransition:
|
||||
{
|
||||
STZ.w $06FC
|
||||
LDA.l OWMode : ORA.l OWMode+1 : BEQ .normal
|
||||
JSR OWShuffle
|
||||
LDA.w $06FA : BMI .special
|
||||
.normal
|
||||
REP #$31 : LDX.b $02 : LDA.b $84 ; what we wrote over
|
||||
RTL
|
||||
.special
|
||||
REP #$30
|
||||
AND.w #$0003 : TAY : ASL : TAX
|
||||
LDA.w #$007F : STA.w $06FA
|
||||
JSR OWLoadSpecialArea
|
||||
SEC
|
||||
RTL
|
||||
}
|
||||
OWDetectSpecialTransition:
|
||||
{
|
||||
STZ.w $06FC
|
||||
LDA.l OWMode : BEQ .normal
|
||||
LDA.l OWSpecialDestIndex,X : BIT.w #$0080 : BNE .special
|
||||
STA.w $06FA
|
||||
LDA.l OWEdgeDataOffset,X : STA.w $06F8
|
||||
PLA : SEP #$30 : PLA ; delete 3 bytes from stack
|
||||
JSL Link_CheckForEdgeScreenTransition : BCS .return ; Link_CheckForEdgeScreenTransition
|
||||
LDA.l $04E879,X : STA.b $00 : CMP.b #$08 : BNE .hobo
|
||||
LSR : STA.b $20 : STZ.b $E8 ; move Link and camera to edge
|
||||
LDA.b #$06 : STA.b $02
|
||||
STZ.w $0418
|
||||
BRA .continue
|
||||
.hobo
|
||||
STA.b $02 : STA.w $0418
|
||||
ASL : STA.b $22 : STZ.b $E2 ; move Link and camera to edge
|
||||
LDA.b #$0A : STA.b $23 : STA.b $E3
|
||||
.continue
|
||||
STZ.b $03
|
||||
; copied from DeleteCertainAncillaeStopDashing at $028A0E
|
||||
JSL Ancilla_TerminateSelectInteractives
|
||||
LDA.w $0372 : BEQ .not_dashing
|
||||
STZ.b $4D : STZ.b $46
|
||||
LDA.b #$FF : STA.b $29 : STA.b $C7
|
||||
STZ.b $3D : STZ.b $5E : STZ.w $032B : STZ.w $0372 : STZ.b $5D
|
||||
.not_dashing
|
||||
PLA : REP #$31 : PLA ; delete 3 bytes from stack
|
||||
LDX.b $02
|
||||
LDA.b $84
|
||||
JML OverworldHandleTransitions_SpecialTrigger+6
|
||||
.special
|
||||
AND.w #$0003 : TAY : ASL : TAX
|
||||
.normal
|
||||
JSR OWLoadSpecialArea
|
||||
.return
|
||||
RTL
|
||||
}
|
||||
OWEdgeTransition:
|
||||
{
|
||||
php : phy
|
||||
lda.l OWMode : ora.l OWMode+1 : beq +
|
||||
jsl OWShuffle : bra .return
|
||||
+ jsl OWVanilla
|
||||
.return
|
||||
ply : plp : rtl
|
||||
LDA.l OWMode : ORA.l OWMode+1 : BEQ .normal
|
||||
LDY.w $06FA : CPY.b #$7F
|
||||
BEQ .normal
|
||||
REP #$10
|
||||
LDX.w $06F8
|
||||
PHB : PHK : PLB
|
||||
JSR OWNewDestination
|
||||
PLB
|
||||
SEP #$30
|
||||
RTL
|
||||
.normal
|
||||
LDA.l $02A4E3,X : ORA.l $7EF3CA ; what we wrote over
|
||||
RTL
|
||||
}
|
||||
OWVanilla:
|
||||
OWSpecialExit:
|
||||
{
|
||||
lda $02a4e3,X : ora $7ef3ca : rtl
|
||||
LDA.l OWMode+1 : AND.b #!FLAG_OW_CROSSED : BEQ .return
|
||||
JSR OWWorldUpdate
|
||||
.return
|
||||
LDA.l $7EFD40,X ; what we wrote over
|
||||
RTL
|
||||
}
|
||||
OWShuffle:
|
||||
{
|
||||
;Assume you're at links house = $2c
|
||||
;transitioning right will result in X = $2d
|
||||
;transitioning left will result in X = $2b
|
||||
;up X = $24
|
||||
;down X = $34
|
||||
|
||||
;compares X to determine direction of edge transition
|
||||
phx : lsr $700 : cpx $700 : !blt .upOrLeft
|
||||
dex : cpx $700 : bne .downEdge
|
||||
lda #$3 : sta $418 : bra .setOWID ;right
|
||||
.downEdge
|
||||
lda #$1 : sta $418 : bra .setOWID ;down
|
||||
.upOrLeft
|
||||
inx : cpx $700 : bne .upEdge
|
||||
lda #$2 : sta $418 : bra .setOWID ;left
|
||||
.upEdge
|
||||
lda #$0 : sta $418 ;up
|
||||
;determine direction of edge transition
|
||||
phx : lsr.w $0700
|
||||
tyx : lda.l OWTransitionDirection,X : sta.w $0418
|
||||
|
||||
.setOWID
|
||||
;look up transitions in current area in table OWEdgeOffsets
|
||||
;offset is (8bytes * OW Slot ID) + (2bytes * direction)
|
||||
asl : rep #$20 : pha : sep #$20 ;2 bytes per direction
|
||||
asl : rep #$20 : and.w #$00ff : pha : sep #$20 ;2 bytes per direction
|
||||
lda $8a : and #$40 : !add $700 : rep #$30 : and #$00ff : asl #3
|
||||
adc 1,S : tax
|
||||
asl $700 : pla
|
||||
@@ -368,25 +449,25 @@ OWShuffle:
|
||||
pla : dec : bne .nextTransition : bra .noTransition
|
||||
|
||||
.newDestination
|
||||
pla : sep #$30 : plx : lda $8a : bra .return
|
||||
pla : sep #$30 : plx : rts
|
||||
|
||||
.noTransition
|
||||
sep #$30 : plx : jsl OWVanilla
|
||||
sep #$30 : plx
|
||||
lda.b #$7f : sta.w $06fa
|
||||
|
||||
.return
|
||||
rtl
|
||||
rts
|
||||
}
|
||||
OWSearchTransition:
|
||||
{
|
||||
;A-16 XY-16
|
||||
lda $418 : bne + ;north
|
||||
lda.l OWNorthEdges,x : dec
|
||||
cmp $22 : !bge .nomatch
|
||||
lda.l OWNorthEdges+2,x : cmp $22 : !blt .nomatch
|
||||
cmp $22 : !bge .exitloop
|
||||
lda.l OWNorthEdges+2,x : cmp $22 : !blt .exitloop
|
||||
;MATCH
|
||||
lda.l OWNorthEdges+14,x : tay ;y = record id of dest
|
||||
sep #$20 : lda #OWSouthEdges>>16 : phb : pha : plb
|
||||
ldx #OWSouthEdges : jsr OWNewDestination : plb ;x = address of table
|
||||
ldx.w #OWSouthEdges ;x = address of table
|
||||
bra .matchfound
|
||||
+ dec : bne + ;south
|
||||
lda.l OWSouthEdges,x : dec
|
||||
@@ -394,29 +475,25 @@ OWSearchTransition:
|
||||
lda.l OWSouthEdges+2,x : cmp $22 : !blt .exitloop
|
||||
;MATCH
|
||||
lda.l OWSouthEdges+14,x : tay ;y = record id of dest
|
||||
sep #$20 : lda #OWNorthEdges>>16 : phb : pha : plb : phx
|
||||
ldx #OWNorthEdges : jsr OWNewDestination : plx : plb ;x = address of table
|
||||
ldx.w #OWNorthEdges ;x = address of table
|
||||
bra .matchfound
|
||||
.nomatch
|
||||
bra .exitloop
|
||||
+ dec : bne + ; west
|
||||
lda.l OWWestEdges,x : dec
|
||||
cmp $20 : !bge .exitloop
|
||||
lda.l OWWestEdges+2,x : cmp $20 : !blt .exitloop
|
||||
;MATCH
|
||||
lda.l OWWestEdges+14,x : tay ;y = record id of dest
|
||||
sep #$20 : lda #OWEastEdges>>16 : phb : pha : plb
|
||||
ldx #OWEastEdges : jsr OWNewDestination : plb ;x = address of table
|
||||
ldx.w #OWEastEdges ;x = address of table
|
||||
bra .matchfound
|
||||
+ lda.l OWEastEdges,x : dec ;east
|
||||
cmp $20 : !bge .exitloop
|
||||
lda.l OWEastEdges+2,x : cmp $20 : !blt .exitloop
|
||||
;MATCH
|
||||
lda.l OWEastEdges+14,x : tay ;y = record id of dest
|
||||
sep #$20 : lda #OWWestEdges>>16 : phb : pha : plb
|
||||
ldx #OWWestEdges : jsr OWNewDestination : plb ;x = address of table
|
||||
ldx.w #OWWestEdges ;x = address of table
|
||||
|
||||
.matchfound
|
||||
stx $06f8 : sty $06fa : sec : rts
|
||||
plx : pla : pea $0001 : phx
|
||||
sec : rts
|
||||
|
||||
@@ -449,10 +526,11 @@ OWNewDestination:
|
||||
++ lda $84 : !add 1,s : sta $84 : pla : pla
|
||||
|
||||
.adjustMainAxis
|
||||
;LDA $84 : SEC : SBC #$0400 : AND #$0F80 : ASL : XBA : STA $88 ; vram
|
||||
LDA $84 : SEC : SBC #$0400 : AND #$0F00 : ASL : XBA : STA $88
|
||||
LDA $84 : SEC : SBC #$0400 : AND #$0F00 : ASL : XBA : STA $88 ; vram
|
||||
LDA $84 : SEC : SBC #$0010 : AND #$003E : LSR : STA $86
|
||||
|
||||
LDA.w $000F,X : AND.w #$00FF : STA.w $06FC ; position to walk to after transition (if non-zero)
|
||||
|
||||
pla : pla : sep #$10 : ldy $418
|
||||
ldx OWCoordIndex,y : lda $20,x : and #$fe00 : pha
|
||||
lda $20,x : and #$01ff : pha ;s1 = relative cur, s3 = ow cur
|
||||
@@ -496,7 +574,7 @@ OWNewDestination:
|
||||
ldx OWOppBGIndex,y : lda $e0,x : !add 1,s : sta $e0,x
|
||||
lda $418 : asl : tax : lda $610,x : !add 1,s : sta $610,x : pla
|
||||
|
||||
sep #$30 : lda OWOppSlotOffset,y : !add $04 : asl : and #$7f : sta $700
|
||||
sep #$30 : lda $04 : and #$3f : !add OWOppSlotOffset,y : asl : sta $700
|
||||
|
||||
; crossed OW shuffle
|
||||
lda.l OWMode+1 : and.b #!FLAG_OW_CROSSED : beq .return
|
||||
@@ -504,13 +582,18 @@ OWNewDestination:
|
||||
|
||||
.return
|
||||
lda $05 : sta $8a
|
||||
;bra +
|
||||
; nop #8
|
||||
; jsl $02EA41
|
||||
; nop #8
|
||||
;+
|
||||
rep #$30 : rts
|
||||
}
|
||||
OWLoadSpecialArea:
|
||||
{
|
||||
LDA.l Overworld_LoadSpecialOverworld_RoomId,X : STA.b $A0
|
||||
JSL Overworld_LoadSpecialOverworld
|
||||
LDA.l OWMode+1 : AND.b #!FLAG_OW_CROSSED : BEQ .return
|
||||
TYX : LDA.l OWSpecialDestSlot,X : TAX
|
||||
JSR OWWorldUpdate
|
||||
.return
|
||||
RTS
|
||||
}
|
||||
OWWorldUpdate: ; x = owid of destination screen
|
||||
{
|
||||
lda.l OWTileWorldAssoc,x : cmp.l $7ef3ca : beq .return
|
||||
@@ -545,10 +628,29 @@ OWWorldUpdate: ; x = owid of destination screen
|
||||
.return
|
||||
rts
|
||||
}
|
||||
OWSpecialTransition:
|
||||
OWAdjustExitPosition:
|
||||
{
|
||||
LDX #$9E
|
||||
- DEX : DEX : CMP $DAEE,X : BNE -
|
||||
LDA.w $06FC : CMP.b #$60 : BEQ .stone_bridge
|
||||
CMP.b #$B0 : BNE .normal
|
||||
LDA.b #$80 : STA.b $20 : STZ.b $21
|
||||
BRA .normal
|
||||
.stone_bridge
|
||||
LDA.b #$A0 : STA.b $E2
|
||||
LDA.b #$3D : STA.w $061C
|
||||
LDA.b #$3B : STA.w $061E
|
||||
INC.b $23 : INC.w $061D : INC.w $061F
|
||||
.normal
|
||||
INC.b $11 : STZ.b $B0 ; what we wrote over
|
||||
RTL
|
||||
}
|
||||
OWEndScrollTransition:
|
||||
{
|
||||
LDY.w $06FC : BEQ .normal
|
||||
CMP.w $06FC
|
||||
RTL
|
||||
.normal
|
||||
CMP.l $02C176,X ; what we wrote over
|
||||
RTL
|
||||
}
|
||||
|
||||
;Data
|
||||
@@ -556,7 +658,7 @@ org $aaa000
|
||||
OWEdgeOffsets:
|
||||
;2 bytes per each direction per each OW Slot, order is NSWE per value at $0418
|
||||
;AABB, A = offset to the transition table, B = number of transitions
|
||||
dw $0001, $0000, $0000, $0000 ;OW Slot 00, OWID 0x00 Lost Woods
|
||||
dw $0000, $0000, $0000, $0000 ;OW Slot 00, OWID 0x00 Lost Woods
|
||||
dw $0000, $0000, $0000, $0001 ;OW Slot 01, OWID 0x00
|
||||
dw $0000, $0001, $0001, $0000 ;OW Slot 02, OWID 0x02 Lumberjack
|
||||
dw $0000, $0000, $0000, $0000
|
||||
@@ -572,7 +674,7 @@ dw $0000, $0000, $0000, $0000
|
||||
dw $0000, $0000, $0000, $0301
|
||||
dw $0000, $0000, $0301, $0000
|
||||
dw $0000, $0000, $0000, $0000
|
||||
dw $0201, $0501, $0000, $0000 ;Zora
|
||||
dw $0000, $0501, $0000, $0000 ;Zora
|
||||
|
||||
dw $0302, $0602, $0000, $0000
|
||||
dw $0501, $0801, $0000, $0402
|
||||
@@ -606,7 +708,7 @@ dw $1101, $0000, $1201, $1301
|
||||
dw $0000, $1502, $1301, $0000
|
||||
dw $1201, $1701, $0000, $1403
|
||||
dw $1301, $1801, $1403, $1701 ;Links
|
||||
dw $1401, $1901, $1702, $1802 ;Hobo
|
||||
dw $1401, $1901, $1801, $1802 ;Hobo
|
||||
dw $1501, $1a02, $1902, $0000
|
||||
dw $1601, $0000, $0000, $0000
|
||||
|
||||
@@ -704,12 +806,15 @@ dw $0000, $4001, $0000, $0000
|
||||
dw $0000, $0000, $0000, $4a01
|
||||
dw $0000, $4101, $0000, $0000
|
||||
|
||||
OWSpecialDestSlot:
|
||||
db $80, $80, $81
|
||||
|
||||
org $aaa800 ;PC 152800
|
||||
OWNorthEdges:
|
||||
; Min Max Width Mid OW Slot/OWID VRAM *FREE* Dest Index
|
||||
dw $00a0, $00a0, $0000, $00a0, $0000, $0000, $0000, $0040 ;Lost Woods
|
||||
dw $00a0, $00a0, $0000, $00a0, $0000, $0000, $0000, $B040 ;Lost Woods (exit only)
|
||||
dw $0458, $0540, $00e8, $04cc, $0a0a, $0000, $0000, $0000
|
||||
dw $0f38, $0f60, $0028, $0f4c, $0f0f, $0000, $0000, $0041
|
||||
dw $0f38, $0f60, $0028, $0f4c, $0f0f, $0000, $0000, $2041 ;Waterfall (exit only)
|
||||
dw $0058, $0058, $0000, $0058, $1010, $0000, $0000, $0001
|
||||
dw $0178, $0178, $0000, $0178, $1010, $0000, $0000, $0002
|
||||
dw $0388, $0388, $0000, $0388, $1111, $0000, $0000, $0003
|
||||
@@ -838,8 +943,8 @@ dw $06a0, $07b0, $0110, $0728, $7373, $0000, $0000, $003e
|
||||
dw $0830, $09b0, $0180, $08f0, $7474, $0000, $0000, $003f
|
||||
dw $0e78, $0e88, $0010, $0e80, $7777, $0000, $0000, $0040
|
||||
dw $0ee0, $0fc0, $00e0, $0f50, $7777, $0000, $0000, $0041
|
||||
dw $0080, $0080, $0000, $0080, $8080, $0000, $0000, $0000 ;Pedestal
|
||||
dw $0288, $02c0, $0038, $02a4, $8189, $0000, $0000, $0002 ;Zora
|
||||
dw $0080, $0080, $0000, $0080, $8080, $0000, $0000, $0000 ;Pedestal (unused)
|
||||
dw $0288, $02c0, $0038, $02a4, $8189, $0000, $0000, $0002 ;Zora (unused)
|
||||
OWWestEdges:
|
||||
dw $0070, $00a0, $0030, $0088, $0202, $0000, $0000, $0000
|
||||
dw $0068, $0078, $0010, $0070, $0505, $0000, $0000, $0001
|
||||
@@ -864,7 +969,7 @@ dw $0b60, $0ba0, $0040, $0b80, $2a2a, $0000, $0000, $0013
|
||||
dw $0ab0, $0ad0, $0020, $0ac0, $2c2c, $0000, $0000, $0014
|
||||
dw $0af0, $0b40, $0050, $0b18, $2c2c, $0000, $0000, $0015
|
||||
dw $0b78, $0ba0, $0028, $0b8c, $2c2c, $0000, $0000, $0016
|
||||
dw $0b10, $0b28, $0018, $0b1c, $2d2d, $0000, $0000, $004a
|
||||
dw $0b10, $0b28, $0018, $0b1c, $2d2d, $0000, $0000, $604a ;Stone Bridge (exit only)
|
||||
dw $0b68, $0b98, $0030, $0b80, $2d2d, $0000, $0000, $0017
|
||||
dw $0a68, $0ab8, $0050, $0a90, $2e2e, $0000, $0000, $0018
|
||||
dw $0b00, $0b78, $0078, $0b3c, $2e2e, $0000, $0000, $0019
|
||||
@@ -991,7 +1096,11 @@ dw $0e28, $0fb8, $0190, $0ef0, $7b7b, $0000, $0000, $0047
|
||||
dw $0f78, $0fb8, $0040, $0f98, $7c7c, $0000, $0000, $0048
|
||||
dw $0f20, $0f40, $0020, $0f30, $757e, $0000, $0000, $0049
|
||||
dw $0f70, $0fb8, $0048, $0f94, $757e, $0000, $0000, $004a
|
||||
dw $0058, $00c0, $0068, $008c, $8080, $0000, $0000, $0017 ;Hobo
|
||||
dw $0058, $00c0, $0068, $008c, $8080, $0000, $0000, $0017 ;Hobo (unused)
|
||||
|
||||
org $aab9e0 ;PC 1539e0
|
||||
OWSpecialDestIndex:
|
||||
dw $0080, $0081, $0082
|
||||
|
||||
org $aaba00 ;PC 153a00
|
||||
OWTileWorldAssoc:
|
||||
@@ -1011,6 +1120,7 @@ db $40, $40, $40, $40, $40, $40, $40, $40
|
||||
db $40, $40, $40, $40, $40, $40, $40, $40
|
||||
db $40, $40, $40, $40, $40, $40, $40, $40
|
||||
db $40, $40, $40, $40, $40, $40, $40, $40
|
||||
db $00, $00
|
||||
|
||||
org $aabb00 ;PC 153b00
|
||||
OWTileMapAlt:
|
||||
@@ -1031,3 +1141,5 @@ db 0, 0, 0, 0, 0, 0, 0, 0
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
db 0, 0
|
||||
|
||||
Binary file not shown.
@@ -53,6 +53,10 @@
|
||||
lean: 2
|
||||
crossed: 3
|
||||
insanity: 1
|
||||
open_pyramid:
|
||||
auto: 1
|
||||
yes: 0
|
||||
no: 0
|
||||
shufflelinks:
|
||||
on: 1
|
||||
off: 1
|
||||
|
||||
@@ -218,8 +218,11 @@
|
||||
]
|
||||
},
|
||||
"openpyramid": {
|
||||
"action": "store_true",
|
||||
"type": "bool"
|
||||
"choices": [
|
||||
"auto",
|
||||
"yes",
|
||||
"no"
|
||||
]
|
||||
},
|
||||
"rom": {},
|
||||
"loglevel": {
|
||||
|
||||
@@ -138,6 +138,9 @@
|
||||
|
||||
|
||||
"randomizer.entrance.openpyramid": "Pre-open Pyramid Hole",
|
||||
"randomizer.entrance.openpyramid.auto": "Auto",
|
||||
"randomizer.entrance.openpyramid.yes": "Yes",
|
||||
"randomizer.entrance.openpyramid.no": "No",
|
||||
"randomizer.entrance.shuffleganon": "Include Ganon's Tower and Pyramid Hole in shuffle pool",
|
||||
"randomizer.entrance.shufflelinks": "Include Link's House in the shuffle pool",
|
||||
"randomizer.entrance.overworld_map": "Overworld Map",
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
{
|
||||
"widgets": {
|
||||
"openpyramid": { "type": "checkbox" },
|
||||
"openpyramid": {
|
||||
"type": "selectbox",
|
||||
"options": [
|
||||
"auto",
|
||||
"yes",
|
||||
"no"
|
||||
],
|
||||
"config": {
|
||||
"width": 10
|
||||
}
|
||||
},
|
||||
"shuffleganon": { "type": "checkbox" },
|
||||
"shufflelinks": { "type": "checkbox" },
|
||||
"overworld_map": {
|
||||
|
||||
@@ -27,7 +27,7 @@ def entrando_page(parent):
|
||||
for key in dictWidgets:
|
||||
self.widgets[key] = dictWidgets[key]
|
||||
packAttrs = {"anchor":E}
|
||||
if self.widgets[key].type == "checkbox":
|
||||
if self.widgets[key].type == "checkbox" or key == "openpyramid":
|
||||
packAttrs["anchor"] = W
|
||||
self.widgets[key].pack(packAttrs)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user