Skip to content

Commit

Permalink
Merge branch 'main' into sni_death_text
Browse files Browse the repository at this point in the history
  • Loading branch information
Silvris authored Aug 29, 2023
2 parents a7f431c + 30e747b commit 45368bb
Show file tree
Hide file tree
Showing 262 changed files with 23,405 additions and 8,598 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ jobs:
- name: Get a recent python
uses: actions/setup-python@v4
with:
python-version: '3.9'
python-version: '3.11'
- name: Install build-time dependencies
run: |
echo "PYTHON=python3.9" >> $GITHUB_ENV
echo "PYTHON=python3.11" >> $GITHUB_ENV
wget -nv https://github.com/AppImage/AppImageKit/releases/download/$APPIMAGETOOL_VERSION/appimagetool-x86_64.AppImage
chmod a+rx appimagetool-x86_64.AppImage
./appimagetool-x86_64.AppImage --appimage-extract
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ jobs:
- name: Get a recent python
uses: actions/setup-python@v4
with:
python-version: '3.9'
python-version: '3.11'
- name: Install build-time dependencies
run: |
echo "PYTHON=python3.9" >> $GITHUB_ENV
echo "PYTHON=python3.11" >> $GITHUB_ENV
wget -nv https://github.com/AppImage/AppImageKit/releases/download/$APPIMAGETOOL_VERSION/appimagetool-x86_64.AppImage
chmod a+rx appimagetool-x86_64.AppImage
./appimagetool-x86_64.AppImage --appimage-extract
Expand Down
17 changes: 4 additions & 13 deletions .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,31 @@ on:
jobs:
build:
runs-on: ${{ matrix.os }}
name: Test Python ${{ matrix.python.version }} ${{ matrix.os }} ${{ matrix.cython }}
name: Test Python ${{ matrix.python.version }} ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
cython:
- '' # default
python:
- {version: '3.8'}
- {version: '3.9'}
- {version: '3.10'}
- {version: '3.11'}
include:
- python: {version: '3.8'} # win7 compat
os: windows-latest
- python: {version: '3.10'} # current
- python: {version: '3.11'} # current
os: windows-latest
- python: {version: '3.10'} # current
- python: {version: '3.11'} # current
os: macos-latest
- python: {version: '3.10'} # current
os: ubuntu-latest
cython: beta

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python.version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python.version }}
- name: Install cython beta
if: ${{ matrix.cython == 'beta' }}
run: |
python -m pip install --upgrade pip
python -m pip install --pre --upgrade cython
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
6 changes: 4 additions & 2 deletions BaseClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,10 @@ def get_placeable_locations(self, state=None, player=None) -> List[Location]:
def get_unfilled_locations_for_players(self, location_names: List[str], players: Iterable[int]):
for player in players:
if not location_names:
location_names = [location.name for location in self.get_unfilled_locations(player)]
for location_name in location_names:
valid_locations = [location.name for location in self.get_unfilled_locations(player)]
else:
valid_locations = location_names
for location_name in valid_locations:
location = self._location_cache.get((location_name, player), None)
if location is not None and location.item is None:
yield location
Expand Down
2 changes: 1 addition & 1 deletion CommonClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ async def process_server_cmd(ctx: CommonContext, args: dict):

