%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     护送
%%% @end
%%%-------------------------------------------------------------------
-module(convoy_api).
-author("liushl").

-include ("errcode.hrl").
-include ("scene.hrl").
-include ("server.hrl").
-include ("convoy.hrl").
-include ("def_module.hrl").
-include ("def_vip.hrl").
-include ("language.hrl").
-include ("def_act_label.hrl").
-include ("common.hrl").
-include ("def_goods.hrl").
-include ("figure.hrl").
-include ("rec_event.hrl").
-include ("def_event.hrl").

-export ([
    login/2                     %% 登录
    % ,host_dummy_end/1
    ,logout/1                   %% 下线
    ,reconnect/1                %% 重连
    ,finish_convoy/2            %% 完成护送
    ,cancel_convoy/1            %% 主动取消护送
    ,convoy_end/2               %% 护送结算
    ,transfer_to_npc/1          %% 切换到npc
    ,handle_event/2
    ,change_scene_callback/4
    ,refresh_convoy_calc/2      %% 刷新祝福值结果
    ,refresh_convoy_cost/5

    ,rand_convoy_id/0
    ,db_update_role_convoy/2
    ,is_convoying/1
    ,is_convoy_action/1
    ,is_in_convoy/3

    ,is_center_convoy/1
    ,is_convoy_status/1
    ,is_near_npc/1
    ,is_near_target/2
    ,convoy_check/2
    ,act_is_double/0
    ]).

%% 上线初始化处理
login(Player, Now) ->
    #player_status{id = RoleId} = Player,
    RoleConvoy =
    case db:get_row(?SELECT_CONVOY_INFO, [RoleId]) of
        ConvoyInfo = [_|_] ->
            calc_convoy_state_when_login(Player, ConvoyInfo, Now);
        _ ->
            #role_convoy{}
    end,
    Player#player_status{role_convoy = RoleConvoy}.

logout(RoleId) ->
    lib_role:update_role_show(RoleId, [{husong_angel_id, 0}]),
    ok.

%% 废土假人托管准备期上线,此时真人上线结束托管
% host_dummy_end(Player) ->
%     #player_status{role_convoy = RoleConvoy, figure = Figure, action_lock = ActionLock} = Player,
%     NewRoleConvoy = login_trigger_convoy_end(Player, RoleConvoy),
%     NewFigure = Figure#figure{husong_angel_id = 0},
%     Player1 = Player#player_status{role_convoy = NewRoleConvoy, figure = NewFigure},
%     mod_scene_agent:update(Player1, [{husong_angel_id, 0}]),
%     Player2 = lib_scene:change_act_label(Player1, ?ACT_LABEL_CONVOY, 0),
%     ErrCode = ?ERRCODE(err500_husong_start),
%     Player3 =
%     if ActionLock == ErrCode ->
%             lib_player:break_action_lock(Player2, ErrCode);
%         true ->
%             Player2
%     end,
%     {ok, Player4} = pp_convoy:handle(50000, Player3, []),
%     Player4.


calc_convoy_state_when_login(Player, [ConvoyId, Convoying, StartTime, Stage, PrayVal, IsDouble|_], Now) ->
    #player_status{online = OnlineFlag, id = RoleId} = Player,
    RoleConvoy = #role_convoy{
        convoy_id = ConvoyId
        ,convoy_status = Convoying
        ,start_time = StartTime
        ,stage = Stage
        ,pray_val = PrayVal
        ,is_double = IsDouble
    },
    OverTime = data_convoy:get_convoy_kv(convoy_overtime),
    EndTime  = StartTime + OverTime,
    if
        StartTime =/= 0 andalso Now >= EndTime -> %% 重置并结算
            login_trigger_convoy_end(Player, RoleConvoy);
        StartTime =/= 0 -> %% 判断是否处于离线托管状态,若还有护送状态则当超时处理
            if OnlineFlag == ?ONLINE_OFF_HOSTING ->
                    login_trigger_convoy_end(Player, RoleConvoy);
                true ->
                    %% 是否处于假人离线托管
                    case offline_hosting_api:is_hosting_dummy(RoleId) of
                        true ->
                            login_trigger_convoy_end(Player, RoleConvoy);
                        _ ->
                            RoleConvoy
                    end
            end;
        true ->
            RoleConvoy
    end.

