def adjust(args):
    start = time.clock()
    logger = logging.getLogger('')
    logger.info('Patching ROM.')

    if args.sprite is not None:
        if isinstance(args.sprite, Sprite):
            sprite = args.sprite
        else:
            sprite = Sprite(args.sprite)
    else:
        sprite = None

    outfilebase = os.path.basename(args.rom)[:-4] + '_adjusted'

    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.heartcolor, 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
def adjust(args):
    start = time.process_time()
    logger = logging.getLogger('')
    logger.info('Patching ROM.')

    outfilebase = os.path.basename(args.rom)[:-4] + '_adjusted'

    if os.stat(args.rom).st_size in (0x200000, 0x400000) and os.path.splitext(
            args.rom)[-1].lower() == '.sfc':
        rom = LocalRom(args.rom, False)
        if os.path.isfile(args.baserom):
            baserom = LocalRom(args.baserom, True)
            rom.orig_buffer = baserom.orig_buffer
    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.heartcolor, args.quickswap,
                       args.fastmenu, args.disablemusic, args.sprite,
                       args.ow_palettes, args.uw_palettes)

    rom.write_to_file(output_path('%s.sfc' % outfilebase))

    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.process_time() - start)

    return args
def adjust(args):
    start = time.perf_counter()
    logger = logging.getLogger('Adjuster')
    logger.info('Patching ROM.')

    if os.path.splitext(args.rom)[-1].lower() == '.bmbp':
        import Patch
        meta, args.rom = Patch.create_rom_file(args.rom)

    if os.stat(args.rom).st_size in (0x200000, 0x400000) and os.path.splitext(
            args.rom)[-1].lower() == '.sfc':
        rom = LocalRom(args.rom, patch=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.heartcolor, args.quickswap,
                       args.fastmenu, args.disablemusic, args.sprite,
                       args.ow_palettes, args.uw_palettes)
    path = output_path(f'{os.path.basename(args.rom)[:-4]}_adjusted.sfc')
    rom.write_to_file(path)

    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.perf_counter() - start)

    return args, path
예제 #4
0
def adjust(args):
    start = time.perf_counter()
    logger = logging.getLogger('Adjuster')
    logger.info('Patching ROM.')
    vanillaRom = args.baserom
    if os.path.splitext(args.rom)[-1].lower() == '.bmbp':
        import Patch
        meta, args.rom = Patch.create_rom_file(args.rom)

    if os.stat(args.rom).st_size in (0x200000, 0x400000) and os.path.splitext(
            args.rom)[-1].lower() == '.sfc':
        rom = LocalRom(args.rom, patch=False, vanillaRom=vanillaRom)
    else:
        raise RuntimeError(
            'Provided Rom is not a valid Link to the Past Randomizer Rom. Please provide one for adjusting.'
        )
    palettes_options = {}
    palettes_options['dungeon'] = args.uw_palettes

    palettes_options['overworld'] = args.ow_palettes
    palettes_options['hud'] = args.hud_palettes
    palettes_options['sword'] = args.sword_palettes
    palettes_options['shield'] = args.shield_palettes
    # palettes_options['link']=args.link_palettesvera
    racerom = rom.read_byte(0x180213) > 0

    apply_rom_settings(
        rom,
        args.heartbeep,
        args.heartcolor,
        args.quickswap,
        args.fastmenu,
        args.disablemusic,
        args.sprite,
        palettes_options,
        cutscenespeed=args.cutscenespeed if not racerom else "normal",
        reduceflashing=args.reduceflashing)
    path = output_path(f'{os.path.basename(args.rom)[:-4]}_adjusted.sfc')
    rom.write_to_file(path)

    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.perf_counter() - start)

    return args, path
예제 #5
0
def main(args, seed=None):
    start = time.clock()

    # initialize the world
    world = World(args.bridge, args.open_forest, args.open_door_of_time,
                  not args.nodungeonitems, args.beatableonly, args.hints)
    logger = logging.getLogger('')
    if seed is None:
        random.seed(None)
        world.seed = random.randint(0, 999999999)
    else:
        world.seed = int(seed)
    random.seed(world.seed)

    logger.info('OoT Randomizer Version %s  -  Seed: %s\n\n', __version__,
                world.seed)

    create_regions(world)

    create_dungeons(world)

    logger.info('Shuffling the World about.')

    link_entrances(world)

    logger.info('Calculating Access Rules.')

    set_rules(world)

    logger.info('Generating Item Pool.')

    generate_itempool(world)

    logger.info('Placing Dungeon Items.')

    shuffled_locations = None
    shuffled_locations = world.get_unfilled_locations()
    random.shuffle(shuffled_locations)
    fill_dungeons_restrictive(world, shuffled_locations)

    logger.info('Fill the world.')

    distribute_items_restrictive(world)

    logger.info('Calculating playthrough.')

    create_playthrough(world)

    logger.info('Patching ROM.')

    outfilebase = 'OoT_%s%s%s%s_%s' % (
        world.bridge, "-openforest" if world.open_forest else "",
        "-opendoor" if world.open_door_of_time else "",
        "-beatableonly" if world.check_beatable_only else "", world.seed)

    if not args.suppress_rom:
        rom = LocalRom(args.rom)
        patch_rom(world, rom)
        rom.write_to_file(output_path('%s.z64' % outfilebase))
        if args.compress_rom:
            logger.info('Compressing ROM.')
            if platform.system() == 'Windows':
                subprocess.call([
                    "Compress\Compress.exe",
                    (output_path('%s.z64' % outfilebase)),
                    (output_path('%s-comp.z64' % outfilebase))
                ])
            elif platform.system() == 'Linux':
                subprocess.call(
                    ["Compress/Compress", ('%s.z64' % outfilebase)])
            elif platform.system() == 'Darwin':
                subprocess.call(
                    ["Compress/Compress.out", ('%s.z64' % outfilebase)])
            else:
                logger.info('OS not supported for compression')

    if args.create_spoiler:
        world.spoiler.to_file(output_path('%s_Spoiler.txt' % outfilebase))

    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.clock() - start)

    return world
