%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     本服公会战-管理进程
%%%     多个公会在一起混战，杀人/打怪/挂机/采集可以获得积分，最后算一个排名
%%% @end
%%%-------------------------------------------------------------------
-module(guild_war_mgr).
-author("liushl").

-behaviour(gen_server).

-include("guild_war.hrl").
-include("common.hrl").
-include("def_module.hrl").
-include("errcode.hrl").
-include("figure.hrl").
-include("scene.hrl").
%% API
-export([start_link/0]).

%% gen_server callbacks
-export([init/1,
    handle_call/3,
    handle_cast/2,
    handle_info/2,
    terminate/2,
    code_change/3]).

-define(SERVER, ?MODULE).

-export([
    is_during_guild_war/0,              %% 是否公会战期间
    rename_guild/2,                     %% 公会改名
    update_role_info/3                  %% 更新玩家信息
]).

%% 玩家协议处理
-export([
    ask_guild_war_info/1,               %% 查看活动信息
    ask_enter_guild_war/1,              %% 请求进入
    success_enter_guild_war/3,
    out_scene/1,
    ask_role_rank/1,                    %% 查看个人榜单
    ask_guild_rank/1                    %% 查看公会榜单
]).

%% 玩法流程
-export([
    gm_start/0,
    gm_end/0,
    activitycalen_start/4,              %% 活动日历通知活动开启
    activitycalen_end/0,                %% 活动日历通知活动结束
    boss_birth/1,                       %% BOSS出生
    boss_die/1,                         %% BOSS死亡
    add_score/3,                        %% 增加积分
    kill_man/5,                         %% 击杀玩家
    update_continue_kill/2,             %% 连杀数改变
    close_act/0                         %% 关闭活动
    ,test_code/1
]).
%%%===================================================================
%%% API
%%%===================================================================
%% 是否公会战期间
is_during_guild_war() ->
    gen_server:call(?MODULE, is_during_guild_war).
%% 公会改名
rename_guild(GuildId, NowGuildName) ->
    gen_server:cast(?MODULE, {rename_guild, GuildId, NowGuildName}).
%% 更新玩家信息
update_role_info(RoleId, Key, Value) ->
    gen_server:cast(?MODULE, {update_role_info, RoleId, Key, Value}).
%%%-------------------------------------------------------------------
%%% @doc 玩家协议处理
%%%-------------------------------------------------------------------
%% 查看活动信息
ask_guild_war_info(RoleId) ->
    gen_server:cast(?MODULE, {ask_guild_war_info, RoleId}).
%% 请求进入
ask_enter_guild_war(RoleId) ->
    gen_server:cast(?MODULE, {ask_enter, RoleId}).
success_enter_guild_war(GuildInfo, RoleInfo, PoolId) ->
    gen_server:cast(?MODULE, {enter_scene, GuildInfo, RoleInfo, PoolId}).
%% 离开场景
out_scene(PoolId) ->
    gen_server:cast(?MODULE, {out_scene, PoolId}).
%% 查看个人榜单
ask_role_rank(Sid) ->
    gen_server:cast(?MODULE, {ask_role_rank, Sid}).
%% 查看公会榜单
ask_guild_rank(Sid) ->
    gen_server:cast(?MODULE, {ask_guild_rank, Sid}).
%%%-------------------------------------------------------------------
%%% @doc 玩法流程处理
%%%-------------------------------------------------------------------
%% 活动日历通知活动开启
activitycalen_start(Module, ModuleSub, AcSub, Now) ->
    EndTime = lib_activitycalen_api:get_ac_end_time(Module, ModuleSub, AcSub, Now),
    ?MODULE ! {act_begin, Now, EndTime}.
%% 活动日历通知活动结束
activitycalen_end() ->
    ?MODULE ! act_end.
%% BOSS出生
boss_birth(PoolId) ->
    ?MODULE ! {boss_alive_state, PoolId, true}.
%% BOSS死亡
boss_die(PoolId) ->
    ?MODULE ! {boss_alive_state, PoolId, false}.
%% 增加积分
add_score(RoleId, Score, Type) ->
    ?MODULE ! {add_score, RoleId, Score, Type, none}.
