Ejemplo n.º 1
0
    def get_hit_actions(
            self,
            skill_lv: int = None
    ) -> list[tuple[str, ActionComponentHasHitLabels]]:
        """
        Get a list of effective hitting actions in tuple ``(label name, action component)``.

        Specify ``skill_lv`` as ``None``, to get un-leveled hit actions.

        .. note::
            Each component contains hit label(s) which each of them corresponds to a hit attribute.
        """
        hit_actions: list[tuple[str, ActionComponentHasHitLabels]] = []

        # Sort hitting components by its starting time
        for action_hit in sorted(self._damaging_hits,
                                 key=lambda component: component.time_start):
            for hit_label in filter(
                    self.is_effective_label,
                    action_hit.hit_labels):  # Effective labels only
                hit_label_data = get_hit_label_data(hit_label)

                if (action_hit.use_same_component
                        or not action_hit.use_same_component
                        and hit_label_data.level == skill_lv):
                    hit_actions.append((make_hit_label(hit_label_data.original,
                                                       level=skill_lv) if
                                        skill_lv else hit_label, action_hit))

        return hit_actions
    def _init_combo_props(self, level: int, ability_ids: list[int]):
        # Get all possible pre-conditions
        pre_conditions: set[ConditionComposite] = {
            ConditionComposite(action_component.skill_pre_condition)
            for _, action_component in self.action_prefab.get_hit_actions(
                level) if action_component.skill_pre_condition not in
            PRE_CONDITIONS_TO_OMIT
        }

        for hit_attr_label, action_component in self.action_prefab.get_hit_actions(
                level):
            self._init_combo_props_single(hit_attr_label, action_component,
                                          pre_conditions)

            has_hit_attr_shift = get_ability_data_to_shift_hit_attr(
                ability_ids, self.asset_manager.asset_ability_data)
            if has_hit_attr_shift:
                self._init_combo_props_single(
                    make_hit_label(hit_attr_label, shifted=True),
                    action_component,
                    {
                        pre_cond_comp + Condition.SELF_PASSIVE_ENHANCED
                        for pre_cond_comp in pre_conditions
                    },
                    # Not found = passive enhancement inapplicable (not logically wrong)
                    do_nothing_on_not_found=True,
                )
Ejemplo n.º 3
0
    def _get_hit_data_hit_attr_shift(
        self,
        hit_data_cls: Type[T],
        hit_data_list: HitDataList,
        ability_ids: list[int],
    ) -> HitDataList:
        """Returns shifted hit data if any of the ability triggers hit attribute shift."""
        ability_data_hit_attr_shift = get_ability_data_to_shift_hit_attr(
            ability_ids, self._asset_ability)
        if not ability_data_hit_attr_shift:
            return []

        ret: HitDataList = []

        for hit_data in hit_data_list:
            hit_label_shifted = make_hit_label(hit_data.hit_attr.id,
                                               shifted=True)

            ability_data = hit_data.ability_data or []

            hit_attr = self._asset_hit_attr.get_data_by_id(hit_label_shifted)
            if not hit_attr:
                # Because the ability variant for hit attr shift does not have target action assigned,
                # skipping non-existed hit attribute is likely to mean "no enhanced hit attribute available"
                continue

            ret.append(
                hit_data_cls(hit_attr=hit_attr,
                             action_component=hit_data.action_component,
                             action_id=hit_data.action_id,
                             pre_condition_comp=hit_data.pre_condition_comp +
                             Condition.SELF_PASSIVE_ENHANCED,
                             ability_data=ability_data +
                             [ability_data_hit_attr_shift]))

        return ret
Ejemplo n.º 4
0
def test_make_hit_label_change_level_no_shift():
    hit_label = make_hit_label("S071_000_00_LV01", level=2)

    assert hit_label == "S071_000_00_LV02"
Ejemplo n.º 5
0
def test_make_hit_label_change_shift():
    hit_label = make_hit_label("S071_000_00_LV01", shifted=True)

    assert hit_label == "S071_000_00_HAS_LV01"
Ejemplo n.º 6
0
def test_make_hit_label_using_leveled_shifted():
    hit_label = make_hit_label("S071_000_00_HAS_LV01", level=2, shifted=False)

    assert hit_label == "S071_000_00_LV02"
Ejemplo n.º 7
0
def test_make_hit_label_leveled_shifted():
    hit_label = make_hit_label("S071_000_00", level=1, shifted=True)

    assert hit_label == "S071_000_00_HAS_LV01"
Ejemplo n.º 8
0
def test_make_hit_label_leveled_no_shift():
    hit_label = make_hit_label("S071_000_00", level=2)

    assert hit_label == "S071_000_00_LV02"
Ejemplo n.º 9
0
def test_make_hit_label_no_level_shifted():
    hit_label = make_hit_label("S071_000_00", shifted=True)

    assert hit_label == "S071_000_00_HAS"
Ejemplo n.º 10
0
def test_make_hit_label_no_level_no_shift():
    hit_label = make_hit_label("S071_000_00")

    assert hit_label == "S071_000_00"