LttP: Fixes patching on a fresh AP install (#2118)

This commit is contained in:
zig-for 2023-08-25 13:25:02 -07:00 committed by GitHub
parent b235ba2c52
commit 41a34b140c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 59 deletions

View File

@ -25,7 +25,7 @@ ModuleUpdate.update()
from worlds.alttp.Rom import Sprite, LocalRom, apply_rom_settings, get_base_rom_bytes from worlds.alttp.Rom import Sprite, LocalRom, apply_rom_settings, get_base_rom_bytes
from Utils import output_path, local_path, user_path, open_file, get_cert_none_ssl_context, persistent_store, \ from Utils import output_path, local_path, user_path, open_file, get_cert_none_ssl_context, persistent_store, \
get_adjuster_settings, tkinter_center_window, init_logging get_adjuster_settings, get_adjuster_settings_no_defaults, tkinter_center_window, init_logging
GAME_ALTTP = "A Link to the Past" GAME_ALTTP = "A Link to the Past"
@ -43,6 +43,47 @@ class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
def _get_help_string(self, action): def _get_help_string(self, action):
return textwrap.dedent(action.help) return textwrap.dedent(action.help)
# See argparse.BooleanOptionalAction
class BooleanOptionalActionWithDisable(argparse.Action):
def __init__(self,
option_strings,
dest,
default=None,
type=None,
choices=None,
required=False,
help=None,
metavar=None):
_option_strings = []
for option_string in option_strings:
_option_strings.append(option_string)
if option_string.startswith('--'):
option_string = '--disable' + option_string[2:]
_option_strings.append(option_string)
if help is not None and default is not None:
help += " (default: %(default)s)"
super().__init__(
option_strings=_option_strings,
dest=dest,
nargs=0,
default=default,
type=type,
choices=choices,
required=required,
help=help,
metavar=metavar)
def __call__(self, parser, namespace, values, option_string=None):
if option_string in self.option_strings:
setattr(namespace, self.dest, not option_string.startswith('--disable'))
def format_usage(self):
return ' | '.join(self.option_strings)
def get_argparser() -> argparse.ArgumentParser: def get_argparser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
@ -52,6 +93,8 @@ def get_argparser() -> argparse.ArgumentParser:
help='Path to an ALttP Japan(1.0) rom to use as a base.') help='Path to an ALttP Japan(1.0) rom to use as a base.')
parser.add_argument('--loglevel', default='info', const='info', nargs='?', parser.add_argument('--loglevel', default='info', const='info', nargs='?',
choices=['error', 'info', 'warning', 'debug'], help='Select level of logging for output.') choices=['error', 'info', 'warning', 'debug'], help='Select level of logging for output.')
parser.add_argument('--auto_apply', default='ask',
choices=['ask', 'always', 'never'], help='Whether or not to apply settings automatically in the future.')
parser.add_argument('--menuspeed', default='normal', const='normal', nargs='?', parser.add_argument('--menuspeed', default='normal', const='normal', nargs='?',
choices=['normal', 'instant', 'double', 'triple', 'quadruple', 'half'], choices=['normal', 'instant', 'double', 'triple', 'quadruple', 'half'],
help='''\ help='''\
@ -61,7 +104,7 @@ def get_argparser() -> argparse.ArgumentParser:
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('--deathlink', help='Enable DeathLink system.', action='store_true') parser.add_argument('--deathlink', help='Enable DeathLink system.', action='store_true')
parser.add_argument('--allowcollect', help='Allow collection of other player items', action='store_true') parser.add_argument('--allowcollect', help='Allow collection of other player items', action='store_true')
parser.add_argument('--disablemusic', help='Disables game music.', action='store_true') parser.add_argument('--music', default=True, help='Enables/Disables game music.', action=BooleanOptionalActionWithDisable)
parser.add_argument('--triforcehud', default='hide_goal', const='hide_goal', nargs='?', parser.add_argument('--triforcehud', default='hide_goal', const='hide_goal', nargs='?',
choices=['normal', 'hide_goal', 'hide_required', 'hide_both'], choices=['normal', 'hide_goal', 'hide_required', 'hide_both'],
help='''\ help='''\
@ -104,21 +147,23 @@ def get_argparser() -> argparse.ArgumentParser:
Alternatively, can be a ALttP Rom patched with a Link Alternatively, can be a ALttP Rom patched with a Link
sprite that will be extracted. sprite that will be extracted.
''') ''')
parser.add_argument('--sprite_pool', nargs='+', default=[], help='''
A list of sprites to pull from.
''')
parser.add_argument('--oof', help='''\ parser.add_argument('--oof', help='''\
Path to a sound effect to replace Link's "oof" sound. Path to a sound effect to replace Link's "oof" sound.
Needs to be in a .brr format and have a length of no Needs to be in a .brr format and have a length of no
more than 2673 bytes, created from a 16-bit signed PCM more than 2673 bytes, created from a 16-bit signed PCM
.wav at 12khz. https://github.com/boldowa/snesbrr .wav at 12khz. https://github.com/boldowa/snesbrr
''') ''')
parser.add_argument('--names', default='', type=str)
parser.add_argument('--update_sprites', action='store_true', help='Update Sprite Database, then exit.') parser.add_argument('--update_sprites', action='store_true', help='Update Sprite Database, then exit.')
return parser return parser
def main(): def main():
parser = get_argparser() parser = get_argparser()
args = parser.parse_args() args = parser.parse_args(namespace=get_adjuster_settings_no_defaults(GAME_ALTTP))
args.music = not args.disablemusic
# set up logger # set up logger
loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[ loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[
args.loglevel] args.loglevel]
@ -530,9 +575,6 @@ class AttachTooltip(object):
def get_rom_frame(parent=None): def get_rom_frame(parent=None):
adjuster_settings = get_adjuster_settings(GAME_ALTTP) adjuster_settings = get_adjuster_settings(GAME_ALTTP)
if not adjuster_settings:
adjuster_settings = Namespace()
adjuster_settings.baserom = "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc"
romFrame = Frame(parent) romFrame = Frame(parent)
baseRomLabel = Label(romFrame, text='LttP Base Rom: ') baseRomLabel = Label(romFrame, text='LttP Base Rom: ')
@ -560,33 +602,8 @@ def get_rom_frame(parent=None):
return romFrame, romVar return romFrame, romVar
def get_rom_options_frame(parent=None): def get_rom_options_frame(parent=None):
adjuster_settings = get_adjuster_settings(GAME_ALTTP) adjuster_settings = get_adjuster_settings(GAME_ALTTP)
defaults = {
"auto_apply": 'ask',
"music": True,
"reduceflashing": True,
"deathlink": False,
"sprite": None,
"oof": None,
"quickswap": True,
"menuspeed": 'normal',
"heartcolor": 'red',
"heartbeep": 'normal',
"ow_palettes": 'default',
"uw_palettes": 'default',
"hud_palettes": 'default',
"sword_palettes": 'default',
"shield_palettes": 'default',
"sprite_pool": [],
"allowcollect": False,
}
if not adjuster_settings:
adjuster_settings = Namespace()
for key, defaultvalue in defaults.items():
if not hasattr(adjuster_settings, key):
setattr(adjuster_settings, key, defaultvalue)
romOptionsFrame = LabelFrame(parent, text="Rom options") romOptionsFrame = LabelFrame(parent, text="Rom options")
romOptionsFrame.columnconfigure(0, weight=1) romOptionsFrame.columnconfigure(0, weight=1)

View File

@ -14,6 +14,7 @@ import collections
import importlib import importlib
import logging import logging
from argparse import Namespace
from settings import Settings, get_settings from settings import Settings, get_settings
from typing import BinaryIO, Coroutine, Optional, Set, Dict, Any, Union from typing import BinaryIO, Coroutine, Optional, Set, Dict, Any, Union
from yaml import load, load_all, dump, SafeLoader from yaml import load, load_all, dump, SafeLoader
@ -318,12 +319,27 @@ def store_data_package_for_checksum(game: str, data: typing.Dict[str, Any]) -> N
except Exception as e: except Exception as e:
logging.debug(f"Could not store data package: {e}") logging.debug(f"Could not store data package: {e}")
def get_default_adjuster_settings(game_name: str) -> Namespace:
import LttPAdjuster
adjuster_settings = Namespace()
if game_name == LttPAdjuster.GAME_ALTTP:
return LttPAdjuster.get_argparser().parse_known_args(args=[])[0]
def get_adjuster_settings(game_name: str) -> typing.Dict[str, typing.Any]:
adjuster_settings = persistent_load().get("adjuster", {}).get(game_name, {})
return adjuster_settings return adjuster_settings
def get_adjuster_settings_no_defaults(game_name: str) -> Namespace:
return persistent_load().get("adjuster", {}).get(game_name, Namespace())
def get_adjuster_settings(game_name: str) -> Namespace:
adjuster_settings = get_adjuster_settings_no_defaults(game_name)
default_settings = get_default_adjuster_settings(game_name)
# Fill in any arguments from the argparser that we haven't seen before
return Namespace(**vars(adjuster_settings), **{k:v for k,v in vars(default_settings).items() if k not in vars(adjuster_settings)})
@cache_argsless @cache_argsless
def get_unique_identifier(): def get_unique_identifier():
uuid = persistent_load().get("client", {}).get("uuid", None) uuid = persistent_load().get("client", {}).get("uuid", None)

View File

@ -581,31 +581,25 @@ class ALTTPSNIClient(SNIClient):
def get_alttp_settings(romfile: str): def get_alttp_settings(romfile: str):
import LttPAdjuster import LttPAdjuster
last_settings = Utils.get_adjuster_settings(GAME_ALTTP)
base_settings = LttPAdjuster.get_argparser().parse_known_args(args=[])[0]
allow_list = {"music", "menuspeed", "heartbeep", "heartcolor", "ow_palettes", "quickswap",
"uw_palettes", "sprite", "sword_palettes", "shield_palettes", "hud_palettes",
"reduceflashing", "deathlink", "allowcollect", "oof"}
for option_name in allow_list:
# set new defaults since last_settings were created
if not hasattr(last_settings, option_name):
setattr(last_settings, option_name, getattr(base_settings, option_name))
adjustedromfile = '' adjustedromfile = ''
if last_settings: if vars(Utils.get_adjuster_settings_no_defaults(GAME_ALTTP)):
last_settings = Utils.get_adjuster_settings(GAME_ALTTP)
allow_list = {"music", "menuspeed", "heartbeep", "heartcolor", "ow_palettes", "quickswap",
"uw_palettes", "sprite", "sword_palettes", "shield_palettes", "hud_palettes",
"reduceflashing", "deathlink", "allowcollect", "oof"}
choice = 'no' choice = 'no'
if not hasattr(last_settings, 'auto_apply') or 'ask' in last_settings.auto_apply: if 'ask' in last_settings.auto_apply:
printed_options = {name: value for name, value in vars(last_settings).items() if name in allow_list} printed_options = {name: value for name, value in vars(last_settings).items() if name in allow_list}
if hasattr(last_settings, "sprite_pool"):
sprite_pool = {} sprite_pool = {}
for sprite in last_settings.sprite_pool: for sprite in last_settings.sprite_pool:
if sprite in sprite_pool: if sprite in sprite_pool:
sprite_pool[sprite] += 1 sprite_pool[sprite] += 1
else: else:
sprite_pool[sprite] = 1 sprite_pool[sprite] = 1
if sprite_pool: if sprite_pool:
printed_options["sprite_pool"] = sprite_pool printed_options["sprite_pool"] = sprite_pool
import pprint import pprint
from CommonClient import gui_enabled from CommonClient import gui_enabled
@ -685,17 +679,17 @@ def get_alttp_settings(romfile: str):
choice = 'yes' choice = 'yes'
if 'yes' in choice: if 'yes' in choice:
import LttPAdjuster
from worlds.alttp.Rom import get_base_rom_path from worlds.alttp.Rom import get_base_rom_path
last_settings.rom = romfile last_settings.rom = romfile
last_settings.baserom = get_base_rom_path() last_settings.baserom = get_base_rom_path()
last_settings.world = None last_settings.world = None
if hasattr(last_settings, "sprite_pool"): if last_settings.sprite_pool:
from LttPAdjuster import AdjusterWorld from LttPAdjuster import AdjusterWorld
last_settings.world = AdjusterWorld(getattr(last_settings, "sprite_pool")) last_settings.world = AdjusterWorld(getattr(last_settings, "sprite_pool"))
adjusted = True adjusted = True
import LttPAdjuster
_, adjustedromfile = LttPAdjuster.adjust(last_settings) _, adjustedromfile = LttPAdjuster.adjust(last_settings)
if hasattr(last_settings, "world"): if hasattr(last_settings, "world"):