Exemplo n.º 1
0
    def resolve_random_settings(self):
        # evaluate settings (important for logic, nice for spoiler)
        self.randomized_list = []
        if self.randomize_settings:
            setting_info = get_setting_info('randomize_settings')
            self.randomized_list.extend(setting_info.disable[True]['settings'])
            for section in setting_info.disable[True]['sections']:
                self.randomized_list.extend(get_settings_from_section(section))
        if self.big_poe_count_random:
            self.big_poe_count = random.randint(1, 10)
            self.randomized_list.append('big_poe_count')
        if self.starting_tod == 'random':
            setting_info = get_setting_info('starting_tod')
            choices = [
                ch for ch in setting_info.choices
                if ch not in ['default', 'random']
            ]
            self.starting_tod = random.choice(choices)
            self.randomized_list.append('starting_tod')
        if self.starting_age == 'random':
            self.starting_age = random.choice(['child', 'adult'])
            self.randomized_list.append('starting_age')
        if self.chicken_count_random:
            self.chicken_count = random.randint(0, 7)
            self.randomized_list.append('chicken_count')

        # Determine Ganon Trials
        trial_pool = list(self.skipped_trials)
        dist_chosen = self.distribution.configure_trials(trial_pool)
        dist_num_chosen = len(dist_chosen)

        if self.trials_random:
            self.trials = dist_num_chosen + random.randint(0, len(trial_pool))
            self.randomized_list.append('trials')
        num_trials = int(self.trials)
        choosen_trials = random.sample(trial_pool,
                                       num_trials - dist_num_chosen)
        for trial in self.skipped_trials:
            if trial not in choosen_trials and trial not in dist_chosen:
                self.skipped_trials[trial] = True

        # Determine MQ Dungeons
        dungeon_pool = list(self.dungeon_mq)
        dist_num_mq = self.distribution.configure_dungeons(self, dungeon_pool)

        if self.mq_dungeons_random:
            for dungeon in dungeon_pool:
                self.dungeon_mq[dungeon] = random.choice([True, False])
            self.mq_dungeons = list(self.dungeon_mq.values()).count(True)
            self.randomized_list.append('mq_dungeons')
        else:
            mqd_picks = random.sample(dungeon_pool,
                                      self.mq_dungeons - dist_num_mq)
            for dung in mqd_picks:
                self.dungeon_mq[dung] = True

        self.distribution.configure_randomized_settings(self)
Exemplo n.º 2
0
 def get_dependency(self, setting_name, check_random=True):
     info = get_setting_info(setting_name)
     if check_random and 'randomize_key' in info.gui_params and self.__dict__[info.gui_params['randomize_key']]:
         return info.disabled_default
     elif info.dependency != None:
         return info.disabled_default if info.dependency(self) else None
     else:
         return None
Exemplo n.º 3
0
 def get_dependency(self, setting_name, check_random=True):
     info = get_setting_info(setting_name)
     not_in_dist = '_settings' not in self.distribution.src_dict or info.name not in self.distribution.src_dict[
         '_settings'].keys()
     if check_random and 'randomize_key' in info.gui_params and self.__dict__[
             info.gui_params['randomize_key']] and not_in_dist:
         return info.disabled_default
     elif info.dependency != None:
         return info.disabled_default if info.dependency(
             self) and not_in_dist else None
     else:
         return None
Exemplo n.º 4
0
def generate_balanced_weights(fname='default_weights.json'):
    """ Generate a file with even weights for each setting. """
    settings_to_randomize = list(get_settings_from_tab('main_tab'))[1:] + \
                list(get_settings_from_tab('detailed_tab')) + \
                list(get_settings_from_tab('other_tab')) + \
                list(get_settings_from_tab('starting_tab'))

    exclude_from_weights = [
        'bridge_tokens', 'lacs_tokens', 'triforce_goal_per_world',
        'disabled_locations', 'allowed_tricks', 'starting_equipment',
        'starting_items', 'starting_songs'
    ]
    weight_dict = {}
    for name in settings_to_randomize:
        if name not in exclude_from_weights:
            opts = list(get_setting_info(name).choices.keys())
            optsdict = {o: 100. / len(opts) for o in opts}
            weight_dict[name] = optsdict

    if fname is not None:
        with open(fname, 'w') as fp:
            json.dump(weight_dict, fp, indent=4)

    return weight_dict
