From e98981b57e290cfed045bbc2d89858a184dcbf9d Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sat, 25 Apr 2020 02:24:37 +0200 Subject: [PATCH] introduce linked options to mystery --- ItemList.py | 3 +-- Mystery.py | 30 ++++++++++++++++++++++++++++-- easy.yaml | 23 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/ItemList.py b/ItemList.py index 3af6092c..e4d34b84 100644 --- a/ItemList.py +++ b/ItemList.py @@ -356,7 +356,6 @@ def fill_prizes(world, attempts=15): placed_prizes = [loc.item.name for loc in crystal_locations if loc.item is not None] unplaced_prizes = [crystal for crystal in crystals if crystal.name not in placed_prizes] empty_crystal_locations = [loc for loc in crystal_locations if loc.item is None] - for attempt in range(attempts): try: prizepool = list(unplaced_prizes) @@ -366,7 +365,7 @@ def fill_prizes(world, attempts=15): fill_restrictive(world, all_state, prize_locs, prizepool, True) except FillError as e: logging.getLogger('').exception("Failed to place dungeon prizes (%s). Will retry %s more times", e, - attempts - attempt - 1) + attempts - attempt) for location in empty_crystal_locations: location.item = None continue diff --git a/Mystery.py b/Mystery.py index 8e517dff..cca98ddf 100644 --- a/Mystery.py +++ b/Mystery.py @@ -38,6 +38,8 @@ def main(): parser.add_argument('--meta', default=None) parser.add_argument('--log_output_path', help='Path to store output log') parser.add_argument('--loglevel', default='info', help='Sets log level') + parser.add_argument('--yaml_output', default=256, type=lambda value: min(max(int(value), 0), 255), + help='Output rolled mystery results to yaml up to specified number (made for async multiworld)"') for player in range(1, multiargs.multi + 1): parser.add_argument(f'--p{player}', help=argparse.SUPPRESS) @@ -161,11 +163,27 @@ def main(): raise RuntimeError(f'No weights specified for player {player}') if not erargs.name[player]: erargs.name[player] = os.path.split(path)[-1].split(".")[0] - if args.samesettings: + if args.weights: erargs.names = "" else: erargs.names = ",".join(erargs.name[i] for i in range(1, args.multi + 1)) del (erargs.name) + if args.yaml_output: + import yaml + important = {} + for option, player_settings in vars(erargs).items(): + if type(player_settings) == dict: + if len(set(player_settings.values())) > 1: + important[option] = {player: value for player, value in player_settings.items() if + player <= args.yaml_output} + else: + important[option] = player_settings[1] + else: + if player_settings != "": # is not empty name + important[option] = player_settings + os.makedirs(args.outputpath, exist_ok=True) + with open(os.path.join(args.outputpath if args.outputpath else ".", f"mystery_result_{seed}.yaml"), "wt") as f: + yaml.dump(important, f) ERmain(erargs, seed) @@ -212,11 +230,19 @@ def roll_settings(weights): ret.name = get_choice('name', weights) if ret.name: ret.name = handle_name(ret.name) + + if "linked_options" in weights: + weights = weights.copy() # make sure we don't write back to other weights sets in same_settings + for option_set in weights["linked_options"]: + if random.random() < (option_set["percentage"] / 100): + weights.update(option_set["options"]) + glitches_required = get_choice('glitches_required', weights) if glitches_required not in ['none', 'no_logic', 'overworld_glitches']: logging.warning("Only NMG, OWG and No Logic supported") glitches_required = 'none' - ret.logic = {None: 'noglitches', 'none': 'noglitches', 'no_logic': 'nologic', 'overworld_glitches': 'owglitches'}[glitches_required] + ret.logic = {None: 'noglitches', 'none': 'noglitches', 'no_logic': 'nologic', 'overworld_glitches': 'owglitches'}[ + glitches_required] # item_placement = get_choice('item_placement') # not supported in ER diff --git a/easy.yaml b/easy.yaml index 212dc378..7a380e73 100644 --- a/easy.yaml +++ b/easy.yaml @@ -156,6 +156,29 @@ glitch_boots: remote_items: # Warning: currently broken. Stores all your items on the server, effectively sending them to you as if another player picked it up on: 0 # intended for racing, as the item information is missing from the ROM off: 1 +linked_options: + - name: crosskeys + options: # these overwrite earlier options if the percentage chance triggers + entrance_shuffle: crossed + bigkey_shuffle: true + compass_shuffle: true + map_shuffle: true + smallkey_shuffle: true + percentage: 0 # set this to the percentage chance you want crosskeys + - name: enemizer + options: + boss_shuffle: # subchances can be injected too, which then get rolled + simple: 1 + full: 1 + random: 1 + enemy_damage: + shuffled: 1 + random: 1 + enemy_health: + easy: 1 + hard: 1 + expert: 1 + percentage: 0 # set this to the percentage chance you want enemizer rom: sprite: # Enter the name of your preferred sprite and weight it appropriately random: 0