def _select_template(self,
                         sim_info: SimInfo,
                         on_close: Callable[[], None] = None):
        self.log.format_with_message('Opening dialog.', sim=sim_info)

        def _on_close() -> None:
            self.log.debug('Slider Template dialog closed.')
            if on_close is not None:
                on_close()

        option_dialog = CommonChooseObjectOptionDialog(
            CSFStringId.SELECTED_TEMPLATE,
            CSFStringId.PLEASE_SELECT_A_TEMPLATE,
            mod_identity=self.mod_identity,
            on_close=_on_close,
            per_page=400)

        self.log.debug('Opening Customize Slider dialog.')

        def _on_chosen(_: str, _chosen_template: CSFSliderTemplate):
            if _chosen_template is None:
                self.log.debug('No template name entered, dialog closed.')
                _on_close()
                return
            self.log.format_with_message(
                'Template name entered.',
                template_name=_chosen_template.template_name)
            CSFSliderTemplateDialog._SELECTED_TEMPLATE = _chosen_template
            _on_close()

        for (template_name,
             template) in self._template_utils.template_library.items():
            template: CSFSliderTemplate = template
            option_dialog.add_option(
                CommonDialogObjectOption(
                    template_name,
                    template,
                    CommonDialogOptionContext(
                        template.display_name,
                        0,
                        icon=CommonIconUtils.load_filled_circle_icon() if
                        CSFSliderTemplateDialog._SELECTED_TEMPLATE == template
                        else CommonIconUtils.load_unfilled_circle_icon(),
                    ),
                    on_chosen=_on_chosen))

        if not option_dialog.has_options():

            def _on_acknowledge(_) -> None:
                _on_close()

            CommonOkDialog(CSFStringId.NO_TEMPLATES_DETECTED_NAME,
                           CSFStringId.NO_TEMPLATES_DETECTED_DESCRIPTION,
                           mod_identity=self.mod_identity).show(
                               on_acknowledged=_on_acknowledge)
            return

        option_dialog.show(sim_info=sim_info)
    def run(
        self,
        sim_info: SimInfo,
        on_completed: Callable[[bool],
                               None] = CommonFunctionUtils.noop) -> bool:
        def _reopen() -> None:
            self.run(sim_info, on_completed=on_completed)

        def _on_close() -> None:
            on_completed(False)

        option_dialog = CommonChooseObjectOptionDialog(
            S4CMSimModifySkillsStringId.SET_SKILL_LEVELS,
            0,
            on_close=_on_close,
            mod_identity=self.mod_identity,
            per_page=20000)

        def _on_input_setting_changed(_skill: Skill, new_skill_level: int,
                                      outcome: CommonChoiceOutcome):
            if new_skill_level is None or CommonChoiceOutcome.is_error_or_cancel(
                    outcome):
                _reopen()
                return
            self.log.format_with_message('Setting skill level for Sim.',
                                         _skill=_skill,
                                         new_skill_level=new_skill_level)
            CommonSimSkillUtils.set_current_skill_level(
                sim_info, _skill, new_skill_level)
            if new_skill_level == 0:
                CommonSimSkillUtils.remove_skill(sim_info, _skill)
            _reopen()

        skill_manager = CommonResourceUtils.get_instance_manager(
            Types.STATISTIC)
        sim = CommonSimUtils.get_sim_instance(sim_info)
        for skill in skill_manager.get_ordered_types(only_subclasses_of=Skill):
            skill: Skill = skill
            skill_id = CommonSkillUtils.get_skill_id(skill)
            if skill_id is None:
                self.log.format_with_message('Missing skill id for Skill.',
                                             skill=skill)
                continue
            try:
                self.verbose_log.format_with_message(
                    'Attempting to display skill',
                    skill=skill,
                    skill_id=skill_id,
                    sim=sim_info)
                if not skill.can_add(sim):
                    self.verbose_log.format_with_message(
                        'Failed, Skill is not allowed for Sim.',
                        skill=skill,
                        skill_id=skill_id,
                        sim=sim_info)
                    continue
                if not CommonSimSkillUtils.has_skill(sim_info, skill_id):
                    current_skill_level = 0
                else:
                    current_skill_level = int(
                        CommonSimSkillUtils.get_current_skill_level(
                            sim_info,
                            skill_id,
                            use_effective_skill_level=False))
                stat_name = getattr(skill, 'stat_name', None)
                # noinspection PyUnresolvedReferences
                if stat_name and skill.stat_name.hash is not 0:
                    # noinspection PyUnresolvedReferences
                    display_name = skill.stat_name
                else:
                    skill_name = skill.__name__ or 'Unknown Skill Name'
                    skill_name = skill_name[0].upper() + skill_name[1:]
                    display_name = LocalizationHelperTuning.get_raw_text(
                        skill_name)

                # noinspection PyUnresolvedReferences
                if skill.hidden:
                    display_name = CommonLocalizationUtils.create_localized_string(
                        S4CMSimControlMenuStringId.STRING_SPACE_PAREN_STRING,
                        tokens=(display_name,
                                S4CMSimControlMenuStringId.HIDDEN))

                display_name = CommonLocalizationUtils.create_localized_string(
                    S4CMSimControlMenuStringId.STRING_COLON_SPACE_STRING,
                    tokens=(display_name, str(current_skill_level)))
                # noinspection PyUnresolvedReferences
                description = CommonLocalizationUtils.create_localized_string(
                    skill.skill_description, tokens=(sim_info, ))
                # noinspection PyUnresolvedReferences
                icon = skill.icon or CommonIconUtils.load_question_mark_icon()
                # MISSING ICON Identifier
                _MISSING_IMAGE_ICON_ID = 3526464109639239417
                if icon.instance == 0 or icon.instance == _MISSING_IMAGE_ICON_ID:
                    icon = CommonIconUtils.load_question_mark_icon()
                option_dialog.add_option(
                    CommonDialogInputIntegerOption(
                        self.mod_identity,
                        skill,
                        current_skill_level,
                        CommonDialogOptionContext(
                            display_name,
                            description,
                            icon=icon,
                            is_enabled=self._is_skill_allowed_for_modification(
                                sim_info, skill)),
                        dialog_description_identifier=S4CMSimModifySkillsStringId
                        .ENTER_A_VALE_BETWEEN_MIN_AND_MAX_FOR_SKILL,
                        dialog_description_tokens=(str(0),
                                                   str(int(skill.max_level)),
                                                   str(current_skill_level)),
                        min_value=0,
                        max_value=int(skill.max_level),
                        on_chosen=_on_input_setting_changed))
            except Exception as ex:
                self.log.format_error_with_message('Failed to display skill.',
                                                   skill=skill,
                                                   skill_name=skill.__name__,
                                                   skill_id=skill_id,
                                                   exception=ex)

        if not option_dialog.has_options():
            self.log.format_with_message('No skills available for the Sim!')
            on_completed(False)
            return False
        option_dialog.show(sim_info=sim_info, sort_options=True)
        return True
    def _view_template(self,
                       sim_info: SimInfo,
                       on_close: Callable[[], None] = None):
        self.log.format_with_message('Opening view template dialog.',
                                     sim=sim_info)

        def _on_close() -> None:
            self.log.debug('Slider Template dialog closed.')
            if on_close is not None:
                on_close()

        def _reopen() -> None:
            self._view_template(sim_info, on_close=on_close)

        if CSFSliderTemplateDialog._SELECTED_TEMPLATE is None:

            def _on_acknowledge(_) -> None:
                _on_close()

            CommonOkDialog(CSFStringId.NO_TEMPLATE_SELECTED,
                           CSFStringId.PLEASE_SELECT_A_TEMPLATE,
                           mod_identity=self.mod_identity).show(
                               on_acknowledged=_on_acknowledge)
            return

        option_dialog = CommonChooseObjectOptionDialog(
            CSFStringId.VIEW_TEMPLATE_NAME,
            CSFStringId.VIEW_TEMPLATE_DESCRIPTION,
            mod_identity=self.mod_identity,
            on_close=_on_close,
            per_page=400)

        for (slider,
             amount) in CSFSliderTemplateDialog._SELECTED_TEMPLATE.get_sliders(
                 sim_info):
            slider: CSFSlider = slider
            option_dialog.add_option(
                CommonDialogObjectOption(
                    slider.unique_identifier,
                    slider,
                    CommonDialogOptionContext(
                        0,
                        CSFStringId.STRING_PLUS_STRING,
                        description_tokens=(
                            slider.display_name,
                            str(amount),
                        ),
                        icon=CommonIconUtils.load_arrow_right_icon(),
                        is_enabled=False),
                    on_chosen=lambda *_, **__: _reopen()))

        if not option_dialog.has_options():

            def _on_acknowledge(_) -> None:
                _on_close()

            CommonOkDialog(CSFStringId.NO_SLIDERS_DETECTED_NAME,
                           CSFStringId.NO_SLIDERS_DETECTED_DESCRIPTION,
                           mod_identity=self.mod_identity).show(
                               on_acknowledged=_on_acknowledge)
            return

        option_dialog.show(sim_info=sim_info)
    def open(self,
             source_sim_info: SimInfo,
             target: Any = None,
             page: int = 1) -> None:
        """open(source_sim_info, target=None, page=1)

        Open the mod settings menu.

        :param source_sim_info: An instance of the Sim opening the dialog.
        :type source_sim_info: SimInfo
        :param target: An instance of an object. Default is None.
        :type target: Any, optional
        :param page: The page to open at. Default is 1.
        :type page: int, optional
        """
        self.log.debug('Opening Mod Settings Menu.')

        def _reopen(*_, **__) -> None:
            self.log.debug('Reopening MSM.')
            self.open(source_sim_info,
                      target=target,
                      page=option_dialog.current_page)

        def _on_close(*_, **__) -> None:
            self.log.debug('MSM closed.')
            if self._on_close is not None:
                self._on_close()

        option_dialog = CommonChooseObjectOptionDialog(
            S4MSMStringId.MOD_SETTINGS_MENU,
            S4MSMStringId.CHOOSE_SETTINGS_TO_MODIFY,
            on_close=_on_close,
            mod_identity=self.mod_identity)

        available_menu_items = self._menu_item_registry.get_menu_items_available_for(
            source_sim_info, target=target)

        sorted_available_menu_items = sorted(available_menu_items,
                                             key=lambda mi: mi.identifier)

        def _on_chosen(_: str, chosen_menu_item: S4MSMMenuItem):
            return chosen_menu_item.show(source_sim_info,
                                         target=target,
                                         on_close=_reopen)

        self.log.debug('Adding menu items.')
        for menu_item in sorted_available_menu_items:
            mod_name_and_version = CommonLocalizationUtils.combine_localized_strings(
                (menu_item.mod_name, menu_item.mod_version),
                separator=CommonLocalizedStringSeparator.SPACE)
            description = CommonLocalizationUtils.combine_localized_strings(
                (menu_item.description, mod_name_and_version),
                separator=CommonLocalizedStringSeparator.
                SPACE_PARENTHESIS_SURROUNDED)
            title = CommonLocalizationUtils.combine_localized_strings(
                (menu_item.title, menu_item.mod_version),
                separator=CommonLocalizedStringSeparator.
                SPACE_PARENTHESIS_SURROUNDED)
            option_dialog.add_option(
                CommonDialogSelectOption(
                    menu_item.identifier,
                    menu_item,
                    CommonDialogOptionContext(
                        title,
                        description,
                        tooltip_text_identifier=menu_item.tooltip_text,
                        tooltip_tokens=(source_sim_info,
                                        target) if target is not None else
                        (source_sim_info, ),
                        icon=menu_item.icon),
                    on_chosen=_on_chosen))

        if not option_dialog.has_options():
            self.log.debug(
                f'No menu items were available for \'{source_sim_info}\' and \'{target}\'.'
            )
            return

        option_dialog.show(sim_info=source_sim_info, page=page)