예제 #6
0
    def _gen_rom(team: int, player: int):
        sprite_random_on_hit = type(
            args.sprite[player]) is str and args.sprite[player].lower(
            ) == 'randomonhit'
        use_enemizer = (world.boss_shuffle[player] != 'none'
                        or world.enemy_shuffle[player] != 'none'
                        or world.enemy_health[player] != 'default'
                        or world.enemy_damage[player] != 'default'
                        or args.shufflepots[player] or sprite_random_on_hit)

        rom = LocalRom(args.rom)

        patch_rom(world, rom, player, team, use_enemizer)

        if use_enemizer:
            patch_enemizer(world, player, rom, args.enemizercli,
                           sprite_random_on_hit)

        if args.race:
            patch_race_rom(rom)

        world.spoiler.hashes[(player, team)] = get_hash_string(rom.hash)

        apply_rom_settings(rom, args.heartbeep[player],
                           args.heartcolor[player], args.quickswap[player],
                           args.fastmenu[player], args.disablemusic[player],
                           args.sprite[player], args.ow_palettes[player],
                           args.uw_palettes[player])

        mcsb_name = ''
        if all([
                world.mapshuffle[player], world.compassshuffle[player],
                world.keyshuffle[player], world.bigkeyshuffle[player]
        ]):
            mcsb_name = '-keysanity'
        elif [
                world.mapshuffle[player], world.compassshuffle[player],
                world.keyshuffle[player], world.bigkeyshuffle[player]
        ].count(True) == 1:
            mcsb_name = '-mapshuffle' if world.mapshuffle[
                player] else '-compassshuffle' if world.compassshuffle[
                    player] else '-keyshuffle' if world.keyshuffle[
                        player] else '-bigkeyshuffle'
        elif any([
                world.mapshuffle[player], world.compassshuffle[player],
                world.keyshuffle[player], world.bigkeyshuffle[player]
        ]):
            mcsb_name = '-%s%s%s%sshuffle' % (
                'M' if world.mapshuffle[player] else '',
                'C' if world.compassshuffle[player] else '',
                'S' if world.keyshuffle[player] else '',
                'B' if world.bigkeyshuffle[player] else '')

        outfilepname = f'_T{team + 1}' if world.teams > 1 else ''
        if world.players > 1:
            outfilepname += f'_P{player}'
        if world.players > 1 or world.teams > 1:
            outfilepname += f"_{world.player_names[player][team].replace(' ', '_')}" if world.player_names[
                player][team] != 'Player%d' % player else ''
        outfilesuffix = (
            '_%s_%s-%s-%s-%s%s_%s-%s%s%s%s%s' %
            (world.logic[player], world.difficulty[player],
             world.difficulty_adjustments[player], world.mode[player],
             world.goal[player],
             "" if world.timer[player] in [False, 'display'] else "-" +
             world.timer[player], world.shuffle[player], world.algorithm,
             mcsb_name, "-retro" if world.retro[player] else "",
             "-prog_" + world.progressive[player] if world.progressive[player]
             in ['off', 'random'] else "", "-nohints" if
             not world.hints[player] else "")) if not args.outputname else ''
        rompath = output_path(
            f'{outfilebase}{outfilepname}{outfilesuffix}.sfc')
        rom.write_to_file(rompath)
        if args.create_diff:
            import Patch
            Patch.create_patch_file(rompath)
        return (player, team, list(rom.name))
