Door pairing system initial pass complete
Sucessfully de-coupling of Big Key doors with dumb small key doors behind Added a bit to trap door fixer so that we can hit the 3rd door in the door list Added door list position info
This commit is contained in:
@@ -6,6 +6,7 @@ from collections import OrderedDict
|
||||
from _vendor.collections_extended import bag
|
||||
from Utils import int16_as_bytes
|
||||
from Tables import normal_offset_table, spiral_offset_table
|
||||
from RoomData import Room
|
||||
|
||||
class World(object):
|
||||
|
||||
@@ -83,6 +84,7 @@ class World(object):
|
||||
self.spoiler = Spoiler(self)
|
||||
self.lamps_needed_for_dark_rooms = 1
|
||||
self.doors = []
|
||||
self.paired_doors = {}
|
||||
self.rooms = []
|
||||
|
||||
def intialize_regions(self):
|
||||
@@ -154,6 +156,15 @@ class World(object):
|
||||
return door
|
||||
return None
|
||||
|
||||
def get_room(self, room_idx, player):
|
||||
if isinstance(room_idx, Room):
|
||||
return room_idx
|
||||
|
||||
for room in self.rooms:
|
||||
if room.index == room_idx and room.player == player:
|
||||
return room
|
||||
raise RuntimeError('No such room %s' % room_idx)
|
||||
|
||||
def get_all_state(self, keys=False):
|
||||
ret = CollectionState(self)
|
||||
|
||||
@@ -846,12 +857,13 @@ class Door(object):
|
||||
self.doorIndex = doorIndex
|
||||
self.layer = layer # 0 for normal floor, 1 for the inset layer
|
||||
self.toggle = toggle
|
||||
self.trap = 0x0
|
||||
self.trapFlag = 0x0
|
||||
self.quadrant = 2
|
||||
self.shiftX = 78
|
||||
self.shiftY = 78
|
||||
self.zeroHzCam = False
|
||||
self.zeroVtCam = False
|
||||
self.doorListPos = -1
|
||||
|
||||
# logical properties
|
||||
# self.connected = False # combine with Dest?
|
||||
@@ -870,7 +882,7 @@ class Door(object):
|
||||
def getTarget(self, toggle):
|
||||
if self.type == DoorType.Normal:
|
||||
bitmask = 4 * (self.layer ^ 1 if toggle else self.layer)
|
||||
bitmask += 0x08 * int(self.trap)
|
||||
bitmask += 0x08 * int(self.trapFlag)
|
||||
return [self.roomIndex, bitmask + self.doorIndex]
|
||||
if self.type == DoorType.SpiralStairs:
|
||||
bitmask = int(self.layer) << 2
|
||||
@@ -887,16 +899,20 @@ class Door(object):
|
||||
self.bigKey = True
|
||||
return self
|
||||
|
||||
def toggle(self):
|
||||
def toggler(self):
|
||||
self.toggle = True
|
||||
return self
|
||||
|
||||
def blocked(self):
|
||||
def no_exit(self):
|
||||
self.blocked = True
|
||||
return self
|
||||
|
||||
def trap(self, trapFlag):
|
||||
self.trap = trapFlag
|
||||
self.trapFlag = trapFlag
|
||||
return self
|
||||
|
||||
def pos(self, pos):
|
||||
self.doorListPos = pos
|
||||
return self
|
||||
|
||||
def __str__(self):
|
||||
|
||||
@@ -5,6 +5,7 @@ import logging
|
||||
from BaseClasses import RegionType, DoorType, Direction, Sector, pol_idx
|
||||
from Dungeons import hyrule_castle_regions, eastern_regions, desert_regions, hera_regions, tower_regions
|
||||
from Dungeons import dungeon_regions
|
||||
from RoomData import DoorKind, PairedDoor
|
||||
|
||||
def link_doors(world, player):
|
||||
|
||||
@@ -155,6 +156,47 @@ def connect_one_way(world, entrancename, exitname, player):
|
||||
y.dest = x
|
||||
|
||||
|
||||
def fix_big_key_doors_with_ugly_smalls(world, player):
|
||||
remove_ugly_small_key_doors(world, player)
|
||||
unpair_big_key_doors(world, player)
|
||||
|
||||
|
||||
def remove_ugly_small_key_doors(world, player):
|
||||
for d in ['Eastern Compass Area SW', 'Eastern Darkness S']:
|
||||
door = world.get_door(d, player)
|
||||
room = world.get_room(door.roomIndex, player)
|
||||
room.change(door.doorListPos, DoorKind.Normal)
|
||||
door.smallKey = False
|
||||
door.ugly = False
|
||||
|
||||
|
||||
def unpair_big_key_doors(world, player):
|
||||
problematic_bk_doors = ['Eastern Courtyard N', 'Eastern Big Key NE']
|
||||
for paired_door in world.paired_doors[player]:
|
||||
if paired_door.door_a in problematic_bk_doors or paired_door.door_b in problematic_bk_doors:
|
||||
paired_door.pair = False
|
||||
|
||||
|
||||
def pair_existing_key_doors(world, player, door_a, door_b):
|
||||
already_paired = False
|
||||
door_names = [door_a.name, door_b.name]
|
||||
for pd in world.paired_doors[player]:
|
||||
if pd.door_a in door_names and pd.door_b in door_names:
|
||||
already_paired = True
|
||||
break
|
||||
if already_paired:
|
||||
return
|
||||
for paired_door in world.paired_doors[player]:
|
||||
if paired_door.door_a in door_names or paired_door.door_b in door_names:
|
||||
paired_door.pair = False
|
||||
world.paired_doors[player].append(PairedDoor(door_a, door_b))
|
||||
|
||||
|
||||
# def unpair_all_doors(world, player):
|
||||
# for paired_door in world.paired_doors[player]:
|
||||
# paired_door.pair = False
|
||||
|
||||
|
||||
def within_dungeon(world, player):
|
||||
# TODO: The "starts" regions need access logic
|
||||
# Aerinon's note: I think this is handled already by ER Rules - may need to check correct requirements
|
||||
@@ -350,6 +392,7 @@ def cross_dungeon(world, player):
|
||||
|
||||
|
||||
def experiment(world, player):
|
||||
fix_big_key_doors_with_ugly_smalls(world, player)
|
||||
hc = convert_to_sectors(dungeon_regions['Hyrule Castle'], world, player)
|
||||
ep = convert_to_sectors(dungeon_regions['Eastern'], world, player)
|
||||
dp = convert_to_sectors(dungeon_regions['Desert'], world, player)
|
||||
|
||||
176
Doors.py
176
Doors.py
@@ -1,5 +1,6 @@
|
||||
|
||||
from BaseClasses import Door, DoorType, Direction
|
||||
from RoomData import PairedDoor
|
||||
|
||||
# constants
|
||||
# door offsets
|
||||
@@ -26,25 +27,25 @@ LTL = 3 # Low to Low 11
|
||||
def create_doors(world, player):
|
||||
world.doors += [
|
||||
# hyrule castle
|
||||
toggle(create_dir_door(player, 'Hyrule Castle Lobby W', DoorType.Normal, Direction.West, 0x61, Mid, High)),
|
||||
toggle(create_dir_door(player, 'Hyrule Castle Lobby E', DoorType.Normal, Direction.East, 0x61, Mid, High)),
|
||||
create_dir_door(player, 'Hyrule Castle Lobby WN', DoorType.Normal, Direction.West, 0x61, Top, High),
|
||||
toggle(create_dir_door(player, 'Hyrule Castle Lobby W', DoorType.Normal, Direction.West, 0x61, Mid, High)).pos(6),
|
||||
toggle(create_dir_door(player, 'Hyrule Castle Lobby E', DoorType.Normal, Direction.East, 0x61, Mid, High)).pos(2),
|
||||
create_dir_door(player, 'Hyrule Castle Lobby WN', DoorType.Normal, Direction.West, 0x61, Top, High).pos(0),
|
||||
create_dir_door(player, 'Hyrule Castle Lobby North Stairs', DoorType.StraightStairs, Direction.North, 0x61, Mid, High),
|
||||
toggle(create_dir_door(player, 'Hyrule Castle West Lobby E', DoorType.Normal, Direction.East, 0x60, Mid, Low)),
|
||||
create_dir_door(player, 'Hyrule Castle West Lobby N', DoorType.Normal, Direction.North, 0x60, Right, Low),
|
||||
create_dir_door(player, 'Hyrule Castle West Lobby EN', DoorType.Normal, Direction.East, 0x60, Top, High),
|
||||
toggle(create_dir_door(player, 'Hyrule Castle East Lobby W', DoorType.Normal, Direction.West, 0x62, Mid, Low)),
|
||||
create_dir_door(player, 'Hyrule Castle East Lobby N', DoorType.Normal, Direction.North, 0x62, Mid, High),
|
||||
create_dir_door(player, 'Hyrule Castle East Lobby NW', DoorType.Normal, Direction.North, 0x62, Left, Low),
|
||||
create_dir_door(player, 'Hyrule Castle East Hall W', DoorType.Normal, Direction.West, 0x52, Top, Low),
|
||||
create_dir_door(player, 'Hyrule Castle East Hall S', DoorType.Normal, Direction.South, 0x52, Mid, High),
|
||||
create_dir_door(player, 'Hyrule Castle East Hall SW', DoorType.Normal, Direction.South, 0x52, Left, Low),
|
||||
create_dir_door(player, 'Hyrule Castle West Hall E', DoorType.Normal, Direction.East, 0x50, Top, Low),
|
||||
create_dir_door(player, 'Hyrule Castle West Hall S', DoorType.Normal, Direction.South, 0x50, Right, Low),
|
||||
create_dir_door(player, 'Hyrule Castle Back Hall W', DoorType.Normal, Direction.West, 0x01, Top, Low),
|
||||
create_dir_door(player, 'Hyrule Castle Back Hall E', DoorType.Normal, Direction.East, 0x01, Top, Low),
|
||||
toggle(create_dir_door(player, 'Hyrule Castle West Lobby E', DoorType.Normal, Direction.East, 0x60, Mid, Low)).pos(1),
|
||||
create_dir_door(player, 'Hyrule Castle West Lobby N', DoorType.Normal, Direction.North, 0x60, Right, Low).pos(0),
|
||||
create_dir_door(player, 'Hyrule Castle West Lobby EN', DoorType.Normal, Direction.East, 0x60, Top, High).pos(3),
|
||||
toggle(create_dir_door(player, 'Hyrule Castle East Lobby W', DoorType.Normal, Direction.West, 0x62, Mid, Low)).pos(0),
|
||||
create_dir_door(player, 'Hyrule Castle East Lobby N', DoorType.Normal, Direction.North, 0x62, Mid, High).pos(3),
|
||||
create_dir_door(player, 'Hyrule Castle East Lobby NW', DoorType.Normal, Direction.North, 0x62, Left, Low).pos(2),
|
||||
create_dir_door(player, 'Hyrule Castle East Hall W', DoorType.Normal, Direction.West, 0x52, Top, Low).pos(0),
|
||||
create_dir_door(player, 'Hyrule Castle East Hall S', DoorType.Normal, Direction.South, 0x52, Mid, High).pos(2),
|
||||
create_dir_door(player, 'Hyrule Castle East Hall SW', DoorType.Normal, Direction.South, 0x52, Left, Low).pos(1),
|
||||
create_dir_door(player, 'Hyrule Castle West Hall E', DoorType.Normal, Direction.East, 0x50, Top, Low).pos(0),
|
||||
create_dir_door(player, 'Hyrule Castle West Hall S', DoorType.Normal, Direction.South, 0x50, Right, Low).pos(1),
|
||||
create_dir_door(player, 'Hyrule Castle Back Hall W', DoorType.Normal, Direction.West, 0x01, Top, Low).pos(0),
|
||||
create_dir_door(player, 'Hyrule Castle Back Hall E', DoorType.Normal, Direction.East, 0x01, Top, Low).pos(1),
|
||||
create_spiral_stairs(player, 'Hyrule Castle Back Hall Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x01, 0, HTL, A, 0x2a, 0x00),
|
||||
create_dir_door(player, 'Hyrule Castle Throne Room N', DoorType.Normal, Direction.North, 0x51, Mid, High),
|
||||
create_dir_door(player, 'Hyrule Castle Throne Room N', DoorType.Normal, Direction.North, 0x51, Mid, High).pos(1),
|
||||
create_dir_door(player, 'Hyrule Castle Throne Room South Stairs', DoorType.StraightStairs, Direction.South, 0x51, Mid, Low),
|
||||
|
||||
# hyrule dungeon level
|
||||
@@ -60,8 +61,8 @@ def create_doors(world, player):
|
||||
create_dir_door(player, 'Hyrule Dungeon South Abyss Catwalk West Edge', DoorType.Open, Direction.West, 0x82, None, High),
|
||||
create_dir_door(player, 'Hyrule Dungeon Guardroom Catwalk Edge', DoorType.Open, Direction.East, 0x81, None, High),
|
||||
create_dir_door(player, 'Hyrule Dungeon Guardroom Abyss Edge', DoorType.Open, Direction.West, 0x81, None, High),
|
||||
create_dir_door(player, 'Hyrule Dungeon Guardroom N', DoorType.Normal, Direction.North, 0x81, Left, Low),
|
||||
trap(create_dir_door(player, 'Hyrule Dungeon Armory S', DoorType.Normal, Direction.South, 0x71, Left, Low), 0x1),
|
||||
create_dir_door(player, 'Hyrule Dungeon Guardroom N', DoorType.Normal, Direction.North, 0x81, Left, Low).pos(0),
|
||||
trap(create_dir_door(player, 'Hyrule Dungeon Armory S', DoorType.Normal, Direction.South, 0x71, Left, Low), 0x2).pos(1),
|
||||
small_key(create_dir_door(player, 'Hyrule Dungeon Armory Interior Key Door N', DoorType.Interior, Direction.North, 0x71, Left, High)),
|
||||
small_key(create_dir_door(player, 'Hyrule Dungeon Armory Interior Key Door S', DoorType.Interior, Direction.South, 0x71, Left, High)),
|
||||
create_spiral_stairs(player, 'Hyrule Dungeon Armory Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x71, 0, HTL, A, 0x11, 0xa8, True),
|
||||
@@ -70,60 +71,60 @@ def create_doors(world, player):
|
||||
create_spiral_stairs(player, 'Hyrule Dungeon Cellblock Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x80, 0, HTH, A, 0x1a, 0x44),
|
||||
|
||||
# sewers
|
||||
trap(blocked(create_dir_door(player, 'Sewers Behind Tapestry S', DoorType.Normal, Direction.South, 0x41, Mid, High)), 0x2),
|
||||
trap(blocked(create_dir_door(player, 'Sewers Behind Tapestry S', DoorType.Normal, Direction.South, 0x41, Mid, High)), 0x4).pos(0),
|
||||
create_spiral_stairs(player, 'Sewers Behind Tapestry Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x41, 0, HTH, S, 0x12, 0xb0),
|
||||
create_spiral_stairs(player, 'Sewers Rope Room Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x42, 0, HTH, S, 0x1b, 0x9c),
|
||||
create_dir_door(player, 'Sewers Rope Room North Stairs', DoorType.StraightStairs, Direction.North, 0x42, Mid, High),
|
||||
create_dir_door(player, 'Sewers Dark Cross South Stairs', DoorType.StraightStairs, Direction.South, 0x32, Mid, High),
|
||||
small_key(create_dir_door(player, 'Sewers Dark Cross Key Door N', DoorType.Normal, Direction.North, 0x32, Mid, High)),
|
||||
small_key(create_dir_door(player, 'Sewers Dark Cross Key Door S', DoorType.Normal, Direction.South, 0x22, Mid, High)),
|
||||
create_dir_door(player, 'Sewers Water W', DoorType.Normal, Direction.West, 0x22, Bot, High),
|
||||
create_dir_door(player, 'Sewers Key Rat E', DoorType.Normal, Direction.East, 0x21, Bot, High),
|
||||
small_key(create_dir_door(player, 'Sewers Key Rat Key Door N', DoorType.Normal, Direction.North, 0x21, Right, High)),
|
||||
small_key(create_dir_door(player, 'Sewers Secret Room Key Door S', DoorType.Normal, Direction.South, 0x11, Right, High)),
|
||||
small_key(create_dir_door(player, 'Sewers Dark Cross Key Door N', DoorType.Normal, Direction.North, 0x32, Mid, High)).pos(0),
|
||||
small_key(create_dir_door(player, 'Sewers Dark Cross Key Door S', DoorType.Normal, Direction.South, 0x22, Mid, High)).pos(0),
|
||||
create_dir_door(player, 'Sewers Water W', DoorType.Normal, Direction.West, 0x22, Bot, High).pos(1),
|
||||
create_dir_door(player, 'Sewers Key Rat E', DoorType.Normal, Direction.East, 0x21, Bot, High).pos(1),
|
||||
small_key(create_dir_door(player, 'Sewers Key Rat Key Door N', DoorType.Normal, Direction.North, 0x21, Right, High)).pos(0),
|
||||
small_key(create_dir_door(player, 'Sewers Secret Room Key Door S', DoorType.Normal, Direction.South, 0x11, Right, High)).pos(2),
|
||||
create_door(player, 'Sewers Secret Room Push Block', DoorType.Logical),
|
||||
create_spiral_stairs(player, 'Sewers Secret Room Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x11, 0, LTH, S, 0x33, 0x6c, True),
|
||||
create_spiral_stairs(player, 'Sewers Pull Switch Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x02, 0, HTL, S, 0x12, 0x80),
|
||||
trap(toggle(create_dir_door(player, 'Sewers Pull Switch S', DoorType.Normal, Direction.South, 0x02, Mid, Low)), 0x2),
|
||||
trap(toggle(create_dir_door(player, 'Sewers Pull Switch S', DoorType.Normal, Direction.South, 0x02, Mid, Low)), 0x4).pos(0),
|
||||
# logically one way the sanc, but should be linked - also toggle
|
||||
toggle(blocked(create_dir_door(player, 'Sanctuary N', DoorType.Normal, Direction.North, 0x12, Mid, High))),
|
||||
toggle(blocked(create_dir_door(player, 'Sanctuary N', DoorType.Normal, Direction.North, 0x12, Mid, High))).pos(0),
|
||||
|
||||
# Eastern Palace
|
||||
create_dir_door(player, 'Eastern Lobby N', DoorType.Normal, Direction.North, 0xc9, Mid, High),
|
||||
create_dir_door(player, 'Eastern Cannonball S', DoorType.Normal, Direction.South, 0xb9, Mid, High),
|
||||
create_dir_door(player, 'Eastern Cannonball N', DoorType.Normal, Direction.North, 0xb9, Mid, High),
|
||||
create_dir_door(player, 'Eastern Cannonball Ledge WN', DoorType.Normal, Direction.West, 0xb9, Top, High),
|
||||
small_key(create_dir_door(player, 'Eastern Cannonball Ledge Key Door EN', DoorType.Normal, Direction.East, 0xb9, Top, High)),
|
||||
create_dir_door(player, 'Eastern Courtyard Ledge S', DoorType.Normal, Direction.South, 0xa9, Mid, High),
|
||||
trap(create_dir_door(player, 'Eastern Courtyard Ledge W', DoorType.Normal, Direction.West, 0xa9, Mid, High), 0x2),
|
||||
trap(create_dir_door(player, 'Eastern Courtyard Ledge E', DoorType.Normal, Direction.East, 0xa9, Mid, High), 0x1),
|
||||
create_dir_door(player, 'Eastern Map Area W', DoorType.Normal, Direction.West, 0xaa, Mid, High),
|
||||
create_dir_door(player, 'Eastern Compass Area E', DoorType.Normal, Direction.East, 0xa8, Mid, High),
|
||||
create_dir_door(player, 'Eastern Compass Area EN', DoorType.Normal, Direction.East, 0xa8, Top, Low),
|
||||
ugly_door(small_key(create_dir_door(player, 'Eastern Compass Area SW', DoorType.Normal, Direction.South, 0xa8, Right, High))),
|
||||
create_dir_door(player, 'Eastern Lobby N', DoorType.Normal, Direction.North, 0xc9, Mid, High).pos(1),
|
||||
create_dir_door(player, 'Eastern Cannonball S', DoorType.Normal, Direction.South, 0xb9, Mid, High).pos(2),
|
||||
create_dir_door(player, 'Eastern Cannonball N', DoorType.Normal, Direction.North, 0xb9, Mid, High).pos(1),
|
||||
create_dir_door(player, 'Eastern Cannonball Ledge WN', DoorType.Normal, Direction.West, 0xb9, Top, High).pos(3),
|
||||
small_key(create_dir_door(player, 'Eastern Cannonball Ledge Key Door EN', DoorType.Normal, Direction.East, 0xb9, Top, High)).pos(0),
|
||||
create_dir_door(player, 'Eastern Courtyard Ledge S', DoorType.Normal, Direction.South, 0xa9, Mid, High).pos(5),
|
||||
trap(create_dir_door(player, 'Eastern Courtyard Ledge W', DoorType.Normal, Direction.West, 0xa9, Mid, High), 0x4).pos(0),
|
||||
trap(create_dir_door(player, 'Eastern Courtyard Ledge E', DoorType.Normal, Direction.East, 0xa9, Mid, High), 0x2).pos(1),
|
||||
create_dir_door(player, 'Eastern Map Area W', DoorType.Normal, Direction.West, 0xaa, Mid, High).pos(4),
|
||||
create_dir_door(player, 'Eastern Compass Area E', DoorType.Normal, Direction.East, 0xa8, Mid, High).pos(5),
|
||||
create_dir_door(player, 'Eastern Compass Area EN', DoorType.Normal, Direction.East, 0xa8, Top, Low).pos(4),
|
||||
ugly_door(small_key(create_dir_door(player, 'Eastern Compass Area SW', DoorType.Normal, Direction.South, 0xa8, Right, High))).pos(2),
|
||||
create_door(player, 'Eastern Hint Tile Push Block', DoorType.Logical),
|
||||
create_dir_door(player, 'Eastern Courtyard WN', DoorType.Normal, Direction.West, 0xa9, Top, Low),
|
||||
create_dir_door(player, 'Eastern Courtyard EN', DoorType.Normal, Direction.East, 0xa9, Top, Low),
|
||||
big_key(create_dir_door(player, 'Eastern Courtyard N', DoorType.Normal, Direction.North, 0xa9, Mid, High)),
|
||||
create_dir_door(player, 'Eastern Courtyard WN', DoorType.Normal, Direction.West, 0xa9, Top, Low).pos(3),
|
||||
create_dir_door(player, 'Eastern Courtyard EN', DoorType.Normal, Direction.East, 0xa9, Top, Low).pos(4),
|
||||
big_key(create_dir_door(player, 'Eastern Courtyard N', DoorType.Normal, Direction.North, 0xa9, Mid, High)).pos(2),
|
||||
create_door(player, 'Eastern Courtyard Potholes', DoorType.Hole),
|
||||
create_door(player, 'Eastern Fairies\' Warp', DoorType.Warp),
|
||||
create_dir_door(player, 'Eastern Map Valley WN', DoorType.Normal, Direction.West, 0xaa, Top, Low),
|
||||
create_dir_door(player, 'Eastern Map Valley SW', DoorType.Normal, Direction.South, 0xaa, Left, High),
|
||||
create_dir_door(player, 'Eastern Dark Square NW', DoorType.Normal, Direction.North, 0xba, Left, High),
|
||||
small_key(create_dir_door(player, 'Eastern Dark Square Key Door WN', DoorType.Normal, Direction.West, 0xba, Top, High)),
|
||||
create_dir_door(player, 'Eastern Big Key EN', DoorType.Normal, Direction.East, 0xb8, Top, High),
|
||||
big_key(create_dir_door(player, 'Eastern Big Key NE', DoorType.Normal, Direction.North, 0xb8, Right, High)),
|
||||
ugly_door(small_key(create_dir_door(player, 'Eastern Darkness S', DoorType.Normal, Direction.South, 0x99, Mid, High))),
|
||||
create_dir_door(player, 'Eastern Map Valley WN', DoorType.Normal, Direction.West, 0xaa, Top, Low).pos(1),
|
||||
create_dir_door(player, 'Eastern Map Valley SW', DoorType.Normal, Direction.South, 0xaa, Left, High).pos(5),
|
||||
create_dir_door(player, 'Eastern Dark Square NW', DoorType.Normal, Direction.North, 0xba, Left, High).pos(1),
|
||||
small_key(create_dir_door(player, 'Eastern Dark Square Key Door WN', DoorType.Normal, Direction.West, 0xba, Top, High)).pos(0),
|
||||
create_dir_door(player, 'Eastern Big Key EN', DoorType.Normal, Direction.East, 0xb8, Top, High).pos(1),
|
||||
big_key(create_dir_door(player, 'Eastern Big Key NE', DoorType.Normal, Direction.North, 0xb8, Right, High)).pos(0),
|
||||
ugly_door(small_key(create_dir_door(player, 'Eastern Darkness S', DoorType.Normal, Direction.South, 0x99, Mid, High))).pos(1),
|
||||
# Up is a keydoor and down is not. Only the up stairs should be considered a key door for now.
|
||||
# Todo: add key door?
|
||||
small_key(create_spiral_stairs(player, 'Eastern Darkness Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x99, 0, HTH, Z, 0x1a, 0x6c, False, True)),
|
||||
ugly_door(create_spiral_stairs(player, 'Eastern Attic Start Down Stairs', DoorType.SpiralStairs, Direction.Down, 0xda, 0, HTH, Z, 0x11, 0x80, False, True)),
|
||||
create_dir_door(player, 'Eastern Attic Start WS', DoorType.Normal, Direction.West, 0xda, Bot, High),
|
||||
create_dir_door(player, 'Eastern Attic Switches ES', DoorType.Normal, Direction.East, 0xd9, Bot, High),
|
||||
create_dir_door(player, 'Eastern Attic Switches WS', DoorType.Normal, Direction.West, 0xd9, Bot, High),
|
||||
create_dir_door(player, 'Eastern Eyegores ES', DoorType.Normal, Direction.East, 0xd8, Bot, High),
|
||||
create_dir_door(player, 'Eastern Eyegores NE', DoorType.Normal, Direction.North, 0xd8, Right, High),
|
||||
trap(blocked(create_dir_door(player, 'Eastern Boss SE', DoorType.Normal, Direction.South, 0xc8, Right, High)), 0x2),
|
||||
ugly_door(create_spiral_stairs(player, 'Eastern Attic Start Down Stairs', DoorType.SpiralStairs, Direction.Down, 0xda, 0, HTH, Z, 0x11, 0x80, True, True)),
|
||||
create_dir_door(player, 'Eastern Attic Start WS', DoorType.Normal, Direction.West, 0xda, Bot, High).pos(0),
|
||||
create_dir_door(player, 'Eastern Attic Switches ES', DoorType.Normal, Direction.East, 0xd9, Bot, High).trap(0x1).pos(2),
|
||||
create_dir_door(player, 'Eastern Attic Switches WS', DoorType.Normal, Direction.West, 0xd9, Bot, High).trap(0x4).pos(0),
|
||||
create_dir_door(player, 'Eastern Eyegores ES', DoorType.Normal, Direction.East, 0xd8, Bot, High).pos(2),
|
||||
create_dir_door(player, 'Eastern Eyegores NE', DoorType.Normal, Direction.North, 0xd8, Right, High).trap(0x4).pos(0),
|
||||
trap(blocked(create_dir_door(player, 'Eastern Boss SE', DoorType.Normal, Direction.South, 0xc8, Right, High)), 0x4).pos(0),
|
||||
|
||||
# Desert Palace
|
||||
create_dir_door(player, 'Desert Main Lobby NW Edge', DoorType.Open, Direction.North, 0x84, None, High),
|
||||
@@ -137,8 +138,8 @@ def create_doors(world, player):
|
||||
create_dir_door(player, 'Desert East Wing ES', DoorType.Interior, Direction.East, 0x85, Bot, High),
|
||||
small_key(create_dir_door(player, 'Desert East Wing Key Door EN', DoorType.Interior, Direction.East, 0x85, Top, High)),
|
||||
small_key(create_dir_door(player, 'Desert Compass Key Door WN', DoorType.Interior, Direction.West, 0x85, Top, High)),
|
||||
trap(create_dir_door(player, 'Desert Compass NW', DoorType.Normal, Direction.North, 0x85, Left, High), 0x2),
|
||||
create_dir_door(player, 'Desert Cannonball S', DoorType.Normal, Direction.South, 0x75, Left, High),
|
||||
trap(create_dir_door(player, 'Desert Compass NW', DoorType.Normal, Direction.North, 0x85, Left, High), 0x4).pos(0),
|
||||
create_dir_door(player, 'Desert Cannonball S', DoorType.Normal, Direction.South, 0x75, Left, High).pos(1),
|
||||
create_dir_door(player, 'Desert Arrow Pot Corner S Edge', DoorType.Open, Direction.South, 0x75, None, High),
|
||||
create_dir_door(player, 'Desert Arrow Pot Corner W Edge', DoorType.Open, Direction.West, 0x75, None, High),
|
||||
create_dir_door(player, 'Desert North Hall SE Edge', DoorType.Open, Direction.South, 0x74, None, High),
|
||||
@@ -170,14 +171,14 @@ def create_doors(world, player):
|
||||
create_dir_door(player, 'Desert Four Statues NW', DoorType.Interior, Direction.North, 0x53, Left, High),
|
||||
create_dir_door(player, 'Desert Four Statues ES', DoorType.Interior, Direction.East, 0x53, Bot, High),
|
||||
create_dir_door(player, 'Desert Beamos Hall WS', DoorType.Interior, Direction.West, 0x53, Bot, High),
|
||||
small_key(create_dir_door(player, 'Desert Beamos Hall NE', DoorType.Normal, Direction.North, 0x53, Right, High)),
|
||||
small_key(create_dir_door(player, 'Desert Tiles 2 SE', DoorType.Normal, Direction.South, 0x43, Right, High)),
|
||||
small_key(create_dir_door(player, 'Desert Beamos Hall NE', DoorType.Normal, Direction.North, 0x53, Right, High)).pos(2),
|
||||
small_key(create_dir_door(player, 'Desert Tiles 2 SE', DoorType.Normal, Direction.South, 0x43, Right, High)).pos(2),
|
||||
create_dir_door(player, 'Desert Tiles 2 NE', DoorType.Interior, Direction.North, 0x43, Right, High),
|
||||
create_dir_door(player, 'Desert Wall Slide SE', DoorType.Interior, Direction.South, 0x43, Right, High),
|
||||
# todo: we need a new flag for a door that has a wall on it - you have to traverse it one particular way first
|
||||
# the above is not a problem until we get to crossed mode
|
||||
big_key(create_dir_door(player, 'Desert Wall Slide NW', DoorType.Normal, Direction.North, 0x43, Left, High)),
|
||||
trap(blocked(create_dir_door(player, 'Desert Boss SW', DoorType.Normal, Direction.South, 0x33, Left, High)), 0x2),
|
||||
big_key(create_dir_door(player, 'Desert Wall Slide NW', DoorType.Normal, Direction.North, 0x43, Left, High)).pos(0),
|
||||
trap(blocked(create_dir_door(player, 'Desert Boss SW', DoorType.Normal, Direction.South, 0x33, Left, High)), 0x4).pos(0),
|
||||
|
||||
# Hera
|
||||
create_spiral_stairs(player, 'Hera Lobby Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x77, 3, HTL, Z, 0x21, 0x90, False, True),
|
||||
@@ -247,8 +248,51 @@ def create_doors(world, player):
|
||||
create_dir_door(player, 'Tower Antechamber South Stairs', DoorType.StraightStairs, Direction.South, 0x30, Left, High),
|
||||
create_dir_door(player, 'Tower Antechamber NW', DoorType.Interior, Direction.North, 0x30, Left, High),
|
||||
create_dir_door(player, 'Tower Altar SW', DoorType.Interior, Direction.South, 0x30, Left, High),
|
||||
create_dir_door(player, 'Tower Altar NW', DoorType.Normal, Direction.North, 0x30, Left, High),
|
||||
create_dir_door(player, 'Tower Agahnim 1 SW', DoorType.Normal, Direction.South, 0x20, Left, High).blocked().trap(0x2),
|
||||
create_dir_door(player, 'Tower Altar NW', DoorType.Normal, Direction.North, 0x30, Left, High).pos(0),
|
||||
create_dir_door(player, 'Tower Agahnim 1 SW', DoorType.Normal, Direction.South, 0x20, Left, High).no_exit().trap(0x4).pos(0),
|
||||
]
|
||||
create_paired_doors(world, player)
|
||||
|
||||
|
||||
def create_paired_doors(world, player):
|
||||
world.paired_doors[player] = [
|
||||
PairedDoor('Sewers Secret Room Key Door S', 'Sewers Key Rat Key Door N'),
|
||||
# PairedDoor('', ''), # TR Pokey Key
|
||||
# PairedDoor('', ''), # TR Big key door by pipes
|
||||
# PairedDoor('', ''), # Pod Dark maze door
|
||||
# PairedDoor('', ''), # PoD Bombable by Big Chest
|
||||
# PairedDoor('', ''), # Pod key door by bridge
|
||||
PairedDoor('Sewers Dark Cross Key Door N', 'Sewers Dark Cross Key Door S'),
|
||||
# PairedDoor('', ''), # Swamp key door above big chest
|
||||
# PairedDoor('', ''), # Pod bombable by arena
|
||||
# PairedDoor('', ''), # Swamp bombable to random pots
|
||||
# PairedDoor('', ''), # Swamp bombable to map chest
|
||||
# PairedDoor('', ''), # Swamp key door early room $38
|
||||
# PairedDoor('', ''), # Pod front key door
|
||||
# PairedDoor('', ''), # GT moldorm key door
|
||||
# PairedDoor('', ''), # Ice BJ key door
|
||||
PairedDoor('Desert Tiles 2 SE', 'Desert Beamos Hall NE'),
|
||||
# PairedDoor('', ''), # Skull 3 key door
|
||||
# PairedDoor('', ''), # Skull 1 key door - pot prison to big chest
|
||||
# PairedDoor('', ''), # Skull 1 - pinball key door
|
||||
# PairedDoor('', ''), # gt main big key door
|
||||
# PairedDoor('', ''), # ice door to spike chest
|
||||
# PairedDoor('', ''), # gt right side key door to cape bridge
|
||||
# PairedDoor('', ''), # gt bombable to rando room
|
||||
# PairedDoor('', ''), # ice's big icy room key door to lonely freezor
|
||||
PairedDoor('Eastern Courtyard N', 'Eastern Darkness S'),
|
||||
# PairedDoor('', ''), # mire fishbone key door
|
||||
# PairedDoor('', ''), # mire big key door to bridges
|
||||
PairedDoor('Eastern Big Key NE', 'Eastern Compass Area SW'),
|
||||
# PairedDoor('', ''), # TR somaria hub to pokey
|
||||
PairedDoor('Eastern Dark Square Key Door WN', 'Eastern Cannonball Ledge Key Door EN'),
|
||||
# PairedDoor('', ''), # TT random bomb to pots
|
||||
# PairedDoor('', ''), # TT big key door
|
||||
# PairedDoor('', ''), # Ice last key door to crystal switch
|
||||
# PairedDoor('', ''), # mire hub key door to attic
|
||||
# PairedDoor('', ''), # mire hub key door to map
|
||||
# PairedDoor('', ''), # tr last key door to switch maze
|
||||
# PairedDoor('', '') # TT dashable above
|
||||
]
|
||||
|
||||
|
||||
@@ -288,7 +332,7 @@ def big_key(door):
|
||||
|
||||
|
||||
def trap(door, trapFlag):
|
||||
door.trap = trapFlag
|
||||
door.trapFlag = trapFlag
|
||||
return door
|
||||
|
||||
|
||||
|
||||
3
Main.py
3
Main.py
@@ -14,6 +14,7 @@ from EntranceShuffle import link_entrances, link_inverted_entrances
|
||||
from Doors import create_doors
|
||||
from DoorShuffle import link_doors
|
||||
from Rom import patch_rom, get_enemizer_patch, apply_rom_settings, Sprite, LocalRom, JsonRom
|
||||
from RoomData import create_rooms
|
||||
from Rules import set_rules
|
||||
from Dungeons import create_dungeons, fill_dungeons, fill_dungeons_restrictive
|
||||
from Fill import distribute_items_cutoff, distribute_items_staleness, distribute_items_restrictive, flood_items, balance_multiworld_progression
|
||||
@@ -48,11 +49,13 @@ def main(args, seed=None):
|
||||
for player in range(1, world.players + 1):
|
||||
create_regions(world, player)
|
||||
create_doors(world, player)
|
||||
create_rooms(world, player)
|
||||
create_dungeons(world, player)
|
||||
else:
|
||||
for player in range(1, world.players + 1):
|
||||
create_inverted_regions(world, player) # todo: port all the dungeon region work
|
||||
create_doors(world, player)
|
||||
create_rooms(world, player)
|
||||
create_dungeons(world, player)
|
||||
|
||||
logger.info('Shuffling dungeons')
|
||||
|
||||
8
Rom.py
8
Rom.py
@@ -18,7 +18,7 @@ from EntranceShuffle import door_addresses
|
||||
|
||||
|
||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||
RANDOMIZERBASEHASH = '1d85b39d2745d745dc02d60b1380ae9f'
|
||||
RANDOMIZERBASEHASH = 'b26631cd0d874e979d660727cb3a1f58'
|
||||
|
||||
|
||||
class JsonRom(object):
|
||||
@@ -536,6 +536,12 @@ def patch_rom(world, player, rom):
|
||||
for door in world.doors:
|
||||
if door.dest is not None and door.player == player and door.type in [DoorType.Normal, DoorType.SpiralStairs]:
|
||||
rom.write_bytes(door.getAddress(), door.dest.getTarget(door.toggle))
|
||||
for room in world.rooms:
|
||||
if room.player == player and room.modified:
|
||||
rom.write_bytes(room.address(), room.rom_data())
|
||||
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_b(world, player), paired_door.rom_data_b(world, player))
|
||||
|
||||
write_custom_shops(rom, world, player)
|
||||
|
||||
|
||||
62
RoomData.py
62
RoomData.py
@@ -1,14 +1,15 @@
|
||||
from enum import Enum, unique
|
||||
from Tables import door_pair_offset_table
|
||||
|
||||
|
||||
def create_rooms(world, player):
|
||||
world.rooms = [
|
||||
Room(player, 0x01, 0x51168).door(Position.WestN2, DoorKind.Warp).door(Position.EastN2, DoorKind.Warp),
|
||||
Room(player, 0x02, 0x50b97).door(Position.South2, DoorKind.TrapTriggerableLow).door(Position.InteriorV2, DoorKind.NormalLow2).door(Position.South2, DoorKind.TrapLow),
|
||||
Room(player, 0x02, 0x50b97).door(Position.South2, DoorKind.TrapTriggerableLow).door(Position.InteriorV2, DoorKind.NormalLow2).door(Position.South2, DoorKind.ToggleFlag),
|
||||
# Room(player, 0x03, 0x509cf).door(Position.SouthW, DoorKind.CaveEntrance),
|
||||
Room(player, 0x04, 0xfe25c).door(Position.NorthW, DoorKind.StairKey2).door(Position.InteriorW, DoorKind.Dashable).door(Position.InteriorS, DoorKind.Dashable).door(Position.InteriorE, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.Normal),
|
||||
Room(player, 0x06, 0xfa192).door(Position.SouthW, DoorKind.Trap),
|
||||
# Room(player, 0x08, 0x5064f).door(Position.InteriorS2, DoorKind.CaveEntranceLow08).door(Position.SouthE, DoorKind.CaveEntrance).door(Position.SouthW2, DoorKind.NormalLow2).door(Position.SouthW2, DoorKind.TrapLow),
|
||||
# Room(player, 0x08, 0x5064f).door(Position.InteriorS2, DoorKind.CaveEntranceLow08).door(Position.SouthE, DoorKind.CaveEntrance).door(Position.SouthW2, DoorKind.NormalLow2).door(Position.SouthW2, DoorKind.ToggleFlag),
|
||||
Room(player, 0x0a, 0xfa734).door(Position.North, DoorKind.StairKey),
|
||||
Room(player, 0x0b, 0xfabf0).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.InteriorS, DoorKind.Trap2).door(Position.InteriorN, DoorKind.SmallKey),
|
||||
Room(player, 0x0c, 0xfef53).door(Position.South, DoorKind.DungeonEntrance),
|
||||
@@ -17,12 +18,12 @@ def create_rooms(world, player):
|
||||
|
||||
# Room(player, 0x10, 0x50596).door(Position.SouthW, DoorKind.DungeonEntrance).door(Position.InteriorS, DoorKind.Normal),
|
||||
Room(player, 0x11, 0x50c52).door(Position.InteriorN, DoorKind.Dashable).door(Position.InteriorS, DoorKind.Dashable).door(Position.SouthE, DoorKind.SmallKey),
|
||||
Room(player, 0x12, 0x50a9b).door(Position.North2, DoorKind.NormalLow).door(Position.North2, DoorKind.TrapLow).door(Position.South2, DoorKind.NormalLow).door(Position.South2, DoorKind.IncognitoEntrance),
|
||||
Room(player, 0x12, 0x50a9b).door(Position.North2, DoorKind.NormalLow).door(Position.North2, DoorKind.ToggleFlag).door(Position.South2, DoorKind.NormalLow).door(Position.South2, DoorKind.IncognitoEntrance),
|
||||
Room(player, 0x13, 0xfe29d).door(Position.EastS, DoorKind.SmallKey).door(Position.EastN, DoorKind.Normal),
|
||||
Room(player, 0x14, 0xfe464).door(Position.SouthE, DoorKind.SmallKey).door(Position.WestS, DoorKind.SmallKey).door(Position.NorthW, DoorKind.Normal).door(Position.WestN, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.EastN, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
|
||||
Room(player, 0x15, 0xfe63e).door(Position.WestS, DoorKind.Trap).door(Position.WestN, DoorKind.Normal),
|
||||
Room(player, 0x16, 0xfa150).door(Position.InteriorV, DoorKind.Bombable).door(Position.InteriorW, DoorKind.SmallKey).door(Position.InteriorE, DoorKind.Normal).door(Position.NorthW, DoorKind.Normal),
|
||||
# Room(player, 0x18, 0x506e5).door(Position.NorthW2, DoorKind.NormalLow).door(Position.NorthW2, DoorKind.TrapLow),
|
||||
# Room(player, 0x18, 0x506e5).door(Position.NorthW2, DoorKind.NormalLow).door(Position.NorthW2, DoorKind.ToggleFlag),
|
||||
Room(player, 0x19, 0xfacc6).door(Position.East, DoorKind.Bombable).door(Position.EastN, DoorKind.SmallKey),
|
||||
Room(player, 0x1a, 0xfa670).door(Position.InteriorE, DoorKind.SmallKey).door(Position.WestN, DoorKind.SmallKey).door(Position.West, DoorKind.Bombable).door(Position.SouthW, DoorKind.SmallKey).door(Position.InteriorN, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal),
|
||||
Room(player, 0x1b, 0xfab31).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.Normal),
|
||||
@@ -93,13 +94,13 @@ def create_rooms(world, player):
|
||||
Room(player, 0x5e, 0xfc6b8).door(Position.EastS, DoorKind.SmallKey).door(Position.InteriorE, DoorKind.Trap2).door(Position.SouthE, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal),
|
||||
Room(player, 0x5f, 0xfc6fa).door(Position.WestS, DoorKind.SmallKey),
|
||||
|
||||
Room(player, 0x60, 0x51309).door(Position.NorthE2, DoorKind.NormalLow2).door(Position.East2, DoorKind.NormalLow2).door(Position.East2, DoorKind.TrapLow).door(Position.EastN, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal).door(Position.SouthE, DoorKind.IncognitoEntrance),
|
||||
Room(player, 0x61, 0x51454).door(Position.West2, DoorKind.NormalLow).door(Position.West2, DoorKind.TrapLow).door(Position.East2, DoorKind.NormalLow).door(Position.East2, DoorKind.TrapLow).door(Position.South2, DoorKind.NormalLow).door(Position.South2, DoorKind.IncognitoEntrance).door(Position.WestN, DoorKind.Normal),
|
||||
Room(player, 0x62, 0x51577).door(Position.West2, DoorKind.NormalLow2).door(Position.West2, DoorKind.TrapLow).door(Position.NorthW2, DoorKind.NormalLow2).door(Position.North, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.SouthW, DoorKind.IncognitoEntrance),
|
||||
Room(player, 0x60, 0x51309).door(Position.NorthE2, DoorKind.NormalLow2).door(Position.East2, DoorKind.NormalLow2).door(Position.East2, DoorKind.ToggleFlag).door(Position.EastN, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal).door(Position.SouthE, DoorKind.IncognitoEntrance),
|
||||
Room(player, 0x61, 0x51454).door(Position.West2, DoorKind.NormalLow).door(Position.West2, DoorKind.ToggleFlag).door(Position.East2, DoorKind.NormalLow).door(Position.East2, DoorKind.ToggleFlag).door(Position.South2, DoorKind.NormalLow).door(Position.South2, DoorKind.IncognitoEntrance).door(Position.WestN, DoorKind.Normal),
|
||||
Room(player, 0x62, 0x51577).door(Position.West2, DoorKind.NormalLow2).door(Position.West2, DoorKind.ToggleFlag).door(Position.NorthW2, DoorKind.NormalLow2).door(Position.North, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.SouthW, DoorKind.IncognitoEntrance),
|
||||
Room(player, 0x63, 0xf88ed).door(Position.NorthE, DoorKind.StairKey).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.DungeonEntrance), # todo: looks like a huge typo - I had to guess on StairKey
|
||||
Room(player, 0x64, 0xfda53).door(Position.InteriorS, DoorKind.Trap2),
|
||||
Room(player, 0x65, 0xfdac5).door(Position.InteriorS, DoorKind.Normal),
|
||||
Room(player, 0x66, 0xfa01b).door(Position.InteriorE2, DoorKind.Waterfall).door(Position.SouthW2, DoorKind.NormalLow2).door(Position.SouthW2, DoorKind.TrapLow).door(Position.InteriorW2, DoorKind.NormalLow2),
|
||||
Room(player, 0x66, 0xfa01b).door(Position.InteriorE2, DoorKind.Waterfall).door(Position.SouthW2, DoorKind.NormalLow2).door(Position.SouthW2, DoorKind.ToggleFlag).door(Position.InteriorW2, DoorKind.NormalLow2),
|
||||
Room(player, 0x67, 0xfbe17).door(Position.NorthE, DoorKind.Normal).door(Position.InteriorS, DoorKind.Normal).door(Position.EastS, DoorKind.Normal),
|
||||
Room(player, 0x68, 0xfbf02).door(Position.WestS, DoorKind.Trap).door(Position.NorthE, DoorKind.SmallKey),
|
||||
Room(player, 0x6a, 0xfa7c7).door(Position.NorthE, DoorKind.BigKey),
|
||||
@@ -113,7 +114,7 @@ def create_rooms(world, player):
|
||||
Room(player, 0x73, 0xf8972).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.InteriorS, DoorKind.Trap2).door(Position.InteriorE, DoorKind.Normal),
|
||||
Room(player, 0x74, 0xf8a66).door(Position.InteriorE, DoorKind.Normal).door(Position.InteriorW, DoorKind.Normal),
|
||||
Room(player, 0x75, 0xf8ab9).door(Position.InteriorW, DoorKind.Trap2).door(Position.SouthE, DoorKind.Normal),
|
||||
Room(player, 0x76, 0xf9e35).door(Position.InteriorN2, DoorKind.NormalLow).door(Position.InteriorS2, DoorKind.NormalLow).door(Position.NorthW2, DoorKind.NormalLow).door(Position.NorthW2, DoorKind.TrapLow),
|
||||
Room(player, 0x76, 0xf9e35).door(Position.InteriorN2, DoorKind.NormalLow).door(Position.InteriorS2, DoorKind.NormalLow).door(Position.NorthW2, DoorKind.NormalLow).door(Position.NorthW2, DoorKind.ToggleFlag),
|
||||
Room(player, 0x77, 0xfd0e6).door(Position.NorthW2, DoorKind.StairKeyLow).door(Position.South2, DoorKind.DungeonEntranceLow),
|
||||
Room(player, 0x7b, 0xff02b).door(Position.SouthW, DoorKind.Trap).door(Position.EastN, DoorKind.SmallKey).door(Position.EastS, DoorKind.Normal),
|
||||
Room(player, 0x7c, 0xff0ef).door(Position.NorthE, DoorKind.BlastWall).door(Position.EastS, DoorKind.Bombable).door(Position.WestN, DoorKind.SmallKey).door(Position.WestS, DoorKind.Normal),
|
||||
@@ -239,11 +240,17 @@ class Room(object):
|
||||
self.index = index
|
||||
self.doorListAddress = address
|
||||
self.doorList = []
|
||||
self.modified = False
|
||||
|
||||
def door(self, pos, kind):
|
||||
self.doorList.append((pos, kind))
|
||||
return self
|
||||
|
||||
def change(self, list_idx, kind):
|
||||
prev = self.doorList[list_idx]
|
||||
self.doorList[list_idx] = (prev[0], kind)
|
||||
self.modified = True
|
||||
|
||||
def address(self):
|
||||
return self.doorListAddress
|
||||
|
||||
@@ -261,6 +268,39 @@ class Room(object):
|
||||
return '%s' % self.index
|
||||
|
||||
|
||||
class PairedDoor(object):
|
||||
def __init__(self, door_a, door_b):
|
||||
self.door_a = door_a
|
||||
self.door_b = door_b
|
||||
self.pair = True
|
||||
|
||||
def address_a(self, world, player):
|
||||
d = world.check_for_door(self.door_a, player)
|
||||
return 0x13C000 + door_pair_offset_table[d.roomIndex]*2
|
||||
|
||||
def address_b(self, world, player):
|
||||
d = world.check_for_door(self.door_b, player)
|
||||
return 0x13C000 + door_pair_offset_table[d.roomIndex]*2
|
||||
|
||||
def rom_data_a(self, world, player):
|
||||
if not self.pair:
|
||||
return [0x00, 0x00]
|
||||
d = world.check_for_door(self.door_b, player)
|
||||
return [d.roomIndex, pos_map[d.doorListPos]]
|
||||
|
||||
def rom_data_b(self, world, player):
|
||||
if not self.pair:
|
||||
return [0x00, 0x00]
|
||||
d = world.check_for_door(self.door_a, player)
|
||||
return [d.roomIndex, pos_map[d.doorListPos]]
|
||||
|
||||
|
||||
pos_map = {
|
||||
0: 0x80, 1: 0x40, 2: 0x20, 3: 0x10
|
||||
# indices 4-7 not supported yet
|
||||
}
|
||||
|
||||
|
||||
@unique
|
||||
class DoorKind(Enum):
|
||||
Normal = 0x00
|
||||
@@ -273,7 +313,7 @@ class DoorKind(Enum):
|
||||
CaveEntranceLow = 0x10
|
||||
IncognitoEntrance = 0x12
|
||||
DungeonChanger = 0x14
|
||||
TrapLow = 0x16
|
||||
ToggleFlag = 0x16
|
||||
Trap = 0x18
|
||||
UnknownD7 = 0x1A
|
||||
SmallKey = 0x1C
|
||||
@@ -292,7 +332,7 @@ class DoorKind(Enum):
|
||||
TrapTriggerableLow = 0x44
|
||||
Warp = 0x46
|
||||
CaveEntranceLow08 = 0x48
|
||||
TrapLowE3 = 0x4A
|
||||
TrapLowE3 = 0x4A # Maybe this is a toggle flag too?
|
||||
|
||||
|
||||
@unique
|
||||
|
||||
2
Rules.py
2
Rules.py
@@ -302,7 +302,7 @@ def global_rules(world, player):
|
||||
set_rule(world.get_entrance('Eastern Courtyard N', player), lambda state: state.has('Big Key (Eastern Palace)', player))
|
||||
# There are two keys and we don't know how we shuffled, so careful with key doors.
|
||||
# TODO: Generate key rules in the shuffler. (But make sure this way works first.)
|
||||
for door in ['Eastern Dark Square Key Door WN', 'Eastern Cannonball Ledge Key Door EN', 'Eastern Darkness Up Stairs', 'Eastern Attic Start Down Stairs']:
|
||||
for door in ['Eastern Dark Square Key Door WN', 'Eastern Cannonball Ledge Key Door EN', 'Eastern Darkness Up Stairs']:
|
||||
set_rule(world.get_entrance(door, player), lambda state: state.has_key('Small Key (Eastern Palace)', player, 2))
|
||||
|
||||
# Boss rules. Same as below but no BK or arrow requirement.
|
||||
|
||||
@@ -10,76 +10,12 @@
|
||||
; Hooks into various routines
|
||||
incsrc drhooks.asm
|
||||
|
||||
org $02b5c4 ; -- moving right routine 135c4
|
||||
jsl WarpRight
|
||||
org $02b665 ; -- moving left routine
|
||||
jsl WarpLeft
|
||||
org $02b713 ; -- moving down routine
|
||||
jsl WarpDown
|
||||
org $02b7b4 ; -- moving up routine
|
||||
jsl WarpUp
|
||||
org $02bd80
|
||||
jsl AdjustTransition
|
||||
nop
|
||||
|
||||
;turn off linking doors -- see .notRoomLinkDoor label in Bank02.asm
|
||||
org $02b5a6
|
||||
bra NotLinkDoor1
|
||||
org $02b5b6
|
||||
NotLinkDoor1:
|
||||
org $02b647
|
||||
bra NotLinkDoor2
|
||||
org $02b657
|
||||
NotLinkDoor2:
|
||||
|
||||
|
||||
; Staircase routine
|
||||
org $01c3d4 ;(PC: c3d4)
|
||||
jsl RecordStairType : nop
|
||||
org $02a1e7 ;(PC: 121e7)
|
||||
jsl SpiralWarp
|
||||
|
||||
|
||||
; Graphics fix
|
||||
org $02895d
|
||||
Splicer:
|
||||
jsl GfxFixer
|
||||
lda $b1 : beq .done
|
||||
rts
|
||||
nop #5
|
||||
.done
|
||||
|
||||
org $00fda4
|
||||
Dungeon_InitStarTileCh:
|
||||
org $00d6ae ;(PC: 56ae)
|
||||
LoadTransAuxGfx:
|
||||
org $00df5a ;(PC: 5f5a)
|
||||
PrepTransAuxGfx:
|
||||
;org $0ffd65 ;(PC: 07fd65)
|
||||
;Dungeon_LoadCustomTileAttr:
|
||||
;org $01fec1
|
||||
;Dungeon_ApproachFixedColor_variable:
|
||||
;org $a0f972 ; Rando version
|
||||
;LoadRoomHook:
|
||||
org $1bee74 ;(PC: 0dee74)
|
||||
Palette_DungBgMain:
|
||||
org $1bec77
|
||||
Palette_SpriteAux3:
|
||||
org $1becc5
|
||||
Palette_SpriteAux2:
|
||||
org $1bece4
|
||||
Palette_SpriteAux1:
|
||||
|
||||
incsrc keydoors.asm
|
||||
;Kill big key (1e) check for south doors - not that easy unfortunately
|
||||
;org $1aa90
|
||||
;nop #5
|
||||
|
||||
;Main Code
|
||||
org $278000 ;138000
|
||||
incsrc normal.asm
|
||||
incsrc spiral.asm
|
||||
incsrc gfx.asm
|
||||
incsrc keydoors.asm
|
||||
|
||||
; Data Section
|
||||
org $279000
|
||||
|
||||
@@ -216,6 +216,7 @@ dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000,
|
||||
|
||||
org $27B000
|
||||
SpiralTable:
|
||||
dw $0203, $8080 ;null row
|
||||
dw $0203, $8080 ;HC Backhallway
|
||||
dw $0203, $8080 ;Sewer Pull
|
||||
dw $0203, $8080 ;Crystaroller
|
||||
@@ -367,7 +368,7 @@ dw $0000 ; this is the odd extra room - shouldn't be used
|
||||
dw $0000,$0000
|
||||
dw $0000,$0000
|
||||
dw $0000,$0000,$0000
|
||||
dw $0000,$0000,$2053
|
||||
dw $0000,$0000,$2043
|
||||
dw $0000,$0000,$0000,$0000
|
||||
dw $0000,$0000,$4058,$0000,$0000,$0000
|
||||
dw $0000,$2057,$4068,$0000,$0000,$0000
|
||||
|
||||
@@ -1,3 +1,78 @@
|
||||
org $02b5c4 ; -- moving right routine 135c4
|
||||
jsl WarpRight
|
||||
org $02b665 ; -- moving left routine
|
||||
jsl WarpLeft
|
||||
org $02b713 ; -- moving down routine
|
||||
jsl WarpDown
|
||||
org $02b7b4 ; -- moving up routine
|
||||
jsl WarpUp
|
||||
org $02bd80
|
||||
jsl AdjustTransition
|
||||
nop
|
||||
|
||||
;turn off linking doors -- see .notRoomLinkDoor label in Bank02.asm
|
||||
org $02b5a6
|
||||
bra NotLinkDoor1
|
||||
org $02b5b6
|
||||
NotLinkDoor1:
|
||||
org $02b647
|
||||
bra NotLinkDoor2
|
||||
org $02b657
|
||||
NotLinkDoor2:
|
||||
|
||||
|
||||
; Staircase routine
|
||||
org $01c3d4 ;(PC: c3d4)
|
||||
jsl RecordStairType : nop
|
||||
org $02a1e7 ;(PC: 121e7)
|
||||
jsl SpiralWarp
|
||||
|
||||
|
||||
; Graphics fix
|
||||
org $02895d
|
||||
Splicer:
|
||||
jsl GfxFixer
|
||||
lda $b1 : beq .done
|
||||
rts
|
||||
nop #5
|
||||
.done
|
||||
|
||||
org $00fda4
|
||||
Dungeon_InitStarTileCh:
|
||||
org $00d6ae ;(PC: 56ae)
|
||||
LoadTransAuxGfx:
|
||||
org $00df5a ;(PC: 5f5a)
|
||||
PrepTransAuxGfx:
|
||||
;org $0ffd65 ;(PC: 07fd65)
|
||||
;Dungeon_LoadCustomTileAttr:
|
||||
;org $01fec1
|
||||
;Dungeon_ApproachFixedColor_variable:
|
||||
;org $a0f972 ; Rando version
|
||||
;LoadRoomHook:
|
||||
org $1bee74 ;(PC: 0dee74)
|
||||
Palette_DungBgMain:
|
||||
org $1bec77
|
||||
Palette_SpriteAux3:
|
||||
org $1becc5
|
||||
Palette_SpriteAux2:
|
||||
org $1bece4
|
||||
Palette_SpriteAux1:
|
||||
|
||||
|
||||
; These two, if enabled together, have implications for vanilla BK doors in IP/Hera/Mire
|
||||
; IPBJ is common enough to consider not doing this. Mire is not a concern for vanilla - maybe glitched modes
|
||||
; Hera BK door back can be seen with Pot clipping - likely useful for no logic seeds
|
||||
|
||||
;Kill big key (1e) check for south doors
|
||||
;org $1aa90
|
||||
;DontCheck:
|
||||
;bra .done
|
||||
;nop #3
|
||||
;.done
|
||||
|
||||
;Enable south facing bk graphic
|
||||
;org $4e24
|
||||
;dw $2ac8
|
||||
|
||||
org $01b714 ; PC: b714
|
||||
OpenableDoors:
|
||||
|
||||
@@ -1,20 +1,3 @@
|
||||
; This is the reverse side of various key doors
|
||||
|
||||
org $1ff8cc ;(PC: 0ff8cc) GT 0x5b (Spikes & Switch)
|
||||
dw $0081
|
||||
|
||||
org $0a972a ;(PC: 05172a) Eastern Darkness 0x99
|
||||
dw $2060, $1e71
|
||||
|
||||
org $1fb759 ;(PC: 0fb759) Mire Bridges 0xa2
|
||||
dw $0071
|
||||
|
||||
org $0a9887 ;(PC: 051887) Eastern Compass Area 0xa8
|
||||
dw $3882, $3660, $1e81
|
||||
|
||||
org $1fd974 ;(PC: 0fd974) TT Bossway 0xbc
|
||||
dw $1c82, $0081
|
||||
|
||||
; code to un-pair or re-pair doors
|
||||
|
||||
; doorlist is loaded into 19A0 but no terminator
|
||||
@@ -29,19 +12,20 @@ dw $1c82, $0081
|
||||
CheckIfDoorsOpen: {
|
||||
jsr TrapDoorFixer ; see normal.asm
|
||||
; note we are 16bit mode right now
|
||||
lda $040c : cmp #$00ff ;: bne .gtg
|
||||
lda $040c : cmp #$00ff : bne .gtg
|
||||
lda $a0 : dec : tax : and #$000f ; hijacked code
|
||||
sec : rtl ; set carry to indicate normal behavior
|
||||
|
||||
.gtg
|
||||
phb : phk : plb
|
||||
stx $00 : ldy #$00 : stz $03
|
||||
stx $00 : ldy #$0000
|
||||
.nextDoor
|
||||
lda $a0 : asl : tax
|
||||
lda KeyDoorOffset, x : beq .skipDoor
|
||||
asl : sty $05 : !add $05 : tax
|
||||
lda PairedDoorTable, x : beq .skipDoor
|
||||
sta $02 : and #$00ff : asl a : tax
|
||||
lda $02 : and #$ff00 : sta $03
|
||||
lda $7ef000, x : and #$f000 : and $03 : beq .skipDoor
|
||||
tyx : lda $068c : ora $0098c0,x : sta $068c
|
||||
.skipDoor
|
||||
@@ -53,5 +37,5 @@ CheckIfDoorsOpen: {
|
||||
; how to indicate opening for other (non-first four doors?)
|
||||
; Bank01 Door Register stores the 4 bits in 068c to 400 (depending on type)
|
||||
; Key collision and others depend on F0-F3 attribute not sure if extendable to other numbers
|
||||
; Dungeon_ProcessTorchAndDoorInteractives.isOpenableDoor is the likely culprit fo collision problems
|
||||
; Dungeon_ProcessTorchAndDoorInteractives.isOpenableDoor is the likely culprit for collision problems
|
||||
; Saving open status to other unused rooms is tricky -- Bank 2 13947 (line 8888)
|
||||
@@ -39,8 +39,8 @@ WarpDown:
|
||||
rtl
|
||||
|
||||
TrapDoorFixer:
|
||||
lda $ab : and #$0018 : beq .end
|
||||
xba : asl #3 : sta $00
|
||||
lda $ab : and #$0038 : beq .end
|
||||
xba : asl #2 : sta $00
|
||||
stz $0468 : lda $068c : ora $00 : sta $068c
|
||||
.end
|
||||
stz $ab ; clear our ab here because we don't need it anymore
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user