示例#5
0
    def _open_outfit_parts_by(self, outfit_parts_by: _OutfitPartsBy, outfit_parts: Tuple[OCOutfitPart], on_close: Callable[[], None]):
        self.log.format_with_message('Opening outfit parts by', outfit_parts_by=outfit_parts_by)

        def _on_close() -> None:
            on_close()

        option_dialog = CommonChooseObjectOptionDialog(
            OCStringId.OC_CUSTOMIZE_OUTFIT_OC,
            0,
            on_close=_on_close,
            mod_identity=self.mod_identity
        )

        def _reopen_dialog() -> None:
            option_dialog.show(sim_info=self._sim_info, page=option_dialog.current_page)

        def _on_option_chosen(option_identifier: str, chosen: Tuple[OCOutfitPart]):
            self.log.debug('Opening Outfit Parts By: {}'.format(option_identifier))
            self._open_with_outfit_parts(chosen, on_close_callback=_reopen_dialog)

        def _no_outfit_parts_found() -> None:
            CommonOkDialog(
                OCStringId.OC_CUSTOMIZE_OUTFIT_OC,
                OCStringId.OC_NO_OUTFIT_PARTS_FOUND,
                mod_identity=self.mod_identity
            ).show(on_acknowledged=_on_close)

        if outfit_parts_by == _OutfitPartsBy.NONE:
            self.log.debug('outfit_parts_by was NONE')
            _no_outfit_parts_found()
            return

        self.log.format_with_message('Creating outfit parts by', outfit_parts_by=outfit_parts_by)
        if len(outfit_parts) == 0:
            self.log.debug('No outfit parts found!')
            _no_outfit_parts_found()
            return

        sorted_outfit_parts = sorted(outfit_parts, key=lambda op: op.raw_display_name)
        if not sorted_outfit_parts:
            self.log.debug('Failed to sort outfit parts by name')
            _no_outfit_parts_found()
            return

        self.log.format_with_message('Outfit parts sorted.', sorted_outfit_parts=sorted_outfit_parts)

        outfit_parts_by_value_dict = {}
        for outfit_part in sorted_outfit_parts:
            outfit_part: OCOutfitPart = outfit_part
            self.log.format_with_message('Looking at outfit part.', outfit_part=outfit_part)
            if not CommonCASUtils.is_cas_part_loaded(outfit_part.part_id):
                self.log.debug('Outfit part not loaded.')
                continue
            keys = self._get_outfit_part_key(outfit_part, outfit_parts_by=outfit_parts_by)
            if keys is None:
                self.log.debug('No key found.')
                continue
            for key in keys:
                str_key = str(key)
                by_value = outfit_parts_by_value_dict.get(str_key, list())
                by_value.append(outfit_part)
                outfit_parts_by_value_dict[str_key] = by_value
            self.log.debug('Outfit part loaded.')

        if len(outfit_parts_by_value_dict) == 0:
            self.log.format_with_message('No outfit parts found with outfit parts by!', outfit_parts_by=outfit_parts_by, outfit_parts_by_value_dict=outfit_parts_by_value_dict)
            self.log.debug('No outfit parts found!')
            _no_outfit_parts_found()
            return

        self.log.format_with_message('Finished filtering outfit parts.', outfit_parts_by_value_dict=outfit_parts_by_value_dict)

        sorted_keys = sorted(outfit_parts_by_value_dict.keys())
        self.log.format(sorted_keys=sorted_keys)
        for key in sorted_keys:
            self.log.format_with_message('Building key', key=key)
            outfit_parts_by_value: List[OCOutfitPart] = outfit_parts_by_value_dict[key]
            if len(outfit_parts_by_value) == 0:
                self.log.debug('No parts found in key.')
                continue
            outfit_parts_count = str(len(outfit_parts_by_value))
            self.log.format_with_message('Found outfit parts', count=outfit_parts_count)
            option_dialog.add_option(
                CommonDialogObjectOption(
                    key,
                    tuple(outfit_parts_by_value),
                    CommonDialogOptionContext(
                        key,
                        OCStringId.OC_OUTFIT_PARTS_COUNT,
                        description_tokens=(outfit_parts_count,),
                        icon=CommonIconUtils.load_arrow_navigate_into_icon()
                    ),
                    on_chosen=_on_option_chosen
                )
            )

        if not option_dialog.has_options():
            self.log.debug('No options found in dialog.')
            _no_outfit_parts_found()
            return

        self.log.debug('Showing dialog.')

        option_dialog.show(sim_info=self._sim_info)