예제 #7
0
def main(settings, window=dummy_window()):

    start = time.clock()

    logger = logging.getLogger('')

    worlds = []

    allowed_tricks = {}
    for trick in logic_tricks.values():
        settings.__dict__[
            trick['name']] = trick['name'] in settings.allowed_tricks

    # we load the rom before creating the seed so that error get caught early
    if settings.compress_rom == 'None' and not settings.create_spoiler:
        raise Exception(
            '`No Output` must have spoiler enabled to produce anything.')

    if settings.compress_rom != 'None':
        window.update_status('Loading ROM')
        rom = LocalRom(settings)

    if not settings.world_count:
        settings.world_count = 1
    if settings.world_count < 1 or settings.world_count > 255:
        raise Exception('World Count must be between 1 and 255')
    if settings.player_num > settings.world_count or settings.player_num < 1:
        if settings.compress_rom not in ['None', 'Patch']:
            raise Exception('Player Num must be between 1 and %d' %
                            settings.world_count)
        else:
            settings.player_num = 1

    settings.remove_disabled()

    logger.info('OoT Randomizer Version %s  -  Seed: %s\n\n', __version__,
                settings.seed)
    random.seed(settings.numeric_seed)
    for i in range(0, settings.world_count):
        worlds.append(World(settings))

    window.update_status('Creating the Worlds')
    for id, world in enumerate(worlds):
        world.id = id
        logger.info('Generating World %d.' % id)

        window.update_progress(0 + 1 * (id + 1) / settings.world_count)
        logger.info('Creating Overworld')

        # Determine MQ Dungeons
        td_count = len(world.dungeon_mq)
        if world.mq_dungeons_random:
            world.mq_dungeons = random.randint(0, td_count)
        mqd_count = world.mq_dungeons
        mqd_picks = random.sample(list(world.dungeon_mq), mqd_count)
        for dung in mqd_picks:
            world.dungeon_mq[dung] = True

        overworld_data = os.path.join(data_path('World'), 'Overworld.json')
        world.load_regions_from_json(overworld_data)

        create_dungeons(world)

        world.initialize_entrances()

        if settings.shopsanity != 'off':
            world.random_shop_prices()
        world.set_scrub_prices()

        window.update_progress(0 + 4 * (id + 1) / settings.world_count)
        logger.info('Calculating Access Rules.')
        set_rules(world)

        window.update_progress(0 + 5 * (id + 1) / settings.world_count)
        logger.info('Generating Item Pool.')
        generate_itempool(world)

    window.update_status('Placing the Items')
    logger.info('Fill the world.')
    distribute_items_restrictive(window, worlds)
    window.update_progress(35)

    spoiler = Spoiler(worlds)
    cosmetics_log = None
    if settings.create_spoiler:
        window.update_status('Calculating Spoiler Data')
        logger.info('Calculating playthrough.')
        create_playthrough(spoiler)
        window.update_progress(50)
    if settings.create_spoiler or settings.hints != 'none':
        window.update_status('Calculating Hint Data')
        State.update_required_items(spoiler)
        for world in worlds:
            world.update_useless_areas(spoiler)
            buildGossipHints(spoiler, world)
        window.update_progress(55)
    spoiler.build_file_hash()

    logger.info('Patching ROM.')

    settings_string_hash = hashlib.sha1(
        settings.settings_string.encode('utf-8')).hexdigest().upper()[:5]
    if settings.output_file:
        outfilebase = settings.output_file
    elif settings.world_count > 1:
        outfilebase = 'OoT_%s_%s_W%d' % (settings_string_hash, settings.seed,
                                         settings.world_count)
    else:
        outfilebase = 'OoT_%s_%s' % (settings_string_hash, settings.seed)

    output_dir = default_output_path(settings.output_dir)

    if settings.compress_rom == 'Patch':
        rng_state = random.getstate()
        file_list = []
        window.update_progress(65)
        for world in worlds:
            if settings.world_count > 1:
                window.update_status('Patching ROM: Player %d' %
                                     (world.id + 1))
                patchfilename = '%sP%d.zpf' % (outfilebase, world.id + 1)
            else:
                window.update_status('Patching ROM')
                patchfilename = '%s.zpf' % outfilebase

            random.setstate(rng_state)
            patch_rom(spoiler, world, rom)
            patch_cosmetics(settings, rom)
            window.update_progress(65 + 20 *
                                   (world.id + 1) / settings.world_count)

            window.update_status('Creating Patch File')
            output_path = os.path.join(output_dir, patchfilename)
            file_list.append(patchfilename)
            create_patch_file(rom, output_path)
            rom.restore()
            window.update_progress(65 + 30 *
                                   (world.id + 1) / settings.world_count)

        if settings.world_count > 1:
            window.update_status('Creating Patch Archive')
            output_path = os.path.join(output_dir, '%s.zpfz' % outfilebase)
            with zipfile.ZipFile(output_path, mode="w") as patch_archive:
                for index, file in enumerate(file_list):
                    file_path = os.path.join(output_dir, file)
                    patch_archive.write(file_path,
                                        'P%d.zpf' % (index + 1),
                                        compress_type=zipfile.ZIP_DEFLATED)
            for file in file_list:
                os.remove(os.path.join(output_dir, file))
        logger.info("Created patchfile at: %s" % output_path)
        window.update_progress(95)

    elif settings.compress_rom != 'None':
        window.update_status('Patching ROM')
        patch_rom(spoiler, worlds[settings.player_num - 1], rom)
        cosmetics_log = patch_cosmetics(settings, rom)
        window.update_progress(65)

        window.update_status('Saving Uncompressed ROM')
        if settings.world_count > 1:
            filename = "%sP%d.z64" % (outfilebase, settings.player_num)
        else:
            filename = '%s.z64' % outfilebase
        output_path = os.path.join(output_dir, filename)
        rom.write_to_file(output_path)
        if settings.compress_rom == 'True':
            window.update_status('Compressing ROM')
            logger.info('Compressing ROM.')

            if is_bundled():
                compressor_path = "."
            else:
                compressor_path = "Compress"

            if platform.system() == 'Windows':
                if 8 * struct.calcsize("P") == 64:
                    compressor_path += "\\Compress.exe"
                else:
                    compressor_path += "\\Compress32.exe"
            elif platform.system() == 'Linux':
                if platform.uname()[4] == 'aarch64' or platform.uname(
                )[4] == 'arm64':
                    compressor_path += "/Compress_ARM64"
                else:
                    compressor_path += "/Compress"
            elif platform.system() == 'Darwin':
                compressor_path += "/Compress.out"
            else:
                compressor_path = ""
                logger.info('OS not supported for compression')

            output_compress_path = output_path[:output_path.
                                               rfind('.')] + '-comp.z64'
            if compressor_path != "":
                run_process(
                    window, logger,
                    [compressor_path, output_path, output_compress_path])
            os.remove(output_path)
            logger.info("Created compessed rom at: %s" % output_compress_path)
        else:
            logger.info("Created uncompessed rom at: %s" % output_path)
        window.update_progress(95)

    for world in worlds:
        for setting in world.settings.__dict__:
            world.settings.__dict__[setting] = world.__dict__[setting]

    if settings.create_spoiler:
        window.update_status('Creating Spoiler Log')
        spoiler.to_file(
            os.path.join(output_dir, '%s_Spoiler.txt' % outfilebase))
    else:
        window.update_status('Creating Settings Log')
        spoiler.to_file(
            os.path.join(output_dir, '%s_Settings.txt' % outfilebase))
    logger.info("Created spoiler log at: %s" %
                ('%s_Settings.txt' % outfilebase))

    if settings.create_cosmetics_log and cosmetics_log:
        window.update_status('Creating Cosmetics Log')
        if settings.world_count > 1 and not settings.output_file:
            filename = "%sP%d_Cosmetics.txt" % (outfilebase,
                                                settings.player_num)
        else:
            filename = '%s_Cosmetics.txt' % outfilebase
        cosmetic_path = os.path.join(output_dir, filename)
        cosmetics_log.to_file(cosmetic_path)
        logger.info("Created cosmetic log at: %s" % cosmetic_path)

    window.update_progress(100)
    if cosmetics_log and cosmetics_log.error:
        window.update_status(
            'Success: Rom patched successfully. Some cosmetics could not be applied.'
        )
    else:
        window.update_status('Success: Rom patched successfully')
    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.clock() - start)

    return worlds[settings.player_num - 1]
