base rom changes

* V32 MSU
* All items from chests/received in dark rooms now visible.
* Regular bunny can read signs
* Players up to Player 255 supported on send/received.
This commit is contained in:
caitsith2 2020-06-06 20:49:53 -07:00
parent 68f453f802
commit 73d1f56ffb
7 changed files with 15 additions and 28 deletions

View File

@ -226,7 +226,6 @@ def parse_arguments(argv, no_defaults=False):
''') ''')
parser.add_argument('--quickswap', help='Enable quick item swapping with L and R.', action='store_true') parser.add_argument('--quickswap', help='Enable quick item swapping with L and R.', action='store_true')
parser.add_argument('--disablemusic', help='Disables game music.', action='store_true') parser.add_argument('--disablemusic', help='Disables game music.', action='store_true')
parser.add_argument('--extendedmsu', help='Use v31 Extended msu', action='store_true')
parser.add_argument('--mapshuffle', default=defval(False), help='Maps are no longer restricted to their dungeons, but can be anywhere', action='store_true') parser.add_argument('--mapshuffle', default=defval(False), help='Maps are no longer restricted to their dungeons, but can be anywhere', action='store_true')
parser.add_argument('--compassshuffle', default=defval(False), help='Compasses are no longer restricted to their dungeons, but can be anywhere', action='store_true') parser.add_argument('--compassshuffle', default=defval(False), help='Compasses are no longer restricted to their dungeons, but can be anywhere', action='store_true')
parser.add_argument('--keyshuffle', default=defval(False), help='Small Keys are no longer restricted to their dungeons, but can be anywhere', action='store_true') parser.add_argument('--keyshuffle', default=defval(False), help='Small Keys are no longer restricted to their dungeons, but can be anywhere', action='store_true')
@ -330,7 +329,7 @@ def parse_arguments(argv, no_defaults=False):
'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots', 'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots',
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor',
'heartbeep', "skip_progression_balancing", 'heartbeep', "skip_progression_balancing",
'remote_items', 'progressive', 'extendedmsu', 'dungeon_counters', 'glitch_boots']: 'remote_items', 'progressive', 'dungeon_counters', 'glitch_boots']:
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
if player == 1: if player == 1:
setattr(ret, name, {1: value}) setattr(ret, name, {1: value})

5
Gui.py
View File

@ -88,9 +88,6 @@ def guiMain(args=None):
balancingVar = IntVar() balancingVar = IntVar()
balancingVar.set(1) #set default balancingVar.set(1) #set default
balancingCheckbutton = Checkbutton(checkBoxFrame, text="Multiworld Progression Balancing", variable=balancingVar) balancingCheckbutton = Checkbutton(checkBoxFrame, text="Multiworld Progression Balancing", variable=balancingVar)
extendedmsuVar = IntVar()
extendedmsuVar.set(0) #set default
extendedmsuCheckbutton = Checkbutton(checkBoxFrame, text="Extended MSU", variable=extendedmsuVar)
createSpoilerCheckbutton.pack(expand=True, anchor=W) createSpoilerCheckbutton.pack(expand=True, anchor=W)
suppressRomCheckbutton.pack(expand=True, anchor=W) suppressRomCheckbutton.pack(expand=True, anchor=W)
openpyramidCheckbutton.pack(expand=True, anchor=W) openpyramidCheckbutton.pack(expand=True, anchor=W)
@ -105,7 +102,6 @@ def guiMain(args=None):
hintsCheckbutton.pack(expand=True, anchor=W) hintsCheckbutton.pack(expand=True, anchor=W)
customCheckbutton.pack(expand=True, anchor=W) customCheckbutton.pack(expand=True, anchor=W)
balancingCheckbutton.pack(expand=True, anchor=W) balancingCheckbutton.pack(expand=True, anchor=W)
extendedmsuCheckbutton.pack(expand=True, anchor=W)
romOptionsFrame = LabelFrame(rightHalfFrame, text="Rom options") romOptionsFrame = LabelFrame(rightHalfFrame, text="Rom options")
romOptionsFrame.columnconfigure(0, weight=1) romOptionsFrame.columnconfigure(0, weight=1)
@ -443,7 +439,6 @@ def guiMain(args=None):
guiargs.item_functionality = itemfunctionVar.get() guiargs.item_functionality = itemfunctionVar.get()
guiargs.timer = timerVar.get() guiargs.timer = timerVar.get()
guiargs.skip_progression_balancing = not balancingVar.get() guiargs.skip_progression_balancing = not balancingVar.get()
guiargs.extendedmsu = extendedmsuVar.get()
if guiargs.timer == "none": if guiargs.timer == "none":
guiargs.timer = False guiargs.timer = False
guiargs.dungeon_counters = dungeonCounterVar.get() guiargs.dungeon_counters = dungeonCounterVar.get()