示例#6
0
    def run(
        self,
        sim_info: SimInfo,
        on_completed: Callable[[bool],
                               None] = CommonFunctionUtils.noop) -> bool:
        def _reopen() -> None:
            self.run(sim_info, on_completed=on_completed)

        def _on_close() -> None:
            on_completed(False)

        @CommonExceptionHandler.catch_exceptions(self.mod_identity,
                                                 fallback_return=False)
        def _on_chosen(_buff_id: int, chosen_buff: Buff):
            if chosen_buff is None:
                on_completed(False)
                return

            def _on_yes_selected(_: Any):
                CommonBuffUtils.remove_buff(sim_info, _buff_id)
                # noinspection PyUnresolvedReferences
                CommonBasicNotification(
                    S4CMSimControlMenuStringId.REMOVED_BUFF_TITLE,
                    S4CMSimControlMenuStringId.REMOVED_BUFF_DESCRIPTION,
                    title_tokens=(chosen_buff.buff_name(sim_info),
                                  str(_buff_id)),
                    description_tokens=(
                        CommonSimUtils.get_sim_instance(sim_info),
                        chosen_buff.buff_name(sim_info), str(_buff_id),
                        CommonBuffUtils.get_buff_name(chosen_buff))).show(
                            icon=IconInfoData(obj_instance=CommonSimUtils.
                                              get_sim_instance(sim_info)))
                _reopen()

            def _on_no_selected(_: Any):
                _reopen()

            # noinspection PyUnresolvedReferences
            confirmation = CommonOkCancelDialog(
                S4CMStringId.CONFIRMATION,
                S4CMSimControlMenuStringId.
                ARE_YOU_SURE_YOU_WANT_TO_REMOVE_BUFF,
                description_tokens=(chosen_buff.buff_name(sim_info),
                                    str(_buff_id),
                                    CommonBuffUtils.get_buff_name(chosen_buff),
                                    CommonSimUtils.get_sim_instance(sim_info)),
                ok_text_identifier=S4CMStringId.YES,
                cancel_text_identifier=S4CMStringId.NO,
                mod_identity=self.mod_identity)
            confirmation.show(on_ok_selected=_on_yes_selected,
                              on_cancel_selected=_on_no_selected)

        option_dialog = CommonChooseObjectOptionDialog(
            S4CMSimControlMenuStringId.REMOVE_BUFFS,
            0,
            on_close=_on_close,
            mod_identity=self.mod_identity,
            per_page=20000)

        for buff in CommonBuffUtils.get_buffs(sim_info):
            buff: Buff = buff
            buff_id = CommonBuffUtils.get_buff_id(buff)
            if buff_id is None:
                self.log.format_with_message('Missing buff id for Buff.',
                                             buff=buff)
                continue
            try:
                # noinspection PyUnresolvedReferences
                display_name = buff.buff_name(sim_info)
                if display_name.hash == 0:
                    buff_name = CommonBuffUtils.get_buff_name(
                        buff) or 'Unknown Buff Name'
                    buff_name = buff_name[0].upper() + buff_name[1:]
                    # noinspection PyUnresolvedReferences
                    display_name = CommonLocalizationUtils.create_localized_string(
                        S4CMSimControlMenuStringId.STRING_SPACE_PAREN_STRING,
                        tokens=(buff_name, str(buff_id)))
                else:
                    # noinspection PyUnresolvedReferences
                    display_name = CommonLocalizationUtils.create_localized_string(
                        S4CMSimControlMenuStringId.STRING_SPACE_PAREN_STRING,
                        tokens=(display_name, str(buff_id)))
                # noinspection PyUnresolvedReferences
                description = CommonLocalizationUtils.create_localized_string(
                    buff.buff_description, tokens=(sim_info, ))
                # noinspection PyUnresolvedReferences
                icon = buff.icon or CommonIconUtils.load_question_mark_icon()
                # MISSING ICON Identifier
                _MISSING_IMAGE_ICON_ID = 3526464109639239417
                if icon.instance == 0 or icon.instance == _MISSING_IMAGE_ICON_ID:
                    icon = CommonIconUtils.load_question_mark_icon()
                option_dialog.add_option(
                    CommonDialogSelectOption(
                        buff_id,
                        buff,
                        CommonDialogOptionContext(
                            display_name,
                            description,
                            icon=icon,
                            is_enabled=self._is_buff_allowed_for_removal(
                                buff)),
                        on_chosen=_on_chosen))
            except Exception as ex:
                self.log.format_error_with_message(
                    'Failed to display buff.',
                    buff=buff,
                    buff_name=CommonBuffUtils.get_buff_name(buff),
                    buff_id=buff_id,
                    exception=ex)

        if not option_dialog.has_options():
            on_completed(False)
            return False
        option_dialog.show(sim_info=sim_info, sort_options=True)
        return True