|
|
- %%%-----------------------------------
- %%% @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) -> <<TaskId:32>> end,
- ListBin = pt:write_array(Fun, TaskList),
- ListBin.
-
- %%解包多个taskid
- unpack_task_id(TaskListBin)->
- Fun = fun(<<Bin0/binary>>) ->
- <<TaskId:32, _Args1/binary>> = 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).
|