View File

@ -57,7 +57,6 @@ def main(args, seed=None):
world.shufflepots = args.shufflepots.copy() world.shufflepots = args.shufflepots.copy()
world.progressive = args.progressive.copy() world.progressive = args.progressive.copy()
world.dungeon_counters = args.dungeon_counters.copy() world.dungeon_counters = args.dungeon_counters.copy()
world.extendedmsu = args.extendedmsu.copy()
world.glitch_boots = args.glitch_boots.copy() world.glitch_boots = args.glitch_boots.copy()
world.progression_balancing = {player: not balance for player, balance in args.skip_progression_balancing.items()} world.progression_balancing = {player: not balance for player, balance in args.skip_progression_balancing.items()}
@ -163,15 +162,15 @@ def main(args, seed=None):
or world.enemy_health[player] != 'default' or world.enemy_damage[player] != 'default' or world.enemy_health[player] != 'default' or world.enemy_damage[player] != 'default'
or args.shufflepots[player] or sprite_random_on_hit) or args.shufflepots[player] or sprite_random_on_hit)
rom = JsonRom() if args.jsonout or use_enemizer else LocalRom(args.rom, extendedmsu=args.extendedmsu[player]) rom = JsonRom() if args.jsonout or use_enemizer else LocalRom(args.rom)
patch_rom(world, rom, player, team, use_enemizer) patch_rom(world, rom, player, team, use_enemizer)
if use_enemizer and (args.enemizercli or not args.jsonout): if use_enemizer and (args.enemizercli or not args.jsonout):
patch_enemizer(world, player, rom, args.rom, args.enemizercli, args.shufflepots[player], patch_enemizer(world, player, rom, args.rom, args.enemizercli, args.shufflepots[player],
sprite_random_on_hit, extendedmsu=args.extendedmsu[player]) sprite_random_on_hit)
if not args.jsonout: if not args.jsonout:
rom = LocalRom.fromJsonRom(rom, args.rom, 0x400000, args.extendedmsu[player]) rom = LocalRom.fromJsonRom(rom, args.rom, 0x400000)
if args.race: if args.race:
patch_race_rom(rom) patch_race_rom(rom)
@ -326,7 +325,6 @@ def copy_world(world):
ret.beemizer = world.beemizer.copy() ret.beemizer = world.beemizer.copy()
ret.timer = world.timer.copy() ret.timer = world.timer.copy()
ret.shufflepots = world.shufflepots.copy() ret.shufflepots = world.shufflepots.copy()
ret.extendedmsu = world.extendedmsu.copy()
for player in range(1, world.players + 1): for player in range(1, world.players + 1):
if world.mode[player] != 'inverted': if world.mode[player] != 'inverted':

View File

@ -376,7 +376,6 @@ def roll_settings(weights):
romweights = weights['rom'] romweights = weights['rom']
ret.sprite = get_choice('sprite', romweights) ret.sprite = get_choice('sprite', romweights)
ret.disablemusic = get_choice('disablemusic', romweights) ret.disablemusic = get_choice('disablemusic', romweights)
ret.extendedmsu = get_choice('extendedmsu', romweights)
ret.quickswap = get_choice('quickswap', romweights) ret.quickswap = get_choice('quickswap', romweights)
ret.fastmenu = get_choice('menuspeed', romweights) ret.fastmenu = get_choice('menuspeed', romweights)
ret.heartcolor = get_choice('heartcolor', romweights) ret.heartcolor = get_choice('heartcolor', romweights)

23
Rom.py
View File

