%%-----------------------------------------------------------------------------
%% @Module  :       lib_dummy_api.erl
%% @Author  :       J
%% @Email   :       j-som@foxmail.com
%% @Created :       2018-01-12
%% @Description:    假人接口
%%-----------------------------------------------------------------------------

-module (lib_dummy_api).

-include ("figure.hrl").
-include ("server.hrl").
-include ("attr.hrl").
-include ("skill.hrl").
-include("predefine.hrl").
-include("common.hrl").
-include("battle.hrl").
-include("mon.hrl").

-export([
    create_role_dummy/7, create_role_dummy_in_role/7, create_role_dummy_do/6,
    create_role_dummy_by_center/8, create_role_dummy_by_node/8, create_role_dummy_by_role/8, create_role_dummy_by_center_to_node/7
]).

-export ([change_figure/2, get_skill_list/1, change_battle_attr/2]).

%%  创建某个玩家的镜像
%%      -完整拿玩家的形象/属性/技能数据（快捷栏上阵的技能）
%%  在跨服调用:  1.将玩家镜像创建到跨服场景-支持
%%             2.将玩家镜像创建到本服场景-不支持, 需要指定游戏服节点
%%  游戏服调用:  1.将其他服玩家镜像创建到本服或跨服场景-支持
%%             2.将本服玩家镜像创建到本服或跨服场景-支持
%%  Arg: 怪物参数
%%      find_type       选取攻击目标类型
%%      revive_time     复活时间/未定义则判断stay_dead
%%      stay_dead       是否保持死亡状态，如果没有设置复活时间，则会销毁
%%      find_target     指定时间后自动战斗
%%      born_handler    假人创建成功回调
%%      TODO 属性调整
create_role_dummy(RoleId, SceneId, PoolId, CopyId, X, Y, Args) ->
    case clusters_api:is_center() of
        true  ->
            case lib_scene:is_clusters_scene(SceneId) of
                true  ->
                    Node = clusters_center:get_node_by_role_id(RoleId),
                    clusters_center:apply_cast(Node, ?MODULE, create_role_dummy, [RoleId, SceneId, PoolId, CopyId, X, Y, Args]);
                false ->
                    ?ERR("不可以在跨服中心创建镜像到游戏服场景"),
                    error
            end;
        false ->
            RoleServer = mod_player_create:get_real_serid_by_id(RoleId),
            case config:get_server_id() =:= RoleServer of
                true  ->
                    lib_player:apply_cast(RoleId, ?APPLY_CAST_STATUS, ?HAND_OFFLINE, ?MODULE, create_role_dummy_in_role, [SceneId, PoolId, CopyId, X, Y, Args]);
                false ->
                    case lib_scene:is_clusters_scene(SceneId) of
                        true  ->
                            %% 通过跨服中心中转到对应游戏服创建镜像到跨服场景
                            clusters_node:apply_cast(?MODULE, create_role_dummy, [RoleId, SceneId, PoolId, CopyId, X, Y, Args]);
                        false ->
                            %% 通过跨服中心中转到对应游戏服，然后再通过跨服中心回传到本服创建镜像
                            clusters_node:apply_cast(?MODULE, create_role_dummy_by_center, [node(), RoleId, SceneId, PoolId, CopyId, X, Y, Args])
                    end
            end
    end.

%% 创建他的镜像
create_role_dummy_in_role(Player, SceneId, PoolId, CopyId, X, Y, Args) ->
    MonArgs = role_dummy_data(Player, Args),
    create_role_dummy_do(SceneId, PoolId, CopyId, X, Y, MonArgs).

%% 在玩家进程或者离线管理进程获取玩家数据
role_dummy_data(Player, Args) ->
    #player_status{
        figure = Figure,
        battle_attr = #battle_attr{attr = Attr},
        passive_skills = PassiveSkills,
        id = RoleId
    } = Player,
    ActiveSkills = get_skill_list(Player),
    BattleAttr = lib_player_attr:attr_to_battle_attr(Attr),
    Args ++ [
        {figure, Figure},
        {battle_attr, BattleAttr},
        {skill, ActiveSkills},
        {skill_passive, PassiveSkills},
        {dummy, #scene_dummy{
            server_num = config:get_server_num(),
            server_id = config:get_server_id(),
            node = node()
        }},
        {skill_owner, #skill_owner{id = RoleId, sign = ?BATTLE_SIGN_PLAYER}}
    ].