elif cmd == "SetReply":
ctx.stored_data[args["key"]] = args["value"]
if args["key"] == "EnergyLink":
if args["key"].startswith("EnergyLink"):
ctx.current_energy_link_value = args["value"]
if ctx.ui:
ctx.ui.set_new_energy_link_value()
Expand Down
7 changes: 5 additions & 2 deletions Fill.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ def fill_restrictive(world: MultiWorld, base_state: CollectionState, locations:
items_to_place = [items.pop()
for items in reachable_items.values() if items]
for item in items_to_place:
item_pool.remove(item)
for p, pool_item in enumerate(item_pool):
if pool_item is item:
item_pool.pop(p)
break
maximum_exploration_state = sweep_from_pool(
base_state, item_pool + unplaced_items)

Expand Down Expand Up @@ -152,8 +155,8 @@ def fill_restrictive(world: MultiWorld, base_state: CollectionState, locations:

if cleanup_required:
# validate all placements and remove invalid ones
state = sweep_from_pool(base_state, [])
for placement in placements:
state = sweep_from_pool(base_state, [])
if world.accessibility[placement.item.player] != "minimal" and not placement.can_reach(state):
placement.item.location = None
unplaced_items.append(placement.item)
Expand Down
12 changes: 6 additions & 6 deletions Generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ def main(args=None, callback=ERmain):
try:
weights_cache[args.weights_file_path] = read_weights_yamls(args.weights_file_path)
except Exception as e:
raise ValueError(f"File {args.weights_file_path} is destroyed. Please fix your yaml.") from e
raise ValueError(f"File {args.weights_file_path} is invalid. Please fix your yaml.") from e
logging.info(f"Weights: {args.weights_file_path} >> "
f"{get_choice('description', weights_cache[args.weights_file_path][-1], 'No description specified')}")

if args.meta_file_path and os.path.exists(args.meta_file_path):
try:
meta_weights = read_weights_yamls(args.meta_file_path)[-1]
except Exception as e:
raise ValueError(f"File {args.meta_file_path} is destroyed. Please fix your yaml.") from e
raise ValueError(f"File {args.meta_file_path} is invalid. Please fix your yaml.") from e
logging.info(f"Meta: {args.meta_file_path} >> {get_choice('meta_description', meta_weights)}")
try: # meta description allows us to verify that the file named meta.yaml is intentionally a meta file
del(meta_weights["meta_description"])
Expand All @@ -114,7 +114,7 @@ def main(args=None, callback=ERmain):
try:
weights_cache[fname] = read_weights_yamls(path)
except Exception as e:
raise ValueError(f"File {fname} is destroyed. Please fix your yaml.") from e
raise ValueError(f"File {fname} is invalid. Please fix your yaml.") from e

# sort dict for consistent results across platforms:
weights_cache = {key: value for key, value in sorted(weights_cache.items())}
Expand Down Expand Up @@ -195,7 +195,7 @@ def main(args=None, callback=ERmain):

player += 1
except Exception as e:
raise ValueError(f"File {path} is destroyed. Please fix your yaml.") from e
raise ValueError(f"File {path} is invalid. Please fix your yaml.") from e
else:
raise RuntimeError(f'No weights specified for player {player}')

Expand Down Expand Up @@ -374,7 +374,7 @@ def roll_linked_options(weights: dict) -> dict:
else:
logging.debug(f"linked option {option_set['name']} skipped.")
except Exception as e:
raise ValueError(f"Linked option {option_set['name']} is destroyed. "
raise ValueError(f"Linked option {option_set['name']} is invalid. "
f"Please fix your linked option.") from e
return weights

Expand Down Expand Up @@ -404,7 +404,7 @@ def roll_triggers(weights: dict, triggers: list) -> dict:
update_weights(currently_targeted_weights, category_options, "Triggered", option_set["option_name"])

except Exception as e:
raise ValueError(f"Your trigger number {i + 1} is destroyed. "
raise ValueError(f"Your trigger number {i + 1} is invalid. "
f"Please fix your triggers.") from e
return weights

Expand Down
3 changes: 2 additions & 1 deletion LinksAwakeningClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,13 @@ async def wait_for_retroarch_connection(self):
f"Core type should be '{GAME_BOY}', found {core_type} instead - wrong type of ROM?")
await asyncio.sleep(1.0)
continue
self.stop_bizhawk_spam = False
logger.info(f"Connected to Retroarch {version.decode('ascii')} running {rom_name.decode('ascii')}")
return
except (BlockingIOError, TimeoutError, ConnectionResetError):
await asyncio.sleep(1.0)
pass
self.stop_bizhawk_spam = False

async def reset_auth(self):
auth = binascii.hexlify(await self.gameboy.async_read_memory(0x0134, 12)).decode()
self.auth = auth
Expand Down
83 changes: 50 additions & 33 deletions LttPAdjuster.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

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, \
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"
Expand All @@ -43,6 +43,47 @@ class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter):
def _get_help_string(self, action):
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:
parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
Expand All @@ -52,6 +93,8 @@ def get_argparser() -> argparse.ArgumentParser:
help='Path to an ALttP Japan(1.0) rom to use as a base.')
parser.add_argument('--loglevel', default='info', const='info', nargs='?',
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='?',
choices=['normal', 'instant', 'double', 'triple', 'quadruple', 'half'],
help='''\
Expand All @@ -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('--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('--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='?',
choices=['normal', 'hide_goal', 'hide_required', 'hide_both'],
help='''\
Expand Down Expand Up @@ -104,21 +147,23 @@ def get_argparser() -> argparse.ArgumentParser:
Alternatively, can be a ALttP Rom patched with a Link
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='''\
Path to a sound effect to replace Link's "oof" sound.
Needs to be in a .brr format and have a length of no
more than 2673 bytes, created from a 16-bit signed PCM
.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.')
return parser


def main():
parser = get_argparser()
args = parser.parse_args()
args.music = not args.disablemusic
args = parser.parse_args(namespace=get_adjuster_settings_no_defaults(GAME_ALTTP))

# set up logger
loglevel = {'error': logging.ERROR, 'info': logging.INFO, 'warning': logging.WARNING, 'debug': logging.DEBUG}[
args.loglevel]
Expand Down Expand Up @@ -530,9 +575,6 @@ def hide(self):

def get_rom_frame(parent=None):
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)
baseRomLabel = Label(romFrame, text='LttP Base Rom: ')
Expand Down Expand Up @@ -560,33 +602,8 @@ def RomSelect():

return romFrame, romVar


def get_rom_options_frame(parent=None):
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.columnconfigure(0, weight=1)
Expand Down
16 changes: 10 additions & 6 deletions MMBN3Client.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def __init__(self, server_address, password):
self.auth_name = None
self.slot_data = dict()
self.patching_error = False
self.sent_hints = []

async def server_auth(self, password_requested: bool = False):
if password_requested and not self.password:
Expand Down Expand Up @@ -175,13 +176,16 @@ async def parse_payload(payload: dict, ctx: MMBN3Context, force: bool):

# If trade hinting is enabled, send scout checks
if ctx.slot_data.get("trade_quest_hinting", 0) == 2:
scouted_locs = [loc.id for loc in scoutable_locations
trade_bits = [loc.id for loc in scoutable_locations
if check_location_scouted(loc, payload["locations"])]
await ctx.send_msgs([{
"cmd": "LocationScouts",
"locations": scouted_locs,
"create_as_hint": 2
}])
scouted_locs = [loc for loc in trade_bits if loc not in ctx.sent_hints]
if len(scouted_locs) > 0:
ctx.sent_hints.extend(scouted_locs)
await ctx.send_msgs([{
"cmd": "LocationScouts",
"locations": scouted_locs,
"create_as_hint": 2
}])


def check_location_packet(location, memory):
Expand Down
13 changes: 7 additions & 6 deletions Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,6 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
world.non_local_items[player].value -= world.local_items[player].value
world.non_local_items[player].value -= set(world.local_early_items[player])

if world.players > 1:
locality_rules(world)
else:
world.non_local_items[1].value = set()
world.local_items[1].value = set()

AutoWorld.call_all(world, "set_rules")

for player in world.player_ids:
Expand All @@ -147,6 +141,13 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
for location_name in world.priority_locations[player].value:
world.get_location(location_name, player).progress_type = LocationProgressType.PRIORITY

# Set local and non-local item rules.
if world.players > 1:
locality_rules(world)
else:
world.non_local_items[1].value = set()
world.local_items[1].value = set()

AutoWorld.call_all(world, "generate_basic")

# remove starting inventory from pool items.
Expand Down
Loading

0 comments on commit 45368bb

Please sign in to comment.