예제 #8
0
def from_patch_file(settings, window=dummy_window()):
    start = time.clock()
    logger = logging.getLogger('')

    # we load the rom before creating the seed so that error get caught early
    if settings.compress_rom == 'None' or settings.compress_rom == 'Patch':
        raise Exception(
            'Output Type must be a ROM when patching from a patch file.')
    window.update_status('Loading ROM')
    rom = LocalRom(settings)

    logger.info('Patching ROM.')

    filename_split = os.path.basename(settings.patch_file).split('.')

    if settings.output_file:
        outfilebase = settings.output_file
    else:
        outfilebase = filename_split[0]

    extension = filename_split[-1]

    output_dir = default_output_path(settings.output_dir)
    output_path = os.path.join(output_dir, outfilebase)

    window.update_status('Patching ROM')
    if extension == 'zpf':
        subfile = None
    else:
        subfile = 'P%d.zpf' % (settings.player_num)
        if not settings.output_file:
            output_path += 'P%d' % (settings.player_num)
    apply_patch_file(rom, settings.patch_file, subfile)
    cosmetics_log = patch_cosmetics(settings, rom)
    window.update_progress(65)

    window.update_status('Saving Uncompressed ROM')
    uncompressed_output_path = output_path + '.z64'
    rom.write_to_file(uncompressed_output_path)
    if settings.compress_rom == 'True':
        window.update_status('Compressing ROM')
        logger.info('Compressing ROM.')

        if is_bundled():
            compressor_path = "."
        else:
            compressor_path = "Compress"

        if platform.system() == 'Windows':
            if 8 * struct.calcsize("P") == 64:
                compressor_path += "\\Compress.exe"
            else:
                compressor_path += "\\Compress32.exe"
        elif platform.system() == 'Linux':
            compressor_path += "/Compress"
        elif platform.system() == 'Darwin':
            compressor_path += "/Compress.out"
        else:
            compressor_path = ""
            logger.info('OS not supported for compression')

        output_compress_path = output_path + '-comp.z64'
        if compressor_path != "":
            run_process(window, logger, [
                compressor_path, uncompressed_output_path, output_compress_path
            ])
        os.remove(uncompressed_output_path)
        logger.info("Created compessed rom at: %s" % output_compress_path)
    else:
        logger.info("Created uncompessed rom at: %s" % output_path)

    window.update_progress(95)

    if settings.create_cosmetics_log and cosmetics_log:
        window.update_status('Creating Cosmetics Log')
        if settings.world_count > 1 and not settings.output_file:
            filename = "%sP%d_Cosmetics.txt" % (outfilebase,
                                                settings.player_num)
        else:
            filename = '%s_Cosmetics.txt' % outfilebase
        cosmetic_path = os.path.join(output_dir, filename)
        cosmetics_log.to_file(cosmetic_path)
        logger.info("Created cosmetic log at: %s" % cosmetic_path)

    window.update_progress(100)
    if cosmetics_log and cosmetics_log.error:
        window.update_status(
            'Success: Rom patched successfully. Some cosmetics could not be applied.'
        )
    else:
        window.update_status('Success: Rom patched successfully')

    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.clock() - start)

    return True
