Beispiel #1
0
    def conditions(self) -> list[Condition]:
        """
        Get the conditions for this action condition to be effective.

        If no conditions are required, return an empty list.

        If any of the conditions returned matches, then the action condition is considered effective.
        """
        if not self.target_limited_by_element:
            # Not limited to certain element, no condition
            return []

        return [
            ConditionCategories.target_element.convert_reversed(element)
            for element in Element.from_flag(self.elemental_target)
        ]
Beispiel #2
0
class SkillDataBase(Generic[HT, ET], ABC):
    """Base class for a single skill data."""

    asset_manager: "AssetManager"

    skill_hit_data: "SkillHitData"

    skill_data: SkillDataEntry = field(init=False)
    skill_id: int = field(init=False)
    hit_data_mtx: list[list[HT]] = field(init=False)
    sp_gradual_fill_pct: list[float] = field(init=False)

    possible_conditions: set[ConditionComposite] = field(
        init=False, default_factory=ConditionComposite)

    max_level: int = field(init=False)

    @final
    def _init_possible_conditions_pre_conditions(
            self) -> Optional[set[tuple[Condition, ...]]]:
        pre_conditions: set[tuple[Condition, ...]] = {
            tuple(hit_data.pre_condition_comp)
            for hit_data_lv in self.hit_data_mtx for hit_data in hit_data_lv
            if hit_data.pre_condition_comp
        }
        if pre_conditions:
            if any(
                    any(pre_condition in ConditionCategories.skill_addl_inputs
                        for pre_condition in pre_condition_tuple)
                    for pre_condition_tuple in pre_conditions):
                # Pre-condition has additional inputs condition,
                # no-additional-input (additional input = 0) condition is possible
                # Appears in Lathna S1 (`105505021`), Ramona S1 (`104501011`)
                pre_conditions.add((Condition.ADDL_INPUT_0, ))

            if any(
                    any(pre_condition in
                        ConditionCategories.skill_action_cancel
                        for pre_condition in pre_condition_tuple)
                    for pre_condition_tuple in pre_conditions):
                # Pre-condition has action cancelling condition,
                # no cancelling (no condition) is possible
                # Appears in handle Formal Joachim S1 (`109503011`)
                pre_conditions.add(())

            if any(
                    any(pre_condition in ConditionCategories.trigger
                        for pre_condition in pre_condition_tuple)
                    for pre_condition_tuple in pre_conditions):
                # Pre-condition has trigger,
                # Triggering conditions are not always happening
                pre_conditions.add(())

            if any(
                    any(pre_condition in
                        ConditionCategories.skill_action_misc_var
                        for pre_condition in pre_condition_tuple)
                    for pre_condition_tuple in pre_conditions):
                # Skill has some variants. However, the skill can be used without triggering the variants.
                # Appears in Nobunaga S1 (`102501031`), Yoshitsune S1 (`109502021`)
                pre_conditions.add(())

            if any(Condition.SELF_PASSIVE_ENHANCED in pre_condition_tuple
                   for pre_condition_tuple in pre_conditions):
                # Pre-condition has passive enhancement, this is not always happening
                pre_conditions.add(())

            return pre_conditions

        return None

    @final
    def _init_possible_conditions_base_elems(self):
        cond_elems: list[set[tuple[Condition, ...]]] = []

        # Get all possible pre-conditions as a condition element
        if pre_conditions := self._init_possible_conditions_pre_conditions():
            cond_elems.append(pre_conditions)

        # Get the elemental restriction from the action conditions if any
        action_conds_elem_flag: set[ElementFlag] = set()
        for hit_data_lv in self.hit_data_mtx:
            for hit_data in hit_data_lv:
                if not hit_data.action_condition_id:
                    continue  # No action condition

                action_conds_elem_flag.add(
                    self.asset_manager.asset_action_cond.get_data_by_id(
                        hit_data.action_condition_id).elemental_target)
        if action_conds_elem_flag:
            # Elemental action condition available

            # Convert discovered elemental flags to elements
            action_conds_elem: set[Element] = set()
            for elem_flag in action_conds_elem_flag:
                action_conds_elem.update(Element.from_flag(elem_flag))

            # Convert elements to conditions and add it
            # - Dummy condition tuple for pre-condition of none, meaning other elements
            cond_elems.append({(
                ConditionCategories.target_element.convert_reversed(elem), )
                               for elem in action_conds_elem}
                              | {()})

        return cond_elems