login_trigger_convoy_end(Player, RoleConvoy) ->
    #player_status{id = RoleId, figure = #figure{lv = RoleLv}} = Player,
    #role_convoy{convoy_id = ConvoyId, stage = Stage, is_double = IsChooseDouble} = RoleConvoy,
    Privilege = lib_vip_api:get_vip_privilege(Player, ?VIP_CONVOY_EXP_ADD, 1),
    ActDouble = act_is_double(),
    IsDouble = calc_choose_double_or_act_double(ActDouble, IsChooseDouble),
    LogDouble = log_double_check(IsChooseDouble),
    offline_expire_convoy_settle(RoleId, RoleLv, Privilege, ConvoyId, Stage, ?CONVOY_SETTLEMENT_OVERDUE, IsDouble),
    NewConvoyId = convoy_api:rand_convoy_id(),
    NewRoleConvoy = RoleConvoy#role_convoy{convoy_id = NewConvoyId, convoy_status = 0, pray_val = 0, start_time = 0, stage = 0, is_double = 0},
    db_update_role_convoy(RoleId, NewRoleConvoy),
    {CostCard, CostBGold, OriginConvoy, RefreshTime} = get_convoy_ta_count(RoleId),
    ta_convoy(Player, [ConvoyId, 3, OriginConvoy, RefreshTime, CostCard, CostBGold, LogDouble]),
    refresh_convoy_ta_count(RoleId, NewConvoyId),
    NewRoleConvoy.

%% 重连处理
reconnect(Player) ->
    #player_status{id = RoleId, role_convoy = RoleConvoy, scene = SceneId, x = X, y = Y, figure = Figure} = Player,
    #role_convoy{convoy_status = Convoying, start_time = StartTime} = RoleConvoy,
    if Convoying =/= 0 ->
            Now = utime:unixtime(),
            OverTime = data_convoy:get_convoy_kv(convoy_overtime),
            EndTime  = StartTime + OverTime,
            RestTime = (EndTime - Now) * 1000,
            Msg      = {mod, ?MODULE, convoy_end, [?CONVOY_SETTLEMENT_OVERDUE]},
            Ref      = erlang:send_after(RestTime, self(), Msg),
            NewRoleConvoy = RoleConvoy#role_convoy{ref = Ref},
            Player1  = lib_scene:change_scene(Player, SceneId, 0, 0, X, Y, []),
            Player2  = Player1#player_status{role_convoy = NewRoleConvoy, figure = Figure#figure{husong_angel_id = Convoying}},
            Player3  = lib_player:setup_action_lock(Player2, ?ERRCODE(err500_husong_start)),
            mod_scene_agent:update(Player3, [{husong_angel_id, Convoying}]),
            %% 添加活动标识
            Player4 = lib_scene:change_act_label(Player3, ?ACT_LABEL_CONVOY, Convoying),
            {ok, Bin} = pt_500:write(50010, [RoleId, Convoying]),
            lib_server_send:send_to_area_scene(SceneId, 0, 0, X, Y, Bin),
            {ok, Player5} = pp_convoy:handle(50000, Player4, []),
            {ok, Player5};
        true ->
            {next, Player}
    end.

