%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     定制活动之跳一跳 ,{custom_act_jump_act,handle_event,[]}
%%% @end
%%%-------------------------------------------------------------------
-module(custom_act_jump_act).
-author("liushl").

-include("custom_act.hrl").
-include("server.hrl").
-include("def_module.hrl").
-include("jump_act.hrl").
-include("errcode.hrl").
-include("predefine.hrl").
-include("def_event.hrl").
-include("rec_event.hrl").
-include("rec_dress_up.hrl").
-include("figure.hrl").
-include("def_fun.hrl").
%% API
-export([
    kf_notify_other_module/4            %% 活动派发接口：开启与结束
    , is_in_jump_scene/1                %% 是否在跳一跳活动场景
    , is_in_jump_room/2
    , is_in_jump_match/1                %% 是否跳一跳匹配中
    , is_in_jump_play/1                 %% 是否参与跳一跳玩法中

    , handle_event/2

    , reconnect/1                       %% 上线回去

    , ask_act_info/3                    %% 跳一跳：活动数据
    , single_jump/3                     %% 单人模式
    , match_start/3                     %% 开始匹配
    , match_start_callback/1

    , cancel_match/1                    %% 取消匹配
    , cancel_match_callback/2
    , after_cancel_match/1

    , after_match_success/2             %% 匹配成功

    , enter_scene_callback/5            %% 进入玩法场景
    , role_enter_scene/5

    , setup_action_lock/1               %% 加玩法锁
    , out_arg/0
    , data_cfg/2
]).


%% @doc 活动派发接口：开启与结束
kf_notify_other_module(?CUSTOM_ACT_STATUS_OPEN, ActInfo, _Stime, _Etime) ->
    jump_act_center:jump_act_begin(ActInfo);
kf_notify_other_module(_, ActInfo, _Stime, _Etime) ->
    jump_act_center:jump_act_end(ActInfo).

%% 是否在跳一跳活动场景
is_in_jump_scene(Scene) ->
    Scene =:= ?JUMP_ACT_SCENE.