%% 击杀玩家
kill_man(Killer, Dead, Scene, PoolId, CopyId) ->
    ?MODULE ! {kill_man, Killer, Dead, Scene, PoolId, CopyId}.
%% 连杀数改变
update_continue_kill(RoleId, Value) ->
    ?MODULE ! {update_continue_kill, RoleId, Value}.
%% 关闭活动
close_act() ->
    erlang:send_after(1000, self(), close_act).

test_code(Hour) ->
    Week = utime:day_of_week(),
    case Week >= 1 andalso Week =< 5 andalso Hour >= 9 andalso Hour =< 20 of
        true  ->
            gm_start();
        false ->
            ok
    end.
gm_start() ->
    Now = utime:unixtime(),
    lib_activitycalen_api:success_start_activity(?MOD_GUILD_WAR, 1, 1),
    EndTime = lib_activitycalen_api:get_ac_end_time(?MOD_GUILD_WAR, 1, 1, Now),
    ?MODULE ! {gm_start, EndTime-Now}.
gm_end() ->
    lib_activitycalen_api:success_end_activity(?MOD_GUILD_WAR, 1, 1),
    ?MODULE ! gm_end.
%%--------------------------------------------------------------------
%% @doc
%% Starts the server
%%
%% @end
%%--------------------------------------------------------------------
-spec(start_link() ->
    {ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
start_link() ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).

%%%===================================================================
%%% gen_server callbacks
%%%===================================================================

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Initializes the server
%%
%% @spec init(Args) -> {ok, State} |
%%                     {ok, State, Timeout} |
%%                     ignore |
%%                     {stop, Reason}
%% @end
%%--------------------------------------------------------------------
-spec(init(Args :: term()) ->
    {ok, State :: #guild_war{}} | {ok, State :: #guild_war{}, timeout() | hibernate} |
    {stop, Reason :: term()} | ignore).
init([]) ->
    {ok, #guild_war{}}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling call messages
%%
%% @end
%%--------------------------------------------------------------------
-spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()},
    State :: #guild_war{}) ->
    {reply, Reply :: term(), NewState :: #guild_war{}} |
    {reply, Reply :: term(), NewState :: #guild_war{}, timeout() | hibernate} |
    {noreply, NewState :: #guild_war{}} |
    {noreply, NewState :: #guild_war{}, timeout() | hibernate} |
    {stop, Reason :: term(), Reply :: term(), NewState :: #guild_war{}} |
    {stop, Reason :: term(), NewState :: #guild_war{}}).
handle_call(Msg, From, State) ->
    try
        do_handle_call(Msg, From, State)
    catch _:_Error ->
        io:format("do_handle_call Msg:~w, Error:~w, ~p", [Msg, _Error, erlang:get_stacktrace()]),
        {reply, error, State}
    end.
do_handle_call(is_during_guild_war, _From, State) ->
    Res = State#guild_war.end_time > 0,
    {reply, Res, State};
do_handle_call(_Request, _From, State) ->
    io:format("module:~p: handle_call unexpect message:~p", [?MODULE, _Request]),
    {reply, ok, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling cast messages
%%
%% @end
%%--------------------------------------------------------------------
-spec(handle_cast(Request :: term(), State :: #guild_war{}) ->
    {noreply, NewState :: #guild_war{}} |
    {noreply, NewState :: #guild_war{}, timeout() | hibernate} |
    {stop, Reason :: term(), NewState :: #guild_war{}}).
handle_cast(Msg, State) ->
    try
        do_handle_cast(Msg, State)
    catch _:_Error ->
        io:format("do handle_cast Msg:~w, Error:~w, ~p", [Msg, _Error, erlang:get_stacktrace()]),
        {noreply, State}
    end.

%% 活动状态信息
do_handle_cast({ask_guild_war_info, RoleId}, #guild_war{end_time = 0} = State) ->
    {ok, Bin} = pt_405:write(40500, [0, 0, 0, []]),
    lib_server_send:send_to_uid(RoleId, Bin),
    {noreply, State};
do_handle_cast({ask_guild_war_info, RoleId}, State) ->
    #guild_war{
        begin_time = BeginTime,
        end_time = Time,
        role_grade = RoleGrades,
        guild_war_pool = GuildWarPool
    } = State,
    case dict:find(RoleId, RoleGrades) of
        {ok, #guild_war_role{score = Score}} ->
            Score;
        _ ->
            Score = 0
    end,
    PoolInfo =
        [
            {PoolId + 1, Num}
            || #guild_war_pool{pool_id = PoolId, role_num = Num} <- GuildWarPool
        ],
    {ok, Bin} = pt_405:write(40500, [BeginTime, Time, Score, PoolInfo]),
    lib_server_send:send_to_uid(RoleId, Bin),
    {noreply, State};

%% 注意：活动未开启，下面的消息会忽略
do_handle_cast(_, #guild_war{end_time = 0} = State) ->
    {noreply, State};

%% 成功进入场景-首次进入记录玩家信息和公会信息
do_handle_cast({enter_scene, ShortGuildInfo, RoleInfo, PoolId}, State) ->
    #guild_war{
        role_grade = RoleGrade           %% 公会成绩 #guild_war_guild{}
        , guild_grade = GuildGrade       %% 玩家成绩 #guild_war_role{}
        , guild_war_pool = PoolInfo      %% 分线情况
    } = State,
    #guild_war_role{role_id = RoleId, guild_id = GuildId, guild_name = GuildName, guild_flag = GuildFlag} = RoleInfo,
    case dict:find(RoleId, RoleGrade) of
        {ok, OldRole}  ->
            %% 已经是重复进入了/清空连杀
            NewRoleGrade = dict:store(RoleId, OldRole#guild_war_role{continue_kill = 0}, RoleGrade),
            NewPoolInfo  = check_enter_new_pool(PoolId, PoolInfo),
            {noreply, State#guild_war{guild_war_pool = NewPoolInfo, role_grade = NewRoleGrade}};
        error ->
            %% 第一次进入，写入玩家数据
            NewRoleGrade = dict:store(RoleId, RoleInfo, RoleGrade),
            case lists:keymember(GuildId, #guild_war_guild.guild_id, GuildGrade) of
                true  ->
                    %% 公会已经有数据了
                    NewGuildGrade = GuildGrade;
                false ->
                    %% 本公会第一次有人进入，写入公会数据
                    [ChiefId, ChiefName, ChiefPower, GuildPower|_] = ShortGuildInfo,
                    GuildInfo = #guild_war_guild{
                        guild_id   = GuildId,
                        guild_name = GuildName,
                        guild_flag = GuildFlag,
                        guild_power = GuildPower,
                        chief_id = ChiefId,
                        chief_name = ChiefName,
                        chief_power = ChiefPower
                    },
                    NewGuildGrade = [GuildInfo|GuildGrade]
            end,
            NewPoolInfo = check_enter_new_pool(PoolId, PoolInfo),
            %% 首次进入，完成一次公会战
            guild_war_api:participate_in_guild_war(RoleId),
            lib_achievement_api:async_event(RoleId, lib_achievement_api, guild_war_event, 1),
            lib_activity_reserve:trigger_reserve_check(RoleId, ?MOD_GUILD_WAR),
            {noreply, State#guild_war{role_grade = NewRoleGrade, guild_grade = NewGuildGrade, guild_war_pool = NewPoolInfo}}
    end;

%% 个人榜单
do_handle_cast({ask_role_rank, Sid}, State) ->
    GradeInfo =
        [
            {
                Role#guild_war_role.picture#rec_picture.name,
                Role#guild_war_role.picture#rec_picture.sup_vip,
                Role#guild_war_role.picture#rec_picture.vip,
                Role#guild_war_role.picture#rec_picture.sex,
                Role#guild_war_role.picture#rec_picture.power,
                Role#guild_war_role.guild_name,
                Role#guild_war_role.score,
                Role#guild_war_role.time,
                Role#guild_war_role.max_kill,
                Role#guild_war_role.continue_kill
            }
            || {_, Role} <- dict:to_list(State#guild_war.role_grade)
        ],
    {ok, Bin} = pt_405:write(40504, [GradeInfo]),
    lib_server_send:send_to_sid(Sid, Bin),
    {noreply, State};

%% 公会榜单
do_handle_cast({ask_guild_rank, Sid}, State) ->
    GradeInfo =
        [
            {Guild#guild_war_guild.guild_id, Guild#guild_war_guild.guild_name, Guild#guild_war_guild.score, Guild#guild_war_guild.time}
            || Guild <- State#guild_war.guild_grade
        ],
    {ok, Bin} = pt_405:write(40505, [GradeInfo]),
    lib_server_send:send_to_sid(Sid, Bin),
    {noreply, State};

%% 公会改名
do_handle_cast({rename_guild, GuildId, NowGuildName}, State) ->
    #guild_war{
        role_grade = RoleGrade           %% 公会成绩 #guild_war_guild{}
        , guild_grade = GuildGrade       %% 玩家成绩 #guild_war_role{}
    } = State,
    NewRoleGrade = dict:map(
        fun(_Key, Value) ->
            case Value#guild_war_role.guild_id =:= GuildId of
                true  -> Value#guild_war_role{guild_name = NowGuildName};
                false -> Value
            end
        end, RoleGrade
    ),
    NewGuildGrade = case lists:keyfind(GuildId, #guild_war_guild.guild_id, GuildGrade) of
        #guild_war_guild{} = One ->
            lists:keyreplace(GuildId, #guild_war_guild.guild_id, GuildGrade, One#guild_war_guild{guild_name = NowGuildName});
        _ ->
            GuildGrade
    end,
    {noreply, State#guild_war{guild_grade = NewGuildGrade, role_grade = NewRoleGrade}};

%% 更新玩家信息
do_handle_cast({update_role_info, RoleId, Key, Value}, State) ->
    #guild_war{
        role_grade = RoleGrade
    } = State,
    case dict:find(RoleId, RoleGrade) of
        {ok, #guild_war_role{picture = Picture} = One} ->
            NewOne =
                case Key of
                    name ->
                        One#guild_war_role{picture = Picture#rec_picture{name = Value}};
                    vip  ->
                        One#guild_war_role{picture = Picture#rec_picture{vip = Value}};
                    sup_vip  ->
                        One#guild_war_role{picture = Picture#rec_picture{sup_vip = Value}}
                end,
            NewRoleGrade = dict:store(RoleId, NewOne, RoleGrade),
            {noreply, State#guild_war{role_grade = NewRoleGrade}};
        _ ->
            {noreply, State}
    end;

%% 离开活动场景
do_handle_cast({out_scene, PoolId}, State) ->
    #guild_war{
        guild_war_pool = PoolInfo      %% 分线情况
    } = State,
    case lists:keyfind(PoolId, #guild_war_pool.pool_id, PoolInfo) of
        #guild_war_pool{role_num = RoleNum} = One ->
            NewPoolInfo = lists:keyreplace(PoolId, #guild_war_pool.pool_id, PoolInfo, One#guild_war_pool{role_num = max(0, RoleNum - 1)}),
            {noreply, State#guild_war{guild_war_pool = NewPoolInfo}};
        _ ->
            {noreply, State}
    end;
    
do_handle_cast(_Request, State) ->
    io:format("module:~p: handle_cast unexpect message:~p", [?MODULE, _Request]),
    {noreply, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling all non call/cast messages
%%
%% @spec handle_info(Info, State) -> {noreply, State} |
%%                                   {noreply, State, Timeout} |
%%                                   {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
-spec(handle_info(Info :: timeout() | term(), State :: #guild_war{}) ->
    {noreply, NewState :: #guild_war{}} |
    {noreply, NewState :: #guild_war{}, timeout() | hibernate} |
    {stop, Reason :: term(), NewState :: #guild_war{}}).
handle_info(Msg, State) ->
    try
        do_handle_info(Msg, State)
    catch _:_Error ->
        io:format("do handle_info Msg:~w, Error:~w, ~p", [Msg, _Error, erlang:get_stacktrace()]),
        {noreply, State}
    end.

do_handle_info({gm_start, LastTime}, State) ->
    case State#guild_war.end_time > 0 of
        true  ->
            {noreply, State};
        false ->
            Now = utime:unixtime(),
            put(gm, erlang:send_after(LastTime*1000, self(), act_end)),
            do_handle_info({act_begin, Now, Now + LastTime}, State)
    end;
do_handle_info(gm_end, State) ->
    util:cancel_timer(erase(gm)),
    case State#guild_war.end_time =:= 0 of
        true  ->
            {noreply, State};
        false ->
            do_handle_info(act_end, State)
    end;

%% 活动流程-活动开启
do_handle_info({act_begin, _, _}, #guild_war{end_time = EndTime} = State)
    when EndTime > 0 ->
    %% 已经开启了，就忽略
    ?ERR("repeat receive begin msg"),
    {noreply, State};
do_handle_info({act_begin, BeginTime, EndTime}, _) ->
    [Time|T] = ?GUILD_WAR_CYCLE_BOSS_REBORN_TIME,
    State = #guild_war{
        begin_time = BeginTime
        , end_time = EndTime
        , guild_war_pool = [#guild_war_pool{}] %% 默认开一个分区，防止一开始没人进去，一直不创建BOSS
        , ref_cycle_add_score = set_timer_cycle_add_score()
        , ref_boss_reborn = set_timer_cycle_boss_reborn(Time)
        , boss_reborn_time = T
    },
    %% 传闻活动开启
    lib_chat:send_TV({all}, ?MOD_GUILD_WAR, 1, []),
    %% 判断托管
    offline_hosting_guild_war:check_hosting(),
    {noreply, State};

%% 循环给场景内玩家加积分
do_handle_info(cycle_add_score, State) when State#guild_war.end_time > 0 ->
    SceneId = ?GUILD_WAR_SCENE,
    [
        guild_war_logic:cycle_add_score(SceneId, PoolId)
        || #guild_war_pool{pool_id = PoolId} <- State#guild_war.guild_war_pool
    ],
    {noreply, State#guild_war{ref_cycle_add_score = set_timer_cycle_add_score()}};

%% 增加积分-打怪/杀人/采集
do_handle_info({add_score, RoleId, Score, Type, _TypeValue}, State) ->
    #guild_war{
        role_grade = RoleGrade,
        guild_grade = GuildGrade,
        broadcast_event_time = LastTime
    } = State,
    case dict:find(RoleId, RoleGrade) of
        {ok, #guild_war_role{score = OldScore, guild_id = GuildId, picture = Picture} = Value} ->
            Now = utime:unixtime(),
            %% 个人加分
            NewScore = OldScore + Score,
            guild_war_logic:check_send_score_reward(RoleId, NewScore, OldScore),
            NewValue = Value#guild_war_role{score = NewScore, time = Now},
            NewRoleGrade = dict:store(RoleId, NewValue, RoleGrade),
            {ok, Bin} = pt_405:write(40503, [NewScore]),
            lib_server_send:send_to_uid(RoleId, Bin),
            %% 社团加分
            NewGuildGrade =
                case lists:keyfind(GuildId, #guild_war_guild.guild_id, GuildGrade) of
                    #guild_war_guild{score = GuildScore} = One  ->
                        lists:keyreplace(GuildId, #guild_war_guild.guild_id, GuildGrade,
                            One#guild_war_guild{score = GuildScore + Score, time = Now});
                    _ ->
                        GuildGrade
                end,
            %% 做1秒CD
            case Now - LastTime > ?GUILD_WAR_BROADCAST_CD of
                true  ->
                    %% 积分增加广播
                    case Type  of
                        collect ->
                            {ok, Bin2} = pt_405:write(40512, [Picture, 1, Score, ""]);
                        boss_last_attack ->
                            {ok, Bin2} = pt_405:write(40512, [Picture, 3, Score, ""]);
                        _ ->
                            Bin2 = ignore
                    end,
                    Bin2 =/= ignore andalso [
                        lib_server_send:send_to_scene(?GUILD_WAR_SCENE, PoolId, Bin2)
                        || #guild_war_pool{pool_id = PoolId} <- State#guild_war.guild_war_pool
                    ],
                    NewTime = Now;
                false ->
                    NewTime = LastTime
            end,
            NewState = State#guild_war{
                role_grade = NewRoleGrade,
                guild_grade = NewGuildGrade,
                broadcast_event_time = NewTime
            },
            {noreply, NewState};
        _ ->
            {noreply, State}
    end;

%% 击杀玩家-击杀玩家需要根据连杀数计算积分
do_handle_info({kill_man, Killer, Dead, Scene, PoolId, CopyId}, State) ->
    #guild_war{role_grade = RoleGrade} = State,
    case dict:find(Killer, RoleGrade) of
        {ok, #guild_war_role{continue_kill = KillerContinueKill, max_kill = MaxKiller, picture = KillerPicture} = KillerInfo} ->
            case dict:find(Dead, RoleGrade) of
                {ok, #guild_war_role{continue_kill = DeadContinueKill, picture = DeadPicture} = DeadInfo} ->
                    NewKillerContinueKill = KillerContinueKill + 1,
                    BaseScore = ?GUILD_WAR_KILL_BASE_SCORE,
                    KillerContinueKillRatio = data_guild_war:get_guild_war_continue_kill_ratio(NewKillerContinueKill),
                    DeadContinueKillRatio   = data_guild_war:get_guild_war_extra_ratio(DeadContinueKill),
                    Score = round(BaseScore * (1 + KillerContinueKillRatio) * (1 + DeadContinueKillRatio)),
                    %% 凶手连杀+1
                    NewKillerInfo = KillerInfo#guild_war_role{continue_kill = NewKillerContinueKill, max_kill = MaxKiller + 1, kill_time = utime:unixtime()},
                    %% 死者连杀清空
                    NewDeadInfo   = DeadInfo#guild_war_role{continue_kill = 0},
                    %% 判断连杀传闻
                    guild_war_logic:check_continue_kill_TV(NewKillerInfo),
                    %% 判断终结传闻
                    guild_war_logic:check_end_kill_TV(NewKillerInfo, DeadInfo),
                    %% 推送连杀
                    lib_game:send_battle_continue_kill(Killer, NewKillerContinueKill),
                    %% 推送连杀
                    lib_game:send_battle_continue_kill(Dead, 0),
                    %% 击杀广播
                    case DeadContinueKill >= 10 of
                        true  ->
                            KillType = 2;
                        false ->
                            KillType = 1
                    end,
                    lib_game:send_battle_kill_info(Scene, PoolId, CopyId, KillerPicture, DeadPicture, KillType),

                    RoleGrade1 = dict:store(Killer, NewKillerInfo, RoleGrade),
                    RoleGrade2 = dict:store(Dead, NewDeadInfo, RoleGrade1),
                    do_handle_info({add_score, Killer, Score, kill_man, DeadPicture#rec_picture.name}, State#guild_war{role_grade = RoleGrade2});
                _ ->
                    {noreply, State}
            end;
        _ ->
            {noreply, State}
    end;
%% 连杀数更新
do_handle_info({update_continue_kill, RoleId, Value}, State) ->
    #guild_war{role_grade = RoleGrade} = State,
    case dict:find(RoleId, RoleGrade) of
        {ok, #guild_war_role{continue_kill = ContinueKill} = RoleInfo} ->
            NewContinueKill = case Value =:= 0 of
                                  true  -> 0;
                                  false -> ContinueKill + 1
                              end,
            NewRoleInfo = RoleInfo#guild_war_role{continue_kill = NewContinueKill},
            NewRoleGrade = dict:store(RoleId, NewRoleInfo, RoleGrade),
            {noreply, State#guild_war{role_grade = NewRoleGrade}};
        _ ->
            {noreply, State}
    end;

%% 循环重生BOSS
do_handle_info(cycle_boss_reborn, State) when State#guild_war.end_time > 0 ->
    #guild_war{boss_reborn_time = TimeCfg} = State,
    [
        guild_war_logic:cycle_boss_reborn(PoolInfo)
        || PoolInfo <- State#guild_war.guild_war_pool
    ],
    case TimeCfg of
        [Time|T] ->
            NewState = State#guild_war{
                boss_reborn_time = T,
                ref_boss_reborn  = set_timer_cycle_boss_reborn(Time)
            },
            {noreply, NewState};
        _ ->
            {noreply, State}
    end;

%% BOSS出生记录
do_handle_info({boss_alive_state, PoolId, Alive}, State) ->
    PoolInfo = State#guild_war.guild_war_pool,
    case lists:keyfind(PoolId, #guild_war_pool.pool_id, PoolInfo) of
        #guild_war_pool{} = One ->
            Pool = One#guild_war_pool{boss_alive = Alive};
        false ->
            Pool = #guild_war_pool{pool_id = PoolId, boss_alive = Alive}
    end,
    NewPoolInfo = lists:keystore(PoolId, #guild_war_pool.pool_id, PoolInfo, Pool),
    {noreply, State#guild_war{guild_war_pool = NewPoolInfo}};

%% 活动流程-活动结束-结算
do_handle_info(act_end, State) when State#guild_war.end_time > 0 ->
    %% 托管结束
    Pid = State#guild_war.pull_host_pid,
    misc:is_process_alive(Pid) andalso erlang:exit(Pid, kill),
    guild_war_logic:act_settlement(State),
    {noreply, #guild_war{}};

%% 关闭活动
do_handle_info(close_act, _State) ->
    SceneId = ?GUILD_WAR_SCENE,
    [
        begin
        %% 踢人
            lib_scene:kick_players_out_scene(SceneId, PoolId, []),
            %% 关闭场景
            mod_scene_agent:close_scene(SceneId, PoolId)
        end
        || PoolId <- scene_mgr:get_scene_pool_ids(SceneId)
    ],
    {noreply, #guild_war{}};

%% 注册拉取托管进程
do_handle_info({register_host, Pid}, State) ->
    {noreply, State#guild_war{pull_host_pid = Pid}};

do_handle_info(_Info, State) ->
    io:format("time:[~p], module:~p: handle_info unexpect message:~p~n", [erlang:localtime(), ?MODULE, _Info]),
    {noreply, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any
%% necessary cleaning up. When it returns, the gen_server terminates
%% with Reason. The return value is ignored.
%%
%% @spec terminate(Reason, State) -> void()
%% @end
%%--------------------------------------------------------------------
-spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
    State :: #guild_war{}) ->
    term()).
terminate(_Reason, _State) ->
    ok.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Convert process state when code is changed
%%
%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
%% @end
%%--------------------------------------------------------------------
-spec(code_change(OldVsn :: term() | {down, term()}, State :: #guild_war{},
    Extra :: term()) ->
    {ok, NewState :: #guild_war{}} | {error, Reason :: term()}).
code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

%%%===================================================================
%%% Internal functions
%%%===================================================================
%% 开启循环加积分定时器
set_timer_cycle_add_score() ->
    erlang:send_after(?GUILD_WAR_CYCLE_ADD_SCORE_TIME*1000, self(), cycle_add_score).

%% 开启循环重生怪物定时器
set_timer_cycle_boss_reborn(Time) ->
    erlang:send_after(Time*1000, self(), cycle_boss_reborn).

%% 判断是否进入了新的分线
check_enter_new_pool(PoolId, PoolInfo) ->
    case lists:keyfind(PoolId, #guild_war_pool.pool_id, PoolInfo) of
        #guild_war_pool{role_num = Num} = One  ->
            NewNum = Num + 1,
            NewPoolInfo = lists:keyreplace(PoolId, #guild_war_pool.pool_id, PoolInfo, One#guild_war_pool{role_num = NewNum}),
            check_init_new_pool(?GUILD_WAR_SCENE, NewPoolInfo, NewNum),
            NewPoolInfo;
        false ->
            %% 该分线第一次有人进入，记录分线数据
            [#guild_war_pool{pool_id = PoolId, role_num = 1}|PoolInfo]
    end.

check_init_new_pool(SceneId, PoolInfo, NewNum) ->
    case data_scene_other:get(SceneId) of
        #ets_scene_other{room_max_people = Max} when NewNum >= Max ->
            AllFull = lists:all(fun(#guild_war_pool{role_num = RoleNum}) -> RoleNum >= Max end, PoolInfo),
            case AllFull of
                true  ->
                    #guild_war_pool{pool_id = MaxPool} = ulists:keymax(#guild_war_pool.pool_id, PoolInfo),
                    mod_scene_agent:get_scene_pid(SceneId, MaxPool + 1);
                false ->
                    ok
            end;
        _ ->
            ok
    end.