예제 #9
0
    def _gen_rom(team: int, player: int):
        use_enemizer = (world.boss_shuffle[player] != 'none'
                        or world.enemy_shuffle[player]
                        or world.enemy_health[player] != 'default'
                        or world.enemy_damage[player] != 'default'
                        or world.shufflepots[player]
                        or world.bush_shuffle[player]
                        or world.killable_thieves[player])

        rom = LocalRom(args.rom)

        patch_rom(world, rom, player, team, use_enemizer)

        if use_enemizer:
            patch_enemizer(world, team, player, rom, args.enemizercli)

        if args.race:
            patch_race_rom(rom, world, player)

        world.spoiler.hashes[(player, team)] = get_hash_string(rom.hash)

        palettes_options = {}
        palettes_options['dungeon'] = args.uw_palettes[player]
        palettes_options['overworld'] = args.ow_palettes[player]
        palettes_options['hud'] = args.hud_palettes[player]
        palettes_options['sword'] = args.sword_palettes[player]
        palettes_options['shield'] = args.shield_palettes[player]
        palettes_options['link'] = args.link_palettes[player]

        apply_rom_settings(rom, args.heartbeep[player],
                           args.heartcolor[player], args.quickswap[player],
                           args.fastmenu[player], args.disablemusic[player],
                           args.sprite[player], palettes_options, world,
                           player, True)

        mcsb_name = ''
        if all([
                world.mapshuffle[player], world.compassshuffle[player],
                world.keyshuffle[player], world.bigkeyshuffle[player]
        ]):
            mcsb_name = '-keysanity'
        elif [
                world.mapshuffle[player], world.compassshuffle[player],
                world.keyshuffle[player], world.bigkeyshuffle[player]
        ].count(True) == 1:
            mcsb_name = '-mapshuffle' if world.mapshuffle[player] else \
                '-compassshuffle' if world.compassshuffle[player] else \
                '-universal_keys' if world.keyshuffle[player] == "universal" else \
                '-keyshuffle' if world.keyshuffle[player] else '-bigkeyshuffle'
        elif any([
                world.mapshuffle[player], world.compassshuffle[player],
                world.keyshuffle[player], world.bigkeyshuffle[player]
        ]):
            mcsb_name = '-%s%s%s%sshuffle' % (
                'M' if world.mapshuffle[player] else '',
                'C' if world.compassshuffle[player] else '',
                'U' if world.keyshuffle[player] == "universal" else
                'S' if world.keyshuffle[player] else '',
                'B' if world.bigkeyshuffle[player] else '')

        outfilepname = f'_T{team + 1}' if world.teams > 1 else ''
        outfilepname += f'_P{player}'
        outfilepname += f"_{world.player_names[player][team].replace(' ', '_')}" \
            if world.player_names[player][team] != 'Player%d' % player else ''
        outfilestuffs = {
            "logic": world.logic[player],  # 0
            "difficulty": world.difficulty[player],  # 1
            "item_functionality": world.item_functionality[player],  # 2
            "mode": world.mode[player],  # 3
            "goal": world.goal[player],  # 4
            "timer": str(world.timer[player]),  # 5
            "shuffle": world.shuffle[player],  # 6
            "algorithm": world.algorithm,  # 7
            "mscb": mcsb_name,  # 8
            "retro": world.retro[player],  # 9
            "progressive": world.progressive,  # A
            "hints": 'True' if world.hints[player] else 'False'  # B
        }
        #                  0  1  2  3  4 5  6  7 8 9 A B
        outfilesuffix = (
            '_%s_%s-%s-%s-%s%s_%s-%s%s%s%s%s' % (
                #  0          1      2      3    4     5    6      7     8        9         A     B           C
                # _noglitches_normal-normal-open-ganon-ohko_simple-balanced-keysanity-retro-prog_random-nohints
                # _noglitches_normal-normal-open-ganon     _simple-balanced-keysanity-retro
                # _noglitches_normal-normal-open-ganon     _simple-balanced-keysanity      -prog_random
                # _noglitches_normal-normal-open-ganon     _simple-balanced-keysanity                  -nohints
                outfilestuffs["logic"],  # 0
                outfilestuffs["difficulty"],  # 1
                outfilestuffs["item_functionality"],  # 2
                outfilestuffs["mode"],  # 3
                outfilestuffs["goal"],  # 4
                "" if outfilestuffs["timer"] in ['False', 'none', 'display']
                else "-" + outfilestuffs["timer"],  # 5
                outfilestuffs["shuffle"],  # 6
                outfilestuffs["algorithm"],  # 7
                outfilestuffs["mscb"],  # 8
                "-retro" if outfilestuffs["retro"] == "True" else "",  # 9
                "-prog_" + outfilestuffs["progressive"] if
                outfilestuffs["progressive"] in ['off', 'random'] else "",  # A
                "-nohints" if not outfilestuffs["hints"] == "True" else ""
            )  # B
        ) if not args.outputname else ''
        rompath = output_path(
            f'{outfilebase}{outfilepname}{outfilesuffix}.sfc')
        rom.write_to_file(rompath, hide_enemizer=True)
        if args.create_diff:
            Patch.create_patch_file(rompath)
        return player, team, bytes(rom.name).decode()
예제 #10
0
def main(settings, window=dummy_window()):

    start = time.clock()
    logger = logging.getLogger('')

    # initialize the world
    worlds = []
    if not settings.world_count:
        settings.world_count = 1
    if settings.world_count < 1:
        raise Exception('World Count must be at least 1')
    if settings.player_num > settings.world_count or settings.player_num < 1:
        raise Exception('Player Num must be between 1 and %d' % settings.world_count)

    for i in range(0, settings.world_count):
        worlds.append(World(settings))

    logger.info('Patching ROM.')

    outfilebase = 'BOoT_%s' % (worlds[0].settings_string)
    output_dir = default_output_path(settings.output_dir)

    window.update_status('Patching ROM')
    rom = LocalRom(settings)
    patch_rom(worlds[settings.player_num - 1], rom)
    window.update_progress(50)

    rom_path = os.path.join(output_dir, '%s.z64' % outfilebase)
    wad_path = os.path.join(output_dir, '%s.wad' % outfilebase)

    window.update_status('Saving Uncompressed ROM')
    rom.write_to_file(rom_path)

    window.update_status('Compressing ROM')
    logger.info('Compressing ROM.')

    compressor_path = ""
    if platform.system() == 'Windows':
        if 8 * struct.calcsize("P") == 64:
            compressor_path = "bin\\Compress\\Compress.exe"
        else:
            compressor_path = "bin\\Compress\\Compress32.exe"
    elif platform.system() == 'Linux':
        compressor_path = "bin/Compress/Compress"
    elif platform.system() == 'Darwin':
        compressor_path = "bin/Compress/Compress.out"
    else:
        logger.info('OS not supported for compression')

    #uncomment below for decompressed output (for debugging)
    #rom.write_to_file(default_output_path('%s.z64' % outfilebase))
    run_process(window, logger, [compressor_path, rom_path, os.path.join(output_dir, '%s-comp.z64' % outfilebase)], None)
    os.remove(rom_path)
    window.update_progress(85)

    #wad generation
    window.update_status('Generating WAD')
    logger.info('Generating WAD.')

    if settings.create_wad == 'True':
        run_process(window, logger,["bin\\gzinject.exe", "-a","genkey"], b'45e') #generate common key
        run_process(window, logger,["bin\\gzinject.exe", "-a","inject", "--rom", os.path.join(output_dir, '%s-comp.z64' % outfilebase), "--wad", settings.wad, "-o",os.path.join(output_dir, '%s.wad' % outfilebase), "-i", "NBOE", "-t", "Better OOT", "--disable-cstick-d-remapping", "--disable-dpad-u-remapping", "--cleanup"], None)
        os.remove(os.path.join(output_dir, '%s-comp.z64' % outfilebase))

    window.update_progress(95)

    window.update_progress(100)
    if settings.create_wad == 'True':
        window.update_status('WAD patched successfully')
    else:
        window.update_status('ROM patched successfully')
    logger.info('ROM patched successfully')
    logger.debug('Total Time: %s', time.clock() - start)

    return worlds[settings.player_num - 1]
