%% ---------------------------------------------------------------------------
%% @doc lib_battle_api
%% @author ming_up@foxmail.com
%% @since  2017-07-11
%% @deprecated  战斗参数
%% ---------------------------------------------------------------------------
-module(lib_battle_api).
-export([
    assist_anything/8,
    break_steath_force/4
    ,slim_back_data/2
    ,update_by_slim_back_data/2

    ,check_multistage/6
    ,skill_stage_set/5
    ,reset_skill_stage/1
    ]).

-include("scene.hrl").
-include("battle.hrl").
-include("attr.hrl").
-include("skill.hrl").

%% 对目标释放一个辅助技能
assist_anything(Scene, ScenePoolId, SignA, IdA, SignT, IdT, SkillId, SkillLv) ->
    mod_scene_agent:apply_cast_with_scene(Scene, ScenePoolId, lib_battle, assist_anything, [SignA, IdA, SignT, IdT, SkillId, SkillLv]).

break_steath_force(Scene, ScenePoolId, Sign, Id) ->
    mod_scene_agent:apply_cast_with_scene(Scene, ScenePoolId, lib_battle, break_steath_force, [Sign, Id]).

%% !!!注意!!!同步修改update_by_slim_back_data
%% 进程传输用的回写数据 怪物、假人、伙伴
slim_back_data(#scene_object{
      battle_attr = #battle_attr{hp = Hp, hp_lim = HpLim},
      skill_cd    = Cd,
      skill_combo = Combo,
      shaking_skill = SkSkill,
      x = X,
      y = Y
     }, _) ->
    [Combo, Hp, HpLim, Cd, SkSkill, X, Y];

slim_back_data(#ets_scene_user{
              battle_attr = #battle_attr{hp = Hp, hp_lim = HpLim},
              skill_cd    = Cd,
              skill_combo = Combo,
              shaking_skill = SkSkill,
              x = X,
              y = Y
             }, ?BATTLE_SIGN_PLAYER) ->
    [Combo, Hp, HpLim, Cd, SkSkill, X, Y];

slim_back_data(Whatever, _) -> Whatever.

%% 更新怪物进程里的scene_object
update_by_slim_back_data(
    #scene_object{battle_attr = BA} = Object,
    [Combo, Hp, HpLim, Cd, SkSkill, X, Y]
    ) ->
    Object#scene_object{
      battle_attr = BA#battle_attr{hp = Hp, hp_lim = HpLim},
      skill_cd    = Cd,
      skill_combo = Combo,
      shaking_skill = SkSkill,
      x = X,
      y = Y
     };

update_by_slim_back_data(
    #ets_scene_user{battle_attr = BA} = User,
    [Combo, Hp, HpLim, Cd, SkSkill, X, Y]
    ) ->
    User#ets_scene_user{
      battle_attr = BA#battle_attr{hp = Hp, hp_lim = HpLim},
      skill_cd    = Cd,
      skill_combo = Combo,
      shaking_skill = SkSkill,
      x = X,
      y = Y
     };

update_by_slim_back_data(#ets_scene_user{} = User, _) -> User;

update_by_slim_back_data(_Whatever, Whatever) -> Whatever.

-spec check_multistage(SkillId, SkillStage, BattleAttr, StageMax, StageCd, NowTime) -> Result when
    SkillId :: non_neg_integer(), SkillStage :: non_neg_integer(),
    BattleAttr :: #battle_attr{},
    StageMax :: non_neg_integer(), StageCd :: non_neg_integer(), NowTime :: non_neg_integer(),
    Result :: true | {false, Error :: non_neg_integer()}.
%% 检测多段技能使用阶段是否合法
check_multistage(_SkillId, SkillStage, _BattleAttr,
    _StageMax, _StageCd, _NowTime) when SkillStage =< 1 ->
    true;
check_multistage(SkillId, SkillStage, #battle_attr{skill_stage_held = SkillStageHeld},
    StageMax, StageCd, NowTime) when SkillStage =< StageMax ->
    case lists:keyfind(SkillId, 1, SkillStageHeld) of
        {_, LastStage, StageTime} ->
            CDOver = StageTime + StageCd,
            if
                SkillStage =/= (LastStage + 1) ->
                    {false, ?ERR_SKILL_STAGE};
                CDOver - 50 > NowTime ->
                    %% 出手太快
                    {false, ?ERR_TOO_FAST};
                CDOver + 2000 < NowTime ->
                    %% 阶段状态已经过了宽限期，需要重新从1开始
                    {false, ?ERR_SKILL_STAGE};
                true ->
                    true
            end;
        _ ->
            {false, ?ERR_SKILL_STAGE}
    end;
check_multistage(_SkillId, _SkillStage, _BattleAttr, _StageMax, _StageCd, _NowTime) ->
    {false, ?ERR_SKILL_STAGE}.

-spec skill_stage_set(SkillId, SkillStage, NowTime, SkillConfig, BattleAttr) -> NewBattleAttr when
    SkillId :: non_neg_integer(), SkillStage :: non_neg_integer(),
    NowTime :: non_neg_integer(), SkillConfig :: #skill{},
    NewBattleAttr :: BattleAttr, BattleAttr :: #battle_attr{}.
%% 使用技能后，缓存skill_stage_held状态数据
skill_stage_set(SkillId, SkillStage, NowTime, SkillConfig, BattleAttr) ->
    case SkillConfig of
        #skill{multistage = StageMax, stage_cd = StageCd} when StageMax > 1 ->
            #battle_attr{skill_stage_held = SkillStageHeld} = BattleAttr,
            InvalidTime = NowTime - StageCd - 2000,     % 早于此时间的数据失效
            RemainSkillStageHeld = [
                SkillStageInfo ||
                SkillStageInfo = {SkillIdX, _StageX, StageTimeX} <- SkillStageHeld,
                StageTimeX > InvalidTime andalso SkillIdX =/= SkillId
            ],
            NewSkillStageHeld = [{SkillId, SkillStage, NowTime} | RemainSkillStageHeld],
            BattleAttr#battle_attr{skill_stage_held = NewSkillStageHeld};
        _ ->
            BattleAttr
    end.

-spec reset_skill_stage(BattleAttr) -> NewBattleAttr when
    BattleAttr :: #battle_attr{}, NewBattleAttr :: #battle_attr{}.
%% 切换场景时（加载场景时），需要reset技能阶段状态
reset_skill_stage(BattleAttr) ->
    BattleAttr#battle_attr{skill_stage_held = []}.

