Shuffle in-room stairs

This commit is contained in:
Catobat
2021-01-30 00:35:41 +01:00
parent c411f5543c
commit 43b0f95877
21 changed files with 368 additions and 64 deletions

View File

@@ -1071,7 +1071,7 @@ hook_dir_map = {
def hook_from_door(door): def hook_from_door(door):
if door.type == DoorType.SpiralStairs: if door.type == DoorType.SpiralStairs:
return Hook.Stairs return Hook.Stairs
if door.type in [DoorType.Normal, DoorType.Open, DoorType.StraightStairs]: if door.type in [DoorType.Normal, DoorType.Open, DoorType.StraightStairs, DoorType.Ladder]:
return hook_dir_map[door.direction] return hook_dir_map[door.direction]
return None return None
@@ -1189,7 +1189,8 @@ class Door(object):
# rom properties # rom properties
self.roomIndex = -1 self.roomIndex = -1
# 0,1,2 + Direction (N:0, W:3, S:6, E:9) for normal # 0,1,2 for normal
# 0-7 for ladder
# 0-4 for spiral offset thing # 0-4 for spiral offset thing
self.doorIndex = -1 self.doorIndex = -1
self.layer = -1 # 0 for normal floor, 1 for the inset layer self.layer = -1 # 0 for normal floor, 1 for the inset layer
@@ -1240,6 +1241,8 @@ class Door(object):
return 0x13A000 + normal_offset_table[self.roomIndex] * 24 + (self.doorIndex + self.direction.value * 3) * 2 return 0x13A000 + normal_offset_table[self.roomIndex] * 24 + (self.doorIndex + self.direction.value * 3) * 2
elif self.type == DoorType.SpiralStairs: elif self.type == DoorType.SpiralStairs:
return 0x13B000 + (spiral_offset_table[self.roomIndex] + self.doorIndex) * 4 return 0x13B000 + (spiral_offset_table[self.roomIndex] + self.doorIndex) * 4
elif self.type == DoorType.Ladder:
return 0x13C700 + self.doorIndex * 2
elif self.type == DoorType.Open: elif self.type == DoorType.Open:
base_address = { base_address = {
Direction.North: 0x13C500, Direction.North: 0x13C500,
@@ -1256,6 +1259,12 @@ class Door(object):
if src.type == DoorType.StraightStairs: if src.type == DoorType.StraightStairs:
bitmask += 0x40 bitmask += 0x40
return [self.roomIndex, bitmask + self.doorIndex] return [self.roomIndex, bitmask + self.doorIndex]
if self.type == DoorType.Ladder:
bitmask = 4 * (self.layer ^ 1 if src.toggle else self.layer)
bitmask += 0x08 * self.doorIndex
if src.type == DoorType.StraightStairs:
bitmask += 0x40
return [self.roomIndex, bitmask + 0x03]
if self.type == DoorType.SpiralStairs: if self.type == DoorType.SpiralStairs:
bitmask = int(self.layer) << 2 bitmask = int(self.layer) << 2
bitmask += 0x10 * int(self.zeroHzCam) bitmask += 0x10 * int(self.zeroHzCam)

View File

@@ -58,14 +58,14 @@ def link_doors_main(world, player):
connect_simple_door(world, exitName, regionName, player) connect_simple_door(world, exitName, regionName, player)
for exitName, regionName in dungeon_warps: for exitName, regionName in dungeon_warps:
connect_simple_door(world, exitName, regionName, player) connect_simple_door(world, exitName, regionName, player)
for ent, ext in ladders:
connect_two_way(world, ent, ext, player)
if world.intensity[player] < 2: if world.intensity[player] < 2:
for entrance, ext in open_edges: for entrance, ext in open_edges:
connect_two_way(world, entrance, ext, player) connect_two_way(world, entrance, ext, player)
for entrance, ext in straight_staircases: for entrance, ext in straight_staircases:
connect_two_way(world, entrance, ext, player) connect_two_way(world, entrance, ext, player)
for entrance, ext in ladders:
connect_two_way(world, entrance, ext, player)
if world.intensity[player] < 3 or world.doorShuffle == 'vanilla': if world.intensity[player] < 3 or world.doorShuffle == 'vanilla':
mirror_route = world.get_entrance('Sanctuary Mirror Route', player) mirror_route = world.get_entrance('Sanctuary Mirror Route', player)
@@ -107,6 +107,8 @@ def link_doors_main(world, player):
connect_simple_door(world, exitName, regionName, player) connect_simple_door(world, exitName, regionName, player)
for entrance, ext in spiral_staircases: for entrance, ext in spiral_staircases:
connect_two_way(world, entrance, ext, player) connect_two_way(world, entrance, ext, player)
for entrance, ext in ladders:
connect_two_way(world, entrance, ext, player)
for entrance, ext in default_door_connections: for entrance, ext in default_door_connections:
connect_two_way(world, entrance, ext, player) connect_two_way(world, entrance, ext, player)
for ent, ext in default_one_way_connections: for ent, ext in default_one_way_connections:
@@ -161,7 +163,7 @@ def create_door_spoiler(world, player):
door_a = ext.door door_a = ext.door
connect = ext.connected_region connect = ext.connected_region
if door_a and door_a.type in [DoorType.Normal, DoorType.SpiralStairs, DoorType.Open, if door_a and door_a.type in [DoorType.Normal, DoorType.SpiralStairs, DoorType.Open,
DoorType.StraightStairs] and door_a not in done: DoorType.StraightStairs, DoorType.Ladder] and door_a not in done:
done.add(door_a) done.add(door_a)
door_b = door_a.dest door_b = door_a.dest
if door_b and not isinstance(door_b, Region): if door_b and not isinstance(door_b, Region):
@@ -1324,11 +1326,10 @@ def combine_layouts(recombinant_builders, dungeon_builders, entrances_map):
if recombine.master_sector is None: if recombine.master_sector is None:
recombine.master_sector = builder.master_sector recombine.master_sector = builder.master_sector
recombine.master_sector.name = recombine.name recombine.master_sector.name = recombine.name
recombine.pre_open_stonewall = builder.pre_open_stonewall recombine.pre_open_stonewalls = builder.pre_open_stonewalls
else: else:
recombine.master_sector.regions.extend(builder.master_sector.regions) recombine.master_sector.regions.extend(builder.master_sector.regions)
if builder.pre_open_stonewall: recombine.pre_open_stonewalls.update(builder.pre_open_stonewalls)
recombine.pre_open_stonewall = builder.pre_open_stonewall
recombine.layout_starts = list(entrances_map[recombine.name]) recombine.layout_starts = list(entrances_map[recombine.name])
dungeon_builders[recombine.name] = recombine dungeon_builders[recombine.name] = recombine
@@ -2009,7 +2010,7 @@ class DROptions(Flag):
Debug = 0x08 Debug = 0x08
Rails = 0x10 # If on, draws rails Rails = 0x10 # If on, draws rails
OriginalPalettes = 0x20 OriginalPalettes = 0x20
Reserved = 0x40 # Reserved for PoD sliding wall? Open_PoD_Wall = 0x40 # If on, pre opens the PoD wall, no bow required
Open_Desert_Wall = 0x80 # If on, pre opens the desert wall, no fire required Open_Desert_Wall = 0x80 # If on, pre opens the desert wall, no fire required
@@ -2042,6 +2043,13 @@ logical_connections = [
('PoD Basement Ledge Drop Down', 'PoD Stalfos Basement'), ('PoD Basement Ledge Drop Down', 'PoD Stalfos Basement'),
('PoD Falling Bridge Path N', 'PoD Falling Bridge Ledge'), ('PoD Falling Bridge Path N', 'PoD Falling Bridge Ledge'),
('PoD Falling Bridge Path S', 'PoD Falling Bridge'), ('PoD Falling Bridge Path S', 'PoD Falling Bridge'),
('PoD Bow Statue Crystal Path', 'PoD Bow Statue Moving Wall'),
('PoD Bow Statue Moving Wall Path', 'PoD Bow Statue'),
('PoD Bow Statue Moving Wall Cane Path', 'PoD Bow Statue'),
('PoD Dark Pegs Hammer Path', 'PoD Dark Pegs Ladder'),
('PoD Dark Pegs Ladder Hammer Path', 'PoD Dark Pegs'),
('PoD Dark Pegs Ladder Cane Path', 'PoD Dark Pegs Switch'),
('PoD Dark Pegs Switch Path', 'PoD Dark Pegs Ladder'),
('Swamp Lobby Moat', 'Swamp Entrance'), ('Swamp Lobby Moat', 'Swamp Entrance'),
('Swamp Entrance Moat', 'Swamp Lobby'), ('Swamp Entrance Moat', 'Swamp Lobby'),
('Swamp Trench 1 Approach Dry', 'Swamp Trench 1 Nexus'), ('Swamp Trench 1 Approach Dry', 'Swamp Trench 1 Nexus'),

View File

@@ -395,8 +395,15 @@ def create_doors(world, player):
create_door(player, 'PoD Mimics 2 SW', Nrml).dir(So, 0x1b, Left, High).pos(1).kill().portal(Z, 0x00), create_door(player, 'PoD Mimics 2 SW', Nrml).dir(So, 0x1b, Left, High).pos(1).kill().portal(Z, 0x00),
create_door(player, 'PoD Mimics 2 NW', Intr).dir(No, 0x1b, Left, High).pos(0), create_door(player, 'PoD Mimics 2 NW', Intr).dir(No, 0x1b, Left, High).pos(0),
create_door(player, 'PoD Bow Statue SW', Intr).dir(So, 0x1b, Left, High).pos(0), create_door(player, 'PoD Bow Statue SW', Intr).dir(So, 0x1b, Left, High).pos(0),
create_door(player, 'PoD Bow Statue Down Ladder', Lddr).no_entrance(), create_door(player, 'PoD Bow Statue Crystal Path', Lgcl),
create_door(player, 'PoD Dark Pegs Up Ladder', Lddr), create_door(player, 'PoD Bow Statue Moving Wall Path', Lgcl),
create_door(player, 'PoD Bow Statue Moving Wall Cane Path', Lgcl),
create_door(player, 'PoD Bow Statue Down Ladder', Lddr).dir(So, 0x1b, 1, High).no_entrance(),
create_door(player, 'PoD Dark Pegs Up Ladder', Lddr).dir(No, 0x0b, 0, High),
create_door(player, 'PoD Dark Pegs Hammer Path', Lgcl),
create_door(player, 'PoD Dark Pegs Ladder Hammer Path', Lgcl),
create_door(player, 'PoD Dark Pegs Ladder Cane Path', Lgcl),
create_door(player, 'PoD Dark Pegs Switch Path', Lgcl),
create_door(player, 'PoD Dark Pegs WN', Intr).dir(We, 0x0b, Mid, High).small_key().pos(2), create_door(player, 'PoD Dark Pegs WN', Intr).dir(We, 0x0b, Mid, High).small_key().pos(2),
create_door(player, 'PoD Lonely Turtle SW', Intr).dir(So, 0x0b, Mid, High).pos(0), create_door(player, 'PoD Lonely Turtle SW', Intr).dir(So, 0x0b, Mid, High).pos(0),
create_door(player, 'PoD Lonely Turtle EN', Intr).dir(Ea, 0x0b, Mid, High).small_key().pos(2), create_door(player, 'PoD Lonely Turtle EN', Intr).dir(Ea, 0x0b, Mid, High).small_key().pos(2),
@@ -663,7 +670,7 @@ def create_doors(world, player):
create_door(player, 'Ice Pengator Switch ES', Intr).dir(Ea, 0x1f, Bot, High).pos(1), create_door(player, 'Ice Pengator Switch ES', Intr).dir(Ea, 0x1f, Bot, High).pos(1),
create_door(player, 'Ice Dead End WS', Intr).dir(We, 0x1f, Bot, High).pos(1), create_door(player, 'Ice Dead End WS', Intr).dir(We, 0x1f, Bot, High).pos(1),
create_door(player, 'Ice Big Key Push Block', Lgcl), create_door(player, 'Ice Big Key Push Block', Lgcl),
create_door(player, 'Ice Big Key Down Ladder', Lddr), create_door(player, 'Ice Big Key Down Ladder', Lddr).dir(So, 0x1f, 3, High),
create_door(player, 'Ice Stalfos Hint SE', Intr).dir(So, 0x3e, Right, High).pos(0), create_door(player, 'Ice Stalfos Hint SE', Intr).dir(So, 0x3e, Right, High).pos(0),
create_door(player, 'Ice Conveyor NE', Intr).dir(No, 0x3e, Right, High).no_exit().pos(0), create_door(player, 'Ice Conveyor NE', Intr).dir(No, 0x3e, Right, High).no_exit().pos(0),
create_door(player, 'Ice Conveyor SW', Nrml).dir(So, 0x3e, Left, High).small_key().pos(1).portal(Z, 0x20), create_door(player, 'Ice Conveyor SW', Nrml).dir(So, 0x3e, Left, High).small_key().pos(1).portal(Z, 0x20),
@@ -679,7 +686,7 @@ def create_doors(world, player):
create_door(player, 'Ice Spike Cross ES', Nrml).dir(Ea, 0x5e, Bot, High).small_key().pos(0), create_door(player, 'Ice Spike Cross ES', Nrml).dir(Ea, 0x5e, Bot, High).small_key().pos(0),
create_door(player, 'Ice Spike Cross WS', Intr).dir(We, 0x5e, Bot, High).pos(3), create_door(player, 'Ice Spike Cross WS', Intr).dir(We, 0x5e, Bot, High).pos(3),
create_door(player, 'Ice Firebar ES', Intr).dir(Ea, 0x5e, Bot, High).pos(3), create_door(player, 'Ice Firebar ES', Intr).dir(Ea, 0x5e, Bot, High).pos(3),
create_door(player, 'Ice Firebar Down Ladder', Lddr), create_door(player, 'Ice Firebar Down Ladder', Lddr).dir(So, 0x5e, 5, High),
create_door(player, 'Ice Spike Cross NE', Intr).dir(No, 0x5e, Right, High).pos(1), create_door(player, 'Ice Spike Cross NE', Intr).dir(No, 0x5e, Right, High).pos(1),
create_door(player, 'Ice Falling Square SE', Intr).dir(So, 0x5e, Right, High).no_exit().pos(1), create_door(player, 'Ice Falling Square SE', Intr).dir(So, 0x5e, Right, High).no_exit().pos(1),
create_door(player, 'Ice Falling Square Hole', Hole), create_door(player, 'Ice Falling Square Hole', Hole),
@@ -689,8 +696,8 @@ def create_doors(world, player):
create_door(player, 'Ice Hammer Block Down Stairs', Sprl).dir(Dn, 0x3f, 0, HTH).ss(Z, 0x11, 0xb8, True, True).kill(), create_door(player, 'Ice Hammer Block Down Stairs', Sprl).dir(Dn, 0x3f, 0, HTH).ss(Z, 0x11, 0xb8, True, True).kill(),
create_door(player, 'Ice Hammer Block ES', Intr).dir(Ea, 0x3f, Bot, High).pos(0), create_door(player, 'Ice Hammer Block ES', Intr).dir(Ea, 0x3f, Bot, High).pos(0),
create_door(player, 'Ice Tongue Pull WS', Intr).dir(We, 0x3f, Bot, High).pos(0), create_door(player, 'Ice Tongue Pull WS', Intr).dir(We, 0x3f, Bot, High).pos(0),
create_door(player, 'Ice Tongue Pull Up Ladder', Lddr), create_door(player, 'Ice Tongue Pull Up Ladder', Lddr).dir(No, 0x3f, 2, High),
create_door(player, 'Ice Freezors Up Ladder', Lddr), create_door(player, 'Ice Freezors Up Ladder', Lddr).dir(No, 0x7e, 4, High),
create_door(player, 'Ice Freezors Hole', Hole), create_door(player, 'Ice Freezors Hole', Hole),
create_door(player, 'Ice Freezors Bomb Hole', Hole), # combine these two? -- they have to lead to the same spot create_door(player, 'Ice Freezors Bomb Hole', Hole), # combine these two? -- they have to lead to the same spot
create_door(player, 'Ice Freezors Ledge Hole', Hole), create_door(player, 'Ice Freezors Ledge Hole', Hole),
@@ -1078,8 +1085,8 @@ def create_doors(world, player):
create_door(player, 'GT Torch Cross WN', Nrml).dir(We, 0x96, Top, High).pos(1), create_door(player, 'GT Torch Cross WN', Nrml).dir(We, 0x96, Top, High).pos(1),
create_door(player, 'GT Torch Cross ES', Intr).dir(Ea, 0x96, Bot, High).pos(0), create_door(player, 'GT Torch Cross ES', Intr).dir(Ea, 0x96, Bot, High).pos(0),
create_door(player, 'GT Staredown WS', Intr).dir(We, 0x96, Bot, High).pos(0), create_door(player, 'GT Staredown WS', Intr).dir(We, 0x96, Bot, High).pos(0),
create_door(player, 'GT Staredown Up Ladder', Lddr), create_door(player, 'GT Staredown Up Ladder', Lddr).dir(No, 0x96, 6, High),
create_door(player, 'GT Falling Torches Down Ladder', Lddr), create_door(player, 'GT Falling Torches Down Ladder', Lddr).dir(So, 0x3d, 7, High),
create_door(player, 'GT Falling Torches NE', Intr).dir(No, 0x3d, Right, High).pos(0), create_door(player, 'GT Falling Torches NE', Intr).dir(No, 0x3d, Right, High).pos(0),
create_door(player, 'GT Mini Helmasaur Room SE', Intr).dir(So, 0x3d, Right, High).pos(0), create_door(player, 'GT Mini Helmasaur Room SE', Intr).dir(So, 0x3d, Right, High).pos(0),
create_door(player, 'GT Falling Torches Hole', Hole), create_door(player, 'GT Falling Torches Hole', Hole),
@@ -1156,9 +1163,11 @@ def create_doors(world, player):
world.get_door('PoD Map Balcony WS', player).c_switch() world.get_door('PoD Map Balcony WS', player).c_switch()
world.get_door('PoD Map Balcony South Stairs', player).c_switch() world.get_door('PoD Map Balcony South Stairs', player).c_switch()
world.get_door('PoD Bow Statue SW', player).c_switch() world.get_door('PoD Bow Statue SW', player).c_switch()
world.get_door('PoD Bow Statue Down Ladder', player).c_switch() world.get_door('PoD Bow Statue Moving Wall Path', player).barrier(CrystalBarrier.Orange)
world.get_door('PoD Dark Pegs Up Ladder', player).c_switch() world.get_door('PoD Bow Statue Crystal Path', player).c_switch()
world.get_door('PoD Dark Pegs WN', player).c_switch() world.get_door('PoD Dark Pegs WN', player).c_switch()
world.get_door('PoD Dark Pegs Switch Path', player).c_switch()
world.get_door('PoD Dark Pegs Hammer Path', player).c_switch()
world.get_door('Swamp Crystal Switch EN', player).c_switch() world.get_door('Swamp Crystal Switch EN', player).c_switch()
world.get_door('Swamp Crystal Switch SE', player).c_switch() world.get_door('Swamp Crystal Switch SE', player).c_switch()

View File

@@ -55,19 +55,21 @@ def pre_validate(builder, entrance_region_names, split_dungeon, world, player):
def generate_dungeon(builder, entrance_region_names, split_dungeon, world, player): def generate_dungeon(builder, entrance_region_names, split_dungeon, world, player):
stonewall = check_for_stonewall(builder) stonewalls = check_for_stonewalls(builder)
sector = generate_dungeon_main(builder, entrance_region_names, split_dungeon, world, player) sector = generate_dungeon_main(builder, entrance_region_names, split_dungeon, world, player)
if stonewall and not stonewall_valid(stonewall): for stonewall in stonewalls:
builder.pre_open_stonewall = stonewall if not stonewall_valid(stonewall):
builder.pre_open_stonewalls.add(stonewall)
return sector return sector
def check_for_stonewall(builder): def check_for_stonewalls(builder):
stonewalls = set()
for sector in builder.sectors: for sector in builder.sectors:
for door in sector.outstanding_doors: for door in sector.outstanding_doors:
if door.stonewall: if door.stonewall:
return door stonewalls.add(door)
return None return stonewalls
def generate_dungeon_main(builder, entrance_region_names, split_dungeon, world, player): def generate_dungeon_main(builder, entrance_region_names, split_dungeon, world, player):
@@ -418,8 +420,7 @@ def check_valid(name, dungeon, hangers, hooks, proposed_map, doors_to_connect, a
true_origin_hooks = [x for x in dungeon['Origin'].hooks.keys() if not x.bigKey or possible_bks > 0 or not bk_needed] true_origin_hooks = [x for x in dungeon['Origin'].hooks.keys() if not x.bigKey or possible_bks > 0 or not bk_needed]
if len(true_origin_hooks) == 0 and len(proposed_map.keys()) < len(doors_to_connect): if len(true_origin_hooks) == 0 and len(proposed_map.keys()) < len(doors_to_connect):
return False return False
if len(true_origin_hooks) == 0 and bk_needed and possible_bks == 0 and len(proposed_map.keys()) == len( if len(true_origin_hooks) == 0 and bk_needed and possible_bks == 0 and len(proposed_map.keys()) == len(doors_to_connect):
doors_to_connect):
return False return False
for key in hangers.keys(): for key in hangers.keys():
if len(hooks[key]) > 0 and len(hangers[key]) == 0: if len(hooks[key]) > 0 and len(hangers[key]) == 0:
@@ -694,17 +695,17 @@ hang_dir_map = {
def hanger_from_door(door): def hanger_from_door(door):
if door.type == DoorType.SpiralStairs: if door.type == DoorType.SpiralStairs:
return Hook.Stairs return Hook.Stairs
if door.type in [DoorType.Normal, DoorType.Open, DoorType.StraightStairs]: if door.type in [DoorType.Normal, DoorType.Open, DoorType.StraightStairs, DoorType.Ladder]:
return hang_dir_map[door.direction] return hang_dir_map[door.direction]
return None return None
def connect_doors(a, b): def connect_doors(a, b):
# Return on unsupported types. # Return on unsupported types.
if a.type in [DoorType.Hole, DoorType.Warp, DoorType.Ladder, DoorType.Interior, DoorType.Logical]: if a.type in [DoorType.Hole, DoorType.Warp, DoorType.Interior, DoorType.Logical]:
return return
# Connect supported types # Connect supported types
if a.type in [DoorType.Normal, DoorType.SpiralStairs, DoorType.Open, DoorType.StraightStairs]: if a.type in [DoorType.Normal, DoorType.SpiralStairs, DoorType.Open, DoorType.StraightStairs, DoorType.Ladder]:
if a.blocked: if a.blocked:
connect_one_way(b.entrance, a.entrance) connect_one_way(b.entrance, a.entrance)
elif b.blocked: elif b.blocked:
@@ -1171,7 +1172,7 @@ class DungeonBuilder(object):
self.path_entrances = None # used for pathing/key doors, I think self.path_entrances = None # used for pathing/key doors, I think
self.split_flag = False self.split_flag = False
self.pre_open_stonewall = None # used by stonewall system self.pre_open_stonewalls = set() # used by stonewall system
self.candidates = None self.candidates = None
self.key_doors_num = None self.key_doors_num = None

View File

@@ -213,8 +213,8 @@ pod_regions = [
'PoD Map Balcony', 'PoD Conveyor', 'PoD Mimics 1', 'PoD Jelly Hall', 'PoD Warp Hint', 'PoD Warp Room', 'PoD Map Balcony', 'PoD Conveyor', 'PoD Mimics 1', 'PoD Jelly Hall', 'PoD Warp Hint', 'PoD Warp Room',
'PoD Stalfos Basement', 'PoD Basement Ledge', 'PoD Big Key Landing', 'PoD Falling Bridge', 'PoD Stalfos Basement', 'PoD Basement Ledge', 'PoD Big Key Landing', 'PoD Falling Bridge',
'PoD Falling Bridge Ledge', 'PoD Dark Maze', 'PoD Big Chest Balcony', 'PoD Compass Room', 'PoD Dark Basement', 'PoD Falling Bridge Ledge', 'PoD Dark Maze', 'PoD Big Chest Balcony', 'PoD Compass Room', 'PoD Dark Basement',
'PoD Harmless Hellway', 'PoD Mimics 2', 'PoD Bow Statue', 'PoD Dark Pegs', 'PoD Lonely Turtle', 'PoD Turtle Party', 'PoD Harmless Hellway', 'PoD Mimics 2', 'PoD Bow Statue', 'PoD Bow Statue Moving Wall', 'PoD Dark Pegs', 'PoD Dark Pegs Ladder', 'PoD Dark Pegs Switch',
'PoD Dark Alley', 'PoD Callback', 'PoD Boss', 'Palace of Darkness Portal' 'PoD Lonely Turtle', 'PoD Turtle Party', 'PoD Dark Alley', 'PoD Callback', 'PoD Boss', 'Palace of Darkness Portal'
] ]
swamp_regions = [ swamp_regions = [

View File

@@ -45,7 +45,7 @@ Doors are not shuffled.
#### Level 1 #### Level 1
Normal door and spiral staircases are shuffled Normal door and spiral staircases are shuffled
#### Level 2 #### Level 2
Same as Level 1 plus open edges and straight staircases are shuffled. Same as Level 1 plus open edges and both types of straight staircases are shuffled.
#### Level 3 #### Level 3
Same as Level 2 plus Dungeon Lobbies are shuffled Same as Level 2 plus Dungeon Lobbies are shuffled

View File

@@ -401,8 +401,11 @@ def create_dungeon_regions(world, player):
create_dungeon_region(player, 'PoD Dark Basement', 'Palace of Darkness', ['Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right'], ['PoD Dark Basement W Up Stairs', 'PoD Dark Basement E Up Stairs']), create_dungeon_region(player, 'PoD Dark Basement', 'Palace of Darkness', ['Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right'], ['PoD Dark Basement W Up Stairs', 'PoD Dark Basement E Up Stairs']),
create_dungeon_region(player, 'PoD Harmless Hellway', 'Palace of Darkness', ['Palace of Darkness - Harmless Hellway'], ['PoD Harmless Hellway NE', 'PoD Harmless Hellway SE']), create_dungeon_region(player, 'PoD Harmless Hellway', 'Palace of Darkness', ['Palace of Darkness - Harmless Hellway'], ['PoD Harmless Hellway NE', 'PoD Harmless Hellway SE']),
create_dungeon_region(player, 'PoD Mimics 2', 'Palace of Darkness', None, ['PoD Mimics 2 SW', 'PoD Mimics 2 NW']), create_dungeon_region(player, 'PoD Mimics 2', 'Palace of Darkness', None, ['PoD Mimics 2 SW', 'PoD Mimics 2 NW']),
create_dungeon_region(player, 'PoD Bow Statue', 'Palace of Darkness', None, ['PoD Bow Statue SW', 'PoD Bow Statue Down Ladder']), create_dungeon_region(player, 'PoD Bow Statue', 'Palace of Darkness', None, ['PoD Bow Statue SW', 'PoD Bow Statue Crystal Path']),
create_dungeon_region(player, 'PoD Dark Pegs', 'Palace of Darkness', None, ['PoD Dark Pegs Up Ladder', 'PoD Dark Pegs WN']), create_dungeon_region(player, 'PoD Bow Statue Moving Wall', 'Palace of Darkness', None, ['PoD Bow Statue Moving Wall Path', 'PoD Bow Statue Down Ladder', 'PoD Bow Statue Moving Wall Cane Path']),
create_dungeon_region(player, 'PoD Dark Pegs', 'Palace of Darkness', None, ['PoD Dark Pegs Hammer Path', 'PoD Dark Pegs WN']),
create_dungeon_region(player, 'PoD Dark Pegs Ladder', 'Palace of Darkness', None, ['PoD Dark Pegs Up Ladder', 'PoD Dark Pegs Ladder Hammer Path', 'PoD Dark Pegs Ladder Cane Path']),
create_dungeon_region(player, 'PoD Dark Pegs Switch', 'Palace of Darkness', None, ['PoD Dark Pegs Switch Path']),
create_dungeon_region(player, 'PoD Lonely Turtle', 'Palace of Darkness', None, ['PoD Lonely Turtle SW', 'PoD Lonely Turtle EN']), create_dungeon_region(player, 'PoD Lonely Turtle', 'Palace of Darkness', None, ['PoD Lonely Turtle SW', 'PoD Lonely Turtle EN']),
create_dungeon_region(player, 'PoD Turtle Party', 'Palace of Darkness', None, ['PoD Turtle Party ES', 'PoD Turtle Party NW']), create_dungeon_region(player, 'PoD Turtle Party', 'Palace of Darkness', None, ['PoD Turtle Party ES', 'PoD Turtle Party NW']),
create_dungeon_region(player, 'PoD Dark Alley', 'Palace of Darkness', None, ['PoD Dark Alley NE']), create_dungeon_region(player, 'PoD Dark Alley', 'Palace of Darkness', None, ['PoD Dark Alley NE']),
@@ -762,7 +765,8 @@ def create_dungeon_regions(world, player):
world.get_region('PoD Arena Main', player).crystal_switch = True world.get_region('PoD Arena Main', player).crystal_switch = True
world.get_region('PoD Arena Bridge', player).crystal_switch = True # RANGED Weapon Required world.get_region('PoD Arena Bridge', player).crystal_switch = True # RANGED Weapon Required
world.get_region('PoD Sexy Statue', player).crystal_switch = True world.get_region('PoD Sexy Statue', player).crystal_switch = True
world.get_region('PoD Bow Statue', player).crystal_switch = True # LADDER not accessible (maybe with cane) world.get_region('PoD Bow Statue', player).crystal_switch = True
world.get_region('PoD Dark Pegs Switch', player).crystal_switch = True
world.get_region('PoD Dark Pegs', player).crystal_switch = True world.get_region('PoD Dark Pegs', player).crystal_switch = True
world.get_region('Swamp Crystal Switch', player).crystal_switch = True world.get_region('Swamp Crystal Switch', player).crystal_switch = True
world.get_region('Thieves Spike Switch', player).crystal_switch = True world.get_region('Thieves Spike Switch', player).crystal_switch = True

10
Rom.py
View File

@@ -27,7 +27,7 @@ from EntranceShuffle import door_addresses, exit_ids
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '30147375153cc57197805eddf38c2a23' RANDOMIZERBASEHASH = 'bffd4e834049ca5f5295601436fc6009'
class JsonRom(object): class JsonRom(object):
@@ -685,7 +685,7 @@ def patch_rom(world, rom, player, team, enemized):
for door in world.doors: for door in world.doors:
if door.dest is not None and isinstance(door.dest, Door) and\ if door.dest is not None and isinstance(door.dest, Door) and\
door.player == player and door.type in [DoorType.Normal, DoorType.SpiralStairs, door.player == player and door.type in [DoorType.Normal, DoorType.SpiralStairs,
DoorType.Open, DoorType.StraightStairs]: DoorType.Open, DoorType.StraightStairs, DoorType.Ladder]:
rom.write_bytes(door.getAddress(), door.dest.getTarget(door)) rom.write_bytes(door.getAddress(), door.dest.getTarget(door))
for paired_door in world.paired_doors[player]: for paired_door in world.paired_doors[player]:
rom.write_bytes(paired_door.address_a(world, player), paired_door.rom_data_a(world, player)) rom.write_bytes(paired_door.address_a(world, player), paired_door.rom_data_a(world, player))
@@ -693,9 +693,11 @@ def patch_rom(world, rom, player, team, enemized):
if world.doorShuffle[player] != 'vanilla': if world.doorShuffle[player] != 'vanilla':
for builder in world.dungeon_layouts[player].values(): for builder in world.dungeon_layouts[player].values():
if builder.pre_open_stonewall: for stonewall in builder.pre_open_stonewalls:
if builder.pre_open_stonewall.name == 'Desert Wall Slide NW': if stonewall.name == 'Desert Wall Slide NW':
dr_flags |= DROptions.Open_Desert_Wall dr_flags |= DROptions.Open_Desert_Wall
elif stonewall.name == 'PoD Bow Statue Down Ladder':
dr_flags |= DROptions.Open_PoD_Wall
for name, pair in boss_indicator.items(): for name, pair in boss_indicator.items():
dungeon_id, boss_door = pair dungeon_id, boss_door = pair
opposite_door = world.get_door(boss_door, player).dest opposite_door = world.get_door(boss_door, player).dest

View File

@@ -180,8 +180,10 @@ def global_rules(world, player):
set_rule(world.get_entrance('PoD Mimics 2 NW', player), lambda state: state.can_shoot_arrows(player)) set_rule(world.get_entrance('PoD Mimics 2 NW', player), lambda state: state.can_shoot_arrows(player))
set_rule(world.get_entrance('PoD Bow Statue Down Ladder', player), lambda state: state.can_shoot_arrows(player)) set_rule(world.get_entrance('PoD Bow Statue Down Ladder', player), lambda state: state.can_shoot_arrows(player))
set_rule(world.get_entrance('PoD Map Balcony Drop Down', player), lambda state: state.has('Hammer', player)) set_rule(world.get_entrance('PoD Map Balcony Drop Down', player), lambda state: state.has('Hammer', player))
set_rule(world.get_entrance('PoD Dark Pegs WN', player), lambda state: state.has('Hammer', player)) set_rule(world.get_entrance('PoD Dark Pegs Hammer Path', player), lambda state: state.has('Hammer', player))
set_rule(world.get_entrance('PoD Dark Pegs Up Ladder', player), lambda state: state.has('Hammer', player)) set_rule(world.get_entrance('PoD Dark Pegs Ladder Hammer Path', player), lambda state: state.has('Hammer', player))
set_rule(world.get_entrance('PoD Dark Pegs Ladder Cane Path', player), lambda state: state.has('Cane of Somaria', player))
set_rule(world.get_entrance('PoD Bow Statue Moving Wall Cane Path', player), lambda state: state.has('Cane of Somaria', player))
set_defeat_dungeon_boss_rule(world.get_location('Palace of Darkness - Boss', player)) set_defeat_dungeon_boss_rule(world.get_location('Palace of Darkness - Boss', player))
set_defeat_dungeon_boss_rule(world.get_location('Palace of Darkness - Prize', player)) set_defeat_dungeon_boss_rule(world.get_location('Palace of Darkness - Prize', player))
@@ -723,7 +725,9 @@ def no_glitches_rules(world, player):
'PoD Callback': {'sewer': False, 'entrances': ['PoD Callback WS', 'PoD Callback Warp'], 'locations': []}, 'PoD Callback': {'sewer': False, 'entrances': ['PoD Callback WS', 'PoD Callback Warp'], 'locations': []},
'PoD Turtle Party': {'sewer': False, 'entrances': ['PoD Turtle Party ES', 'PoD Turtle Party NW'], 'locations': []}, 'PoD Turtle Party': {'sewer': False, 'entrances': ['PoD Turtle Party ES', 'PoD Turtle Party NW'], 'locations': []},
'PoD Lonely Turtle': {'sewer': False, 'entrances': ['PoD Lonely Turtle SW', 'PoD Lonely Turtle EN'], 'locations': []}, 'PoD Lonely Turtle': {'sewer': False, 'entrances': ['PoD Lonely Turtle SW', 'PoD Lonely Turtle EN'], 'locations': []},
'PoD Dark Pegs': {'sewer': False, 'entrances': ['PoD Dark Pegs Up Ladder', 'PoD Dark Pegs WN'], 'locations': []}, 'PoD Dark Pegs': {'sewer': False, 'entrances': ['PoD Dark Pegs Hammer Path', 'PoD Dark Pegs WN'], 'locations': []},
'PoD Dark Pegs Ladder': {'sewer': False, 'entrances': ['PoD Dark Pegs Up Ladder', 'PoD Dark Pegs Ladder Hammer Path', 'PoD Dark Pegs Ladder Cane Path'], 'locations': []},
'PoD Dark Pegs Switch': {'sewer': False, 'entrances': ['PoD Dark Pegs Switch Path'], 'locations': []},
'PoD Dark Basement': {'sewer': False, 'entrances': ['PoD Dark Basement W Up Stairs', 'PoD Dark Basement E Up Stairs'], 'locations': ['Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right']}, 'PoD Dark Basement': {'sewer': False, 'entrances': ['PoD Dark Basement W Up Stairs', 'PoD Dark Basement E Up Stairs'], 'locations': ['Palace of Darkness - Dark Basement - Left', 'Palace of Darkness - Dark Basement - Right']},
'PoD Dark Maze': {'sewer': False, 'entrances': ['PoD Dark Maze EN', 'PoD Dark Maze E'], 'locations': ['Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom']}, 'PoD Dark Maze': {'sewer': False, 'entrances': ['PoD Dark Maze EN', 'PoD Dark Maze E'], 'locations': ['Palace of Darkness - Dark Maze - Top', 'Palace of Darkness - Dark Maze - Bottom']},
'Eastern Dark Square': {'sewer': False, 'entrances': ['Eastern Dark Square NW', 'Eastern Dark Square Key Door WN', 'Eastern Dark Square EN'], 'locations': []}, 'Eastern Dark Square': {'sewer': False, 'entrances': ['Eastern Dark Square NW', 'Eastern Dark Square Key Door WN', 'Eastern Dark Square EN'], 'locations': []},

View File

@@ -7,6 +7,8 @@
; Free RAM notes ; Free RAM notes
; Normal doors use $AB-AC for scrolling indicator ; Normal doors use $AB-AC for scrolling indicator
; Normal doors use $FE to store the trap door indicator ; Normal doors use $FE to store the trap door indicator
; Normal doors use $045e to store Y coordinate when transitioning to in-room stairs
; Normal doors use $045f to determine the order in which supertile quadrants are drawn
; Spiral doors use $045e to store stair type ; Spiral doors use $045e to store stair type
; Gfx uses $b1 to for sub-sub-sub-module thing ; Gfx uses $b1 to for sub-sub-sub-module thing
@@ -35,7 +37,7 @@ incsrc edges.asm
incsrc math.asm incsrc math.asm
incsrc hudadditions.asm incsrc hudadditions.asm
incsrc dr_lobby.asm incsrc dr_lobby.asm
warnpc $279700 warnpc $279C00
incsrc doortables.asm incsrc doortables.asm
warnpc $288000 warnpc $288000

View File

@@ -1,4 +1,4 @@
org $279700 org $279C00
KeyDoorOffset: KeyDoorOffset:
; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler ; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler
dw $0000,$0001,$0003,$0000,$0006,$0000,$000b,$0000,$0000,$0000,$000c,$000d,$0010,$0011,$0012,$0000 dw $0000,$0001,$0003,$0000,$0006,$0000,$000b,$0000,$0000,$0000,$000c,$000d,$0010,$0011,$0012,$0000
@@ -58,7 +58,7 @@ db $9f
org $27A000 org $27A000
DoorTable: DoorTable:
;; NW 00 N 01 N 02 WN 00 W 01 WS 02 SW 00 S 01 SE 02 EN 00 E 01 ES 02 - Door ruler ;; NW 00 N 01 NE 02 WN 00 W 01 WS 02 SW 00 S 01 SE 02 EN 00 E 01 ES 02 - Door ruler
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Default/Garbage row dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Default/Garbage row
dw $0003, $0003, $0003, $0450, $0003, $0003, $0003, $0003, $0003, $0452, $0003, $0003 ; HC Back Hall (x01) dw $0003, $0003, $0003, $0450, $0003, $0003, $0003, $0003, $0003, $0452, $0003, $0003 ; HC Back Hall (x01)
dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Switches (x02) dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Switches (x02)
@@ -227,7 +227,7 @@ dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003,
;dw $0080, $1f50 ; ->zelda's cellblock ;dw $0080, $1f50 ; ->zelda's cellblock
org $27B000 org $27B000
SpiralTable: ;113 4 byte entries - should end at 27B44C SpiralTable: ;113 4 byte entries - should end at 27B1C4
dw $0203, $8080 ;null row dw $0203, $8080 ;null row
dw $0203, $8080 ;HC Backhallway dw $0203, $8080 ;HC Backhallway
dw $0203, $8080 ;Sewer Pull dw $0203, $8080 ;Sewer Pull
@@ -557,6 +557,20 @@ MultDivInfo: ; (1, 2, 3, 4, 5, 6, 10, 20)
db $01, $02, $03, $04, $05, $06, $0a, $14 db $01, $02, $03, $04, $05, $06, $0a, $14
; indices: 0-7 ; indices: 0-7
; In-room stairs in North/South pairs. From left to right:
; PoD, IP right side, IP Freezor chest and GT
org $27C700
InroomStairsTable:
dw $0003,$0003, $0003,$0003, $0003,$0003, $0003,$0003
org $27C720
InroomStairsRoom:
db $0B,$1B, $3F,$1F, $7E,$5E, $96,$3D
InroomStairsX:
dw $0190, $0160, $0040, $0178
InroomStairsY:
dw $0058, $0148, $0198, $0190
; dungeon tables ; dungeon tables
; HC HC EP DP AT SP PD MM SW IP TH TT TR GT ; HC HC EP DP AT SP PD MM SW IP TH TT TR GT

View File

@@ -46,8 +46,19 @@ org $029396 ; <- 11396 - Bank02.asm : 3641 (LDA $01C322, X)
jsl StraightStairLayerFix jsl StraightStairLayerFix
org $02c06d ; <- Bank02.asm : 9874 (LDX $0418, CMP.b #$02) org $02c06d ; <- Bank02.asm : 9874 (LDX $0418, CMP.b #$02)
jsl DoorToStraight : nop jsl DoorToStraight : nop
org $02c092 ; STA $0020, Y : LDX #$00
jsl DoorToInroom : nop
org $02c0f8 ; CMP $02C034, X
jsl DoorToInroomEnd
org $02941a ; <- Bank02.asm : 3748 module 7.12.11 (LDA $0464 : BNE BRANCH_$11513 : INC $B0 : RTS) org $02941a ; <- Bank02.asm : 3748 module 7.12.11 (LDA $0464 : BNE BRANCH_$11513 : INC $B0 : RTS)
jsl StraightStairsTrapDoor : rts jsl StraightStairsTrapDoor : rts
org $028b54 ; <- Bank02.asm : 2200 (JSL UseImplicitRegIndexedLocalJumpTable)
jsl InroomStairsTrapDoor
org $0289a0 ; JSL $0091C4
jsl QuadrantLoadOrderBeforeScroll
org $02bd9c ; JSL $0091C4
jsl QuadrantLoadOrderAfterScroll
; Graphics fix ; Graphics fix

View File

@@ -52,14 +52,20 @@ LoadEdgeRoomVert:
lda $03 : sta $a0 lda $03 : sta $a0
sty $06 sty $06
and.b #$f0 : lsr #3 : !sub $21 : !add $06 : sta $02 and.b #$f0 : lsr #3 : !sub $21 : !add $06 : sta $02
ldy #$01 : jsr ShiftVariablesMainDir
lda $04 : and #$80 : bne .edge lda $04 : and #$80 : bne .edge
lda $04 : sta $01 ; load up flags in $01 lda $04 : sta $01 ; load up flags in $01
and #$03 : cmp #$03 : beq .inroom
ldy #$01 : jsr ShiftVariablesMainDir
jsr PrepScrollToNormal jsr PrepScrollToNormal
bra .scroll bra .scroll
.inroom
jsr ScrollToInroomStairs
rts
.edge .edge
ldy #$01 : jsr ShiftVariablesMainDir
lda $04 : and #$10 : beq + lda $04 : and #$10 : beq +
lda #$01 lda #$01
+ sta $ee ; layer stuff + sta $ee ; layer stuff

View File

@@ -31,6 +31,13 @@ WarpUp:
jsr Cleanup jsr Cleanup
rtl rtl
; Checks if $a0 is equal to <Room>. If it is, opens its stonewall if it's there
macro StonewallCheck(Room)
lda $a0 : cmp.b #<Room> : bne ?end
lda.l <Room>*2+$7ef000 : ora #$80 : sta.l <Room>*2+$7ef000
?end
endmacro
WarpDown: WarpDown:
lda.l DRMode : beq .end lda.l DRMode : beq .end
lda $040c : cmp.b #$ff : beq .end lda $040c : cmp.b #$ff : beq .end
@@ -38,6 +45,7 @@ WarpDown:
jsr CalcIndex jsr CalcIndex
!add #$0c : ldy #$ff ; offsets in A, Y !add #$0c : ldy #$ff ; offsets in A, Y
jsr LoadRoomVert jsr LoadRoomVert
%StonewallCheck($43)
.end .end
jsr Cleanup jsr Cleanup
rtl rtl
@@ -130,15 +138,20 @@ LoadRoomVert:
.gtg ;Good to Go! .gtg ;Good to Go!
pla ; Throw away normal room (don't fill up the stack) pla ; Throw away normal room (don't fill up the stack)
lda $a0 : and.b #$F0 : lsr #3 : !sub $21 : !add $06 : sta $02 lda $a0 : and.b #$F0 : lsr #3 : !sub $21 : !add $06 : sta $02
ldy #$01 : jsr ShiftVariablesMainDir
lda $01 : and #$80 : beq .normal lda $01 : and #$80 : beq .notEdge
ldy #$01 : jsr ShiftVariablesMainDir
ldy $06 : cpy #$ff : beq + ldy $06 : cpy #$ff : beq +
lda $01 : jsr LoadSouthMidpoint : bra ++ lda $01 : jsr LoadSouthMidpoint : bra ++
+ lda $01 : jsr LoadNorthMidpoint + lda $01 : jsr LoadNorthMidpoint
++ jsr PrepScrollToEdge : bra .scroll ++ jsr PrepScrollToEdge : bra .scroll
.notEdge
lda $01 : and #$03 : cmp #$03 : bne .normal
jsr ScrollToInroomStairs
bra .end
.normal .normal
ldy #$01 : jsr ShiftVariablesMainDir
jsr PrepScrollToNormal jsr PrepScrollToNormal
.scroll .scroll
lda $01 : and #$40 : pha lda $01 : and #$40 : pha
@@ -180,6 +193,68 @@ ShiftVariablesMainDir:
rts rts
} }
; Normal Flags should be in $01
ScrollToInroomStairs:
{
jsr PrepScrollToInroomStairs
ldy #$01 : jsr ShiftVariablesMainDir
jsr ScrollX
ldy #$00 : jsr ApplyScroll
lda $a0 : and #$0f : cmp #$0f : bne +
stz $e0 : stz $e2 ; special case camera fix
lda #$1f : sta $e1 : sta $e3
+
rts
}
; Direction should be in $06, Shift Value (see above) in $02 and other info in $01
; Sets $02, $04, $05, $ee, $045e, $045f and things related to Y coordinate
PrepScrollToInroomStairs:
{
lda $01 : and #$30 : lsr #3 : tay
lda.w InroomStairsX,y : sta $04
lda.w InroomStairsX+1,y : sta $05
lda $06 : cmp #$ff : beq .south
lda.w InroomStairsY+1,y : bne +
inc $045f ; flag indicating special screen transition
dec $02 ; shift variables further
stz $aa
lda $a8 : and #%11111101 : sta $a8
stz $0613 ; North scroll target
inc $0603 : inc $0607
dec $0619 : dec $061b
+
lda.w InroomStairsY,y : !add #$20 : sta $20
!sub #$38 : sta $045e
lda $01 : and #$40 : beq +
lda $20 : !add #$20 : sta $20
stz $045f
+
dec $21
%StonewallCheck($1b)
bra ++
.south
lda.w InroomStairsY+1,y : beq +
inc $045f ; flag indicating special screen transition
inc $02 ; shift variables further
lda #$02 : sta $aa
lda $a8 : ora #%00000010 : sta $a8
inc $0611 ; South scroll target
dec $0603 : dec $0607
inc $0619 : inc $061b
+
lda.w InroomStairsY,y : !sub #$20 : sta $20
!add #$38 : sta $045e
lda $01 : and #$40 : beq +
lda $20 : !sub #$20 : sta $20
stz $045f
+
inc $21
++
lda $01 : and #$04 : lsr #2 : sta $ee : bne +
stz $0476
+ rts
}
; Target pixel should be in A, other info in $01 ; Target pixel should be in A, other info in $01
; Sets $04 $05 and $ee ; Sets $04 $05 and $ee
@@ -214,6 +289,7 @@ StraightStairsAdj:
{ {
stx $0464 : sty $012e ; what we wrote over stx $0464 : sty $012e ; what we wrote over
lda.l DRMode : beq + lda.l DRMode : beq +
lda $045e : bne .toInroom
jsr GetTileAttribute : tax jsr GetTileAttribute : tax
lda $11 : cmp #$12 : beq .goingNorth lda $11 : cmp #$12 : beq .goingNorth
lda $a2 : cmp #$51 : bne ++ lda $a2 : cmp #$51 : bne ++
@@ -234,6 +310,9 @@ StraightStairsAdj:
pla : !add #$f6 : pha pla : !add #$f6 : pha
++ pla : !add $0464 : sta $0464 ++ pla : !add $0464 : sta $0464
+ rtl + rtl
.toInroom
lda #$32 : sta $0464 : stz $045e
rtl
} }
GetTileAttribute: GetTileAttribute:
@@ -283,11 +362,32 @@ DoorToStraight:
rtl rtl
} }
DoorToInroom:
{
ldx $045e : bne .end
sta $0020, y ; what we wrote over
.end
ldx #$00 ; what we wrote over
rtl
}
DoorToInroomEnd:
{
ldy $045e : beq .vanilla
cmp $045e : bne .return
stz $045e ; clear
.return
rtl
.vanilla
cmp $02c034, x ; what we wrote over
rtl
}
StraightStairsTrapDoor: StraightStairsTrapDoor:
{ {
lda $0464 : bne + lda $0464 : bne +
; reset function ; reset function
phk : pea.w .jslrtsreturn-1 .reset phk : pea.w .jslrtsreturn-1
pea.w $02802c pea.w $02802c
jml $028c73 ; $10D71 .reset label of Bank02 jml $028c73 ; $10D71 .reset label of Bank02
.jslrtsreturn .jslrtsreturn
@@ -300,5 +400,15 @@ StraightStairsTrapDoor:
inc $0468 : stz $068e : stz $0690 inc $0468 : stz $068e : stz $0690
++ rtl ++ rtl
+ jsl Dungeon_ApproachFixedColor ; what we wrote over + jsl Dungeon_ApproachFixedColor ; what we wrote over
.end rtl rtl
}
InroomStairsTrapDoor:
{
lda $0200 : cmp #$05 : beq .reset
lda $b0 : jml $008781 ; what we wrote over (essentially)
.reset
pla : pla : pla
jsl StraightStairsTrapDoor_reset
jml $028b15 ; just some RTS in bank 02
} }

View File

@@ -37,6 +37,8 @@ OnFileLoadOverride:
jsl OnFileLoad ; what I wrote over jsl OnFileLoad ; what I wrote over
lda.l DRFlags : and #$80 : beq + ;flag is off lda.l DRFlags : and #$80 : beq + ;flag is off
lda $7ef086 : ora #$80 : sta $7ef086 lda $7ef086 : ora #$80 : sta $7ef086
+ lda.l DRFlags : and #$40 : beq + ;flag is off
lda $7ef036 : ora #$80 : sta $7ef036
+ lda.l DRFlags : and #$02 : beq + + lda.l DRFlags : and #$02 : beq +
lda $7ef353 : bne + lda $7ef353 : bne +
lda #$01 : sta $7ef353 lda #$01 : sta $7ef353

View File

@@ -204,3 +204,17 @@ ApplyScroll:
sta $00e2, y sta $00e2, y
sta $00e0, y sta $00e0, y
stz $ab : sep #$30 : rts stz $ab : sep #$30 : rts
QuadrantLoadOrderBeforeScroll:
lda $045f : beq .end
lda #$08 : sta $045c ; start with opposite quadrant row
.end
jsl $0091c4 ; what we overwrote
rtl
QuadrantLoadOrderAfterScroll:
lda $045f : beq .end
stz $045c : stz $045f ; draw other row and clear flag
.end
jsl $0091c4 ; what we overwrote
rtl

View File

@@ -2,9 +2,10 @@ RecordStairType: {
pha pha
lda.l DRMode : beq .norm lda.l DRMode : beq .norm
lda $040c : cmp #$ff : beq .norm lda $040c : cmp #$ff : beq .norm
lda $0e : sta $045e lda $0e
cmp #$26 : beq .norm ; skipping in-floor staircases cmp #$25 : bcc ++ ; don't record straight staircases
pla : bra + sta $045e
++ pla : bra +
.norm pla : sta $a0 .norm pla : sta $a0
+ lda $063d, x + lda $063d, x
rtl rtl
@@ -15,8 +16,13 @@ SpiralWarp: {
lda $040c : cmp.b #$ff : beq .abort ; abort if not in dungeon lda $040c : cmp.b #$ff : beq .abort ; abort if not in dungeon
lda $045e : cmp #$5e : beq .gtg ; abort if not spiral - intended room is in A! lda $045e : cmp #$5e : beq .gtg ; abort if not spiral - intended room is in A!
cmp #$5f : beq .gtg cmp #$5f : beq .gtg
cmp #$26 : beq .inroom
.abort .abort
stz $045e : lda $a2 : and #$0f : rtl ; clear,run hijacked code and get out stz $045e : lda $a2 : and #$0f : rtl ; clear,run hijacked code and get out
.inroom
jsr InroomStairsWarp
lda $a2 : and #$0f ; this is the code we are hijacking
rtl
.gtg .gtg
phb : phk : plb : phx : phy ; push stuff phb : phk : plb : phx : phy ; push stuff
@@ -70,6 +76,13 @@ SpiralWarp: {
lda $01 : and #$20 : sta $07 ; zeroVtCam check lda $01 : and #$20 : sta $07 ; zeroVtCam check
ldy #$01 : jsr SetCamera ldy #$01 : jsr SetCamera
jsr StairCleanup
ply : plx : plb ; pull the stuff we pushed
lda $a2 : and #$0f ; this is the code we are hijacking
rtl
}
StairCleanup: {
stz $045e ; clear the staircase flag stz $045e ; clear the staircase flag
; animated tiles fix ; animated tiles fix
@@ -81,9 +94,7 @@ SpiralWarp: {
jsl DecompDungAnimatedTiles jsl DecompDungAnimatedTiles
+ +
stz $047a stz $047a
ply : plx : plb ; pull the stuff we pushed rts
lda $a2 : and #$0f ; this is the code we are hijacking
rtl
} }
;Sets the offset in A ;Sets the offset in A
@@ -105,7 +116,7 @@ LookupSpiralOffset: {
lda $a9 : ora $aa : and #$03 : beq .quad0 lda $a9 : ora $aa : and #$03 : beq .quad0
cmp #$01 : beq .quad1 cmp #$01 : beq .quad1
cmp #$02 : beq .quad2 cmp #$02 : beq .quad2
cmp #$03 : beq .quad3 bra .quad3
.quad0 .quad0
inc $01 : lda $a2 inc $01 : lda $a2
cmp #$0c : beq .q0diff ;gt ent cmp #$0c : beq .q0diff ;gt ent
@@ -138,6 +149,103 @@ LookupSpiralOffset: {
rts rts
} }
InroomStairsWarp: {
phb : phk : plb : phx : phy ; push stuff
; find stairs by room and store index in X
lda $a0 : ldx #$07
.loop
cmp.w InroomStairsRoom,x
beq .found
dex
bne .loop
.found
rep #$30
txa : and #$00ff : asl : tay
lda.w InroomStairsTable,y : sta $00
sep #$30
sta $a0
; set position and everything else based on target door type
txa : and #$01 : eor #$01 : sta $07
; should be the same as lda $0462 : and #$04 : lsr #2 : eor #$01 : sta $07
lda $01 : and #$80 : beq .notEdge
lda $07 : sta $03 : beq +
lda $01 : jsr LoadSouthMidpoint : sta $22 : lda #$e0
bra ++
+
lda $01 : jsr LoadNorthMidpoint : sta $22 : lda #$1b
++
sta $20
lda $01 : and #$20 : beq +
lda #$01
+
sta $02
stz $07
lda $01 : and #$10 : lsr #4
brl .layer
.notEdge
lda $01 : and #$03 : cmp #$03 : bne .normal
lda $01 : and #$30 : lsr #3 : tay
lda.w InroomStairsX,y : sta $22
lda.w InroomStairsX+1,y : sta $02
lda.w InroomStairsY+1,y : sta $03
lda.w InroomStairsY,y
ldy $07 : beq +
!add #$07
+
sta $20
%StonewallCheck($1b)
inc $07
lda $01 : and #$04 : lsr #2
bra .layer
.normal
lda $01 : sta $fe ; trap door
lda $07 : sta $03 : beq +
lda #$e0
ldy $a0 : cpy #$51 : bne ++ ; special fix for throne room
!sub #$18
bra ++
+
%StonewallCheck($43)
lda #$1b
++
sta $20
inc $07 : stz $02 : lda #$78 : sta $22
lda $01 : and #$03 : beq ++
cmp #$02 : !bge +
lda #$f8 : sta $22 : stz $07 : bra ++
+ inc $02
++
lda $01 : and #$04 : lsr #2
.layer
sta $ee
bne +
stz $0476
+
lda $02 : !sub $a9
beq .skipXQuad
sta $06 : !add $a9 : sta $a9
ldy #$00 : jsr ShiftQuadSimple
.skipXQuad
lda $aa : lsr : sta $06 : lda $03 : !sub $06
beq .skipYQuad
sta $06 : asl : !add $aa : sta $aa
ldy #$01 : jsr ShiftQuadSimple
.skipYQuad
ldy #$00 : jsr SetCamera ; horizontal camera
ldy #$01 : sty $07 : jsr SetCamera ; vertical camera
lda $20 : cmp #$e0 : bcc +
lda $e8 : bne +
lda #$10 : sta $e8 ; adjust vertical camera at bottom
+
jsr StairCleanup
ply : plx : plb ; pull the stuff we pushed
rts
}
ShiftQuadSimple: { ShiftQuadSimple: {
lda.w CoordIndex,y : tax lda.w CoordIndex,y : tax
lda $20,x : beq .skip lda $20,x : beq .skip

Binary file not shown.

View File

@@ -202,7 +202,7 @@
"intensity" : [ "intensity" : [
"Door Shuffle Intensity Level (default: %(default)s)", "Door Shuffle Intensity Level (default: %(default)s)",
"1: Shuffles normal doors and spiral staircases", "1: Shuffles normal doors and spiral staircases",
"2: And shuffles open edges and straight staircases", "2: And shuffles open edges and both types of straight staircases",
"3: And shuffles dungeon lobbies", "3: And shuffles dungeon lobbies",
"random: Picks one of those at random" "random: Picks one of those at random"
], ],

View File

@@ -60,7 +60,7 @@
"randomizer.dungeon.dungeonintensity": "Intensity Level", "randomizer.dungeon.dungeonintensity": "Intensity Level",
"randomizer.dungeon.dungeonintensity.1": "1: Normal Supertile and Spiral Stairs", "randomizer.dungeon.dungeonintensity.1": "1: Normal Supertile and Spiral Stairs",
"randomizer.dungeon.dungeonintensity.2": "2: Open Edges and Straight Stairs", "randomizer.dungeon.dungeonintensity.2": "2: Open Edges, Straight Stairs and In-Room Stairs",
"randomizer.dungeon.dungeonintensity.3": "3: Dungeon Lobbies", "randomizer.dungeon.dungeonintensity.3": "3: Dungeon Lobbies",
"randomizer.dungeon.dungeonintensity.random": "Random", "randomizer.dungeon.dungeonintensity.random": "Random",

View File

@@ -19,7 +19,7 @@
"random" "random"
], ],
"config": { "config": {
"width": 35 "width": 45
} }
}, },
"potshuffle": { "type": "checkbox" }, "potshuffle": { "type": "checkbox" },