%%% -------------------------------------------------------
%%% @author huangyongxing@yeah.net
%%% @doc 提供#attr{}、[{AttrId, AttrVal}, ...]、#{}的转换接口
%%% 由工具模块 attr_tool 根据#attr{}结构生成
%%% 隐含的规则是，#attr{}的字段，对应属性的宏必须是字段名的大写
%%% -------------------------------------------------------
-module(attr_conv).
-export([
        to_attr_record/1
        ,to_attr_tuple_list/1
        ,to_attr_map/1
        ,set_attr_val/2
        ,attr_list_filter/1
        ,get_attr_index/1
        ,get_attr_id/1
        ,attr_plus/2
        ,attr_minus/2
    ]).
-include("common.hrl").
-include("attr.hrl").

%% 属性最大索引编号（ 即size(#attr{}) ）
-define(MAX_ATTR_IDX, 66).

%% 转换为#attr{}
-spec to_attr_record(AttrData) -> Attr when
    AttrData :: [{AttrId, AttrVal}] | #attr{} | AttrMap,
    AttrMap :: map(),
    AttrId :: non_neg_integer(), AttrVal :: number(),
    Attr :: #attr{}.
to_attr_record(AttrData) ->
    if
        is_list(AttrData) ->
            lists:foldl(fun set_attr_val/2, #attr{}, AttrData);
        is_map(AttrData) ->
            maps:fold(fun set_attr_val/2, #attr{}, AttrData);
        true ->
            AttrData
    end.

%% 转换为列表[{AttrId, AttrVal},...]
-spec to_attr_tuple_list(AttrData) -> AttrTupleList when
    AttrData :: [{AttrId, AttrVal}] | #attr{} | AttrMap,
    AttrMap :: map(),
    AttrId :: non_neg_integer(), AttrVal :: number(),
    AttrTupleList :: [{AttrId, AttrVal}].
to_attr_tuple_list(Attr) when is_map(Attr) ->
    maps:to_list(Attr);
to_attr_tuple_list(Attr = #attr{}) ->
    [_ | AttrValList] = tuple_to_list(Attr),
    F = fun(AttrVal, {Index, Acc}) ->
            case AttrVal > 0 of
                true  ->
                    AttrId = get_attr_id(Index),
                    case AttrId > 0 of
                        true  -> {Index + 1, [{AttrId, AttrVal} | Acc]};
                        false ->
                            %% 这里意味着attr_conv需要重新生成，可能新增了字段，无法映射到AttrId
                            ?ERR("error attr index: ~w, please execute attr_tool:c().", [Index]),
                            {Index + 1, Acc}
                    end;
                false ->
                    {Index + 1, Acc}
            end
    end,
    {_, AttrList} = lists:foldl(F, {2, []}, AttrValList),
    AttrList;
to_attr_tuple_list(AttrList) when is_list(AttrList) ->
    AttrList.

%% 转换为map格式的attr
-spec to_attr_map(AttrData) -> AttrMap when
    AttrData :: [{AttrId, AttrVal}] | #attr{} | AttrMap,
    AttrMap :: map(),
    AttrId :: non_neg_integer(), AttrVal :: number().
to_attr_map(AttrList) when is_list(AttrList) ->
    maps:from_list(AttrList);
to_attr_map(Attr = #attr{}) ->
    AttrList = to_attr_tuple_list(Attr),
    maps:from_list(AttrList);
to_attr_map(AttrMap) when is_map(AttrMap) ->
    AttrMap.

%% 设定#attr{}某属性id对应的属性值
-spec set_attr_val({AttrId, AttrVal}, Attr) -> NewAttr when
    AttrId :: non_neg_integer(), AttrVal :: number(),
    Attr :: #attr{},
    NewAttr :: #attr{}.
set_attr_val({AttrId, AttrVal}, Attr) ->
    Index = get_attr_index(AttrId),
    if
        Index > ?MAX_ATTR_IDX ->
            %% 可能删除了某些字段，意味着需要重新生成attr_conv
            ?ERR("error attr index:~w, please execute attr_tool:c().", [Index]),
            throw({<<"error_attr_index">>, Index});
        Index > 0 ->
            setelement(Index, Attr, AttrVal);
        true ->
            %% 由于原属性设计中的AttrId存在一些超出#attr{}范围的属性，这里
            %% 无法判定一定是出错，有可能是原设计逻辑中需要忽略的属性，所以不打印日志
            %% ?INFO("error attr id or virtual attr id:~w", [AttrId]),
            Attr
    end.

%% 只保留#attr{}中的属性
attr_list_filter(AttrList) ->
    [{AttrId, AttrVal} || {AttrId, AttrVal} <- AttrList, AttrId =< ?MAX_ATTR_IDX].

get_attr_index(?ATT) -> 2;
get_attr_index(?HP) -> 3;
get_attr_index(?DEF) -> 4;
get_attr_index(?HIT) -> 5;
get_attr_index(?DODGE) -> 6;
get_attr_index(?CRIT) -> 7;
get_attr_index(?TEN) -> 8;
get_attr_index(?FINAL_HURT_ADD) -> 9;
get_attr_index(?FINAL_HURT_DEL) -> 10;
get_attr_index(?HP_RESUME) -> 11;
get_attr_index(?HURT_ADD_RATIO) -> 12;
get_attr_index(?HURT_DEL_RATIO) -> 13;
get_attr_index(?HIT_RATIO) -> 14;
get_attr_index(?DODGE_RATIO) -> 15;
get_attr_index(?CRIT_RATIO) -> 16;
get_attr_index(?UNCRIT_RATIO) -> 17;
get_attr_index(?CRIT_HURT_ADD_RATIO) -> 18;
get_attr_index(?CRIT_HURT_DEL_RATIO) -> 19;
get_attr_index(?HEART_RATIO) -> 20;
get_attr_index(?HEART_RESIST_RATIO) -> 21;
get_attr_index(?HEART_ADD_HURT) -> 22;
get_attr_index(?HEART_DEL_HURT) -> 23;
get_attr_index(?STAB_RATIO) -> 24;
get_attr_index(?PARRY_RATIO) -> 25;
get_attr_index(?PVP_HURT_ADD_RATIO) -> 26;
get_attr_index(?PVP_HURT_DEL_RATIO) -> 27;
get_attr_index(?SKILL_HURT_ADD_RATIO) -> 28;
get_attr_index(?SKILL_HURT_DEL_RATIO) -> 29;
get_attr_index(?HP_RESUME_RATIO) -> 30;
get_attr_index(?ICE_HURT) -> 31;
get_attr_index(?ICE_DEF) -> 32;
get_attr_index(?THUNDER_HURT) -> 33;
get_attr_index(?THUNDER_DEF) -> 34;
get_attr_index(?FIRE_HURT) -> 35;
get_attr_index(?FIRE_DEF) -> 36;
get_attr_index(?WIND_HURT) -> 37;
get_attr_index(?WIND_DEF) -> 38;
get_attr_index(?BOSS_HURT_ADD_RATIO) -> 39;
get_attr_index(?BOSS_HURT_DEL_RATIO) -> 40;
get_attr_index(?MON_HURT_ADD_RATIO) -> 41;
get_attr_index(?MON_HURT_DEL_RATIO) -> 42;
get_attr_index(?SUCK_BLOOD) -> 43;
get_attr_index(?ATT_ADD_RATIO) -> 44;
get_attr_index(?HP_ADD_RATIO) -> 45;
get_attr_index(?DEF_ADD_RATIO) -> 46;
get_attr_index(?HIT_ADD_RATIO) -> 47;
get_attr_index(?DODGE_ADD_RATIO) -> 48;
get_attr_index(?CRIT_ADD_RATIO) -> 49;
get_attr_index(?TEN_ADD_RATIO) -> 50;
get_attr_index(?FINAL_HURT_ADD_RATIO) -> 51;
get_attr_index(?FINAL_HURT_DEL_RATIO) -> 52;
get_attr_index(?SUCK_BLOOD_ADD) -> 53;
get_attr_index(?SUCK_BLOOD_MINUS) -> 54;
get_attr_index(?SPEED) -> 55;
get_attr_index(?EXP_ADD_RATIO) -> 56;
get_attr_index(?EXP_DROP_ADD_RATIO) -> 57;
get_attr_index(?SPEED_ADD_RATIO) -> 58;
get_attr_index(?ICE_HURT_ADD_RATIO) -> 59;
get_attr_index(?ICE_DEF_ADD_RATIO) -> 60;
get_attr_index(?THUNDER_HURT_ADD_RATIO) -> 61;
get_attr_index(?THUNDER_DEF_ADD_RATIO) -> 62;
get_attr_index(?FIRE_HURT_ADD_RATIO) -> 63;
get_attr_index(?FIRE_DEF_ADD_RATIO) -> 64;
get_attr_index(?WIND_HURT_ADD_RATIO) -> 65;
get_attr_index(?WIND_DEF_ADD_RATIO) -> 66;
get_attr_index(_AttrId) -> 0.

get_attr_id(2) -> ?ATT;
get_attr_id(3) -> ?HP;
get_attr_id(4) -> ?DEF;
get_attr_id(5) -> ?HIT;
get_attr_id(6) -> ?DODGE;
get_attr_id(7) -> ?CRIT;
get_attr_id(8) -> ?TEN;
get_attr_id(9) -> ?FINAL_HURT_ADD;
get_attr_id(10) -> ?FINAL_HURT_DEL;
get_attr_id(11) -> ?HP_RESUME;
get_attr_id(12) -> ?HURT_ADD_RATIO;
get_attr_id(13) -> ?HURT_DEL_RATIO;
get_attr_id(14) -> ?HIT_RATIO;
get_attr_id(15) -> ?DODGE_RATIO;
get_attr_id(16) -> ?CRIT_RATIO;
get_attr_id(17) -> ?UNCRIT_RATIO;
get_attr_id(18) -> ?CRIT_HURT_ADD_RATIO;
get_attr_id(19) -> ?CRIT_HURT_DEL_RATIO;
get_attr_id(20) -> ?HEART_RATIO;
get_attr_id(21) -> ?HEART_RESIST_RATIO;
get_attr_id(22) -> ?HEART_ADD_HURT;
get_attr_id(23) -> ?HEART_DEL_HURT;
get_attr_id(24) -> ?STAB_RATIO;
get_attr_id(25) -> ?PARRY_RATIO;
get_attr_id(26) -> ?PVP_HURT_ADD_RATIO;
get_attr_id(27) -> ?PVP_HURT_DEL_RATIO;
get_attr_id(28) -> ?SKILL_HURT_ADD_RATIO;
get_attr_id(29) -> ?SKILL_HURT_DEL_RATIO;
get_attr_id(30) -> ?HP_RESUME_RATIO;
get_attr_id(31) -> ?ICE_HURT;
get_attr_id(32) -> ?ICE_DEF;
get_attr_id(33) -> ?THUNDER_HURT;
get_attr_id(34) -> ?THUNDER_DEF;
get_attr_id(35) -> ?FIRE_HURT;
get_attr_id(36) -> ?FIRE_DEF;
get_attr_id(37) -> ?WIND_HURT;
get_attr_id(38) -> ?WIND_DEF;
get_attr_id(39) -> ?BOSS_HURT_ADD_RATIO;
get_attr_id(40) -> ?BOSS_HURT_DEL_RATIO;
get_attr_id(41) -> ?MON_HURT_ADD_RATIO;
get_attr_id(42) -> ?MON_HURT_DEL_RATIO;
get_attr_id(43) -> ?SUCK_BLOOD;
get_attr_id(44) -> ?ATT_ADD_RATIO;
get_attr_id(45) -> ?HP_ADD_RATIO;
get_attr_id(46) -> ?DEF_ADD_RATIO;
get_attr_id(47) -> ?HIT_ADD_RATIO;
get_attr_id(48) -> ?DODGE_ADD_RATIO;
get_attr_id(49) -> ?CRIT_ADD_RATIO;
get_attr_id(50) -> ?TEN_ADD_RATIO;
get_attr_id(51) -> ?FINAL_HURT_ADD_RATIO;
get_attr_id(52) -> ?FINAL_HURT_DEL_RATIO;
get_attr_id(53) -> ?SUCK_BLOOD_ADD;
get_attr_id(54) -> ?SUCK_BLOOD_MINUS;
get_attr_id(55) -> ?SPEED;
get_attr_id(56) -> ?EXP_ADD_RATIO;
get_attr_id(57) -> ?EXP_DROP_ADD_RATIO;
get_attr_id(58) -> ?SPEED_ADD_RATIO;
get_attr_id(59) -> ?ICE_HURT_ADD_RATIO;
get_attr_id(60) -> ?ICE_DEF_ADD_RATIO;
get_attr_id(61) -> ?THUNDER_HURT_ADD_RATIO;
get_attr_id(62) -> ?THUNDER_DEF_ADD_RATIO;
get_attr_id(63) -> ?FIRE_HURT_ADD_RATIO;
get_attr_id(64) -> ?FIRE_DEF_ADD_RATIO;
get_attr_id(65) -> ?WIND_HURT_ADD_RATIO;
get_attr_id(66) -> ?WIND_DEF_ADD_RATIO;
get_attr_id(_AttrIndex) -> 0.

%% 属性相加及相减的操作函数
%% 不调用util:record_plus/2及util:record_minus/2，直接匹配后操作会更省内存（约为1/4内存开销，但运算速度相当）

attr_plus(AttrA, AttrB) ->
    #attr{
        att = AttA, hp = HpA, def = DefA, hit = HitA, dodge = DodgeA, crit = CritA, ten = TenA, final_hurt_add = FinalHurtAddA, final_hurt_del = FinalHurtDelA, hp_resume = HpResumeA, hurt_add_ratio = HurtAddRatioA, hurt_del_ratio = HurtDelRatioA, hit_ratio = HitRatioA, dodge_ratio = DodgeRatioA, crit_ratio = CritRatioA, uncrit_ratio = UncritRatioA, crit_hurt_add_ratio = CritHurtAddRatioA, crit_hurt_del_ratio = CritHurtDelRatioA, heart_ratio = HeartRatioA, heart_resist_ratio = HeartResistRatioA, heart_add_hurt = HeartAddHurtA, heart_del_hurt = HeartDelHurtA, stab_ratio = StabRatioA, parry_ratio = ParryRatioA, pvp_hurt_add_ratio = PvpHurtAddRatioA, pvp_hurt_del_ratio = PvpHurtDelRatioA, skill_hurt_add_ratio = SkillHurtAddRatioA, skill_hurt_del_ratio = SkillHurtDelRatioA, hp_resume_ratio = HpResumeRatioA, ice_hurt = IceHurtA, ice_def = IceDefA, thunder_hurt = ThunderHurtA, thunder_def = ThunderDefA, fire_hurt = FireHurtA, fire_def = FireDefA, wind_hurt = WindHurtA, wind_def = WindDefA, boss_hurt_add_ratio = BossHurtAddRatioA, boss_hurt_del_ratio = BossHurtDelRatioA, mon_hurt_add_ratio = MonHurtAddRatioA, mon_hurt_del_ratio = MonHurtDelRatioA, suck_blood = SuckBloodA, att_add_ratio = AttAddRatioA, hp_add_ratio = HpAddRatioA, def_add_ratio = DefAddRatioA, hit_add_ratio = HitAddRatioA, dodge_add_ratio = DodgeAddRatioA, crit_add_ratio = CritAddRatioA, ten_add_ratio = TenAddRatioA, final_hurt_add_ratio = FinalHurtAddRatioA, final_hurt_del_ratio = FinalHurtDelRatioA, suck_blood_add = SuckBloodAddA, suck_blood_minus = SuckBloodMinusA, speed = SpeedA, exp_add_ratio = ExpAddRatioA, exp_drop_add_ratio = ExpDropAddRatioA, speed_add_ratio = SpeedAddRatioA, ice_hurt_add_ratio = IceHurtAddRatioA, ice_def_add_ratio = IceDefAddRatioA, thunder_hurt_add_ratio = ThunderHurtAddRatioA, thunder_def_add_ratio = ThunderDefAddRatioA, fire_hurt_add_ratio = FireHurtAddRatioA, fire_def_add_ratio = FireDefAddRatioA, wind_hurt_add_ratio = WindHurtAddRatioA, wind_def_add_ratio = WindDefAddRatioA
    } = AttrA,
    #attr{
        att = AttB, hp = HpB, def = DefB, hit = HitB, dodge = DodgeB, crit = CritB, ten = TenB, final_hurt_add = FinalHurtAddB, final_hurt_del = FinalHurtDelB, hp_resume = HpResumeB, hurt_add_ratio = HurtAddRatioB, hurt_del_ratio = HurtDelRatioB, hit_ratio = HitRatioB, dodge_ratio = DodgeRatioB, crit_ratio = CritRatioB, uncrit_ratio = UncritRatioB, crit_hurt_add_ratio = CritHurtAddRatioB, crit_hurt_del_ratio = CritHurtDelRatioB, heart_ratio = HeartRatioB, heart_resist_ratio = HeartResistRatioB, heart_add_hurt = HeartAddHurtB, heart_del_hurt = HeartDelHurtB, stab_ratio = StabRatioB, parry_ratio = ParryRatioB, pvp_hurt_add_ratio = PvpHurtAddRatioB, pvp_hurt_del_ratio = PvpHurtDelRatioB, skill_hurt_add_ratio = SkillHurtAddRatioB, skill_hurt_del_ratio = SkillHurtDelRatioB, hp_resume_ratio = HpResumeRatioB, ice_hurt = IceHurtB, ice_def = IceDefB, thunder_hurt = ThunderHurtB, thunder_def = ThunderDefB, fire_hurt = FireHurtB, fire_def = FireDefB, wind_hurt = WindHurtB, wind_def = WindDefB, boss_hurt_add_ratio = BossHurtAddRatioB, boss_hurt_del_ratio = BossHurtDelRatioB, mon_hurt_add_ratio = MonHurtAddRatioB, mon_hurt_del_ratio = MonHurtDelRatioB, suck_blood = SuckBloodB, att_add_ratio = AttAddRatioB, hp_add_ratio = HpAddRatioB, def_add_ratio = DefAddRatioB, hit_add_ratio = HitAddRatioB, dodge_add_ratio = DodgeAddRatioB, crit_add_ratio = CritAddRatioB, ten_add_ratio = TenAddRatioB, final_hurt_add_ratio = FinalHurtAddRatioB, final_hurt_del_ratio = FinalHurtDelRatioB, suck_blood_add = SuckBloodAddB, suck_blood_minus = SuckBloodMinusB, speed = SpeedB, exp_add_ratio = ExpAddRatioB, exp_drop_add_ratio = ExpDropAddRatioB, speed_add_ratio = SpeedAddRatioB, ice_hurt_add_ratio = IceHurtAddRatioB, ice_def_add_ratio = IceDefAddRatioB, thunder_hurt_add_ratio = ThunderHurtAddRatioB, thunder_def_add_ratio = ThunderDefAddRatioB, fire_hurt_add_ratio = FireHurtAddRatioB, fire_def_add_ratio = FireDefAddRatioB, wind_hurt_add_ratio = WindHurtAddRatioB, wind_def_add_ratio = WindDefAddRatioB
    } = AttrB,
    #attr{
        att = AttA + AttB, hp = HpA + HpB, def = DefA + DefB, hit = HitA + HitB, dodge = DodgeA + DodgeB, crit = CritA + CritB, ten = TenA + TenB, final_hurt_add = FinalHurtAddA + FinalHurtAddB, final_hurt_del = FinalHurtDelA + FinalHurtDelB, hp_resume = HpResumeA + HpResumeB, hurt_add_ratio = HurtAddRatioA + HurtAddRatioB, hurt_del_ratio = HurtDelRatioA + HurtDelRatioB, hit_ratio = HitRatioA + HitRatioB, dodge_ratio = DodgeRatioA + DodgeRatioB, crit_ratio = CritRatioA + CritRatioB, uncrit_ratio = UncritRatioA + UncritRatioB, crit_hurt_add_ratio = CritHurtAddRatioA + CritHurtAddRatioB, crit_hurt_del_ratio = CritHurtDelRatioA + CritHurtDelRatioB, heart_ratio = HeartRatioA + HeartRatioB, heart_resist_ratio = HeartResistRatioA + HeartResistRatioB, heart_add_hurt = HeartAddHurtA + HeartAddHurtB, heart_del_hurt = HeartDelHurtA + HeartDelHurtB, stab_ratio = StabRatioA + StabRatioB, parry_ratio = ParryRatioA + ParryRatioB, pvp_hurt_add_ratio = PvpHurtAddRatioA + PvpHurtAddRatioB, pvp_hurt_del_ratio = PvpHurtDelRatioA + PvpHurtDelRatioB, skill_hurt_add_ratio = SkillHurtAddRatioA + SkillHurtAddRatioB, skill_hurt_del_ratio = SkillHurtDelRatioA + SkillHurtDelRatioB, hp_resume_ratio = HpResumeRatioA + HpResumeRatioB, ice_hurt = IceHurtA + IceHurtB, ice_def = IceDefA + IceDefB, thunder_hurt = ThunderHurtA + ThunderHurtB, thunder_def = ThunderDefA + ThunderDefB, fire_hurt = FireHurtA + FireHurtB, fire_def = FireDefA + FireDefB, wind_hurt = WindHurtA + WindHurtB, wind_def = WindDefA + WindDefB, boss_hurt_add_ratio = BossHurtAddRatioA + BossHurtAddRatioB, boss_hurt_del_ratio = BossHurtDelRatioA + BossHurtDelRatioB, mon_hurt_add_ratio = MonHurtAddRatioA + MonHurtAddRatioB, mon_hurt_del_ratio = MonHurtDelRatioA + MonHurtDelRatioB, suck_blood = SuckBloodA + SuckBloodB, att_add_ratio = AttAddRatioA + AttAddRatioB, hp_add_ratio = HpAddRatioA + HpAddRatioB, def_add_ratio = DefAddRatioA + DefAddRatioB, hit_add_ratio = HitAddRatioA + HitAddRatioB, dodge_add_ratio = DodgeAddRatioA + DodgeAddRatioB, crit_add_ratio = CritAddRatioA + CritAddRatioB, ten_add_ratio = TenAddRatioA + TenAddRatioB, final_hurt_add_ratio = FinalHurtAddRatioA + FinalHurtAddRatioB, final_hurt_del_ratio = FinalHurtDelRatioA + FinalHurtDelRatioB, suck_blood_add = SuckBloodAddA + SuckBloodAddB, suck_blood_minus = SuckBloodMinusA + SuckBloodMinusB, speed = SpeedA + SpeedB, exp_add_ratio = ExpAddRatioA + ExpAddRatioB, exp_drop_add_ratio = ExpDropAddRatioA + ExpDropAddRatioB, speed_add_ratio = SpeedAddRatioA + SpeedAddRatioB, ice_hurt_add_ratio = IceHurtAddRatioA + IceHurtAddRatioB, ice_def_add_ratio = IceDefAddRatioA + IceDefAddRatioB, thunder_hurt_add_ratio = ThunderHurtAddRatioA + ThunderHurtAddRatioB, thunder_def_add_ratio = ThunderDefAddRatioA + ThunderDefAddRatioB, fire_hurt_add_ratio = FireHurtAddRatioA + FireHurtAddRatioB, fire_def_add_ratio = FireDefAddRatioA + FireDefAddRatioB, wind_hurt_add_ratio = WindHurtAddRatioA + WindHurtAddRatioB, wind_def_add_ratio = WindDefAddRatioA + WindDefAddRatioB
    }.

attr_minus(AttrA, AttrB) ->
    #attr{
        att = AttA, hp = HpA, def = DefA, hit = HitA, dodge = DodgeA, crit = CritA, ten = TenA, final_hurt_add = FinalHurtAddA, final_hurt_del = FinalHurtDelA, hp_resume = HpResumeA, hurt_add_ratio = HurtAddRatioA, hurt_del_ratio = HurtDelRatioA, hit_ratio = HitRatioA, dodge_ratio = DodgeRatioA, crit_ratio = CritRatioA, uncrit_ratio = UncritRatioA, crit_hurt_add_ratio = CritHurtAddRatioA, crit_hurt_del_ratio = CritHurtDelRatioA, heart_ratio = HeartRatioA, heart_resist_ratio = HeartResistRatioA, heart_add_hurt = HeartAddHurtA, heart_del_hurt = HeartDelHurtA, stab_ratio = StabRatioA, parry_ratio = ParryRatioA, pvp_hurt_add_ratio = PvpHurtAddRatioA, pvp_hurt_del_ratio = PvpHurtDelRatioA, skill_hurt_add_ratio = SkillHurtAddRatioA, skill_hurt_del_ratio = SkillHurtDelRatioA, hp_resume_ratio = HpResumeRatioA, ice_hurt = IceHurtA, ice_def = IceDefA, thunder_hurt = ThunderHurtA, thunder_def = ThunderDefA, fire_hurt = FireHurtA, fire_def = FireDefA, wind_hurt = WindHurtA, wind_def = WindDefA, boss_hurt_add_ratio = BossHurtAddRatioA, boss_hurt_del_ratio = BossHurtDelRatioA, mon_hurt_add_ratio = MonHurtAddRatioA, mon_hurt_del_ratio = MonHurtDelRatioA, suck_blood = SuckBloodA, att_add_ratio = AttAddRatioA, hp_add_ratio = HpAddRatioA, def_add_ratio = DefAddRatioA, hit_add_ratio = HitAddRatioA, dodge_add_ratio = DodgeAddRatioA, crit_add_ratio = CritAddRatioA, ten_add_ratio = TenAddRatioA, final_hurt_add_ratio = FinalHurtAddRatioA, final_hurt_del_ratio = FinalHurtDelRatioA, suck_blood_add = SuckBloodAddA, suck_blood_minus = SuckBloodMinusA, speed = SpeedA, exp_add_ratio = ExpAddRatioA, exp_drop_add_ratio = ExpDropAddRatioA, speed_add_ratio = SpeedAddRatioA, ice_hurt_add_ratio = IceHurtAddRatioA, ice_def_add_ratio = IceDefAddRatioA, thunder_hurt_add_ratio = ThunderHurtAddRatioA, thunder_def_add_ratio = ThunderDefAddRatioA, fire_hurt_add_ratio = FireHurtAddRatioA, fire_def_add_ratio = FireDefAddRatioA, wind_hurt_add_ratio = WindHurtAddRatioA, wind_def_add_ratio = WindDefAddRatioA
    } = AttrA,
    #attr{
        att = AttB, hp = HpB, def = DefB, hit = HitB, dodge = DodgeB, crit = CritB, ten = TenB, final_hurt_add = FinalHurtAddB, final_hurt_del = FinalHurtDelB, hp_resume = HpResumeB, hurt_add_ratio = HurtAddRatioB, hurt_del_ratio = HurtDelRatioB, hit_ratio = HitRatioB, dodge_ratio = DodgeRatioB, crit_ratio = CritRatioB, uncrit_ratio = UncritRatioB, crit_hurt_add_ratio = CritHurtAddRatioB, crit_hurt_del_ratio = CritHurtDelRatioB, heart_ratio = HeartRatioB, heart_resist_ratio = HeartResistRatioB, heart_add_hurt = HeartAddHurtB, heart_del_hurt = HeartDelHurtB, stab_ratio = StabRatioB, parry_ratio = ParryRatioB, pvp_hurt_add_ratio = PvpHurtAddRatioB, pvp_hurt_del_ratio = PvpHurtDelRatioB, skill_hurt_add_ratio = SkillHurtAddRatioB, skill_hurt_del_ratio = SkillHurtDelRatioB, hp_resume_ratio = HpResumeRatioB, ice_hurt = IceHurtB, ice_def = IceDefB, thunder_hurt = ThunderHurtB, thunder_def = ThunderDefB, fire_hurt = FireHurtB, fire_def = FireDefB, wind_hurt = WindHurtB, wind_def = WindDefB, boss_hurt_add_ratio = BossHurtAddRatioB, boss_hurt_del_ratio = BossHurtDelRatioB, mon_hurt_add_ratio = MonHurtAddRatioB, mon_hurt_del_ratio = MonHurtDelRatioB, suck_blood = SuckBloodB, att_add_ratio = AttAddRatioB, hp_add_ratio = HpAddRatioB, def_add_ratio = DefAddRatioB, hit_add_ratio = HitAddRatioB, dodge_add_ratio = DodgeAddRatioB, crit_add_ratio = CritAddRatioB, ten_add_ratio = TenAddRatioB, final_hurt_add_ratio = FinalHurtAddRatioB, final_hurt_del_ratio = FinalHurtDelRatioB, suck_blood_add = SuckBloodAddB, suck_blood_minus = SuckBloodMinusB, speed = SpeedB, exp_add_ratio = ExpAddRatioB, exp_drop_add_ratio = ExpDropAddRatioB, speed_add_ratio = SpeedAddRatioB, ice_hurt_add_ratio = IceHurtAddRatioB, ice_def_add_ratio = IceDefAddRatioB, thunder_hurt_add_ratio = ThunderHurtAddRatioB, thunder_def_add_ratio = ThunderDefAddRatioB, fire_hurt_add_ratio = FireHurtAddRatioB, fire_def_add_ratio = FireDefAddRatioB, wind_hurt_add_ratio = WindHurtAddRatioB, wind_def_add_ratio = WindDefAddRatioB
    } = AttrB,
    #attr{
        att = AttA - AttB, hp = HpA - HpB, def = DefA - DefB, hit = HitA - HitB, dodge = DodgeA - DodgeB, crit = CritA - CritB, ten = TenA - TenB, final_hurt_add = FinalHurtAddA - FinalHurtAddB, final_hurt_del = FinalHurtDelA - FinalHurtDelB, hp_resume = HpResumeA - HpResumeB, hurt_add_ratio = HurtAddRatioA - HurtAddRatioB, hurt_del_ratio = HurtDelRatioA - HurtDelRatioB, hit_ratio = HitRatioA - HitRatioB, dodge_ratio = DodgeRatioA - DodgeRatioB, crit_ratio = CritRatioA - CritRatioB, uncrit_ratio = UncritRatioA - UncritRatioB, crit_hurt_add_ratio = CritHurtAddRatioA - CritHurtAddRatioB, crit_hurt_del_ratio = CritHurtDelRatioA - CritHurtDelRatioB, heart_ratio = HeartRatioA - HeartRatioB, heart_resist_ratio = HeartResistRatioA - HeartResistRatioB, heart_add_hurt = HeartAddHurtA - HeartAddHurtB, heart_del_hurt = HeartDelHurtA - HeartDelHurtB, stab_ratio = StabRatioA - StabRatioB, parry_ratio = ParryRatioA - ParryRatioB, pvp_hurt_add_ratio = PvpHurtAddRatioA - PvpHurtAddRatioB, pvp_hurt_del_ratio = PvpHurtDelRatioA - PvpHurtDelRatioB, skill_hurt_add_ratio = SkillHurtAddRatioA - SkillHurtAddRatioB, skill_hurt_del_ratio = SkillHurtDelRatioA - SkillHurtDelRatioB, hp_resume_ratio = HpResumeRatioA - HpResumeRatioB, ice_hurt = IceHurtA - IceHurtB, ice_def = IceDefA - IceDefB, thunder_hurt = ThunderHurtA - ThunderHurtB, thunder_def = ThunderDefA - ThunderDefB, fire_hurt = FireHurtA - FireHurtB, fire_def = FireDefA - FireDefB, wind_hurt = WindHurtA - WindHurtB, wind_def = WindDefA - WindDefB, boss_hurt_add_ratio = BossHurtAddRatioA - BossHurtAddRatioB, boss_hurt_del_ratio = BossHurtDelRatioA - BossHurtDelRatioB, mon_hurt_add_ratio = MonHurtAddRatioA - MonHurtAddRatioB, mon_hurt_del_ratio = MonHurtDelRatioA - MonHurtDelRatioB, suck_blood = SuckBloodA - SuckBloodB, att_add_ratio = AttAddRatioA - AttAddRatioB, hp_add_ratio = HpAddRatioA - HpAddRatioB, def_add_ratio = DefAddRatioA - DefAddRatioB, hit_add_ratio = HitAddRatioA - HitAddRatioB, dodge_add_ratio = DodgeAddRatioA - DodgeAddRatioB, crit_add_ratio = CritAddRatioA - CritAddRatioB, ten_add_ratio = TenAddRatioA - TenAddRatioB, final_hurt_add_ratio = FinalHurtAddRatioA - FinalHurtAddRatioB, final_hurt_del_ratio = FinalHurtDelRatioA - FinalHurtDelRatioB, suck_blood_add = SuckBloodAddA - SuckBloodAddB, suck_blood_minus = SuckBloodMinusA - SuckBloodMinusB, speed = SpeedA - SpeedB, exp_add_ratio = ExpAddRatioA - ExpAddRatioB, exp_drop_add_ratio = ExpDropAddRatioA - ExpDropAddRatioB, speed_add_ratio = SpeedAddRatioA - SpeedAddRatioB, ice_hurt_add_ratio = IceHurtAddRatioA - IceHurtAddRatioB, ice_def_add_ratio = IceDefAddRatioA - IceDefAddRatioB, thunder_hurt_add_ratio = ThunderHurtAddRatioA - ThunderHurtAddRatioB, thunder_def_add_ratio = ThunderDefAddRatioA - ThunderDefAddRatioB, fire_hurt_add_ratio = FireHurtAddRatioA - FireHurtAddRatioB, fire_def_add_ratio = FireDefAddRatioA - FireDefAddRatioB, wind_hurt_add_ratio = WindHurtAddRatioA - WindHurtAddRatioB, wind_def_add_ratio = WindDefAddRatioA - WindDefAddRatioB
    }.

