%%%----------------------------------- %%% @Module : lib_task %%% @Author : xyao %%% @Created : 2010.05.05 %%% @Description: 任务 %%%----------------------------------- -module(lib_task). -compile(export_all). -include("scene.hrl"). -include("common.hrl"). -include("server.hrl"). -include("task.hrl"). -include("figure.hrl"). -include("team.hrl"). -include("errcode.hrl"). -include("predefine.hrl"). -include("def_module.hrl"). -include("goods.hrl"). -include("daily.hrl"). -include("def_fun.hrl"). -include("def_goods.hrl"). -include("guild_labor.hrl"). -include("dungeon.hrl"). -include("local_boss.hrl"). -define(LIMIT_TIME1, 900). -define(LIMIT_TIME2, 1800). %% 获取我的任务列表 get_my_task_list(TaskArgs)-> get_my_task_list(0,TaskArgs). get_my_task_list(Type,#task_args{id = RoleId, sid=Sid}=TaskArgs) -> %% 可接任务 F = fun(TD, TmpActiveList) -> case Type == 0 orelse TD#task.type == Type of true -> [{TD#task.id, get_tip(active, TD#task.id, TaskArgs)} | TmpActiveList]; false -> TmpActiveList end end, ActiveList = lists:foldl(F, [], get_active()), %% 已接任务 NowTime = utime:unixtime(), F1 = fun(RT, {TL, CL}) -> #role_task{task_id = TaskId, type = TaskType, trigger_time = TriggerTime, mark = Mark} = RT, if Type =/= 0 andalso TaskType =/= Type -> {TL, CL}; TaskType == ?TASK_TYPE_CHAPTER -> LimitTime = ?IF(TaskId == 101 orelse TaskId == 102, ?LIMIT_TIME1, ?LIMIT_TIME2), if NowTime > TriggerTime + LimitTime -> %% 大于限时 case is_finish_mark(Mark, TaskArgs) of false -> {TL, [RT|CL]}; true -> TipList = get_tip(trigger, TaskId, TaskArgs), {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(TipList), {[{TaskId, TipList, WitchState, NeedNum, NowNum, TriggerTime}|TL], CL} end; true -> TipList = get_tip(trigger, TaskId, TaskArgs), {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(TipList), {[{TaskId, TipList, WitchState, NeedNum, NowNum, TriggerTime}|TL], CL} end; true -> TipList = get_tip(trigger, TaskId, TaskArgs), {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(TipList), {[{TaskId, TipList, WitchState, NeedNum, NowNum, TriggerTime}|TL], CL} end end, {TriggerList, NeedToDelTask} = lists:foldl(F1, {[], []}, get_trigger()), %% 删除需要去掉的限时章节任务 F2 = fun(RT) -> #role_task{task_id = TaskId, type = TaskType, trigger_time = TriggerTime} = RT, add_log(RoleId, TaskId, TaskType, TriggerTime, 0, 0) %% 完成时间是0就代表过时 end, lists:map(F2, NeedToDelTask), {ok, BinData} = pt_300:write(30000, [Type, ActiveList, TriggerList]), lib_server_send:send_to_sid(Sid, BinData). %% 获取任务是否完成 get_task_finish_state(TaskId, TaskArgs)-> case get_one_trigger(TaskId) of false -> ?ERRCODE(err300_no_task_trigger); %% 没接这个任务 RT -> ?IF(is_finish(RT, TaskArgs), true, ?ERRCODE(err300_task_no_finish)) end. %% 获取任务类型 get_task_type(TaskId) -> TD = get_data(TaskId), ?IF(TD == null, 0, TD#task.type). %% 升级自动触发任务 lv_up(TaskArgs) -> %% 刷新缓存可以优化一下 refresh_active(TaskArgs), case auto_trigger(TaskArgs) of true -> skip; _ -> skip end, get_my_task_list(0, TaskArgs), refresh_npc_ico(TaskArgs). %% ================================= 登录加载数据 ================================= flush_role_task(TaskArgs) -> #task_args{id = Id} = TaskArgs, %% 所有已经触发的任务列表 F1 = fun([Tid, Tt, S ,ES, M, TP, Lv], AllTask) -> case data_task:get(Tid) of null -> del_trigger_from_sql(Id, Tid), %% 移除无效的已接任务 AllTask; _ -> Kind = case data_task_condition:get(Tid) of null -> 0; TD -> TD#task_condition.kind end, case util:bitstring_to_term(M) of undefined -> AllTask; Mark -> [#role_task{role_id=Id, lv = Lv, task_id=Tid, trigger_time = Tt, state = S, end_state = ES, mark = Mark, type=TP, kind = Kind}|AllTask] end end end, RoleTaskList = db:get_all(io_lib:format("select task_id, trigger_time, state, end_state, mark, type, lv from task_bag where role_id=~w", [Id])), RoleTaskListRed = lists:foldl(F1, [], RoleTaskList), set_task_bag_list(RoleTaskListRed), %% 所有已经完成的任务列表 F2 = fun([Tid2, Ty2]) -> put_task_log_list(Tid2,#role_task_log{type= Ty2}) end, RoleTaskLogList = db:get_all(io_lib:format("select task_id, type from task_log where role_id=~w", [Id])), lists:map(F2, RoleTaskLogList), refresh_active(TaskArgs), get_my_task_list(0, TaskArgs), %% 自动接取任务 auto_trigger(TaskArgs), auto_finish(TaskArgs), login_after(TaskArgs), ok. login_after(TaskArgs) -> %%同步转生任务id case get_task_bag_id_list_type(?TASK_TYPE_TURN) of [#role_task{task_id = TaskId} | _T] -> lib_task_event:trigger_after(data_task:get(TaskId), TaskArgs); _ -> ok end. %%上线处理已完成的触发任务 handle_refresh_trigger(TaskArgs)-> RoleTaskList = get_task_bag_id_list(), %%纠正配置不匹配任务 case catch do_refresh_conflict_trigger(RoleTaskList, TaskArgs, []) of UpdateList when is_list(UpdateList) -> case UpdateList =/= [] of true -> refresh_task(TaskArgs); false -> ok end; _Rson -> ?ERR("do_refresh_conflict_trigger~p~n",[_Rson]) end, NewRoleTaskList = get_task_bag_id_list(), %%自动完成已接取的特殊支线任务和可能离线完成的主线特殊任务(副本) case catch do_handle_refresh_trigger(NewRoleTaskList, TaskArgs, []) of [] -> ok; EventList when is_list(EventList) -> lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_STATUS, lib_task_api, cast_handle_refresh_trigger, [EventList]); _Reason -> Rid = TaskArgs#task_args.id, ?ERR("do_handle_refresh_trigger~p:~p~n",[Rid, _Reason]) end. %%纠正配置不匹配任务 do_refresh_conflict_trigger([], _TaskArgs, UpdateList) -> UpdateList; do_refresh_conflict_trigger([RT | T], TaskArgs, UpdateList) -> TD = data_task:get(RT#role_task.task_id), NewUpdateList = do_conflict_correct(TD, TaskArgs, RT, UpdateList), do_refresh_conflict_trigger(T, TaskArgs, NewUpdateList). %%检测条件 % 等级不匹配:直接清任务 % 任务内容不匹配:替换更新任务 do_conflict_correct(#task{type = Type} = TD, TaskArgs, RT, UpdateList) when Type == ?TASK_TYPE_MAIN orelse Type == ?TASK_TYPE_SIDE orelse Type == ?TASK_TYPE_TURN orelse Type == ?TASK_TYPE_CHAPTER orelse Type == ?TASK_TYPE_NUCLEON -> CheckList = [lv, content], case check_conflict(CheckList, TaskArgs, TD, RT) of {true, Reason, NewRT} -> do_conflict_correct_help(Reason, RT, NewRT), [1|UpdateList]; _ -> UpdateList end; do_conflict_correct(_, _TaskArgs, _RT, UpdateList) -> UpdateList. check_conflict([], _TaskArgs, _TD, _RT) -> true; check_conflict([lv | T], TaskArgs, TD, RT) -> Lv = TaskArgs#task_args.figure#figure.lv, case Lv < TD#task.level of true -> {true, del, RT}; false -> check_conflict(T, TaskArgs, TD, RT) end; check_conflict([content | T], TaskArgs, #task{content = Content} = TD, RT) -> CfgTaskMark = [content_to_mark(E, TaskArgs)|| E <- Content] ++ case TD#task.end_talk of 0 -> []; %% end_talk = 0则直接提交任务 _ -> [content_to_mark([TD#task.state, ?TASK_CONTENT_END_TALK, TD#task.end_npc, TD#task.end_talk, 0, 0, 0, TD#task.finish_pathfind], TaskArgs)] end, Mark = RT#role_task.mark, %%检测任务内容冲突(主要存在情况) case check_content_conflict(CfgTaskMark, Mark, RT, []) of {true, Mark, _NewRT} -> check_conflict(T, TaskArgs, TD, RT); {true, _NewMark, NewRT} -> %%与配置有出入,处理 % ?ERR("do_conflict_trigger~p,~p,~p~n", [TaskArgs#task_args.id, NewMark, Mark]), {true, update, NewRT}; _ -> check_conflict(T, TaskArgs, TD, RT) end; check_conflict([_H | T], TaskArgs, TD, RT) -> check_conflict(T, TaskArgs, TD, RT). check_content_conflict([], [], RT, NewMark) -> {true, NewMark, RT#role_task{mark = NewMark}}; check_content_conflict([], _, RT, NewMark) -> {true, NewMark, RT#role_task{mark = NewMark}}; check_content_conflict([CfgE | CfgT], [ME | MET], RT, NewMark) -> [State, _, ContentType, Id, NeedNum, RealSceneId, RealX, RealY, _, PathFind] = CfgE, case ME of [State, _Finish, ContentType, Id, NeedNum, RealSceneId, RealX, RealY, _Num, _PathFind] -> %%相同不处理 NewMark1 = NewMark ++ [ME], check_content_conflict(CfgT, MET, RT, NewMark1); [_, _, ContentType, Id, _, _, _, _, Num, _] -> %% 类型和id相同,保持数量不变,纠正其它信息 case Num >= NeedNum of true -> NewMark1 = NewMark ++ [[State, 1, ContentType, Id, NeedNum, RealSceneId, RealX, RealY, Num, PathFind]]; false -> FinishState = ?IF(ContentType == ?TASK_CONTENT_END_TALK, 1, 0), NewMark1 = NewMark ++ [[State, FinishState, ContentType, Id, NeedNum, RealSceneId, RealX, RealY, Num, PathFind]] end, check_content_conflict(CfgT, MET, RT, NewMark1); [_, _, _, _, _, _, _, _, _, _] -> %% 纠正所有信息 NewMark1 = NewMark ++ [CfgE], check_content_conflict(CfgT, MET, RT, NewMark1); _ -> ok %%异常 end; check_content_conflict([CfgE | CfgT], [], RT, NewMark) -> NewMark1 = NewMark ++ [CfgE], check_content_conflict(CfgT, [], RT, NewMark1). %%处理冲突的任务 do_conflict_correct_help(update, _OldRT, NewRT) -> #role_task{role_id = RId, task_id = TaskId, mark = Mark, end_state = EndState} = NewRT, NoFinishState = [EachState || [EachState, 0|_ ] <- Mark], if NoFinishState == [] -> NewState = EndState; true -> NewState = lists:min(NoFinishState) end, ?IF(NewState == 0, ok, refresh_npc_ico(RId)), upd_trigger(RId, TaskId, NewState, Mark), put_task_bag_list(NewRT#role_task{write_db = 0, state = NewState}), case NewState == EndState of true -> case lists:last(Mark) of [_, 1, ?TASK_CONTENT_END_TALK|_] -> ok; _R -> auto_finish_task(RId, TaskId) end; _ -> ok end; do_conflict_correct_help(del, _OldRT, NewRT) -> #role_task{role_id = RId, task_id = TaskId} = NewRT, %% 删除缓存 delete_task_bag_list(TaskId), %% 删除数据库 del_trigger_from_sql(RId, TaskId), %% 刷新npc头图标 refresh_npc_ico(RId), ok; do_conflict_correct_help(_, _OldRT, _NewRT) -> ok. %%处理已完成的触发支线任务 do_handle_refresh_trigger([], _TaskArgs, EventList) -> EventList; do_handle_refresh_trigger([#role_task{type = ?TASK_TYPE_SIDE, task_id = TaskId, mark = TaskMark} |T], TaskArgs, OEventList) -> EventList = handle_finish_before_trigger(TaskId, TaskMark, TaskArgs, []), do_handle_refresh_trigger(T, TaskArgs, OEventList ++ EventList); do_handle_refresh_trigger([#role_task{type = ?TASK_TYPE_MAIN, task_id = TaskId, mark = [ [_State, 0, ?TASK_CONTENT_DUNGEON|_T1] | _T2 ] = TaskMark } |T], TaskArgs, OEventList) -> EventList = handle_finish_before_trigger(TaskId, TaskMark, TaskArgs, []), do_handle_refresh_trigger(T, TaskArgs, OEventList ++ EventList); do_handle_refresh_trigger([_RT |T], TaskArgs, EventList) -> do_handle_refresh_trigger(T, TaskArgs, EventList). %% 刷新任务并发送更新列表 refresh_task(#task_args{id=Id}=TaskArgs) -> refresh_active(TaskArgs), refresh_npc_ico(Id), {ok, BinData} = pt_300:write(30006, []), lib_server_send:send_to_uid(Id, BinData). %% 遍历所有任务看是否可接任务 refresh_active(TaskArgs) -> #task_args{figure=#figure{lv=Lv}} = TaskArgs, Tids = data_task_lv:get_ids(Lv), F = fun(Tid) -> get_data(Tid) end, QueryCacheListRed = [F(Tid) || Tid <- Tids, check_task_type(Tid), can_trigger(Tid, TaskArgs) == true], set_query_cache_list(QueryCacheListRed). %% 日常和公会任务不会进入可接缓存 check_task_type(Tid)-> #task{type = TaskType} = get_data(Tid), ?IF(TaskType == ?TASK_TYPE_DAILY orelse TaskType == ?TASK_TYPE_GUILD, false, true). %% 刷新悬赏任务和公会周任务 refresh_trigger_by_type(TaskArgs, TaskType) -> TriggerTasks = get_trigger(), F1 = fun(RT, L) -> ?IF(RT#role_task.type =/= TaskType, [RT|L], L) end, NewTriggerList0 = lists:foldl(F1, [], TriggerTasks), KfDay = data_key_value:get(1030001), NewTriggerList = case util:get_open_day()>= KfDay of true-> fix_task_npc(NewTriggerList0,[],TaskArgs); _-> NewTriggerList0 end, set_task_bag_list(NewTriggerList). %% 获取任务详细数据 get_data(TaskId) -> TD = data_task:get(TaskId), ?IF(TD == null, #task{}, TD). %% 获取玩家能在该Npc接任务或者交任务 get_npc_task_list(NpcId, TaskArgs) -> {CanTrigger, Link, UnFinish, Finish} = get_npc_task(NpcId, TaskArgs), F1 = fun({Tid,TriTime,ShowTalk}, NS) -> TD = get_data(Tid), {Tid, NS, TD#task.name, TD#task.type,TriTime,ShowTalk} end, F2 = fun(TD, NS) -> {TD#task.id, NS, TD#task.name, TD#task.type,0,0} end, L1 = [F2(T1, 1) || T1 <- CanTrigger, T1#task.level =< TaskArgs#task_args.figure#figure.lv], L2 = [F1(T2, 4) || T2 <- Link], L3 = [F1(T3, 2) || T3 <- UnFinish], L4 = [F1(T4, 3) || T4 <- Finish], L1++L2++L3++L4. %% 动态控制npc do_dynamic_npc(TaskArgs, []) -> TaskArgs; do_dynamic_npc(#task_args{id=Id, npc_info=NpcInfo}=TaskArgs, NpcShow) -> NewNpcInfo = lib_npc:change_role_npc_info(Id, NpcInfo, NpcShow), lib_player:apply_cast(Id, ?APPLY_CAST_STATUS, lib_npc, update_role_npc_info, [NewNpcInfo]), TaskArgs#task_args{npc_info=NewNpcInfo}. %% 更新场景上npc的任务图标 refresh_npc_ico(#task_args{scene=Scene, sid=Sid, npc_info=NpcInfo}=TaskArgs) -> NpcList = lib_npc:get_scene_npc(Scene, NpcInfo), F = fun({Id, _, _, _, _, _}) -> S = ?IF(Id == 0, 0, get_npc_state(Id, TaskArgs)), [Id, S] end, L = lists:map(F, NpcList), {ok, BinData} = pt_120:write(12020, [L]), lib_server_send:send_to_sid(Sid, BinData); refresh_npc_ico(#player_status{} = PS) -> TaskArgs = lib_task_api:ps2task_args(PS), refresh_npc_ico(TaskArgs); refresh_npc_ico(PlayerId) -> case misc:get_player_process(PlayerId) of Pid when is_pid(Pid) -> lib_player:apply_cast(Pid, ?APPLY_CAST_STATUS, ?NOT_HAND_OFFLINE, lib_task, refresh_npc_ico, []); _ -> skip end. %% 获取npc任务状态 get_npc_state(NpcId, TaskArgs) -> {CanTrigger, Link, UnFinish, Finish} = get_npc_task(NpcId, TaskArgs), %% 0表示什么都没有,1表示有可接任务,2表示已接受任务但未完成,3表示有完成任务,4表示有任务相关 case length(Finish) > 0 of true -> 3; false -> case length(Link)>0 of true-> 4; false-> case length([0 || RT <- CanTrigger, RT#task.level =< TaskArgs#task_args.figure#figure.lv])>0 of true -> 1; false -> case length(UnFinish)>0 of true -> 2; false -> 0 end end end end. %% 获取npc任务关联 %%{可接任务,关联,任务未完成,完成任务} get_npc_task(NpcId, TaskArgs)-> CanTrigger = [ TS || TS <- get_query_cache_list(), lib_role_task:exchange_npc(TS#task.start_npc) =:= NpcId], %% 已经接了的任务处理 {Link, Unfinish, Finish} = get_npc_other_link_task(NpcId, TaskArgs), {CanTrigger, Link, Unfinish, Finish}. %% 获取已触发任务 get_npc_other_link_task(NpcId, TaskArgs) -> get_npc_other_link_task(get_task_bag_id_list(), {[], [], []}, NpcId, TaskArgs). get_npc_other_link_task([], Result, _, _) -> Result; get_npc_other_link_task([RT | T], {Link, Unfinish, Finish}, NpcId, TaskArgs) -> TD = get_data(RT#role_task.task_id), case is_finish(RT, TaskArgs) andalso get_end_npc_id(RT) =:= NpcId of %% 判断是否完成 true -> get_npc_other_link_task(T, {Link, Unfinish, Finish++[{RT#role_task.task_id,RT#role_task.trigger_time,filter_show_talk(RT#role_task.mark)}]}, NpcId, TaskArgs); false -> case task_talk_to_npc(RT, NpcId) of %% 判断是否和NPC对话 true -> get_npc_other_link_task(T, {Link++[{RT#role_task.task_id,RT#role_task.trigger_time,filter_show_talk(RT#role_task.mark)}], Unfinish, Finish}, NpcId, TaskArgs); false -> %% 获取npc未完成 case get_start_npc(TD#task.start_npc, TaskArgs#task_args.figure#figure.career) =:= NpcId of %% 判断是否接任务NPC true -> get_npc_other_link_task(T, {Link, Unfinish++[{RT#role_task.task_id,RT#role_task.trigger_time,filter_show_talk(RT#role_task.mark)}], Finish}, NpcId, TaskArgs); false -> get_npc_other_link_task(T, {Link, Unfinish, Finish}, NpcId, TaskArgs) end end end. %%过滤对话选项任务的完成TalkId filter_show_talk([])-> 0; filter_show_talk([H|T])-> case H of [_, _, ?TASK_CONTENT_CHOOSE_TALK, _NeedId, ShowTalk, _Scene, _X, _Y,_Talk, _PathFind]-> ShowTalk; _-> filter_show_talk(T) end. %%检查任务的下一内容是否为与某npc的对话 task_talk_to_npc(RT, NpcId)-> Temp = [0 || [State, Fin, CType, Nid|_] <- RT#role_task.mark, State =:= RT#role_task.state, Fin =:= 0,lib_role_task:exchange_npc(Nid) =:= NpcId,lists:member(CType,[?TASK_CONTENT_TALK,?TASK_CONTENT_CHOOSE_TALK,?TASK_CONTENT_MAILER_RUN])], length(Temp)>0. %% 获取任务对话id get_npc_task_talk_id(TaskId, NpcId, TaskArgs) -> case get_data(TaskId) of null -> {none, 0}; TD -> {CanTrigger, Link, UnFinish, Finish} = get_npc_task(NpcId, TaskArgs), case {lists:keymember(TaskId, #task.id, CanTrigger), lists:keymember(TaskId,1,Link), lists:keymember(TaskId,1,UnFinish), lists:keymember(TaskId,1,Finish) } of {true, _, _, _} -> {start_talk, TD#task.start_talk}; %% 任务触发对话 {_, true, _, _} -> %% 关联对话 case get_one_trigger(TaskId) of false -> {none, 0}; RT -> [Fir|_] = [TalkId || [State,Fin,CType,Nid,TalkId|_] <- RT#role_task.mark, State=:= RT#role_task.state, Fin=:=0, lib_role_task:exchange_npc(Nid) =:= NpcId,lists:member(CType,[?TASK_CONTENT_TALK,?TASK_CONTENT_CHOOSE_TALK,?TASK_CONTENT_MAILER_RUN])], {link_talk, Fir} end; {_, _, true, _} -> {unfinished_talk, TD#task.unfinished_talk}; %% 未完成对话 {_, _, _, true} -> %% 提交任务对话 case get_one_trigger(TaskId) of false -> {none, 0}; RT -> [Fir|_] = [TalkId || [_,_,?TASK_CONTENT_END_TALK,Nid,TalkId|_] <- RT#role_task.mark, lib_role_task:exchange_npc(Nid) == NpcId], {end_talk, Fir} end; _ -> {none, 0} end end. %% 获取提示信息 %% 可接任务会有开始npc对话 get_tip(active, TaskId, #task_args{figure=#figure{career=Career}}=TaskArgs) -> TD = get_data(TaskId), case get_start_npc(TD#task.start_npc, Career) of 0 -> []; StartNpcId -> [content_to_mark([0, ?TASK_CONTENT_TALK, StartNpcId, TD#task.start_talk, 0, 0, 0, TD#task.trigger_pathfind], TaskArgs)] end; get_tip(trigger, TaskId, TaskArgs) -> RT = get_one_trigger(TaskId), [mark_refresh(TaskMark, TaskArgs) || TaskMark <- RT#role_task.mark]. %% 任务阶段内容 转为 任务完成情况记录 %% 任务内容格式:[State(阶段), ContentType(内容类型), Id(任务id), Num(采集或者杀怪的需要数量), ScneId, X, Y, PathFind] %% 任务内存格式:[State(阶段), IsFinish(是否完成) ContentType(内容类型), Id(任务id), Num(采集或者杀怪的需要数量), ScneId, X, Y, RealNum(收集或者杀怪的完成数量), PathFind] content_to_mark([State, ContentType, Id, Num, SceneId, X, Y, PathFind], TaskArgs) -> content_to_mark([State, ContentType, Id, Num, SceneId, X, Y, PathFind], [],TaskArgs). content_to_mark([State, ContentType, Id, Num, SceneId, X, Y, PathFind], _Contents, TaskArgs)-> case ContentType of ?TASK_CONTENT_START_TALK -> NewId=lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info), [State, 0, ContentType, NewId, Num, RealSceneId, RealX, RealY, 0, PathFind]; ?TASK_CONTENT_END_TALK -> NewId=lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info), [State, 1, ContentType, NewId, Num, RealSceneId, RealX, RealY, 0, PathFind]; ?TASK_CONTENT_TALK -> NewId=lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info), [State, 0, ContentType, NewId, Num, RealSceneId, RealX, RealY, 0, PathFind]; ?TASK_CONTENT_ITEM -> #task_args{id = RoleId, gs_dict = GsDict} = TaskArgs, case data_goods_type:get(Id) of #ets_goods_type{bag_location = BagLocation} -> GoodsList = lib_goods_util:get_type_goods_list(RoleId, Id, BagLocation, GsDict, 0), TotalNum = lib_goods_util:get_goods_total_num(GoodsList); _ -> ?ERR("goods_num err: goods_type_id = ~p err_config", [Id]), TotalNum = 0 end, {Finish, NowNum} = ?IF(TotalNum >= Num, {1, Num}, {0, TotalNum}), [State, Finish, ContentType, Id, Num, SceneId, X, Y, NowNum, PathFind]; ?TASK_CONTENT_MAILER_RUN -> NewId=lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info), [State, 0, ContentType, NewId, Num, RealSceneId, RealX, RealY, 0, PathFind]; _ -> [State, 0, ContentType, Id, Num, SceneId, X, Y, 0, PathFind] end; content_to_mark(_, _Contents, _TaskArgs) -> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]. %% 异常时刷新 mark_refresh([State, Fin, ContentType, Id, Num, Scene, _X, _Y, Count, PathFind]=Mark, TaskArgs) -> if Scene == 0 andalso (ContentType == ?TASK_CONTENT_START_TALK orelse ContentType == ?TASK_CONTENT_END_TALK orelse ContentType == ?TASK_CONTENT_TALK) -> NewNpc=lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewNpc, TaskArgs#task_args.npc_info), [State, Fin, ContentType, NewNpc, Num, RealSceneId, RealX, RealY, Count, PathFind]; ContentType =:= ?TASK_CONTENT_CHOOSE_TALK -> NewNpc = lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewNpc, TaskArgs#task_args.npc_info), [State, Fin, ContentType, NewNpc, Num, RealSceneId, RealX, RealY, Count, PathFind]; true -> Mark end. %% 获取奖励 get_award_item(TD, TaskArgs) -> SL = get_special_reward_item(TD#task.special_goods_list, TaskArgs, []), F = fun(E, LL) -> case E of {?TYPE_GOODS, GoodsTypeId, Num} -> [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|LL]; _ -> [E|LL] end end, lists:foldl(F, SL, TD#task.award_list). %% 获取特殊奖励 get_special_reward_item([], _TaskArgs, Rewards) -> Rewards; get_special_reward_item([{Career, Sex, GoodsTypeId, Num}|SpecialGoods], TaskArgs, Rewards) -> if Career == 0 andalso Sex == 0 -> get_special_reward_item(SpecialGoods, TaskArgs, [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|Rewards]); Career == TaskArgs#task_args.figure#figure.career andalso Sex == 0-> get_special_reward_item(SpecialGoods, TaskArgs, [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|Rewards]); Sex == TaskArgs#task_args.figure#figure.sex andalso Career == 0 -> get_special_reward_item(SpecialGoods, TaskArgs, [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|Rewards]); Career == TaskArgs#task_args.figure#figure.career andalso Sex == TaskArgs#task_args.figure#figure.sex -> get_special_reward_item(SpecialGoods, TaskArgs, [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|Rewards]); true -> get_special_reward_item(SpecialGoods, TaskArgs, Rewards) end; get_special_reward_item([_|SpecialGoods], TaskArgs, Rewards) -> get_special_reward_item(SpecialGoods, TaskArgs, Rewards). %% 获取开始npc的id %% 如果需要判断职业才匹配第2,3 get_start_npc(StartNpc, _) when is_integer(StartNpc) -> lib_role_task:exchange_npc(StartNpc); get_start_npc([], _) -> 0; get_start_npc([{career, Career, NpcId}|T], RoleCareer) -> case Career =:= RoleCareer of false -> get_start_npc(T, RoleCareer); true -> lib_role_task:exchange_npc(NpcId) end. %%获取当前NPC所在的场景(自动寻路用) get_npc_info(NpcId, NpcInfo) -> case lists:keyfind(NpcId, 1, NpcInfo) of {_, _IsShow, Scene, X, Y, _} -> {Scene, X, Y}; false -> case lib_npc:get_npc_info_by_id(NpcId) of [] -> {0, 0, 0}; Npc -> {Npc#ets_npc.scene, Npc#ets_npc.x, Npc#ets_npc.y} end end. %%获取当前怪物所在的场景 get_mon_info(MonId) -> case mod_scene_mon:lookup(MonId) of [] -> {0, 0, 0}; D -> {D#ets_scene_mon.scene, D#ets_scene_mon.x, D#ets_scene_mon.y} end. %% 指定id任务是否可接 in_active(TaskId) -> find_query_cache_exits(TaskId). get_active() -> get_query_cache_list(). get_active(type, Type) -> get_query_cache_list_type(Type). %% 获取已触发任务列表 get_trigger() -> get_task_bag_id_list(). %% 获取该阶段任务内容 get_phase(RT)-> [[State | T] || [State | T] <- RT#role_task.mark, RT#role_task.state =:= State]. %% 获取任务阶段的未完成内容:改成这个任务没有最终完成的 %% get_phase_unfinish(RT)-> %% [[State, Fin | T] || [State, Fin |T] <- RT#role_task.mark]. get_one_trigger(TaskId) -> find_task_bag_list(TaskId). %% 查看是否领取了指定的任务ID:是:true 否:false is_trigger_task_id(TaskId) -> case find_task_bag_list(TaskId) of false -> false; _ -> true end. %% 查看是否领取了指定的任务ID:是:true 否:false is_during_task(TaskId) -> case find_task_bag_list(TaskId) of #role_task{state=S} when S=<0-> true; _ -> false end. %% 只能在任务进程调用 %% 查看是否完成了指定的任务ID:是:true 否:false is_finish_task_id(TaskId) -> case find_task_log_list(TaskId) of false -> false; _ -> true end. %% 只能在任务进程调用 %% 查看是否完成了多个指定的任务ID: %% return 已完成的TaskId的Bin形式 %% 是否完成多个任务 %% TaskIds可以是列表形式:[TaskId] %% TaskIds也可以打包形式(Bin形式):lib_task:pack_task_id([TaskId]) is_finish_task_ids(BinTaskIds) when is_binary(BinTaskIds)-> TaskIds = unpack_task_id(BinTaskIds), FinishIds = is_finish_task_ids(TaskIds), pack_task_id(FinishIds); %% return 已完成的TaskId is_finish_task_ids(TaskIds) -> F = fun(TaskId, TmpList)-> case find_task_log_list(TaskId) of false -> TmpList; _ -> [TaskId|TmpList] end end, FinishIds = lists:foldl(F, [], TaskIds), FinishIds. %% 只能在任务进程调用 %% 是否完成对应章节的所有主线任务 is_finish_chapter_all_task(Chapter) -> List = data_task:get_ids_by_chapter(Chapter), F = fun(TaskId) -> is_finish_task_id(TaskId) end, lists:all(F, List). %% 获取结束任务的npcid get_end_npc_id(RT) when is_record(RT, role_task)-> get_end_npc_id(RT#role_task.mark); get_end_npc_id(TaskId) when is_integer(TaskId) -> case get_one_trigger(TaskId) of false -> 0; RT -> get_end_npc_id(RT) end; get_end_npc_id([]) -> 0; get_end_npc_id(Mark) -> case lists:last(Mark) of [_, _, ?TASK_CONTENT_END_TALK, NpcId|_] -> lib_role_task:exchange_npc(NpcId); _ -> 0 %% 这里是异常 end. %% ================================= 任务触发检查 ================================= %% 检查是否可以触发任务 can_trigger(TaskId, TaskArgs) -> #figure{lv = PlayerLv, career = PlayerCareer, realm = PlayerRealm, turn = PlayerTurn, guild_id = PlayerGuilId} = TaskArgs#task_args.figure, case find_task_bag_exits(TaskId) of true -> {false, ?ERRCODE(err300_task_trigger)}; %%已经触发过了 false -> case data_task_condition:get(TaskId) of null -> {false, ?ERRCODE(err300_task_config_null)}; #task_condition{type = TaskType, level = Level, level_max = MaxLevel, realm = Realm, career = Career, turn = Turn, prev = Prev, repeat = Repeat, condition = Condition} = _TD -> if (TaskType ==?TASK_TYPE_DAILY orelse TaskType == ?TASK_TYPE_GUILD) andalso (PlayerLv > MaxLevel orelse PlayerLv < Level)-> {false, ?ERRCODE(err300_lv_not_enough)}; %% 等级不足 PlayerLv < Level -> {false, ?ERRCODE(err300_lv_not_enough)}; %% 等级不足 TaskType == ?TASK_TYPE_GUILD andalso PlayerGuilId == 0 -> %% 没有帮派 {false, ?ERRCODE(err300_not_guild)}; Realm /=0 andalso PlayerRealm /= Realm -> {false, ?ERRCODE(err300_realm_diff)}; %% 阵营不符合 Career /= 0 andalso PlayerCareer /= Career -> {false, ?ERRCODE(err300_career_diff)}; %% 阵营不符合 Turn /= 0 andalso PlayerTurn < Turn -> {false, ?ERRCODE(err300_turn_diff)}; %% 转生次数不符合(向下兼容) TaskType == ?TASK_TYPE_TURN andalso PlayerTurn > Turn andalso PlayerTurn > 0 -> {false, ?ERRCODE(err300_turn_diff)}; %% 如果是转生任务 但是玩家的转生次数已经超过了任务的转生次数则不能重复触发 true -> case check_prev_task(Prev) of false -> {false, ?ERRCODE(err300_prev_not_fin)}; %% 前置任务未完成 true -> case check_repeat(TaskId, Repeat) of false -> {false, ?ERRCODE(err300_fin)}; true -> case length([1||ConditionItem <- Condition, check_condition(ConditionItem, TaskId, TaskArgs)=:=false]) =:= 0 of true -> true; false -> {false, ?ERRCODE(err300_condition_err)} end end end end end end. % %% 获取下一等级的任务 % next_lev_list(PS) -> % Tids = data_task:get_ids(), % F = fun(Tid) -> TD = get_data(Tid), (PS#player_status.figure#figure.lv + 1) =:= TD#task.level end, % [XTid || XTid<-Tids, F(XTid)]. %% 是否重复可以接 check_repeat(TaskId, Repeat) -> case Repeat =:= 0 of true -> find_task_log_exits(TaskId) =/= true; false -> true end. %% 前置任务 check_prev_task(PrevId) -> case PrevId =:= 0 of true -> true; false -> find_task_log_exits(PrevId) end. %% 任务条件建检查 %% 是否完成任务 check_condition({task, TaskId}, _, _) -> find_task_log_exits(TaskId); %% 是否完成其中之一的任务 check_condition({task_one, TaskList}, _, _) -> lists:any(fun(Tid)-> find_task_log_exits(Tid) end, TaskList); %% 今天的任务次数是否过多 check_condition({daily_limit, Num}, TaskId, _) -> case find_task_log_list(TaskId) of false -> true; RTL -> RTL#role_task_log.count < Num end; %%验证开服天数 check_condition({open_day,Day},_,_)-> OpDay = util:get_open_day(), OpDay>=Day; %% 容错 check_condition(_Other, _, _TaskArgs) -> false. %% ================================= 触发任务 ================================= %% 自动触发任务 auto_trigger(TaskArgs) -> ActiveTasks = get_active(), %% 获取可以接的任务 do_auto_trigger(TaskArgs,ActiveTasks). auto_trigger(Type,TaskArgs)-> ActiveTasks = get_active(type,Type), do_auto_trigger(TaskArgs,ActiveTasks). do_auto_trigger(TaskArgs,ActiveTasks)-> F = fun(TD, Bool) -> case TD#task.start_npc == 0 andalso TD#task.start_talk == 0 of true -> trigger(TD#task.id, TaskArgs), true; false -> Bool end end, lists:foldl(F, false, ActiveTasks). %% 手动触发任务 %% return true | {false, Code} trigger(TaskId, TaskArgs) -> %% 注: 给机器人放行逻辑 IsRobot = lib_robot:is_robot(TaskArgs), CanTrigger = case can_trigger(TaskId, TaskArgs) of {false, _ErrCode} when IsRobot == true -> true; {false, ErrCode} -> {false, ErrCode}; true -> true end, case CanTrigger of {false, Res} -> {false, Res}; true -> TD = get_data(TaskId), TaskMark = [content_to_mark(E, TaskArgs)||E<-TD#task.content] ++ case TD#task.end_talk of 0 -> []; %% end_talk = 0则直接提交任务 _ -> [content_to_mark([TD#task.state, ?TASK_CONTENT_END_TALK, TD#task.end_npc, TD#task.end_talk, 0, 0, 0, TD#task.finish_pathfind], TaskArgs)] end, Now = utime:unixtime(), add_trigger(TaskArgs#task_args.id, TaskId, Now, 0, TD#task.state, TaskMark, TD#task.type, TD#task.kind, TaskArgs#task_args.figure#figure.lv), case handle_finish_before_trigger(TaskId, TaskMark, TaskArgs, []) of EventList when is_list(EventList) andalso EventList =/= [] -> lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_SAVE, lib_task_api, cast_handle_refresh_trigger, [EventList]); _ -> ok end, %% 转生任务接取了要通知其他模块 ?IF(TD#task.type =/= ?TASK_TYPE_TURN, skip, lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_SAVE, transform, trigger_task, [TD#task.id])), get_my_task_list(TD#task.type, TaskArgs), refresh_npc_ico(TaskArgs), lib_task_event:trigger_after(TD, TaskArgs), %lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_SAVE, ta_agent_fire, task_completed, [Now, [TD#task.id, 1, 0]]), true end. %% 有部分支线任务内容在触发时候判断 %% 增加的对应类型,要同步在lib_task_api:make_action_list()增加类型支持 handle_finish_before_trigger(_TaskId, [], _TaskArgs, EventList) -> EventList; %%转生任务 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_TURN, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_TURN,Id} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%好友数量 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ADD_FRIEND, _Id, Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_ADD_FRIEND, Num, NowNum} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%副本进度 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUN_WAVE, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_DUN_WAVE, Id} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%某个副本 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUNGEON, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_DUNGEON, Id} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%副本类型 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUNGEON_TYPE, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_DUNGEON_TYPE, Id} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%指定BOSS handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_KILL_BOSS, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_KILL_BOSS, Id} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%装备进化 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ERISE, _Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_ERISE} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%装备强化 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_STREN, _Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_STREN} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%装备附能 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_EMPOWER, _Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_EMPOWER} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%活跃度 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DAY_ACTIVITY, _Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_DAY_ACTIVITY} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%副本类型特定经验 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUNGEON_EXP, Id, Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_DUNGEON_EXP, Id, Num} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%层级副本类型 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DunId, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DunId} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%动态积分购买 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_SCORE_BUY, Item,_Num, _Scene, ShopId, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_SCORE_BUY, Item, ShopId} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%好友度 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_FRIEND_EXP, _Id,_Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_FRIEND_EXP, NowNum} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%竞技场 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ARENA_TIMES, _Id,_Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_ARENA_TIMES} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%装备套装 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_EQUIP_SUIT, _Id,_Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_EQUIP_SUIT} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%进阶系统 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_FOSTER_GRADE, Type,_Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_FOSTER_GRADE, Type} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%预期任务 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_EXPECT_TASK, ExpectTask,_Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId,?TASK_CONTENT_EXPECT_TASK,ExpectTask}| EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%宝宝同心值 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_CHILD_HEART, _Id,_Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_CHILD_HEART,NowNum} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%战力任务 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_COMBAT, _Id,_Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_COMBAT,NowNum} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%任意主动技能升级次 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ACTIVE_SKILL_LV_TIMES, _Id,_Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_ACTIVE_SKILL_LV_TIMES,NowNum} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%指定商定购买技能书 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_SOME_SHOP_BUY_BOOK, ShopId,NeedNum, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_SOME_SHOP_BUY_BOOK,ShopId,NowNum,NeedNum} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); %%任意商定购买技能书 handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ANY_SHOP_BUY_BOOK, _Id,NeedNum, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) -> NewEventList = [{TaskId, ?TASK_CONTENT_ANY_SHOP_BUY_BOOK,NowNum,NeedNum} | EventList], handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList); handle_finish_before_trigger(TaskId, [_|T], TaskArgs, EventList) -> handle_finish_before_trigger(TaskId, T, TaskArgs, EventList). %% ================================= 完成任务 ================================= %% 自动完成 auto_finish(TaskArgs) when TaskArgs#role_task.type =/= ?TASK_TYPE_SIDE-> TriggerTasks = get_trigger(), F = fun(RT, Bool) -> case RT#role_task.state == RT#role_task.end_state of true -> case lists:last(RT#role_task.mark) of [_, 1, ?TASK_CONTENT_END_TALK|_] -> Bool; _ -> case finish(RT#role_task.task_id, [], TaskArgs) of {false, _} -> Bool; true -> true; {ok, _} -> true end end; false -> Bool end end, case lists:foldl(F, false, TriggerTasks) of false -> true; true -> auto_trigger(TaskArgs) %% 这里是个递归,可能会继续触发完成 end; auto_finish(_TaskArgs) -> true. %% return true | {false, Code} | {ok, 1} finish(TaskId, ParamList, TaskArgs) -> case is_finish(TaskId, TaskArgs) of false -> #task{type = Type} = get_data(TaskId), if ParamList == cost_finish andalso %% 花费完成 (Type == ?TASK_TYPE_DAILY orelse Type == ?TASK_TYPE_GUILD orelse Type == ?TASK_TYPE_SIDE)-> do_normal_finish(TaskId, ParamList, TaskArgs); true -> %% ?ERR("error no finish task id:~p~n", [TaskId]), {false, ?ERRCODE(err300_task_no_finish)} end; true -> do_normal_finish(TaskId, ParamList, TaskArgs) end. do_normal_finish(TaskId, ParamList, TaskArgs) -> #task_args{id = Id} = TaskArgs, TD = get_data(TaskId), RT = get_one_trigger(TaskId), %% 奖励物品 if TD#task.type == ?TASK_TYPE_DAILY orelse TD#task.type == ?TASK_TYPE_GUILD -> Items0 = calc_task_type_reward(TD#task.type, RT#role_task.lv), BaseItems = get_award_item(TD, TaskArgs), Items = calc_extra_ratio_type_reward(TD#task.type, BaseItems, TaskArgs)++Items0; TD#task.type == ?TASK_TYPE_MAIN -> %%计算双倍奖励 BaseItems = get_award_item(TD, TaskArgs), Items = calc_dobule_reward(BaseItems, ParamList); true -> Items = get_award_item(TD, TaskArgs) end, LogType = get_log_type(TD#task.type), Produce=#produce{ type=LogType, subtype = TaskId, title=data_language:get(145), content=data_language:get(146), reward=Items, show_tips=3, remark = lists:concat(["task_id:", TaskId]) }, lib_goods_api:send_reward_with_mail(Id, Produce, ?MOD_TASK), {ok, BinData} = pt_300:write(30004, [TaskId, 1, Items]), lib_server_send:send_to_sid(TaskArgs#task_args.sid, BinData), %% 判断特殊类型的任务完成 if TD#task.type == ?TASK_TYPE_DAILY orelse TD#task.type == ?TASK_TYPE_GUILD -> finish_task_type(TD#task.type, Id, TaskArgs, RT); true -> %% 数据库回写 Time = utime:unixtime(), add_log(Id, TaskId, TD#task.type, RT#role_task.trigger_time, Time, 0), %% 刷新任务 refresh_active(TaskArgs), %% 完成任务事件 TalkId = filter_task_talk(RT#role_task.mark), lib_task_event:async_finish(Id, TaskId, TalkId), case auto_trigger(TaskArgs) of true -> get_my_task_list(TD#task.type, TaskArgs), %%主线需要补充更新推送 case TD#task.type =:= ?TASK_TYPE_MAIN of true-> refresh_npc_ico(TaskArgs); _-> skip end, trigger_next_special_task(TD, RT), true; _ -> get_my_task_list(TD#task.type, TaskArgs), refresh_npc_ico(TaskArgs), %% check some special task trigger_next_special_task(TD, RT), true end end. get_log_type(?TASK_TYPE_DAILY) -> finish_daily_task; get_log_type(?TASK_TYPE_GUILD) -> finish_guild_task; get_log_type(_) -> task. trigger_next_special_task(TD, RT)-> #task{type = Type, kind = Kind, next = NextTaskId} = TD, case Type == ?TASK_TYPE_SIDE andalso NextTaskId > 0 of false -> skip; true -> #role_task{mark = Mark} = RT, if Kind == ?TASK_KIND_STREN -> lib_player:apply_cast(RT#role_task.role_id, ?APPLY_CAST_STATUS, lib_task_api, auto_stren_equip, []); Kind == ?TASK_KIND_RUNE_DUN -> case get_mark_content_type_num(Mark, ?TASK_CONTENT_DUNGEON_RUNE) of {DunType, DunId} -> lib_player:apply_cast(RT#role_task.role_id, ?APPLY_CAST_STATUS, lib_task_api, fin_level_dun, [DunType, DunId]); _ -> skip end; Kind == ?TASK_KIND_EXP_DUN -> case get_mark_content_type_num(Mark, ?TASK_CONTENT_DUNGEON_EXP) of [] -> skip; {DunType, Exp} -> lib_player:apply_cast(RT#role_task.role_id, ?APPLY_CAST_STATUS, lib_task_api, fin_dun_exp, [DunType, Exp]) end; true -> skip end end. get_mark_content_type_num([[_, _, ?TASK_CONTENT_DUNGEON_RUNE, DunType, _, _, _, _, RuneDunId, _]|_Mark], ?TASK_CONTENT_DUNGEON_RUNE)-> {DunType, RuneDunId}; get_mark_content_type_num([[_, _, ?TASK_CONTENT_DUNGEON_EXP, DunType, _, _, _, _, NowExpNum, _]|_Mark], ?TASK_CONTENT_DUNGEON_EXP) -> {DunType, NowExpNum}; get_mark_content_type_num([_H|Mark], ContentType) -> get_mark_content_type_num(Mark, ContentType); get_mark_content_type_num([], _ContentType)-> []. %% 完成悬赏和公会周任务 finish_task_type(TaskType, RoleId, TaskArgs, RT)-> case data_task_lv_dynamic:get_task_type(TaskType) of #task_type{count = Count, module_id = ModuleId, counter_id = CounterId} -> % mod_guild:add_growth(RoleId, Figure#figure.guild_id, 1, finish_guild_task, {task_type, TaskType}), FinishCount = lib_daily:get_count(RoleId, ModuleId, CounterId)+1, ProduceType = ?IF(TaskType == ?TASK_TYPE_GUILD, finish_guild_task, finish_daily_task), lib_daily:increment(RoleId, ModuleId, CounterId), %% 数据库回写 Time = utime:unixtime(), LogType = ?IF(lists:member(TaskArgs#task_args.figure#figure.lv, ?DAILY_SPECIAL_LV) andalso TaskType == ?TASK_TYPE_DAILY, 1, TaskType), add_log(TaskArgs#task_args.id, RT#role_task.task_id, LogType, RT#role_task.trigger_time, Time, FinishCount), %% 完成任务事件 lib_task_event:async_finish(TaskArgs#task_args.id, RT#role_task.task_id,0), case calc_extra_task_type_reward(RT#role_task.task_id, TaskType, FinishCount, RT#role_task.lv) of [] -> skip; Reward -> Produce=#produce{ type=ProduceType, subtype = RT#role_task.task_id, title=data_language:get(145), content=data_language:get(146), reward=Reward, show_tips=3, remark = lists:concat(["task_id:", RT#role_task.task_id]) }, lib_goods_api:send_reward_with_mail(TaskArgs#task_args.id, Produce, ?MOD_TASK) % lib_goods_api:send_reward_by_id(Reward, ProduceType, RT#role_task.task_id, TaskArgs#task_args.id) end, TaskType == ?TASK_TYPE_GUILD andalso guild_run_assist:check_run_assist_trigger(TaskArgs#task_args.id), if FinishCount >= Count -> %% ?ERR("finish task type:~p~n FinishCount:~p~n", [TaskType, FinishCount]), get_my_task_list(TaskType, TaskArgs), refresh_npc_ico(TaskArgs), if TaskType == ?TASK_TYPE_DAILY -> {ok, ?ERRCODE(err300_daily_task_finished)}; true -> {ok, ?ERRCODE(err300_guild_task_finished)} end; true -> lib_player:apply_cast(RoleId, ?APPLY_CAST_STATUS, ?MODULE, finish_task_type_after, [TaskType]), {ok, ?SUCCESS} % trigger_type_task(TaskType, TaskArgs) end; _R -> ?ERR("error task type:~p~n _R:~p~n", [TaskType, _R]), {false, ?FAIL} end. finish_task_type_after(PS, ?TASK_TYPE_DAILY) -> TaskArgs = lib_task_api:ps2task_args(PS), case get_task_bag_id_list_type(?TASK_TYPE_DAILY) of [] -> {_, Code} = trigger_type_task(?TASK_TYPE_DAILY, TaskArgs), {ok, Bin} = pt_300:write(30009, [Code]), lib_server_send:send_to_uid(TaskArgs#task_args.id, Bin), PS; _-> PS end; finish_task_type_after(PS, TaskType) -> TaskArgs = lib_task_api:ps2task_args(PS), {_, Code} = trigger_type_task(TaskType, TaskArgs), {ok, Bin} = pt_300:write(30009, [Code]), lib_server_send:send_to_uid(TaskArgs#task_args.id, Bin), PS. %% 检查扣除物品 %% check_task_cost_goods(TD, RT, ParamList, TaskArgs) -> %% #task_args{id = Id, gs_dict = GsDict} = TaskArgs, %% %% 删除回收物品 %% if %% TD#task.end_item == [] -> ok; %% ParamList == cost_finish -> ok; %% 特殊任务消耗直接完成不需要扣除物品 %% true -> %% case get_task_cost_goods(TD, RT) of %% [] -> ok; %% [{GoodsId, Num}|_] -> %% case data_goods_type:get(GoodsId) of %% #ets_goods_type{bag_location = BagLocation} -> %% GoodsList = lib_goods_util:get_type_goods_list(Id, GoodsId, BagLocation, GsDict), %% TotalNum = lib_goods_util:get_goods_totalnum(GoodsList), %% if %% TotalNum >= Num -> %% lib_player:apply_cast(Id, ?APPLY_CAST_STATUS, lib_goods_api, goods_delete_type_list, [[{GoodsId, Num}], finish_task]), %% ok; %% true -> %% {false, ?ERRCODE(goods_not_enough)} %% end; %% _ -> %% {false, ?ERRCODE(err150_no_goods)} %% end %% end %% end. %% 根据任务内容去扣除物品 %% get_task_cost_goods(TD, RT) -> %% if %% TD#task.type == ?TASK_TYPE_DAILY orelse TD#task.type == ?TASK_TYPE_GUILD -> %% #role_task{mark = Mark, kind = _Kind} = RT, %% case lists:keyfind(?TASK_CONTENT_ITEM, 3, Mark) of %% false -> []; %% {_State, _, _CType, Id, Num, _SceneId, _X, _Y, _Num, _FindPath} -> %% [{Id, Num}] %% end; %% true -> %% TD#task.end_item %% end. %% 经验双倍奖励 calc_dobule_reward(BaseItems, [{double_type, _}|_T]) -> lists:foldl( fun ({?TYPE_EXP, GoodsId, Num}, AccList) -> %%经验双倍奖励 [{?TYPE_EXP, GoodsId, Num * 2} | AccList]; ({_TypeId, _GoodsId, _Num} = Info, AccList) -> [Info| AccList]; (_, AccList) -> AccList end, [], BaseItems ); calc_dobule_reward(BaseItems, _ParamList) -> BaseItems. %% 赏金任务 calc_task_type_reward(?TASK_TYPE_DAILY, Lv)-> ExpValue0 = data_exp_base:get(Lv), LvExtra = data_award_exp:get_exp_extra(?MOD_TASK,1,Lv), [{?TYPE_EXP, ?GOODS_ID_EXP, round(ExpValue0*LvExtra/10000)}]; %% 公会周任务 calc_task_type_reward(?TASK_TYPE_GUILD, Lv) -> ExpValue0 = data_exp_base:get(Lv), LvExtra = data_award_exp:get_exp_extra(?MOD_TASK,2,Lv), [{?TYPE_EXP, ?GOODS_ID_EXP, round(ExpValue0*LvExtra/10000)}]; calc_task_type_reward(_, _) -> []. %% 计算赏金和公会周任务额外奖励 calc_extra_task_type_reward(TaskId, _TaskType, FinishCount, Lv) -> case FinishCount rem 5 of %% 每十次一个 0 when FinishCount /= 0-> case data_task_lv_dynamic:get_type_task_dynamic(TaskId, Lv) of #task_lv_dynamic_content{extra_reward = ExtraReward} -> case lists:keyfind(FinishCount, 1, ExtraReward) of {_, Rewards} when is_list(Rewards)-> Rewards; _ -> [] end; _ -> [] end; _ -> [] end. %% 计算公会任务的加成奖励 calc_extra_ratio_type_reward(?TASK_TYPE_GUILD, Items, _TaskArgs) -> Rewards = lib_goods_api:make_reward_unique(Items), Rewards; calc_extra_ratio_type_reward(?TASK_TYPE_DAILY, Items, TaskArgs) -> Rewards = lib_goods_api:make_reward_unique(Items), #task_args{figure = #figure{vip_type = _VipType, vip = _VipLv}} = TaskArgs, % VipRatio = lib_vip:get_vip_privilege(VipType, VipLv, ?MOD_TASK, 3), VipRatio = 0, Fun = fun ({?TYPE_EXP, GoodTypeId, Num})-> {?TYPE_EXP, GoodTypeId, trunc(Num * (10000 + VipRatio) / 10000 )}; (Element) -> Element end, [Fun(Item) || Item <- Rewards]; calc_extra_ratio_type_reward(_, Items, _) -> Items. %% 放弃任务 abnegate(TaskId, TaskArgs) -> case get_one_trigger(TaskId) of false -> Code = 0; _RT -> %% 删除缓存 delete_task_bag_list(TaskId), %% 删除数据库 del_trigger_from_sql(TaskArgs#task_args.id, TaskId), %% 刷新 refresh_active(TaskArgs), refresh_npc_ico(TaskArgs), Code = 1 end, {ok, BinData} = pt_300:write(30005, [Code]), lib_server_send:send_to_sid(TaskArgs#task_args.sid, BinData). %% 有部分任务内容在触发的时候可能就完成了 %% preact_finish(Rid) -> %% lists:member(true, [preact_finish(RT, Rid) || RT <- get_task_bag_id_list()]). %% preact_finish(TaskId, Rid) when is_integer(TaskId) -> %% RT = get_one_trigger(TaskId), %% case RT of %% false -> skip; %% _ -> preact_finish(RT, Rid) %% end; %% preact_finish(RT, Rid) -> %% lists:member(true, [preact_finish_check([State, Fin | T], Rid) || [State, Fin | T] <- RT#role_task.mark, State =:= RT#role_task.state, Fin =:= 0]). %% %% 装备武器 %% preact_finish_check([_, 0, equip, _ItemId | _], PS) when is_record(PS, player_status)-> %% false; %% %% 加入帮派 %% preact_finish_check([_, 0, join_guild | _], PS) when is_record(PS, player_status)-> %% false; %% %% 购买武器 %% preact_finish_check([_, 0, buy_equip, _ItemId | _], _PS) when is_record(_PS, player_status)-> %% skip; %% %% 学习技能 %% preact_finish_check([_, 0, learn_skill, _SkillId | _], PS) when is_record(PS, player_status)-> %% false; %% %% 收集物品 %% preact_finish_check([_, 0, item, ItemId, _, NowNum | _], PS) when is_record(PS, player_status) -> %% Dict = lib_goods_dict:get_player_dict(PS), %% Num = lib_goods_util:get_task_goods_num(PS#player_status.id, ItemId, Dict), %% case Num > NowNum of %% false -> false; %% true -> action(PS#player_status.id, item, [[{ItemId, Num}]]) %% end; %% preact_finish_check(_, _) -> %% false. %% 检测任务是否完成 is_finish(TaskId, TaskArgs) when is_integer(TaskId) -> case get_one_trigger(TaskId) of false -> false; RT -> IsFinish = is_finish(RT, TaskArgs), % ?PRINT("####### is_finish:~p~n", [{TaskArgs#task_args.id, TaskArgs#task_args.figure#figure.lv, TaskArgs#task_args.source, TaskId, IsFinish, lib_robot:is_robot(TaskArgs)}]), %% 注: 给机器人放行逻辑 case {IsFinish, lib_robot:is_robot(TaskArgs)} of {false, true} -> true; _ -> IsFinish end end; is_finish(RT, TaskArgs) when is_record(RT, role_task) -> is_finish_mark(RT#role_task.mark, TaskArgs); is_finish(Mark, TaskArgs) when is_list(Mark) -> is_finish_mark(Mark, TaskArgs). is_finish_mark([], _) -> true; is_finish_mark([[_, 1|_] | T], TaskArgs) -> is_finish_mark(T, TaskArgs); is_finish_mark([MK|_T], _TaskArgs) when is_list(MK) -> false; is_finish_mark([MK|_T], _TaskArgs) -> ?ERR("error task mark:~p~n", [MK]), false. %% ================================= 任务进度更新 ================================= %% 批量刷新任务过程 action_more(EventList) -> [action(TaskId, Rid, Event, ParamList) || {TaskId, Event, ParamList, Rid} <- EventList]. %% 已接所有任务更新判断 action(Rid, Event, ParamList) -> case get_task_bag_id_list() of [] -> false; RTL -> Result = [action_one(RT, Rid, Event, ParamList)|| RT<- RTL], lists:member(true, Result) end. %% 单个任务更新判断 action(TaskId, Rid, Event, ParamList)-> case get_one_trigger(TaskId) of false -> false; RT -> action_one(RT, Rid, Event, ParamList) end. %% 触发任务 %% 如果是减少: %% 判断:阶段:后退,保持,前进; %% 变成没有完成状态 action_one(RT, Rid, Event, ParamList) -> NowTime = utime:unixtime(), #role_task{task_id = TaskId, type = TaskType, trigger_time = TriggerTime} = RT, if TaskType == ?TASK_TYPE_CHAPTER -> LimitTime = ?IF(TaskId == 101 orelse TaskId == 102, ?LIMIT_TIME1, ?LIMIT_TIME2); true -> LimitTime = 0 end, if TaskType == ?TASK_TYPE_CHAPTER andalso NowTime > TriggerTime + LimitTime -> %% 限时章节任务,大于限时后不做触发 false; true -> F = fun(MarkItem, Update) -> {NewMarkItem, NewUpdate} = content(MarkItem, RT#role_task.state, Event, ParamList), case NewUpdate of true -> {NewMarkItem, true}; false -> {NewMarkItem, Update} end end, {NewMark, UpdateAble} = lists:mapfoldl(F, false, RT#role_task.mark), case UpdateAble of false -> false; true -> NoFinishState = [EachState || [EachState, 0|_ ] <- NewMark], if NoFinishState == [] -> NewState = RT#role_task.end_state; true -> NewState = lists:min(NoFinishState) end, %% 更新任务记录和任务状态 %% 更新数据,但是不更新步骤状态,先缓存,下线的时候再记录数据库 NewRT = if RT#role_task.type == ?TASK_TYPE_TURN -> %% 转生任务比较难,默认保存数据 upd_trigger(RT#role_task.role_id, RT#role_task.task_id, NewState, NewMark), RT#role_task{write_db = 0, state = NewState, mark = NewMark}; RT#role_task.state == NewState -> RT#role_task{write_db = 1, mark = NewMark}; true -> upd_trigger(RT#role_task.role_id, RT#role_task.task_id, NewState, NewMark), RT#role_task{write_db = 0, state = NewState, mark = NewMark} end, put_task_bag_list(NewRT), ?IF(NewState == RT#role_task.state, ok, refresh_npc_ico(Rid)), % TEST % Ticket = config:get_ticket(), % case Ticket =:= ?INTERNAL_TICKET of % true -> auto_finish_task(Rid, RT#role_task.task_id); % false ->skip % end, case NewState == RT#role_task.end_state of true -> case lists:last(NewMark) of [_, 1, ?TASK_CONTENT_END_TALK|_] -> notify_client_new_mark(RT#role_task.task_id, Rid, NewState, NewMark); _R when TaskType =:= ?TASK_TYPE_NUCLEON -> notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark); _R when TaskType =:= ?TASK_TYPE_FOUR -> notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark); _R when TaskType =:= ?TASK_TYPE_DAILY -> notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark); _R when TaskType =:= ?TASK_TYPE_GUILD -> notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark); _R when TaskType =/= ?TASK_TYPE_SIDE -> auto_finish_task(Rid, RT#role_task.task_id); _R -> notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark) end, %lib_player:apply_cast(RT#role_task.role_id, ?APPLY_CAST_STATUS, ta_agent_fire, task_completed, % [NowTime, [RT#role_task.task_id, 2, NowTime - TriggerTime]]), true; _ -> notify_client_new_mark(RT#role_task.task_id, Rid, NewState, NewMark), true end end end. %% 通知客户端刷新任务栏 notify_client_new_mark(TaskId, Rid, NowState, Mark) -> {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(Mark), F = fun([EState|_]) -> EState == NowState end, {ok, BinData} = pt_300:write(30001, [TaskId, lists:filter(F, Mark), WitchState, NeedNum, NowNum]), lib_server_send:send_to_uid(Rid, BinData). %% 通知客户端刷新任务已完成状态 notify_client_new_state_mark(TaskId, Rid, _NowState, Mark) -> {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(Mark), F = fun([_, EState|_T]) -> EState >0 end, {ok, BinData} = pt_300:write(30001, [TaskId, lists:filter(F, Mark), WitchState, NeedNum, NowNum]), lib_server_send:send_to_uid(Rid, BinData). get_mon_or_goods_nums([]) -> {0, 0, 0}; get_mon_or_goods_nums([H|Mark])-> case H of [State, _, ContentType, Id, NeedNum, _, _, _, NowNum, _] when ContentType == ?TASK_CONTENT_KILL; ContentType == ?TASK_CONTENT_DUNGEON; ContentType == ?TASK_CONTENT_ITEM; ContentType == ?TASK_CONTENT_COLLECT; ContentType == ?TASK_CONTENT_GOODS_COMPOSE; ContentType == ?TASK_CONTENT_DAY_ACTIVITY; ContentType == ?TASK_CONTENT_STREN; ContentType == ?TASK_CONTENT_ARENA_TIMES; ContentType == ?TASK_CONTENT_COMBAT -> if ContentType == ?TASK_CONTENT_STREN -> {State, Id, NowNum}; NeedNum == 0 andalso NowNum == 0 -> get_mon_or_goods_nums(Mark); true -> {State, NeedNum, NowNum} end; _ -> get_mon_or_goods_nums(Mark) end. %% 自动完成任务 auto_finish_task(Player, TaskId) when is_record(Player, player_status) -> TaskArgs = lib_task_api:ps2task_args(Player), %% CellNum = lib_goods_api:get_cell_num(Player), lib_role_task:finish(TaskId, [], TaskArgs), ok; auto_finish_task(PlayerId, TaskId) -> case misc:get_player_process(PlayerId) of Pid when is_pid(Pid) -> lib_player:apply_cast(Pid, ?APPLY_CAST_STATUS, ?NOT_HAND_OFFLINE, lib_task, auto_finish_task, [TaskId]); _ -> skip end. %% 检查物品是否为任务需要 返回所需要的物品ID列表 can_gain_item() -> case get_task_bag_id_list() of [] -> []; RTL -> F = fun(RT) -> %% MarkList = get_phase_unfinish(RT), [Id || [_, _, ?TASK_CONTENT_ITEM, Id, Num, _SceneId, _X, _Y, NowNum | _T] <- RT#role_task.mark, NowNum =< Num] end, List = lists:flatmap(F, RTL), List end. %% after_event(Rid) -> %% %% TODO 后续事件提前完成检测 %% case preact_finish(Rid) of %% true -> ok; %% false -> %% %% TODO 通知角色数据更新 %% refresh_npc_ico(Rid), %% {ok, BinData} = pt_300:write(30006, []), %% lib_server_send:send_to_uid(Rid, BinData) %% end. %% 兼容可以从完成状态变成没有完成状态 %% 到达某个位置 content([State, 0, ?TASK_CONTENT_ENTER_SCENE, Id, Num, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_ENTER_SCENE, {PlayerScene, PlayerX, PlayerY}) -> case Scene == PlayerScene andalso abs(X - PlayerX) < 300 andalso abs(Y - PlayerY) < 300 of true -> {[State, 1, ?TASK_CONTENT_ENTER_SCENE, Id, Num, Scene, X, Y, NowNum, PathFind], true}; false -> {[State, 0, ?TASK_CONTENT_ENTER_SCENE, Id, Num, Scene, X, Y, NowNum, PathFind], false} end; %% 装备套装中id是 X代, NeedNum是Y件, EqStrenList = [{代,品质,件数}] content([State, 0, ?TASK_CONTENT_EQUIP_SUIT, Series, NeedNum, Color, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_EQUIP_SUIT, {id_num_list, SCNList}) -> case check_equip_suit_con(SCNList, Series, Color, NeedNum, 0) of {false, NowNum} -> {[State, 0, ?TASK_CONTENT_EQUIP_SUIT, Series, NeedNum, Color, X, Y, NowNum, PathFind], false}; {false, Count} -> {[State, 0, ?TASK_CONTENT_EQUIP_SUIT, Series, NeedNum, Color, X, Y, Count, PathFind], true}; {true, Count}-> {[State, 1, ?TASK_CONTENT_EQUIP_SUIT, Series, NeedNum, Color, X, Y, Count, PathFind], true} end; %% 装备强化中id是x级, NeedNum是y件, EqStrenList = [{lv, 件数}] content([State, 0, ?TASK_CONTENT_STREN, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_STREN, {id_num_list, EqStrenList}) -> case check_equip_num_con(EqStrenList, Id, NeedNum, 0) of {false, NowNum} -> {[State, 0, ?TASK_CONTENT_STREN, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false}; {false, Count} -> {[State, 0, ?TASK_CONTENT_STREN, Id, NeedNum, Scene, X, Y, Count, PathFind], true}; {true, Count}-> {[State, 1, ?TASK_CONTENT_STREN, Id, NeedNum, Scene, X, Y, Count, PathFind], true} end; %% 装备强化中id是x级, NeedNum是y件, EqStrenList = [{lv, 件数}] content([State, 0, ?TASK_CONTENT_EMPOWER, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_EMPOWER, {id_num_list, EqStrenList}) -> case check_equip_num_con(EqStrenList, Id, NeedNum, 0) of {false, NowNum} -> {[State, 0, ?TASK_CONTENT_EMPOWER, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false}; {false, Count} -> {[State, 0, ?TASK_CONTENT_EMPOWER, Id, NeedNum, Scene, X, Y, Count, PathFind], true}; {true, Count}-> {[State, 1, ?TASK_CONTENT_EMPOWER, Id, NeedNum, Scene, X, Y, Count, PathFind], true} end; %% 单次发条密室副本中获得xxx经验 content([State, 0, ?TASK_CONTENT_DUNGEON_EXP, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_DUNGEON_EXP, {num, Id, Num}) -> %% 密室副本id是副本类型, num是所需要的经验 case Num >= NeedNum of true -> {[State, 1, ?TASK_CONTENT_DUNGEON_EXP, Id, NeedNum, Scene, X, Y, Num, PathFind], true}; _ -> {[State, 0, ?TASK_CONTENT_DUNGEON_EXP, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false} end; content([State,0,?TASK_CONTENT_DUN_WAVE,Id,NeedNum,Scene,X,Y,NowNum, PathFind],State,?TASK_CONTENT_DUN_WAVE,{num, Id, Num})-> %%Num是波数 case Num >= NeedNum of true -> {[State, 1, ?TASK_CONTENT_DUN_WAVE, Id, NeedNum, Scene, X, Y, Num, PathFind], true}; _ -> {[State, 0, ?TASK_CONTENT_DUN_WAVE, Id, NeedNum, Scene, X, Y, max(NowNum,Num), PathFind], true} end; %% 符文之塔的触发 content([State, _Finish, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DId, Scene, X, Y, Id, PathFind], _State, ?TASK_CONTENT_DUNGEON_RUNE, {id, DunType, DunId}) -> case DunId >= DId of true -> if _Finish == 1 -> {[State, 1, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DId, Scene, X, Y, DunId, PathFind], false}; true -> {[State, 1, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DId, Scene, X, Y, DunId, PathFind], true} end; _ -> {[State, 0, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DId, Scene, X, Y, Id, PathFind], false} end; %% 符文之塔的触发 %% content([ContentState, 1, ?TASK_CONTENT_DUNGEON_RUNE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], _FState, ?TASK_CONTENT_DUNGEON_RUNE, {id, DunId}) -> %% case DunId >= Id of %% true -> {[ContentState, 1, ?TASK_CONTENT_DUNGEON_RUNE, Id, NeedNum, Scene, X, Y, DunId, PathFind], false}; %% _ -> {[ContentState, 1, ?TASK_CONTENT_DUNGEON_RUNE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false} %% end; %% 公会回收装备(提交x阶y品质及以上品质装备完成任务(id=x阶,NeedNum = y品质) content([State, 0, ?TASK_CONTENT_GUILD_EQ_RECYCLE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_GUILD_EQ_RECYCLE, {num, Stage, Color}) -> case Stage >= Id andalso Color >= NeedNum of true -> {[State, 1, ?TASK_CONTENT_GUILD_EQ_RECYCLE, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _ -> {[State, 0, ?TASK_CONTENT_GUILD_EQ_RECYCLE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false} end; %% 吞噬装备(吞噬x阶y品质及以上品质装备完成任务(id=x阶,NeedNum = y品质) content([State, 0, ?TASK_CONTENT_DEVOUR, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_DEVOUR, {num, Stage, Color}) -> case Stage >= Id andalso Color >= NeedNum of true -> {[State, 1, ?TASK_CONTENT_DEVOUR, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _ -> {[State, 0, ?TASK_CONTENT_DEVOUR, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false} end; %% 装备进化 content([State, 0, ?TASK_CONTENT_ERISE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_ERISE, {num, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_ERISE, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; Num > NowNum -> {[State, 0, ?TASK_CONTENT_ERISE, Id, NeedNum, Scene, X, Y, Num, PathFind], true}; true -> {[State, 0, ?TASK_CONTENT_ERISE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true} end; %% 竞技场 content([State, 0, ?TASK_CONTENT_ARENA_TIMES, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_ARENA_TIMES, {num, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_ARENA_TIMES, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; true-> {[State, 0, ?TASK_CONTENT_ARENA_TIMES, Id, NeedNum, Scene, X, Y, Num, PathFind], true} end; %% 战魂升级 content([State, 0, ?TASK_CONTENT_WAR_SOUL_LV, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_WAR_SOUL_LV, {num, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_WAR_SOUL_LV, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; Num > NowNum -> {[State, 0, ?TASK_CONTENT_WAR_SOUL_LV, Id, NeedNum, Scene, X, Y, Num, PathFind], true}; true -> {[State, 0, ?TASK_CONTENT_WAR_SOUL_LV, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true} end; %% 羁绊缔结就行 content([State, 0, ?TASK_CONTENT_MATE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_MATE, {num, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_MATE, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; Num > NowNum -> {[State, 0, ?TASK_CONTENT_MATE, Id, NeedNum, Scene, X, Y, Num, PathFind], true}; true -> {[State, 0, ?TASK_CONTENT_MATE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true} end; %% 完成次数就行 content([State, 0, ?TASK_CONTENT_DAY_ACTIVITY, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_DAY_ACTIVITY, {num, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_DAY_ACTIVITY, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; true-> {[State, 0, ?TASK_CONTENT_DAY_ACTIVITY, Id, NeedNum, Scene, X, Y, Num, PathFind], true} end; %% 完成亲密度就行 content([State, 0, ?TASK_CONTENT_FRIEND_EXP, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_FRIEND_EXP, {num, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_FRIEND_EXP, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; Num > NowNum -> {[State, 0, ?TASK_CONTENT_FRIEND_EXP, Id, NeedNum, Scene, X, Y, Num, PathFind], true}; true -> {[State, 0, ?TASK_CONTENT_FRIEND_EXP, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true} end; %% 完成同心值就行 content([State, 0, ?TASK_CONTENT_CHILD_HEART, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_CHILD_HEART, {num, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_CHILD_HEART, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; Num > NowNum -> {[State, 0, ?TASK_CONTENT_CHILD_HEART, Id, NeedNum, Scene, X, Y, Num, PathFind], true}; true -> {[State, 0, ?TASK_CONTENT_CHILD_HEART, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true} end; %战力任务 content([State, 0, ?TASK_CONTENT_COMBAT, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_COMBAT, {num, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_COMBAT, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; Num > NowNum -> {[State, 0, ?TASK_CONTENT_COMBAT, Id, NeedNum, Scene, X, Y, Num, PathFind], true}; true -> {[State, 0, ?TASK_CONTENT_COMBAT, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true} end; %%选项对话任务 content([State, 0, ?TASK_CONTENT_CHOOSE_TALK, NeedId, NeedNum, Scene, X, Y, _NowNum, PathFind], _, ?TASK_CONTENT_CHOOSE_TALK, {num,Id,TalkId}) -> NewNpc = lib_role_task:exchange_npc(NeedId), case NewNpc =:= Id of true-> {[State, 1, ?TASK_CONTENT_CHOOSE_TALK, Id, NeedNum, Scene, X, Y, TalkId, PathFind], true}; _-> {[State, 0, ?TASK_CONTENT_CHOOSE_TALK, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], false} end; %% 任务对话 content([State, 0, ?TASK_CONTENT_TALK, NeedId, Num, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_TALK, {id, Id}) -> NewNpc = lib_role_task:exchange_npc(NeedId), case NewNpc =:= NeedId of true->%%无变化 case NewNpc =:= Id of true-> {[State, 1, ?TASK_CONTENT_TALK, Id, Num, Scene, X, Y, Num, PathFind], true}; _-> {[State, 0, ?TASK_CONTENT_TALK, Id, Num, Scene, X, Y, _NowNum, PathFind], false} end; _-> case NewNpc =:= Id of true-> {[State, 1, ?TASK_CONTENT_TALK, NewNpc, Num, Scene, X, Y, Num, PathFind], true}; _-> {[State, 0, ?TASK_CONTENT_TALK, NewNpc, Num, Scene, X, Y, _NowNum, PathFind], false} end end; %% 个人幻魔处理 数据初始 content([State, 0, ?TASK_CONTENT_DUNGEON_TYPE, ?DUNGEON_TYPE_PER_BOSS, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_DUNGEON_TYPE, {init, ?DUNGEON_TYPE_PER_BOSS, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_DUNGEON_TYPE, ?DUNGEON_TYPE_PER_BOSS, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; Num>NowNum-> {[State, 0, ?TASK_CONTENT_DUNGEON_TYPE, ?DUNGEON_TYPE_PER_BOSS, NeedNum, Scene, X, Y, Num, PathFind], true}; true-> {[State, 0, ?TASK_CONTENT_DUNGEON_TYPE, ?DUNGEON_TYPE_PER_BOSS, NeedNum, Scene, X, Y, NowNum, PathFind], false} end; %% 次元幻魔处理 数据初始 content([State, 0, ?TASK_CONTENT_KILL_BOSS, ?MON_REWARD_BOSS, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_KILL_BOSS, {init, ?MON_REWARD_BOSS, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_KILL_BOSS, ?MON_REWARD_BOSS, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; Num>NowNum-> {[State, 0, ?TASK_CONTENT_KILL_BOSS, ?MON_REWARD_BOSS, NeedNum, Scene, X, Y, Num, PathFind], true}; true-> {[State, 0, ?TASK_CONTENT_KILL_BOSS, ?MON_REWARD_BOSS, NeedNum, Scene, X, Y, NowNum, PathFind], false} end; %% 进阶 数据初始 content([State, 0, ?TASK_CONTENT_FOSTER_GRADE, Type, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_FOSTER_GRADE, {num, Type, Num}) -> if Num >= NeedNum -> {[State, 1, ?TASK_CONTENT_FOSTER_GRADE, Type, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; Num>NowNum-> {[State, 0, ?TASK_CONTENT_FOSTER_GRADE, Type, NeedNum, Scene, X, Y, Num, PathFind], true}; true-> {[State, 0, ?TASK_CONTENT_FOSTER_GRADE, Type, NeedNum, Scene, X, Y, NowNum, PathFind], false} end; %%指定对话 content([State, 0, ?TASK_CONTENT_TALK, NeedId, TalkId, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_TALK, {id,TalkId,Id}) -> NewNpc = lib_role_task:exchange_npc(NeedId), case NewNpc =:= NeedId of true->%%无变化 case NewNpc =:= Id of true-> {[State, 1, ?TASK_CONTENT_TALK, Id, TalkId, Scene, X, Y, 1, PathFind], true}; _-> {[State, 0, ?TASK_CONTENT_TALK, Id, TalkId, Scene, X, Y, 1, PathFind], false} end; _-> case NewNpc =:= Id of true-> {[State, 1, ?TASK_CONTENT_TALK, NewNpc, TalkId, Scene, X, Y, 1, PathFind], true}; _-> {[State, 0, ?TASK_CONTENT_TALK, NewNpc, TalkId, Scene, X, Y, 1, PathFind], false} end end; %% 送信任务 content([State, 0, ?TASK_CONTENT_MAILER_RUN, NeedId, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_MAILER_RUN, {id,Id}) -> NewNpc = lib_role_task:exchange_npc(NeedId), case NewNpc =:= NeedId of true->%%无变化 case NewNpc =:= Id of true-> {[State, 1, ?TASK_CONTENT_MAILER_RUN, NewNpc, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _-> {[State, 0, ?TASK_CONTENT_MAILER_RUN, NewNpc, NeedNum, Scene, X, Y, _NowNum, PathFind], false} end; _-> case NewNpc =:= Id of true-> {[State, 1, ?TASK_CONTENT_MAILER_RUN, NewNpc, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _-> {[State, 0, ?TASK_CONTENT_MAILER_RUN, NewNpc, NeedNum, Scene, X, Y, _NowNum, PathFind], false} end end; %% 某个特定的id(特定的副本,特定的活动) content([State, 0, ContentType, Id, Num, Scene, X, Y, _NowNum, PathFind], State, ContentType, {id, Id}) -> {[State, 1, ContentType, Id, Num, Scene, X, Y, Num, PathFind], true}; %% 完成次数就行 content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ContentType, {num, Num}) -> case NowNum + Num >= NeedNum of true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum + Num, PathFind], true} end; %% 通用的id和次数 content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ContentType, {num, Id, Num}) -> case NowNum + Num >= NeedNum of true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum + Num, PathFind], true} end; %% 列表类型id和次数 content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum, PathFind]=H, _Taskstate, ContentType, {id_num_list, IdNumList}) -> case lists:keyfind(Id, 1, IdNumList) of false -> {H, false}; {Id, Num} -> case NowNum + Num >= NeedNum of true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum + Num, PathFind], true} end end; %% 收集物品减少触发状态变成 content([State, _Finsh, ?TASK_CONTENT_ITEM, Id, NeedNum, Scene, X, Y, _NowNum, PathFind]=H, _TaskState, ?TASK_CONTENT_ITEM, {reduce_id_num_list, IdNumList}) -> case lists:keyfind(Id, 1, IdNumList) of false -> {H, false}; {Id, _Num, GAllNum} -> NewNowNum = min(GAllNum, NeedNum), case NewNowNum >= NeedNum of true -> {[State, 1, ?TASK_CONTENT_ITEM, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _ -> {[State, 0, ?TASK_CONTENT_ITEM, Id, NeedNum, Scene, X, Y, NewNowNum, PathFind], true} end end; %% 完成次数就行 content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ContentType, {value, Num}) -> case Num >= NeedNum of true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, Num, PathFind], true} end; %% 通用的id和次数 content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ContentType, {value, Id, Num}) -> case Num >= NeedNum of true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true}; _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, Num, PathFind], true} end; %% 容错 content(MarkItem, _State, _Event, _Args) -> {MarkItem, false}. %% 检查装备的件数和强化数 check_equip_num_con([], _StrenNum, Num, Count)-> {Count >= Num, Count}; check_equip_num_con(_EqStrenList, _StrenNum, Num, Num)-> {true, Num}; check_equip_num_con([{StrNum, N}|EqStrenList], StrenNum, Num, Count)-> if StrNum >= StrenNum andalso N >= Num -> {true, Num}; StrNum >= StrenNum -> check_equip_num_con(EqStrenList, StrenNum, Num, Count+N); true -> check_equip_num_con(EqStrenList, StrenNum, Num, Count) end. %%检查套件中装备品质数 check_equip_suit_con([], _Series, _Color, NeedNum, Count)-> {Count >= NeedNum, Count}; check_equip_suit_con(_SCNList, _Series, _Color, NeedNum, Count) when Count>=NeedNum-> {true, NeedNum}; check_equip_suit_con([{S,C,N}|SCNList], Series, Color, NeedNum, Count)-> if S =:= Series andalso C>=Color -> check_equip_suit_con(SCNList,Series,Color,NeedNum,Count+N); true-> check_equip_suit_con(SCNList,Series,Color,NeedNum,Count) end. % %% 任务失败,算完成了任务一次(超时或者放弃) % task_fail(PS, RT) -> % add_log(PS#player_status.id, RT#role_task.task_id, RT#role_task.type, RT#role_task.trigger_time, utime:unixtime(), 0), % refresh_active(PS). %% ------------------------------ %% 自动完成任务 %% ------------------------------ %% 检测任务是否完成 % auto_finish(TaskId, Id) when is_integer(TaskId) -> % case get_one_trigger(TaskId) of % false -> % Msg = data_task_text:get_auto_finish(1), % {ok, BinData} = pt_300:write(30004, [0, Msg, []]), % lib_server_send:send_to_uid(Id, BinData), % false; % RT -> % case RT#role_task.state > 0 of % true -> % Msg = data_task_text:get_auto_finish(2), % {ok, BinData} = pt_300:write(30004, [0, Msg, []]), % lib_server_send:send_to_uid(Id, BinData), % false; % false -> % auto_finish(RT, Id) % end % end; % auto_finish(RT, Id) when is_record(RT, role_task) -> % NewMark = auto_finish_mark(RT#role_task.mark, []), % put_task_bag_list(RT#role_task{mark = NewMark, state=RT#role_task.state + 1}), % %% 通知客户端刷新任务栏 % refresh_npc_ico(Id), % TipList = get_tip(trigger, RT#role_task.task_id, Id), % {ok, BinData} = pt_302:write(30200, [RT#role_task.task_id, TipList]), % lib_server_send:send_to_uid(Id, BinData), % true. auto_finish_mark([], NewMark) -> NewMark; auto_finish_mark([MarkItem | T], NewMark) -> auto_finish_mark(T, NewMark ++ [auto_check_content(MarkItem)]). %% 检测任务内容是否完成 auto_check_content([D1, _Finish, kill, D2, Num, _NowNum]) -> [D1, 1, kill, D2, Num, Num]; auto_check_content([D1, _Finish, item, D2, Num, _NowNum]) -> [D1, 1, item, D2, Num, Num]; auto_check_content([D1, _Finish | D2]) -> [D1, 1 | D2]; auto_check_content(Other) -> Other. %% ================================= 进程字段记录 ================================= put_task_log_list(TaskId,TaskInfo) -> LogIdList = get_task_log_id_list(), case find_task_log_list(TaskId) of false -> put(log_id_list,[TaskId|LogIdList]), put({log, TaskId}, TaskInfo); Data -> C = Data#role_task_log.count + 1, put({log, TaskId}, TaskInfo#role_task_log{count = C}) end. find_task_log_list(TaskId) -> case get({log, TaskId}) of undefined -> false; Data -> Data end. %% 已经完成任务的ID列表 get_task_log_id_list() -> case get(log_id_list) of undefined -> []; Data -> Data end. find_task_log_exits(TaskId) -> ?IF(find_task_log_list(TaskId) == false, false, true). delete_task_log_list(TaskId) -> erase({log, TaskId}). get_task_bag_id_list() -> get("lib_task_task_bag_id_list"). set_task_bag_list(Data) -> put("lib_task_task_bag_id_list", Data). %% 按type类型 get_task_bag_id_list_type(Type)-> L = get_task_bag_id_list(), [ T || T <- L, T#role_task.type =:= Type]. %% 按TaskId类型 get_task_bag_id_list_task_id(TaskId)-> L = get_task_bag_id_list(), [ T || T <- L, T#role_task.task_id =:= TaskId]. %% 按kind类型 get_task_bag_id_list_kind(Kind)-> L = get_task_bag_id_list(), [ T || T <- L, T#role_task.kind =:= Kind]. put_task_bag_list(TaskInfo) -> %% upd_trigger(TaskInfo#role_task.role_id, TaskInfo#role_task.task_id, TaskInfo#role_task.state, TaskInfo#role_task.mark), List = lists:keydelete(TaskInfo#role_task.task_id, #role_task.task_id, get_task_bag_id_list()), put("lib_task_task_bag_id_list", [TaskInfo|List]). find_task_bag_list(TaskId) -> lists:keyfind(TaskId, #role_task.task_id, get_task_bag_id_list()). find_task_bag_exits(TaskId) -> ?IF(find_task_bag_list(TaskId) == false, false, true). %% 获取任务接取时间 get_trigger_time(TaskId) -> case find_task_bag_list(TaskId) of false -> false; RT -> RT#role_task.trigger_time end. delete_task_bag_list(TaskId) -> put("lib_task_task_bag_id_list", lists:keydelete(TaskId, #role_task.task_id, get_task_bag_id_list())). get_query_cache_list() -> get("lib_task_query_cache_list"). set_query_cache_list(Data) -> put("lib_task_query_cache_list", Data). %% 按类型 get_query_cache_list_type(Type)-> [ T || T <- get_query_cache_list(), T#task.type =:= Type]. put_query_cache_list(TaskInfo) -> List = lists:keydelete(TaskInfo#task.id, 2, get_query_cache_list()), List1 = List ++ [TaskInfo], put("lib_task_query_cache_list", List1). find_query_cache_list(TaskId) -> lists:keyfind(TaskId, 2, get_query_cache_list()). find_query_cache_exits(TaskId) -> ?IF(find_query_cache_list(TaskId) == false, false, true). delete_query_cache_list(TaskId) -> put("lib_task_query_cache_list", lists:keydelete(TaskId, #task.id, get_query_cache_list())). %% ================================= db op ================================= %% Type:1 2 3 4需要永久保存的,事物执行task 删除和记录日志操作 add_log(Rid, Tid, Type, TriggerTime, FinishTime, Count) -> %% 删除已触发的任务缓存 delete_task_bag_list(Tid), %% 记录任务日志缓存 put_task_log_list(Tid,#role_task_log{type = Type}), %% db操作 F = fun() -> if Type =/= ?TASK_TYPE_MAIN -> skip; true -> db:execute(io_lib:format(<<"update player_state set last_task_id = ~p where id= ~p">>, [Tid, Rid])) end, if Type == ?TASK_TYPE_MAIN; Type == ?TASK_TYPE_SIDE; Type == ?TASK_TYPE_TURN; Type == ?TASK_TYPE_CHAPTER; Type == ?TASK_TYPE_NUCLEON; Type == ?TASK_TYPE_FOUR-> db:execute(lists:concat(["insert into `task_log`(`role_id`,`task_id`,`type`,`trigger_time`,`finish_time`) values(",Rid,",",Tid,",",Type,",",TriggerTime,",",FinishTime,")"])); true -> db:execute(lists:concat(["insert into `task_log_clear`(`role_id`, `task_id`, `type`, `trigger_time`, `finish_time`, `count`) values(",Rid,",",Tid,",",Type,",",TriggerTime,",",FinishTime,",",Count,")"])) end, db:execute(lists:concat(["delete from `task_bag` where role_id=", Rid, " and task_id=", Tid])) end, db:transaction(F). %% 删除完成日志 del_log(Rid, Tid, Type) when Type == ?TASK_TYPE_MAIN; Type == ?TASK_TYPE_SIDE; Type == ?TASK_TYPE_TURN; Type == ?TASK_TYPE_CHAPTER; Type == ?TASK_TYPE_NUCLEON; Type == ?TASK_TYPE_FOUR -> db:execute(lists:concat(["delete from `task_log` where role_id=",Rid," and task_id=",Tid])); del_log(Rid, Tid, _Type) -> db:execute(lists:concat(["delete from `task_log_clear` where role_id=",Rid," and task_id=",Tid])). %% 删除完成日志 del_log_type(Type) when Type == ?TASK_TYPE_FOUR -> db:execute(io_lib:format("delete from `task_log` where `type` = ~p", [Type])); del_log_type(_Type) -> ok. %% 添加触发,新+到任务背包 add_trigger(Rid, Tid, TriggerTime, TaskState, TaskEndState, TaskMark, Type, Kind, RoleLv) -> put_task_bag_list(#role_task{role_id = Rid, task_id = Tid, trigger_time = TriggerTime, lv = RoleLv, state=TaskState, type=Type, kind=Kind, end_state=TaskEndState, mark = TaskMark}), delete_query_cache_list(Tid), db:execute( io_lib:format(<<"insert into `task_bag`(`role_id`, `task_id`, `trigger_time`, `state`, `end_state`, `mark`, `type`, `lv`) values(~p,~p,~p,~p,~p,'~s',~p, ~p)">>, [Rid, Tid, TriggerTime, TaskState, TaskEndState, util:term_to_bitstring(TaskMark), Type, RoleLv])). %% 更新任务记录器 upd_trigger(Rid, Tid, TaskState, TaskMark) -> db:execute(io_lib:format(<<"update `task_bag` set state=~p,mark='~s' where role_id=~p and task_id=~p">>, [TaskState, util:term_to_bitstring(TaskMark), Rid, Tid])). %% 玩家下线更新需要保存数据库的操作 task_offline_up(RoleTaskList)-> F = fun(TaskInfo, Args) -> case TaskInfo#role_task.write_db =/= 1 of true-> Args; _-> [TaskInfo|Args] end end, Tasks = lists:foldl(F, [], RoleTaskList), DbList = format_task_bag([],Tasks), Sql = ?SQL_ROLE_TASK_BAG_BATCH, batch_save(Sql,DbList), ok. format_task_bag(DbList,[])-> DbList; format_task_bag(DbList,[H|T])-> #role_task{ role_id = Rid, task_id = Tid, trigger_time = TriggerTime, lv = RoleLv, state=TaskState, type=Type, end_state=TaskEndState, mark = TaskMark, write_db = IsDb }=H, case IsDb >= 1 of true-> Data0 = [Rid, Tid, TriggerTime, TaskState, TaskEndState, util:term_to_bitstring(TaskMark), Type, RoleLv], Data1 = io_lib:format("(~p,~p,~p,~p,~p,'~ts',~p,~p)", Data0), format_task_bag([Data1|DbList],T); _-> format_task_bag(DbList,T) end. batch_save(_Sql,[])-> ok; batch_save(Sql,DbList)-> ArgsString = string:join(DbList, ","), SqlN = io_lib:format(Sql, [ArgsString]), db:execute(SqlN), ok. %% 删除触发任务 del_trigger_from_sql(Rid, Tid) -> db:execute(lists:concat(["delete from `task_bag` where role_id=", Rid, " and task_id=", Tid])). %% 日常任务清理 daily_clear(Clock, DelaySec)-> spawn(fun() -> util:multiserver_delay(DelaySec, lib_task, daily_clear, [Clock]) end), ok. %% 每日清理 daily_clear(Clock) -> case utime:day_of_week() of 1 -> %% 周一4点重置公会周任务 if Clock == ?TWELVE -> %% 周一0点清理可清理的任务日志和公会任务 skip; Clock == ?FOUR -> %% 日常支线任务(悬赏任务)(日清理) del_log_type(?TASK_TYPE_FOUR), db:execute("TRUNCATE TABLE `task_log_clear`"), db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_GUILD]) ), db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_DAILY]) ), db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_FOUR]) ); true -> skip end; _ -> if Clock =/= ?FOUR -> skip; true -> %% 日常支线任务(悬赏任务)(日清理) del_log_type(?TASK_TYPE_FOUR), db:execute("TRUNCATE TABLE `task_log_clear`"), db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_GUILD]) ), db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_DAILY]) ), db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_FOUR]) ) end end, case Clock of ?FOUR-> db:execute("delete from `task_log` where `task_id` = 3070002"), db:execute("delete from `task_bag` where `task_id` = 3070002"); _-> ignore end, %% 每个玩家清理 [gen_server:cast(D#ets_online.pid, {'refresh_and_clear_task', Clock}) || D <- ets:tab2list(?ETS_ONLINE)], ?ERR("task_clear_daily ~n", []), ok. %% ================================= 特殊的任务类型触发:悬赏任务和公会任务 ================================= %% return {false, ErrorCode} | {ok, ?SUCCESS} trigger_type_task(TaskType, TaskArgs)-> %% 是否已经接取了同类型任务 case get_task_bag_id_list_type(TaskType) of [] -> %% 过滤出响应等级的任务 case filter_task_type_ids(TaskType, TaskArgs) of [] -> {false, ?ERRCODE(err300_lv_no_task)}; TD when TaskType =:= ?TASK_TYPE_DAILY-> %%日常不拼接 TaskMark = [content_to_mark(E, TD#task.content, TaskArgs)||E<-TD#task.content], add_trigger(TaskArgs#task_args.id, TD#task.id, utime:unixtime(), 0, TD#task.state, TaskMark, TD#task.type, TD#task.kind, TaskArgs#task_args.figure#figure.lv), get_my_task_list(TaskType, TaskArgs), refresh_npc_ico(TaskArgs), {ok, ?SUCCESS}; TD-> %% npc显示 %% TaskArgs1 = do_dynamic_npc(TaskArgs, TD#task.npc_show), TaskMark = [content_to_mark(E, TD#task.content, TaskArgs)||E<-TD#task.content] ++ case TD#task.end_talk of 0 -> []; %% end_talk = 0 则直接提交任务 _ -> [content_to_mark([TD#task.state, ?TASK_CONTENT_END_TALK, TD#task.end_npc, TD#task.end_talk, 0, 0, 0, TD#task.finish_pathfind], TaskArgs)] end, add_trigger(TaskArgs#task_args.id, TD#task.id, utime:unixtime(), 0, TD#task.state, TaskMark, TD#task.type, TD#task.kind, TaskArgs#task_args.figure#figure.lv), get_my_task_list(TaskType, TaskArgs), refresh_npc_ico(TaskArgs), {ok, ?SUCCESS} end; _R -> ?ERR("error have task type:~p~n _R:~p~n", [TaskType, _R]), {false, ?ERRCODE(err300_task_trigger)} end. %% 过滤类型 filter_task_type_ids(TaskType, TaskArgs)-> ClsState = case czone_api:zone_enter_check_city() of true when TaskType =:= ?TASK_TYPE_DAILY-> 2; _-> 1 end, case data_task_lv_dynamic:get_type_task_id(TaskType,ClsState,TaskArgs#task_args.figure#figure.lv) of #task_lv_dynamic_id{task_ids = TaskIds} when TaskIds /= []-> TaskId = get_next_type_task_id(TaskType, TaskIds, TaskArgs#task_args.figure#figure.lv), case data_task_lv_dynamic:get_type_task_dynamic(TaskId, TaskArgs#task_args.figure#figure.lv) of #task_lv_dynamic_content{start_npc = StartNpc, end_npc = EndNpc, scene = SceneId, x = X, y = Y, content_type = ContentType, id = Id, num = NeedNum} -> case data_task:get(TaskId) of #task{kind = LastKind} = TD-> put({'last_task_kind_type', TaskType}, LastKind), format_task_dynamic_content(TD, StartNpc, EndNpc, SceneId, X, Y, ContentType, Id, NeedNum); _ -> ?ERR("error dynamic task_id :~p~n", [TaskId]), [] end; _ -> ?ERR("error dynamic content :~p~n", [[TaskIds, TaskArgs#task_args.figure#figure.lv]]), [] end; _ -> ?ERR("error dynamic task content :~p~n", [[TaskType, TaskArgs#task_args.figure#figure.lv]]), [] end. get_next_type_task_id(?TASK_TYPE_DAILY = TaskType, TaskIds, RoleLv) -> case lists:member(RoleLv, ?DAILY_SPECIAL_LV) of true -> get_special_task_id(TaskType, TaskIds); false -> do_get_next_type_task_id(TaskType, TaskIds) end; get_next_type_task_id(TaskType, TaskIds, _RoleLv) -> do_get_next_type_task_id(TaskType, TaskIds). get_special_task_id(?TASK_TYPE_DAILY = TaskType, TaskIds) -> Fun = fun({_, TaskId}, TmpList) -> case is_finish_task_id(TaskId) of true -> TmpList; false -> [TaskId | TmpList] end end, FilterList = lists:foldr(Fun, [], TaskIds), case FilterList == [] of true -> do_get_next_type_task_id(TaskType, TaskIds); false -> hd(FilterList) end; get_special_task_id(TaskType, TaskIds) -> do_get_next_type_task_id(TaskType, TaskIds). %%日常非类型过滤 do_get_next_type_task_id(?TASK_TYPE_DAILY, TaskIds)-> {_, TaskId} = util:find_ratio(TaskIds, 1), TaskId; % case get({'last_task_kind_type', TaskType}) of % undefined -> % {_, TaskId} = util:find_ratio(TaskIds, 1), % TaskId; % LastKindType -> % LessTaskIds = [{Weight, TId} || {Weight, TId} <- TaskIds, TaskInfo <- [data_task:get(TId)], TaskInfo#task.kind =/= LastKindType], % {_, TaskId} = util:find_ratio(LessTaskIds, 1), % TaskId % end. do_get_next_type_task_id(TaskType, TaskIds)-> case get({'last_task_kind_type', TaskType}) of undefined -> {_, TaskId} = util:find_ratio(TaskIds, 1), TaskId; LastKindType -> LessTaskIds = [{Weight, TId} || {Weight, TId} <- TaskIds, TaskInfo <- [data_task:get(TId)], TaskInfo#task.kind =/= LastKindType], {_, TaskId} = util:find_ratio(LessTaskIds, 1), TaskId end. %% 组装动态任务内容 format_task_dynamic_content(TD, StartNpcId, EndNpcId, SceneId, X, Y, ContentType, Id, NeedNum)-> Content = if StartNpcId == 0 -> []; true -> [[0, ?TASK_CONTENT_TALK, StartNpcId, TD#task.start_talk, 0, 0, 0, 1]] end, NewContent = if ContentType == 0 orelse Id == 0 -> []; ContentType == 5 -> Content; Content == [] -> [[0, ContentType, Id, NeedNum, SceneId, X, Y, 1]]; true -> Content ++ [[1, ContentType, Id, NeedNum, SceneId, X, Y, 1]] end, State = length(NewContent), if EndNpcId == 0 -> EndTalk = 0; true -> EndTalk = TD#task.end_talk end, TD#task{start_npc = StartNpcId, content = NewContent, end_npc = EndNpcId, state = State, end_talk = EndTalk}. %% 获取赏金(日常)和公会周任务 get_special_task_reward(TaskId, Type, TaskArgs) -> RoleId = TaskArgs#task_args.id, case get_one_trigger(TaskId) of false -> Goods = [], ExtraReward = []; RT -> Goods0 = calc_task_type_reward(Type, RT#role_task.lv), Goods = get_award_item(data_task:get(TaskId), TaskArgs)++Goods0, case data_task_lv_dynamic:get_task_type(Type) of #task_type{module_id = ModuleId, counter_id = CounterId} -> FinishCount = lib_daily:get_count(RoleId, ModuleId, CounterId)+1, ExtraReward = calc_extra_task_type_reward(TaskId, Type, FinishCount, RT#role_task.lv); _ -> ExtraReward = [] end end, lib_server_send:send_to_uid(RoleId, pt_300, 30011, [TaskId, Goods, ExtraReward]). %% ================================= 任务秘籍 ================================= %% 强制接取某个任务(秘籍使用) force_trigger(TaskId, TaskArgs) -> %% 删除缓存 delete_task_bag_list(TaskId), delete_task_log_list(TaskId), %% 删除db TD = get_data(TaskId), F = fun() -> del_trigger_from_sql(TaskArgs#task_args.id, TaskId), del_log(TaskArgs#task_args.id, TaskId, TD#task.type) end, db:transaction(F), %% 刷新 refresh_active(TaskArgs), TaskArgs1 = do_dynamic_npc(TaskArgs, TD#task.npc_show), TaskMark = [content_to_mark(E, TaskArgs1)||E<-TD#task.content] ++ case TD#task.end_talk of 0 -> []; %% end_talk=0则直接提交任务 _ -> [content_to_mark([TD#task.state, ?TASK_CONTENT_END_TALK, TD#task.end_npc, TD#task.end_talk, 0, 0, 0, TD#task.finish_pathfind], TaskArgs1)] end, add_trigger(TaskArgs#task_args.id, TaskId, utime:unixtime(), 0, TD#task.state, TaskMark, TD#task.type, TD#task.kind, TaskArgs#task_args.figure#figure.lv), %% 转生任务接取了要通知其他模块 if TD#task.type == ?TASK_TYPE_TURN -> lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_SAVE, transform, trigger_task, [TD#task.id]); true -> skip end, get_my_task_list(0, TaskArgs1), refresh_npc_ico(TaskArgs1), ok. %% 清理自身触发的任务 gm_refresh_task(GmType, TaskArgs) -> put("lib_task_task_bag_id_list", []), db:execute(io_lib:format("delete from task_log_clear where role_id=~w", [TaskArgs#task_args.id])), if GmType == 0 -> %% 当前已接 db:execute(io_lib:format("delete from task_bag where role_id=~w", [TaskArgs#task_args.id])); true -> %% 删除所有的任务,从0开始 [delete_task_log_list(Tid) || Tid <- data_task_lv:get_ids(TaskArgs#task_args.figure#figure.lv)], db:execute(io_lib:format("delete from task_log where role_id=~w", [TaskArgs#task_args.id])), db:execute(io_lib:format("delete from task_bag where role_id=~w", [TaskArgs#task_args.id])) end, flush_role_task(TaskArgs), get_my_task_list(0, TaskArgs), refresh_npc_ico(TaskArgs). %% 直接移除某个任务(秘籍使用) del_task(TaskId, TaskArgs) -> %% 删除缓存 delete_task_bag_list(TaskId), delete_task_log_list(TaskId), TD = get_data(TaskId), F = fun() -> db:execute(io_lib:format("delete from task_bag where role_id=~w and task_id=~p", [TaskArgs#task_args.id, TaskId])), del_log(TaskArgs#task_args.id, TaskId, TD#task.type) end, db:transaction(F), %% 刷新 refresh_active(TaskArgs), get_my_task_list(0, TaskArgs), refresh_npc_ico(TaskArgs), ok. %% 完成当前主线任务 gm_finitask(TaskArgs) -> % spawn(fun()-> finish_lv_task(TaskArgs) end), TaskList = get_task_bag_id_list(), Fun = fun(#role_task{task_id = TaskId, type = TaskType})-> case TaskType == ?TASK_TYPE_MAIN of true -> finish(TaskId, [], TaskArgs); false -> ok end end, lists:map(Fun, TaskList), get_my_task_list(0, TaskArgs), ok. gm_finish_lv_task(Status)-> TaskArgs = lib_task_api:ps2task_args(Status), finish_lv_task(TaskArgs). %% 完成该等级前的所有任务 finish_lv_task(#task_args{id=RoleId, figure=#figure{lv=Lv}}=TaskArgs) -> % Sql = io_lib:format(<<"delete from `role_npc_show` where id = ~p ">>, [RoleId]), % db:execute(Sql), AllIdList = data_task_lv:get_ids(Lv - 1), F2 = fun(TaskId, Acc) -> TD = data_task:get(TaskId), case TD of #task{type = 1} -> [TaskId|Acc]; _ -> Acc end end, MainTaskIds = lists:droplast( lists:foldr(F2, [], AllIdList)), %% 过滤后把当前级即最后一个去掉 case db:get_all(io_lib:format(<<"select task_id from task_log WHERE role_id=~p">>, [RoleId])) of LogIds when is_list(LogIds) -> LogIds2 = lists:usort(LogIds); _ -> LogIds2 = [] end, NowTime = utime:unixtime(), F1 = fun(TaskId, Acc) -> TD = data_task:get(TaskId), case TD =/= null andalso TD =/= [] andalso TD#task.type == 1 andalso lists:member(TaskId, LogIds2) == false of true -> Sql3 = io_lib:format(<<"REPLACE INTO `task_log` set `role_id`=~p, `task_id`=~p, `type`=~p, `trigger_time`=~p, `finish_time`=~p">>, [RoleId, TaskId, TD#task.type, NowTime, NowTime]), db:execute(Sql3), [TaskId|Acc]; false -> Acc end end, TIds = lists:foldl(F1, [], MainTaskIds), Sql2 = io_lib:format(<<"delete from `task_bag` where role_id=~p and task_id in (~s)">>, [RoleId, util:link_list(TIds)]), db:execute(Sql2), flush_role_task(TaskArgs), lv_up(TaskArgs), List = get_task_log_id_list(), lib_server_send:send_to_uid(RoleId, pt_300, 30017, [List]), ok. %%打包多个taskid pack_task_id(TaskList)-> Fun = fun(TaskId) -> <> end, ListBin = pt:write_array(Fun, TaskList), ListBin. %%解包多个taskid unpack_task_id(TaskListBin)-> Fun = fun(<>) -> <> = Bin0, {TaskId, _Args1} end, {TaskList, _Bin1} = pt:read_array(Fun, TaskListBin), TaskList. %%触发长剧情 event_to_story(PS, TaskId, EndTime) -> #player_status{id = RoleId, sid = Sid, scene = SceneId, scene_pool_id = ScenePoolId, copy_id = CopyId, x = X, y = Y} = PS, Utime = utime:unixtime(), %%默认60s DefaultTime = 60, Times = ?IF( EndTime - Utime > DefaultTime, DefaultTime, max(1, EndTime - Utime)), Ref = erlang:send_after(Times * 1000, self(), {mod, ?MODULE, event_to_cancel_story, [TaskId]}), put({?MODULE, event_story, TaskId}, Ref), lib_server_send:send_to_sid(Sid, pt_300, 30016, [?SUCCESS]), {ok, BinData} = pt_300:write(30017, [RoleId, 1]), lib_server_send:send_to_area_scene(SceneId, ScenePoolId, CopyId, X, Y, BinData), ok. %%触发结束长剧情 event_to_cancel_story(PS, TaskId) -> #player_status{id = RoleId, scene = SceneId, scene_pool_id = ScenePoolId, copy_id = CopyId, x = X, y = Y} = PS, lib_counter:increment(RoleId, ?MOD_TASK, 1, TaskId), Ref = get({?MODULE, event_story, TaskId}), util:cancel_timer(Ref), erase({?MODULE, event_story, TaskId}), {ok, BinData} = pt_300:write(30017, [RoleId, 0]), lib_server_send:send_to_area_scene(SceneId, ScenePoolId, CopyId, X, Y, BinData), {ok, PS}. after_finish_round_task(RoleId, TaskType, Num) -> if TaskType == ?TASK_TYPE_DAILY -> %% 日常任务 custom_act_mobilize:update_mobilize_task(RoleId, dailytask, Num), mod_hi_point:success_end(RoleId, ?MOD_TASK, 1, 1), custom_act_adventure:do_trigger_adventure_task(RoleId, ?MOD_TASK, 1), lib_activitycalen_api:role_success_end_activity(RoleId, ?MOD_TASK, 1, Num), lib_role_legion:trigger_task(RoleId, ?MOD_TASK, 1); TaskType == ?TASK_TYPE_GUILD -> %% 公会任务 lib_activitycalen_api:role_success_end_activity(RoleId, ?MOD_TASK, 2, Num), mod_hi_point:success_end(RoleId, ?MOD_TASK, 2, 1), custom_act_adventure:do_trigger_adventure_task(RoleId, ?MOD_TASK, 2), lib_guild_labor:task_active(RoleId,?GTASK_TYPE_TASK); true -> skip end. %%过滤对话选项任务的完成TalkId filter_task_talk([])-> 0; filter_task_talk([H|T])-> case H of [_, _, ?TASK_CONTENT_CHOOSE_TALK, _NeedId, _NeedNum, _Scene, _X, _Y,Talk, _PathFind]-> Talk; _-> filter_task_talk(T) end. %%npc矫正 fix_task_npc([],NewTriggerList,_TaskArgs)-> NewTriggerList; fix_task_npc([H|T],NewTriggerList,TaskArgs)-> #role_task{mark=Mark}=H, NMark = fix_task_mark(Mark,[],TaskArgs), fix_task_npc(T,[H#role_task{mark=NMark}|NewTriggerList],TaskArgs). fix_task_mark([],Mark,_TaskArgs)-> lists:reverse(Mark); fix_task_mark([[State,CurState,?TASK_CONTENT_CHOOSE_TALK,Id,Num,_SceneId,_X,_Y,NeedNum,PathFind]|Mark],NMark,TaskArgs)-> NewId=lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info), fix_task_mark(Mark,[[State,CurState,?TASK_CONTENT_CHOOSE_TALK,NewId,Num,RealSceneId, RealX, RealY,NeedNum,PathFind]|NMark],TaskArgs); fix_task_mark([[State,CurState,?TASK_CONTENT_TALK,Id,Num,_SceneId,_X,_Y,NeedNum,PathFind]|Mark],NMark,TaskArgs)-> NewId=lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info), fix_task_mark(Mark,[[State,CurState,?TASK_CONTENT_TALK,NewId,Num,RealSceneId, RealX, RealY,NeedNum,PathFind]|NMark],TaskArgs); fix_task_mark([[State,CurState,?TASK_CONTENT_END_TALK,Id,Num,_SceneId,_X,_Y,NeedNum,PathFind]|Mark],NMark,TaskArgs)-> NewId=lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info), fix_task_mark(Mark,[[State,CurState,?TASK_CONTENT_END_TALK,NewId,Num,RealSceneId, RealX, RealY,NeedNum,PathFind]|NMark],TaskArgs); fix_task_mark([[State,CurState,?TASK_CONTENT_MAILER_RUN,Id,Num,_SceneId,_X,_Y,NeedNum,PathFind]|Mark],NMark,TaskArgs)-> NewId=lib_role_task:exchange_npc(Id), {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info), fix_task_mark(Mark,[[State,CurState,?TASK_CONTENT_MAILER_RUN,NewId,Num,RealSceneId, RealX, RealY,NeedNum,PathFind]|NMark],TaskArgs); fix_task_mark([H|T],NMark,TaskArgs)-> fix_task_mark(T,[H|NMark],TaskArgs).