%%% -------------------------------------------------------
%%% @author huangyongxing@yeah.net
%%% @doc
%%% 技能基础属性（base_attr）部分的相关接口
%%% @end
%%% @since 2021-03-30
%%% -------------------------------------------------------
-module(lib_skill_attr).
-export([
        count_skill_attr_with_mod_id/3
        ,get_passive_skill_attr/2
        ,get_passive_skill_attr_and_power/2
        ,get_skill_attr2mod/4
    ]).

-include("common.hrl").
-include("server.hrl").
-include("skill.hrl").

%%--------------------------------------------------
%% 计算功能自己相关技能加成的属性
%% @param  ModId     功能模块id
%% @param  SkillList 功能解锁的技能列表[{SkillId, SkillLv}|SkillId]
%% @return           [{AttrId, AttrVal}]
%%--------------------------------------------------
count_skill_attr_with_mod_id(ModId, SkillList, RoleLv) ->
    F = fun(Tmp, AccList) ->
            case Tmp of
                {SkillId, SkillLv} -> skip;
                SkillId -> SkillLv = 1
            end,
            case data_skill:get(SkillId, SkillLv) of
                [] ->
                    AccList;
                #skill{type=Type, lv_data = LvData}
                when Type == ?SKILL_TYPE_PASSIVE
                orelse Type == ?SKILL_TYPE_PERMANENT_GAIN ->
                    Attr = LvData#skill_lv.base_attr,
                    BaseAttr = base_attr_calc(RoleLv, Attr, [0,ModId]),
                    BaseAttr ++ AccList;
                _ ->
                    AccList
            end
    end,
    lists:foldl(F, [], SkillList).

%%--------------------------------------------------
%% 获取玩家技能加成的永久增益属性
%% @param  SkillList 玩家技能列表[{SkillId, SkillLv}]
%% @return           {基础属性map, 特殊属性map}
%%--------------------------------------------------
get_passive_skill_attr(SkillList, RoleLv) ->
    F = fun({SkillId, SkillLv}, Result) ->
            case data_skill:get(SkillId, SkillLv) of
                [] ->
                    Result;
                #skill{
                    type=Type, lv_data = LvData
                } when Type == ?SKILL_TYPE_PASSIVE; Type == ?SKILL_TYPE_PERMANENT_GAIN ->
                    BaseAttr = base_attr_calc(RoleLv, LvData#skill_lv.base_attr),
                    BaseAttr ++ Result;
                _ ->
                    Result
            end
    end,
    lists:foldl(F, [], SkillList).

%% ---------------------------------------------------------------------------
%% @doc 获取玩家技能加成的永久增益属性和战力
-spec get_passive_skill_attr_and_power(SkillList, RoleLv) -> {AttrList, Power} when
    SkillList   :: [{SkillId :: integer(), SkillLv :: integer()}],
    AttrList    :: [{AttrId :: integer(), Value :: integer()}],
    RoleLv      :: integer(),
    Power       :: integer().
%% ---------------------------------------------------------------------------
get_passive_skill_attr_and_power(SkillList, RoleLv) ->
    Fun = fun({SkillId, SkillLv}, {AccList, Power}) ->
            case data_skill:get(SkillId, SkillLv) of
                #skill{
                    type = Type, lv_data = #skill_lv{power = SPower, base_attr = BaseAttrList}
                } when Type == ?SKILL_TYPE_PASSIVE orelse Type == ?SKILL_TYPE_PERMANENT_GAIN ->
                    BaseAttr = base_attr_calc(RoleLv, BaseAttrList),
                    NewAccList = BaseAttr ++ AccList,
                    {NewAccList, Power + SPower};
                #skill{id = _Id, lv_data = #skill_lv{power = SPower}} ->
                    {AccList, Power + SPower};
                _ ->
                    {AccList, Power}
            end
    end,
    lists:foldl(Fun, {[], 0}, SkillList).

%% 获取技能对其他模块加成的属性列表
%% @param  ModId   功能模块id 0:表示全局的
%% @param  SkillId 技能id
%% @param  SkillLv 技能等级
-spec get_skill_attr2mod(ModId, SkillId, SkillLv, RoleLv) -> AttrList when
    ModId :: non_neg_integer(),
    SkillId :: non_neg_integer(), SkillLv :: non_neg_integer(),
    RoleLv :: non_neg_integer(),
    AttrList :: [{AttrId, AttrVal}],
    AttrId :: non_neg_integer(), AttrVal :: number().
get_skill_attr2mod(ModId, SkillId, SkillLv, RoleLv) ->
    case data_skill:get(SkillId, SkillLv) of
        #skill{type = Type, lv_data = LvData}
          when Type == ?SKILL_TYPE_PASSIVE; Type == ?SKILL_TYPE_PERMANENT_GAIN ->
            #skill_lv{base_attr = BaseAttr} = LvData,
            base_attr_calc(RoleLv, BaseAttr, [ModId]);
        _ ->
            []
    end.


%% 基础属性的等级影响计算
base_attr_calc(RoleLv, BaseAttr) ->
    base_attr_calc(RoleLv, BaseAttr, [0]).

%% 基础属性的等级影响计算
%% FuncIdPattern有效值必须是非空list，
%% 通常应该包含0，除非需要刻意排除0，只取对应模块数据的情况（0表示通用的模块）
%% 例如： base_attr_calc(RoleLv, BaseAttr, [0, ModId]).
base_attr_calc(RoleLv, BaseAttr = [_|_], FuncIdPattern = [_|_]) ->
    lists:filtermap(fun(BaseAttrElem) ->
                case base_attr_conv(RoleLv, BaseAttrElem, FuncIdPattern) of
                    false  ->
                        false;
                    Value ->
                        {true, Value}
                end
        end, BaseAttr);
base_attr_calc(RoleLv, #skill_lv{base_attr = BaseAttr}, FuncIdPattern) ->
    base_attr_calc(RoleLv, BaseAttr, FuncIdPattern);
base_attr_calc(_RoleLv, _, _FuncIdPattern) ->
    [].

base_attr_conv(_RoleLv, {FuncId, AttrId, AttrVal}, FuncIdPattern) ->
    case lists:member(FuncId, FuncIdPattern) of
        true  ->
            {AttrId, AttrVal};
        false ->
            false
    end;
base_attr_conv(RoleLv, {FuncId, AttrId, AttrVal, LevelPeriod, ValAdd}, FuncIdPattern) ->
    case lists:member(FuncId, FuncIdPattern) of
        true  ->
            base_attr_conv_level(RoleLv,  AttrId, AttrVal, LevelPeriod, ValAdd);
        false ->
            false
    end;
base_attr_conv(_RoleLv, _BaseAttrElem, _FuncIdPattern) ->
    false.

base_attr_conv_level(RoleLv,  AttrId, AttrVal, LevelPeriod, ValAdd) ->
    LevelDiff = max(RoleLv - 1, 0),
    FixLevelPeriod = case LevelPeriod =:= 0 of
        true  -> 1;
        false -> LevelPeriod
    end,
    Period = LevelDiff div FixLevelPeriod,
    NewAttrVal = AttrVal + ValAdd * Period,
    {AttrId, NewAttrVal}.
