From e57e92bfee2d528a4e44ab7c4af5055814ff7fba Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 12 Sep 2021 21:15:03 +0200 Subject: [PATCH 1/4] CommonClient: reduce blind sleep time of keep_alive --- CommonClient.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/CommonClient.py b/CommonClient.py index b8438bdb..456311fa 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -224,13 +224,17 @@ class CommonContext(): pass -async def keep_alive(ctx: CommonContext): - """ some ISPs/network configurations drop TCP connections if no payload is sent (ignore TCP-keep-alive) - so we send a payload to prevent drop and if we were dropped anyway this will cause a reconnect.""" +async def keep_alive(ctx: CommonContext, seconds_between_checks=100): + """some ISPs/network configurations drop TCP connections if no payload is sent (ignore TCP-keep-alive) + so we send a payload to prevent drop and if we were dropped anyway this will cause an auto-reconnect.""" + seconds_elapsed = 0 while not ctx.exit_event.is_set(): - await asyncio.sleep(100) + await asyncio.sleep(1) # short sleep to not block program shutdown if ctx.server and ctx.slot: - await ctx.send_msgs([{"cmd": "Bounce", "slots": [ctx.slot]}]) + seconds_elapsed += 1 + if seconds_elapsed > seconds_between_checks: + await ctx.send_msgs([{"cmd": "Bounce", "slots": [ctx.slot]}]) + seconds_elapsed = 0 async def server_loop(ctx: CommonContext, address=None): From 033adceb6f554c157e63fd322125e6d153d20804 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 13 Sep 2021 01:32:32 +0200 Subject: [PATCH 2/4] LttP: move some simple Toggle options over to new system --- BaseClasses.py | 18 +-------- Generate.py | 18 +-------- Main.py | 12 +----- WebHostLib/generate.py | 3 +- worlds/alttp/EntranceRandomizer.py | 39 ++++--------------- worlds/alttp/Options.py | 60 ++++++++++++++++++++++++++++++ worlds/alttp/Rom.py | 2 +- worlds/alttp/__init__.py | 2 +- 8 files changed, 74 insertions(+), 80 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index ba14dcda..2532aaf8 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -77,7 +77,6 @@ class MultiWorld(): set_player_attr('shuffle', "vanilla") set_player_attr('logic', "noglitches") set_player_attr('mode', 'open') - set_player_attr('swordless', False) set_player_attr('difficulty', 'normal') set_player_attr('item_functionality', 'normal') set_player_attr('timer', False) @@ -1127,7 +1126,7 @@ class Spoiler(): 'tile_shuffle': self.world.tile_shuffle, 'bush_shuffle': self.world.bush_shuffle, 'beemizer': self.world.beemizer, - 'shufflepots': self.world.shufflepots, + 'pot_shuffle': self.world.pot_shuffle, 'players': self.world.players, 'progression_balancing': self.world.progression_balancing, 'triforce_pieces_available': self.world.triforce_pieces_available, @@ -1193,13 +1192,7 @@ class Spoiler(): outfile.write('Logic: %s\n' % self.metadata['logic'][player]) outfile.write('Dark Room Logic: %s\n' % self.metadata['dark_room_logic'][player]) - outfile.write('Restricted Boss Drops: %s\n' % - bool_to_text(self.metadata['restrict_dungeon_item_on_boss'][player])) - outfile.write('Mode: %s\n' % self.metadata['mode'][player]) - outfile.write('Retro: %s\n' % - ('Yes' if self.metadata['retro'][player] else 'No')) - outfile.write('Swordless: %s\n' % ('Yes' if self.metadata['swordless'][player] else 'No')) outfile.write('Goal: %s\n' % self.metadata['goal'][player]) if "triforce" in self.metadata["goal"][player]: # triforce hunt outfile.write("Pieces available for Triforce: %s\n" % @@ -1225,18 +1218,9 @@ class Spoiler(): outfile.write('Custom Potion Shop: %s\n' % bool_to_text("w" in self.metadata["shop_shuffle"][player])) outfile.write('Boss shuffle: %s\n' % self.metadata['boss_shuffle'][player]) - outfile.write( - 'Enemy shuffle: %s\n' % bool_to_text(self.metadata['enemy_shuffle'][player])) outfile.write('Enemy health: %s\n' % self.metadata['enemy_health'][player]) outfile.write('Enemy damage: %s\n' % self.metadata['enemy_damage'][player]) - outfile.write(f'Killable thieves: {bool_to_text(self.metadata["killable_thieves"][player])}\n') - outfile.write(f'Shuffled tiles: {bool_to_text(self.metadata["tile_shuffle"][player])}\n') - outfile.write(f'Shuffled bushes: {bool_to_text(self.metadata["bush_shuffle"][player])}\n') - outfile.write( - 'Hints: %s\n' % ('Yes' if self.metadata['hints'][player] else 'No')) outfile.write('Beemizer: %s\n' % self.metadata['beemizer'][player]) - outfile.write('Pot shuffle %s\n' - % ('Yes' if self.metadata['shufflepots'][player] else 'No')) outfile.write('Prize shuffle %s\n' % self.metadata['shuffle_prizes'][player]) if self.entrances: diff --git a/Generate.py b/Generate.py index 7980d299..8e44968d 100644 --- a/Generate.py +++ b/Generate.py @@ -121,10 +121,9 @@ def main(args=None, callback=ERmain): f"A mix is also permitted.") erargs = parse_arguments(['--multi', str(args.multi)]) erargs.seed = seed - erargs.create_spoiler = args.spoiler > 0 erargs.glitch_triforce = options["generator"]["glitch_triforce_room"] + erargs.spoiler = args.spoiler erargs.race = args.race - erargs.skip_playthrough = args.spoiler < 2 erargs.outputname = seed_name erargs.outputpath = args.outputpath @@ -587,8 +586,6 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options): if ret.dark_room_logic not in {"lamp", "torches", "none"}: raise ValueError(f"Unknown Dark Room Logic: \"{ret.dark_room_logic}\"") - ret.restrict_dungeon_item_on_boss = get_choice_legacy('restrict_dungeon_item_on_boss', weights, False) - entrance_shuffle = get_choice_legacy('entrance_shuffle', weights, 'vanilla') if entrance_shuffle.startswith('none-'): ret.shuffle = 'vanilla' @@ -628,11 +625,6 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options): ret.shop_shuffle = '' ret.mode = get_choice_legacy("mode", weights) - ret.retro = get_choice_legacy("retro", weights) - - ret.hints = get_choice_legacy('hints', weights) - - ret.swordless = get_choice_legacy('swordless', weights, False) ret.difficulty = get_choice_legacy('item_pool', weights) @@ -641,12 +633,6 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options): boss_shuffle = get_choice_legacy('boss_shuffle', weights) ret.shufflebosses = get_plando_bosses(boss_shuffle, plando_options) - ret.enemy_shuffle = bool(get_choice_legacy('enemy_shuffle', weights, False)) - - ret.killable_thieves = get_choice_legacy('killable_thieves', weights, False) - ret.tile_shuffle = get_choice_legacy('tile_shuffle', weights, False) - ret.bush_shuffle = get_choice_legacy('bush_shuffle', weights, False) - ret.enemy_damage = {None: 'default', 'default': 'default', 'shuffled': 'shuffled', @@ -656,8 +642,6 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options): ret.enemy_health = get_choice_legacy('enemy_health', weights) - ret.shufflepots = get_choice_legacy('pot_shuffle', weights) - ret.beemizer = int(get_choice_legacy('beemizer', weights, 0)) ret.timer = {'none': False, diff --git a/Main.py b/Main.py index 3c3a2ad4..aeddad8f 100644 --- a/Main.py +++ b/Main.py @@ -63,24 +63,17 @@ def main(args, seed=None): world.customitemarray = args.customitemarray world.accessibility = args.accessibility.copy() - world.retro = args.retro.copy() - - world.hints = args.hints.copy() world.open_pyramid = args.open_pyramid.copy() world.boss_shuffle = args.shufflebosses.copy() world.enemy_shuffle = args.enemy_shuffle.copy() world.enemy_health = args.enemy_health.copy() world.enemy_damage = args.enemy_damage.copy() - world.killable_thieves = args.killable_thieves.copy() - world.bush_shuffle = args.bush_shuffle.copy() - world.tile_shuffle = args.tile_shuffle.copy() world.beemizer = args.beemizer.copy() world.timer = args.timer.copy() world.countdown_start_time = args.countdown_start_time.copy() world.red_clock_time = args.red_clock_time.copy() world.blue_clock_time = args.blue_clock_time.copy() world.green_clock_time = args.green_clock_time.copy() - world.shufflepots = args.shufflepots.copy() world.dungeon_counters = args.dungeon_counters.copy() world.triforce_pieces_available = args.triforce_pieces_available.copy() world.triforce_pieces_required = args.triforce_pieces_required.copy() @@ -93,7 +86,6 @@ def main(args, seed=None): world.plando_texts = args.plando_texts.copy() world.plando_connections = args.plando_connections.copy() world.er_seeds = getattr(args, "er_seeds", {}) - world.restrict_dungeon_item_on_boss = args.restrict_dungeon_item_on_boss.copy() world.required_medallions = args.required_medallions.copy() world.game = args.game.copy() world.set_options(args) @@ -346,11 +338,11 @@ def main(args, seed=None): logger.info(f'Generating output files ({i}/{len(output_file_futures)}).') future.result() - if not args.skip_playthrough: + if args.spoiler > 1: logger.info('Calculating playthrough.') create_playthrough(world) - if args.create_spoiler: + if args.spoiler: world.spoiler.to_file(os.path.join(temp_dir, '%s_Spoiler.txt' % outfilebase)) zipfilename = output_path(f"AP_{world.seed_name}.zip") diff --git a/WebHostLib/generate.py b/WebHostLib/generate.py index 99af0d39..bfb711d0 100644 --- a/WebHostLib/generate.py +++ b/WebHostLib/generate.py @@ -74,9 +74,8 @@ def gen_game(gen_options, race=False, owner=None, sid=None): erargs = parse_arguments(['--multi', str(playercount)]) erargs.seed = seed erargs.name = {x: "" for x in range(1, playercount + 1)} # only so it can be overwrittin in mystery - erargs.create_spoiler = not race + erargs.spoiler = 0 if race else 2 erargs.race = race - erargs.skip_playthrough = race erargs.outputname = seedname erargs.outputpath = target.name erargs.teams = 1 diff --git a/worlds/alttp/EntranceRandomizer.py b/worlds/alttp/EntranceRandomizer.py index 5bd01299..02efe463 100644 --- a/worlds/alttp/EntranceRandomizer.py +++ b/worlds/alttp/EntranceRandomizer.py @@ -20,7 +20,6 @@ def parse_arguments(argv, no_defaults=False): multiargs, _ = parser.parse_known_args(argv) parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) - parser.add_argument('--create_spoiler', help='Output a Spoiler File', action='store_true') parser.add_argument('--logic', default=defval('noglitches'), const='noglitches', nargs='?', choices=['noglitches', 'minorglitches', 'owglitches', 'hybridglitches', 'nologic'], help='''\ Select Enforcement of Item Requirements. (default: %(default)s) @@ -46,17 +45,6 @@ def parse_arguments(argv, no_defaults=False): Requires the moon pearl to be Link in the Light World instead of a bunny. ''') - parser.add_argument('--swordless', action='store_true', - help='''\ - Toggles Swordless Mode - Swordless: No swords. Curtains in Skull Woods and Agahnim\'s - Tower are removed, Agahnim\'s Tower barrier can be - destroyed with hammer. Misery Mire and Turtle Rock - can be opened without a sword. Hammer damages Ganon. - Ether and Bombos Tablet can be activated with Hammer - (and Book). Bombos pads have been added in Ice - Palace, to allow for an alternative to firerod. - ''') parser.add_argument('--goal', default=defval('ganon'), const='ganon', nargs='?', choices=['ganon', 'pedestal', 'bosses', 'triforcehunt', 'localtriforcehunt', 'ganontriforcehunt', 'localganontriforcehunt', 'crystals', 'ganonpedestal'], help='''\ @@ -206,10 +194,6 @@ def parse_arguments(argv, no_defaults=False): time). ''', type=int) - parser.add_argument('--retro', default=defval(False), help='''\ - Keys are universal, shooting arrows costs rupees, - and a few other little things make this more like Zelda-1. - ''', action='store_true') parser.add_argument('--local_items', default=defval(''), help='Specifies a list of items that will not spread across the multiworld (separated by commas)') parser.add_argument('--non_local_items', default=defval(''), @@ -223,9 +207,6 @@ def parse_arguments(argv, no_defaults=False): Locations: You will be able to reach every location in the game. None: You will be able to reach enough locations to beat the game. ''') - parser.add_argument('--hints', default=defval(False), help='''\ - Make telepathic tiles and storytellers give helpful hints. - ''', action='store_true') # included for backwards compatibility parser.add_argument('--shuffleganon', help=argparse.SUPPRESS, action='store_true', default=defval(True)) parser.add_argument('--no-shuffleganon', help='''\ @@ -243,18 +224,13 @@ def parse_arguments(argv, no_defaults=False): parser.add_argument('--gui', help='Launch the GUI', action='store_true') parser.add_argument('--progression_balancing', action='store_true', default=defval(False), help="Enable Multiworld Progression balancing.") - parser.add_argument('--skip_playthrough', action='store_true', default=defval(False)) parser.add_argument('--enemizercli', default=defval('EnemizerCLI/EnemizerCLI.Core')) parser.add_argument('--shufflebosses', default=defval('none'), choices=['none', 'basic', 'normal', 'chaos', "singularity"]) - parser.add_argument('--enemy_shuffle', action='store_true') - parser.add_argument('--killable_thieves', action='store_true') - parser.add_argument('--tile_shuffle', action='store_true') - parser.add_argument('--bush_shuffle', action='store_true') + parser.add_argument('--enemy_health', default=defval('default'), choices=['default', 'easy', 'normal', 'hard', 'expert']) parser.add_argument('--enemy_damage', default=defval('default'), choices=['default', 'shuffled', 'chaos']) - parser.add_argument('--shufflepots', default=defval(False), action='store_true') parser.add_argument('--beemizer', default=defval(0), type=lambda value: min(max(int(value), 0), 4)) parser.add_argument('--shop_shuffle', default='', help='''\ combine letters for options: @@ -272,7 +248,6 @@ def parse_arguments(argv, no_defaults=False): For unlit dark rooms, require the Lamp to be considered in logic by default. Torches means additionally easily accessible Torches that can be lit with Fire Rod are considered doable. None means full traversal through dark rooms without tools is considered doable.''') - parser.add_argument('--restrict_dungeon_item_on_boss', default=defval(False), action="store_true") parser.add_argument('--multi', default=defval(1), type=lambda value: min(max(int(value), 1), 255)) parser.add_argument('--names', default=defval('')) parser.add_argument('--outputpath') @@ -307,19 +282,19 @@ def parse_arguments(argv, no_defaults=False): for player in range(1, multiargs.multi + 1): playerargs = parse_arguments(shlex.split(getattr(ret, f"p{player}")), True) - for name in ['logic', 'mode', 'swordless', 'goal', 'difficulty', 'item_functionality', + for name in ['logic', 'mode', 'goal', 'difficulty', 'item_functionality', 'shuffle', 'open_pyramid', 'timer', 'countdown_start_time', 'red_clock_time', 'blue_clock_time', 'green_clock_time', - 'local_items', 'non_local_items', 'retro', 'accessibility', 'hints', 'beemizer', - 'shufflebosses', 'enemy_shuffle', 'enemy_health', 'enemy_damage', 'shufflepots', + 'local_items', 'non_local_items', 'accessibility', 'beemizer', + 'shufflebosses', 'enemy_health', 'enemy_damage', 'sprite', "progression_balancing", "triforce_pieces_available", "triforce_pieces_required", "shop_shuffle", "required_medallions", "start_hints", "plando_items", "plando_texts", "plando_connections", "er_seeds", - 'dungeon_counters', 'killable_thieves', - 'tile_shuffle', 'bush_shuffle', 'shuffle_prizes', 'sprite_pool', 'dark_room_logic', - 'restrict_dungeon_item_on_boss', 'game']: + 'dungeon_counters', + 'shuffle_prizes', 'sprite_pool', 'dark_room_logic', + 'game']: value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) if player == 1: setattr(ret, name, {1: value}) diff --git a/worlds/alttp/Options.py b/worlds/alttp/Options.py index 93225e05..c6a2f87b 100644 --- a/worlds/alttp/Options.py +++ b/worlds/alttp/Options.py @@ -126,6 +126,59 @@ class Progressive(Choice): return random.choice([True, False]) if self.value == self.option_grouped_random else bool(self.value) +class Swordless(Toggle): + """No swords. Curtains in Skull Woods and Agahnim\'s + Tower are removed, Agahnim\'s Tower barrier can be + destroyed with hammer. Misery Mire and Turtle Rock + can be opened without a sword. Hammer damages Ganon. + Ether and Bombos Tablet can be activated with Hammer + (and Book).""" + displayname = "Swordless" + + +class Retro(Toggle): + """Zelda-1 like mode. You have to purchase a quiver to shoot arrows using rupees + and there are randomly placed take-any caves that contain one Sword and choices of Heart Container/Blue Potion.""" + displayname = "Retro" + + +class RestrictBossItem(Toggle): + """Don't place dungeon-native items on the dungeon's boss.""" + displayname = "Prevent Dungeon Item on Boss" + + +class Hints(DefaultOnToggle): + """Put item and entrance placement hints on telepathic tiles and some NPCs. + Additionally King Zora and Bottle Merchant say what they're selling.""" + displayname = "Hints" + + +class EnemyShuffle(Toggle): + """Randomize every enemy spawn. + If mode is Standard, Hyrule Castle is left out (may result in visually wrong enemy sprites in that area.)""" + displayname = "Enemy Shuffle" + + +class KillableThieves(Toggle): + """Makes Thieves killable.""" + displayname = "Killable Thieves" + + +class BushShuffle(Toggle): + """Randomize chance that a bush contains an enemy as well as which enemy may spawn.""" + displayname = "Bush Shuffle" + + +class TileShuffle(Toggle): + """Randomize flying tiles floor patterns.""" + displayname = "Tile Shuffle" + + +class PotShuffle(Toggle): + """Shuffle contents of pots within "supertiles" (item will still be nearby original placement).""" + displayname = "Pot Shuffle" + + class Palette(Choice): option_default = 0 option_good = 1 @@ -226,6 +279,13 @@ alttp_options: typing.Dict[str, type(Option)] = { "compass_shuffle": compass_shuffle, "map_shuffle": map_shuffle, "progressive": Progressive, + "swordless": Swordless, + "hints": Hints, + "restrict_dungeon_item_on_boss": RestrictBossItem, + "pot_shuffle": PotShuffle, + "enemy_shuffle": EnemyShuffle, + "killable_thieves": KillableThieves, + "bush_shuffle": BushShuffle, "shop_item_slots": ShopItemSlots, "ow_palettes": OWPalette, "uw_palettes": UWPalette, diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index a1cd2b9b..434eba67 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -323,7 +323,7 @@ def patch_enemizer(world, player: int, rom: LocalRom, enemizercli, output_direct 'GrayscaleMode': False, 'GenerateSpoilers': False, 'RandomizeLinkSpritePalette': False, - 'RandomizePots': world.shufflepots[player], + 'RandomizePots': world.pot_shuffle[player], 'ShuffleMusic': False, 'BootlegMagic': True, 'CustomBosses': False, diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index fd04cd47..45917640 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -258,7 +258,7 @@ class ALTTPWorld(World): try: 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.pot_shuffle[player] or world.bush_shuffle[player] or world.killable_thieves[player]) rom = LocalRom(world.alttp_rom) From c1c92647ca4712cecc7480f1521990f5bbf9a671 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 13 Sep 2021 02:01:15 +0200 Subject: [PATCH 3/4] LttP: move some simple Toggle options over to new system part 2 --- BaseClasses.py | 100 ++++++++++++---------------------------- worlds/alttp/Options.py | 2 + 2 files changed, 31 insertions(+), 71 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 2532aaf8..e7235d30 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -10,6 +10,8 @@ from typing import List, Dict, Optional, Set, Iterable, Union, Any, Tuple import secrets import random +import Utils + class MultiWorld(): debug_types = False @@ -82,8 +84,6 @@ class MultiWorld(): set_player_attr('timer', False) set_player_attr('goal', 'ganon') set_player_attr('accessibility', 'items') - set_player_attr('retro', False) - set_player_attr('hints', True) set_player_attr('required_medallions', ['Ether', 'Quake']) set_player_attr('swamp_patch_required', False) set_player_attr('powder_patch_required', False) @@ -96,12 +96,8 @@ class MultiWorld(): set_player_attr('fix_fake_world', True) set_player_attr('difficulty_requirements', None) set_player_attr('boss_shuffle', 'none') - set_player_attr('enemy_shuffle', False) set_player_attr('enemy_health', 'default') set_player_attr('enemy_damage', 'default') - set_player_attr('killable_thieves', False) - set_player_attr('tile_shuffle', False) - set_player_attr('bush_shuffle', False) set_player_attr('beemizer', 0) set_player_attr('escape_assist', []) set_player_attr('open_pyramid', False) @@ -122,7 +118,6 @@ class MultiWorld(): set_player_attr('shuffle_prizes', "g") set_player_attr('sprite_pool', []) set_player_attr('dark_room_logic', "lamp") - set_player_attr('restrict_dungeon_item_on_boss', False) set_player_attr('plando_items', []) set_player_attr('plando_texts', {}) set_player_attr('plando_connections', []) @@ -1011,7 +1006,6 @@ class Spoiler(): self.startinventory = [] self.locations = {} self.paths = {} - self.metadata = {} self.shops = [] self.bosses = OrderedDict() @@ -1104,41 +1098,6 @@ class Spoiler(): self.bosses[str(player)]["Ganons Tower"] = "Agahnim 2" self.bosses[str(player)]["Ganon"] = "Ganon" - from Utils import __version__ as APVersion - self.metadata = {'version': APVersion, - 'logic': self.world.logic, - 'dark_room_logic': self.world.dark_room_logic, - 'mode': self.world.mode, - 'retro': self.world.retro, - 'swordless': self.world.swordless, - 'goal': self.world.goal, - 'shuffle': self.world.shuffle, - 'item_pool': self.world.difficulty, - 'item_functionality': self.world.item_functionality, - 'open_pyramid': self.world.open_pyramid, - 'accessibility': self.world.accessibility, - 'hints': self.world.hints, - 'boss_shuffle': self.world.boss_shuffle, - 'enemy_shuffle': self.world.enemy_shuffle, - 'enemy_health': self.world.enemy_health, - 'enemy_damage': self.world.enemy_damage, - 'killable_thieves': self.world.killable_thieves, - 'tile_shuffle': self.world.tile_shuffle, - 'bush_shuffle': self.world.bush_shuffle, - 'beemizer': self.world.beemizer, - 'pot_shuffle': self.world.pot_shuffle, - 'players': self.world.players, - 'progression_balancing': self.world.progression_balancing, - 'triforce_pieces_available': self.world.triforce_pieces_available, - 'triforce_pieces_required': self.world.triforce_pieces_required, - 'shop_shuffle': self.world.shop_shuffle, - 'shuffle_prizes': self.world.shuffle_prizes, - 'sprite_pool': self.world.sprite_pool, - 'restrict_dungeon_item_on_boss': self.world.restrict_dungeon_item_on_boss, - 'game': self.world.game, - 'er_seeds': self.world.er_seeds - } - def to_json(self): self.parse_data() out = OrderedDict() @@ -1153,7 +1112,6 @@ class Spoiler(): out['playthrough'] = self.playthrough out['paths'] = self.paths out['Bosses'] = self.bosses - out['meta'] = self.metadata return json.dumps(out) @@ -1168,7 +1126,7 @@ class Spoiler(): with open(filename, 'w', encoding="utf-8-sig") as outfile: outfile.write( 'Archipelago Version %s - Seed: %s\n\n' % ( - self.metadata['version'], self.world.seed)) + Utils.__version__, self.world.seed)) outfile.write('Filling Algorithm: %s\n' % self.world.algorithm) outfile.write('Players: %d\n' % self.world.players) @@ -1178,8 +1136,8 @@ class Spoiler(): outfile.write('Game: %s\n' % self.world.game[player]) if self.world.players > 1: outfile.write('Progression Balanced: %s\n' % ( - 'Yes' if self.metadata['progression_balancing'][player] else 'No')) - outfile.write('Accessibility: %s\n' % self.metadata['accessibility'][player]) + 'Yes' if self.world.progression_balancing[player] else 'No')) + outfile.write('Accessibility: %s\n' % self.world.accessibility[player]) options = self.world.worlds[player].options if options: for f_option, option in options.items(): @@ -1190,39 +1148,39 @@ class Spoiler(): if player in self.world.get_game_players("A Link to the Past"): outfile.write('%s%s\n' % ('Hash: ', self.hashes[player])) - outfile.write('Logic: %s\n' % self.metadata['logic'][player]) - outfile.write('Dark Room Logic: %s\n' % self.metadata['dark_room_logic'][player]) - outfile.write('Mode: %s\n' % self.metadata['mode'][player]) - outfile.write('Goal: %s\n' % self.metadata['goal'][player]) - if "triforce" in self.metadata["goal"][player]: # triforce hunt + outfile.write('Logic: %s\n' % self.world.logic[player]) + outfile.write('Dark Room Logic: %s\n' % self.world.dark_room_logic[player]) + outfile.write('Mode: %s\n' % self.world.mode[player]) + outfile.write('Goal: %s\n' % self.world.goal[player]) + if "triforce" in self.world.goal[player]: # triforce hunt outfile.write("Pieces available for Triforce: %s\n" % - self.metadata['triforce_pieces_available'][player]) + self.world.triforce_pieces_available[player]) outfile.write("Pieces required for Triforce: %s\n" % - self.metadata["triforce_pieces_required"][player]) - outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player]) - outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player]) - outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player]) - if self.metadata['shuffle'][player] != "vanilla": - outfile.write('Entrance Shuffle Seed %s\n' % self.metadata['er_seeds'][player]) + self.world.triforce_pieces_required[player]) + outfile.write('Difficulty: %s\n' % self.world.item_pool[player]) + outfile.write('Item Functionality: %s\n' % self.world.item_functionality[player]) + outfile.write('Entrance Shuffle: %s\n' % self.world.shuffle[player]) + if self.world.shuffle[player] != "vanilla": + outfile.write('Entrance Shuffle Seed %s\n' % self.world.er_seeds[player]) outfile.write('Pyramid hole pre-opened: %s\n' % ( - 'Yes' if self.metadata['open_pyramid'][player] else 'No')) + 'Yes' if self.world.open_pyramid[player] else 'No')) outfile.write('Shop inventory shuffle: %s\n' % - bool_to_text("i" in self.metadata["shop_shuffle"][player])) + bool_to_text("i" in self.world.shop_shuffle[player])) outfile.write('Shop price shuffle: %s\n' % - bool_to_text("p" in self.metadata["shop_shuffle"][player])) + bool_to_text("p" in self.world.shop_shuffle[player])) outfile.write('Shop upgrade shuffle: %s\n' % - bool_to_text("u" in self.metadata["shop_shuffle"][player])) + bool_to_text("u" in self.world.shop_shuffle[player])) outfile.write('New Shop inventory: %s\n' % - bool_to_text("g" in self.metadata["shop_shuffle"][player] or - "f" in self.metadata["shop_shuffle"][player])) + bool_to_text("g" in self.world.shop_shuffle[player] or + "f" in self.world.shop_shuffle[player])) outfile.write('Custom Potion Shop: %s\n' % - bool_to_text("w" in self.metadata["shop_shuffle"][player])) - outfile.write('Boss shuffle: %s\n' % self.metadata['boss_shuffle'][player]) - outfile.write('Enemy health: %s\n' % self.metadata['enemy_health'][player]) - outfile.write('Enemy damage: %s\n' % self.metadata['enemy_damage'][player]) - outfile.write('Beemizer: %s\n' % self.metadata['beemizer'][player]) + bool_to_text("w" in self.world.shop_shuffle[player])) + outfile.write('Boss shuffle: %s\n' % self.world.boss_shuffle[player]) + outfile.write('Enemy health: %s\n' % self.world.enemy_health[player]) + outfile.write('Enemy damage: %s\n' % self.world.enemy_damage[player]) + outfile.write('Beemizer: %s\n' % self.world.beemizer[player]) outfile.write('Prize shuffle %s\n' % - self.metadata['shuffle_prizes'][player]) + self.world.shuffle_prizes[player]) if self.entrances: outfile.write('\n\nEntrances:\n\n') outfile.write('\n'.join(['%s%s %s %s' % (f'{self.world.get_player_name(entry["player"])}: ' diff --git a/worlds/alttp/Options.py b/worlds/alttp/Options.py index c6a2f87b..22277625 100644 --- a/worlds/alttp/Options.py +++ b/worlds/alttp/Options.py @@ -280,6 +280,7 @@ alttp_options: typing.Dict[str, type(Option)] = { "map_shuffle": map_shuffle, "progressive": Progressive, "swordless": Swordless, + "retro": Retro, "hints": Hints, "restrict_dungeon_item_on_boss": RestrictBossItem, "pot_shuffle": PotShuffle, @@ -287,6 +288,7 @@ alttp_options: typing.Dict[str, type(Option)] = { "killable_thieves": KillableThieves, "bush_shuffle": BushShuffle, "shop_item_slots": ShopItemSlots, + "tile_shuffle": TileShuffle, "ow_palettes": OWPalette, "uw_palettes": UWPalette, "hud_palettes": HUDPalette, From 80c90c0a0059d9343eec6c6faa593c5626f8f17f Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 13 Sep 2021 02:03:59 +0200 Subject: [PATCH 4/4] LttP: why is item pool called difficulty again? --- BaseClasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index e7235d30..fbba6976 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1157,7 +1157,7 @@ class Spoiler(): self.world.triforce_pieces_available[player]) outfile.write("Pieces required for Triforce: %s\n" % self.world.triforce_pieces_required[player]) - outfile.write('Difficulty: %s\n' % self.world.item_pool[player]) + outfile.write('Difficulty: %s\n' % self.world.difficulty[player]) outfile.write('Item Functionality: %s\n' % self.world.item_functionality[player]) outfile.write('Entrance Shuffle: %s\n' % self.world.shuffle[player]) if self.world.shuffle[player] != "vanilla":