%%%-----------------------------------
%%% @Module  : lib_mon
%%% @Author  : zzm
%%% @mail    : ming_up@163.com
%%% @Created : 2010.05.08
%%% @Description: 怪物接口，封装了lib_scene_object接口
%%%-----------------------------------
-module(lib_mon).

-include("scene.hrl").
-include("server.hrl").
-include("battle.hrl").
-include("attr.hrl").
%% 对外接口
-export([
        sync_create_mon/9                %% 同步创建怪物
        , async_create_mon/9             %% 异步创建怪物
        , get_scene_mon/4                %% 获取场景内所有怪物属性
        , get_scene_mon_by_ids/4         %% 根据怪物id获取属性
        , get_scene_mon_by_mids/5        %% 根据怪物资源id获取属性
        , get_scene_mon_battle_attr_by_ids/4
        , clear_scene_mon/4              %% 清理场景所有怪物
        , clear_scene_dummy/4            %% 清理场景所有假人
        , kill_scene_mon/3               %% 杀死全场景怪物
        , clear_scene_mon_by_ids/4       %% 根据怪物id清理怪物
        , clear_scene_mon_by_mids/5      %% 根据怪物资源id清理怪物
        , create_mon_on_user/7           %% 在玩家位置上创建怪
        , ac_skill/4                     %% 怪物释放某个技能
        , ac_skill/6
        , clean_buff/5                   %% 怪物移除BUFF
        % , apply_info/6                   %% 怪物进程info方式执行MFA
        , change_attr_by_ids/4
        , change_attr_by_mids/5
]).

%% 对场景怪物模块内部接口
-export([
        get_name_by_mon_id/1,
        get_hplim_by_mon_id/1,
        deal_with_alive_mon_hp/2
    ]).

%% 同步创建怪物
%% MonId 怪物资源ID
%% Scene 场景ID
%% ScenePoolId 场景进程id
%% X 坐标
%% X 坐标
%% Type       怪物战斗类型（0被动，1主动）
%% CopyId     房间号ID 为0时，普通房间，非0值切换房间。值相同，在同一个房间。
%% BroadCast  是否出生时广播（0不广播，1广播）
%% Args       其余动态创建属性
%%            = list() = [Tuple1, Tuple2...]
%%     Tuple1 = tuple(), {auto_lv, V} | {group, V}

%%  @returne MonAutoId 怪物自增ID，每个怪物唯一
sync_create_mon(MonId, Scene, ScenePoolId, X, Y, Type, CopyId, BroadCast, Args) ->
    lib_scene_object:sync_create_object(?BATTLE_SIGN_MON, MonId, Scene, ScenePoolId, X, Y, Type, CopyId, BroadCast, Args).

%% 异步创建怪物
async_create_mon(MonId, Scene, ScenePoolId, X, Y, Type, CopyId, BroadCast, Args) ->
    lib_scene_object:async_create_object(?BATTLE_SIGN_MON, MonId, Scene, ScenePoolId, X, Y, Type, CopyId, BroadCast, Args).


%% 更新怪物属性
change_attr_by_ids(Scene, ScenePoolId, Ids, KeyValues) ->
    lib_scene_object:change_attr_by_ids(Scene, ScenePoolId, Ids, KeyValues).

change_attr_by_mids(Scene, ScenePoolId, CopyId, Ids, KeyValues) ->
    lib_scene_object:change_attr_by_mids(Scene, ScenePoolId, CopyId, Ids, KeyValues).