@ -22,8 +22,7 @@ from EntranceShuffle import door_addresses
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '1347ce535618fa1a844d2d45cf0ca661' RANDOMIZERBASEHASH = '680f844ec899a8349a11d95de17547f9'
EXTENDEDMSURANDOMIZERBASEHASH = 'f42949bde03ba5ea71c2d43a21f5d6bf'
class JsonRom(object): class JsonRom(object):
@ -74,15 +73,14 @@ class JsonRom(object):
class LocalRom(object): class LocalRom(object):
def __init__(self, file, extendedmsu=False, patch=True, name=None, hash=None): def __init__(self, file, patch=True, name=None, hash=None):
self.name = name self.name = name
self.hash = hash self.hash = hash
self.orig_buffer = None self.orig_buffer = None
self.extendedmsu = extendedmsu
with open(file, 'rb') as stream: with open(file, 'rb') as stream:
self.buffer = read_rom(stream) self.buffer = read_rom(stream)
if patch: if patch:
self.patch_base_rom(extendedmsu) self.patch_base_rom()
self.orig_buffer = self.buffer.copy() self.orig_buffer = self.buffer.copy()
def write_byte(self, address: int, value): def write_byte(self, address: int, value):
@ -96,14 +94,14 @@ class LocalRom(object):
outfile.write(self.buffer) outfile.write(self.buffer)
@staticmethod @staticmethod
def fromJsonRom(rom, file, rom_size=0x200000, extendedmsu=False): def fromJsonRom(rom, file, rom_size=0x200000):
ret = LocalRom(file, extendedmsu, True, rom.name, rom.hash) ret = LocalRom(file, True, rom.name, rom.hash)
ret.buffer.extend(bytearray([0x00]) * (rom_size - len(ret.buffer))) ret.buffer.extend(bytearray([0x00]) * (rom_size - len(ret.buffer)))
for address, values in rom.patches.items(): for address, values in rom.patches.items():
ret.write_bytes(int(address), values) ret.write_bytes(int(address), values)
return ret return ret
def patch_base_rom(self, extendedmsu): def patch_base_rom(self):
# verify correct checksum of baserom # verify correct checksum of baserom
basemd5 = hashlib.md5() basemd5 = hashlib.md5()
basemd5.update(self.buffer) basemd5.update(self.buffer)
@ -114,7 +112,7 @@ class LocalRom(object):
self.buffer.extend(bytearray([0x00]) * (0x200000 - len(self.buffer))) self.buffer.extend(bytearray([0x00]) * (0x200000 - len(self.buffer)))
# load randomizer patches # load randomizer patches
with open(local_path('data/base2current.json') if not extendedmsu else local_path('data/base2current_extendedmsu.json'), 'r') as stream: with open(local_path('data/base2current.json')) as stream:
patches = json.load(stream) patches = json.load(stream)
for patch in patches: for patch in patches:
if isinstance(patch, dict): if isinstance(patch, dict):
@ -124,7 +122,7 @@ class LocalRom(object):
# verify md5 # verify md5
patchedmd5 = hashlib.md5() patchedmd5 = hashlib.md5()
patchedmd5.update(self.buffer) patchedmd5.update(self.buffer)
if patchedmd5.hexdigest() not in [RANDOMIZERBASEHASH, EXTENDEDMSURANDOMIZERBASEHASH]: if patchedmd5.hexdigest() not in [RANDOMIZERBASEHASH]:
raise RuntimeError('Provided Base Rom unsuitable for patching. Please provide a JAP(1.0) "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc" rom to use as a base.') raise RuntimeError('Provided Base Rom unsuitable for patching. Please provide a JAP(1.0) "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc" rom to use as a base.')
def write_crc(self): def write_crc(self):
@ -159,10 +157,9 @@ def read_rom(stream) -> bytearray:
buffer = buffer[0x200:] buffer = buffer[0x200:]
return buffer return buffer
def patch_enemizer(world, player, rom, baserom_path, enemizercli, shufflepots, random_sprite_on_hit, extendedmsu): def patch_enemizer(world, player, rom, baserom_path, enemizercli, shufflepots, random_sprite_on_hit):
baserom_path = os.path.abspath(baserom_path) baserom_path = os.path.abspath(baserom_path)
basepatch_path = os.path.abspath( basepatch_path = os.path.abspath(local_path('data/base2current.json'))
local_path('data/base2current.json') if not extendedmsu else local_path('data/base2current_extendedmsu.json'))
enemizer_basepatch_path = os.path.join(os.path.dirname(enemizercli), "enemizerBasePatch.json") enemizer_basepatch_path = os.path.join(os.path.dirname(enemizercli), "enemizerBasePatch.json")
randopatch_path = os.path.abspath(output_path(f'enemizer_randopatch_{player}.json')) randopatch_path = os.path.abspath(output_path(f'enemizer_randopatch_{player}.json'))
options_path = os.path.abspath(output_path(f'enemizer_options_{player}.json')) options_path = os.path.abspath(output_path(f'enemizer_options_{player}.json'))

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long