def main(args, seed=None):
    start = time.clock()

    # initialize the world
    world = World('vanilla', 'noglitches', 'standard', 'normal', 'none', 'on',
                  'ganon', 'freshness', False, False, False, args.quickswap,
                  args.fastmenu, False)
    logger = logging.getLogger('')

    hasher = hashlib.md5()
    with open(args.plando, 'rb') as plandofile:
        buf = plandofile.read()
        hasher.update(buf)
    world.seed = int(hasher.hexdigest(), 16) % 1000000000

    random.seed(world.seed)

    logger.info('ALttP Plandomizer Version %s  -  Seed: %s\n\n' %
                (__version__, args.plando))

    create_regions(world)
    create_dungeons(world)

    link_entrances(world)

    logger.info('Calculating Access Rules.')

    set_rules(world)

    logger.info('Fill the world.')

    text_patches = []

    fill_world(world, args.plando, text_patches)

    if world.get_entrance(
            'Dam').connected_region.name != 'Dam' or world.get_entrance(
                'Swamp Palace'
            ).connected_region.name != 'Swamp Palace (Entrance)':
        world.swamp_patch_required = True

    logger.info('Calculating playthrough.')

    try:
        create_playthrough(world)
    except RuntimeError:
        if args.ignore_unsolvable:
            pass
        else:
            raise

    logger.info('Patching ROM.')

    if args.sprite is not None:
        sprite = bytearray(open(args.sprite, 'rb').read())
    else:
        sprite = None

    rom = LocalRom(args.rom)
    patch_rom(world, rom, logic_hash, args.heartbeep, sprite)

    for textname, texttype, text in text_patches:
        if texttype == 'text':
            write_string_to_rom(rom, textname, text)
        elif texttype == 'credit':
            write_credits_string_to_rom(rom, textname, text)

    outfilebase = 'Plando_%s_%s' % (os.path.splitext(
        os.path.basename(args.plando))[0], world.seed)

    rom.write_to_file('%s.sfc' % outfilebase)
    if args.create_spoiler:
        world.spoiler.to_file('%s_Spoiler.txt' % outfilebase)

    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s' % (time.clock() - start))

    return world
예제 #12
0
def main(settings):
    start = time.clock()

    # initialize the world

    worlds = []

    if not settings.world_count:
        settings.world_count = 1
    if settings.world_count < 1:
        raise Exception('World Count must be at least 1')
    if settings.player_num > settings.world_count or settings.player_num < 1:
        raise Exception('Player Num must be between 1 and %d' %
                        settings.world_count)

    for i in range(0, settings.world_count):
        worlds.append(World(settings))

    logger = logging.getLogger('')

    random.seed(worlds[0].numeric_seed)

    logger.info('OoT Randomizer Version %s  -  Seed: %s\n\n', __version__,
                worlds[0].seed)

    for id, world in enumerate(worlds):
        world.id = id
        logger.info('Generating World %d.' % id)

        logger.info('Creating Overworld')
        create_regions(world)
        logger.info('Creating Dungeons')
        create_dungeons(world)
        logger.info('Linking Entrances')
        link_entrances(world)
        logger.info('Calculating Access Rules.')
        set_rules(world)
        logger.info('Generating Item Pool.')
        generate_itempool(world)

    logger.info('Fill the world.')
    distribute_items_restrictive(worlds)

    if settings.create_spoiler:
        logger.info('Calculating playthrough.')
        create_playthrough(worlds)
    CollectionState.update_required_items(worlds)

    logger.info('Patching ROM.')

    if settings.world_count > 1:
        outfilebase = 'OoT_%s_%s_W%dP%d' % (
            worlds[0].settings_string, worlds[0].seed, worlds[0].world_count,
            worlds[0].player_num)
    else:
        outfilebase = 'OoT_%s_%s' % (worlds[0].settings_string, worlds[0].seed)

    output_dir = default_output_path(settings.output_dir)

    if not settings.suppress_rom:
        rom = LocalRom(settings)
        patch_rom(worlds[settings.player_num - 1], rom)

        rom_path = os.path.join(output_dir, '%s.z64' % outfilebase)

        rom.write_to_file(rom_path)
        if settings.compress_rom:
            logger.info('Compressing ROM.')
            if platform.system() == 'Windows':
                subprocess.call([
                    "Compress\\Compress.exe", rom_path,
                    os.path.join(output_dir, '%s-comp.z64' % outfilebase)
                ])
            elif platform.system() == 'Linux':
                subprocess.call([
                    "Compress/Compress", rom_path,
                    os.path.join(output_dir, '%s-comp.z64' % outfilebase)
                ])
            elif platform.system() == 'Darwin':
                subprocess.call(
                    ["Compress/Compress.out", ('%s.z64' % outfilebase)])
            else:
                logger.info('OS not supported for compression')

    if settings.create_spoiler:
        worlds[settings.player_num - 1].spoiler.to_file(
            os.path.join(output_dir, '%s_Spoiler.txt' % outfilebase))
    os.remove('hints.txt')
    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.clock() - start)

    return worlds[settings.player_num - 1]