create_role_dummy_do(SceneId, PoolId, CopyId, X, Y, MonArgs) ->
    lib_scene_object:async_create_object(?BATTLE_SIGN_DUMMY, 0, SceneId, PoolId, X, Y, 1, CopyId, 1, MonArgs).
%%%-------------------------------------------------------------------
%%% @doc
%%%    通过跨服中心中转到对应游戏服，然后再通过跨服中心回传到本服创建镜像
%%% @end
%%%-------------------------------------------------------------------
%% 通过跨服中心中转到镜像玩家节点
create_role_dummy_by_center(Node, RoleId, SceneId, PoolId, CopyId, X, Y, Arg) ->
    RoleNode = clusters_center:get_node_by_role_id(RoleId),
    clusters_center:apply_cast(RoleNode, ?MODULE, create_role_dummy_by_node, [Node, RoleId, SceneId, PoolId, CopyId, X, Y, Arg]).

%% 在镜像玩家节点创建数据
create_role_dummy_by_node(ToNode, RoleId, SceneId, PoolId, CopyId, X, Y, Arg) ->
    lib_player:apply_cast(RoleId, ?APPLY_CAST_STATUS, ?HAND_OFFLINE, ?MODULE, create_role_dummy_by_role, [ToNode, SceneId, PoolId, CopyId, X, Y, Arg]).

%% 在镜像玩家进程或者离线管理进程创建数据
create_role_dummy_by_role(Player, ToNode, SceneId, PoolId, CopyId, X, Y, Args) ->
    MonArgs = role_dummy_data(Player, Args),
    clusters_node:apply_cast(?MODULE, create_role_dummy_by_center_to_node, [ToNode, SceneId, PoolId, CopyId, X, Y, MonArgs]).

%% 通过跨服中心中转回创建进程节点
create_role_dummy_by_center_to_node(ToNode, SceneId, PoolId, CopyId, X, Y, MonArgs) ->
    clusters_center:apply_cast(ToNode, ?MODULE, create_role_dummy_do,  [SceneId, PoolId, CopyId, X, Y, MonArgs]).
%%%-------------------------------------------------------------------
%%%
%%%-------------------------------------------------------------------
change_figure(Figure, [rand_name|T]) ->
    change_figure(Figure#figure{name = ""}, T); %% 客户端有名字库，传空字符串给客户端，让客户端去随机

change_figure(Figure, [rand_fashion|T]) ->
    #figure{career = Career} = Figure,
    FashionList = lib_fashion:get_rand_fashion_model_list(Career),
    change_figure(Figure#figure{fashion_model = FashionList}, T);

change_figure(Figure, [create_name|T]) ->   %% 有些名字要跨好几个系统使用，所以服务端生成一个固定的
    #figure{sex = Sex} = Figure,
    Group = data_vsn:calc_name_group(),
    FirstName = urand:list_rand(data_role_name:first_name_list(Group, Sex)),
    LastName = urand:list_rand(data_role_name:last_name_list(Group)),
    change_figure(Figure#figure{name = LastName++FirstName}, T);

change_figure(Figure, [_|T]) ->
    change_figure(Figure, T);

change_figure(Figure, []) -> %% 最后清掉一些社交信息
    Figure#figure{
        picture = "",
        picture_ver = 0,
        guild_id = 0,
        guild_name = <<>>,
        position = 0,
        position_name = ""
    }.

change_battle_attr(BattleAttr, [{hp_r, R}|T]) ->
    Hp = trunc(BattleAttr#battle_attr.hp_lim * R),
    change_battle_attr(BattleAttr#battle_attr{hp = Hp, hp_lim = Hp}, T);

change_battle_attr(BattleAttr, [{att_r, R}|T]) ->
    Attr = BattleAttr#battle_attr.attr,
    Att = trunc(Attr#attr.att * R),
    change_battle_attr(BattleAttr#battle_attr{attr = Attr#attr{att = Att}}, T);

change_battle_attr(BattleAttr, [_|T]) ->
    change_battle_attr(BattleAttr, T);

change_battle_attr(BattleAttr, []) ->
    BattleAttr.

get_skill_list(Player) when is_record(Player, player_status) ->
    quickbar_api:quickbar_skills(Player);

get_skill_list(QuickBar) ->
    quickbar_api:quickbar_skills(QuickBar).
    