handle_event(Player, #event_callback{type_id = ?EVENT_FIN_CHANGE_SCENE}) ->
    case is_convoy_action(Player) of
        true ->
            #player_status{id = RoleId, scene = SceneId, scene_pool_id = ScenePoolId, copy_id = CopyId,
                x = X, y = Y, role_convoy = #role_convoy{convoy_status = Convoying}} = Player,
            Player1 = lib_scene:change_act_label(Player, ?ACT_LABEL_CONVOY, Convoying),
            {ok, Bin} = pt_500:write(50010, [RoleId, Convoying]),
            lib_server_send:send_to_area_scene(SceneId, ScenePoolId, CopyId, X, Y, Bin),
            {ok, Player1};
        _ ->
            {ok, Player}
    end.

%% 切场景回调
change_scene_callback(Player, {OldSceneId, _OldScenePoolId, _OldCopyId, _OldX, _OldY}, _OldSceneData, NewSceneInfo) ->
    #player_status{id = RoleId, sid = Sid, action_lock = ActionLock, role_convoy = RoleConvoy} = Player,
    #ets_scene{id = DstSceneId} = NewSceneInfo,
    case is_in_convoy(ActionLock, OldSceneId, DstSceneId) of
        true ->
            NewRoleConvoy = RoleConvoy#role_convoy{stage = ?CONVOY_STAGE_TWO},
            db:execute(?UPDATE_CONVOY_INFO_STAGE, [?CONVOY_STAGE_TWO, RoleId]),
            lib_server_send:send_to_sid(Sid, pt_500, 50003, [?SUCCESS, ?CONVOY_STAGE_ONE]),
            % #role_convoy{convoy_id = ConvoyId, is_double = IsChooseDouble} = RoleConvoy,
            % LogDouble = log_double_check(IsChooseDouble),
            % IsDouble = act_is_double(ta_format) orelse IsChooseDouble =/= 0,
            % {CostCard, CostBGold, OriginConvoy, RefreshTime} = get_convoy_ta_count(RoleId),
            % ta_convoy(Player, [ConvoyId, 1, OriginConvoy, RefreshTime, CostCard, CostBGold, LogDouble]),
            Player1 = Player#player_status{role_convoy = NewRoleConvoy},
            {ok, Player1};
        _ ->
            Player
    end.

refresh_convoy_calc(true, _Weight) ->
    true;
refresh_convoy_calc(_CanUp, Weight) ->
    Rand = urand:rand(1, 10000),
    if Rand < Weight -> true;
        true -> false
    end.

refresh_convoy_cost(Player, Cost, CostList, _NextConvoyId, _ConvoyId) ->
    #player_status{id = RoleId} = Player,
    case lists:keyfind(?TYPE_BGOLD, 1, CostList) of
        {_, _, Val} -> ok;
        _ -> Val = 0
    end,
    [{_, GoodsId, _}|_] = Cost,
    case lists:keyfind(GoodsId, 2, CostList) of
        {_, _, GoodsNum} -> ok;
        _ -> GoodsNum = 0
    end,
    GoodsNum =/= 0 andalso lib_counter:plus_count(RoleId, ?MOD_CONVOY, 4, GoodsNum),
    Val =/= 0 andalso lib_counter:plus_count(RoleId, ?MOD_CONVOY, 5, Val),
    % NextConvoyId =/= ConvoyId andalso lib_counter:set_count(RoleId, ?MOD_CONVOY, 6, NextConvoyId),
    lib_counter:increment(RoleId, ?MOD_CONVOY, 7),
    ok.

db_update_role_convoy(RoleId, RoleConvoy) ->
    #role_convoy{
        convoy_id = ConvoyId
        , refresh_count = _Count
        , convoy_status = ConvoyStatus
        , start_time = StartTime
        , stage = Stage
        , pray_val = PrayVal
        , is_double = IsDouble
    } = RoleConvoy,
    db:execute(?REPLACE_CONVOY_INFO, [RoleId, ConvoyId, ConvoyStatus, StartTime, Stage, PrayVal, IsDouble]),
    ok.

rand_convoy_id() ->
    ConvoyIds    = data_convoy:get_convoy_kv(convoy_object_weight),
    RandConvoyId = urand:rand_with_weight(ConvoyIds),
    RandConvoyId.

convoy_check(Player, DstSceneId) ->
    #player_status{scene = OldScene, action_lock = ActionLock, role_convoy = #role_convoy{stage = Stage}} = Player,
    IsInConvoy = is_convoy_action(ActionLock),
    if
        IsInConvoy -> %% 初步检查
            IsInConvoy1 = is_in_convoy(ActionLock, OldScene, DstSceneId),
            IsNearTarget = is_near_target(Player, Stage),
            if
                not IsInConvoy1 orelse not IsNearTarget -> %% 不是护送场景的切换或者远离切换坐标点
                    false;
                true -> 
                    true          
            end;
        true -> false 
    end.