예제 #13
0
def main(args, seed=None):
    start = time.clock()

    # initialize the world
    world = World(args.shuffle, args.bridge, args.open_forest, not args.nodungeonitems, args.beatableonly)
    logger = logging.getLogger('')
    if seed is None:
        random.seed(None)
        world.seed = random.randint(0, 999999999)
    else:
        world.seed = int(seed)
    random.seed(world.seed)

    logger.info('ALttP Entrance Randomizer Version %s  -  Seed: %s\n\n', __version__, world.seed)

    create_regions(world)

    create_dungeons(world)

    logger.info('Shuffling the World about.')

    link_entrances(world)

    logger.info('Calculating Access Rules.')

    set_rules(world)

    logger.info('Generating Item Pool.')

    generate_itempool(world)

    logger.info('Placing Dungeon Items.')

    shuffled_locations = None
    shuffled_locations = world.get_unfilled_locations()
    random.shuffle(shuffled_locations)
    fill_dungeons_restrictive(world, shuffled_locations)

    logger.info('Fill the world.')

    distribute_items_restrictive(world)

    logger.info('Calculating playthrough.')

    create_playthrough(world)

    logger.info('Patching ROM.')

    outfilebase = 'OoT_%s_%s_%s' % (world.shuffle, world.bridge, world.seed)

    if not args.suppress_rom:
        rom = LocalRom(args.rom)
        patch_rom(world, rom)
        rom.write_to_file(output_path('%s.z64' % outfilebase))

    if args.create_spoiler:
        world.spoiler.to_file(output_path('%s_Spoiler.txt' % outfilebase))

    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.clock() - start)

    return world
예제 #14
0
def main(settings, window=dummy_window()):

    start = time.clock()

    logger = logging.getLogger('')

    # verify that the settings are valid
    if settings.free_scarecrow:
        verify_scarecrow_song_str(settings.scarecrow_song,
                                  settings.ocarina_songs)

    # initialize the world

    worlds = []
    if settings.compress_rom == 'None':
        settings.create_spoiler = True
        settings.update()

    if not settings.world_count:
        settings.world_count = 1
    if settings.world_count < 1:
        raise Exception('World Count must be at least 1')
    if settings.player_num > settings.world_count or settings.player_num < 1:
        raise Exception('Player Num must be between 1 and %d' %
                        settings.world_count)

    for i in range(0, settings.world_count):
        worlds.append(World(settings))

    random.seed(worlds[0].numeric_seed)

    logger.info('OoT Randomizer Version %s  -  Seed: %s\n\n', __version__,
                worlds[0].seed)

    window.update_status('Creating the Worlds')
    for id, world in enumerate(worlds):
        world.id = id
        logger.info('Generating World %d.' % id)

        window.update_progress(0 + (((id + 1) / settings.world_count) * 1))
        logger.info('Creating Overworld')
        if world.quest == 'master':
            for dungeon in world.dungeon_mq:
                world.dungeon_mq[dungeon] = True
        elif world.quest == 'mixed':
            for dungeon in world.dungeon_mq:
                world.dungeon_mq[dungeon] = random.choice([True, False])
        else:
            for dungeon in world.dungeon_mq:
                world.dungeon_mq[dungeon] = False
        create_regions(world)

        window.update_progress(0 + (((id + 1) / settings.world_count) * 2))
        logger.info('Creating Dungeons')
        create_dungeons(world)

        window.update_progress(0 + (((id + 1) / settings.world_count) * 3))
        logger.info('Linking Entrances')
        link_entrances(world)

        if settings.shopsanity != 'off':
            world.random_shop_prices()

        window.update_progress(0 + (((id + 1) / settings.world_count) * 4))
        logger.info('Calculating Access Rules.')
        set_rules(world)

        window.update_progress(0 + (((id + 1) / settings.world_count) * 5))
        logger.info('Generating Item Pool.')
        generate_itempool(world)

    window.update_status('Placing the Items')
    logger.info('Fill the world.')
    distribute_items_restrictive(window, worlds)
    window.update_progress(35)

    if settings.create_spoiler:
        window.update_status('Calculating Spoiler Data')
        logger.info('Calculating playthrough.')
        create_playthrough(worlds)
        window.update_progress(50)
    if settings.hints != 'none':
        window.update_status('Calculating Hint Data')
        CollectionState.update_required_items(worlds)
        buildGossipHints(worlds[settings.player_num - 1])
        window.update_progress(55)

    logger.info('Patching ROM.')

    if settings.world_count > 1:
        outfilebase = 'OoT_%s_%s_W%dP%d' % (
            worlds[0].settings_string, worlds[0].seed, worlds[0].world_count,
            worlds[0].player_num)
    else:
        outfilebase = 'OoT_%s_%s' % (worlds[0].settings_string, worlds[0].seed)

    output_dir = default_output_path(settings.output_dir)

    if settings.compress_rom != 'None':
        window.update_status('Patching ROM')
        rom = LocalRom(settings)
        patch_rom(worlds[settings.player_num - 1], rom)
        window.update_progress(65)

        rom_path = os.path.join(output_dir, '%s.z64' % outfilebase)

        window.update_status('Saving Uncompressed ROM')
        rom.write_to_file(rom_path)
        if settings.compress_rom == 'True':
            window.update_status('Compressing ROM')
            logger.info('Compressing ROM.')

            compressor_path = ""
            if platform.system() == 'Windows':
                if 8 * struct.calcsize("P") == 64:
                    compressor_path = "Compress\\Compress.exe"
                else:
                    compressor_path = "Compress\\Compress32.exe"
            elif platform.system() == 'Linux':
                compressor_path = "Compress/Compress"
            elif platform.system() == 'Darwin':
                compressor_path = "Compress/Compress.out"
            else:
                logger.info('OS not supported for compression')

            run_process(window, logger, [
                compressor_path, rom_path,
                os.path.join(output_dir, '%s-comp.z64' % outfilebase)
            ])
            os.remove(rom_path)
            window.update_progress(95)

    if settings.create_spoiler:
        window.update_status('Creating Spoiler Log')
        worlds[settings.player_num - 1].spoiler.to_file(
            os.path.join(output_dir, '%s_Spoiler.txt' % outfilebase))

    window.update_progress(100)
    window.update_status('Success: Rom patched successfully')
    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.clock() - start)

    return worlds[settings.player_num - 1]
