def attribute_match_text(self, ls):
        skill_text = self.matching_n_or_more_attr(
            ls.match_attributes,
            ls.min_attr,
            is_range=ls.max_attr > ls.min_attr)
        skill_text += 'で' + self.fmt_stats_type_attr_bonus(ls,
                                                           reduce_join_txt='、',
                                                           skip_attr_all=True,
                                                           atk=ls.min_atk,
                                                           rcv=ls.min_rcv)

        if ls.atk > ls.min_atk:
            skill_text += '、'
            if ls.match_attributes == [0, 1, 2, 3, 4, 5]:
                skill_text += '最大5色+回復で{}倍'.format(fmt_mult(ls.atk))
            elif ls.max_attr < 5 and (len(ls.match_attributes) < 5
                                      or 5 in ls.match_attributes):
                skill_text += '最大{}色で{}倍'.format(ls.max_attr, fmt_mult(ls.atk))
            else:
                if ls.match_attributes == [0, 1, 2, 3, 4]:
                    skill_text += '最大{}色で{}倍'.format(ls.max_attr,
                                                     fmt_mult(ls.atk))
                elif ls.match_attributes == [0, 1, 2, 3, 4, 5]:
                    skill_text += '最大{}色({}色+回復)で{}倍'.format(
                        ls.max_attr, ls.max_attr - 1, fmt_mult(ls.atk))
                elif len(ls.match_attributes) > ls.max_attr:
                    skill_text += '{}個ところまで{}倍'.format(str(ls.max_attr),
                                                       fmt_mult(ls.atk))
                else:
                    skill_text += '同時攻撃で{}倍'.format(
                        self.attributes_to_str(ls.match_attributes))
        return skill_text + '。'
 def counter_attack_text(self, ls):
     attribute = self.ATTRIBUTES[ls.attributes[0]]
     multiplier = fmt_mult(ls.multiplier)
     if ls.chance == 1:
         return '攻撃力x{}倍の{}属性で反撃。'.format(multiplier, attribute)
     return '{}%の確率で攻撃力x{}倍の{}属性で反撃。'.format(fmt_mult(ls.chance * 100),
                                             multiplier, attribute)
 def orb_remain_text(self, ls):
     skill_text = self.fmt_stats_type_attr_bonus(ls, atk=ls.min_atk)
     if ls.base_atk in [0, 1]:
         return skill_text
     if skill_text:
         skill_text += '。'
     skill_text += 'パズル後の残りドロップ数が{}個'.format(ls.orb_count)
     if ls.bonus_atk != 0:
         skill_text += 'で攻撃力{}倍、0個のところまで{}倍'.format(
             fmt_mult(ls.base_atk), fmt_mult(ls.max_bonus_atk))
     else:
         skill_text += '以下で攻撃力が{}倍'.format(fmt_mult(ls.base_atk))
     return skill_text + '。'
    def combo_match_text(self, ls):
        if ls.min_combos == 0:
            return ''

        skill_text = ''
        min_atk = ls.min_atk
        min_rcv = ls.min_rcv
        min_combos = ls.min_combos
        if (min_atk == 1 and ls.atk != 1) or (min_rcv == 1 and ls.rcv != 1):
            skill_text = '{}コンボ以上で'.format(min_combos)
            skill_text = self.fmt_stats_type_attr_bonus(
                ls, reduce_join_txt='、', atk=min_atk, rcv=min_rcv) + '。'
            min_combos += 1
            min_atk += ls.atk_step
            min_rcv += ls.rcv_step

        skill_text += '{}コンボ以上で'.format(min_combos)
        skill_text += self.fmt_stats_type_attr_bonus(ls,
                                                     reduce_join_txt='、',
                                                     atk=min_atk,
                                                     rcv=min_rcv)
        if min_combos != ls.max_combos and ls.max_combos:
            skill_text += '、最大{}コンボで{}倍'.format(ls.max_combos,
                                                fmt_mult(ls.atk))
        return skill_text + '。'
 def random_shield_threshold_text(self, ls):
     threshold_text = self.fmt_stats_type_attr_bonus(ls, skip_attr_all=True)
     threshold_text += self.threshold_hp(ls.threshold, ls.above)
     if ls.chance == 1:
         return threshold_text + '。'
     else:
         chance = fmt_mult(ls.chance * 100)
         return '{}%の確率で{}。'.format(chance, threshold_text).lower()
    def scaling_attribute_match_text(self, ls):
        min_atk = ls.min_atk
        min_attr = ls.min_attr

        if min_atk < ls.atk:
            if ls.min_atk == 1:
                min_atk = 1 + (ls.atk - ls.min_atk) / (ls.max_attr -
                                                       ls.min_attr)
                min_attr += 1
        else:
            return self.attribute_match_text(ls)

        skill_text = self.matching_n_or_more_attr(ls.match_attributes,
                                                  ls.min_attr)
        skill_text += 'で' + self.fmt_stats_type_attr_bonus(
            ls, reduce_join_txt='、', atk=1, rcv=1) + '。'

        skill_text += self.matching_n_or_more_attr(
            ls.match_attributes, min_attr, is_range=ls.max_attr > min_attr)
        skill_text += 'で' + self.fmt_stats_type_attr_bonus(
            ls, reduce_join_txt='、', atk=min_atk, shield=0)

        if ls.atk > ls.min_atk:
            skill_text += '、'
            if ls.match_attributes == [0, 1, 2, 3, 4, 5]:
                skill_text += '最大5色+回復で{}倍'.format(fmt_mult(ls.atk))
            elif ls.max_attr < 5 and (len(ls.match_attributes) < 5
                                      or 5 in ls.match_attributes):
                skill_text += '最大{}色で{}倍'.format(ls.max_attr, fmt_mult(ls.atk))
            else:
                if ls.match_attributes == [0, 1, 2, 3, 4]:
                    skill_text += '最大{}色で{}倍'.format(ls.max_attr,
                                                     fmt_mult(ls.atk))
                elif ls.match_attributes == [0, 1, 2, 3, 4, 5]:
                    skill_text += '最大{}色({}色+回復)で{}倍'.format(
                        ls.max_attr, ls.max_attr - 1, fmt_mult(ls.atk))
                elif len(ls.match_attributes) > ls.max_attr:
                    skill_text += '{}個ところまで{}倍'.format(str(ls.max_attr),
                                                       fmt_mult(ls.atk))
                else:
                    skill_text += '同時攻撃で{}倍'.format(
                        self.attributes_to_str(ls.match_attributes))
        return skill_text + '。'
    def multi_attribute_match_text(self, ls):
        if not ls.match_attributes:
            return ''

        stat_text = self.fmt_stats_type_attr_bonus(ls,
                                                   reduce_join_txt='、',
                                                   skip_attr_all=True,
                                                   atk=ls.min_atk,
                                                   rcv=ls.min_rcv)

        if len(set(ls.match_attributes)) == 1:
            skill_text = '{}の{}コンボ'.format(
                self.ATTRIBUTES[ls.match_attributes[0]], ls.min_match)
            if not len(ls.match_attributes) != ls.min_match:
                skill_text += '以上'
            skill_text += 'で{}'.format(stat_text)
            if len(ls.match_attributes) != ls.min_match:
                skill_text += '、最大{}コンボで{}倍'.format(len(ls.match_attributes),
                                                    fmt_mult(ls.atk))
        else:
            skill_text = '{}'.format(
                self.attributes_to_str(ls.match_attributes[:ls.min_match],
                                       concat='、'))
            if len(ls.match_attributes) > ls.min_match:
                if ls.min_match == 1:
                    skill_text += 'が{}ドロップを消すと{}'.format(
                        self.attributes_to_str(ls.match_attributes[1:]),
                        stat_text)
                else:
                    skill_text += '({})のコンボ消すと{}'.format(
                        self.attributes_to_str(ls.match_attributes[1:]),
                        stat_text)
            else:
                skill_text += 'の同時攻撃で{}'.format(stat_text)
            if ls.atk > ls.min_atk:
                skill_text += 'の、最大{}で{}倍'.format(
                    self.attributes_to_str(ls.match_attributes),
                    fmt_mult(ls.atk))
        return skill_text + '。'
 def mass_match_text(self, ls):
     stat_text = self.fmt_stats_type_attr_bonus(ls,
                                                reduce_join_txt='、',
                                                skip_attr_all=True,
                                                atk=ls.min_atk,
                                                rcv=ls.min_rcv)
     skill_text = 'を{}個{}つなげて消すと{}'.format(
         ls.min_count, '以上' if ls.max_count != ls.min_count else '',
         stat_text)
     attr_text = self.fmt_multi_attr(ls.match_attributes) or 'ドロップ'
     skill_text = attr_text + skill_text
     if ls.max_count != ls.min_count and ls.max_count > 0:
         skill_text += '、最大{}個で{}倍'.format(ls.max_count, fmt_mult(ls.atk))
     return skill_text + '。'
    def dual_passive_stat_text(self, ls):
        skill_text = [
            self.fmt_stats_type_attr_bonus(None,
                                           attributes=ls.attributes_1,
                                           types=ls.types_1,
                                           hp=ls.hp_1,
                                           atk=ls.atk_1,
                                           rcv=ls.rcv_1),
            self.fmt_stats_type_attr_bonus(None,
                                           attributes=ls.attributes_2,
                                           types=ls.types_2,
                                           hp=ls.hp_2,
                                           atk=ls.atk_2,
                                           rcv=ls.rcv_2)
        ]

        if ls.atk_1 != 1 and ls.atk_2 != 1 and ls.types_1 == ls.types_2 == []:
            skill_text.append('両方の属性を持つ場合、攻撃力が{}倍'.format(fmt_mult(ls.atk)))

        return self.concat_list_semicolons(skill_text) + '。'
    def sized_blob(self, ls):
        if 0 < len(ls.attributes) < 10:
            attrs = self.attributes_to_str(ls.attributes,
                                           concat='か').replace('、', 'か')
        else:
            attrs = 'ドロップ'
        condition = '{}の{}個消し1個につき'.format(attrs, ls.blob_size)

        effects = []

        if ls.extra_combos:
            effects.append('{}コンボ加算'.format(ls.extra_combos))
        if ls.bonus_damage:
            effects.append('固定{}ダメージ加算'.format(self.big_number(
                ls.bonus_damage)))
        if ls.atk:
            effects.append('攻撃力が{}倍'.format(fmt_mult(ls.atk)))
        if ls.shield:
            effects.append(self.fmt_reduct_text(ls.shield))

        return condition + '、'.join(effects) + '。'
 def resolve_text(self, ls):
     return 'HPが0になる攻撃を受けてもふんばることがある(HPが{}%以上)。'.format(
         fmt_mult(ls.threshold * 100))
 def heal_on_text(self, ls):
     return 'ドロップ消した時、回復力x{}倍のHPを回復。'.format(fmt_mult(ls.multiplier))
 def after_attack_text(self, ls):
     return 'ドロップ消した時、攻撃力x{}倍の追い打ち。'.format(fmt_mult(ls.multiplier))
 def coin_drop_text(self, ls):
     return '入手コインx{}倍。'.format(fmt_mult(ls.multiplier))
 def color_cross_text(self, ls):
     atk = fmt_mult(ls.multiplier)
     attrs = self.attributes_to_str(ls.attributes,
                                    concat='か').replace('、', 'か')
     return '{}の5個十字消し1個につき攻撃力が{}倍。'.format(attrs, atk)
 def heart_tpa_stats_text(self, ls):
     return '回復ドロップを4個つなげ消すと回復力が{}倍。'.format(fmt_mult(ls.rcv))
 def egg_drop_text(self, ls):
     return '卵ドロップ率x{}倍。'.format(fmt_mult(ls.multiplier))
 def passive_stats_type_atk_all_hp_text(self, ls):
     skill_text = '総HPが{}%減少するが、{}タイプの攻撃力が{}倍。'.format(
         fmt_mult((1 - ls.hp) * 100), self.typing_to_str(ls.types),
         fmt_mult(ls.atk))
     return skill_text
 def rank_exp_rate_text(self, ls):
     return 'ランク経験値x{}倍。'.format(fmt_mult(ls.multiplier))
 def bonus_time_text(self, ls):
     skill_text = [self.fmt_stats_type_attr_bonus(ls)]
     if ls.time:
         skill_text.append('ドロップ操作時間を{}秒延長'.format(fmt_mult(ls.time)))
     return self.concat_list_semicolons(skill_text) + '。'
 def five_orb_one_enhance_text(self, ls):
     return '強化ドロップを含めてを5個消した属性の攻撃力が{}倍。'.format(fmt_mult(ls.atk))
 def exact_combo_text(self, ls):
     return '{}コンボちょっとで攻撃力が{}倍。'.format(ls.combos, fmt_mult(ls.atk))