%% 按格式返回怪物属性
%% SceneId    = int()              场景id
%% ScenePoolId = int()             场景进程id
%% CopyId     = [] | int() | pid() 房间id
%% ResultForm = list()             [#scene_object.xx1, #scene_object.xx2...] | all | #scene_object.xx1 属性组装列表或者单项属性, 复合属性暂不支持
get_scene_mon(SceneId, ScenePoolId, CopyId, ResultForm) ->
    mod_scene_agent:apply_call(SceneId, ScenePoolId, lib_scene_object_agent, get_scene_object, [CopyId, ResultForm]).

%% 按格式返回怪物属性
%% SceneId    = int()           场c景id
%% Ids        = list()          怪物唯一Id列表
%% ResultForm = list()          同get_scene_mon/4
get_scene_mon_by_ids(SceneId, ScenePoolId, Ids, ResultForm) ->
    mod_scene_agent:apply_call(SceneId, ScenePoolId, lib_scene_object_agent, get_scene_object_by_ids, [Ids, ResultForm]).

%% 按格式返回怪物属性
%% SceneId    = int()              场景id
%% CopyId     = [] | int() | pid() 房间id
%% Mids       = list()             怪物类型id
%% ResultForm = list()|int()       同get_scene_mon/4
get_scene_mon_by_mids(SceneId, ScenePoolId, CopyId, Mids, ResultForm) ->
    mod_scene_agent:apply_call(SceneId, ScenePoolId, lib_scene_object_agent, get_scene_mon_by_mids, [CopyId, Mids, ResultForm]).

%% 按格式返回怪物战斗属性
%% SceneId    = int()           场景id
%% Ids        = list()          怪物唯一Id列表
%% ResultForm = list()          [#battle_attr.xx1, #battle_attr.xx2...] | all | #battle_attr.xx1 属性组装列表或者单项属性, 复合属性暂不支持
get_scene_mon_battle_attr_by_ids(SceneId, ScenePoolId, Ids, ResultForm) ->
    mod_scene_agent:apply_call(SceneId, ScenePoolId, lib_scene_object_agent, get_scene_object_battle_attr_by_ids, [Ids, ResultForm]).

%% 清除全场景的怪物
%% SceneId    = int()                 场景ID
%% ScenePoolId= int()
%% CopyId     = int() | pid()         房间id,不分房间清理时置为 []
%% BroadCast  = 0 | 1                 是否需要在清除的时候广播(0不广播，1广播)
clear_scene_mon(SceneId, ScenePoolId, CopyId, BroadCast) ->
    lib_scene_object:clear_scene_object(?BATTLE_SIGN_MON, SceneId, ScenePoolId, CopyId, BroadCast),
    ok.

clear_scene_dummy(SceneId, ScenePoolId, CopyId, BroadCast) ->
    lib_scene_object:clear_scene_object(?BATTLE_SIGN_DUMMY, SceneId, ScenePoolId, CopyId, BroadCast),
    ok.

%% 杀死全场景怪物，会播死亡动画
kill_scene_mon(SceneId, ScenePoolId, CopyId) ->
    lib_scene_object:kill_scene_object(?BATTLE_SIGN_MON, SceneId, ScenePoolId, CopyId),
    ok.

%% 清除id怪物
%% SceneId    = int()                 场景ID
%% BroadCast  = 0 | 1                 是否需要在清除的时候广播(0不广播，1广播)
%% Ids        = list()                怪物唯一Id列表 #scene_object.id
clear_scene_mon_by_ids(SceneId, ScenePoolId, BroadCast, Ids) ->
    lib_scene_object:clear_scene_object_by_ids(SceneId, ScenePoolId, BroadCast, Ids),
    ok.

%% 清除场景相同mid的怪物
%% SceneId    = int()                 场景ID
%% CopyId     = int() | pid()         房间id,不分房间清理时置为 []
%% BroadCast  = 0 | 1                 是否需要在清除的时候广播(0不广播，1广播)
%% Mids       = list()                怪物资源Id列表 #scene_object.mon#scene_mon.mid
clear_scene_mon_by_mids(SceneId, ScenePoolId, CopyId, BroadCast, Mids) ->
    mod_scene_agent:apply_cast(SceneId, ScenePoolId, lib_scene_object_agent, clear_scene_mon_by_mids, [CopyId, BroadCast, Mids]),
    ok.
%% 在玩家的位置上创建怪
%% Mid 怪物id IsActive是否主动 OtherArgs怪物参数
create_mon_on_user(SceneId, ScenePoolId, CopyId, Data, Mid, IsActive, OtherArgs) ->
    mod_scene_agent:apply_cast(SceneId, ScenePoolId, lib_scene_agent, create_mon_on_user, [CopyId, Data, Mid, IsActive, OtherArgs]),
    ok.

% 不应该通过场景中转消息，多余
% %% 怪物进程info方式执行MFA
% %% SceneId     = int()                场景id
% %% ScenePoolId = int()                场景进程id
% %% MonPid      = integer() | pid()    怪物唯一Id或者怪物进程pid
% %% Moudle      = atom()               模块名
% %% Method      = atom()               方法名
% %% Args        = term()               方法实参
% apply_info(SceneId, ScenePoolId, MonPid, Moudle, Method, Args) ->
%     lib_scene_object:apply_info(SceneId, ScenePoolId, MonPid, Moudle, Method, Args),
%     ok.

%% 向场景怪物发送技能释放命令
ac_skill(SceneId, PoolId, CopyId, MonIds, SkillId, SkillLv) ->
    mod_scene_agent:apply_cast(SceneId, PoolId, lib_scene_object_agent, mon_ac_skill, [CopyId, MonIds, SkillId, SkillLv]),
    ok.

%% 通知怪物释放技能
%% MonIdData :: MonId | [MonId]
ac_skill(Aid, MonIdData, SkillId, SkillLv) ->
    % old: Aid ! {ac_skill, SkillId, SkillLv}.
    mon_mgr:send(Aid, MonIdData, {ac_skill, SkillId, SkillLv}).

%% 怪物移除BUFF
clean_buff(SceneId, PoolId, CopyId, MonIds, SkillId) ->
    mod_scene_agent:apply_cast_with_scene(SceneId, PoolId, lib_scene_object_agent, clean_buff, [CopyId, MonIds, SkillId]),
    ok.

%% 获取怪物名称 MonId:怪物配置id
get_name_by_mon_id(MonId)->
    case data_mon:get(MonId) of
        [] -> <<>>;
        Mon -> util:make_sure_binary(Mon#mon.name)
    end.

get_hplim_by_mon_id(MonId)->
    case data_mon:get(MonId) of
        [] -> 0;
        Mon -> Mon#mon.hp_lim
    end.

%% 不死怪血量处理
deal_with_alive_mon_hp(
    #scene_object{
        sign = ?BATTLE_SIGN_MON,
        mon = #scene_mon{kind = ?MON_KIND_NORMAL, boss = Boss},
        battle_attr = #battle_attr{hp = BeforeHp}},
    NowHp) when Boss =:= ?MON_KEEP_ALIVE orelse Boss =:= ?MON_REWARD_BOSS->
    case BeforeHp > ?KEEP_ALIVE_MON_DIE_HP of
        true  ->
            BeforeHp;
        false ->
            NowHp
    end;
deal_with_alive_mon_hp(_, NowHp) -> NowHp.
    

