Merge branch 'DoorDev' into DoorShuffleStandardModeDev
This commit is contained in:
@@ -284,7 +284,7 @@ class World(object):
|
|||||||
|
|
||||||
def has_beaten_game(self, state, player=None):
|
def has_beaten_game(self, state, player=None):
|
||||||
if player:
|
if player:
|
||||||
return state.has('Triforce', player) or (self.goal in ['triforcehunt'] and (state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) > self.treasure_hunt_count))
|
return state.has('Triforce', player)
|
||||||
else:
|
else:
|
||||||
return all((self.has_beaten_game(state, p) for p in range(1, self.players + 1)))
|
return all((self.has_beaten_game(state, p) for p in range(1, self.players + 1)))
|
||||||
|
|
||||||
@@ -862,7 +862,8 @@ class Door(object):
|
|||||||
layer = 4 * (self.layer ^ 1 if toggle else self.layer)
|
layer = 4 * (self.layer ^ 1 if toggle else self.layer)
|
||||||
return [self.roomIndex, layer + self.doorIndex]
|
return [self.roomIndex, layer + self.doorIndex]
|
||||||
if self.type == DoorType.SpiralStairs:
|
if self.type == DoorType.SpiralStairs:
|
||||||
bitmask = 0x10 * int(self.zeroHzCam)
|
bitmask = int(self.layer) << 2
|
||||||
|
bitmask += 0x10 * int(self.zeroHzCam)
|
||||||
bitmask += 0x20 * int(self.zeroVtCam)
|
bitmask += 0x20 * int(self.zeroVtCam)
|
||||||
return [self.roomIndex, bitmask + self.quadrant, self.shiftX, self.shiftY]
|
return [self.roomIndex, bitmask + self.quadrant, self.shiftX, self.shiftY]
|
||||||
|
|
||||||
|
|||||||
@@ -119,11 +119,11 @@ def can_place_boss(world, boss, dungeon_name, level=None):
|
|||||||
if world.swords in ['swordless'] and boss == 'Kholdstare' and dungeon_name != 'Ice Palace':
|
if world.swords in ['swordless'] and boss == 'Kholdstare' and dungeon_name != 'Ice Palace':
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if dungeon_name == 'Ganons Tower' and level == 'top':
|
if dungeon_name in ['Ganons Tower', 'Inverted Ganons Tower'] and level == 'top':
|
||||||
if boss in ["Armos Knights", "Arrghus", "Blind", "Trinexx", "Lanmolas"]:
|
if boss in ["Armos Knights", "Arrghus", "Blind", "Trinexx", "Lanmolas"]:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if dungeon_name == 'Ganons Tower' and level == 'middle':
|
if dungeon_name in ['Ganons Tower', 'Inverted Ganons Tower'] and level == 'middle':
|
||||||
if boss in ["Blind"]:
|
if boss in ["Blind"]:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
30
Doors.py
30
Doors.py
@@ -16,6 +16,12 @@ A = 0
|
|||||||
S = 1
|
S = 1
|
||||||
Z = 2
|
Z = 2
|
||||||
X = 3
|
X = 3
|
||||||
|
# Layer transitions
|
||||||
|
HTH = 0 # High to High 00
|
||||||
|
HTL = 1 # High to Low 01
|
||||||
|
LTH = 2 # Low to High 10
|
||||||
|
LTL = 3 # Low to Low 11
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_doors(world, player):
|
def create_doors(world, player):
|
||||||
@@ -38,12 +44,12 @@ def create_doors(world, player):
|
|||||||
create_dir_door(player, 'Hyrule Castle West Hall S', DoorType.Normal, Direction.South, 0x50, Right, 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 W', DoorType.Normal, Direction.West, 0x01, Top, Low),
|
||||||
create_dir_door(player, 'Hyrule Castle Back Hall E', DoorType.Normal, Direction.East, 0x01, Top, Low),
|
create_dir_door(player, 'Hyrule Castle Back Hall E', DoorType.Normal, Direction.East, 0x01, Top, Low),
|
||||||
create_spiral_stairs(player, 'Hyrule Castle Back Hall Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x01, 0, Low, A, 0x37, 0xf8),
|
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),
|
||||||
create_dir_door(player, 'Hyrule Castle Throne Room South Stairs', DoorType.StraightStairs, Direction.South, 0x51, Mid, Low),
|
create_dir_door(player, 'Hyrule Castle Throne Room South Stairs', DoorType.StraightStairs, Direction.South, 0x51, Mid, Low),
|
||||||
|
|
||||||
# hyrule dungeon level
|
# hyrule dungeon level
|
||||||
create_spiral_stairs(player, 'Hyrule Dungeon Map Room Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x72, 0, High, A, 0x4f, 0xf8),
|
create_spiral_stairs(player, 'Hyrule Dungeon Map Room Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x72, 0, LTH, A, 0x4b, 0xec),
|
||||||
create_small_key_door(player, 'Hyrule Dungeon Map Room Key Door S', DoorType.Interior, Direction.South, 0x71, Right, High),
|
create_small_key_door(player, 'Hyrule Dungeon Map Room Key Door S', DoorType.Interior, Direction.South, 0x71, Right, High),
|
||||||
create_small_key_door(player, 'Hyrule Dungeon North Abyss Key Door N', DoorType.Interior, Direction.North, 0x71, Right, High),
|
create_small_key_door(player, 'Hyrule Dungeon North Abyss Key Door N', DoorType.Interior, Direction.North, 0x71, Right, High),
|
||||||
create_dir_door(player, 'Hyrule Dungeon North Abyss South Edge', DoorType.Open, Direction.South, 0x72, None, Low),
|
create_dir_door(player, 'Hyrule Dungeon North Abyss South Edge', DoorType.Open, Direction.South, 0x72, None, Low),
|
||||||
@@ -58,15 +64,15 @@ def create_doors(world, player):
|
|||||||
create_dir_door(player, 'Hyrule Dungeon Armory S', DoorType.Normal, Direction.South, 0x71, Left, Low), # not sure what the layer should be here
|
create_dir_door(player, 'Hyrule Dungeon Armory S', DoorType.Normal, Direction.South, 0x71, Left, Low), # not sure what the layer should be here
|
||||||
create_small_key_door(player, 'Hyrule Dungeon Armory Interior Key Door N', DoorType.Interior, Direction.North, 0x71, Left, High),
|
create_small_key_door(player, 'Hyrule Dungeon Armory Interior Key Door N', DoorType.Interior, Direction.North, 0x71, Left, High),
|
||||||
create_small_key_door(player, 'Hyrule Dungeon Armory Interior Key Door S', DoorType.Interior, Direction.South, 0x71, Left, High),
|
create_small_key_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, Low, A, 0x1e, 0xa0, True),
|
create_spiral_stairs(player, 'Hyrule Dungeon Armory Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x71, 0, HTL, A, 0x11, 0xa8, True),
|
||||||
create_spiral_stairs(player, 'Hyrule Dungeon Staircase Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x70, 2, High, A, 0x36, 0xa0, True),
|
create_spiral_stairs(player, 'Hyrule Dungeon Staircase Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x70, 2, LTH, A, 0x32, 0x94, True),
|
||||||
create_spiral_stairs(player, 'Hyrule Dungeon Staircase Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x70, 1, High, A, 0x1f, 0x50),
|
create_spiral_stairs(player, 'Hyrule Dungeon Staircase Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x70, 1, HTH, A, 0x11, 0x58),
|
||||||
create_spiral_stairs(player, 'Hyrule Dungeon Cellblock Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x80, 0, Low, A, 0x1f, 0x50),
|
create_spiral_stairs(player, 'Hyrule Dungeon Cellblock Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x80, 0, HTH, A, 0x1a, 0x44),
|
||||||
|
|
||||||
# sewers
|
# sewers
|
||||||
create_blocked_door(player, 'Sewers Behind Tapestry S', DoorType.Normal, Direction.South, 0x41, Mid, High),
|
create_blocked_door(player, 'Sewers Behind Tapestry S', DoorType.Normal, Direction.South, 0x41, Mid, High),
|
||||||
create_spiral_stairs(player, 'Sewers Behind Tapestry Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x41, 0, High, S, 0x1f, 0xa8),
|
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, High, S, 0x1f, 0xa8),
|
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 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),
|
create_dir_door(player, 'Sewers Dark Cross South Stairs', DoorType.StraightStairs, Direction.South, 0x32, Mid, High),
|
||||||
create_dir_door(player, 'Sewers Dark Cross Key Door N', DoorType.Normal, Direction.North, 0x32, Mid, High),
|
create_dir_door(player, 'Sewers Dark Cross Key Door N', DoorType.Normal, Direction.North, 0x32, Mid, High),
|
||||||
@@ -75,8 +81,8 @@ def create_doors(world, player):
|
|||||||
create_dir_door(player, 'Sewers Key Rat E', DoorType.Normal, Direction.East, 0x21, Bot, High),
|
create_dir_door(player, 'Sewers Key Rat E', DoorType.Normal, Direction.East, 0x21, Bot, High),
|
||||||
create_small_key_door(player, 'Sewers Key Rat Key Door N', DoorType.Normal, Direction.North, 0x21, Right, High),
|
create_small_key_door(player, 'Sewers Key Rat Key Door N', DoorType.Normal, Direction.North, 0x21, Right, High),
|
||||||
create_small_key_door(player, 'Sewers Secret Room Key Door S', DoorType.Normal, Direction.South, 0x11, Right, High),
|
create_small_key_door(player, 'Sewers Secret Room Key Door S', DoorType.Normal, Direction.South, 0x11, Right, High),
|
||||||
create_spiral_stairs(player, 'Sewers Secret Room Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x11, 0, High, S, 0x37, 0x78),
|
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, High, S, 0x1f, 0x78),
|
create_spiral_stairs(player, 'Sewers Pull Switch Down Stairs', DoorType.SpiralStairs, Direction.Down, 0x02, 0, HTL, S, 0x12, 0x80),
|
||||||
create_toggle_door(player, 'Sewers Pull Switch S', DoorType.Normal, Direction.South, 0x02, Mid, Low),
|
create_toggle_door(player, 'Sewers Pull Switch S', DoorType.Normal, Direction.South, 0x02, Mid, Low),
|
||||||
# logically one way the sanc, but should be linked - also toggle
|
# logically one way the sanc, but should be linked - also toggle
|
||||||
create_blocked_door(player, 'Sanctuary N', DoorType.Normal, Direction.North, 0x12, Mid, 0, True),
|
create_blocked_door(player, 'Sanctuary N', DoorType.Normal, Direction.North, 0x12, Mid, 0, True),
|
||||||
@@ -108,8 +114,8 @@ def create_doors(world, player):
|
|||||||
create_small_key_door(player, 'Eastern Big Key EN', DoorType.Normal, Direction.East, 0xb8, Top, High),
|
create_small_key_door(player, 'Eastern Big Key EN', DoorType.Normal, Direction.East, 0xb8, Top, High),
|
||||||
create_dir_door(player, 'Eastern Big Key NE', DoorType.Normal, Direction.North, 0xb8, Right, High),
|
create_dir_door(player, 'Eastern Big Key NE', DoorType.Normal, Direction.North, 0xb8, Right, High),
|
||||||
create_small_key_door(player, 'Eastern Darkness S', DoorType.Normal, Direction.South, 0x99, Mid, High),
|
create_small_key_door(player, 'Eastern Darkness S', DoorType.Normal, Direction.South, 0x99, Mid, High),
|
||||||
create_spiral_stairs(player, 'Eastern Darkness Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x99, 0, High, Z, 0x1e, 0x78, False, True),
|
create_spiral_stairs(player, 'Eastern Darkness Up Stairs', DoorType.SpiralStairs, Direction.Up, 0x99, 0, HTH, Z, 0x1a, 0x6c, False, True),
|
||||||
create_spiral_stairs(player, 'Eastern Attic Start Down Stairs', DoorType.SpiralStairs, Direction.Down, 0xda, 0, High, Z, 0x1f, 0x78, False, True),
|
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 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 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 Attic Switches WS', DoorType.Normal, Direction.West, 0xd9, Bot, High),
|
||||||
|
|||||||
@@ -3507,8 +3507,8 @@ inverted_default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'
|
|||||||
('Bumper Cave (Top)', 'Dark Death Mountain Healer Fairy'),
|
('Bumper Cave (Top)', 'Dark Death Mountain Healer Fairy'),
|
||||||
('Bumper Cave Exit (Top)', 'Death Mountain Return Ledge'),
|
('Bumper Cave Exit (Top)', 'Death Mountain Return Ledge'),
|
||||||
('Bumper Cave Exit (Bottom)', 'Light World'),
|
('Bumper Cave Exit (Bottom)', 'Light World'),
|
||||||
('Death Mountain Return Cave (East)', 'Bumper Cave'),
|
('Death Mountain Return Cave (West)', 'Bumper Cave'),
|
||||||
('Death Mountain Return Cave (West)', 'Death Mountain Return Cave'),
|
('Death Mountain Return Cave (East)', 'Death Mountain Return Cave'),
|
||||||
('Death Mountain Return Cave Exit (West)', 'Death Mountain'),
|
('Death Mountain Return Cave Exit (West)', 'Death Mountain'),
|
||||||
('Death Mountain Return Cave Exit (East)', 'Death Mountain'),
|
('Death Mountain Return Cave Exit (East)', 'Death Mountain'),
|
||||||
('Hookshot Cave Exit (South)', 'Dark Death Mountain'),
|
('Hookshot Cave Exit (South)', 'Dark Death Mountain'),
|
||||||
|
|||||||
17
ItemList.py
17
ItemList.py
@@ -137,6 +137,23 @@ def generate_itempool(world, player):
|
|||||||
else:
|
else:
|
||||||
world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False)
|
world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False)
|
||||||
|
|
||||||
|
if world.goal in ['triforcehunt']:
|
||||||
|
if world.mode == 'inverted':
|
||||||
|
region = world.get_region('Light World',player)
|
||||||
|
else:
|
||||||
|
region = world.get_region('Hyrule Castle Courtyard', player)
|
||||||
|
|
||||||
|
loc = Location(player, "Murahdahla", parent=region)
|
||||||
|
loc.access_rule = lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) > state.world.treasure_hunt_count
|
||||||
|
region.locations.append(loc)
|
||||||
|
world.dynamic_locations.append(loc)
|
||||||
|
|
||||||
|
world.clear_location_cache()
|
||||||
|
|
||||||
|
world.push_item(loc, ItemFactory('Triforce', player), False)
|
||||||
|
loc.event = True
|
||||||
|
loc.locked = True
|
||||||
|
|
||||||
world.get_location('Ganon', player).event = True
|
world.get_location('Ganon', player).event = True
|
||||||
world.get_location('Ganon', player).locked = True
|
world.get_location('Ganon', player).locked = True
|
||||||
world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False)
|
world.push_item(world.get_location('Agahnim 1', player), ItemFactory('Beat Agahnim 1', player), False)
|
||||||
|
|||||||
5
Main.py
5
Main.py
@@ -285,6 +285,11 @@ def copy_dynamic_regions_and_locations(world, ret):
|
|||||||
for location in world.dynamic_locations:
|
for location in world.dynamic_locations:
|
||||||
new_reg = ret.get_region(location.parent_region.name, location.parent_region.player)
|
new_reg = ret.get_region(location.parent_region.name, location.parent_region.player)
|
||||||
new_loc = Location(location.player, location.name, location.address, location.crystal, location.hint_text, new_reg)
|
new_loc = Location(location.player, location.name, location.address, location.crystal, location.hint_text, new_reg)
|
||||||
|
# todo: this is potentially dangerous. later refactor so we
|
||||||
|
# can apply dynamic region rules on top of copied world like other rules
|
||||||
|
new_loc.access_rule = location.access_rule
|
||||||
|
new_loc.always_allow = location.always_allow
|
||||||
|
new_loc.item_rule = location.item_rule
|
||||||
new_reg.locations.append(new_loc)
|
new_reg.locations.append(new_loc)
|
||||||
|
|
||||||
ret.clear_location_cache()
|
ret.clear_location_cache()
|
||||||
|
|||||||
11
Rom.py
11
Rom.py
@@ -18,7 +18,7 @@ from EntranceShuffle import door_addresses
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = 'fdfff1a9046506a57dbcbe23fb5fd386'
|
RANDOMIZERBASEHASH = 'efb85e71cf7d9bc0401c6683992d6e2f'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -842,6 +842,7 @@ def patch_rom(world, player, rom):
|
|||||||
# set up goals for treasure hunt
|
# set up goals for treasure hunt
|
||||||
rom.write_bytes(0x180165, [0x0E, 0x28] if world.treasure_hunt_icon == 'Triforce Piece' else [0x0D, 0x28])
|
rom.write_bytes(0x180165, [0x0E, 0x28] if world.treasure_hunt_icon == 'Triforce Piece' else [0x0D, 0x28])
|
||||||
rom.write_byte(0x180167, world.treasure_hunt_count % 256)
|
rom.write_byte(0x180167, world.treasure_hunt_count % 256)
|
||||||
|
rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled)
|
||||||
|
|
||||||
# TODO: a proper race rom mode should be implemented, that changes the following flag, and rummages the table (or uses the future encryption feature, etc)
|
# TODO: a proper race rom mode should be implemented, that changes the following flag, and rummages the table (or uses the future encryption feature, etc)
|
||||||
rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed
|
rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed
|
||||||
@@ -1282,17 +1283,18 @@ def write_strings(rom, world, player):
|
|||||||
random.shuffle(silverarrows)
|
random.shuffle(silverarrows)
|
||||||
silverarrow_hint = (' %s?' % hint_text(silverarrows[0]).replace('Ganon\'s', 'my')) if silverarrows else '?\nI think not!'
|
silverarrow_hint = (' %s?' % hint_text(silverarrows[0]).replace('Ganon\'s', 'my')) if silverarrows else '?\nI think not!'
|
||||||
tt['ganon_phase_3_no_silvers'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
tt['ganon_phase_3_no_silvers'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||||
|
tt['ganon_phase_3_no_silvers_alt'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||||
|
|
||||||
prog_bow_locs = world.find_items('Progressive Bow', player)
|
prog_bow_locs = world.find_items('Progressive Bow', player)
|
||||||
distinguished_prog_bow_loc = next((location for location in prog_bow_locs if location.item.code == 0x65), None)
|
distinguished_prog_bow_loc = next((location for location in prog_bow_locs if location.item.code == 0x65), None)
|
||||||
if distinguished_prog_bow_loc:
|
if distinguished_prog_bow_loc:
|
||||||
prog_bow_locs.remove(distinguished_prog_bow_loc)
|
prog_bow_locs.remove(distinguished_prog_bow_loc)
|
||||||
silverarrow_hint = (' %s?' % hint_text(distinguished_prog_bow_loc).replace('Ganon\'s', 'my'))
|
silverarrow_hint = (' %s?' % hint_text(distinguished_prog_bow_loc).replace('Ganon\'s', 'my'))
|
||||||
tt['ganon_phase_3_no_silvers'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
tt['ganon_phase_3_no_silvers_alt'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||||
|
|
||||||
if any(prog_bow_locs):
|
if any(prog_bow_locs):
|
||||||
silverarrow_hint = (' %s?' % hint_text(random.choice(prog_bow_locs)).replace('Ganon\'s', 'my'))
|
silverarrow_hint = (' %s?' % hint_text(random.choice(prog_bow_locs)).replace('Ganon\'s', 'my'))
|
||||||
tt['ganon_phase_3_no_silvers_alt'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
tt['ganon_phase_3_no_silvers'] = 'Did you find the silver arrows%s' % silverarrow_hint
|
||||||
|
|
||||||
|
|
||||||
silverarrow_hint = (' %s?' % hint_text(silverarrows[0]).replace('Ganon\'s', 'my')) if silverarrows else '?\nI think not!'
|
silverarrow_hint = (' %s?' % hint_text(silverarrows[0]).replace('Ganon\'s', 'my')) if silverarrows else '?\nI think not!'
|
||||||
@@ -1323,6 +1325,7 @@ def write_strings(rom, world, player):
|
|||||||
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Get the Triforce Pieces.'
|
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Get the Triforce Pieces.'
|
||||||
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
||||||
tt['sign_ganon'] = 'Go find the Triforce pieces... Ganon is invincible!'
|
tt['sign_ganon'] = 'Go find the Triforce pieces... Ganon is invincible!'
|
||||||
|
tt['murahdahla'] = "Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\nhidden in a hollow tree. If you bring\n%d triforce pieces, I can reassemble it." % world.treasure_hunt_count
|
||||||
elif world.goal in ['pedestal']:
|
elif world.goal in ['pedestal']:
|
||||||
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Your goal is at the pedestal.'
|
tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Your goal is at the pedestal.'
|
||||||
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.'
|
||||||
@@ -1406,8 +1409,6 @@ def set_inverted_mode(world, rom):
|
|||||||
rom.write_int16s(snes_to_pc(0x02E849), [0x0043, 0x0056, 0x0058, 0x006C, 0x006F, 0x0070, 0x007B, 0x007F, 0x001B]) # dw flute
|
rom.write_int16s(snes_to_pc(0x02E849), [0x0043, 0x0056, 0x0058, 0x006C, 0x006F, 0x0070, 0x007B, 0x007F, 0x001B]) # dw flute
|
||||||
rom.write_int16(snes_to_pc(0x02E8D5), 0x07C8)
|
rom.write_int16(snes_to_pc(0x02E8D5), 0x07C8)
|
||||||
rom.write_int16(snes_to_pc(0x02E8F7), 0x01F8)
|
rom.write_int16(snes_to_pc(0x02E8F7), 0x01F8)
|
||||||
rom.write_byte(0x7A943, 0xF0)
|
|
||||||
rom.write_byte(0x7A96D, 0xD0)
|
|
||||||
rom.write_byte(snes_to_pc(0x08D40C), 0xD0) # morph proof
|
rom.write_byte(snes_to_pc(0x08D40C), 0xD0) # morph proof
|
||||||
# the following bytes should only be written in vanilla
|
# the following bytes should only be written in vanilla
|
||||||
# or they'll overwrite the randomizer's shuffles
|
# or they'll overwrite the randomizer's shuffles
|
||||||
|
|||||||
1
Text.py
1
Text.py
@@ -1890,5 +1890,6 @@ class TextTable(object):
|
|||||||
text['ganon_phase_3_no_silvers_alt'] = CompressedTextMapper.convert("You can't best me without silver arrows!")
|
text['ganon_phase_3_no_silvers_alt'] = CompressedTextMapper.convert("You can't best me without silver arrows!")
|
||||||
text['ganon_phase_3_no_silvers'] = CompressedTextMapper.convert("You can't best me without silver arrows!")
|
text['ganon_phase_3_no_silvers'] = CompressedTextMapper.convert("You can't best me without silver arrows!")
|
||||||
text['ganon_phase_3_silvers'] = CompressedTextMapper.convert("Oh no! Silver! My one true weakness!")
|
text['ganon_phase_3_silvers'] = CompressedTextMapper.convert("Oh no! Silver! My one true weakness!")
|
||||||
|
text['murahdahla'] = CompressedTextMapper.convert("Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n{PAUSE3}\n… … …\nWait! you can see me? I knew I should have\nhidden in a hollow tree.")
|
||||||
text['end_pad_data'] = bytearray([0xfb])
|
text['end_pad_data'] = bytearray([0xfb])
|
||||||
text['terminator'] = bytearray([0xFF, 0xFF])
|
text['terminator'] = bytearray([0xFF, 0xFF])
|
||||||
|
|||||||
@@ -122,6 +122,26 @@ c2 21 ae b6 0a bf 1b
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Trap doors:
|
||||||
|
|
||||||
|
0468 - flag is set when doors are down (1 = down? 0 = up?)
|
||||||
|
$690 - 7 for open - 0 for down
|
||||||
|
|
||||||
|
IntraRoom: ->
|
||||||
|
Dungeon_IntraRoomTransShutDoors (maybe should be Open)
|
||||||
|
stz $0468
|
||||||
|
#$07 -> $0690
|
||||||
|
|
||||||
|
Dungeon_IntraRoomTransOpenDoors (maybe should be Shut)
|
||||||
|
|
||||||
|
10D71 -> A
|
||||||
|
A -> 0468
|
||||||
|
0468++
|
||||||
|
0 -> 0690
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Other transition stuff
|
Other transition stuff
|
||||||
|
|
||||||
Overworld_LoadTransGfx -> LoadTransAuxGfx
|
Overworld_LoadTransGfx -> LoadTransAuxGfx
|
||||||
|
|||||||
@@ -27,9 +27,10 @@ NotLinkDoor2:
|
|||||||
|
|
||||||
|
|
||||||
; Staircase routine
|
; Staircase routine
|
||||||
;org $02a1e7 ;(PC: 121e7)
|
|
||||||
org $01c3d4 ;(PC: c3d4)
|
org $01c3d4 ;(PC: c3d4)
|
||||||
jsl SpiralWarp : nop
|
jsl RecordStairType : nop
|
||||||
|
org $02a1e7 ;(PC: 121e7)
|
||||||
|
jsl SpiralWarp
|
||||||
|
|
||||||
|
|
||||||
; Graphics fix
|
; Graphics fix
|
||||||
@@ -333,5 +334,12 @@ ShiftQuadIndex:
|
|||||||
db 2, 1 ; see ShiftQuad func (relates to $a9,$aa)
|
db 2, 1 ; see ShiftQuad func (relates to $a9,$aa)
|
||||||
CamBoundIndex: ; Horizontal 1st
|
CamBoundIndex: ; Horizontal 1st
|
||||||
db 0, 4 ; Camera Bounds $0618-$61f
|
db 0, 4 ; Camera Bounds $0618-$61f
|
||||||
|
OppCamBoundIndex: ; Horizontal 1st
|
||||||
|
db 4, 0 ; Camera Bounds $0618-$61f
|
||||||
|
CamBoundBaseLine: ; X camera stuff is 1st column todo Y camera is not right yet
|
||||||
|
dw $007f, $0077 ; Left/Top camera bounds when at edge or layout frozen
|
||||||
|
dw $0007, $000b ; Left/Top camera bounds when not frozen + appropriate low byte $22/$20 (preadj. by #$78/#$6c)
|
||||||
|
dw $00ff, $010b ; Right/Bot camera bounds when not frozen + appropriate low byte $20/$22
|
||||||
|
dw $017f, $0187 ; Right/Bot camera bound when at edge or layout frozen
|
||||||
|
|
||||||
incsrc doortables.asm
|
incsrc doortables.asm
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
SpiralWarp:
|
RecordStairType: {
|
||||||
{
|
pha
|
||||||
|
lda $0e : sta $045e
|
||||||
|
pla : sta $a0 : lda $063d, x
|
||||||
|
rtl
|
||||||
|
}
|
||||||
|
|
||||||
pha : lda $040c : cmp.b #$ff : beq .abort ; abort if not in dungeon
|
SpiralWarp: {
|
||||||
|
lda $040c : cmp.b #$ff : beq .abort ; abort if not in dungeon
|
||||||
cmp #$06 : bcs .abort ; abort if not supported yet -- todo: this needs to be altered/removed as more dungeons are implemented
|
cmp #$06 : bcs .abort ; abort if not supported yet -- todo: this needs to be altered/removed as more dungeons are implemented
|
||||||
lda $0e : 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
|
||||||
.abort pla : sta $a0 : bra .end
|
.abort
|
||||||
|
lda $a2 : and #$0f : rtl ; run highjack code and get out
|
||||||
|
|
||||||
.gtg
|
.gtg
|
||||||
pla
|
|
||||||
phb : phk : plb : phx : phy ; push stuff
|
phb : phk : plb : phx : phy ; push stuff
|
||||||
jsr LookupSpiralOffset
|
jsr LookupSpiralOffset
|
||||||
rep #$30 : and #$00FF : asl #2 : tax
|
rep #$30 : and #$00FF : asl #2 : tax
|
||||||
@@ -29,25 +34,29 @@ SpiralWarp:
|
|||||||
ldy #$01 : jsr ShiftQuadSimple
|
ldy #$01 : jsr ShiftQuadSimple
|
||||||
|
|
||||||
.skipYQuad
|
.skipYQuad
|
||||||
|
lda $01 : and #$04 : lsr : sta $048a ;fix layer calc 0->0 2->1
|
||||||
|
lda $01 : and #$08 : lsr #2 : sta $0492 ;fix from layer calc 0->0 2->1
|
||||||
; shift lower coordinates
|
; shift lower coordinates
|
||||||
lda $02 : sta $22
|
lda $02 : sta $22 : bne .adjY : inc $23
|
||||||
lda $03 : sta $20
|
.adjY lda $03 : sta $20 : bne .set53 : inc $21
|
||||||
|
.set53 ldx #$08
|
||||||
|
lda $0462 : and #$04 : beq .upStairs
|
||||||
|
ldx #$fd
|
||||||
|
.upStairs
|
||||||
|
txa : !add $22 : sta $53
|
||||||
|
|
||||||
ldy #$00 : jsr SetCamera ; todo: figure out camera jazz
|
lda $01 : and #$10 : sta $07 ; zeroHzCam check
|
||||||
|
ldy #$00 : jsr SetCamera
|
||||||
|
lda $01 : and #$20 : sta $07 ; zeroVtCam check
|
||||||
ldy #$01 : jsr SetCamera
|
ldy #$01 : jsr SetCamera
|
||||||
|
|
||||||
ply : plx : plb ; pull the stuff we pushed
|
ply : plx : plb ; pull the stuff we pushed
|
||||||
|
lda $a2 : and #$0f ; this is the code we are hijacking
|
||||||
.end
|
|
||||||
; this is the code we are hijacking
|
|
||||||
; lda $a0 - we overwrote this behavior
|
|
||||||
lda $063d, x
|
|
||||||
rtl
|
rtl
|
||||||
}
|
}
|
||||||
|
|
||||||
;Sets the offset in A
|
;Sets the offset in A
|
||||||
LookupSpiralOffset:
|
LookupSpiralOffset: {
|
||||||
{
|
|
||||||
;where link currently is in $a2: quad in a8 & #$03
|
;where link currently is in $a2: quad in a8 & #$03
|
||||||
;count doors
|
;count doors
|
||||||
stz $00 : ldx #$00 : stz $01
|
stz $00 : ldx #$00 : stz $01
|
||||||
@@ -84,43 +93,65 @@ LookupSpiralOffset:
|
|||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
|
|
||||||
ShiftQuadSimple:
|
ShiftQuadSimple: {
|
||||||
{
|
|
||||||
lda CoordIndex,y : tax
|
lda CoordIndex,y : tax
|
||||||
|
lda $20,x : beq .skip
|
||||||
lda $21,x : !add $06 : sta $21,x ; coordinate update
|
lda $21,x : !add $06 : sta $21,x ; coordinate update
|
||||||
|
.skip
|
||||||
lda CamQuadIndex,y : tax
|
lda CamQuadIndex,y : tax
|
||||||
lda $0601,x : !add $06 : sta $0601,x
|
lda $0601,x : !add $06 : sta $0601,x
|
||||||
lda $0605,x : !add $06 : sta $0605,x ; high bytes of these guys
|
lda $0605,x : !add $06 : sta $0605,x ; high bytes of these guys
|
||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCamera:
|
SetCamera: {
|
||||||
{
|
stz $04
|
||||||
stz $04 : sty $05
|
|
||||||
lda $01 : and #$10 : !add $05 : cmp #$10 : beq .done ; zeroHzCam check (10+0 = 10)
|
|
||||||
lda $01 : and #$20 : !add $05 : cmp #$21 : beq .done ; zeroVtCam check (20+1 = 21)
|
|
||||||
|
|
||||||
tyx : lda $a9,x : bne .nonZeroHalf
|
tyx : lda $a9,x : bne .nonZeroHalf
|
||||||
lda CamQuadIndex,y : tax : lda $607,x : pha
|
lda CamQuadIndex,y : tax : lda $607,x : pha
|
||||||
lda CameraIndex,y : tax : pla : cmp $e3, x : bne .noQuadAdj
|
lda CameraIndex,y : tax : pla : cmp $e3, x : bne .noQuadAdj
|
||||||
dec $e3,x
|
dec $e3,x
|
||||||
|
|
||||||
.noQuadAdj
|
.noQuadAdj
|
||||||
|
lda $07 : bne .adj0
|
||||||
lda CoordIndex,y : tax
|
lda CoordIndex,y : tax
|
||||||
lda $20,x : cmp #$79 : bcc .adjust
|
lda $20,x : beq .oddQuad
|
||||||
!sub #$78 : sta $04 : bra .adjust
|
cmp #$79 : bcc .adj0
|
||||||
|
!sub #$78 : sta $04
|
||||||
|
tya : asl : !add #$04 : tax : jsr AdjCamBounds : bra .done
|
||||||
|
.oddQuad
|
||||||
|
lda #$80 : sta $04 : bra .adj1 ; this is such a weird case - quad cross boundary
|
||||||
|
.adj0
|
||||||
|
tya : asl : tax : jsr AdjCamBounds : bra .done
|
||||||
|
|
||||||
.nonZeroHalf ;meaning either right half or bottom half
|
.nonZeroHalf ;meaning either right half or bottom half
|
||||||
|
lda $07 : bne .setQuad
|
||||||
lda CoordIndex,y : tax
|
lda CoordIndex,y : tax
|
||||||
lda $20,x : cmp #$78 : bcs .setQuad
|
lda $20,x : cmp #$78 : bcs .setQuad
|
||||||
!add #$78 : sta $04 : bra .adjust
|
!add #$78 : sta $04
|
||||||
|
.adj1
|
||||||
|
tya : asl : !add #$08 : tax : jsr AdjCamBounds : bra .done
|
||||||
|
|
||||||
.setQuad
|
.setQuad
|
||||||
lda CamQuadIndex,y : tax : lda $0607, x : pha
|
lda CamQuadIndex,y : tax : lda $0607, x : pha
|
||||||
lda CameraIndex,y : tax : pla : sta $e3, x : bra .done
|
lda CameraIndex,y : tax : pla : sta $e3, x
|
||||||
|
tya : asl : !add #$0c : tax : jsr AdjCamBounds : bra .done
|
||||||
|
|
||||||
.adjust
|
.done
|
||||||
lda CameraIndex,y : tax
|
lda CameraIndex,y : tax
|
||||||
.done lda $04 : sta $e2,x
|
lda $04 : sta $e2, x
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
|
||||||
|
; input, expects X to be an appropriate offset into the CamBoundBaseLine table
|
||||||
|
; when $04 is 0 no coordinate are added
|
||||||
|
AdjCamBounds: {
|
||||||
|
rep #$20 : lda CamBoundBaseLine, x : sta $05
|
||||||
|
lda $04 : and #$00ff : beq .common
|
||||||
|
lda CoordIndex,y : tax
|
||||||
|
lda $20, x : and #$00ff : !add $05 : sta $05
|
||||||
|
.common
|
||||||
|
lda OppCamBoundIndex,y : tax
|
||||||
|
lda $05 : sta $0618, x
|
||||||
|
inc #2 : sta $061A, x : sep #$20
|
||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
File diff suppressed because one or more lines are too long
16
notes.txt
16
notes.txt
@@ -1,9 +1,9 @@
|
|||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
|
Zero camera out skips quad logic
|
||||||
|
|
||||||
|
|
||||||
|
The armory guard room and the room above have fake layers. Shutter doors
|
||||||
The armory guard room and the room above have fake layers. Maybe not???
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -13,4 +13,14 @@ Notes 2:
|
|||||||
(Fixed partially )Guardroom N Door is set to $8000, I think it was supposed to be Eastern Compass Area SW $02a8 that how this get teleported back to HC. Wrong room index. Still might be a toggle door
|
(Fixed partially )Guardroom N Door is set to $8000, I think it was supposed to be Eastern Compass Area SW $02a8 that how this get teleported back to HC. Wrong room index. Still might be a toggle door
|
||||||
(Fixed) Courtyard N is set to $02D8 - typo
|
(Fixed) Courtyard N is set to $02D8 - typo
|
||||||
(Fixed) Sanc N is $0650 but should be $0250 which I think is right. typo again on the wrong layer
|
(Fixed) Sanc N is $0650 but should be $0250 which I think is right. typo again on the wrong layer
|
||||||
(Fixed) Eastern boss had wrong room
|
(Fixed) Eastern boss had wrong room
|
||||||
|
|
||||||
|
Pairing Notes
|
||||||
|
30-34 4f-37 #$18,-24
|
||||||
|
30-34 37-1f #$18,-24
|
||||||
|
30-34 1f-1f???
|
||||||
|
30-35 1f-1f
|
||||||
|
30-34 36-1e #$18,-24
|
||||||
|
30-34 1e-1f
|
||||||
|
|
||||||
|
inconsistencies are caused by $0492 being set wrong
|
||||||
Reference in New Issue
Block a user