is_in_jump_room(Player, Room) ->
    is_in_jump_scene(Player#player_status.scene)
        andalso Player#player_status.copy_id =:= Room.

%% 是否跳一跳匹配中
is_in_jump_match(Player) ->
    Player#player_status.action_lock =:= ?ERRCODE(err459_jump_matching).
%% 是否参与跳一跳玩法中
is_in_jump_play(Player) ->
    Player#player_status.action_lock =:= ?ERRCODE(err459_jump_playing).

%% 完成场景的切换
handle_event(Player, #event_callback{type_id = ?EVENT_FIN_CHANGE_SCENE}) ->
    case is_in_jump_scene(Player#player_status.scene) of
        true  ->
            jump_act_center:role_enter(Player#player_status.copy_id, Player#player_status.id, Player#player_status.sid);
        false ->
            ok
    end,
    {ok, Player};
%% 离线，需要取消匹配
handle_event(Player, #event_callback{type_id = ?EVENT_DISCONNECT}) ->
    case is_in_jump_scene(Player#player_status.scene) of
        true  ->
            jump_act_center:offline(Player#player_status.copy_id, Player#player_status.id);
        false ->
            case erlang:get(?JUMP_ACT_PRC_DATA) of
                RoomId when is_integer(RoomId) ->
                    jump_act_center:offline(RoomId, Player#player_status.id);
                _ ->
                    cancel_match(Player)
            end
    end,
    {ok, Player};
%% 角色升级
handle_event(Player, #event_callback{type_id = ?EVENT_LV_UP}) ->
    #player_status{id = RoleId, figure = #figure{lv = Lv}} = Player,
    is_in_jump_match(Player) andalso
        jump_act_center:update_role_info(RoleId, lv, Lv),
    {ok, Player};
%% 角色改名
handle_event(Player, #event_callback{type_id = ?EVENT_RENAME, data = Name}) ->
    is_in_jump_match(Player) andalso
        jump_act_center:update_role_info(Player#player_status.id, name, Name),
    {ok, Player};
%% 角色VIP升级
handle_event(Player, #event_callback{type_id = ?EVENT_VIP}) ->
    #player_status{id = RoleId, figure = #figure{vip = Vip}} = Player,
    is_in_jump_match(Player) andalso
        jump_act_center:update_role_info(RoleId, vip, Vip),
    {ok, Player};
%% 角色至尊VIP变化
handle_event(Player, #event_callback{type_id = ?EVENT_SUP_VIP_CHANGE}) ->
    #player_status{id = RoleId, figure = #figure{sup_vip = SupVip}} = Player,
    is_in_jump_match(Player) andalso
        jump_act_center:update_role_info(RoleId, sup_vip, SupVip),
    {ok, Player};
%% 头像
handle_event(Player, #event_callback{type_id = ?EVENT_PICTURE_CHANGE}) ->
    #player_status{id = RoleId, figure = #figure{profile_photo_id = ProfilePhotoId}} = Player,
    is_in_jump_match(Player) andalso
        jump_act_center:update_role_info(RoleId, photo, ProfilePhotoId),
    {ok, Player};
%% 头像框
handle_event(Player, #event_callback{type_id = ?EVENT_DRESS_UP_CHANGE}) ->
    #player_status{id = RoleId, figure = #figure{dress_list = DressList}} = Player,
    is_in_jump_match(Player) andalso
        jump_act_center:update_role_info(RoleId, dress_list, DressList),
    {ok, Player};
handle_event(Player, _) -> {ok, Player}.

%% 上线回去
reconnect(Player) ->
    case lib_custom_act_util:get_open_subtype_list(?CUSTOM_ACT_TYPE_JUMP_ACT) of
        [#act_info{key = {_, SubType}}] ->
            %% 先调整到大世界，问清楚活动进程是否需要拉玩家回去
            jump_act_center:re_login(SubType, Player#player_status.id),
            {next, Player};
        _ ->
            {next, Player}
    end.

%% 跳一跳：活动数据
ask_act_info(Player, Type, SubType) ->
    case lib_custom_act_api:is_open_act(Type, SubType) of
        true  ->
            MaxAwardTimes = ?JUMP_ACT_MAX_AWARD,
            DailyCount = lib_daily:get_count(Player#player_status.id, ?MOD_JUMP_ACT, ?JUMP_ACT_COUNTER_DAILY_COUNT, ?JUMP_ACT_PATTERN_MULTIPLE),
            LifeCount  = lib_counter:get_count(Player#player_status.id, ?MOD_JUMP_ACT, ?JUMP_ACT_COUNTER_LIFE_COUNT),
            IsMatching = is_in_jump_match(Player),
            jump_act_center:ask_act_info(SubType, Player#player_status.sid, max(MaxAwardTimes - DailyCount, 0), LifeCount, IsMatching);
        false ->
            ok
    end.

%% 开玩条件
check_begin(Player, Type, SubType, Pattern) ->
    ActOpen = lib_custom_act_api:is_open_act(Type, SubType),
    IsFree  = lib_player_check:check_all(Player),
    DailyCount = lib_daily:get_count(Player#player_status.id, ?MOD_JUMP_ACT, ?JUMP_ACT_COUNTER_DAILY_COUNT, Pattern),
    LifeCount  = lib_counter:get_count(Player#player_status.id, ?MOD_JUMP_ACT, ?JUMP_ACT_COUNTER_LIFE_COUNT),
    CommonMaxCount   = ?JUMP_ACT_MAX_MATCH,
    MaxAward         = ?JUMP_ACT_MAX_AWARD,
    SingleMaxCount   = ?JUMP_ACT_SINGLE_PLAY,
    LvLimit    = lib_module:is_open(Player, ?MOD_AC_CUSTOM, ?CUSTOM_ACT_TYPE_JUMP_ACT),
    if
        not ActOpen ->
            {false, ?ERRCODE(err331_act_closed)};
        IsFree =/= true ->
            IsFree;
        Pattern =:= ?JUMP_ACT_PATTERN_SINGLE andalso DailyCount >= SingleMaxCount ->
            {false, ?ERRCODE(err459_max_single_count)};
        Pattern =:= ?JUMP_ACT_PATTERN_MULTIPLE andalso DailyCount >= CommonMaxCount ->
            {false, ?ERRCODE(err459_max_match_count)};
        not LvLimit ->
            {false, ?ERRCODE(lv_limit)};
        LifeCount =:= 0 andalso Pattern =:= ?JUMP_ACT_PATTERN_MULTIPLE ->
            {false, ?ERRCODE(err459_single_first)};
        true ->
            {true, DailyCount < MaxAward}
    end.
%% 单人模式
single_jump(Player, Type, SubType) ->
    case check_begin(Player, Type, SubType, ?JUMP_ACT_PATTERN_SINGLE) of
        {false, Error} ->
            {false, Error};
        {true, _} ->
            match(Player, false, ?JUMP_ACT_PATTERN_SINGLE, SubType),
            ok
    end.
%% 开始匹配
match_start(Player, Type, SubType) ->
    case check_begin(Player, Type, SubType, ?JUMP_ACT_PATTERN_MULTIPLE) of
        {false, Error} ->
            {false, Error};
        {true, CanAward} ->
            match(Player, CanAward, ?JUMP_ACT_PATTERN_MULTIPLE, SubType),
            ok
    end.

match(Player, CanAward, Pattern, SubType) ->
    RoleInfo = #jump_act_role{
        role_id         = Player#player_status.id
        , node          = node()
        , server_num    = Player#player_status.server_num
        , figure        = Player#player_status.figure
        , life          = ?IF(Pattern =:= ?JUMP_ACT_PATTERN_SINGLE, ?JUMP_ACT_SINGLE_LEFT, ?JUMP_ACT_MAX_LIFE)
        , stop_round    = 0     %% 止步轮次
        , rank          = 0     %% 排名
        , is_out        = 0     %% 是否已经离开活动场景：或者跟is_award一样
        , is_online     = 0     %% 是否在场
        , can_get_award = CanAward
    },
    jump_act_center:match_start(SubType, RoleInfo, Pattern).

match_start_callback(RoleInfo) ->
    %% 开始匹配就加匹配锁
    clusters_center:apply_cast(RoleInfo#jump_act_role.node, lib_player, setup_action_lock, [RoleInfo#jump_act_role.role_id, ?ERRCODE(err459_jump_matching)]).

%% 取消匹配
cancel_match(Player) ->
    Code = ?ERRCODE(err459_jump_matching),
    case Player#player_status.action_lock of
        Code ->
            case lib_custom_act_util:get_open_subtype_list(?CUSTOM_ACT_TYPE_JUMP_ACT) of
                [#act_info{key = {_, SubType}}] ->
                    %% 直接取消锁，防止出现意外情况，无法解锁
                    jump_act_center:cancel_match(SubType, Player#player_status.id);
                _ ->
                    ignore
            end,
            lib_player:break_action_lock(Player, Code);
        _ ->
            Player
    end.
cancel_match_callback(Node, RoleId) ->
    clusters_center:apply_cast(Node, lib_player, apply_cast, [RoleId, ?APPLY_CAST_STATUS, ?MODULE, after_cancel_match, []]).
after_cancel_match(Player) ->
    {ok, Bin} = pt_459:write(45902, [1, 0]),
    lib_server_send:send_to_sid(Player#player_status.sid, Bin),
    Code = ?ERRCODE(err459_jump_matching),
    case Player#player_status.action_lock of
        Code ->
            lib_player:break_action_lock(Player, Code);
        _ ->
            Player
    end.

%% 匹配成功
after_match_success(Player, RoomId) ->
    lib_custom_act_slices:task_event(Player#player_status.id, ?MOD_AC_CUSTOM, ?CUSTOM_ACT_TYPE_JUMP_ACT),
    erlang:put(?JUMP_ACT_PRC_DATA, RoomId),
    setup_action_lock(Player).

%% 进入玩法场景
enter_scene_callback(Role, PoolId, RoomId, X, Y) ->
    #jump_act_role{node = Node, role_id = RoleId} = Role,
    clusters_center:apply_cast(Node, lib_player, apply_cast, [RoleId, ?APPLY_CAST_STATUS, ?MODULE, role_enter_scene, [PoolId, RoomId, X, Y]]).
role_enter_scene(Player, PoolId, RoomId, X, Y) ->
    SceneId = ?JUMP_ACT_SCENE,
    Player1 = lib_scene:change_scene(Player, SceneId, PoolId, RoomId, X, Y, false, []),
    erlang:erase(?JUMP_ACT_PRC_DATA),
    setup_action_lock(Player1).

%% 加玩法锁-入场的时候加一次锁/4人匹配成功的时候也加一次锁
setup_action_lock(Player) ->
    case Player#player_status.action_lock =:= ?ERRCODE(err459_jump_matching) of
        true ->
            %% 如果是匹配状态，则直接替换为玩法锁
            lib_player:setup_action_lock(Player#player_status{action_lock = free}, ?ERRCODE(err459_jump_playing));
        false ->
            case Player#player_status.action_lock =:= ?ERRCODE(err459_jump_playing) of
                true  ->
                    Player;
                false ->
                    lib_player:setup_action_lock(Player, ?ERRCODE(err459_jump_playing))
            end
    end.

out_arg() ->
    [{action_free, ?ERRCODE(err459_jump_playing)}].

%%%-------------------------------------------------------------------
data_cfg(Key, Default) ->
    case data_jump_act:get_jump_act_kv(Key) of
        [Value] -> Value;
        _ -> Default
    end.

    