Exemplo n.º 5
0
def GetSettingJson(setting, web_version, as_array=False):
    try:
        setting_info = get_setting_info(setting)
    except KeyError:
        if as_array:
            return {'name': setting}
        else:
            return {}

    if setting_info.gui_text is None:
        return None

    settingJson = {
        'options': [],
        'default':
        setting_info.default,
        'text':
        setting_info.gui_text,
        'tooltip':
        RemoveTrailingLines('<br>'.join(
            line.strip() for line in setting_info.gui_tooltip.split('\n'))),
        'type':
        setting_info.gui_type,
        'shared':
        setting_info.shared,
    }

    if as_array:
        settingJson['name'] = setting_info.name
    else:
        settingJson['current_value'] = setting_info.default

    setting_disable = {}
    if setting_info.disable != None:
        setting_disable = copy.deepcopy(setting_info.disable)

    for key, value in setting_info.gui_params.items():
        if key.startswith('web:'):
            if web_version:
                key = key[4:]
            else:
                continue
        if key.startswith('electron:'):
            if not web_version:
                key = key[9:]
            else:
                continue

        if key in setting_keys:
            settingJson[key] = value
        if key == 'disable':
            for option, types in value.items():
                for s in types.get('settings', []):
                    if get_setting_info(s).shared:
                        raise ValueError(
                            f'Cannot disable setting {s}. Disabling "shared" settings in the gui_params is forbidden. Use the non gui_param version of disable instead.'
                        )
                for section in types.get('sections', []):
                    for s in get_settings_from_section(section):
                        if get_setting_info(s).shared:
                            raise ValueError(
                                f'Cannot disable setting {s} in {section}. Disabling "shared" settings in the gui_params is forbidden. Use the non gui_param version of disable instead.'
                            )
                for tab in types.get('tabs', []):
                    for s in get_settings_from_tab(tab):
                        if get_setting_info(s).shared:
                            raise ValueError(
                                f'Cannot disable setting {s} in {tab}. Disabling "shared" settings in the gui_params is forbidden. Use the non gui_param version of disable instead.'
                            )
            deep_update(setting_disable, value)

    if settingJson['type'] in types_with_options:
        if as_array:
            settingJson['options'] = []
        else:
            settingJson['options'] = {}

        tags_list = []

        for option_name in setting_info.choice_list:
            if option_name in settingJson.get('option_remove', []):
                continue

            if as_array:
                optionJson = {
                    'name': option_name,
                    'text': setting_info.choices[option_name],
                }
            else:
                optionJson = {
                    'text': setting_info.choices[option_name],
                }

            if option_name in setting_disable:
                add_disable_option_to_json(setting_disable[option_name],
                                           optionJson)

            option_tooltip = setting_info.gui_params.get('choice_tooltip',
                                                         {}).get(
                                                             option_name, None)
            if option_tooltip != None:
                optionJson['tooltip'] = RemoveTrailingLines('<br>'.join(
                    line.strip() for line in option_tooltip.split('\n')))

            option_filter = setting_info.gui_params.get('filterdata', {}).get(
                option_name, None)
            if option_filter != None:
                optionJson['tags'] = option_filter
                for tag in option_filter:
                    if tag not in tags_list:
                        tags_list.append(tag)

            if as_array:
                settingJson['options'].append(optionJson)
            else:
                settingJson['options'][option_name] = optionJson

        # For disables with '!', add disable settings to all options other than the one marked.
        for option_name in setting_disable:
            if isinstance(option_name, str) and option_name[0] == '!':
                if as_array:
                    for option in settingJson['options']:
                        if option['name'] != option_name[1:]:
                            add_disable_option_to_json(
                                setting_disable[option_name], option)
                else:
                    for name, option in settingJson['options'].items():
                        if name != option_name[1:]:
                            add_disable_option_to_json(
                                setting_disable[option_name], option)

        if tags_list:
            tags_list.sort()
            settingJson['tags'] = ['(all)'] + tags_list
            settingJson['filter_by_tag'] = True

    return settingJson
