Merge Unstable into EdgeWork

This commit is contained in:
aerinon
2020-04-24 14:02:47 -06:00
43 changed files with 1520 additions and 309 deletions

46
Rom.py
View File

@@ -10,7 +10,7 @@ import sys
import subprocess
from BaseClasses import CollectionState, ShopType, Region, Location, DoorType
from DoorShuffle import compass_data, DROptions
from DoorShuffle import compass_data, DROptions, boss_indicator
from Dungeons import dungeon_music_addresses
from Regions import location_table
from Text import MultiByteTextMapper, CompressedTextMapper, text_addresses, Credits, TextTable
@@ -22,7 +22,7 @@ from EntranceShuffle import door_addresses, exit_ids
JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '5e01caffabb4509a0987ef2f2f0bcd56'
RANDOMIZERBASEHASH = '6042de1d3a63417efe4397b69c626b88'
class JsonRom(object):
@@ -162,7 +162,7 @@ def read_rom(stream):
def patch_enemizer(world, player, rom, baserom_path, enemizercli, shufflepots, random_sprite_on_hit):
baserom_path = os.path.abspath(baserom_path)
basepatch_path = os.path.abspath(local_path('data/base2current.json'))
basepatch_path = os.path.abspath(local_path(os.path.join("data","base2current.json")))
enemizer_basepatch_path = os.path.join(os.path.dirname(enemizercli), "enemizerBasePatch.json")
randopatch_path = os.path.abspath(output_path('enemizer_randopatch.json'))
options_path = os.path.abspath(output_path('enemizer_options.json'))
@@ -305,7 +305,7 @@ def patch_enemizer(world, player, rom, baserom_path, enemizercli, shufflepots, r
_sprite_table = {}
def _populate_sprite_table():
if not _sprite_table:
for dir in [local_path('data/sprites/official'), local_path('data/sprites/unofficial')]:
for dir in [local_path(os.path.join("data","sprites","official")), local_path(os.path.join("data","sprites","unofficial"))]:
for file in os.listdir(dir):
filepath = os.path.join(dir, file)
if not os.path.isfile(filepath):
@@ -387,7 +387,7 @@ class Sprite(object):
@staticmethod
def default_link_sprite():
return Sprite(local_path('data/default.zspr'))
return get_sprite_from_name('Link')
def decode8(self, pos):
arr = [[0 for _ in range(8)] for _ in range(8)]
@@ -594,10 +594,22 @@ def patch_rom(world, rom, player, team, enemized):
if world.mode[player] == 'inverted':
patch_shuffled_dark_sanc(world, rom, player)
# setup dr option flags based on experimental, etc.
dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' else DROptions.Town_Portal
if world.experimental[player]:
dr_flags |= DROptions.Map_Info
# patch doors
dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' or not world.experimental[player] else DROptions.Town_Portal
if world.doorShuffle[player] == 'crossed':
rom.write_byte(0x139004, 2)
for name, layout in world.key_layout[player].items():
offset = compass_data[name][4]//2
rom.write_byte(0x13f01c+offset, layout.max_chests + layout.max_drops)
rom.write_byte(0x13f02a+offset, layout.max_chests)
builder = world.dungeon_layouts[player][name]
bk_status = 1 if builder.bk_required else 0
bk_status = 2 if builder.bk_provided else bk_status
rom.write_byte(0x13f038+offset*2, bk_status)
rom.write_byte(0x151f1, 2)
rom.write_byte(0x15270, 2)
rom.write_byte(0x1597b, 2)
@@ -622,6 +634,13 @@ def patch_rom(world, rom, player, team, enemized):
if builder.pre_open_stonewall:
if builder.pre_open_stonewall.name == 'Desert Wall Slide NW':
dr_flags |= DROptions.Open_Desert_Wall
for name, pair in boss_indicator.items():
dungeon_id, boss_door = pair
opposite_door = world.get_door(boss_door, player).dest
if opposite_door.roomIndex > -1:
dungeon_name = opposite_door.entrance.parent_region.dungeon.name
dungeon_id = boss_indicator[dungeon_name][0]
rom.write_byte(0x13f000+dungeon_id, opposite_door.roomIndex)
rom.write_byte(0x139006, dr_flags.value)
if dr_flags & DROptions.Town_Portal and world.mode[player] == 'inverted':
rom.write_byte(0x139008, 1)
@@ -1048,6 +1067,7 @@ def patch_rom(world, rom, player, team, enemized):
'Big Key (Desert Palace)': (0x367, 0x10), 'Compass (Desert Palace)': (0x365, 0x10), 'Map (Desert Palace)': (0x369, 0x10),
'Big Key (Tower of Hera)': (0x366, 0x20), 'Compass (Tower of Hera)': (0x364, 0x20), 'Map (Tower of Hera)': (0x368, 0x20),
'Big Key (Escape)': (0x367, 0xC0), 'Compass (Escape)': (0x365, 0xC0), 'Map (Escape)': (0x369, 0xC0),
'Big Key (Agahnims Tower)': (0x367, 0x08), 'Compass (Agahnims Tower)': (0x365, 0x08), 'Map (Agahnims Tower)': (0x369, 0x08),
'Big Key (Palace of Darkness)': (0x367, 0x02), 'Compass (Palace of Darkness)': (0x365, 0x02), 'Map (Palace of Darkness)': (0x369, 0x02),
'Big Key (Thieves Town)': (0x366, 0x10), 'Compass (Thieves Town)': (0x364, 0x10), 'Map (Thieves Town)': (0x368, 0x10),
'Big Key (Skull Woods)': (0x366, 0x80), 'Compass (Skull Woods)': (0x364, 0x80), 'Map (Skull Woods)': (0x368, 0x80),
@@ -1173,8 +1193,8 @@ def patch_rom(world, rom, player, team, enemized):
rom.write_byte(0x180045, ((0x01 if world.keyshuffle[player] else 0x00)
| (0x02 if world.bigkeyshuffle[player] else 0x00)
| (0x04 if world.compassshuffle[player] else 0x00)
| (0x08 if world.mapshuffle[player] else 0x00))) # free roaming items in menu
| (0x04 if world.mapshuffle[player] else 0x00)
| (0x08 if world.compassshuffle[player] else 0x00))) # free roaming items in menu
# Map reveals
reveal_bytes = {
@@ -1232,6 +1252,7 @@ def patch_rom(world, rom, player, team, enemized):
rom.write_bytes(0x180185, [0,0,0]) # Uncle respawn refills (magic, bombs, arrows)
rom.write_bytes(0x180188, [0,0,0]) # Zelda respawn refills (magic, bombs, arrows)
rom.write_bytes(0x18018B, [0,0,0]) # Mantle respawn refills (magic, bombs, arrows)
bow_max, bomb_max, magic_max = 0, 0, 0
if world.mode[player] == 'standard':
if uncle_location.item is not None and uncle_location.item.name in ['Bow', 'Progressive Bow']:
rom.write_byte(0x18004E, 1) # Escape Fill (arrows)
@@ -1239,16 +1260,25 @@ def patch_rom(world, rom, player, team, enemized):
rom.write_bytes(0x180185, [0,0,70]) # Uncle respawn refills (magic, bombs, arrows)
rom.write_bytes(0x180188, [0,0,10]) # Zelda respawn refills (magic, bombs, arrows)
rom.write_bytes(0x18018B, [0,0,10]) # Mantle respawn refills (magic, bombs, arrows)
bow_max = 70
elif uncle_location.item is not None and uncle_location.item.name in ['Bombs (10)']:
rom.write_byte(0x18004E, 2) # Escape Fill (bombs)
rom.write_bytes(0x180185, [0,50,0]) # Uncle respawn refills (magic, bombs, arrows)
rom.write_bytes(0x180188, [0,3,0]) # Zelda respawn refills (magic, bombs, arrows)
rom.write_bytes(0x18018B, [0,3,0]) # Mantle respawn refills (magic, bombs, arrows)
bomb_max = 50
elif uncle_location.item is not None and uncle_location.item.name in ['Cane of Somaria', 'Cane of Byrna', 'Fire Rod']:
rom.write_byte(0x18004E, 4) # Escape Fill (magic)
rom.write_bytes(0x180185, [0x80,0,0]) # Uncle respawn refills (magic, bombs, arrows)
rom.write_bytes(0x180188, [0x20,0,0]) # Zelda respawn refills (magic, bombs, arrows)
rom.write_bytes(0x18018B, [0x20,0,0]) # Mantle respawn refills (magic, bombs, arrows)
magic_max = 0x80
if world.doorShuffle[player] == 'crossed':
# Uncle respawn refills (magic, bombs, arrows)
rom.write_bytes(0x180185, [max(0x20, magic_max), max(3, bomb_max), max(10, bow_max)])
rom.write_bytes(0x180188, [0x20, 3, 10]) # Zelda respawn refills (magic, bombs, arrows)
rom.write_bytes(0x18018B, [0x20, 3, 10]) # Mantle respawn refills (magic, bombs, arrows)
# patch swamp: Need to enable permanent drain of water as dam or swamp were moved
rom.write_byte(0x18003D, 0x01 if world.swamp_patch_required[player] else 0x00)