예제 #15
0
def main(args):
    start_time = time.perf_counter()

    # initialize the world
    world = World(1, 'vanilla', 'noglitches', 'standard', 'normal', 'none',
                  'on', 'ganon', 'freshness', False, False, False, False,
                  False, False, None, False)
    world.player_names[1].append("Player1")
    logger = logging.getLogger('')

    hasher = hashlib.md5()
    with open(args.plando, 'rb') as plandofile:
        buf = plandofile.read()
        hasher.update(buf)
    world.seed = int(hasher.hexdigest(), 16) % 1000000000

    random.seed(world.seed)

    logger.info('ALttP Plandomizer Version %s  -  Seed: %s\n\n', __version__,
                args.plando)

    world.difficulty_requirements[1] = difficulties[world.difficulty[1]]

    create_regions(world, 1)
    create_dungeons(world, 1)

    link_entrances(world, 1)

    logger.info('Calculating Access Rules.')

    set_rules(world, 1)

    logger.info('Fill the world.')

    text_patches = []

    fill_world(world, args.plando, text_patches)

    if world.get_entrance(
            'Dam', 1).connected_region.name != 'Dam' or world.get_entrance(
                'Swamp Palace',
                1).connected_region.name != 'Swamp Palace (Entrance)':
        world.swamp_patch_required[1] = True

    logger.info('Calculating playthrough.')

    try:
        create_playthrough(world)
    except RuntimeError:
        if args.ignore_unsolvable:
            pass
        else:
            raise

    logger.info('Patching ROM.')

    rom = LocalRom(args.rom)
    patch_rom(world, rom, 1, 1, False)

    apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap,
                       args.fastmenu, args.disablemusic, args.sprite,
                       args.ow_palettes, args.uw_palettes)

    for textname, texttype, text in text_patches:
        if texttype == 'text':
            write_string_to_rom(rom, textname, text)
        #elif texttype == 'credit':
        #    write_credits_string_to_rom(rom, textname, text)

    outfilebase = 'Plando_%s_%s' % (os.path.splitext(
        os.path.basename(args.plando))[0], world.seed)

    rom.write_to_file('%s.sfc' % outfilebase)
    if args.create_spoiler:
        world.spoiler.to_file('%s_Spoiler.txt' % outfilebase)

    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.perf_counter() - start_time)

    return world
예제 #16
0
def cosmetic_patch(settings, window=dummy_window()):
    start = time.clock()
    logger = logging.getLogger('')

    # we load the rom before creating the seed so that error get caught early
    if settings.compress_rom == 'None':
        raise Exception(
            'An output type must be specified to produce anything.')

    window.update_status('Loading ROM')
    rom = LocalRom(settings)

    logger.info('OoT Randomizer Version %s', __version__)

    logger.info('Patching ROM.')

    outfilebase = 'OoT_cosmetics'
    output_dir = default_output_path(settings.output_dir)

    if settings.compress_rom == 'Patch':
        file_list = []
        window.update_progress(65)
        window.update_status('Patching ROM')
        patchfilename = '%s.zpf' % outfilebase

        patch_cosmetics(settings, rom)
        window.update_progress(65 + 20)

        window.update_status('Creating Patch File')
        output_path = os.path.join(output_dir, patchfilename)
        file_list.append(patchfilename)
        create_patch_file(rom, output_path)
        window.update_progress(95)

    elif settings.compress_rom != 'None':
        window.update_status('Patching ROM')
        cosmetics_log = patch_cosmetics(settings, rom)
        window.update_progress(65)

        window.update_status('Saving Uncompressed ROM')
        filename = '%s.z64' % outfilebase
        output_path = os.path.join(output_dir, filename)
        rom.write_to_file(output_path)
        if settings.compress_rom == 'True':
            window.update_status('Compressing ROM')
            logger.info('Compressing ROM.')

            if is_bundled():
                compressor_path = "."
            else:
                compressor_path = "Compress"

            if platform.system() == 'Windows':
                if 8 * struct.calcsize("P") == 64:
                    compressor_path += "\\Compress.exe"
                else:
                    compressor_path += "\\Compress32.exe"
            elif platform.system() == 'Linux':
                if platform.uname()[4] == 'aarch64' or platform.uname(
                )[4] == 'arm64':
                    compressor_path += "/Compress_ARM64"
                else:
                    compressor_path += "/Compress"
            elif platform.system() == 'Darwin':
                compressor_path += "/Compress.out"
            else:
                compressor_path = ""
                logger.info('OS not supported for compression')

            if compressor_path != "":
                run_process(window, logger, [
                    compressor_path, output_path,
                    output_path[:output_path.rfind('.')] + '-comp.z64'
                ])
            os.remove(output_path)
        window.update_progress(95)

    if settings.create_cosmetics_log and cosmetics_log:
        window.update_status('Creating Cosmetics Log')
        filename = '%s_Cosmetics.txt' % outfilebase
        cosmetics_log.to_file(os.path.join(output_dir, filename))

    window.update_progress(100)
    window.update_status('Success: Rom patched successfully')
    logger.info('Done. Enjoy.')
    logger.debug('Total Time: %s', time.clock() - start)