diff --git a/.gitignore b/.gitignore index c4ce894b..2c13bec1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ README.html *multidata *multisave EnemizerCLI/ -.mypy_cache/ \ No newline at end of file +.mypy_cache/ +RaceRom.py \ No newline at end of file diff --git a/EntranceRandomizer.py b/EntranceRandomizer.py index 547514bb..76aed357 100755 --- a/EntranceRandomizer.py +++ b/EntranceRandomizer.py @@ -255,6 +255,7 @@ def start(): parser.add_argument('--multi', default=1, type=lambda value: min(max(int(value), 1), 255)) parser.add_argument('--names', default='') parser.add_argument('--outputpath') + parser.add_argument('--race', default=False, action='store_true') args = parser.parse_args() if args.outputpath and os.path.isdir(args.outputpath): diff --git a/Main.py b/Main.py index fb9f122f..20a7548c 100644 --- a/Main.py +++ b/Main.py @@ -12,7 +12,7 @@ from BaseClasses import World, CollectionState, Item, Region, Location, Shop from Regions import create_regions, mark_light_world_regions from InvertedRegions import create_inverted_regions, mark_dark_world_regions from EntranceShuffle import link_entrances, link_inverted_entrances -from Rom import patch_rom, get_enemizer_patch, apply_rom_settings, Sprite, LocalRom, JsonRom +from Rom import patch_rom, get_race_rom_patches, get_enemizer_patch, apply_rom_settings, Sprite, LocalRom, JsonRom from Rules import set_rules from Dungeons import create_dungeons, fill_dungeons, fill_dungeons_restrictive from Fill import distribute_items_cutoff, distribute_items_staleness, distribute_items_restrictive, flood_items, balance_multiworld_progression @@ -174,11 +174,17 @@ def main(args, seed=None): jsonout[f'patch{player}'] = rom.patches if use_enemizer: jsonout[f'enemizer{player}'] = enemizer_patch + if args.race: + jsonout[f'race{player}'] = get_race_rom_patches(rom) else: if use_enemizer: local_rom.patch_enemizer(rom.patches, os.path.join(os.path.dirname(args.enemizercli), "enemizerBasePatch.json"), enemizer_patch) rom = local_rom + if args.race: + for addr, values in get_race_rom_patches(rom).items(): + rom.write_bytes(int(addr), values) + apply_rom_settings(rom, args.heartbeep, args.heartcolor, world.quickswap, world.fastmenu, world.disable_music, sprite, player_names) outfilepname = f'P{player}_' if world.players > 1 else '' + f'{player_names[player]}_' if player in player_names else '' rom.write_to_file(output_path(f'{outfileprefix}{outfilepname}{outfilesuffix}.sfc')) diff --git a/Rom.py b/Rom.py index da5574df..8f1f59fa 100644 --- a/Rom.py +++ b/Rom.py @@ -5,6 +5,7 @@ import logging import os import random import struct +import sys import subprocess from BaseClasses import ShopType, Region, Location, Item @@ -852,7 +853,6 @@ def patch_rom(world, player, rom, enemized): rom.write_byte(0x180167, world.treasure_hunt_count % 256) rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled) - # TODO: a proper race rom mode should be implemented, that changes the following flag, and rummages the table (or uses the future encryption feature, etc) rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed gametype = 0x04 # item @@ -1069,6 +1069,19 @@ def patch_rom(world, player, rom, enemized): return rom +try: + import RaceRom +except ImportError: + RaceRom = None + +def get_race_rom_patches(rom): + patches = {str(0x180213): [0x01, 0x00]} # Tournament Seed + + if 'RaceRom' in sys.modules: + RaceRom.encrypt(rom, patches) + + return patches + def write_custom_shops(rom, world, player): shops = [shop for shop in world.shops if shop.replaceable and shop.active and shop.region.player == player]