Exemplo n.º 6
0
    def __init__(self, settings):
        self.shuffle = 'vanilla'
        self.dungeons = []
        self.regions = []
        self.itempool = []
        self.state = State(self)
        self._cached_locations = None
        self._entrance_cache = {}
        self._region_cache = {}
        self._location_cache = {}
        self.required_locations = []
        self.shop_prices = {}
        self.scrub_prices = {}
        self.light_arrow_location = None

        # dump settings directly into world's namespace
        # this gives the world an attribute for every setting listed in Settings.py
        self.settings = settings
        self.__dict__.update(settings.__dict__)
        self.distribution = None

        # evaluate settings (important for logic, nice for spoiler)
        if self.big_poe_count_random:
            self.big_poe_count = random.randint(1, 10)
        if self.starting_tod == 'random':
            setting_info = get_setting_info('starting_tod')
            choices = [
                ch for ch in setting_info.choices
                if ch not in ['default', 'random']
            ]
            self.starting_tod = random.choice(choices)
        if self.starting_age == 'random':
            self.starting_age = random.choice(['child', 'adult'])

        # rename a few attributes...
        self.keysanity = self.shuffle_smallkeys != 'dungeon'
        self.check_beatable_only = not self.all_reachable
        self.shuffle_dungeon_entrances = self.entrance_shuffle != 'off'
        self.shuffle_grotto_entrances = self.entrance_shuffle in [
            'simple-indoors', 'all-indoors', 'all'
        ]
        self.shuffle_interior_entrances = self.entrance_shuffle in [
            'simple-indoors', 'all-indoors', 'all'
        ]
        self.shuffle_special_interior_entrances = self.entrance_shuffle in [
            'all-indoors', 'all'
        ]
        self.shuffle_overworld_entrances = self.entrance_shuffle == 'all'

        # trials that can be skipped will be decided later
        self.skipped_trials = {
            'Forest': False,
            'Fire': False,
            'Water': False,
            'Spirit': False,
            'Shadow': False,
            'Light': False
        }

        # dungeon forms will be decided later
        self.dungeon_mq = {
            'Deku Tree': False,
            'Dodongos Cavern': False,
            'Jabu Jabus Belly': False,
            'Bottom of the Well': False,
            'Ice Cavern': False,
            'Gerudo Training Grounds': False,
            'Forest Temple': False,
            'Fire Temple': False,
            'Water Temple': False,
            'Spirit Temple': False,
            'Shadow Temple': False,
            'Ganons Castle': False
        }

        self.can_take_damage = True
Exemplo n.º 7
0
def GetSettingJson(setting, web_version, as_array=False):
    try:
        setting_info = get_setting_info(setting)
    except KeyError:
        if as_array:
            return {'name': setting}
        else:
            return {}

    if setting_info.gui_text is None:
        return None

    settingJson = {
        'options': [],
        'default':
        setting_info.default,
        'text':
        setting_info.gui_text,
        'tooltip':
        RemoveTrailingLines('<br>'.join(
            line.strip() for line in setting_info.gui_tooltip.split('\n'))),
        'type':
        setting_info.gui_type,
    }

    if as_array:
        settingJson['name'] = setting_info.name
    else:
        settingJson['current_value'] = setting_info.default

    for key, value in setting_info.gui_params.items():
        if key in setting_keys:
            settingJson[key] = value
        if key.startswith('web:') and web_version:
            settingJson[key[4:]] = value
        if key.startswith('electron:') and not web_version:
            settingJson[key[9:]] = value

    if settingJson['type'] in types_with_options:
        if as_array:
            settingJson['options'] = []
        else:
            settingJson['options'] = {}

        tags_list = []

        for option_name in setting_info.choice_list:
            if as_array:
                optionJson = {
                    'name': option_name,
                    'text': setting_info.choices[option_name],
                }
            else:
                optionJson = {
                    'text': setting_info.choices[option_name],
                }

            if setting_info.disable != None and option_name in setting_info.disable:
                disable_option = setting_info.disable[option_name]
                if disable_option.get('settings') != None:
                    optionJson['controls_visibility_setting'] = ','.join(
                        disable_option['settings'])
                if disable_option.get('sections') != None:
                    optionJson['controls_visibility_section'] = ','.join(
                        disable_option['sections'])
                if disable_option.get('tabs') != None:
                    optionJson['controls_visibility_tab'] = ','.join(
                        disable_option['tabs'])

            option_tooltip = setting_info.gui_params.get('choice_tooltip',
                                                         {}).get(
                                                             option_name, None)
            if option_tooltip != None:
                optionJson['tooltip'] = RemoveTrailingLines('<br>'.join(
                    line.strip() for line in option_tooltip.split('\n')))

            option_filter = setting_info.gui_params.get('filterdata', {}).get(
                option_name, None)
            if option_filter != None:
                optionJson['tags'] = option_filter
                for tag in option_filter:
                    if tag not in tags_list:
                        tags_list.append(tag)

            if as_array:
                settingJson['options'].append(optionJson)
            else:
                settingJson['options'][option_name] = optionJson

        if tags_list:
            tags_list.sort()
            settingJson['tags'] = ['(all)'] + tags_list
            settingJson['filter_by_tag'] = True

    return settingJson
Exemplo n.º 8
0
 def check_dependency(self, setting_name):
     info = get_setting_info(setting_name)
     if info.gui_params is not None and 'dependency' in info.gui_params:
         return info.gui_params['dependency'](self) == None
     else:
         return True
