Merge pull request #5 from KevinCathcart/Dev
Bunny logic and misc updates
This commit is contained in:
commit
1e4b0f0da3
268
AdjusterMain.py
268
AdjusterMain.py
|
@ -4,264 +4,8 @@ import os
|
|||
import time
|
||||
import logging
|
||||
|
||||
class LocalRom(object):
|
||||
from Rom import LocalRom, apply_rom_settings
|
||||
|
||||
def __init__(self, file):
|
||||
if (os.stat(file).st_size == 2097152 and os.path.splitext(file)[-1].lower() == '.sfc'):
|
||||
self.buffer = bytearray(open(file, 'rb').read())
|
||||
else:
|
||||
raise RuntimeError('Provided Rom is not a valid Link to the Past Randomizer Rom. Please provide one for adjusting.')
|
||||
|
||||
def write_byte(self, address, value):
|
||||
self.buffer[address] = value
|
||||
|
||||
def write_bytes(self, startaddress, values):
|
||||
for i, value in enumerate(values):
|
||||
self.write_byte(startaddress + i, value)
|
||||
|
||||
def write_int16_to_rom(self, address, value):
|
||||
self.write_bytes(address, int16_as_bytes(value))
|
||||
|
||||
def write_int32_to_rom(self, address, value):
|
||||
self.write_bytes(address, int32_as_bytes(value))
|
||||
|
||||
def write_to_file(self, file):
|
||||
with open(file, 'wb') as outfile:
|
||||
outfile.write(self.buffer)
|
||||
|
||||
def write_crc(self):
|
||||
crc = (sum(self.buffer[:0x7FDC] + self.buffer[0x7FE0:]) + 0x01FE) & 0xFFFF
|
||||
inv = crc ^ 0xFFFF
|
||||
self.write_bytes(0x7FDC, [inv & 0xFF, (inv >> 8) & 0xFF, crc & 0xFF, (crc >> 8) & 0xFF])
|
||||
|
||||
def write_sprite(rom, sprite):
|
||||
if len(sprite) == 0x7000:
|
||||
# sprite file with graphics and without palette data
|
||||
rom.write_bytes(0x80000, sprite[:0x7000])
|
||||
elif len(sprite) == 0x7078:
|
||||
# sprite file with graphics and palette data
|
||||
rom.write_bytes(0x80000, sprite[:0x7000])
|
||||
rom.write_bytes(0xDD308, sprite[0x7000:])
|
||||
rom.write_bytes(0xDEDF5, sprite[0x7036:0x7038])
|
||||
rom.write_bytes(0xDEDF7, sprite[0x7054:0x7056])
|
||||
elif len(sprite) in [0x100000, 0x200000]:
|
||||
# full rom with patched sprite, extract it
|
||||
rom.write_bytes(0x80000, sprite[0x80000:0x87000])
|
||||
rom.write_bytes(0xDD308, sprite[0xDD308:0xDD380])
|
||||
rom.write_bytes(0xDEDF5, sprite[0xDEDF5:0xDEDF9])
|
||||
|
||||
def patch_rom(rom, fastmenu=False, quickswap=False, disable_music=False, beep='normal', sprite=None):
|
||||
# enable instant item menu
|
||||
if fastmenu:
|
||||
rom.write_byte(0x180048, 0x01)
|
||||
# Sound twekas for fastmenu:
|
||||
rom.write_byte(0x6DD9A, 0x20)
|
||||
rom.write_byte(0x6DF2A, 0x20)
|
||||
rom.write_byte(0x6E0E9, 0x20)
|
||||
else:
|
||||
rom.write_byte(0x180048, 0x00)
|
||||
# Sound twekas for fastmenu:
|
||||
rom.write_byte(0x6DD9A, 0x11)
|
||||
rom.write_byte(0x6DF2A, 0x12)
|
||||
rom.write_byte(0x6E0E9, 0x12)
|
||||
|
||||
# enable quick item swapping with L and R (ported by Amazing Ampharos)
|
||||
if quickswap:
|
||||
rom.write_bytes(0x107fb, [0x22, 0x50, 0xFF, 0x1F])
|
||||
rom.write_bytes(0x12451, [0x22, 0x50, 0xFF, 0x1F])
|
||||
rom.write_bytes(0xfff50, [0x20, 0x58, 0xFF, 0xA5, 0xF6, 0x29, 0x40, 0x6B, 0xA5, 0xF6, 0x89, 0x10, 0xF0, 0x03, 0x4C, 0x69,
|
||||
0xFF, 0x89, 0x20, 0xF0, 0x03, 0x4C, 0xAA, 0xFF, 0x60, 0xAD, 0x02, 0x02, 0xF0, 0x3B, 0xDA, 0xAA,
|
||||
0xE0, 0x0F, 0xF0, 0x14, 0xE0, 0x10, 0xF0, 0x14, 0xE0, 0x14, 0xD0, 0x02, 0xA2, 0x00, 0xE8, 0xBF,
|
||||
0x3F, 0xF3, 0x7E, 0xF0, 0xEB, 0x4C, 0xEB, 0xFF, 0xA2, 0x01, 0x80, 0x0A, 0xAF, 0x4F, 0xF3, 0x7E,
|
||||
0xAA, 0xE0, 0x04, 0xF0, 0x10, 0xE8, 0xBF, 0x5B, 0xF3, 0x7E, 0xF0, 0xF5, 0x8A, 0x8F, 0x4F, 0xF3,
|
||||
0x7E, 0xA2, 0x10, 0x80, 0xE0, 0xA2, 0x11, 0x80, 0xD6, 0x60, 0xAD, 0x02, 0x02, 0xF0, 0x3B, 0xDA,
|
||||
0xAA, 0xE0, 0x11, 0xF0, 0x14, 0xE0, 0x10, 0xF0, 0x14, 0xE0, 0x01, 0xD0, 0x02, 0xA2, 0x15, 0xCA,
|
||||
0xBF, 0x3F, 0xF3, 0x7E, 0xF0, 0xEB, 0x4C, 0xEB, 0xFF, 0xA2, 0x04, 0x80, 0x0A, 0xAF, 0x4F, 0xF3,
|
||||
0x7E, 0xAA, 0xE0, 0x01, 0xF0, 0x10, 0xCA, 0xBF, 0x5B, 0xF3, 0x7E, 0xF0, 0xF5, 0x8A, 0x8F, 0x4F,
|
||||
0xF3, 0x7E, 0xA2, 0x10, 0x80, 0xE0, 0xA2, 0x0F, 0x80, 0xD6, 0x60, 0xA9, 0x20, 0x8D, 0x2F, 0x01,
|
||||
0x8E, 0x02, 0x02, 0x22, 0x7F, 0xDB, 0x0D, 0xFA, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
|
||||
else:
|
||||
rom.write_bytes(0x107fb, [0xa5, 0xf6, 0x29, 0x40])
|
||||
rom.write_bytes(0x12451, [0xa5, 0xf6, 0x29, 0x40])
|
||||
rom.write_bytes(0xfff50, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
|
||||
|
||||
if disable_music:
|
||||
volumeaddresses = [0xD373B, 0xD375B, 0xD90F8, 0xDA710, 0xDA7A4, 0xDA7BB, 0xDA7D2, 0xD5954, 0xD653B, 0xDA736, 0xDA752, 0xDA772, 0xDA792,
|
||||
0xD5B47, 0xD5B5E, 0xD4306, 0xD6878, 0xD6883, 0xD6E48, 0xD6E76, 0xD6EFB, 0xD6F2D, 0xDA211, 0xDA35B, 0xDA37B, 0xDA38E,
|
||||
0xDA39F, 0xDA5C3, 0xDA691, 0xDA6A8, 0xDA6DF, 0xD2349, 0xD3F45, 0xD42EB, 0xD48B9, 0xD48FF, 0xD543F, 0xD5817, 0xD5957,
|
||||
0xD5ACB, 0xD5AE8, 0xD5B4A, 0xDA5DE, 0xDA608, 0xDA635, 0xDA662, 0xDA71F, 0xDA7AF, 0xDA7C6, 0xDA7DD, 0xD2F00, 0xDA3D5,
|
||||
0xD249C, 0xD24CD, 0xD2C09, 0xD2C53, 0xD2CAF, 0xD2CEB, 0xD2D91, 0xD2EE6, 0xD38ED, 0xD3C91, 0xD3CD3, 0xD3CE8, 0xD3F0C,
|
||||
0xD3F82, 0xD405F, 0xD4139, 0xD4198, 0xD41D5, 0xD41F6, 0xD422B, 0xD4270, 0xD42B1, 0xD4334, 0xD4371, 0xD43A6, 0xD43DB,
|
||||
0xD441E, 0xD4597, 0xD4B3C, 0xD4BAB, 0xD4C03, 0xD4C53, 0xD4C7F, 0xD4D9C, 0xD5424, 0xD65D2, 0xD664F, 0xD6698, 0xD66FF,
|
||||
0xD6985, 0xD6C5C, 0xD6C6F, 0xD6C8E, 0xD6CB4, 0xD6D7D, 0xD827D, 0xD960C, 0xD9828, 0xDA233, 0xDA3A2, 0xDA49E, 0xDA72B,
|
||||
0xDA745, 0xDA765, 0xDA785, 0xDABF6, 0xDAC0D, 0xDAEBE, 0xDAFAC, 0xD9A02, 0xD9BD6, 0xD21CD, 0xD2279, 0xD2E66, 0xD2E70,
|
||||
0xD2EAB, 0xD3B97, 0xD3BAC, 0xD3BE8, 0xD3C0D, 0xD3C39, 0xD3C68, 0xD3C9F, 0xD3CBC, 0xD401E, 0xD4290, 0xD443E, 0xD456F,
|
||||
0xD47D3, 0xD4D43, 0xD4DCC, 0xD4EBA, 0xD4F0B, 0xD4FE5, 0xD5012, 0xD54BC, 0xD54D5, 0xD54F0, 0xD5509, 0xD57D8, 0xD59B9,
|
||||
0xD5A2F, 0xD5AEB, 0xD5E5E, 0xD5FE9, 0xD658F, 0xD674A, 0xD6827, 0xD69D6, 0xD69F5, 0xD6A05, 0xD6AE9, 0xD6DCF, 0xD6E20,
|
||||
0xD6ECB, 0xD71D4, 0xD71E6, 0xD7203, 0xD721E, 0xD8724, 0xD8732, 0xD9652, 0xD9698, 0xD9CBC, 0xD9DC0, 0xD9E49, 0xDAA68,
|
||||
0xDAA77, 0xDAA88, 0xDAA99, 0xDAF04, 0xD1D28, 0xD1D41, 0xD1D5C, 0xD1D77, 0xD1EEE, 0xD311D, 0xD31D1, 0xD4148, 0xD5543,
|
||||
0xD5B6F, 0xD65B3, 0xD6760, 0xD6B6B, 0xD6DF6, 0xD6E0D, 0xD73A1, 0xD814C, 0xD825D, 0xD82BE, 0xD8340, 0xD8394, 0xD842C,
|
||||
0xD8796, 0xD8903, 0xD892A, 0xD91E8, 0xD922B, 0xD92E0, 0xD937E, 0xD93C1, 0xDA958, 0xDA971, 0xDA98C, 0xDA9A7, 0xD1D92,
|
||||
0xD1DBD, 0xD1DEB, 0xD1F5D, 0xD1F9F, 0xD1FBD, 0xD1FDC, 0xD1FEA, 0xD20CA, 0xD21BB, 0xD22C9, 0xD2754, 0xD284C, 0xD2866,
|
||||
0xD2887, 0xD28A0, 0xD28BA, 0xD28DB, 0xD28F4, 0xD293E, 0xD2BF3, 0xD2C1F, 0xD2C69, 0xD2CA1, 0xD2CC5, 0xD2D05, 0xD2D73,
|
||||
0xD2DAF, 0xD2E3D, 0xD2F36, 0xD2F46, 0xD2F6F, 0xD2FCF, 0xD2FDF, 0xD302B, 0xD3086, 0xD3099, 0xD30A5, 0xD30CD, 0xD30F6,
|
||||
0xD3154, 0xD3184, 0xD333A, 0xD33D9, 0xD349F, 0xD354A, 0xD35E5, 0xD3624, 0xD363C, 0xD3672, 0xD3691, 0xD36B4, 0xD36C6,
|
||||
0xD3724, 0xD3767, 0xD38CB, 0xD3B1D, 0xD3B2F, 0xD3B55, 0xD3B70, 0xD3B81, 0xD3BBF, 0xD3D34, 0xD3D55, 0xD3D6E, 0xD3DC6,
|
||||
0xD3E04, 0xD3E38, 0xD3F65, 0xD3FA6, 0xD404F, 0xD4087, 0xD417A, 0xD41A0, 0xD425C, 0xD4319, 0xD433C, 0xD43EF, 0xD440C,
|
||||
0xD4452, 0xD4494, 0xD44B5, 0xD4512, 0xD45D1, 0xD45EF, 0xD4682, 0xD46C3, 0xD483C, 0xD4848, 0xD4855, 0xD4862, 0xD486F,
|
||||
0xD487C, 0xD4A1C, 0xD4A3B, 0xD4A60, 0xD4B27, 0xD4C7A, 0xD4D12, 0xD4D81, 0xD4E90, 0xD4ED6, 0xD4EE2, 0xD5005, 0xD502E,
|
||||
0xD503C, 0xD5081, 0xD51B1, 0xD51C7, 0xD51CF, 0xD51EF, 0xD520C, 0xD5214, 0xD5231, 0xD5257, 0xD526D, 0xD5275, 0xD52AF,
|
||||
0xD52BD, 0xD52CD, 0xD52DB, 0xD549C, 0xD5801, 0xD58A4, 0xD5A68, 0xD5A7F, 0xD5C12, 0xD5D71, 0xD5E10, 0xD5E9A, 0xD5F8B,
|
||||
0xD5FA4, 0xD651A, 0xD6542, 0xD65ED, 0xD661D, 0xD66D7, 0xD6776, 0xD68BD, 0xD68E5, 0xD6956, 0xD6973, 0xD69A8, 0xD6A51,
|
||||
0xD6A86, 0xD6B96, 0xD6C3E, 0xD6D4A, 0xD6E9C, 0xD6F80, 0xD717E, 0xD7190, 0xD71B9, 0xD811D, 0xD8139, 0xD816B, 0xD818A,
|
||||
0xD819E, 0xD81BE, 0xD829C, 0xD82E1, 0xD8306, 0xD830E, 0xD835E, 0xD83AB, 0xD83CA, 0xD83F0, 0xD83F8, 0xD844B, 0xD8479,
|
||||
0xD849E, 0xD84CB, 0xD84EB, 0xD84F3, 0xD854A, 0xD8573, 0xD859D, 0xD85B4, 0xD85CE, 0xD862A, 0xD8681, 0xD87E3, 0xD87FF,
|
||||
0xD887B, 0xD88C6, 0xD88E3, 0xD8944, 0xD897B, 0xD8C97, 0xD8CA4, 0xD8CB3, 0xD8CC2, 0xD8CD1, 0xD8D01, 0xD917B, 0xD918C,
|
||||
0xD919A, 0xD91B5, 0xD91D0, 0xD91DD, 0xD9220, 0xD9273, 0xD9284, 0xD9292, 0xD92AD, 0xD92C8, 0xD92D5, 0xD9311, 0xD9322,
|
||||
0xD9330, 0xD934B, 0xD9366, 0xD9373, 0xD93B6, 0xD97A6, 0xD97C2, 0xD97DC, 0xD97FB, 0xD9811, 0xD98FF, 0xD996F, 0xD99A8,
|
||||
0xD99D5, 0xD9A30, 0xD9A4E, 0xD9A6B, 0xD9A88, 0xD9AF7, 0xD9B1D, 0xD9B43, 0xD9B7C, 0xD9BA9, 0xD9C84, 0xD9C8D, 0xD9CAC,
|
||||
0xD9CE8, 0xD9CF3, 0xD9CFD, 0xD9D46, 0xDA35E, 0xDA37E, 0xDA391, 0xDA478, 0xDA4C3, 0xDA4D7, 0xDA4F6, 0xDA515, 0xDA6E2,
|
||||
0xDA9C2, 0xDA9ED, 0xDAA1B, 0xDAA57, 0xDABAF, 0xDABC9, 0xDABE2, 0xDAC28, 0xDAC46, 0xDAC63, 0xDACB8, 0xDACEC, 0xDAD08,
|
||||
0xDAD25, 0xDAD42, 0xDAD5F, 0xDAE17, 0xDAE34, 0xDAE51, 0xDAF2E, 0xDAF55, 0xDAF6B, 0xDAF81, 0xDB14F, 0xDB16B, 0xDB180,
|
||||
0xDB195, 0xDB1AA, 0xD2B88, 0xD364A, 0xD369F, 0xD3747, 0xD213F, 0xD2174, 0xD229E, 0xD2426, 0xD4731, 0xD4753, 0xD4774,
|
||||
0xD4795, 0xD47B6, 0xD4AA5, 0xD4AE4, 0xD4B96, 0xD4CA5, 0xD5477, 0xD5A3D, 0xD6566, 0xD672C, 0xD67C0, 0xD69B8, 0xD6AB1,
|
||||
0xD6C05, 0xD6DB3, 0xD71AB, 0xD8E2D, 0xD8F0D, 0xD94E0, 0xD9544, 0xD95A8, 0xD9982, 0xD9B56, 0xDA694, 0xDA6AB, 0xDAE88,
|
||||
0xDAEC8, 0xDAEE6, 0xDB1BF, 0xD210A, 0xD22DC, 0xD2447, 0xD5A4D, 0xD5DDC, 0xDA251, 0xDA26C, 0xD945E, 0xD967D, 0xD96C2,
|
||||
0xD9C95, 0xD9EE6, 0xDA5C6, 0xD2047, 0xD24C2, 0xD24EC, 0xD25A4, 0xD3DAA, 0xD51A8, 0xD51E6, 0xD524E, 0xD529E, 0xD6045,
|
||||
0xD81DE, 0xD821E, 0xD94AA, 0xD9A9E, 0xD9AE4, 0xDA289, 0xD2085, 0xD21C5, 0xD5F28]
|
||||
for address in volumeaddresses:
|
||||
rom.write_byte(address, 0x00)
|
||||
else:
|
||||
volumeaddresses1 = [0xD373B, 0xD375B, 0xD90F8]
|
||||
for address in volumeaddresses1:
|
||||
rom.write_byte(address, 0x00)
|
||||
volumeaddresses2 = [0xDA710, 0xDA7A4, 0xDA7BB, 0xDA7D2]
|
||||
for address in volumeaddresses2:
|
||||
rom.write_byte(address, 0x14)
|
||||
|
||||
volumeaddresses3 = [0xD5954, 0xD653B, 0xDA736, 0xDA752, 0xDA772, 0xDA792]
|
||||
for address in volumeaddresses3:
|
||||
rom.write_byte(address, 0x3C)
|
||||
|
||||
volumeaddresses4 = [0xD5B47, 0xD5B5E]
|
||||
for address in volumeaddresses4:
|
||||
rom.write_byte(address, 0x50)
|
||||
|
||||
rom.write_byte(0xD4306, 0x5A)
|
||||
|
||||
volumeaddresses5 = [0xD6878, 0xD6883, 0xD6E48, 0xD6E76, 0xD6EFB, 0xD6F2D, 0xDA211, 0xDA35B, 0xDA37B, 0xDA38E, 0xDA39F, 0xDA5C3, 0xDA691, 0xDA6A8, 0xDA6DF]
|
||||
for address in volumeaddresses5:
|
||||
rom.write_byte(address, 0x64)
|
||||
|
||||
volumeaddresses6 = [0xD2349, 0xD3F45, 0xD42EB, 0xD48B9, 0xD48FF, 0xD543F, 0xD5817, 0xD5957, 0xD5ACB, 0xD5AE8, 0xD5B4A, 0xDA5DE, 0xDA608, 0xDA635,
|
||||
0xDA662, 0xDA71F, 0xDA7AF, 0xDA7C6, 0xDA7DD]
|
||||
for address in volumeaddresses6:
|
||||
rom.write_byte(address, 0x78)
|
||||
|
||||
volumeaddresses7 = [0xD2F00, 0xDA3D5]
|
||||
for address in volumeaddresses7:
|
||||
rom.write_byte(address, 0x82)
|
||||
|
||||
volumeaddresses8 = [0xD249C, 0xD24CD, 0xD2C09, 0xD2C53, 0xD2CAF, 0xD2CEB, 0xD2D91, 0xD2EE6, 0xD38ED, 0xD3C91, 0xD3CD3, 0xD3CE8, 0xD3F0C,
|
||||
0xD3F82, 0xD405F, 0xD4139, 0xD4198, 0xD41D5, 0xD41F6, 0xD422B, 0xD4270, 0xD42B1, 0xD4334, 0xD4371, 0xD43A6, 0xD43DB,
|
||||
0xD441E, 0xD4597, 0xD4B3C, 0xD4BAB, 0xD4C03, 0xD4C53, 0xD4C7F, 0xD4D9C, 0xD5424, 0xD65D2, 0xD664F, 0xD6698, 0xD66FF,
|
||||
0xD6985, 0xD6C5C, 0xD6C6F, 0xD6C8E, 0xD6CB4, 0xD6D7D, 0xD827D, 0xD960C, 0xD9828, 0xDA233, 0xDA3A2, 0xDA49E, 0xDA72B,
|
||||
0xDA745, 0xDA765, 0xDA785, 0xDABF6, 0xDAC0D, 0xDAEBE, 0xDAFAC]
|
||||
for address in volumeaddresses8:
|
||||
rom.write_byte(address, 0xA0)
|
||||
|
||||
volumeaddresses9 = [0xD9A02, 0xD9BD6]
|
||||
for address in volumeaddresses9:
|
||||
rom.write_byte(address, 0xAA)
|
||||
|
||||
volumeaddressesA = [0xD21CD, 0xD2279, 0xD2E66, 0xD2E70, 0xD2EAB, 0xD3B97, 0xD3BAC, 0xD3BE8, 0xD3C0D, 0xD3C39, 0xD3C68, 0xD3C9F, 0xD3CBC,
|
||||
0xD401E, 0xD4290, 0xD443E, 0xD456F, 0xD47D3, 0xD4D43, 0xD4DCC, 0xD4EBA, 0xD4F0B, 0xD4FE5, 0xD5012, 0xD54BC, 0xD54D5,
|
||||
0xD54F0, 0xD5509, 0xD57D8, 0xD59B9, 0xD5A2F, 0xD5AEB, 0xD5E5E, 0xD5FE9, 0xD658F, 0xD674A, 0xD6827, 0xD69D6, 0xD69F5,
|
||||
0xD6A05, 0xD6AE9, 0xD6DCF, 0xD6E20, 0xD6ECB, 0xD71D4, 0xD71E6, 0xD7203, 0xD721E, 0xD8724, 0xD8732, 0xD9652, 0xD9698,
|
||||
0xD9CBC, 0xD9DC0, 0xD9E49, 0xDAA68, 0xDAA77, 0xDAA88, 0xDAA99, 0xDAF04]
|
||||
for address in volumeaddressesA:
|
||||
rom.write_byte(address, 0xB4)
|
||||
|
||||
volumeaddressesB = [0xD1D28, 0xD1D41, 0xD1D5C, 0xD1D77, 0xD1EEE, 0xD311D, 0xD31D1, 0xD4148, 0xD5543, 0xD5B6F, 0xD65B3, 0xD6760, 0xD6B6B,
|
||||
0xD6DF6, 0xD6E0D, 0xD73A1, 0xD814C, 0xD825D, 0xD82BE, 0xD8340, 0xD8394, 0xD842C, 0xD8796, 0xD8903, 0xD892A, 0xD91E8,
|
||||
0xD922B, 0xD92E0, 0xD937E, 0xD93C1, 0xDA958, 0xDA971, 0xDA98C, 0xDA9A7]
|
||||
for address in volumeaddressesB:
|
||||
rom.write_byte(address, 0x8C)
|
||||
|
||||
volumeaddressesC = [0xD1D92, 0xD1DBD, 0xD1DEB, 0xD1F5D, 0xD1F9F, 0xD1FBD, 0xD1FDC, 0xD1FEA, 0xD20CA, 0xD21BB, 0xD22C9, 0xD2754, 0xD284C,
|
||||
0xD2866, 0xD2887, 0xD28A0, 0xD28BA, 0xD28DB, 0xD28F4, 0xD293E, 0xD2BF3, 0xD2C1F, 0xD2C69, 0xD2CA1, 0xD2CC5, 0xD2D05,
|
||||
0xD2D73, 0xD2DAF, 0xD2E3D, 0xD2F36, 0xD2F46, 0xD2F6F, 0xD2FCF, 0xD2FDF, 0xD302B, 0xD3086, 0xD3099, 0xD30A5, 0xD30CD,
|
||||
0xD30F6, 0xD3154, 0xD3184, 0xD333A, 0xD33D9, 0xD349F, 0xD354A, 0xD35E5, 0xD3624, 0xD363C, 0xD3672, 0xD3691, 0xD36B4,
|
||||
0xD36C6, 0xD3724, 0xD3767, 0xD38CB, 0xD3B1D, 0xD3B2F, 0xD3B55, 0xD3B70, 0xD3B81, 0xD3BBF, 0xD3D34, 0xD3D55, 0xD3D6E,
|
||||
0xD3DC6, 0xD3E04, 0xD3E38, 0xD3F65, 0xD3FA6, 0xD404F, 0xD4087, 0xD417A, 0xD41A0, 0xD425C, 0xD4319, 0xD433C, 0xD43EF,
|
||||
0xD440C, 0xD4452, 0xD4494, 0xD44B5, 0xD4512, 0xD45D1, 0xD45EF, 0xD4682, 0xD46C3, 0xD483C, 0xD4848, 0xD4855, 0xD4862,
|
||||
0xD486F, 0xD487C, 0xD4A1C, 0xD4A3B, 0xD4A60, 0xD4B27, 0xD4C7A, 0xD4D12, 0xD4D81, 0xD4E90, 0xD4ED6, 0xD4EE2, 0xD5005,
|
||||
0xD502E, 0xD503C, 0xD5081, 0xD51B1, 0xD51C7, 0xD51CF, 0xD51EF, 0xD520C, 0xD5214, 0xD5231, 0xD5257, 0xD526D, 0xD5275,
|
||||
0xD52AF, 0xD52BD, 0xD52CD, 0xD52DB, 0xD549C, 0xD5801, 0xD58A4, 0xD5A68, 0xD5A7F, 0xD5C12, 0xD5D71, 0xD5E10, 0xD5E9A,
|
||||
0xD5F8B, 0xD5FA4, 0xD651A, 0xD6542, 0xD65ED, 0xD661D, 0xD66D7, 0xD6776, 0xD68BD, 0xD68E5, 0xD6956, 0xD6973, 0xD69A8,
|
||||
0xD6A51, 0xD6A86, 0xD6B96, 0xD6C3E, 0xD6D4A, 0xD6E9C, 0xD6F80, 0xD717E, 0xD7190, 0xD71B9, 0xD811D, 0xD8139, 0xD816B,
|
||||
0xD818A, 0xD819E, 0xD81BE, 0xD829C, 0xD82E1, 0xD8306, 0xD830E, 0xD835E, 0xD83AB, 0xD83CA, 0xD83F0, 0xD83F8, 0xD844B,
|
||||
0xD8479, 0xD849E, 0xD84CB, 0xD84EB, 0xD84F3, 0xD854A, 0xD8573, 0xD859D, 0xD85B4, 0xD85CE, 0xD862A, 0xD8681, 0xD87E3,
|
||||
0xD87FF, 0xD887B, 0xD88C6, 0xD88E3, 0xD8944, 0xD897B, 0xD8C97, 0xD8CA4, 0xD8CB3, 0xD8CC2, 0xD8CD1, 0xD8D01, 0xD917B,
|
||||
0xD918C, 0xD919A, 0xD91B5, 0xD91D0, 0xD91DD, 0xD9220, 0xD9273, 0xD9284, 0xD9292, 0xD92AD, 0xD92C8, 0xD92D5, 0xD9311,
|
||||
0xD9322, 0xD9330, 0xD934B, 0xD9366, 0xD9373, 0xD93B6, 0xD97A6, 0xD97C2, 0xD97DC, 0xD97FB, 0xD9811, 0xD98FF, 0xD996F,
|
||||
0xD99A8, 0xD99D5, 0xD9A30, 0xD9A4E, 0xD9A6B, 0xD9A88, 0xD9AF7, 0xD9B1D, 0xD9B43, 0xD9B7C, 0xD9BA9, 0xD9C84, 0xD9C8D,
|
||||
0xD9CAC, 0xD9CE8, 0xD9CF3, 0xD9CFD, 0xD9D46, 0xDA35E, 0xDA37E, 0xDA391, 0xDA478, 0xDA4C3, 0xDA4D7, 0xDA4F6, 0xDA515,
|
||||
0xDA6E2, 0xDA9C2, 0xDA9ED, 0xDAA1B, 0xDAA57, 0xDABAF, 0xDABC9, 0xDABE2, 0xDAC28, 0xDAC46, 0xDAC63, 0xDACB8, 0xDACEC,
|
||||
0xDAD08, 0xDAD25, 0xDAD42, 0xDAD5F, 0xDAE17, 0xDAE34, 0xDAE51, 0xDAF2E, 0xDAF55, 0xDAF6B, 0xDAF81, 0xDB14F, 0xDB16B,
|
||||
0xDB180, 0xDB195, 0xDB1AA]
|
||||
for address in volumeaddressesC:
|
||||
rom.write_byte(address, 0xC8)
|
||||
|
||||
volumeaddressesD = [0xD2B88, 0xD364A, 0xD369F, 0xD3747]
|
||||
for address in volumeaddressesD:
|
||||
rom.write_byte(address, 0xD2)
|
||||
|
||||
volumeaddressesE = [0xD213F, 0xD2174, 0xD229E, 0xD2426, 0xD4731, 0xD4753, 0xD4774, 0xD4795, 0xD47B6, 0xD4AA5, 0xD4AE4, 0xD4B96, 0xD4CA5,
|
||||
0xD5477, 0xD5A3D, 0xD6566, 0xD672C, 0xD67C0, 0xD69B8, 0xD6AB1, 0xD6C05, 0xD6DB3, 0xD71AB, 0xD8E2D, 0xD8F0D, 0xD94E0,
|
||||
0xD9544, 0xD95A8, 0xD9982, 0xD9B56, 0xDA694, 0xDA6AB, 0xDAE88, 0xDAEC8, 0xDAEE6, 0xDB1BF]
|
||||
for address in volumeaddressesE:
|
||||
rom.write_byte(address, 0xDC)
|
||||
|
||||
volumeaddressesF = [0xD210A, 0xD22DC, 0xD2447, 0xD5A4D, 0xD5DDC, 0xDA251, 0xDA26C]
|
||||
for address in volumeaddressesF:
|
||||
rom.write_byte(address, 0xE6)
|
||||
|
||||
volumeaddressesG = [0xD945E, 0xD967D, 0xD96C2, 0xD9C95, 0xD9EE6, 0xDA5C6]
|
||||
for address in volumeaddressesG:
|
||||
rom.write_byte(address, 0xF0)
|
||||
|
||||
volumeaddressesH = [0xD2047, 0xD24C2, 0xD24EC, 0xD25A4, 0xD3DAA, 0xD51A8, 0xD51E6, 0xD524E, 0xD529E, 0xD6045, 0xD81DE, 0xD821E, 0xD94AA,
|
||||
0xD9A9E, 0xD9AE4, 0xDA289]
|
||||
for address in volumeaddressesG:
|
||||
rom.write_byte(address, 0xFA)
|
||||
|
||||
volumeaddressesI = [0xD2085, 0xD21C5, 0xD5F28]
|
||||
for address in volumeaddressesI:
|
||||
rom.write_byte(address, 0xFF)
|
||||
|
||||
|
||||
# set heart beep rate
|
||||
rom.write_byte(0x180033, {'off': 0x00, 'half': 0x40, 'quarter': 0x80, 'normal': 0x20}[beep])
|
||||
|
||||
# write link sprite if required
|
||||
if sprite is not None:
|
||||
write_sprite(rom, sprite)
|
||||
|
||||
if isinstance(rom, LocalRom):
|
||||
rom.write_crc()
|
||||
|
||||
return rom
|
||||
|
||||
def adjust(args):
|
||||
start = time.clock()
|
||||
|
@ -275,12 +19,16 @@ def adjust(args):
|
|||
|
||||
outfilebase = 'ER_adjusted'
|
||||
|
||||
rom = LocalRom(args.rom)
|
||||
patch_rom(rom, args.fastmenu, args.quickswap, args.disablemusic, args.heartbeep, sprite)
|
||||
if (os.stat(args.rom).st_size == 2097152 and os.path.splitext(args.rom)[-1].lower() == '.sfc'):
|
||||
rom = LocalRom(args.rom, False)
|
||||
else:
|
||||
raise RuntimeError('Provided Rom is not a valid Link to the Past Randomizer Rom. Please provide one for adjusting.')
|
||||
|
||||
apply_rom_settings(rom, args.heartbeep, args.quickswap, args.fastmenu, args.disablemusic, sprite)
|
||||
|
||||
rom.write_to_file(output_path('%s.sfc' % outfilebase))
|
||||
|
||||
logger.info('Done. Enjoy.')
|
||||
logger.debug('Total Time: %s' % (time.clock() - start))
|
||||
|
||||
return args
|
||||
return args
|
||||
|
|
|
@ -473,6 +473,7 @@ class Region(object):
|
|||
self.locations = []
|
||||
self.dungeon = None
|
||||
self.world = None
|
||||
self.is_light_world = False # will be set aftermaking connections.
|
||||
self.spot_type = 'Region'
|
||||
self.hint_text = 'Hyrule'
|
||||
self.recursion_count = 0
|
||||
|
|
|
@ -18,7 +18,7 @@ def create_dungeons(world):
|
|||
AT = make_dungeon('Agahnims Tower', ['Agahnims Tower', 'Agahnim 1'], None, ItemFactory(['Small Key (Agahnims Tower)'] * 2), [])
|
||||
PoD = make_dungeon('Palace of Darkness', ['Palace of Darkness (Entrance)', 'Palace of Darkness (Center)', 'Palace of Darkness (Big Key Chest)', 'Palace of Darkness (Bonk Section)', 'Palace of Darkness (North)', 'Palace of Darkness (Maze)', 'Palace of Darkness (Harmless Hellway)', 'Palace of Darkness (Final Section)'], ItemFactory('Big Key (Palace of Darkness)'), ItemFactory(['Small Key (Palace of Darkness)'] * 6), ItemFactory(['Map (Palace of Darkness)', 'Compass (Palace of Darkness)']))
|
||||
TT = make_dungeon('Thieves Town', ['Thieves Town (Entrance)', 'Thieves Town (Deep)', 'Blind Fight'], ItemFactory('Big Key (Thieves Town)'), [ItemFactory('Small Key (Thieves Town)')], ItemFactory(['Map (Thieves Town)', 'Compass (Thieves Town)']))
|
||||
SW = make_dungeon('Skull Woods', ['Skull Woods Final Section (Entrance)', 'Skull Woods First Section', 'Skull Woods Second Section', 'Skull Woods Final Section (Mothula)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)'], ItemFactory('Big Key (Skull Woods)'), ItemFactory(['Small Key (Skull Woods)'] * 2), ItemFactory(['Map (Skull Woods)', 'Compass (Skull Woods)']))
|
||||
SW = make_dungeon('Skull Woods', ['Skull Woods Final Section (Entrance)', 'Skull Woods First Section', 'Skull Woods Second Section', 'Skull Woods Second Section (Drop)', 'Skull Woods Final Section (Mothula)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)'], ItemFactory('Big Key (Skull Woods)'), ItemFactory(['Small Key (Skull Woods)'] * 2), ItemFactory(['Map (Skull Woods)', 'Compass (Skull Woods)']))
|
||||
SP = make_dungeon('Swamp Palace', ['Swamp Palace (Entrance)', 'Swamp Palace (First Room)', 'Swamp Palace (Starting Area)', 'Swamp Palace (Center)', 'Swamp Palace (North)'], ItemFactory('Big Key (Swamp Palace)'), [ItemFactory('Small Key (Swamp Palace)')], ItemFactory(['Map (Swamp Palace)', 'Compass (Swamp Palace)']))
|
||||
IP = make_dungeon('Ice Palace', ['Ice Palace (Entrance)', 'Ice Palace (Main)', 'Ice Palace (East)', 'Ice Palace (East Top)', 'Ice Palace (Kholdstare)'], ItemFactory('Big Key (Ice Palace)'), ItemFactory(['Small Key (Ice Palace)'] * 2), ItemFactory(['Map (Ice Palace)', 'Compass (Ice Palace)']))
|
||||
MM = make_dungeon('Misery Mire', ['Misery Mire (Entrance)', 'Misery Mire (Main)', 'Misery Mire (West)', 'Misery Mire (Final Area)', 'Misery Mire (Vitreous)'], ItemFactory('Big Key (Misery Mire)'), ItemFactory(['Small Key (Misery Mire)'] * 3), ItemFactory(['Map (Misery Mire)', 'Compass (Misery Mire)']))
|
||||
|
|
|
@ -191,7 +191,7 @@ if __name__ == '__main__':
|
|||
''')
|
||||
args = parser.parse_args()
|
||||
|
||||
if is_bundled and len(sys.argv) == 1 :
|
||||
if is_bundled() and len(sys.argv) == 1 :
|
||||
# for the bundled builds, if we have no arguments, the user
|
||||
# probably wants the gui. Users of the bundled build who want the command line
|
||||
# interface shouuld specify at least one option, possibly setting a value to a
|
||||
|
|
|
@ -293,7 +293,7 @@ def link_entrances(world):
|
|||
('North Fairy Cave Exit', 'North Fairy Cave'),
|
||||
('Lost Woods Hideout Exit', 'Lost Woods Hideout (top)'),
|
||||
('Lumberjack Tree Exit', 'Lumberjack Tree (top)'),
|
||||
(('Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'), 'Skull Woods Second Section')]
|
||||
(('Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'), 'Skull Woods Second Section (Drop)')]
|
||||
|
||||
if world.mode == 'standard':
|
||||
# cannot move uncle cave
|
||||
|
@ -519,7 +519,7 @@ def link_entrances(world):
|
|||
hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave',
|
||||
'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole']
|
||||
|
||||
hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Woods Second Section',
|
||||
hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Woods Second Section (Drop)',
|
||||
'Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)']
|
||||
|
||||
if world.mode == 'standard':
|
||||
|
@ -834,7 +834,7 @@ def connect_doors(world, doors, targets):
|
|||
|
||||
def skull_woods_shuffle(world):
|
||||
connect_random(world, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'],
|
||||
['Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)', 'Skull Woods Second Section'])
|
||||
['Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)', 'Skull Woods Second Section (Drop)'])
|
||||
connect_random(world, ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'],
|
||||
['Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'], True)
|
||||
|
||||
|
@ -1173,6 +1173,8 @@ mandatory_connections = [('Links House', 'Links House'), # unshuffled. For now
|
|||
('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'),
|
||||
('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'),
|
||||
('Death Mountain Return Ledge Drop', 'Light World'),
|
||||
('Old Man House Front to Back', 'Old Man House Back'),
|
||||
('Old Man House Back to Front', 'Old Man House'),
|
||||
('Broken Bridge (West)', 'East Death Mountain (Bottom)'),
|
||||
('Broken Bridge (East)', 'Death Mountain'),
|
||||
('East Death Mountain Drop', 'East Death Mountain (Bottom)'),
|
||||
|
@ -1232,6 +1234,7 @@ mandatory_connections = [('Links House', 'Links House'), # unshuffled. For now
|
|||
('Turtle Rock Teleporter', 'Turtle Rock (Top)'),
|
||||
('Turtle Rock Drop', 'Dark Death Mountain (Top)'),
|
||||
('Floating Island Drop', 'Dark Death Mountain (Top)'),
|
||||
('Floating Island Mirror Spot', 'Death Mountain Floating Island (Light World)'),
|
||||
('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'),
|
||||
('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'),
|
||||
('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'),
|
||||
|
@ -1249,6 +1252,7 @@ mandatory_connections = [('Links House', 'Links House'), # unshuffled. For now
|
|||
('Skull Woods First Section (Left) Door to Right', 'Skull Woods First Section (Right)'),
|
||||
('Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section'),
|
||||
('Skull Woods First Section (Top) One-Way Path', 'Skull Woods First Section'),
|
||||
('Skull Woods Second Section (Drop)', 'Skull Woods Second Section'),
|
||||
('Blind Fight', 'Blind Fight'),
|
||||
('Ice Palace Entrance Room', 'Ice Palace (Main)'),
|
||||
('Ice Palace (East)', 'Ice Palace (East)'),
|
||||
|
@ -1439,7 +1443,7 @@ default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'),
|
|||
('Superbunny Cave Exit (Top)', 'Dark Death Mountain (Top)'),
|
||||
('Superbunny Cave Exit (Bottom)', 'Dark Death Mountain (East Bottom)'),
|
||||
('Hookshot Cave Exit (South)', 'Dark Death Mountain (Top)'),
|
||||
('Hookshot Cave Exit (North)', 'Death Mountain Floating Island'),
|
||||
('Hookshot Cave Exit (North)', 'Death Mountain Floating Island (Dark World)'),
|
||||
('Hookshot Cave Back Entrance', 'Hookshot Cave'),
|
||||
('Mimic Cave Mirror Spot', 'Mimic Cave'),
|
||||
|
||||
|
@ -1479,7 +1483,7 @@ default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert Palace
|
|||
('Skull Woods First Section Hole (North)', 'Skull Woods First Section (Top)'),
|
||||
('Skull Woods First Section Door', 'Skull Woods First Section'),
|
||||
('Skull Woods First Section Exit', 'Skull Woods Forest'),
|
||||
('Skull Woods Second Section Hole', 'Skull Woods Second Section'),
|
||||
('Skull Woods Second Section Hole', 'Skull Woods Second Section (Drop)'),
|
||||
('Skull Woods Second Section Door (East)', 'Skull Woods Second Section'),
|
||||
('Skull Woods Second Section Door (West)', 'Skull Woods Second Section'),
|
||||
('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'),
|
||||
|
@ -1772,7 +1776,7 @@ exit_ids = {'Desert Palace Exit (South)': (0x09, 0x84),
|
|||
'Lost Woods Hideout (top)': 0x7A,
|
||||
'Lumberjack Tree (top)': 0x7F,
|
||||
'Sewer Drop': 0x81,
|
||||
'Skull Woods Second Section': 0x79,
|
||||
'Skull Woods Second Section (Drop)': 0x79,
|
||||
'Skull Woods First Section (Left)': 0x77,
|
||||
'Skull Woods First Section (Right)': 0x78,
|
||||
'Skull Woods First Section (Top)': 0x76,
|
||||
|
|
7
Main.py
7
Main.py
|
@ -1,5 +1,5 @@
|
|||
from BaseClasses import World, CollectionState, Item
|
||||
from Regions import create_regions
|
||||
from Regions import create_regions, mark_light_world_regions
|
||||
from EntranceShuffle import link_entrances
|
||||
from Rom import patch_rom, LocalRom, JsonRom
|
||||
from Rules import set_rules
|
||||
|
@ -48,6 +48,7 @@ def main(args, seed=None):
|
|||
logger.info('Shuffling the World about.')
|
||||
|
||||
link_entrances(world)
|
||||
mark_light_world_regions(world)
|
||||
|
||||
logger.info('Calculating Access Rules.')
|
||||
|
||||
|
@ -134,8 +135,10 @@ def copy_world(world):
|
|||
|
||||
# connect copied world
|
||||
for region in world.regions:
|
||||
copied_region = ret.get_region(region.name)
|
||||
copied_region.is_light_world = region.is_light_world
|
||||
for entrance in region.entrances:
|
||||
ret.get_entrance(entrance.name).connect(ret.get_region(region.name))
|
||||
ret.get_entrance(entrance.name).connect(copied_region)
|
||||
|
||||
# fill locations
|
||||
for location in world.get_locations():
|
||||
|
|
26
Regions.py
26
Regions.py
|
@ -1,3 +1,4 @@
|
|||
import collections
|
||||
from BaseClasses import Region, Location, Entrance
|
||||
|
||||
|
||||
|
@ -178,7 +179,8 @@ def create_regions(world):
|
|||
create_region('Spike Cave', ['Spike Cave']),
|
||||
create_region('Hookshot Cave', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'],
|
||||
['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']),
|
||||
create_region('Death Mountain Floating Island', ['Floating Island'], ['Floating Island Drop', 'Hookshot Cave Back Entrance']),
|
||||
create_region('Death Mountain Floating Island (Dark World)', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance', 'Floating Island Mirror Spot']),
|
||||
create_region('Death Mountain Floating Island (Light World)', ['Floating Island'] ),
|
||||
create_region('Turtle Rock (Top)', None, ['Turtle Rock Drop']),
|
||||
create_region('Mimic Cave', ['Mimic Cave']),
|
||||
|
||||
|
@ -201,6 +203,7 @@ def create_regions(world):
|
|||
create_region('Skull Woods First Section (Right)', ['Skull Woods - Pinball Room'], ['Skull Woods First Section (Right) North Door']),
|
||||
create_region('Skull Woods First Section (Left)', ['Skull Woods - Compass Chest', 'Skull Woods - Pot Prison'], ['Skull Woods First Section (Left) Door to Exit', 'Skull Woods First Section (Left) Door to Right']),
|
||||
create_region('Skull Woods First Section (Top)', ['Skull Woods - Big Chest'], ['Skull Woods First Section (Top) One-Way Path']),
|
||||
create_region('Skull Woods Second Section (Drop)', None, ['Skull Woods Second Section (Drop)']),
|
||||
create_region('Skull Woods Second Section', ['Skull Woods - Big Key Chest'], ['Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)']),
|
||||
create_region('Skull Woods Final Section (Entrance)', ['Skull Woods - Bridge Room'], ['Skull Woods Torch Room', 'Skull Woods Final Section Exit']),
|
||||
create_region('Skull Woods Final Section (Mothula)', ['Skull Woods - Mothula', 'Skull Woods - Prize']),
|
||||
|
@ -282,6 +285,27 @@ def create_region(name, locations=None, exits=None):
|
|||
return ret
|
||||
|
||||
|
||||
def mark_light_world_regions(world):
|
||||
# Note that in "inanity" shuffle this code may mark some dark world locations as being in light world. That is fine because this flag
|
||||
# is only used for bunny logic, and you start with a Moon pearl immediately availible in Insanity shuffle.
|
||||
|
||||
# Exclude entrances that represent connections from the light world to the dark world
|
||||
excluded_entrances = set(['Top of Pyramid', 'Lake Hylia Central Island Teleporter', 'Dark Desert Teleporter', 'East Hyrule Teleporter', 'South Hyrule Teleporter', 'Kakariko Teleporter', 'Death Mountain Teleporter', 'East Death Mountain Teleporter', 'Turtle Rock Teleporter'])
|
||||
|
||||
starting_regions = ['Links House', 'Cave 45', 'Graveyard Cave','Mimic Cave', 'Death Mountain Floating Island (Light World)','Desert Ledge (West)', 'Lake Hylia Island', 'Spectacle Rock']
|
||||
queue = collections.deque([world.get_region(region) for region in starting_regions])
|
||||
seen = set(queue)
|
||||
while queue:
|
||||
current = queue.popleft()
|
||||
current.is_light_world = True
|
||||
for exit in current.exits:
|
||||
if exit.name in excluded_entrances:
|
||||
continue
|
||||
if exit.connected_region not in seen:
|
||||
seen.add(exit.connected_region)
|
||||
queue.append(exit.connected_region)
|
||||
|
||||
|
||||
location_table = {'Mushroom': (0x180013, False, 'in the woods'),
|
||||
'Bottle Merchant': (0x2EB18, False, 'with a merchant'),
|
||||
'Flute Spot': (0x18014A, False, 'underground'),
|
||||
|
|
246
Rom.py
246
Rom.py
|
@ -35,9 +35,10 @@ class JsonRom(object):
|
|||
|
||||
class LocalRom(object):
|
||||
|
||||
def __init__(self, file):
|
||||
def __init__(self, file, patch=True):
|
||||
self.buffer = bytearray(open(file, 'rb').read())
|
||||
self.patch_base_rom()
|
||||
if patch:
|
||||
self.patch_base_rom()
|
||||
|
||||
def write_byte(self, address, value):
|
||||
self.buffer[address] = value
|
||||
|
@ -197,6 +198,8 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
rom.write_byte(0x34FD6, 0x80)
|
||||
#Set overflow items for progressive equipment
|
||||
rom.write_bytes(0x180090, [0x03, 0x47, 0x02, 0x47, 0x01, 0x47, 0x02, 0x47])
|
||||
# Rupoor negative value
|
||||
rom.write_int16_to_rom(0x180036, 10)
|
||||
#Make Blue Shield more expensive
|
||||
rom.write_bytes(0xF73D2, [0xFC, 0xFF])
|
||||
rom.write_bytes(0xF73DA, [0x04, 0x00])
|
||||
|
@ -230,6 +233,8 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
rom.write_byte(0x34FD6, 0x80)
|
||||
#Set overflow items for progressive equipment
|
||||
rom.write_bytes(0x180090, [0x02, 0x47, 0x00, 0x47, 0x00, 0x47, 0x01, 0x47])
|
||||
# Rupoor negative value
|
||||
rom.write_int16_to_rom(0x180036, 20)
|
||||
#Make Blue Shield more expensive
|
||||
rom.write_bytes(0xF73D2, [0xFC, 0xFF])
|
||||
rom.write_bytes(0xF73DA, [0x04, 0x00])
|
||||
|
@ -263,6 +268,8 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
rom.write_byte(0x34FD6, 0x80)
|
||||
#Set overflow items for progressive equipment
|
||||
rom.write_bytes(0x180090, [0x02, 0x47, 0x00, 0x47, 0x00, 0x47, 0x01, 0x47])
|
||||
# Rupoor negative value
|
||||
rom.write_int16_to_rom(0x180036, 9999)
|
||||
#Make Blue Shield more expensive
|
||||
rom.write_bytes(0xF73D2, [0xFC, 0xFF])
|
||||
rom.write_bytes(0xF73DA, [0x04, 0x00])
|
||||
|
@ -288,6 +295,12 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
rom.write_byte(0x180084, 0xA0) # full
|
||||
# potion magic restore amount
|
||||
rom.write_byte(0x180085, 0x80) # full
|
||||
#Cape magic cost
|
||||
rom.write_bytes(0x3ADA7, [0x04, 0x08, 0x10])
|
||||
#Byrna residual magic cost
|
||||
rom.write_bytes(0x3ADA7, [0x04, 0x02, 0x01])
|
||||
#Enable catching fairies
|
||||
rom.write_byte(0x34FD6, 0xF0)
|
||||
#Set overflow items for progressive equipment
|
||||
if world.goal == 'triforcehunt':
|
||||
rom.write_bytes(0x180090, [0x04, 0x6C, 0x03, 0x6C, 0x02, 0x6C, 0x04, 0x6C])
|
||||
|
@ -296,6 +309,8 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
else:
|
||||
rom.write_bytes(0x180090, [0x04, 0x47, 0x03, 0x47, 0x02, 0x47, 0x04, 0x47])
|
||||
|
||||
# TODO: FIXME: need to set capcity upgrade fills (2,3,0,0) for easy, (0,0,0,0) otherwise
|
||||
|
||||
# set up game internal RNG seed
|
||||
for i in range(1024):
|
||||
rom.write_byte(0x178000 + i, random.randint(0, 255))
|
||||
|
@ -347,16 +362,17 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
rom.write_byte(0x6B632 + i, (vanilla_prize_pack_assignment[i] & 0xF0) | random.randint(1, 7))
|
||||
|
||||
# set bonk prizes
|
||||
bonk_prizes = [0x79, 0xE3, 0x79, 0xAC, 0xAC, 0xE0, 0xDC, 0xAC, 0xE3, 0xE3, 0xDA, 0xE3, 0xDA, 0xD8, 0xAC, 0xAC, 0xE3, 0xD8, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xDC, 0xDB, 0xE3, 0xDA, 0x79, 0x79, 0xE3, 0xE3,
|
||||
0xDA, 0x79, 0xAC, 0xAC, 0x79, 0xE3, 0x79, 0xAC, 0xAC, 0xE0, 0xDC, 0xE3, 0x79, 0xDE, 0xE3, 0xAC, 0xDB, 0x79, 0xE3, 0xD8, 0xAC, 0x79, 0xE3, 0xDB, 0xDB, 0xE3, 0xE3, 0x79, 0xD8, 0xDD]
|
||||
bonk_addresses = [0x4CF6C, 0x4CFBA, 0x4CFE0, 0x4CFFB, 0x4D018, 0x4D01B, 0x4D028, 0x4D03C, 0x4D059, 0x4D07A, 0x4D09E, 0x4D0A8, 0x4D0AB, 0x4D0AE, 0x4D0BE, 0x4D0DD,
|
||||
0x4D16A, 0x4D1E5, 0x4D1EE, 0x4D20B, 0x4CBBF, 0x4CBBF, 0x4CC17, 0x4CC1A, 0x4CC4A, 0x4CC4D, 0x4CC53, 0x4CC69, 0x4CC6F, 0x4CC7C, 0x4CCEF, 0x4CD51,
|
||||
0x4CDC0, 0x4CDC3, 0x4CDC6, 0x4CE37, 0x4D2DE, 0x4D32F, 0x4D355, 0x4D367, 0x4D384, 0x4D387, 0x4D397, 0x4D39E, 0x4D3AB, 0x4D3AE, 0x4D3D1, 0x4D3D7,
|
||||
0x4D3F8, 0x4D416, 0x4D420, 0x4D423, 0x4D42D, 0x4D449, 0x4D48C, 0x4D4D9, 0x4D4DC, 0x4D4E3, 0x4D504, 0x4D507, 0x4D55E, 0x4D56A]
|
||||
if world.shuffle_bonk_prizes:
|
||||
bonk_prizes = [0x79, 0xE3, 0x79, 0xAC, 0xAC, 0xE0, 0xDC, 0xAC, 0xE3, 0xE3, 0xDA, 0xE3, 0xDA, 0xD8, 0xAC, 0xAC, 0xE3, 0xD8, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xDC, 0xDB, 0xE3, 0xDA, 0x79, 0x79, 0xE3, 0xE3,
|
||||
0xDA, 0x79, 0xAC, 0xAC, 0x79, 0xE3, 0x79, 0xAC, 0xAC, 0xE0, 0xDC, 0xE3, 0x79, 0xDE, 0xE3, 0xAC, 0xDB, 0x79, 0xE3, 0xD8, 0xAC, 0x79, 0xE3, 0xDB, 0xDB, 0xE3, 0xE3, 0x79, 0xD8, 0xDD]
|
||||
bonk_addresses = [0x4CF6C, 0x4CFBA, 0x4CFE0, 0x4CFFB, 0x4D018, 0x4D01B, 0x4D028, 0x4D03C, 0x4D059, 0x4D07A, 0x4D09E, 0x4D0A8, 0x4D0AB, 0x4D0AE, 0x4D0BE, 0x4D0DD,
|
||||
0x4D16A, 0x4D1E5, 0x4D1EE, 0x4D20B, 0x4CBBF, 0x4CBBF, 0x4CC17, 0x4CC1A, 0x4CC4A, 0x4CC4D, 0x4CC53, 0x4CC69, 0x4CC6F, 0x4CC7C, 0x4CCEF, 0x4CD51,
|
||||
0x4CDC0, 0x4CDC3, 0x4CDC6, 0x4CE37, 0x4D2DE, 0x4D32F, 0x4D355, 0x4D367, 0x4D384, 0x4D387, 0x4D397, 0x4D39E, 0x4D3AB, 0x4D3AE, 0x4D3D1, 0x4D3D7,
|
||||
0x4D3F8, 0x4D416, 0x4D420, 0x4D423, 0x4D42D, 0x4D449, 0x4D48C, 0x4D4D9, 0x4D4DC, 0x4D4E3, 0x4D504, 0x4D507, 0x4D55E, 0x4D56A]
|
||||
random.shuffle(bonk_prizes)
|
||||
for prize, address in zip(bonk_prizes, bonk_addresses):
|
||||
rom.write_byte(address, prize)
|
||||
for prize, address in zip(bonk_prizes, bonk_addresses):
|
||||
rom.write_byte(address, prize)
|
||||
|
||||
|
||||
# set Fountain bottle exchange items
|
||||
if world.difficulty in ['hard', 'expert', 'insane']:
|
||||
|
@ -365,6 +381,9 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
else:
|
||||
rom.write_byte(0x348FF, [0x16, 0x2B, 0x2C, 0x2D, 0x3C, 0x3D, 0x48][random.randint(0, 6)])
|
||||
rom.write_byte(0x3493B, [0x16, 0x2B, 0x2C, 0x2D, 0x3C, 0x3D, 0x48][random.randint(0, 6)])
|
||||
|
||||
#enable Fat Fairy Chests
|
||||
rom.write_bytes(0x1FC16, [0xB1, 0xC6, 0xF9, 0xC9, 0xC6, 0xF9])
|
||||
# set Fat Fairy Bow/Sword prizes to be disappointing
|
||||
rom.write_byte(0x34914, 0x3A) # Bow and Arrow
|
||||
rom.write_byte(0x180028, 0x49) # Fighter Sword
|
||||
|
@ -382,6 +401,8 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
rom.write_byte(0x348DB, 0x3A) # Red Boomerang becomes Red Boomerang
|
||||
rom.write_byte(0x348EB, 0x05) # Blue Shield becomes Blue Shield
|
||||
|
||||
rom.write_byte(0x180029, 0x01) # Smithy quick item give
|
||||
|
||||
# set swordless mode settings
|
||||
rom.write_byte(0x18003F, 0x01 if world.mode == 'swordless' else 0x00) # hammer can harm ganon
|
||||
rom.write_byte(0x180040, 0x01 if world.mode == 'swordless' else 0x00) # open curtains
|
||||
|
@ -438,22 +459,37 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
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)
|
||||
|
||||
# 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
|
||||
|
||||
# assorted fixes
|
||||
rom.write_byte(0x180030, 0x00) # Disable SRAM trace
|
||||
rom.write_byte(0x180036, 0x0A) # Rupoor negative value
|
||||
rom.write_byte(0x1800A2, 0x01) # remain in real dark world when dying in dark word dungion before killing aga1
|
||||
rom.write_byte(0x180169, 0x01 if world.lock_aga_door_in_escape else 0x00) # Lock or unlock aga tower door during escape sequence.
|
||||
rom.write_byte(0x180171, 0x01 if world.ganon_at_pyramid else 0x00) # Enable respawning on pyramid after ganon death
|
||||
rom.write_byte(0x180168, 0x08) # Spike Cave Damage
|
||||
rom.write_bytes(0x18016B, [0x04, 0x02, 0x01]) #Set spike cave and MM spike room Cape usage
|
||||
rom.write_bytes(0x18016E, [0x04, 0x08, 0x10]) #Set spike cave and MM spike room Cape usage
|
||||
rom.write_bytes(0x50563, [0x3F, 0x14]) # disable below ganon chest
|
||||
rom.write_byte(0x50599, 0x00) # disable below ganon chest
|
||||
rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest
|
||||
rom.write_byte(0xF5D73, 0x08) # bees are catchable
|
||||
rom.write_byte(0xF5F10, 0x08) # bees are catchable
|
||||
rom.write_byte(0x180086, 0x00 if world.aga_randomness else 0x01) # set blue ball and ganon warp randomness
|
||||
rom.write_byte(0x1800A0, 0x01) # return to light world on s+q without mirror
|
||||
rom.write_byte(0x1800A1, 0x01) # enable overworld screen transition draining for water level inside swamp
|
||||
if world.goal in ['ganon']:
|
||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
||||
elif world.goal in ['pedestal', 'triforcehunt']:
|
||||
rom.write_byte(0x180034, 0x0A) # starting max bombs
|
||||
rom.write_byte(0x180035, 30) # starting max bombs
|
||||
|
||||
if world.goal in ['pedestal', 'triforcehunt']:
|
||||
rom.write_byte(0x18003E, 0x01) # make ganon invincible
|
||||
elif world.goal in ['dungeons']:
|
||||
rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat
|
||||
elif world.goal in ['crystals']:
|
||||
rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals
|
||||
else:
|
||||
rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected
|
||||
|
||||
rom.write_byte(0x18016A, 0x01 if world.keysanity else 0x00) # free roaming item text boxes
|
||||
rom.write_byte(0x18003B, 0x01 if world.keysanity else 0x00) # maps showing crystals on overworld
|
||||
|
||||
|
@ -483,9 +519,9 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
rom.write_bytes(0x6D2FB, [0x00, 0x00, 0xf7, 0xff, 0x02, 0x0E])
|
||||
rom.write_bytes(0x6D313, [0x00, 0x00, 0xe4, 0xff, 0x08, 0x0E])
|
||||
|
||||
if world.swamp_patch_required:
|
||||
# patch swamp: Need to enable permanent drain of water as dam or swamp were moved
|
||||
rom.write_byte(0x18003D, 0x01)
|
||||
|
||||
# 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 else 0x00)
|
||||
|
||||
# set correct flag for hera basement item
|
||||
if world.get_location('Tower of Hera - Basement Cage').item is not None and world.get_location('Tower of Hera - Basement Cage').item.name == 'Small Key (Tower of Hera)':
|
||||
|
@ -497,36 +533,56 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
if world.fix_trock_doors:
|
||||
rom.write_byte(0xFED31, 0x0E) # preopen bombable exit
|
||||
rom.write_byte(0xFEE41, 0x0E) # preopen bombable exit
|
||||
rom.write_byte(0xFE465, 0x1E) # remove small key door on backside of big key door
|
||||
# included unconditionally in base2current
|
||||
#rom.write_byte(0xFE465, 0x1E) # remove small key door on backside of big key door
|
||||
else:
|
||||
rom.write_byte(0xFED31, 0x2A) # preopen bombable exit
|
||||
rom.write_byte(0xFEE41, 0x2A) # preopen bombable exit
|
||||
|
||||
# Thanks to Zarby89 for finding these values
|
||||
# fix skull woods exit point
|
||||
if world.fix_skullwoods_exit:
|
||||
rom.write_byte(0x15E0D, 0xF8)
|
||||
rom.write_byte(0x15E0D, 0xF8 if world.fix_skullwoods_exit else 0xB8)
|
||||
|
||||
# fix palace of darkness exit point
|
||||
if world.fix_palaceofdarkness_exit:
|
||||
rom.write_byte(0x15E03, 0x40)
|
||||
rom.write_byte(0x15E03, 0x40 if world.fix_palaceofdarkness_exit else 0x28)
|
||||
|
||||
# fix turtle rock exit point
|
||||
if world.fix_trock_exit:
|
||||
rom.write_byte(0x15E1D, 0x34)
|
||||
rom.write_byte(0x15E1D, 0x34 if world.fix_trock_exit else 0x28)
|
||||
|
||||
# fix ganons tower exit point
|
||||
if world.fix_gtower_exit:
|
||||
rom.write_byte(0x15E25, 0xA4)
|
||||
# todo fix screen scrolling
|
||||
rom.write_byte(0x15E25, 0xA4 if world.fix_gtower_exit else 0x28)
|
||||
# todo fix screen scrolling
|
||||
|
||||
write_strings(rom, world)
|
||||
|
||||
# set rom name
|
||||
# 21 bytes
|
||||
rom.write_bytes(0x7FC0, bytearray('ER_050_%09d\0' % world.seed, 'utf8') + world.option_identifier.to_bytes(4, 'big'))
|
||||
|
||||
# store hash table for main menu hash
|
||||
rom.write_bytes(0x187F00, hashtable)
|
||||
|
||||
apply_rom_settings(rom, beep, world.quickswap, world.fastmenu, world.disable_music, sprite)
|
||||
|
||||
return rom
|
||||
|
||||
def apply_rom_settings(rom, beep, quickswap, fastmenu, disable_music, sprite):
|
||||
|
||||
# enable instant item menu
|
||||
if world.fastmenu:
|
||||
if fastmenu:
|
||||
rom.write_byte(0x180048, 0x01)
|
||||
# Sound twekas for fastmenu:
|
||||
# Sound tweaks for fastmenu:
|
||||
rom.write_byte(0x6DD9A, 0x20)
|
||||
rom.write_byte(0x6DF2A, 0x20)
|
||||
rom.write_byte(0x6E0E9, 0x20)
|
||||
else:
|
||||
rom.write_byte(0x180048, 0x00)
|
||||
rom.write_byte(0x6DD9A, 0x11)
|
||||
rom.write_byte(0x6DF2A, 0x12)
|
||||
rom.write_byte(0x6E0E9, 0x12)
|
||||
|
||||
# enable quick item swapping with L and R (ported by Amazing Ampharos)
|
||||
if world.quickswap:
|
||||
if quickswap:
|
||||
rom.write_bytes(0x107fb, [0x22, 0x50, 0xFF, 0x1F])
|
||||
rom.write_bytes(0x12451, [0x22, 0x50, 0xFF, 0x1F])
|
||||
rom.write_bytes(0xfff50, [0x20, 0x58, 0xFF, 0xA5, 0xF6, 0x29, 0x40, 0x6B, 0xA5, 0xF6, 0x89, 0x10, 0xF0, 0x03, 0x4C, 0x69,
|
||||
|
@ -540,66 +596,84 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
0x7E, 0xAA, 0xE0, 0x01, 0xF0, 0x10, 0xCA, 0xBF, 0x5B, 0xF3, 0x7E, 0xF0, 0xF5, 0x8A, 0x8F, 0x4F,
|
||||
0xF3, 0x7E, 0xA2, 0x10, 0x80, 0xE0, 0xA2, 0x0F, 0x80, 0xD6, 0x60, 0xA9, 0x20, 0x8D, 0x2F, 0x01,
|
||||
0x8E, 0x02, 0x02, 0x22, 0x7F, 0xDB, 0x0D, 0xFA, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
|
||||
else:
|
||||
rom.write_bytes(0x107fb, [0xa5, 0xf6, 0x29, 0x40])
|
||||
rom.write_bytes(0x12451, [0xa5, 0xf6, 0x29, 0x40])
|
||||
rom.write_bytes(0xfff50, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
|
||||
|
||||
write_strings(rom, world)
|
||||
|
||||
if world.disable_music:
|
||||
volumeaddresses = [0xD373B, 0xD375B, 0xD90F8, 0xDA710, 0xDA7A4, 0xDA7BB, 0xDA7D2, 0xD5954, 0xD653B, 0xDA736, 0xDA752, 0xDA772, 0xDA792,
|
||||
0xD5B47, 0xD5B5E, 0xD4306, 0xD6878, 0xD6883, 0xD6E48, 0xD6E76, 0xD6EFB, 0xD6F2D, 0xDA211, 0xDA35B, 0xDA37B, 0xDA38E,
|
||||
0xDA39F, 0xDA5C3, 0xDA691, 0xDA6A8, 0xDA6DF, 0xD2349, 0xD3F45, 0xD42EB, 0xD48B9, 0xD48FF, 0xD543F, 0xD5817, 0xD5957,
|
||||
0xD5ACB, 0xD5AE8, 0xD5B4A, 0xDA5DE, 0xDA608, 0xDA635, 0xDA662, 0xDA71F, 0xDA7AF, 0xDA7C6, 0xDA7DD, 0xD2F00, 0xDA3D5,
|
||||
0xD249C, 0xD24CD, 0xD2C09, 0xD2C53, 0xD2CAF, 0xD2CEB, 0xD2D91, 0xD2EE6, 0xD38ED, 0xD3C91, 0xD3CD3, 0xD3CE8, 0xD3F0C,
|
||||
0xD3F82, 0xD405F, 0xD4139, 0xD4198, 0xD41D5, 0xD41F6, 0xD422B, 0xD4270, 0xD42B1, 0xD4334, 0xD4371, 0xD43A6, 0xD43DB,
|
||||
0xD441E, 0xD4597, 0xD4B3C, 0xD4BAB, 0xD4C03, 0xD4C53, 0xD4C7F, 0xD4D9C, 0xD5424, 0xD65D2, 0xD664F, 0xD6698, 0xD66FF,
|
||||
0xD6985, 0xD6C5C, 0xD6C6F, 0xD6C8E, 0xD6CB4, 0xD6D7D, 0xD827D, 0xD960C, 0xD9828, 0xDA233, 0xDA3A2, 0xDA49E, 0xDA72B,
|
||||
0xDA745, 0xDA765, 0xDA785, 0xDABF6, 0xDAC0D, 0xDAEBE, 0xDAFAC, 0xD9A02, 0xD9BD6, 0xD21CD, 0xD2279, 0xD2E66, 0xD2E70,
|
||||
0xD2EAB, 0xD3B97, 0xD3BAC, 0xD3BE8, 0xD3C0D, 0xD3C39, 0xD3C68, 0xD3C9F, 0xD3CBC, 0xD401E, 0xD4290, 0xD443E, 0xD456F,
|
||||
0xD47D3, 0xD4D43, 0xD4DCC, 0xD4EBA, 0xD4F0B, 0xD4FE5, 0xD5012, 0xD54BC, 0xD54D5, 0xD54F0, 0xD5509, 0xD57D8, 0xD59B9,
|
||||
0xD5A2F, 0xD5AEB, 0xD5E5E, 0xD5FE9, 0xD658F, 0xD674A, 0xD6827, 0xD69D6, 0xD69F5, 0xD6A05, 0xD6AE9, 0xD6DCF, 0xD6E20,
|
||||
0xD6ECB, 0xD71D4, 0xD71E6, 0xD7203, 0xD721E, 0xD8724, 0xD8732, 0xD9652, 0xD9698, 0xD9CBC, 0xD9DC0, 0xD9E49, 0xDAA68,
|
||||
0xDAA77, 0xDAA88, 0xDAA99, 0xDAF04, 0xD1D28, 0xD1D41, 0xD1D5C, 0xD1D77, 0xD1EEE, 0xD311D, 0xD31D1, 0xD4148, 0xD5543,
|
||||
0xD5B6F, 0xD65B3, 0xD6760, 0xD6B6B, 0xD6DF6, 0xD6E0D, 0xD73A1, 0xD814C, 0xD825D, 0xD82BE, 0xD8340, 0xD8394, 0xD842C,
|
||||
0xD8796, 0xD8903, 0xD892A, 0xD91E8, 0xD922B, 0xD92E0, 0xD937E, 0xD93C1, 0xDA958, 0xDA971, 0xDA98C, 0xDA9A7, 0xD1D92,
|
||||
0xD1DBD, 0xD1DEB, 0xD1F5D, 0xD1F9F, 0xD1FBD, 0xD1FDC, 0xD1FEA, 0xD20CA, 0xD21BB, 0xD22C9, 0xD2754, 0xD284C, 0xD2866,
|
||||
0xD2887, 0xD28A0, 0xD28BA, 0xD28DB, 0xD28F4, 0xD293E, 0xD2BF3, 0xD2C1F, 0xD2C69, 0xD2CA1, 0xD2CC5, 0xD2D05, 0xD2D73,
|
||||
0xD2DAF, 0xD2E3D, 0xD2F36, 0xD2F46, 0xD2F6F, 0xD2FCF, 0xD2FDF, 0xD302B, 0xD3086, 0xD3099, 0xD30A5, 0xD30CD, 0xD30F6,
|
||||
0xD3154, 0xD3184, 0xD333A, 0xD33D9, 0xD349F, 0xD354A, 0xD35E5, 0xD3624, 0xD363C, 0xD3672, 0xD3691, 0xD36B4, 0xD36C6,
|
||||
0xD3724, 0xD3767, 0xD38CB, 0xD3B1D, 0xD3B2F, 0xD3B55, 0xD3B70, 0xD3B81, 0xD3BBF, 0xD3D34, 0xD3D55, 0xD3D6E, 0xD3DC6,
|
||||
0xD3E04, 0xD3E38, 0xD3F65, 0xD3FA6, 0xD404F, 0xD4087, 0xD417A, 0xD41A0, 0xD425C, 0xD4319, 0xD433C, 0xD43EF, 0xD440C,
|
||||
0xD4452, 0xD4494, 0xD44B5, 0xD4512, 0xD45D1, 0xD45EF, 0xD4682, 0xD46C3, 0xD483C, 0xD4848, 0xD4855, 0xD4862, 0xD486F,
|
||||
0xD487C, 0xD4A1C, 0xD4A3B, 0xD4A60, 0xD4B27, 0xD4C7A, 0xD4D12, 0xD4D81, 0xD4E90, 0xD4ED6, 0xD4EE2, 0xD5005, 0xD502E,
|
||||
0xD503C, 0xD5081, 0xD51B1, 0xD51C7, 0xD51CF, 0xD51EF, 0xD520C, 0xD5214, 0xD5231, 0xD5257, 0xD526D, 0xD5275, 0xD52AF,
|
||||
0xD52BD, 0xD52CD, 0xD52DB, 0xD549C, 0xD5801, 0xD58A4, 0xD5A68, 0xD5A7F, 0xD5C12, 0xD5D71, 0xD5E10, 0xD5E9A, 0xD5F8B,
|
||||
0xD5FA4, 0xD651A, 0xD6542, 0xD65ED, 0xD661D, 0xD66D7, 0xD6776, 0xD68BD, 0xD68E5, 0xD6956, 0xD6973, 0xD69A8, 0xD6A51,
|
||||
0xD6A86, 0xD6B96, 0xD6C3E, 0xD6D4A, 0xD6E9C, 0xD6F80, 0xD717E, 0xD7190, 0xD71B9, 0xD811D, 0xD8139, 0xD816B, 0xD818A,
|
||||
0xD819E, 0xD81BE, 0xD829C, 0xD82E1, 0xD8306, 0xD830E, 0xD835E, 0xD83AB, 0xD83CA, 0xD83F0, 0xD83F8, 0xD844B, 0xD8479,
|
||||
0xD849E, 0xD84CB, 0xD84EB, 0xD84F3, 0xD854A, 0xD8573, 0xD859D, 0xD85B4, 0xD85CE, 0xD862A, 0xD8681, 0xD87E3, 0xD87FF,
|
||||
0xD887B, 0xD88C6, 0xD88E3, 0xD8944, 0xD897B, 0xD8C97, 0xD8CA4, 0xD8CB3, 0xD8CC2, 0xD8CD1, 0xD8D01, 0xD917B, 0xD918C,
|
||||
0xD919A, 0xD91B5, 0xD91D0, 0xD91DD, 0xD9220, 0xD9273, 0xD9284, 0xD9292, 0xD92AD, 0xD92C8, 0xD92D5, 0xD9311, 0xD9322,
|
||||
0xD9330, 0xD934B, 0xD9366, 0xD9373, 0xD93B6, 0xD97A6, 0xD97C2, 0xD97DC, 0xD97FB, 0xD9811, 0xD98FF, 0xD996F, 0xD99A8,
|
||||
0xD99D5, 0xD9A30, 0xD9A4E, 0xD9A6B, 0xD9A88, 0xD9AF7, 0xD9B1D, 0xD9B43, 0xD9B7C, 0xD9BA9, 0xD9C84, 0xD9C8D, 0xD9CAC,
|
||||
0xD9CE8, 0xD9CF3, 0xD9CFD, 0xD9D46, 0xDA35E, 0xDA37E, 0xDA391, 0xDA478, 0xDA4C3, 0xDA4D7, 0xDA4F6, 0xDA515, 0xDA6E2,
|
||||
0xDA9C2, 0xDA9ED, 0xDAA1B, 0xDAA57, 0xDABAF, 0xDABC9, 0xDABE2, 0xDAC28, 0xDAC46, 0xDAC63, 0xDACB8, 0xDACEC, 0xDAD08,
|
||||
0xDAD25, 0xDAD42, 0xDAD5F, 0xDAE17, 0xDAE34, 0xDAE51, 0xDAF2E, 0xDAF55, 0xDAF6B, 0xDAF81, 0xDB14F, 0xDB16B, 0xDB180,
|
||||
0xDB195, 0xDB1AA, 0xD2B88, 0xD364A, 0xD369F, 0xD3747, 0xD213F, 0xD2174, 0xD229E, 0xD2426, 0xD4731, 0xD4753, 0xD4774,
|
||||
0xD4795, 0xD47B6, 0xD4AA5, 0xD4AE4, 0xD4B96, 0xD4CA5, 0xD5477, 0xD5A3D, 0xD6566, 0xD672C, 0xD67C0, 0xD69B8, 0xD6AB1,
|
||||
0xD6C05, 0xD6DB3, 0xD71AB, 0xD8E2D, 0xD8F0D, 0xD94E0, 0xD9544, 0xD95A8, 0xD9982, 0xD9B56, 0xDA694, 0xDA6AB, 0xDAE88,
|
||||
0xDAEC8, 0xDAEE6, 0xDB1BF, 0xD210A, 0xD22DC, 0xD2447, 0xD5A4D, 0xD5DDC, 0xDA251, 0xDA26C, 0xD945E, 0xD967D, 0xD96C2,
|
||||
0xD9C95, 0xD9EE6, 0xDA5C6, 0xD2047, 0xD24C2, 0xD24EC, 0xD25A4, 0xD3DAA, 0xD51A8, 0xD51E6, 0xD524E, 0xD529E, 0xD6045,
|
||||
0xD81DE, 0xD821E, 0xD94AA, 0xD9A9E, 0xD9AE4, 0xDA289, 0xD2085, 0xD21C5, 0xD5F28]
|
||||
for address in volumeaddresses:
|
||||
rom.write_byte(address, 0x00)
|
||||
|
||||
# set rom name
|
||||
# 21 bytes
|
||||
rom.write_bytes(0x7FC0, bytearray('ER_050_%09d\0' % world.seed, 'utf8') + world.option_identifier.to_bytes(4, 'big'))
|
||||
music_volumes = [
|
||||
(0x00, [0xD373B, 0xD375B, 0xD90F8]),
|
||||
(0x14, [0xDA710, 0xDA7A4, 0xDA7BB, 0xDA7D2]),
|
||||
(0x3C, [0xD5954, 0xD653B, 0xDA736, 0xDA752, 0xDA772, 0xDA792]),
|
||||
(0x50, [0xD5B47, 0xD5B5E]),
|
||||
(0x54, [0xD4306]),
|
||||
(0x64, [0xD6878, 0xD6883, 0xD6E48, 0xD6E76, 0xD6EFB, 0xD6F2D, 0xDA211, 0xDA35B, 0xDA37B, 0xDA38E, 0xDA39F, 0xDA5C3, 0xDA691, 0xDA6A8, 0xDA6DF]),
|
||||
(0x78, [0xD2349, 0xD3F45, 0xD42EB, 0xD48B9, 0xD48FF, 0xD543F, 0xD5817, 0xD5957, 0xD5ACB, 0xD5AE8, 0xD5B4A, 0xDA5DE, 0xDA608, 0xDA635,
|
||||
0xDA662, 0xDA71F, 0xDA7AF, 0xDA7C6, 0xDA7DD]),
|
||||
(0x82, [0xD2F00, 0xDA3D5]),
|
||||
(0xA0, [0xD249C, 0xD24CD, 0xD2C09, 0xD2C53, 0xD2CAF, 0xD2CEB, 0xD2D91, 0xD2EE6, 0xD38ED, 0xD3C91, 0xD3CD3, 0xD3CE8, 0xD3F0C,
|
||||
0xD3F82, 0xD405F, 0xD4139, 0xD4198, 0xD41D5, 0xD41F6, 0xD422B, 0xD4270, 0xD42B1, 0xD4334, 0xD4371, 0xD43A6, 0xD43DB,
|
||||
0xD441E, 0xD4597, 0xD4B3C, 0xD4BAB, 0xD4C03, 0xD4C53, 0xD4C7F, 0xD4D9C, 0xD5424, 0xD65D2, 0xD664F, 0xD6698, 0xD66FF,
|
||||
0xD6985, 0xD6C5C, 0xD6C6F, 0xD6C8E, 0xD6CB4, 0xD6D7D, 0xD827D, 0xD960C, 0xD9828, 0xDA233, 0xDA3A2, 0xDA49E, 0xDA72B,
|
||||
0xDA745, 0xDA765, 0xDA785, 0xDABF6, 0xDAC0D, 0xDAEBE, 0xDAFAC]),
|
||||
(0xAA, [0xD9A02, 0xD9BD6]),
|
||||
(0xB4, [0xD21CD, 0xD2279, 0xD2E66, 0xD2E70, 0xD2EAB, 0xD3B97, 0xD3BAC, 0xD3BE8, 0xD3C0D, 0xD3C39, 0xD3C68, 0xD3C9F, 0xD3CBC,
|
||||
0xD401E, 0xD4290, 0xD443E, 0xD456F, 0xD47D3, 0xD4D43, 0xD4DCC, 0xD4EBA, 0xD4F0B, 0xD4FE5, 0xD5012, 0xD54BC, 0xD54D5,
|
||||
0xD54F0, 0xD5509, 0xD57D8, 0xD59B9, 0xD5A2F, 0xD5AEB, 0xD5E5E, 0xD5FE9, 0xD658F, 0xD674A, 0xD6827, 0xD69D6, 0xD69F5,
|
||||
0xD6A05, 0xD6AE9, 0xD6DCF, 0xD6E20, 0xD6ECB, 0xD71D4, 0xD71E6, 0xD7203, 0xD721E, 0xD8724, 0xD8732, 0xD9652, 0xD9698,
|
||||
0xD9CBC, 0xD9DC0, 0xD9E49, 0xDAA68, 0xDAA77, 0xDAA88, 0xDAA99, 0xDAF04]),
|
||||
(0x8c, [0xD1D28, 0xD1D41, 0xD1D5C, 0xD1D77, 0xD1EEE, 0xD311D, 0xD31D1, 0xD4148, 0xD5543, 0xD5B6F, 0xD65B3, 0xD6760, 0xD6B6B,
|
||||
0xD6DF6, 0xD6E0D, 0xD73A1, 0xD814C, 0xD825D, 0xD82BE, 0xD8340, 0xD8394, 0xD842C, 0xD8796, 0xD8903, 0xD892A, 0xD91E8,
|
||||
0xD922B, 0xD92E0, 0xD937E, 0xD93C1, 0xDA958, 0xDA971, 0xDA98C, 0xDA9A7]),
|
||||
(0xC8, [0xD1D92, 0xD1DBD, 0xD1DEB, 0xD1F5D, 0xD1F9F, 0xD1FBD, 0xD1FDC, 0xD1FEA, 0xD20CA, 0xD21BB, 0xD22C9, 0xD2754, 0xD284C,
|
||||
0xD2866, 0xD2887, 0xD28A0, 0xD28BA, 0xD28DB, 0xD28F4, 0xD293E, 0xD2BF3, 0xD2C1F, 0xD2C69, 0xD2CA1, 0xD2CC5, 0xD2D05,
|
||||
0xD2D73, 0xD2DAF, 0xD2E3D, 0xD2F36, 0xD2F46, 0xD2F6F, 0xD2FCF, 0xD2FDF, 0xD302B, 0xD3086, 0xD3099, 0xD30A5, 0xD30CD,
|
||||
0xD30F6, 0xD3154, 0xD3184, 0xD333A, 0xD33D9, 0xD349F, 0xD354A, 0xD35E5, 0xD3624, 0xD363C, 0xD3672, 0xD3691, 0xD36B4,
|
||||
0xD36C6, 0xD3724, 0xD3767, 0xD38CB, 0xD3B1D, 0xD3B2F, 0xD3B55, 0xD3B70, 0xD3B81, 0xD3BBF, 0xD3D34, 0xD3D55, 0xD3D6E,
|
||||
0xD3DC6, 0xD3E04, 0xD3E38, 0xD3F65, 0xD3FA6, 0xD404F, 0xD4087, 0xD417A, 0xD41A0, 0xD425C, 0xD4319, 0xD433C, 0xD43EF,
|
||||
0xD440C, 0xD4452, 0xD4494, 0xD44B5, 0xD4512, 0xD45D1, 0xD45EF, 0xD4682, 0xD46C3, 0xD483C, 0xD4848, 0xD4855, 0xD4862,
|
||||
0xD486F, 0xD487C, 0xD4A1C, 0xD4A3B, 0xD4A60, 0xD4B27, 0xD4C7A, 0xD4D12, 0xD4D81, 0xD4E90, 0xD4ED6, 0xD4EE2, 0xD5005,
|
||||
0xD502E, 0xD503C, 0xD5081, 0xD51B1, 0xD51C7, 0xD51CF, 0xD51EF, 0xD520C, 0xD5214, 0xD5231, 0xD5257, 0xD526D, 0xD5275,
|
||||
0xD52AF, 0xD52BD, 0xD52CD, 0xD52DB, 0xD549C, 0xD5801, 0xD58A4, 0xD5A68, 0xD5A7F, 0xD5C12, 0xD5D71, 0xD5E10, 0xD5E9A,
|
||||
0xD5F8B, 0xD5FA4, 0xD651A, 0xD6542, 0xD65ED, 0xD661D, 0xD66D7, 0xD6776, 0xD68BD, 0xD68E5, 0xD6956, 0xD6973, 0xD69A8,
|
||||
0xD6A51, 0xD6A86, 0xD6B96, 0xD6C3E, 0xD6D4A, 0xD6E9C, 0xD6F80, 0xD717E, 0xD7190, 0xD71B9, 0xD811D, 0xD8139, 0xD816B,
|
||||
0xD818A, 0xD819E, 0xD81BE, 0xD829C, 0xD82E1, 0xD8306, 0xD830E, 0xD835E, 0xD83AB, 0xD83CA, 0xD83F0, 0xD83F8, 0xD844B,
|
||||
0xD8479, 0xD849E, 0xD84CB, 0xD84EB, 0xD84F3, 0xD854A, 0xD8573, 0xD859D, 0xD85B4, 0xD85CE, 0xD862A, 0xD8681, 0xD87E3,
|
||||
0xD87FF, 0xD887B, 0xD88C6, 0xD88E3, 0xD8944, 0xD897B, 0xD8C97, 0xD8CA4, 0xD8CB3, 0xD8CC2, 0xD8CD1, 0xD8D01, 0xD917B,
|
||||
0xD918C, 0xD919A, 0xD91B5, 0xD91D0, 0xD91DD, 0xD9220, 0xD9273, 0xD9284, 0xD9292, 0xD92AD, 0xD92C8, 0xD92D5, 0xD9311,
|
||||
0xD9322, 0xD9330, 0xD934B, 0xD9366, 0xD9373, 0xD93B6, 0xD97A6, 0xD97C2, 0xD97DC, 0xD97FB, 0xD9811, 0xD98FF, 0xD996F,
|
||||
0xD99A8, 0xD99D5, 0xD9A30, 0xD9A4E, 0xD9A6B, 0xD9A88, 0xD9AF7, 0xD9B1D, 0xD9B43, 0xD9B7C, 0xD9BA9, 0xD9C84, 0xD9C8D,
|
||||
0xD9CAC, 0xD9CE8, 0xD9CF3, 0xD9CFD, 0xD9D46, 0xDA35E, 0xDA37E, 0xDA391, 0xDA478, 0xDA4C3, 0xDA4D7, 0xDA4F6, 0xDA515,
|
||||
0xDA6E2, 0xDA9C2, 0xDA9ED, 0xDAA1B, 0xDAA57, 0xDABAF, 0xDABC9, 0xDABE2, 0xDAC28, 0xDAC46, 0xDAC63, 0xDACB8, 0xDACEC,
|
||||
0xDAD08, 0xDAD25, 0xDAD42, 0xDAD5F, 0xDAE17, 0xDAE34, 0xDAE51, 0xDAF2E, 0xDAF55, 0xDAF6B, 0xDAF81, 0xDB14F, 0xDB16B,
|
||||
0xDB180, 0xDB195, 0xDB1AA]),
|
||||
(0xD2, [0xD2B88, 0xD364A, 0xD369F, 0xD3747]),
|
||||
(0xDC, [0xD213F, 0xD2174, 0xD229E, 0xD2426, 0xD4731, 0xD4753, 0xD4774, 0xD4795, 0xD47B6, 0xD4AA5, 0xD4AE4, 0xD4B96, 0xD4CA5,
|
||||
0xD5477, 0xD5A3D, 0xD6566, 0xD672C, 0xD67C0, 0xD69B8, 0xD6AB1, 0xD6C05, 0xD6DB3, 0xD71AB, 0xD8E2D, 0xD8F0D, 0xD94E0,
|
||||
0xD9544, 0xD95A8, 0xD9982, 0xD9B56, 0xDA694, 0xDA6AB, 0xDAE88, 0xDAEC8, 0xDAEE6, 0xDB1BF]),
|
||||
(0xE6, [0xD210A, 0xD22DC, 0xD2447, 0xD5A4D, 0xD5DDC, 0xDA251, 0xDA26C]),
|
||||
(0xF0, [0xD945E, 0xD967D, 0xD96C2, 0xD9C95, 0xD9EE6, 0xDA5C6]),
|
||||
(0xFA, [0xD2047, 0xD24C2, 0xD24EC, 0xD25A4, 0xD3DAA, 0xD51A8, 0xD51E6, 0xD524E, 0xD529E, 0xD6045, 0xD81DE, 0xD821E, 0xD94AA,
|
||||
0xD9A9E, 0xD9AE4, 0xDA289]),
|
||||
(0xFF, [0xD2085, 0xD21C5, 0xD5F28])
|
||||
]
|
||||
for volume, addresses in music_volumes:
|
||||
for address in addresses:
|
||||
rom.write_byte(address, volume if not disable_music else 0x00)
|
||||
|
||||
# set heart beep rate
|
||||
rom.write_byte(0x180033, {'off': 0x00, 'half': 0x40, 'quarter': 0x80, 'normal': 0x20}[beep])
|
||||
|
||||
# store hash table for main menu hash
|
||||
rom.write_bytes(0x187F00, hashtable)
|
||||
|
||||
# write link sprite if required
|
||||
if sprite is not None:
|
||||
write_sprite(rom, sprite)
|
||||
|
@ -607,8 +681,6 @@ def patch_rom(world, rom, hashtable, beep='normal', sprite=None):
|
|||
if isinstance(rom, LocalRom):
|
||||
rom.write_crc()
|
||||
|
||||
return rom
|
||||
|
||||
|
||||
def write_sprite(rom, sprite):
|
||||
if len(sprite) == 0x7000:
|
||||
|
|
140
Rules.py
140
Rules.py
|
@ -33,6 +33,8 @@ def set_rules(world):
|
|||
if not world.swamp_patch_required:
|
||||
add_rule(world.get_entrance('Swamp Palace Moat'), lambda state: state.has_Mirror())
|
||||
|
||||
set_bunny_rules(world)
|
||||
|
||||
|
||||
def set_rule(spot, rule):
|
||||
spot.access_rule = rule
|
||||
|
@ -76,7 +78,7 @@ def global_rules(world):
|
|||
world.get_region('Old Man House').can_reach = lambda state: state.can_reach('Old Man', 'Location') or old_rule(state)
|
||||
|
||||
# overworld requirements
|
||||
set_rule(world.get_entrance('Kings Grave'), lambda state: state.has_Boots() and (state.can_lift_heavy_rocks() or (state.has_Mirror() and state.can_reach('West Dark World'))))
|
||||
set_rule(world.get_entrance('Kings Grave'), lambda state: state.has_Boots() and (state.can_lift_heavy_rocks() or (state.has_Pearl() and state.has_Mirror() and state.can_reach('West Dark World'))))
|
||||
set_rule(world.get_entrance('Bonk Fairy (Light)'), lambda state: state.has_Boots())
|
||||
set_rule(world.get_location('Sunken Treasure'), lambda state: state.can_reach('Dam'))
|
||||
set_rule(world.get_entrance('Bat Cave Drop Ledge'), lambda state: state.has('Hammer'))
|
||||
|
@ -90,9 +92,9 @@ def global_rules(world):
|
|||
set_rule(world.get_entrance('Flute Spot 1'), lambda state: state.has('Ocarina'))
|
||||
set_rule(world.get_entrance('Lake Hylia Central Island Teleporter'), lambda state: state.can_lift_heavy_rocks())
|
||||
set_rule(world.get_entrance('Dark Desert Teleporter'), lambda state: state.has('Ocarina') and state.can_lift_heavy_rocks())
|
||||
set_rule(world.get_entrance('East Hyrule Teleporter'), lambda state: state.has('Hammer') and state.can_lift_rocks() and state.has_Pearl())
|
||||
set_rule(world.get_entrance('South Hyrule Teleporter'), lambda state: state.has('Hammer') and state.can_lift_rocks() and state.has_Pearl())
|
||||
set_rule(world.get_entrance('Kakariko Teleporter'), lambda state: ((state.has('Hammer') and state.can_lift_rocks()) or state.can_lift_heavy_rocks()) and state.has_Pearl())
|
||||
set_rule(world.get_entrance('East Hyrule Teleporter'), lambda state: state.has('Hammer') and state.can_lift_rocks() and state.has_Pearl()) # bunny cannot use hammer
|
||||
set_rule(world.get_entrance('South Hyrule Teleporter'), lambda state: state.has('Hammer') and state.can_lift_rocks() and state.has_Pearl()) # bunny cannot use hammer
|
||||
set_rule(world.get_entrance('Kakariko Teleporter'), lambda state: ((state.has('Hammer') and state.can_lift_rocks()) or state.can_lift_heavy_rocks()) and state.has_Pearl()) # bunny cannot lift bushes
|
||||
set_rule(world.get_location('Flute Spot'), lambda state: state.has('Shovel'))
|
||||
set_rule(world.get_location('Purple Chest'), lambda state: state.can_reach('Blacksmith', 'Location')) # Can S&Q with chest
|
||||
|
||||
|
@ -123,67 +125,62 @@ def global_rules(world):
|
|||
set_rule(world.get_location('Ether Tablet'), lambda state: state.has('Book of Mudora') and state.has_beam_sword())
|
||||
set_rule(world.get_entrance('East Death Mountain (Top)'), lambda state: state.has('Hammer'))
|
||||
|
||||
set_rule(world.get_location('Catfish'), lambda state: state.has_Pearl() and state.can_lift_rocks())
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Fairy'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('Palace of Darkness Hint'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('East Dark World Hint'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_location('Catfish'), lambda state: state.can_lift_rocks())
|
||||
set_rule(world.get_entrance('Dark World Potion Shop'), lambda state: state.has_Pearl() and (state.can_lift_rocks() or state.has('Hammer') or state.has('Flippers')))
|
||||
set_rule(world.get_entrance('South Dark World Bridge'), lambda state: state.has('Hammer') and state.has_Pearl())
|
||||
set_rule(world.get_entrance('Bonk Fairy (Dark)'), lambda state: state.has_Boots())
|
||||
set_rule(world.get_entrance('Bonk Fairy (Dark)'), lambda state: state.has_Pearl() and state.has_Boots())
|
||||
set_rule(world.get_entrance('West Dark World Gap'), lambda state: state.has_Pearl() and state.has('Hookshot') and (state.has('Flippers') or state.has('Hammer') or state.can_lift_rocks()))
|
||||
set_rule(world.get_entrance('Palace of Darkness'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('Palace of Darkness'), lambda state: state.has_Pearl()) # kiki needs pearl
|
||||
set_rule(world.get_entrance('Hyrule Castle Ledge Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Hyrule Castle Main Gate'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Drop (East)'), lambda state: (state.has_Pearl() and state.has('Flippers') or state.has_Mirror())) # Overworld Bunny Revival
|
||||
set_rule(world.get_location('Bombos Tablet'), lambda state: state.has('Book of Mudora') and state.has_beam_sword() and state.has_Mirror())
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Drop (South)'), lambda state: state.has('Flippers')) # ToDo any fake flipper set up?
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave'), lambda state: state.can_lift_rocks())
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Ledge'), lambda state: state.has_Pearl()) # To avoid Bunny nonsense for now
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Drop (South)'), lambda state: state.has_Pearl() and state.has('Flippers')) # ToDo any fake flipper set up?
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Ledge Fairy'), lambda state: state.has_Pearl()) # bomb required
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Ledge Spike Cave'), lambda state: state.can_lift_rocks() and state.has_Pearl())
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Teleporter'), lambda state: state.has_Pearl() and (state.has('Hammer') or state.can_lift_rocks())) # Fake Flippers
|
||||
set_rule(world.get_entrance('Village of Outcasts Heavy Rock'), lambda state: state.can_lift_heavy_rocks())
|
||||
set_rule(world.get_entrance('Village of Outcasts Heavy Rock'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks())
|
||||
set_rule(world.get_entrance('Hype Cave'), lambda state: state.has_Pearl()) # bomb required
|
||||
set_rule(world.get_entrance('Brewery'), lambda state: state.has_Pearl()) # bomb required
|
||||
set_rule(world.get_entrance('Thieves Town'), lambda state: state.has_Pearl()) # bunny cannot pull
|
||||
set_rule(world.get_entrance('Skull Woods First Section Hole (North)'), lambda state: state.has_Pearl()) # bunny cannot lift bush
|
||||
set_rule(world.get_entrance('Maze Race Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Cave 45'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('East Dark World Bridge'), lambda state: state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Lake Hylia Island Mirror Spot'), lambda state: state.has_Mirror() and state.has('Flippers'))
|
||||
set_rule(world.get_entrance('East Dark World Bridge'), lambda state: state.has_Pearl() and state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Lake Hylia Island Mirror Spot'), lambda state: state.has_Pearl() and state.has_Mirror() and state.has('Flippers'))
|
||||
set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('East Dark World River Pier'), lambda state: state.has('Flippers')) # ToDo any fake flipper set up?
|
||||
set_rule(world.get_entrance('Graveyard Cave'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Bumper Cave (Bottom)'), lambda state: state.can_lift_rocks())
|
||||
set_rule(world.get_entrance('East Dark World River Pier'), lambda state: state.has_Pearl() and state.has('Flippers')) # ToDo any fake flipper set up?
|
||||
set_rule(world.get_entrance('Graveyard Cave'), lambda state: state.has_Pearl() and state.has_Mirror())
|
||||
set_rule(world.get_entrance('Bumper Cave (Bottom)'), lambda state: state.has_Pearl() and state.can_lift_rocks())
|
||||
set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Bat Cave Drop Ledge Mirror Spot'), lambda state: state.can_lift_heavy_rocks() and state.has_Mirror())
|
||||
set_rule(world.get_entrance('Dark World Hammer Peg Cave'), lambda state: state.can_lift_heavy_rocks() and state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Dark World Shop'), lambda state: state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Bat Cave Drop Ledge Mirror Spot'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks() and state.has_Mirror())
|
||||
set_rule(world.get_entrance('Dark World Hammer Peg Cave'), lambda state: state.has_Pearl() and state.can_lift_heavy_rocks() and state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Dark World Shop'), lambda state: state.has_Pearl() and state.has('Hammer'))
|
||||
set_rule(world.get_entrance('Bumper Cave Exit (Top)'), lambda state: state.has('Cape'))
|
||||
set_rule(world.get_entrance('Bumper Cave Exit (Bottom)'), lambda state: state.has('Cape') or state.has('Hookshot'))
|
||||
set_rule(world.get_entrance('Skull Woods Final Section'), lambda state: state.has('Fire Rod'))
|
||||
|
||||
set_rule(world.get_entrance('Skull Woods Final Section'), lambda state: state.has('Fire Rod') and state.has_Pearl()) # bunny cannot use fire rod
|
||||
set_rule(world.get_entrance('Misery Mire'), lambda state: state.has_Pearl() and state.has_sword() and state.has_misery_mire_medallion()) # sword required to cast magic (!)
|
||||
set_rule(world.get_entrance('Desert Ledge (West) Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Desert Ledge Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Desert Palace Stairs Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Desert Palace Entrance (North) Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Mire Shed'), lambda state: state.has_Pearl()) # ToDo Bunny Revival can give access to this cave in super bunny state. Not sure how to deal with shuffled entrances, as much easier to block of cave entrances than individual shuffled chests
|
||||
set_rule(world.get_entrance('Dark Desert Hint'), lambda state: state.has_Pearl()) # ToDo Bunny Revival can give access to this cave in super bunny state. Not sure how to deal with shuffled entrances, as much easier to block of cave entrances than individual shuffled chests
|
||||
set_rule(world.get_entrance('Dark Desert Fairy'), lambda state: state.has_Pearl()) # ToDo Bunny Revival can give access to this cave in super bunny state. Not sure how to deal with shuffled entrances, as much easier to block of cave entrances than individual shuffled chests
|
||||
set_rule(world.get_entrance('Spike Cave'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('Dark Death Mountain Fairy'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('Spectacle Rock Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Ganons Tower'), lambda state: state.has('Crystal 1') and state.has('Crystal 2') and state.has('Crystal 3') and state.has('Crystal 4') and state.has('Crystal 5') and state.has('Crystal 6') and state.has('Crystal 7'))
|
||||
set_rule(world.get_entrance('Hookshot Cave'), lambda state: state.can_lift_rocks() and state.has_Pearl())
|
||||
|
||||
set_rule(world.get_entrance('East Death Mountain (Top) Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Mimic Cave Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Spiral Cave Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Fairy Ascension Mirror Spot'), lambda state: state.has_Mirror() and state.has_Pearl()) # need to lift flowers
|
||||
set_rule(world.get_entrance('Isolated Ledge Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Superbunny Cave (Top)'), lambda state: state.has_Pearl()) # Chests inside could be collected with super bunny, but may be shuffled. rather limit access for now ToDo
|
||||
set_rule(world.get_entrance('Superbunny Cave (Bottom)'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('Cave Shop (Dark Death Mountain)'), lambda state: state.has_Pearl()) # just for save bunny algo for now
|
||||
set_rule(world.get_entrance('Superbunny Cave Exit (Bottom)'), lambda state: False) # Cannot get to bottom exit from top. Just exists for shuffling
|
||||
set_rule(world.get_location('Spike Cave'), lambda state: state.has('Hammer') and state.can_lift_rocks() and (state.has('Cane of Byrna') or state.has('Cape')) and (state.has_bottle() or state.has('Half Magic') or state.has('Quarter Magic')))
|
||||
set_rule(world.get_location('Hookshot Cave - Top Right'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_location('Hookshot Cave - Top Left'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_location('Hookshot Cave - Bottom Right'), lambda state: state.has('Hookshot') or state.has('Pegasus Boots'))
|
||||
set_rule(world.get_location('Hookshot Cave - Bottom Left'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_location('Floating Island'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Floating Island Mirror Spot'), lambda state: state.has_Mirror())
|
||||
set_rule(world.get_entrance('Turtle Rock'), lambda state: state.has_Pearl() and state.has_sword() and state.has_turtle_rock_medallion() and state.can_reach('Turtle Rock (Top)', 'Region')) # sword required to cast magic (!)
|
||||
set_rule(world.get_location('Mimic Cave'), lambda state: state.has('Hammer'))
|
||||
|
||||
|
@ -357,8 +354,7 @@ def global_rules(world):
|
|||
set_rule(world.get_entrance('Ganons Tower Moldorm Door'), lambda state: state.has('Small Key (Ganons Tower)', 4))
|
||||
set_rule(world.get_entrance('Ganons Tower Moldorm Gap'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_location('Agahnim 2'), lambda state: state.has_sword() or state.has('Hammer') or state.has('Bug Catching Net'))
|
||||
set_rule(world.get_entrance('Pyramid Hole'), lambda state: state.has('Beat Agahnim 2') and state.has_Pearl())
|
||||
set_rule(world.get_entrance('Pyramid Entrance'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('Pyramid Hole'), lambda state: state.has('Beat Agahnim 2'))
|
||||
for location in ['Ganons Tower - Big Chest', 'Ganons Tower - Mini Helmasaur Room - Left', 'Ganons Tower - Mini Helmasaur Room - Right',
|
||||
'Ganons Tower - Pre-Moldorm Chest', 'Ganons Tower - Validation Chest']:
|
||||
forbid_item(world.get_location(location), 'Big Key (Ganons Tower)')
|
||||
|
@ -373,10 +369,9 @@ def no_glitches_rules(world):
|
|||
set_rule(world.get_entrance('Zoras River'), lambda state: state.has('Flippers') or state.can_lift_rocks())
|
||||
set_rule(world.get_entrance('Lake Hylia Central Island Pier'), lambda state: state.has('Flippers')) # can be fake flippered to
|
||||
set_rule(world.get_entrance('Hobo Bridge'), lambda state: state.has('Flippers'))
|
||||
add_rule(world.get_entrance('Ice Palace'), lambda state: state.has_Pearl())
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Drop (East)'), lambda state: state.has_Pearl() and state.has('Flippers'))
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Teleporter'), lambda state: state.has_Pearl() and state.has('Flippers') and (state.has('Hammer') or state.can_lift_rocks()))
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop'), lambda state: state.has('Flippers'))
|
||||
set_rule(world.get_entrance('Dark Lake Hylia Ledge Drop'), lambda state: state.has_Pearl() and state.has('Flippers'))
|
||||
add_rule(world.get_entrance('Ganons Tower (Hookshot Room)'), lambda state: state.has('Hookshot'))
|
||||
set_rule(world.get_entrance('Paradox Cave Push Block Reverse'), lambda state: False) # no glitches does not require block override
|
||||
set_rule(world.get_entrance('Paradox Cave Bomb Jump'), lambda state: False)
|
||||
|
@ -583,20 +578,75 @@ def set_big_bomb_rules(world):
|
|||
'Mimic Cave Mirror Spot']
|
||||
Isolated_LW_entrances = ['Capacity Upgrade',
|
||||
'Hookshot Fairy']
|
||||
set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Pearl() and state.can_reach('Big Bomb Shop', 'Region') and state.has('Crystal 5') and state.has('Crystal 6'))
|
||||
set_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('East Dark World', 'Region') and state.can_reach('Big Bomb Shop', 'Region') and state.has('Crystal 5') and state.has('Crystal 6'))
|
||||
if bombshop_entrance.name in Normal_LW_entrances:
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()) or state.has_Mirror())
|
||||
#1. Enter via gate: Needs Aga1
|
||||
#2. south hyrule teleporter and cross peg bridge: Hammer and moon pearl
|
||||
#3. Can reach Eastern dark world some other way, mirror, get bomb, return to mirror spot, walk to pyramid: Needs mirror
|
||||
# -> A or (H and P)) or (M)
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl()) or state.has_Mirror())
|
||||
elif bombshop_entrance.name in LW_walkable_entrances:
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks())))
|
||||
#1. Mirror then gate: Needs mirror and Aga1
|
||||
#2. Mirror then go to south hyrule teleporter and cross peg bridge: Needs Mirror and Hammer and moon pearl
|
||||
# -> M and (A or (H and P))
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl())))
|
||||
elif bombshop_entrance.name in Northern_DW_entrances:
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.can_lift_heavy_rocks() and state.has('Hammer')) or (state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()))))
|
||||
#1. Mirror and enter via gate: Need mirror and Aga1
|
||||
#2. Mirror and enter via south hyrule teleporter: Need mirror and hammer and moon pearl
|
||||
#3. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl
|
||||
# -> (Mitts and P and H) or (M and (A or (H and P)))
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.can_lift_heavy_rocks() and state.has_Pearl() and state.has('Hammer')) or (state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl()))))
|
||||
elif bombshop_entrance.name in Southern_DW_entrances:
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Hammer') or (state.has_Mirror() and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks()))))
|
||||
#1. Mirror and enter via gate: Need mirror and Aga1
|
||||
#2. cross peg bridge: Need hammer and moon pearl
|
||||
# -> (H and P) or (M and A)
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has('Hammer') and state.has_Pearl()) or (state.has_Mirror() and state.can_reach('Top of Pyramid', 'Entrance')))
|
||||
elif bombshop_entrance.name in Isolated_DW_entrances:
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks())))
|
||||
# 1. mirror then flute then enter via gate: Needs mirror and flute and Aga 1
|
||||
# 2. mirror then flute then enter via south hyrule teleporter: Needs mirror and Flute and hammer and moon pearl
|
||||
# -> M and Flute and (A or (H and P))
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has_Mirror() and state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl())))
|
||||
elif bombshop_entrance.name in Isolated_LW_entrances:
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.can_lift_rocks())))
|
||||
# 1. flute then enter via gate: Needs flute and Aga 1
|
||||
# 2. flute then enter via south hyrule teleporter: Needs Flute and hammer and moon pearl
|
||||
# Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations.
|
||||
# -> Flute and (A or (H and P))
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Ocarina') and (state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl())))
|
||||
elif bombshop_entrance.name == 'Dark World Potion Shop':
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.has('Hammer') or state.can_lift_rocks() or (state.has_Mirror() and state.can_reach('Top of Pyramid', 'Entrance')))
|
||||
# 1. walk down by lifting rock: needs gloves and pearl`
|
||||
# 2. walk down by hammering peg: needs hammer and pearl
|
||||
# 3. mirror and eneter via gate: needs Mirror and Aga1
|
||||
# (south hyrule teleporter would be redundant with #2)
|
||||
# -> P and (H or H) or (M and A)
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: (state.has_Pearl() and (state.has('Hammer') or state.can_lift_rocks())) or (state.has_Mirror() and state.can_reach('Top of Pyramid', 'Entrance')))
|
||||
elif bombshop_entrance.name == 'Kings Grave':
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.can_lift_rocks() and state.has('Hammer')) or (state.can_lift_heavy_rocks() and state.has_Mirror()))
|
||||
# same as the Normal_LW_entrances case except that the pre-existing mirror is only possible if you have mitts
|
||||
# (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot)
|
||||
# -> A or (H and P) or (M and Mitts)
|
||||
add_rule(world.get_entrance('Pyramid Fairy'), lambda state: state.can_reach('Top of Pyramid', 'Entrance') or (state.has('Hammer') and state.has_Pearl()) or (state.can_lift_heavy_rocks() and state.has_Mirror()))
|
||||
|
||||
def set_bunny_rules(world):
|
||||
|
||||
# regions for the extis of multi-entrace caves/drops that bunny cannot pass
|
||||
# Note spiral cave may be technically passible, but it would be too absurd to require since OHKO mode is a thing.
|
||||
bunny_impassable_caves = ['Bumper Cave', 'Two Brothers House', 'Hookshot Cave', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Left)', 'Skull Woods First Section (Top)', 'Turtle Rock (Entrance)', 'Turtle Rock (Second Section)', 'Turtle Rock (Big Chest)', 'Skull Woods Second Section (Drop)',
|
||||
'Turtle Rock (Eye Bridge)', 'Sewers', 'Pyramid', 'Spiral Cave (Top)']
|
||||
|
||||
bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree', 'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge']
|
||||
|
||||
# Add pearl requirements for bunny-impassible caves if they occur in the dark world
|
||||
for region in [world.get_region(name) for name in bunny_impassable_caves]:
|
||||
|
||||
if region.is_light_world:
|
||||
continue
|
||||
for exit in region.exits:
|
||||
add_rule(exit, lambda state: state.has_Pearl)
|
||||
|
||||
# Add a moon pearl requirement for all locations that are actually in the dark world, except those available to the bunny
|
||||
for location in world.get_locations():
|
||||
if not location.parent_region.is_light_world:
|
||||
|
||||
if location.name in bunny_accessible_locations:
|
||||
continue
|
||||
|
||||
add_rule(location, lambda state: state.has_Pearl())
|
||||
|
|
Loading…
Reference in New Issue