%% 是否处于护送状态:护送数据保存在ETS表中
is_convoying(Player) ->
    is_convoy_action(Player#player_status.action_lock).

%% 是否护送活动锁
is_convoy_action(ActionLock) ->
    ActionLock =:= ?ERRCODE(err500_husong_start).

%% 主动切场景特殊判断,一般若处于自动护送状态由50003处理切场景
is_in_convoy(ActionLock, OldScene, DstSceneId) ->
    StageOneScenes = data_convoy:get_convoy_kv(convoy_safe_scene),
    StageTwoScenes = data_convoy:get_convoy_kv(convoy_pk_scene),
    IsStageOne = lists:member(OldScene, StageOneScenes),
    IsStageTwo = lists:member(DstSceneId, StageTwoScenes),
    is_convoy_action(ActionLock) andalso (IsStageOne andalso IsStageTwo).
        % ((OldScene == LocStartScene andalso DstSceneId == LocEndScene) orelse
        %     (OldScene == CrossStartScene andalso DstSceneId == CrossEndScene)).

%% 是否跨服护送
is_center_convoy(SceneId) ->
    SceneId =:= 1017.

%% 是否护送状态
is_convoy_status(Player) ->
    Action = ?ERRCODE(err500_husong_start),
    case {Player#player_status.role_convoy, Player#player_status.action_lock} of
        {#role_convoy{convoy_status = Convoying}, Action} when Convoying =/= 0 -> true;
        _ -> false
    end.

is_near_npc(Player) ->
    #player_status{x = X, y = Y, scene = RoleScene} = Player,
    case case czone_api:zone_enter_check_city() of
        true ->
            data_convoy:get_convoy_kv(convoy_start_kf);
        _ ->
            data_convoy:get_convoy_kv(convoy_start)
    end of
        [{RoleScene, CenterX, CenterY}|_] ->
            umath:distance({X, Y}, {CenterX, CenterY}) < 1000;
        _ ->
            false
    end.

is_near_target(Player, Stage = ?CONVOY_STAGE_ONE) ->
    #player_status{scene = SceneId, x = X, y = Y} = Player,
    StageOneScene = data_convoy:get_convoy_kv(convoy_safe_scene),
    is_near_target_do(StageOneScene, SceneId, X, Y, Stage);
is_near_target(Player, Stage = ?CONVOY_STAGE_TWO) ->
    #player_status{scene = SceneId, x = X, y = Y} = Player,
    StageTwoScene = data_convoy:get_convoy_kv(convoy_pk_scene),
    is_near_target_do(StageTwoScene, SceneId, X, Y, Stage);
is_near_target(_Player, _) ->
    false.

is_near_target_do(SceneList, SceneId, X, Y, Stage) ->
    case czone_api:zone_open_check() of
        {true, _} -> %% 跨服场景
            % TargetScene = lists:nth(2, SceneList),
            if Stage == ?CONVOY_STAGE_ONE ->
                    [{_, TranX, TranY}|_] = data_convoy:get_convoy_kv(convoy_fly_kf);
                true ->
                    [{_, TranX, TranY}|_] = data_convoy:get_convoy_kv(convoy_end_kf)
            end;
        false -> %% 本服场景
            % TargetScene = lists:nth(1, SceneList),
            if Stage == ?CONVOY_STAGE_ONE ->
                    [{_, TranX, TranY}|_] = data_convoy:get_convoy_kv(convoy_fly);
                true ->
                    [{_, TranX, TranY}|_] = data_convoy:get_convoy_kv(convoy_end)
            end
    end,
    IsInConvoyScene = lists:member(SceneId, SceneList),
    if
        % TargetScene =/= SceneId -> false;
        not IsInConvoyScene ->  false;
        true ->
            umath:distance({X, Y}, {TranX, TranY}) < 1000
    end.

act_is_double() ->
    case lib_activitycalen_api:get_first_enabled_ac_id(?MOD_CONVOY, ?MOD_SUB_HUSONG_DOUBLE) of
        {ok, _}  -> 2;
        _ -> 1
    end.

act_is_double(ta_format) ->
    case act_is_double() of
        2 -> true;
        _ -> false
    end.

log_double_check(IsChooseDouble) ->
    ActIsDouble = act_is_double(ta_format),
    if 
        ActIsDouble -> 2;
        IsChooseDouble =/= 0 -> 3;
        true -> 1
    end.

%% @doc 传送到护送NPC
transfer_to_npc(Player) ->
    case case czone_api:zone_enter_check_city() of
        true  ->
            data_convoy:get_convoy_kv(convoy_start_kf);
        false ->
            data_convoy:get_convoy_kv(convoy_start)
    end of
        [{Scene, X, Y}] ->
            case lib_scene:check_enter(Player, 0, Scene, ?TRANS_TYPE_SERVER) of
                {false, Error} -> {false, Error};
                {true, _, _} ->
                    Player1 = lib_scene:change_scene(Player, Scene, 0, 0, X, Y, true, []),
                    {true, Player1}
            end;
        _ ->
            {false, 0}
    end.

%% 完成阶段护送
finish_convoy(Player, Stage = ?CONVOY_STAGE_ONE) ->
    #player_status{id = RoleId, sid = Sid, role_convoy = RoleConvoy} = Player,
    #role_convoy{convoy_id = _ConvoyId, is_double = _IsChooseDouble} = RoleConvoy,
    NewRoleConvoy = RoleConvoy#role_convoy{stage = ?CONVOY_STAGE_TWO},
    db:execute(?UPDATE_CONVOY_INFO_STAGE, [?CONVOY_STAGE_TWO, RoleId]),
    Player1 = Player#player_status{role_convoy = NewRoleConvoy},
    StageTwoScene = data_convoy:get_convoy_kv(convoy_pk_scene),
    case czone_api:zone_open_check() of
        {true, _} ->
            NextScene = lists:nth(2, StageTwoScene);
        _ ->
            NextScene = lists:nth(1, StageTwoScene)
    end,
    Player2 = lib_scene:change_scene(Player1, NextScene, 0, 0, true, []),
    % IsDouble = act_is_double(ta_format) orelse IsChooseDouble =/= 0,
    % LogDouble = log_double_check(IsChooseDouble),
    % {CostCard, CostBGold, OriginConvoy, RefreshTime} = get_convoy_ta_count(RoleId),
    % ta_convoy(Player2, [ConvoyId, 1, OriginConvoy, RefreshTime, CostCard, CostBGold, LogDouble]),
    lib_server_send:send_to_sid(Sid, pt_500, 50003, [?SUCCESS, Stage]),
    {ok, Player2};
finish_convoy(Player, Stage = ?CONVOY_STAGE_TWO) ->
    #player_status{sid = Sid} = Player,
    {ok, Player1} = convoy_end(Player, ?CONVOY_SETTLEMENT_PERFECT),
    lib_server_send:send_to_sid(Sid, pt_500, 50003, [?SUCCESS, Stage]),
    {ok, Player1}.

%% 主动取消护送
cancel_convoy(Player) ->
    #player_status{id = RoleId, sid = Sid, scene = SceneId, scene_pool_id = ScenePoolId,
        copy_id = CopyId, x = X, y = Y, role_convoy = RoleConvoy, figure = Figure} = Player,
    #role_convoy{ref = Ref, convoy_status = Convoying, start_time = StartTime, stage = Stage, is_double = IsChooseDouble} = RoleConvoy,
    util:cancel_timer(Ref),
    NewRoleConvoy = RoleConvoy#role_convoy{stage = 0, is_double = 0, start_time = 0, convoy_status = 0, ref = undefined},
    db_update_role_convoy(RoleId, NewRoleConvoy),
    Player1 = Player#player_status{role_convoy = NewRoleConvoy, figure = Figure#figure{husong_angel_id = 0}},
    Player2 = lib_player:break_action_lock(Player1, ?ERRCODE(err500_husong_start)),
    Player3 = lib_scene:change_act_label(Player2, ?ACT_LABEL_CONVOY, 0),
    mod_scene_agent:update(Player3, [{husong_angel_id, 0}]),
    Player4 = lib_player:count_player_speed(Player3),
    {ok, Bin} = pt_500:write(50010, [RoleId, 0]),
    lib_server_send:send_to_area_scene(SceneId, ScenePoolId, CopyId, X, Y, Bin),
    DailyCount = lib_daily:get_count(RoleId, ?MOD_CONVOY, ?CONVOY_COUNTER_DAILY_CONVOY),
    {ok, Bin1} = pt_500:write(50004, [3, ?CONVOY_STAGE_TWO, Convoying, DailyCount]),
    lib_server_send:send_to_sid(Sid, Bin1),
    LogDouble = log_double_check(IsChooseDouble),
    lib_log_api:log_convoy_result(
        [RoleId, Figure#figure.name, Convoying, StartTime, Stage, ?CONVOY_SETTLEMENT_CANCEL, LogDouble, "[]", utime:unixtime()]
    ),
    %% TA数据上报
    % IsDouble = act_is_double(ta_format) orelse IsChooseDouble =/= 0,
    {CostCard, CostBGold, OriginConvoy, RefreshTime} = get_convoy_ta_count(RoleId),
    ta_convoy(Player4, [Convoying, 2, OriginConvoy, RefreshTime, CostCard, CostBGold, LogDouble]),
    refresh_convoy_ta_count(RoleId, RoleConvoy#role_convoy.convoy_id),
    {ok, Player4}.

%% 结算
convoy_end(Player, SettleType) ->
    #player_status{id = RoleId, sid = Sid, scene = SceneId, scene_pool_id = ScenePoolId,
        copy_id = CopyId, x = X, y = Y, figure = #figure{lv = RoleLv, name = Name}, role_convoy = RoleConvoy} = Player,
    #role_convoy{convoy_status = ConvoyId, start_time = StartTime, stage = Stage, ref = Ref, is_double = IsChooseDouble} = RoleConvoy,
    util:cancel_timer(Ref),

    %% 发奖励
    VipAdd      = lib_vip_api:get_vip_privilege(Player, ?VIP_CONVOY_EXP_ADD, 1),
    ActDouble   = act_is_double(),
    IsDouble   = calc_choose_double_or_act_double(ActDouble, IsChooseDouble),
    Rewards     = calc_reward(RoleLv, VipAdd, ConvoyId, Stage, SettleType, IsDouble),
    #player_status{figure = Figure1} = Player1   = lib_goods_api:send_reward(Player, Rewards, convoy_go, SettleType),

    %% 更新护送数据
    NewConvoyId = convoy_api:rand_convoy_id(),
    NewRoleConvoy = RoleConvoy#role_convoy{convoy_id = NewConvoyId, pray_val = 0, convoy_status = 0, start_time = 0, stage = 0, is_double = 0, ref = undefined},
    db_update_role_convoy(RoleId, NewRoleConvoy),

    %% 更新形象&场景头标数据
    NewFigure   = Figure1#figure{husong_angel_id = 0},
    Player2     = Player1#player_status{role_convoy = NewRoleConvoy, figure = NewFigure},
    Player3 = lib_player:break_action_lock(Player2, ?ERRCODE(err500_husong_start)),
    Player4 = lib_scene:change_act_label(Player3, ?ACT_LABEL_CONVOY, 0),
    mod_scene_agent:update(Player4, [{husong_angel_id, 0}]),
    {ok, Bin} = pt_500:write(50010, [RoleId, 0]),
    lib_server_send:send_to_area_scene(SceneId, ScenePoolId, CopyId, X, Y, Bin),

    DailyCount = lib_daily:get_count(RoleId, ?MOD_CONVOY, ?CONVOY_COUNTER_DAILY_CONVOY),
    IsDouble1 =
     if IsChooseDouble =/= 0 orelse ActDouble == 2 -> %% 双倍进行中
            1;
        true -> 0 %% 非双倍
    end,
    {ok, Bin2} = pt_500:write(50000, [NewConvoyId, DailyCount, 0, 0, 0, IsDouble1]),
    if SettleType == ?CONVOY_SETTLEMENT_OVERDUE ->
            {ok, Bin1} = pt_500:write(50004, [2, ?CONVOY_STAGE_TWO, RoleConvoy#role_convoy.convoy_status, DailyCount]);
        true ->
            {ok, Bin1} = pt_500:write(50004, [1, ?CONVOY_STAGE_TWO, RoleConvoy#role_convoy.convoy_status, DailyCount])
    end,
    lib_server_send:send_to_sid(Sid, <<Bin1/binary, Bin2/binary>>),
    Player5 = lib_player:count_player_speed(Player4),

    lib_activitycalen_api:role_success_end_activity(RoleId, ?MOD_CONVOY, ?MOD_SUB_HUSONG_ANGEL),
    lib_role_legion:trigger_task(Player5, ?MOD_CONVOY, 1),
    LogDouble = log_double_check(IsChooseDouble),
    lib_log_api:log_convoy_result(
        [RoleId, Name, ConvoyId, StartTime, Stage, SettleType, LogDouble, util:term_to_bitstring(Rewards), utime:unixtime()]
    ),

    %% TA数据上报
    {CostCard, CostBGold, OriginConvoy, RefreshTime} = get_convoy_ta_count(RoleId),
    LogDouble = log_double_check(IsChooseDouble),
    ta_convoy(Player5, [ConvoyId, 1, OriginConvoy, RefreshTime, CostCard, CostBGold, LogDouble]),
    refresh_convoy_ta_count(RoleId, NewConvoyId),

    {ok, Player5}.

%% ActDouble :: 1|2
%% IsChooseDouble :: 0|1
calc_choose_double_or_act_double(ActDouble, IsChooseDouble) ->
    if ActDouble == 2 orelse IsChooseDouble =/= 0 ->
            2;
        true ->
            1
    end.

get_convoy_ta_count(RoleId) ->
    CountList = [
        {?MOD_CONVOY, 0, 4}, {?MOD_CONVOY, 0, 5},       %% 本次护送凭证消耗|本次护送红钻消耗
        {?MOD_CONVOY, 0, 6}, {?MOD_CONVOY, 0, 7}    %% 本次护送初始品质|本次护送刷新次数
        ],
    [{_, CostCard}, {_, CostBGold}, {_, OriginConvoy}, {_, RefreshTime}|_] = lib_counter:get_count(RoleId, CountList),
    {CostCard, CostBGold, OriginConvoy, RefreshTime}.

refresh_convoy_ta_count(RoleId, OriginConvoy) ->
    lib_counter:set_count(RoleId, [
        {{?MOD_CONVOY, 0, 4}, 0}, {{?MOD_CONVOY, 0, 5}, 0}, %% 本次护送凭证消耗|本次护送红钻消耗
        {{?MOD_CONVOY, 0, 6}, OriginConvoy}, {{?MOD_CONVOY, 0, 7}, 0}  %% 本次护送初始品质|本次护送刷新次数
        ]),
    ok.

offline_expire_convoy_settle(RoleId, RoleLv, VipAdd, ConvoyId, Stage, TYPE, IsDouble) ->
    Rewards = calc_reward(RoleLv, VipAdd, ConvoyId, Stage, TYPE, IsDouble),
    Title   = ?LAN_MSG(?LAN_TITLE_OFFLINE_AWARD),
    Content = ?LAN_MSG(?LAN_CONTENT_OFFLINE_AWARD),
    lib_mail_api:send_sys_mail([RoleId], Title, Content, Rewards),
    DailyCount = lib_daily:get_count_offline(RoleId, ?MOD_CONVOY, ?CONVOY_COUNTER_DAILY_CONVOY),
    lib_server_send:send_to_uid(RoleId, pt_500, 50004, [2, ?CONVOY_STAGE_TWO, ConvoyId, DailyCount]),
    ok.

%% 根据阶段和结束类型计算奖励
calc_reward(RoleLv, VipAdd, ConvoyId, Stage, TYPE, IsDouble) ->
    Cfg = data_convoy:get_convoy_object(ConvoyId),
    ExpCfg = data_convoy:get_convoy_exp(RoleLv),
    if
        not is_record(Cfg, base_convoy_object) ->
            ?ERR("get_convoy_object settlement error:~p", [ConvoyId]),
            [];
        ExpCfg =:= [] ->
            ?ERR("get_convoy_exp settlement error:~p", [RoleLv]),
            [];
        true ->
            #base_convoy_object{
                stage_one_ratio = StageOneRatio, overdue_ratio = OverDueRatio, award = Award
            } = Cfg,
            [ExpBase|_] = ExpCfg,
            ExpRatio =
                case TYPE of
                    ?CONVOY_SETTLEMENT_PERFECT -> %% 完美
                        StageOneRatio/100;
                    ?CONVOY_SETTLEMENT_OVERDUE -> %% 超时
                        (OverDueRatio/100) * (StageOneRatio/100);
                    _ ->
                        ?ERR("unknown result error:~p", [{Stage, TYPE}]),
                        0
                end,
            %% 加经验
            Exp = [{?TYPE_EXP, ?GOODS_ID_EXP, round(ExpBase * ExpRatio * IsDouble * (1 + VipAdd/100))}],
            %% 给物品
            case TYPE of
                ?CONVOY_SETTLEMENT_PERFECT ->
                    Goods = Award;
                _ ->
                    Goods = []
            end,
            Goods ++ Exp
    end.

%% TA护送数据上报
ta_convoy(Player, [ColorId, ResultType, OldColor, RefreshTime, CostCard, CosyBGold, DoubleRet]) ->
    % DoubleRet =
    % if is_boolean(IsDouble) -> IsDouble;
    %     IsDouble == 1 -> false;
    %     IsDouble == 2 -> true;
    %     true -> false
    % end,
    ta_agent_fire:ta_convoy(Player, [ColorId, ResultType, OldColor, RefreshTime, CostCard, CosyBGold, DoubleRet]);
ta_convoy(_Player, _) ->
    skip.