Exemplo n.º 9
0
 def check_dependency(self, setting_name):
     info = get_setting_info(setting_name)
     if info.dependency != None:
         return info.dependency(self) == None
     else:
         return True
Exemplo n.º 10
0
    def resolve_random_settings(self):
        # evaluate settings (important for logic, nice for spoiler)
        self.randomized_list = []
        dist_keys = []
        if '_settings' in self.distribution.distribution.src_dict:
            dist_keys = self.distribution.distribution.src_dict[
                '_settings'].keys()
        if self.settings.randomize_settings:
            setting_info = get_setting_info('randomize_settings')
            self.randomized_list.extend(setting_info.disable[True]['settings'])
            for section in setting_info.disable[True]['sections']:
                self.randomized_list.extend(get_settings_from_section(section))
                # Remove settings specified in the distribution
                self.randomized_list = [
                    x for x in self.randomized_list if x not in dist_keys
                ]
            for setting in list(self.randomized_list):
                if (setting == 'bridge_medallions' and self.settings.bridge != 'medallions') \
                        or (setting == 'bridge_stones' and self.settings.bridge != 'stones') \
                        or (setting == 'bridge_rewards' and self.settings.bridge != 'dungeons') \
                        or (setting == 'bridge_tokens' and self.settings.bridge != 'tokens') \
                        or (setting == 'lacs_medallions' and self.settings.lacs_condition != 'medallions') \
                        or (setting == 'lacs_stones' and self.settings.lacs_condition != 'stones') \
                        or (setting == 'lacs_rewards' and self.settings.lacs_condition != 'dungeons') \
                        or (setting == 'lacs_tokens' and self.settings.lacs_condition != 'tokens'):
                    self.randomized_list.remove(setting)
        if self.settings.big_poe_count_random and 'big_poe_count' not in dist_keys:
            self.settings.big_poe_count = random.randint(1, 10)
            self.randomized_list.append('big_poe_count')
        if self.settings.starting_tod == 'random' and 'starting_tod' not in dist_keys:
            setting_info = get_setting_info('starting_tod')
            choices = [
                ch for ch in setting_info.choices
                if ch not in ['default', 'random']
            ]
            self.settings.starting_tod = random.choice(choices)
            self.randomized_list.append('starting_tod')
        if self.settings.starting_age == 'random' and 'starting_age' not in dist_keys:
            if self.settings.open_forest == 'closed':
                # adult is not compatible
                self.settings.starting_age = 'child'
            else:
                self.settings.starting_age = random.choice(['child', 'adult'])
            self.randomized_list.append('starting_age')
        if self.settings.chicken_count_random and 'chicken_count' not in dist_keys:
            self.settings.chicken_count = random.randint(0, 7)
            self.randomized_list.append('chicken_count')

        # Handle random Rainbow Bridge condition
        if self.settings.bridge == 'random':
            possible_bridge_requirements = [
                "open", "medallions", "dungeons", "stones", "vanilla"
            ]
            self.settings.bridge = random.choice(possible_bridge_requirements)
            self.set_random_bridge_values()
            self.randomized_list.append('bridge')

        # Determine Ganon Trials
        trial_pool = list(self.skipped_trials)
        dist_chosen = self.distribution.configure_trials(trial_pool)
        dist_num_chosen = len(dist_chosen)

        if self.settings.trials_random and 'trials' not in dist_keys:
            self.settings.trials = dist_num_chosen + random.randint(
                0, len(trial_pool))
            self.randomized_list.append('trials')
        num_trials = int(self.settings.trials)
        choosen_trials = random.sample(trial_pool,
                                       num_trials - dist_num_chosen)
        for trial in self.skipped_trials:
            if trial not in choosen_trials and trial not in dist_chosen:
                self.skipped_trials[trial] = True

        # Determine MQ Dungeons
        dungeon_pool = list(self.dungeon_mq)
        dist_num_mq = self.distribution.configure_dungeons(self, dungeon_pool)

        if self.settings.mq_dungeons_random and 'mq_dungeons' not in dist_keys:
            for dungeon in dungeon_pool:
                self.dungeon_mq[dungeon] = random.choice([True, False])
            self.settings.mq_dungeons = list(
                self.dungeon_mq.values()).count(True)
            self.randomized_list.append('mq_dungeons')
        else:
            mqd_picks = random.sample(dungeon_pool,
                                      self.settings.mq_dungeons - dist_num_mq)
            for dung in mqd_picks:
                self.dungeon_mq[dung] = True

        self.distribution.configure_randomized_settings(self)