%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     独享BOSS
%%% @end
%%%-------------------------------------------------------------------
-module(unshared_boss).
-author("liushl").

-include("server.hrl").
-include("scene.hrl").
-include("mon.hrl").
-include("errcode.hrl").
-include("figure.hrl").
-include("local_boss.hrl").
-include("battle.hrl").
-include("predefine.hrl").
-include("goods.hrl").
-include("def_goods.hrl").
-include("def_module.hrl").
-include("language.hrl").
-include("drop.hrl").
%% API
-export([]).
-compile(export_all).

-define(KEY(RoleId), {?MODULE, RoleId}).

-define(GOODS_ID_REWARD_BOSS,   102325).  %% 赏金BOSS刷新卡
-define(GOODS_ID_DESERTED_BOSS, 102326).  %% 星域BOSS刷新卡

-define(BOSS_CLEAN_TIME, 10*60).    %% BOSS清理时间

%% 使用刷新卡
use_refresh_card(Player, BossId) ->
    #player_status{id = RoleId, figure = #figure{lv = Lv}} = Player,
    AlreadyUse =
    case mod_cache:get(?KEY(RoleId)) of
        true -> true;
        _ -> false
    end,
    OutSideScene = lib_scene:is_outside_scene(Player#player_status.scene),
    %% 当前处于非战斗区域
    PosOk = scene_landform:is_battle_pos(Player#player_status.scene, Player#player_status.x, Player#player_status.y),
    MonCfg = data_mon:get(BossId),

    case MonCfg of
        #mon{boss = ?MON_REWARD_BOSS}   ->
            case data_local_boss:get_reward_boss_info(BossId) of
                #base_reward_boss_info{enter_lv = OpenLv} ->
                    LvOk = Lv >= OpenLv;
                _ ->
                    LvOk = false
            end,
            Cost = [{0, ?GOODS_ID_REWARD_BOSS, 1}];
        #mon{boss = ?MON_DESERTED_BOSS} ->
            case data_deserted_boss:get_boss_cfg(BossId) of
                #base_deserted_boss_info{level = Level} ->
                    case data_deserted_boss:get_level(Level) of
                        #base_deserted_level{open_lv = OpenLv} ->
                            LvOk = Lv >= OpenLv;
                        _ ->
                            LvOk = false
                    end;
                _ ->
                    LvOk = false
            end,
            Cost = [{0, ?GOODS_ID_DESERTED_BOSS, 1}];
        _ ->
            LvOk = false,
            Cost = false
    end,
    
    if
        AlreadyUse  ->
            {false, ?ERRCODE(err460_already_refresh)};
        not OutSideScene ->
            {false, ?ERRCODE(err460_not_outside)};
        not PosOk ->
            {false, ?ERRCODE(err460_pos_not_ok)};
        not LvOk ->
            {false, ?ERRCODE(err460_lv_not_ok)};
        Cost == false ->
            {false, 0};
        true ->
            case lib_goods_api:cost_object_list_with_check(Player, Cost, unshared_boss, "") of
                {false, Error, _} ->
                    {false, Error};
                {true, Player1, _} ->
                    refresh_monster(Player1, MonCfg),
                    {true, Player1}
            end
    end.

%% 刷新怪物
refresh_monster(Player, MonCfg) ->
    #player_status{figure = #figure{name = Name}, id = RoleId} = Player,
    #mon{boss = Boss, id = MonId} = MonCfg,
    {X, Y} = umath:calc_position_around(Player#player_status.scene, Player#player_status.x, Player#player_status.y),
    Origin = case Boss of
        ?MON_REWARD_BOSS ->
            ?DROP_ORIGIN_REWARD_BOSS_UNSHARED;
        ?MON_DESERTED_BOSS ->
            ?DROP_ORIGIN_DESERTED_BOSS_UNSHARED;
        _ ->
            0
    end,
    Args = [
        {born_handler, {?MODULE, when_monster_born, []}},
        {die_handler, {?MODULE, when_monster_die, []}},
        {owner, Player#player_status.id},
        {create_key, {?MODULE, node(), RoleId}},
        {stop, ?BOSS_CLEAN_TIME * 1000},
        {owner_name, Name},
        {can_att_list, [{?BATTLE_SIGN_PLAYER, [RoleId]}]},
        {origin, Origin}
    ],
    lib_mon:async_create_mon(MonId, Player#player_status.scene, Player#player_status.scene_pool_id, X, Y, 0, Player#player_status.copy_id, 1, Args).

%% 怪物出生:记录为已刷新
when_monster_born(init, #scene_object{mon = MonInfo}, _) ->
    case MonInfo of
        #scene_mon{create_key = {?MODULE, Node, RoleId}} ->
            clusters_api:rpc_cast_do_mfa(Node, {mod_cache, put, [?KEY(RoleId), true]});
        _ ->
            ok
    end.

%% 怪物被杀死死亡
when_monster_die(#ob_act{object = #scene_object{mon = MonInfo, config_id = BossId}}, _Klist, _Killer, _AtterSign, _) ->
    case MonInfo of
        #scene_mon{create_key = {?MODULE, Node, RoleId}, boss = Boss} ->
            clusters_api:rpc_cast_do_mfa(Node, {lib_player, apply_cast, [RoleId, ?APPLY_CAST_STATUS, ?MODULE, after_kill_boss, [BossId, Boss]]});
        _ ->
            ok
    end,
    monster_clean(MonInfo).

after_kill_boss(Player, BossId, Boss) ->
    case Boss of
        ?MON_REWARD_BOSS ->
            lib_daily:increment(Player#player_status.id, ?MOD_LOCAL_BOSS, ?COUNT_REWARD_BOSS_DAILY_KILL);
        _ ->
            ignore
    end,
    case data_local_boss:get_reward_boss_info(BossId) of
        #base_reward_boss_info{} = Cfg ->
            Reward = reward_boss_mgr:calc_extra_reward(Cfg),
            lib_goods_api:send_reward(Player, Reward, unshared_boss);
        _ ->
            Player
    end.

%% 怪物被超时清理
when_monster_stop(Object) ->
    monster_clean(Object#scene_object.mon).

%% 清理怪物刷新信息
monster_clean(MonInfo) ->
    case MonInfo of
        #scene_mon{create_key = {?MODULE, Node, RoleId}} ->
            clusters_api:rpc_cast_do_mfa(Node, {mod_cache, erase, [?KEY(RoleId)]});
        _ ->
            ok
    end.