%%% -------------------------------------------------------
%%% @author < >
%%% @doc
%%% @end
%%% -------------------------------------------------------
-module(cli_scene).
-export([
        handle/3
        , async_load_scene/0
        , after_load_scene/1
        %% 角色进程中专用，获取怪物及角色列表使用
        , get_mon_list/0
        , get_scene_role_list/0
    ]).
-include("cli_simu.hrl").

%% 走路返回
handle(12001, CliRole = #cli_role{id = MyId}, [Id, NewX, NewY]) ->
    case MyId =:= Id of
        true  ->
            CliRole#cli_role{x = NewX, y = NewY};
        false ->
            ignore
    end;

%% 加载场景对象
handle(12002, CliRole, [RoleList, MonList, _DummyList]) ->
    %% 保存场景角色列表和场景怪物列表
    put_scene_role_list(RoleList),
    put_mon_list(MonList),
    NewCliRole = update_me(CliRole, RoleList),
    NewCliRoleEnd = after_load_scene(NewCliRole),
    {ok, NewCliRoleEnd};

%% 角色进入通知
handle(12003, _CliRole, EnterRole = #scene_role{id = EnterId}) ->
    OtherRoleList = get_scene_role_list(),
    NewOtherRoleList = lists:keystore(EnterId, #scene_role.id, OtherRoleList, EnterRole),
    put_scene_role_list(NewOtherRoleList),
    ok;

%% 角色离开通知（消失）
handle(12004, _CliRole, LeavaRoleId) ->
    SceneRoleList = get_scene_role_list(),
    NewSceneRoleList = lists:keydelete(LeavaRoleId, #scene_role.id, SceneRoleList),
    put_scene_role_list(NewSceneRoleList),
    ok;

%% 场景对象移除通知
handle(12006, _CliRole, LeaveId) ->
    MonList = get_mon_list(),
    NewMonList = lists:keydelete(LeaveId, #cli_mon.id, MonList),
    put_mon_list(NewMonList),
    ok;

%% 怪物进入通知
handle(12007, _CliRole, EnterMon = #cli_mon{id = MonId}) ->
    CliMonList = get_mon_list(),
    NewCliMonList = lists:keystore(MonId, #cli_mon.id, CliMonList, EnterMon),
    put_mon_list(NewCliMonList),
    ok;

%% 场景对象更新坐标
handle(12008, _CliRole, [X, Y, Id]) ->
    CliMonList = get_mon_list(),
    case lists:keyfind(Id, #cli_mon.id, CliMonList) of
        CliMon = #cli_mon{} ->
            NewCliMon = CliMon#cli_mon{x = X, y = Y},
            NewCliMonList = lists:keystore(Id, #cli_mon.id, CliMonList, NewCliMon),
            put_mon_list(NewCliMonList);
        _ ->
            ignore
    end,
    ok;

handle(_, _, _) ->
    ignore.

%% 触发加载场景
async_load_scene() ->
    cli_simu_proto:pack_send(12002, []),
    ok.

%% -------------------------------------------------------------------
%% 在登录并加载场景完成后，执行各种自定义操作
%%     如果等级不足，使用GM命令升级到150级
%%     如果不在特定场景，使用GM命令进入指定场景区域
%%     发现附近的怪物，并进行战斗操作
%% -------------------------------------------------------------------

%% 加载场景完成触发，在其后添加各种自定义操作
after_load_scene(State = #cli_role{id = _RoleId, scene_id = _SceneId,
        figure = #figure{lv = Level}, pid = Pid, socket = Socket}) ->
    %% ?INFO_TTY("id:~w, lv:~w, scene:~w", [_RoleId, Level, _SceneId]),
    %% 检测设置等级
    MinLevel = 150,
    case Level < MinLevel of
        true  -> cli_gm:set_level(Socket, MinLevel);
        false -> ignore
    end,
    %% 获取新手装
    %% （如果集中请求容易导致服务器数据库阻塞，
    %% 所以随机一个时间段进行操作）
    RandMilliSecs = urand:rand(2000, 120000),
    erlang:start_timer(RandMilliSecs, self(), get_equips),
    %% 设置PK状态为强制（有些设定是全体不可以手动切换，用强制比较通用）
    cli_player:set_pk(Socket, 1),
    %% 开始进行随机自动行为
    Timer = erlang:start_timer(urand:rand(1000, 2000), Pid, auto_do),
    put({timer, auto_do}, Timer),
    State.

%% 角色列表
get_scene_role_list() ->
    case get(scene_role_list) of
        [_|_] = OtherRoleList -> OtherRoleList;
        _ -> []
    end.
put_scene_role_list(OtherRoleList) when is_list(OtherRoleList) ->
    put(scene_role_list, OtherRoleList).

get_mon_list() ->
    case get(cli_mon_list) of
        [_|_] = CliMonList -> CliMonList;
        _ -> []
    end.
put_mon_list(MonList) when is_list(MonList) ->
    put(cli_mon_list, MonList).

update_me(CliRole = #cli_role{id = RoleId}, RoleList) ->
    case lists:keyfind(RoleId, #scene_role.id, RoleList) of
        #scene_role{x = X, y = Y, hp = Hp, hp_lim = HpLim} ->
            CliRole#cli_role{x = X, y = Y, hp = Hp, hp_lim = HpLim};
        _ ->
            CliRole
    end.

