源战役
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2546 lines
115 KiB

  1. %%%-----------------------------------
  2. %%% @Module : lib_task
  3. %%% @Author : xyao
  4. %%% @Created : 2010.05.05
  5. %%% @Description: 任务
  6. %%%-----------------------------------
  7. -module(lib_task).
  8. -compile(export_all).
  9. -include("scene.hrl").
  10. -include("common.hrl").
  11. -include("server.hrl").
  12. -include("task.hrl").
  13. -include("figure.hrl").
  14. -include("team.hrl").
  15. -include("errcode.hrl").
  16. -include("predefine.hrl").
  17. -include("def_module.hrl").
  18. -include("goods.hrl").
  19. -include("daily.hrl").
  20. -include("def_fun.hrl").
  21. -include("def_goods.hrl").
  22. -include("guild_labor.hrl").
  23. -include("dungeon.hrl").
  24. -include("local_boss.hrl").
  25. -define(LIMIT_TIME1, 900).
  26. -define(LIMIT_TIME2, 1800).
  27. %% 获取我的任务列表
  28. get_my_task_list(TaskArgs)->
  29. get_my_task_list(0,TaskArgs).
  30. get_my_task_list(Type,#task_args{id = RoleId, sid=Sid}=TaskArgs) ->
  31. %% 可接任务
  32. F = fun(TD, TmpActiveList) ->
  33. case Type == 0 orelse TD#task.type == Type of
  34. true ->
  35. [{TD#task.id, get_tip(active, TD#task.id, TaskArgs)} | TmpActiveList];
  36. false ->
  37. TmpActiveList
  38. end
  39. end,
  40. ActiveList = lists:foldl(F, [], get_active()),
  41. %% 已接任务
  42. NowTime = utime:unixtime(),
  43. F1 = fun(RT, {TL, CL}) ->
  44. #role_task{task_id = TaskId, type = TaskType, trigger_time = TriggerTime, mark = Mark} = RT,
  45. if
  46. Type =/= 0 andalso TaskType =/= Type ->
  47. {TL, CL};
  48. TaskType == ?TASK_TYPE_CHAPTER ->
  49. LimitTime = ?IF(TaskId == 101 orelse TaskId == 102, ?LIMIT_TIME1, ?LIMIT_TIME2),
  50. if
  51. NowTime > TriggerTime + LimitTime -> %% 大于限时
  52. case is_finish_mark(Mark, TaskArgs) of
  53. false -> {TL, [RT|CL]};
  54. true ->
  55. TipList = get_tip(trigger, TaskId, TaskArgs),
  56. {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(TipList),
  57. {[{TaskId, TipList, WitchState, NeedNum, NowNum, TriggerTime}|TL], CL}
  58. end;
  59. true ->
  60. TipList = get_tip(trigger, TaskId, TaskArgs),
  61. {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(TipList),
  62. {[{TaskId, TipList, WitchState, NeedNum, NowNum, TriggerTime}|TL], CL}
  63. end;
  64. true ->
  65. TipList = get_tip(trigger, TaskId, TaskArgs),
  66. {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(TipList),
  67. {[{TaskId, TipList, WitchState, NeedNum, NowNum, TriggerTime}|TL], CL}
  68. end
  69. end,
  70. {TriggerList, NeedToDelTask} = lists:foldl(F1, {[], []}, get_trigger()),
  71. %% 删除需要去掉的限时章节任务
  72. F2 = fun(RT) ->
  73. #role_task{task_id = TaskId, type = TaskType, trigger_time = TriggerTime} = RT,
  74. add_log(RoleId, TaskId, TaskType, TriggerTime, 0, 0) %% 完成时间是0就代表过时
  75. end,
  76. lists:map(F2, NeedToDelTask),
  77. {ok, BinData} = pt_300:write(30000, [Type, ActiveList, TriggerList]),
  78. lib_server_send:send_to_sid(Sid, BinData).
  79. %% 获取任务是否完成
  80. get_task_finish_state(TaskId, TaskArgs)->
  81. case get_one_trigger(TaskId) of
  82. false -> ?ERRCODE(err300_no_task_trigger); %% 没接这个任务
  83. RT -> ?IF(is_finish(RT, TaskArgs), true, ?ERRCODE(err300_task_no_finish))
  84. end.
  85. %% 获取任务类型
  86. get_task_type(TaskId) ->
  87. TD = get_data(TaskId),
  88. ?IF(TD == null, 0, TD#task.type).
  89. %% 升级自动触发任务
  90. lv_up(TaskArgs) ->
  91. %% 刷新缓存可以优化一下
  92. refresh_active(TaskArgs),
  93. case auto_trigger(TaskArgs) of
  94. true -> skip;
  95. _ ->
  96. skip
  97. end,
  98. get_my_task_list(0, TaskArgs),
  99. refresh_npc_ico(TaskArgs).
  100. %% ================================= 登录加载数据 =================================
  101. flush_role_task(TaskArgs) ->
  102. #task_args{id = Id} = TaskArgs,
  103. %% 所有已经触发的任务列表
  104. F1 = fun([Tid, Tt, S ,ES, M, TP, Lv], AllTask) ->
  105. case data_task:get(Tid) of
  106. null ->
  107. del_trigger_from_sql(Id, Tid), %% 移除无效的已接任务
  108. AllTask;
  109. _ ->
  110. Kind = case data_task_condition:get(Tid) of
  111. null -> 0;
  112. TD -> TD#task_condition.kind
  113. end,
  114. case util:bitstring_to_term(M) of
  115. undefined -> AllTask;
  116. Mark ->
  117. [#role_task{role_id=Id, lv = Lv, task_id=Tid, trigger_time = Tt,
  118. state = S, end_state = ES, mark = Mark, type=TP, kind = Kind}|AllTask]
  119. end
  120. end
  121. end,
  122. 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])),
  123. RoleTaskListRed = lists:foldl(F1, [], RoleTaskList),
  124. set_task_bag_list(RoleTaskListRed),
  125. %% 所有已经完成的任务列表
  126. F2 = fun([Tid2, Ty2]) ->
  127. put_task_log_list(Tid2,#role_task_log{type= Ty2})
  128. end,
  129. RoleTaskLogList = db:get_all(io_lib:format("select task_id, type from task_log where role_id=~w", [Id])),
  130. lists:map(F2, RoleTaskLogList),
  131. refresh_active(TaskArgs),
  132. get_my_task_list(0, TaskArgs),
  133. %% 自动接取任务
  134. auto_trigger(TaskArgs),
  135. auto_finish(TaskArgs),
  136. login_after(TaskArgs),
  137. ok.
  138. login_after(TaskArgs) ->
  139. %%同步转生任务id
  140. case get_task_bag_id_list_type(?TASK_TYPE_TURN) of
  141. [#role_task{task_id = TaskId} | _T] ->
  142. lib_task_event:trigger_after(data_task:get(TaskId), TaskArgs);
  143. _ -> ok
  144. end.
  145. %%上线处理已完成的触发任务
  146. handle_refresh_trigger(TaskArgs)->
  147. RoleTaskList = get_task_bag_id_list(),
  148. %%纠正配置不匹配任务
  149. case catch do_refresh_conflict_trigger(RoleTaskList, TaskArgs, []) of
  150. UpdateList when is_list(UpdateList) ->
  151. case UpdateList =/= [] of
  152. true ->
  153. refresh_task(TaskArgs);
  154. false -> ok
  155. end;
  156. _Rson ->
  157. ?ERR("do_refresh_conflict_trigger~p~n",[_Rson])
  158. end,
  159. NewRoleTaskList = get_task_bag_id_list(),
  160. %%自动完成已接取的特殊支线任务和可能离线完成的主线特殊任务(副本)
  161. case catch do_handle_refresh_trigger(NewRoleTaskList, TaskArgs, []) of
  162. [] -> ok;
  163. EventList when is_list(EventList) ->
  164. lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_STATUS, lib_task_api, cast_handle_refresh_trigger, [EventList]);
  165. _Reason ->
  166. Rid = TaskArgs#task_args.id,
  167. ?ERR("do_handle_refresh_trigger~p:~p~n",[Rid, _Reason])
  168. end.
  169. %%纠正配置不匹配任务
  170. do_refresh_conflict_trigger([], _TaskArgs, UpdateList) -> UpdateList;
  171. do_refresh_conflict_trigger([RT | T], TaskArgs, UpdateList) ->
  172. TD = data_task:get(RT#role_task.task_id),
  173. NewUpdateList = do_conflict_correct(TD, TaskArgs, RT, UpdateList),
  174. do_refresh_conflict_trigger(T, TaskArgs, NewUpdateList).
  175. %%检测条件
  176. % 等级不匹配:直接清任务
  177. % 任务内容不匹配:替换更新任务
  178. do_conflict_correct(#task{type = Type} = TD, TaskArgs, RT, UpdateList)
  179. when Type == ?TASK_TYPE_MAIN orelse Type == ?TASK_TYPE_SIDE orelse
  180. Type == ?TASK_TYPE_TURN orelse Type == ?TASK_TYPE_CHAPTER orelse
  181. Type == ?TASK_TYPE_NUCLEON ->
  182. CheckList = [lv, content],
  183. case check_conflict(CheckList, TaskArgs, TD, RT) of
  184. {true, Reason, NewRT} ->
  185. do_conflict_correct_help(Reason, RT, NewRT),
  186. [1|UpdateList];
  187. _ -> UpdateList
  188. end;
  189. do_conflict_correct(_, _TaskArgs, _RT, UpdateList) -> UpdateList.
  190. check_conflict([], _TaskArgs, _TD, _RT) -> true;
  191. check_conflict([lv | T], TaskArgs, TD, RT) ->
  192. Lv = TaskArgs#task_args.figure#figure.lv,
  193. case Lv < TD#task.level of
  194. true -> {true, del, RT};
  195. false -> check_conflict(T, TaskArgs, TD, RT)
  196. end;
  197. check_conflict([content | T], TaskArgs, #task{content = Content} = TD, RT) ->
  198. CfgTaskMark = [content_to_mark(E, TaskArgs)|| E <- Content]
  199. ++ case TD#task.end_talk of
  200. 0 -> []; %% end_talk = 0则直接提交任务
  201. _ ->
  202. [content_to_mark([TD#task.state, ?TASK_CONTENT_END_TALK, TD#task.end_npc,
  203. TD#task.end_talk, 0, 0, 0, TD#task.finish_pathfind], TaskArgs)]
  204. end,
  205. Mark = RT#role_task.mark,
  206. %%检测任务内容冲突(主要存在情况)
  207. case check_content_conflict(CfgTaskMark, Mark, RT, []) of
  208. {true, Mark, _NewRT} -> check_conflict(T, TaskArgs, TD, RT);
  209. {true, _NewMark, NewRT} -> %%与配置有出入,处理
  210. % ?ERR("do_conflict_trigger~p,~p,~p~n", [TaskArgs#task_args.id, NewMark, Mark]),
  211. {true, update, NewRT};
  212. _ -> check_conflict(T, TaskArgs, TD, RT)
  213. end;
  214. check_conflict([_H | T], TaskArgs, TD, RT) ->
  215. check_conflict(T, TaskArgs, TD, RT).
  216. check_content_conflict([], [], RT, NewMark) -> {true, NewMark, RT#role_task{mark = NewMark}};
  217. check_content_conflict([], _, RT, NewMark) -> {true, NewMark, RT#role_task{mark = NewMark}};
  218. check_content_conflict([CfgE | CfgT], [ME | MET], RT, NewMark) ->
  219. [State, _, ContentType, Id, NeedNum, RealSceneId, RealX, RealY, _, PathFind] = CfgE,
  220. case ME of
  221. [State, _Finish, ContentType, Id, NeedNum, RealSceneId, RealX, RealY, _Num, _PathFind] -> %%相同不处理
  222. NewMark1 = NewMark ++ [ME],
  223. check_content_conflict(CfgT, MET, RT, NewMark1);
  224. [_, _, ContentType, Id, _, _, _, _, Num, _] -> %% 类型和id相同,保持数量不变,纠正其它信息
  225. case Num >= NeedNum of
  226. true ->
  227. NewMark1 = NewMark ++ [[State, 1, ContentType, Id, NeedNum, RealSceneId, RealX, RealY, Num, PathFind]];
  228. false ->
  229. FinishState = ?IF(ContentType == ?TASK_CONTENT_END_TALK, 1, 0),
  230. NewMark1 = NewMark ++ [[State, FinishState, ContentType, Id, NeedNum, RealSceneId, RealX, RealY, Num, PathFind]]
  231. end,
  232. check_content_conflict(CfgT, MET, RT, NewMark1);
  233. [_, _, _, _, _, _, _, _, _, _] -> %% 纠正所有信息
  234. NewMark1 = NewMark ++ [CfgE],
  235. check_content_conflict(CfgT, MET, RT, NewMark1);
  236. _ -> ok %%异常
  237. end;
  238. check_content_conflict([CfgE | CfgT], [], RT, NewMark) ->
  239. NewMark1 = NewMark ++ [CfgE],
  240. check_content_conflict(CfgT, [], RT, NewMark1).
  241. %%处理冲突的任务
  242. do_conflict_correct_help(update, _OldRT, NewRT) ->
  243. #role_task{role_id = RId, task_id = TaskId, mark = Mark, end_state = EndState} = NewRT,
  244. NoFinishState = [EachState || [EachState, 0|_ ] <- Mark],
  245. if
  246. NoFinishState == [] -> NewState = EndState;
  247. true -> NewState = lists:min(NoFinishState)
  248. end,
  249. ?IF(NewState == 0, ok, refresh_npc_ico(RId)),
  250. upd_trigger(RId, TaskId, NewState, Mark),
  251. put_task_bag_list(NewRT#role_task{write_db = 0, state = NewState}),
  252. case NewState == EndState of
  253. true ->
  254. case lists:last(Mark) of
  255. [_, 1, ?TASK_CONTENT_END_TALK|_] -> ok;
  256. _R -> auto_finish_task(RId, TaskId)
  257. end;
  258. _ -> ok
  259. end;
  260. do_conflict_correct_help(del, _OldRT, NewRT) ->
  261. #role_task{role_id = RId, task_id = TaskId} = NewRT,
  262. %% 删除缓存
  263. delete_task_bag_list(TaskId),
  264. %% 删除数据库
  265. del_trigger_from_sql(RId, TaskId),
  266. %% 刷新npc头图标
  267. refresh_npc_ico(RId),
  268. ok;
  269. do_conflict_correct_help(_, _OldRT, _NewRT) -> ok.
  270. %%处理已完成的触发支线任务
  271. do_handle_refresh_trigger([], _TaskArgs, EventList) -> EventList;
  272. do_handle_refresh_trigger([#role_task{type = ?TASK_TYPE_SIDE, task_id = TaskId, mark = TaskMark} |T], TaskArgs, OEventList) ->
  273. EventList = handle_finish_before_trigger(TaskId, TaskMark, TaskArgs, []),
  274. do_handle_refresh_trigger(T, TaskArgs, OEventList ++ EventList);
  275. 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) ->
  276. EventList = handle_finish_before_trigger(TaskId, TaskMark, TaskArgs, []),
  277. do_handle_refresh_trigger(T, TaskArgs, OEventList ++ EventList);
  278. do_handle_refresh_trigger([_RT |T], TaskArgs, EventList) ->
  279. do_handle_refresh_trigger(T, TaskArgs, EventList).
  280. %% 刷新任务并发送更新列表
  281. refresh_task(#task_args{id=Id}=TaskArgs) ->
  282. refresh_active(TaskArgs),
  283. refresh_npc_ico(Id),
  284. {ok, BinData} = pt_300:write(30006, []),
  285. lib_server_send:send_to_uid(Id, BinData).
  286. %% 遍历所有任务看是否可接任务
  287. refresh_active(TaskArgs) ->
  288. #task_args{figure=#figure{lv=Lv}} = TaskArgs,
  289. Tids = data_task_lv:get_ids(Lv),
  290. F = fun(Tid) -> get_data(Tid) end,
  291. QueryCacheListRed = [F(Tid) || Tid <- Tids, check_task_type(Tid), can_trigger(Tid, TaskArgs) == true],
  292. set_query_cache_list(QueryCacheListRed).
  293. %% 日常和公会任务不会进入可接缓存
  294. check_task_type(Tid)->
  295. #task{type = TaskType} = get_data(Tid),
  296. ?IF(TaskType == ?TASK_TYPE_DAILY orelse TaskType == ?TASK_TYPE_GUILD, false, true).
  297. %% 刷新悬赏任务和公会周任务
  298. refresh_trigger_by_type(TaskArgs, TaskType) ->
  299. TriggerTasks = get_trigger(),
  300. F1 = fun(RT, L) -> ?IF(RT#role_task.type =/= TaskType, [RT|L], L) end,
  301. NewTriggerList0 = lists:foldl(F1, [], TriggerTasks),
  302. KfDay = data_key_value:get(1030001),
  303. NewTriggerList = case util:get_open_day()>= KfDay of
  304. true->
  305. fix_task_npc(NewTriggerList0,[],TaskArgs);
  306. _->
  307. NewTriggerList0
  308. end,
  309. set_task_bag_list(NewTriggerList).
  310. %% 获取任务详细数据
  311. get_data(TaskId) ->
  312. TD = data_task:get(TaskId),
  313. ?IF(TD == null, #task{}, TD).
  314. %% 获取玩家能在该Npc接任务或者交任务
  315. get_npc_task_list(NpcId, TaskArgs) ->
  316. {CanTrigger, Link, UnFinish, Finish} = get_npc_task(NpcId, TaskArgs),
  317. F1 = fun({Tid,TriTime,ShowTalk}, NS) -> TD = get_data(Tid), {Tid, NS, TD#task.name, TD#task.type,TriTime,ShowTalk} end,
  318. F2 = fun(TD, NS) -> {TD#task.id, NS, TD#task.name, TD#task.type,0,0} end,
  319. L1 = [F2(T1, 1) || T1 <- CanTrigger, T1#task.level =< TaskArgs#task_args.figure#figure.lv],
  320. L2 = [F1(T2, 4) || T2 <- Link],
  321. L3 = [F1(T3, 2) || T3 <- UnFinish],
  322. L4 = [F1(T4, 3) || T4 <- Finish],
  323. L1++L2++L3++L4.
  324. %% 动态控制npc
  325. do_dynamic_npc(TaskArgs, []) -> TaskArgs;
  326. do_dynamic_npc(#task_args{id=Id, npc_info=NpcInfo}=TaskArgs, NpcShow) ->
  327. NewNpcInfo = lib_npc:change_role_npc_info(Id, NpcInfo, NpcShow),
  328. lib_player:apply_cast(Id, ?APPLY_CAST_STATUS, lib_npc, update_role_npc_info, [NewNpcInfo]),
  329. TaskArgs#task_args{npc_info=NewNpcInfo}.
  330. %% 更新场景上npc的任务图标
  331. refresh_npc_ico(#task_args{scene=Scene, sid=Sid, npc_info=NpcInfo}=TaskArgs) ->
  332. NpcList = lib_npc:get_scene_npc(Scene, NpcInfo),
  333. F = fun({Id, _, _, _, _, _}) ->
  334. S = ?IF(Id == 0, 0, get_npc_state(Id, TaskArgs)),
  335. [Id, S]
  336. end,
  337. L = lists:map(F, NpcList),
  338. {ok, BinData} = pt_120:write(12020, [L]),
  339. lib_server_send:send_to_sid(Sid, BinData);
  340. refresh_npc_ico(#player_status{} = PS) ->
  341. TaskArgs = lib_task_api:ps2task_args(PS),
  342. refresh_npc_ico(TaskArgs);
  343. refresh_npc_ico(PlayerId) ->
  344. case misc:get_player_process(PlayerId) of
  345. Pid when is_pid(Pid) -> lib_player:apply_cast(Pid, ?APPLY_CAST_STATUS, ?NOT_HAND_OFFLINE, lib_task, refresh_npc_ico, []);
  346. _ -> skip
  347. end.
  348. %% 获取npc任务状态
  349. get_npc_state(NpcId, TaskArgs) ->
  350. {CanTrigger, Link, UnFinish, Finish} = get_npc_task(NpcId, TaskArgs),
  351. %% 0表示什么都没有,1表示有可接任务,2表示已接受任务但未完成,3表示有完成任务,4表示有任务相关
  352. case length(Finish) > 0 of
  353. true -> 3;
  354. false ->
  355. case length(Link)>0 of
  356. true-> 4;
  357. false->
  358. case length([0 || RT <- CanTrigger, RT#task.level =< TaskArgs#task_args.figure#figure.lv])>0 of
  359. true -> 1;
  360. false ->
  361. case length(UnFinish)>0 of
  362. true -> 2;
  363. false -> 0
  364. end
  365. end
  366. end
  367. end.
  368. %% 获取npc任务关联
  369. %%{可接任务,关联,任务未完成,完成任务}
  370. get_npc_task(NpcId, TaskArgs)->
  371. CanTrigger = [ TS || TS <- get_query_cache_list(), lib_role_task:exchange_npc(TS#task.start_npc) =:= NpcId],
  372. %% 已经接了的任务处理
  373. {Link, Unfinish, Finish} = get_npc_other_link_task(NpcId, TaskArgs),
  374. {CanTrigger, Link, Unfinish, Finish}.
  375. %% 获取已触发任务
  376. get_npc_other_link_task(NpcId, TaskArgs) ->
  377. get_npc_other_link_task(get_task_bag_id_list(), {[], [], []}, NpcId, TaskArgs).
  378. get_npc_other_link_task([], Result, _, _) -> Result;
  379. get_npc_other_link_task([RT | T], {Link, Unfinish, Finish}, NpcId, TaskArgs) ->
  380. TD = get_data(RT#role_task.task_id),
  381. case is_finish(RT, TaskArgs) andalso get_end_npc_id(RT) =:= NpcId of %% 判断是否完成
  382. 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);
  383. false ->
  384. case task_talk_to_npc(RT, NpcId) of %% 判断是否和NPC对话
  385. 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);
  386. false ->
  387. %% 获取npc未完成
  388. case get_start_npc(TD#task.start_npc, TaskArgs#task_args.figure#figure.career) =:= NpcId of %% 判断是否接任务NPC
  389. 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);
  390. false -> get_npc_other_link_task(T, {Link, Unfinish, Finish}, NpcId, TaskArgs)
  391. end
  392. end
  393. end.
  394. %%过滤对话选项任务的完成TalkId
  395. filter_show_talk([])->
  396. 0;
  397. filter_show_talk([H|T])->
  398. case H of
  399. [_, _, ?TASK_CONTENT_CHOOSE_TALK, _NeedId, ShowTalk, _Scene, _X, _Y,_Talk, _PathFind]->
  400. ShowTalk;
  401. _->
  402. filter_show_talk(T)
  403. end.
  404. %%检查任务的下一内容是否为与某npc的对话
  405. task_talk_to_npc(RT, NpcId)->
  406. 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])],
  407. length(Temp)>0.
  408. %% 获取任务对话id
  409. get_npc_task_talk_id(TaskId, NpcId, TaskArgs) ->
  410. case get_data(TaskId) of
  411. null -> {none, 0};
  412. TD ->
  413. {CanTrigger, Link, UnFinish, Finish} = get_npc_task(NpcId, TaskArgs),
  414. case {lists:keymember(TaskId, #task.id, CanTrigger), lists:keymember(TaskId,1,Link),
  415. lists:keymember(TaskId,1,UnFinish), lists:keymember(TaskId,1,Finish) } of
  416. {true, _, _, _} -> {start_talk, TD#task.start_talk}; %% 任务触发对话
  417. {_, true, _, _} -> %% 关联对话
  418. case get_one_trigger(TaskId) of
  419. false ->
  420. {none, 0};
  421. RT ->
  422. [Fir|_] = [TalkId || [State,Fin,CType,Nid,TalkId|_] <- RT#role_task.mark,
  423. 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])],
  424. {link_talk, Fir}
  425. end;
  426. {_, _, true, _} -> {unfinished_talk, TD#task.unfinished_talk}; %% 未完成对话
  427. {_, _, _, true} -> %% 提交任务对话
  428. case get_one_trigger(TaskId) of
  429. false ->
  430. {none, 0};
  431. RT ->
  432. [Fir|_] = [TalkId || [_,_,?TASK_CONTENT_END_TALK,Nid,TalkId|_] <- RT#role_task.mark, lib_role_task:exchange_npc(Nid) == NpcId],
  433. {end_talk, Fir}
  434. end;
  435. _ -> {none, 0}
  436. end
  437. end.
  438. %% 获取提示信息
  439. %% 可接任务会有开始npc对话
  440. get_tip(active, TaskId, #task_args{figure=#figure{career=Career}}=TaskArgs) ->
  441. TD = get_data(TaskId),
  442. case get_start_npc(TD#task.start_npc, Career) of
  443. 0 -> [];
  444. StartNpcId ->
  445. [content_to_mark([0, ?TASK_CONTENT_TALK, StartNpcId, TD#task.start_talk, 0, 0, 0, TD#task.trigger_pathfind], TaskArgs)]
  446. end;
  447. get_tip(trigger, TaskId, TaskArgs) ->
  448. RT = get_one_trigger(TaskId),
  449. [mark_refresh(TaskMark, TaskArgs) || TaskMark <- RT#role_task.mark].
  450. %% 任务阶段内容 转为 任务完成情况记录
  451. %% 任务内容格式:[State(阶段), ContentType(内容类型), Id(任务id), Num(采集或者杀怪的需要数量), ScneId, X, Y, PathFind]
  452. %% 任务内存格式:[State(阶段), IsFinish(是否完成) ContentType(内容类型), Id(任务id), Num(采集或者杀怪的需要数量), ScneId, X, Y, RealNum(收集或者杀怪的完成数量), PathFind]
  453. content_to_mark([State, ContentType, Id, Num, SceneId, X, Y, PathFind], TaskArgs) ->
  454. content_to_mark([State, ContentType, Id, Num, SceneId, X, Y, PathFind], [],TaskArgs).
  455. content_to_mark([State, ContentType, Id, Num, SceneId, X, Y, PathFind], _Contents, TaskArgs)->
  456. case ContentType of
  457. ?TASK_CONTENT_START_TALK ->
  458. NewId=lib_role_task:exchange_npc(Id),
  459. {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info),
  460. [State, 0, ContentType, NewId, Num, RealSceneId, RealX, RealY, 0, PathFind];
  461. ?TASK_CONTENT_END_TALK ->
  462. NewId=lib_role_task:exchange_npc(Id),
  463. {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info),
  464. [State, 1, ContentType, NewId, Num, RealSceneId, RealX, RealY, 0, PathFind];
  465. ?TASK_CONTENT_TALK ->
  466. NewId=lib_role_task:exchange_npc(Id),
  467. {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info),
  468. [State, 0, ContentType, NewId, Num, RealSceneId, RealX, RealY, 0, PathFind];
  469. ?TASK_CONTENT_ITEM ->
  470. #task_args{id = RoleId, gs_dict = GsDict} = TaskArgs,
  471. case data_goods_type:get(Id) of
  472. #ets_goods_type{bag_location = BagLocation} ->
  473. GoodsList = lib_goods_util:get_type_goods_list(RoleId, Id, BagLocation, GsDict, 0),
  474. TotalNum = lib_goods_util:get_goods_total_num(GoodsList);
  475. _ ->
  476. ?ERR("goods_num err: goods_type_id = ~p err_config", [Id]),
  477. TotalNum = 0
  478. end,
  479. {Finish, NowNum} = ?IF(TotalNum >= Num, {1, Num}, {0, TotalNum}),
  480. [State, Finish, ContentType, Id, Num, SceneId, X, Y, NowNum, PathFind];
  481. ?TASK_CONTENT_MAILER_RUN ->
  482. NewId=lib_role_task:exchange_npc(Id),
  483. {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info),
  484. [State, 0, ContentType, NewId, Num, RealSceneId, RealX, RealY, 0, PathFind];
  485. _ ->
  486. [State, 0, ContentType, Id, Num, SceneId, X, Y, 0, PathFind]
  487. end;
  488. content_to_mark(_, _Contents, _TaskArgs) -> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0].
  489. %% 异常时刷新
  490. mark_refresh([State, Fin, ContentType, Id, Num, Scene, _X, _Y, Count, PathFind]=Mark, TaskArgs) ->
  491. if
  492. Scene == 0 andalso (ContentType == ?TASK_CONTENT_START_TALK orelse
  493. ContentType == ?TASK_CONTENT_END_TALK orelse
  494. ContentType == ?TASK_CONTENT_TALK) ->
  495. NewNpc=lib_role_task:exchange_npc(Id),
  496. {RealSceneId, RealX, RealY} = get_npc_info(NewNpc, TaskArgs#task_args.npc_info),
  497. [State, Fin, ContentType, NewNpc, Num, RealSceneId, RealX, RealY, Count, PathFind];
  498. ContentType =:= ?TASK_CONTENT_CHOOSE_TALK ->
  499. NewNpc = lib_role_task:exchange_npc(Id),
  500. {RealSceneId, RealX, RealY} = get_npc_info(NewNpc, TaskArgs#task_args.npc_info),
  501. [State, Fin, ContentType, NewNpc, Num, RealSceneId, RealX, RealY, Count, PathFind];
  502. true ->
  503. Mark
  504. end.
  505. %% 获取奖励
  506. get_award_item(TD, TaskArgs) ->
  507. SL = get_special_reward_item(TD#task.special_goods_list, TaskArgs, []),
  508. F = fun(E, LL) ->
  509. case E of
  510. {?TYPE_GOODS, GoodsTypeId, Num} -> [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|LL];
  511. _ -> [E|LL]
  512. end
  513. end,
  514. lists:foldl(F, SL, TD#task.award_list).
  515. %% 获取特殊奖励
  516. get_special_reward_item([], _TaskArgs, Rewards) -> Rewards;
  517. get_special_reward_item([{Career, Sex, GoodsTypeId, Num}|SpecialGoods], TaskArgs, Rewards) ->
  518. if
  519. Career == 0 andalso Sex == 0 ->
  520. get_special_reward_item(SpecialGoods, TaskArgs, [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|Rewards]);
  521. Career == TaskArgs#task_args.figure#figure.career andalso Sex == 0->
  522. get_special_reward_item(SpecialGoods, TaskArgs, [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|Rewards]);
  523. Sex == TaskArgs#task_args.figure#figure.sex andalso Career == 0 ->
  524. get_special_reward_item(SpecialGoods, TaskArgs, [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|Rewards]);
  525. Career == TaskArgs#task_args.figure#figure.career andalso Sex == TaskArgs#task_args.figure#figure.sex ->
  526. get_special_reward_item(SpecialGoods, TaskArgs, [{?TYPE_BIND_GOODS, GoodsTypeId, Num}|Rewards]);
  527. true ->
  528. get_special_reward_item(SpecialGoods, TaskArgs, Rewards)
  529. end;
  530. get_special_reward_item([_|SpecialGoods], TaskArgs, Rewards) ->
  531. get_special_reward_item(SpecialGoods, TaskArgs, Rewards).
  532. %% 获取开始npc的id
  533. %% 如果需要判断职业才匹配第2,3
  534. get_start_npc(StartNpc, _) when is_integer(StartNpc) ->
  535. lib_role_task:exchange_npc(StartNpc);
  536. get_start_npc([], _) -> 0;
  537. get_start_npc([{career, Career, NpcId}|T], RoleCareer) ->
  538. case Career =:= RoleCareer of
  539. false -> get_start_npc(T, RoleCareer);
  540. true -> lib_role_task:exchange_npc(NpcId)
  541. end.
  542. %%获取当前NPC所在的场景(自动寻路用)
  543. get_npc_info(NpcId, NpcInfo) ->
  544. case lists:keyfind(NpcId, 1, NpcInfo) of
  545. {_, _IsShow, Scene, X, Y, _} -> {Scene, X, Y};
  546. false ->
  547. case lib_npc:get_npc_info_by_id(NpcId) of
  548. [] -> {0, 0, 0};
  549. Npc -> {Npc#ets_npc.scene, Npc#ets_npc.x, Npc#ets_npc.y}
  550. end
  551. end.
  552. %%获取当前怪物所在的场景
  553. get_mon_info(MonId) ->
  554. case mod_scene_mon:lookup(MonId) of
  555. [] -> {0, 0, 0};
  556. D -> {D#ets_scene_mon.scene, D#ets_scene_mon.x, D#ets_scene_mon.y}
  557. end.
  558. %% 指定id任务是否可接
  559. in_active(TaskId) ->
  560. find_query_cache_exits(TaskId).
  561. get_active() ->
  562. get_query_cache_list().
  563. get_active(type, Type) ->
  564. get_query_cache_list_type(Type).
  565. %% 获取已触发任务列表
  566. get_trigger() ->
  567. get_task_bag_id_list().
  568. %% 获取该阶段任务内容
  569. get_phase(RT)->
  570. [[State | T] || [State | T] <- RT#role_task.mark, RT#role_task.state =:= State].
  571. %% 获取任务阶段的未完成内容:改成这个任务没有最终完成的
  572. %% get_phase_unfinish(RT)->
  573. %% [[State, Fin | T] || [State, Fin |T] <- RT#role_task.mark].
  574. get_one_trigger(TaskId) ->
  575. find_task_bag_list(TaskId).
  576. %% 查看是否领取了指定的任务ID:是:true 否:false
  577. is_trigger_task_id(TaskId) ->
  578. case find_task_bag_list(TaskId) of
  579. false -> false;
  580. _ -> true
  581. end.
  582. %% 查看是否领取了指定的任务ID:是:true 否:false
  583. is_during_task(TaskId) ->
  584. case find_task_bag_list(TaskId) of
  585. #role_task{state=S} when S=<0->
  586. true;
  587. _ ->
  588. false
  589. end.
  590. %% 只能在任务进程调用
  591. %% 查看是否完成了指定的任务ID:是:true 否:false
  592. is_finish_task_id(TaskId) ->
  593. case find_task_log_list(TaskId) of
  594. false -> false;
  595. _ -> true
  596. end.
  597. %% 只能在任务进程调用
  598. %% 查看是否完成了多个指定的任务ID:
  599. %% return 已完成的TaskId的Bin形式
  600. %% 是否完成多个任务
  601. %% TaskIds可以是列表形式:[TaskId]
  602. %% TaskIds也可以打包形式(Bin形式):lib_task:pack_task_id([TaskId])
  603. is_finish_task_ids(BinTaskIds) when is_binary(BinTaskIds)->
  604. TaskIds = unpack_task_id(BinTaskIds),
  605. FinishIds = is_finish_task_ids(TaskIds),
  606. pack_task_id(FinishIds);
  607. %% return 已完成的TaskId
  608. is_finish_task_ids(TaskIds) ->
  609. F = fun(TaskId, TmpList)->
  610. case find_task_log_list(TaskId) of
  611. false -> TmpList;
  612. _ -> [TaskId|TmpList]
  613. end
  614. end,
  615. FinishIds = lists:foldl(F, [], TaskIds),
  616. FinishIds.
  617. %% 只能在任务进程调用
  618. %% 是否完成对应章节的所有主线任务
  619. is_finish_chapter_all_task(Chapter) ->
  620. List = data_task:get_ids_by_chapter(Chapter),
  621. F = fun(TaskId) ->
  622. is_finish_task_id(TaskId)
  623. end,
  624. lists:all(F, List).
  625. %% 获取结束任务的npcid
  626. get_end_npc_id(RT) when is_record(RT, role_task)->
  627. get_end_npc_id(RT#role_task.mark);
  628. get_end_npc_id(TaskId) when is_integer(TaskId) ->
  629. case get_one_trigger(TaskId) of
  630. false -> 0;
  631. RT -> get_end_npc_id(RT)
  632. end;
  633. get_end_npc_id([]) -> 0;
  634. get_end_npc_id(Mark) ->
  635. case lists:last(Mark) of
  636. [_, _, ?TASK_CONTENT_END_TALK, NpcId|_] -> lib_role_task:exchange_npc(NpcId);
  637. _ -> 0 %% 这里是异常
  638. end.
  639. %% ================================= 任务触发检查 =================================
  640. %% 检查是否可以触发任务
  641. can_trigger(TaskId, TaskArgs) ->
  642. #figure{lv = PlayerLv, career = PlayerCareer, realm = PlayerRealm,
  643. turn = PlayerTurn, guild_id = PlayerGuilId} = TaskArgs#task_args.figure,
  644. case find_task_bag_exits(TaskId) of
  645. true ->
  646. {false, ?ERRCODE(err300_task_trigger)}; %%已经触发过了
  647. false ->
  648. case data_task_condition:get(TaskId) of
  649. null ->
  650. {false, ?ERRCODE(err300_task_config_null)};
  651. #task_condition{type = TaskType, level = Level, level_max = MaxLevel, realm = Realm,
  652. career = Career, turn = Turn, prev = Prev, repeat = Repeat, condition = Condition} = _TD ->
  653. if
  654. (TaskType ==?TASK_TYPE_DAILY orelse TaskType == ?TASK_TYPE_GUILD) andalso
  655. (PlayerLv > MaxLevel orelse PlayerLv < Level)->
  656. {false, ?ERRCODE(err300_lv_not_enough)}; %% 等级不足
  657. PlayerLv < Level ->
  658. {false, ?ERRCODE(err300_lv_not_enough)}; %% 等级不足
  659. TaskType == ?TASK_TYPE_GUILD andalso PlayerGuilId == 0 -> %% 没有帮派
  660. {false, ?ERRCODE(err300_not_guild)};
  661. Realm /=0 andalso PlayerRealm /= Realm ->
  662. {false, ?ERRCODE(err300_realm_diff)}; %% 阵营不符合
  663. Career /= 0 andalso PlayerCareer /= Career ->
  664. {false, ?ERRCODE(err300_career_diff)}; %% 阵营不符合
  665. Turn /= 0 andalso PlayerTurn < Turn ->
  666. {false, ?ERRCODE(err300_turn_diff)}; %% 转生次数不符合(向下兼容)
  667. TaskType == ?TASK_TYPE_TURN andalso PlayerTurn > Turn andalso PlayerTurn > 0 ->
  668. {false, ?ERRCODE(err300_turn_diff)}; %% 如果是转生任务 但是玩家的转生次数已经超过了任务的转生次数则不能重复触发
  669. true ->
  670. case check_prev_task(Prev) of
  671. false -> {false, ?ERRCODE(err300_prev_not_fin)}; %% 前置任务未完成
  672. true ->
  673. case check_repeat(TaskId, Repeat) of
  674. false -> {false, ?ERRCODE(err300_fin)};
  675. true ->
  676. case length([1||ConditionItem <- Condition, check_condition(ConditionItem, TaskId, TaskArgs)=:=false]) =:= 0 of
  677. true -> true;
  678. false -> {false, ?ERRCODE(err300_condition_err)}
  679. end
  680. end
  681. end
  682. end
  683. end
  684. end.
  685. % %% 获取下一等级的任务
  686. % next_lev_list(PS) ->
  687. % Tids = data_task:get_ids(),
  688. % F = fun(Tid) -> TD = get_data(Tid), (PS#player_status.figure#figure.lv + 1) =:= TD#task.level end,
  689. % [XTid || XTid<-Tids, F(XTid)].
  690. %% 是否重复可以接
  691. check_repeat(TaskId, Repeat) ->
  692. case Repeat =:= 0 of
  693. true -> find_task_log_exits(TaskId) =/= true;
  694. false -> true
  695. end.
  696. %% 前置任务
  697. check_prev_task(PrevId) ->
  698. case PrevId =:= 0 of
  699. true -> true;
  700. false -> find_task_log_exits(PrevId)
  701. end.
  702. %% 任务条件建检查
  703. %% 是否完成任务
  704. check_condition({task, TaskId}, _, _) -> find_task_log_exits(TaskId);
  705. %% 是否完成其中之一的任务
  706. check_condition({task_one, TaskList}, _, _) -> lists:any(fun(Tid)-> find_task_log_exits(Tid) end, TaskList);
  707. %% 今天的任务次数是否过多
  708. check_condition({daily_limit, Num}, TaskId, _) ->
  709. case find_task_log_list(TaskId) of false -> true; RTL -> RTL#role_task_log.count < Num end;
  710. %%验证开服天数
  711. check_condition({open_day,Day},_,_)->
  712. OpDay = util:get_open_day(),
  713. OpDay>=Day;
  714. %% 容错
  715. check_condition(_Other, _, _TaskArgs) -> false.
  716. %% ================================= 触发任务 =================================
  717. %% 自动触发任务
  718. auto_trigger(TaskArgs) ->
  719. ActiveTasks = get_active(), %% 获取可以接的任务
  720. do_auto_trigger(TaskArgs,ActiveTasks).
  721. auto_trigger(Type,TaskArgs)->
  722. ActiveTasks = get_active(type,Type),
  723. do_auto_trigger(TaskArgs,ActiveTasks).
  724. do_auto_trigger(TaskArgs,ActiveTasks)->
  725. F = fun(TD, Bool) ->
  726. case TD#task.start_npc == 0 andalso TD#task.start_talk == 0 of
  727. true -> trigger(TD#task.id, TaskArgs), true;
  728. false -> Bool
  729. end
  730. end,
  731. lists:foldl(F, false, ActiveTasks).
  732. %% 手动触发任务
  733. %% return true | {false, Code}
  734. trigger(TaskId, TaskArgs) ->
  735. %% 注: 给机器人放行逻辑
  736. IsRobot = lib_robot:is_robot(TaskArgs),
  737. CanTrigger = case can_trigger(TaskId, TaskArgs) of
  738. {false, _ErrCode} when IsRobot == true -> true;
  739. {false, ErrCode} -> {false, ErrCode};
  740. true -> true
  741. end,
  742. case CanTrigger of
  743. {false, Res} -> {false, Res};
  744. true ->
  745. TD = get_data(TaskId),
  746. TaskMark = [content_to_mark(E, TaskArgs)||E<-TD#task.content]
  747. ++ case TD#task.end_talk of
  748. 0 -> []; %% end_talk = 0则直接提交任务
  749. _ -> [content_to_mark([TD#task.state, ?TASK_CONTENT_END_TALK, TD#task.end_npc,
  750. TD#task.end_talk, 0, 0, 0, TD#task.finish_pathfind], TaskArgs)]
  751. end,
  752. Now = utime:unixtime(),
  753. add_trigger(TaskArgs#task_args.id, TaskId, Now, 0, TD#task.state,
  754. TaskMark, TD#task.type, TD#task.kind, TaskArgs#task_args.figure#figure.lv),
  755. case handle_finish_before_trigger(TaskId, TaskMark, TaskArgs, []) of
  756. EventList when is_list(EventList) andalso EventList =/= [] ->
  757. lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_SAVE, lib_task_api, cast_handle_refresh_trigger, [EventList]);
  758. _ -> ok
  759. end,
  760. %% 转生任务接取了要通知其他模块
  761. ?IF(TD#task.type =/= ?TASK_TYPE_TURN, skip,
  762. lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_SAVE, transform, trigger_task, [TD#task.id])),
  763. get_my_task_list(TD#task.type, TaskArgs),
  764. refresh_npc_ico(TaskArgs),
  765. lib_task_event:trigger_after(TD, TaskArgs),
  766. %lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_SAVE, ta_agent_fire, task_completed, [Now, [TD#task.id, 1, 0]]),
  767. true
  768. end.
  769. %% 有部分支线任务内容在触发时候判断
  770. %% 增加的对应类型,要同步在lib_task_api:make_action_list()增加类型支持
  771. handle_finish_before_trigger(_TaskId, [], _TaskArgs, EventList) -> EventList;
  772. %%转生任务
  773. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_TURN, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  774. NewEventList = [{TaskId, ?TASK_CONTENT_TURN,Id} | EventList],
  775. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  776. %%好友数量
  777. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ADD_FRIEND, _Id, Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  778. NewEventList = [{TaskId, ?TASK_CONTENT_ADD_FRIEND, Num, NowNum} | EventList],
  779. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  780. %%副本进度
  781. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUN_WAVE, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  782. NewEventList = [{TaskId, ?TASK_CONTENT_DUN_WAVE, Id} | EventList],
  783. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  784. %%某个副本
  785. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUNGEON, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  786. NewEventList = [{TaskId, ?TASK_CONTENT_DUNGEON, Id} | EventList],
  787. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  788. %%副本类型
  789. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUNGEON_TYPE, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  790. NewEventList = [{TaskId, ?TASK_CONTENT_DUNGEON_TYPE, Id} | EventList],
  791. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  792. %%指定BOSS
  793. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_KILL_BOSS, Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  794. NewEventList = [{TaskId, ?TASK_CONTENT_KILL_BOSS, Id} | EventList],
  795. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  796. %%装备进化
  797. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ERISE, _Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  798. NewEventList = [{TaskId, ?TASK_CONTENT_ERISE} | EventList],
  799. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  800. %%装备强化
  801. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_STREN, _Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  802. NewEventList = [{TaskId, ?TASK_CONTENT_STREN} | EventList],
  803. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  804. %%装备附能
  805. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_EMPOWER, _Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  806. NewEventList = [{TaskId, ?TASK_CONTENT_EMPOWER} | EventList],
  807. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  808. %%活跃度
  809. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DAY_ACTIVITY, _Id, _Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  810. NewEventList = [{TaskId, ?TASK_CONTENT_DAY_ACTIVITY} | EventList],
  811. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  812. %%副本类型特定经验
  813. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUNGEON_EXP, Id, Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  814. NewEventList = [{TaskId, ?TASK_CONTENT_DUNGEON_EXP, Id, Num} | EventList],
  815. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  816. %%层级副本类型
  817. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DunId, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  818. NewEventList = [{TaskId, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DunId} | EventList],
  819. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  820. %%动态积分购买
  821. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_SCORE_BUY, Item,_Num, _Scene, ShopId, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  822. NewEventList = [{TaskId, ?TASK_CONTENT_SCORE_BUY, Item, ShopId} | EventList],
  823. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  824. %%好友度
  825. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_FRIEND_EXP, _Id,_Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  826. NewEventList = [{TaskId, ?TASK_CONTENT_FRIEND_EXP, NowNum} | EventList],
  827. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  828. %%竞技场
  829. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ARENA_TIMES, _Id,_Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  830. NewEventList = [{TaskId, ?TASK_CONTENT_ARENA_TIMES} | EventList],
  831. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  832. %%装备套装
  833. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_EQUIP_SUIT, _Id,_Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  834. NewEventList = [{TaskId, ?TASK_CONTENT_EQUIP_SUIT} | EventList],
  835. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  836. %%进阶系统
  837. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_FOSTER_GRADE, Type,_Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  838. NewEventList = [{TaskId, ?TASK_CONTENT_FOSTER_GRADE, Type} | EventList],
  839. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  840. %%预期任务
  841. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_EXPECT_TASK, ExpectTask,_Num, _Scene, _X, _Y, _NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  842. NewEventList = [{TaskId,?TASK_CONTENT_EXPECT_TASK,ExpectTask}| EventList],
  843. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  844. %%宝宝同心值
  845. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_CHILD_HEART, _Id,_Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  846. NewEventList = [{TaskId, ?TASK_CONTENT_CHILD_HEART,NowNum} | EventList],
  847. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  848. %%战力任务
  849. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_COMBAT, _Id,_Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  850. NewEventList = [{TaskId, ?TASK_CONTENT_COMBAT,NowNum} | EventList],
  851. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  852. %%任意主动技能升级次
  853. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ACTIVE_SKILL_LV_TIMES, _Id,_Num, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  854. NewEventList = [{TaskId, ?TASK_CONTENT_ACTIVE_SKILL_LV_TIMES,NowNum} | EventList],
  855. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  856. %%指定商定购买技能书
  857. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_SOME_SHOP_BUY_BOOK, ShopId,NeedNum, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  858. NewEventList = [{TaskId, ?TASK_CONTENT_SOME_SHOP_BUY_BOOK,ShopId,NowNum,NeedNum} | EventList],
  859. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  860. %%任意商定购买技能书
  861. handle_finish_before_trigger(TaskId, [ [_State, 0, ?TASK_CONTENT_ANY_SHOP_BUY_BOOK, _Id,NeedNum, _Scene, _X, _Y, NowNum, _PathFind]|T ], TaskArgs, EventList) ->
  862. NewEventList = [{TaskId, ?TASK_CONTENT_ANY_SHOP_BUY_BOOK,NowNum,NeedNum} | EventList],
  863. handle_finish_before_trigger(TaskId, T, TaskArgs, NewEventList);
  864. handle_finish_before_trigger(TaskId, [_|T], TaskArgs, EventList) -> handle_finish_before_trigger(TaskId, T, TaskArgs, EventList).
  865. %% ================================= 完成任务 =================================
  866. %% 自动完成
  867. auto_finish(TaskArgs) when TaskArgs#role_task.type =/= ?TASK_TYPE_SIDE->
  868. TriggerTasks = get_trigger(),
  869. F = fun(RT, Bool) ->
  870. case RT#role_task.state == RT#role_task.end_state of
  871. true ->
  872. case lists:last(RT#role_task.mark) of
  873. [_, 1, ?TASK_CONTENT_END_TALK|_] -> Bool;
  874. _ ->
  875. case finish(RT#role_task.task_id, [], TaskArgs) of
  876. {false, _} -> Bool;
  877. true -> true;
  878. {ok, _} -> true
  879. end
  880. end;
  881. false -> Bool
  882. end
  883. end,
  884. case lists:foldl(F, false, TriggerTasks) of
  885. false -> true;
  886. true -> auto_trigger(TaskArgs) %% 这里是个递归,可能会继续触发完成
  887. end;
  888. auto_finish(_TaskArgs) ->
  889. true.
  890. %% return true | {false, Code} | {ok, 1}
  891. finish(TaskId, ParamList, TaskArgs) ->
  892. case is_finish(TaskId, TaskArgs) of
  893. false ->
  894. #task{type = Type} = get_data(TaskId),
  895. if
  896. ParamList == cost_finish andalso %% 花费完成
  897. (Type == ?TASK_TYPE_DAILY orelse Type == ?TASK_TYPE_GUILD orelse Type == ?TASK_TYPE_SIDE)->
  898. do_normal_finish(TaskId, ParamList, TaskArgs);
  899. true ->
  900. %% ?ERR("error no finish task id:~p~n", [TaskId]),
  901. {false, ?ERRCODE(err300_task_no_finish)}
  902. end;
  903. true ->
  904. do_normal_finish(TaskId, ParamList, TaskArgs)
  905. end.
  906. do_normal_finish(TaskId, ParamList, TaskArgs) ->
  907. #task_args{id = Id} = TaskArgs,
  908. TD = get_data(TaskId),
  909. RT = get_one_trigger(TaskId),
  910. %% 奖励物品
  911. if
  912. TD#task.type == ?TASK_TYPE_DAILY orelse TD#task.type == ?TASK_TYPE_GUILD ->
  913. Items0 = calc_task_type_reward(TD#task.type, RT#role_task.lv),
  914. BaseItems = get_award_item(TD, TaskArgs),
  915. Items = calc_extra_ratio_type_reward(TD#task.type, BaseItems, TaskArgs)++Items0;
  916. TD#task.type == ?TASK_TYPE_MAIN -> %%计算双倍奖励
  917. BaseItems = get_award_item(TD, TaskArgs),
  918. Items = calc_dobule_reward(BaseItems, ParamList);
  919. true ->
  920. Items = get_award_item(TD, TaskArgs)
  921. end,
  922. LogType = get_log_type(TD#task.type),
  923. Produce=#produce{
  924. type=LogType, subtype = TaskId, title=data_language:get(145),
  925. content=data_language:get(146), reward=Items, show_tips=3,
  926. remark = lists:concat(["task_id:", TaskId])
  927. },
  928. lib_goods_api:send_reward_with_mail(Id, Produce, ?MOD_TASK),
  929. {ok, BinData} = pt_300:write(30004, [TaskId, 1, Items]),
  930. lib_server_send:send_to_sid(TaskArgs#task_args.sid, BinData),
  931. %% 判断特殊类型的任务完成
  932. if
  933. TD#task.type == ?TASK_TYPE_DAILY orelse TD#task.type == ?TASK_TYPE_GUILD ->
  934. finish_task_type(TD#task.type, Id, TaskArgs, RT);
  935. true ->
  936. %% 数据库回写
  937. Time = utime:unixtime(),
  938. add_log(Id, TaskId, TD#task.type, RT#role_task.trigger_time, Time, 0),
  939. %% 刷新任务
  940. refresh_active(TaskArgs),
  941. %% 完成任务事件
  942. TalkId = filter_task_talk(RT#role_task.mark),
  943. lib_task_event:async_finish(Id, TaskId, TalkId),
  944. case auto_trigger(TaskArgs) of
  945. true ->
  946. get_my_task_list(TD#task.type, TaskArgs),
  947. %%主线需要补充更新推送
  948. case TD#task.type =:= ?TASK_TYPE_MAIN of
  949. true->
  950. refresh_npc_ico(TaskArgs);
  951. _->
  952. skip
  953. end,
  954. trigger_next_special_task(TD, RT),
  955. true;
  956. _ ->
  957. get_my_task_list(TD#task.type, TaskArgs),
  958. refresh_npc_ico(TaskArgs),
  959. %% check some special task
  960. trigger_next_special_task(TD, RT),
  961. true
  962. end
  963. end.
  964. get_log_type(?TASK_TYPE_DAILY) -> finish_daily_task;
  965. get_log_type(?TASK_TYPE_GUILD) -> finish_guild_task;
  966. get_log_type(_) -> task.
  967. trigger_next_special_task(TD, RT)->
  968. #task{type = Type, kind = Kind, next = NextTaskId} = TD,
  969. case Type == ?TASK_TYPE_SIDE andalso NextTaskId > 0 of
  970. false -> skip;
  971. true ->
  972. #role_task{mark = Mark} = RT,
  973. if
  974. Kind == ?TASK_KIND_STREN ->
  975. lib_player:apply_cast(RT#role_task.role_id, ?APPLY_CAST_STATUS, lib_task_api, auto_stren_equip, []);
  976. Kind == ?TASK_KIND_RUNE_DUN ->
  977. case get_mark_content_type_num(Mark, ?TASK_CONTENT_DUNGEON_RUNE) of
  978. {DunType, DunId} ->
  979. lib_player:apply_cast(RT#role_task.role_id, ?APPLY_CAST_STATUS, lib_task_api, fin_level_dun, [DunType, DunId]);
  980. _ -> skip
  981. end;
  982. Kind == ?TASK_KIND_EXP_DUN ->
  983. case get_mark_content_type_num(Mark, ?TASK_CONTENT_DUNGEON_EXP) of
  984. [] -> skip;
  985. {DunType, Exp} -> lib_player:apply_cast(RT#role_task.role_id, ?APPLY_CAST_STATUS, lib_task_api, fin_dun_exp, [DunType, Exp])
  986. end;
  987. true ->
  988. skip
  989. end
  990. end.
  991. get_mark_content_type_num([[_, _, ?TASK_CONTENT_DUNGEON_RUNE, DunType, _, _, _, _, RuneDunId, _]|_Mark], ?TASK_CONTENT_DUNGEON_RUNE)-> {DunType, RuneDunId};
  992. get_mark_content_type_num([[_, _, ?TASK_CONTENT_DUNGEON_EXP, DunType, _, _, _, _, NowExpNum, _]|_Mark], ?TASK_CONTENT_DUNGEON_EXP) -> {DunType, NowExpNum};
  993. get_mark_content_type_num([_H|Mark], ContentType) -> get_mark_content_type_num(Mark, ContentType);
  994. get_mark_content_type_num([], _ContentType)-> [].
  995. %% 完成悬赏和公会周任务
  996. finish_task_type(TaskType, RoleId, TaskArgs, RT)->
  997. case data_task_lv_dynamic:get_task_type(TaskType) of
  998. #task_type{count = Count, module_id = ModuleId, counter_id = CounterId} ->
  999. % mod_guild:add_growth(RoleId, Figure#figure.guild_id, 1, finish_guild_task, {task_type, TaskType}),
  1000. FinishCount = lib_daily:get_count(RoleId, ModuleId, CounterId)+1,
  1001. ProduceType = ?IF(TaskType == ?TASK_TYPE_GUILD, finish_guild_task, finish_daily_task),
  1002. lib_daily:increment(RoleId, ModuleId, CounterId),
  1003. %% 数据库回写
  1004. Time = utime:unixtime(),
  1005. LogType = ?IF(lists:member(TaskArgs#task_args.figure#figure.lv, ?DAILY_SPECIAL_LV) andalso TaskType == ?TASK_TYPE_DAILY, 1, TaskType),
  1006. add_log(TaskArgs#task_args.id, RT#role_task.task_id, LogType, RT#role_task.trigger_time, Time, FinishCount),
  1007. %% 完成任务事件
  1008. lib_task_event:async_finish(TaskArgs#task_args.id, RT#role_task.task_id,0),
  1009. case calc_extra_task_type_reward(RT#role_task.task_id, TaskType, FinishCount, RT#role_task.lv) of
  1010. [] -> skip;
  1011. Reward ->
  1012. Produce=#produce{
  1013. type=ProduceType, subtype = RT#role_task.task_id, title=data_language:get(145),
  1014. content=data_language:get(146), reward=Reward, show_tips=3,
  1015. remark = lists:concat(["task_id:", RT#role_task.task_id])
  1016. },
  1017. lib_goods_api:send_reward_with_mail(TaskArgs#task_args.id, Produce, ?MOD_TASK)
  1018. % lib_goods_api:send_reward_by_id(Reward, ProduceType, RT#role_task.task_id, TaskArgs#task_args.id)
  1019. end,
  1020. TaskType == ?TASK_TYPE_GUILD andalso guild_run_assist:check_run_assist_trigger(TaskArgs#task_args.id),
  1021. if
  1022. FinishCount >= Count ->
  1023. %% ?ERR("finish task type:~p~n FinishCount:~p~n", [TaskType, FinishCount]),
  1024. get_my_task_list(TaskType, TaskArgs),
  1025. refresh_npc_ico(TaskArgs),
  1026. if
  1027. TaskType == ?TASK_TYPE_DAILY -> {ok, ?ERRCODE(err300_daily_task_finished)};
  1028. true -> {ok, ?ERRCODE(err300_guild_task_finished)}
  1029. end;
  1030. true ->
  1031. lib_player:apply_cast(RoleId, ?APPLY_CAST_STATUS, ?MODULE, finish_task_type_after, [TaskType]),
  1032. {ok, ?SUCCESS}
  1033. % trigger_type_task(TaskType, TaskArgs)
  1034. end;
  1035. _R ->
  1036. ?ERR("error task type:~p~n _R:~p~n", [TaskType, _R]),
  1037. {false, ?FAIL}
  1038. end.
  1039. finish_task_type_after(PS, ?TASK_TYPE_DAILY) ->
  1040. TaskArgs = lib_task_api:ps2task_args(PS),
  1041. case get_task_bag_id_list_type(?TASK_TYPE_DAILY) of
  1042. [] ->
  1043. {_, Code} = trigger_type_task(?TASK_TYPE_DAILY, TaskArgs),
  1044. {ok, Bin} = pt_300:write(30009, [Code]),
  1045. lib_server_send:send_to_uid(TaskArgs#task_args.id, Bin),
  1046. PS;
  1047. _->
  1048. PS
  1049. end;
  1050. finish_task_type_after(PS, TaskType) ->
  1051. TaskArgs = lib_task_api:ps2task_args(PS),
  1052. {_, Code} = trigger_type_task(TaskType, TaskArgs),
  1053. {ok, Bin} = pt_300:write(30009, [Code]),
  1054. lib_server_send:send_to_uid(TaskArgs#task_args.id, Bin),
  1055. PS.
  1056. %% 检查扣除物品
  1057. %% check_task_cost_goods(TD, RT, ParamList, TaskArgs) ->
  1058. %% #task_args{id = Id, gs_dict = GsDict} = TaskArgs,
  1059. %% %% 删除回收物品
  1060. %% if
  1061. %% TD#task.end_item == [] -> ok;
  1062. %% ParamList == cost_finish -> ok; %% 特殊任务消耗直接完成不需要扣除物品
  1063. %% true ->
  1064. %% case get_task_cost_goods(TD, RT) of
  1065. %% [] -> ok;
  1066. %% [{GoodsId, Num}|_] ->
  1067. %% case data_goods_type:get(GoodsId) of
  1068. %% #ets_goods_type{bag_location = BagLocation} ->
  1069. %% GoodsList = lib_goods_util:get_type_goods_list(Id, GoodsId, BagLocation, GsDict),
  1070. %% TotalNum = lib_goods_util:get_goods_totalnum(GoodsList),
  1071. %% if
  1072. %% TotalNum >= Num ->
  1073. %% lib_player:apply_cast(Id, ?APPLY_CAST_STATUS, lib_goods_api, goods_delete_type_list, [[{GoodsId, Num}], finish_task]),
  1074. %% ok;
  1075. %% true ->
  1076. %% {false, ?ERRCODE(goods_not_enough)}
  1077. %% end;
  1078. %% _ ->
  1079. %% {false, ?ERRCODE(err150_no_goods)}
  1080. %% end
  1081. %% end
  1082. %% end.
  1083. %% 根据任务内容去扣除物品
  1084. %% get_task_cost_goods(TD, RT) ->
  1085. %% if
  1086. %% TD#task.type == ?TASK_TYPE_DAILY orelse TD#task.type == ?TASK_TYPE_GUILD ->
  1087. %% #role_task{mark = Mark, kind = _Kind} = RT,
  1088. %% case lists:keyfind(?TASK_CONTENT_ITEM, 3, Mark) of
  1089. %% false -> [];
  1090. %% {_State, _, _CType, Id, Num, _SceneId, _X, _Y, _Num, _FindPath} ->
  1091. %% [{Id, Num}]
  1092. %% end;
  1093. %% true ->
  1094. %% TD#task.end_item
  1095. %% end.
  1096. %% 经验双倍奖励
  1097. calc_dobule_reward(BaseItems, [{double_type, _}|_T]) ->
  1098. lists:foldl(
  1099. fun ({?TYPE_EXP, GoodsId, Num}, AccList) -> %%经验双倍奖励
  1100. [{?TYPE_EXP, GoodsId, Num * 2} | AccList];
  1101. ({_TypeId, _GoodsId, _Num} = Info, AccList) ->
  1102. [Info| AccList];
  1103. (_, AccList) -> AccList
  1104. end,
  1105. [],
  1106. BaseItems
  1107. );
  1108. calc_dobule_reward(BaseItems, _ParamList) -> BaseItems.
  1109. %% 赏金任务
  1110. calc_task_type_reward(?TASK_TYPE_DAILY, Lv)->
  1111. ExpValue0 = data_exp_base:get(Lv),
  1112. LvExtra = data_award_exp:get_exp_extra(?MOD_TASK,1,Lv),
  1113. [{?TYPE_EXP, ?GOODS_ID_EXP, round(ExpValue0*LvExtra/10000)}];
  1114. %% 公会周任务
  1115. calc_task_type_reward(?TASK_TYPE_GUILD, Lv) ->
  1116. ExpValue0 = data_exp_base:get(Lv),
  1117. LvExtra = data_award_exp:get_exp_extra(?MOD_TASK,2,Lv),
  1118. [{?TYPE_EXP, ?GOODS_ID_EXP, round(ExpValue0*LvExtra/10000)}];
  1119. calc_task_type_reward(_, _) -> [].
  1120. %% 计算赏金和公会周任务额外奖励
  1121. calc_extra_task_type_reward(TaskId, _TaskType, FinishCount, Lv) ->
  1122. case FinishCount rem 5 of %% 每十次一个
  1123. 0 when FinishCount /= 0->
  1124. case data_task_lv_dynamic:get_type_task_dynamic(TaskId, Lv) of
  1125. #task_lv_dynamic_content{extra_reward = ExtraReward} ->
  1126. case lists:keyfind(FinishCount, 1, ExtraReward) of
  1127. {_, Rewards} when is_list(Rewards)-> Rewards;
  1128. _ -> []
  1129. end;
  1130. _ -> []
  1131. end;
  1132. _ -> []
  1133. end.
  1134. %% 计算公会任务的加成奖励
  1135. calc_extra_ratio_type_reward(?TASK_TYPE_GUILD, Items, _TaskArgs) ->
  1136. Rewards = lib_goods_api:make_reward_unique(Items),
  1137. Rewards;
  1138. calc_extra_ratio_type_reward(?TASK_TYPE_DAILY, Items, TaskArgs) ->
  1139. Rewards = lib_goods_api:make_reward_unique(Items),
  1140. #task_args{figure = #figure{vip_type = _VipType, vip = _VipLv}} = TaskArgs,
  1141. % VipRatio = lib_vip:get_vip_privilege(VipType, VipLv, ?MOD_TASK, 3),
  1142. VipRatio = 0,
  1143. Fun = fun
  1144. ({?TYPE_EXP, GoodTypeId, Num})->
  1145. {?TYPE_EXP, GoodTypeId, trunc(Num * (10000 + VipRatio) / 10000 )};
  1146. (Element) -> Element
  1147. end,
  1148. [Fun(Item) || Item <- Rewards];
  1149. calc_extra_ratio_type_reward(_, Items, _) -> Items.
  1150. %% 放弃任务
  1151. abnegate(TaskId, TaskArgs) ->
  1152. case get_one_trigger(TaskId) of
  1153. false -> Code = 0;
  1154. _RT ->
  1155. %% 删除缓存
  1156. delete_task_bag_list(TaskId),
  1157. %% 删除数据库
  1158. del_trigger_from_sql(TaskArgs#task_args.id, TaskId),
  1159. %% 刷新
  1160. refresh_active(TaskArgs),
  1161. refresh_npc_ico(TaskArgs),
  1162. Code = 1
  1163. end,
  1164. {ok, BinData} = pt_300:write(30005, [Code]),
  1165. lib_server_send:send_to_sid(TaskArgs#task_args.sid, BinData).
  1166. %% 有部分任务内容在触发的时候可能就完成了
  1167. %% preact_finish(Rid) ->
  1168. %% lists:member(true, [preact_finish(RT, Rid) || RT <- get_task_bag_id_list()]).
  1169. %% preact_finish(TaskId, Rid) when is_integer(TaskId) ->
  1170. %% RT = get_one_trigger(TaskId),
  1171. %% case RT of
  1172. %% false -> skip;
  1173. %% _ -> preact_finish(RT, Rid)
  1174. %% end;
  1175. %% preact_finish(RT, Rid) ->
  1176. %% lists:member(true, [preact_finish_check([State, Fin | T], Rid) || [State, Fin | T] <- RT#role_task.mark, State =:= RT#role_task.state, Fin =:= 0]).
  1177. %% %% 装备武器
  1178. %% preact_finish_check([_, 0, equip, _ItemId | _], PS) when is_record(PS, player_status)->
  1179. %% false;
  1180. %% %% 加入帮派
  1181. %% preact_finish_check([_, 0, join_guild | _], PS) when is_record(PS, player_status)->
  1182. %% false;
  1183. %% %% 购买武器
  1184. %% preact_finish_check([_, 0, buy_equip, _ItemId | _], _PS) when is_record(_PS, player_status)->
  1185. %% skip;
  1186. %% %% 学习技能
  1187. %% preact_finish_check([_, 0, learn_skill, _SkillId | _], PS) when is_record(PS, player_status)->
  1188. %% false;
  1189. %% %% 收集物品
  1190. %% preact_finish_check([_, 0, item, ItemId, _, NowNum | _], PS) when is_record(PS, player_status) ->
  1191. %% Dict = lib_goods_dict:get_player_dict(PS),
  1192. %% Num = lib_goods_util:get_task_goods_num(PS#player_status.id, ItemId, Dict),
  1193. %% case Num > NowNum of
  1194. %% false -> false;
  1195. %% true -> action(PS#player_status.id, item, [[{ItemId, Num}]])
  1196. %% end;
  1197. %% preact_finish_check(_, _) ->
  1198. %% false.
  1199. %% 检测任务是否完成
  1200. is_finish(TaskId, TaskArgs) when is_integer(TaskId) ->
  1201. case get_one_trigger(TaskId) of
  1202. false -> false;
  1203. RT ->
  1204. IsFinish = is_finish(RT, TaskArgs),
  1205. % ?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)}]),
  1206. %% 注: 给机器人放行逻辑
  1207. case {IsFinish, lib_robot:is_robot(TaskArgs)} of
  1208. {false, true} -> true;
  1209. _ -> IsFinish
  1210. end
  1211. end;
  1212. is_finish(RT, TaskArgs) when is_record(RT, role_task) ->
  1213. is_finish_mark(RT#role_task.mark, TaskArgs);
  1214. is_finish(Mark, TaskArgs) when is_list(Mark) ->
  1215. is_finish_mark(Mark, TaskArgs).
  1216. is_finish_mark([], _) -> true;
  1217. is_finish_mark([[_, 1|_] | T], TaskArgs) -> is_finish_mark(T, TaskArgs);
  1218. is_finish_mark([MK|_T], _TaskArgs) when is_list(MK) -> false;
  1219. is_finish_mark([MK|_T], _TaskArgs) -> ?ERR("error task mark:~p~n", [MK]), false.
  1220. %% ================================= 任务进度更新 =================================
  1221. %% 批量刷新任务过程
  1222. action_more(EventList) ->
  1223. [action(TaskId, Rid, Event, ParamList) || {TaskId, Event, ParamList, Rid} <- EventList].
  1224. %% 已接所有任务更新判断
  1225. action(Rid, Event, ParamList) ->
  1226. case get_task_bag_id_list() of
  1227. [] -> false;
  1228. RTL ->
  1229. Result = [action_one(RT, Rid, Event, ParamList)|| RT<- RTL],
  1230. lists:member(true, Result)
  1231. end.
  1232. %% 单个任务更新判断
  1233. action(TaskId, Rid, Event, ParamList)->
  1234. case get_one_trigger(TaskId) of
  1235. false -> false;
  1236. RT -> action_one(RT, Rid, Event, ParamList)
  1237. end.
  1238. %% 触发任务
  1239. %% 如果是减少:
  1240. %% 判断:阶段:后退,保持,前进;
  1241. %% 变成没有完成状态
  1242. action_one(RT, Rid, Event, ParamList) ->
  1243. NowTime = utime:unixtime(),
  1244. #role_task{task_id = TaskId, type = TaskType, trigger_time = TriggerTime} = RT,
  1245. if
  1246. TaskType == ?TASK_TYPE_CHAPTER ->
  1247. LimitTime = ?IF(TaskId == 101 orelse TaskId == 102, ?LIMIT_TIME1, ?LIMIT_TIME2);
  1248. true -> LimitTime = 0
  1249. end,
  1250. if
  1251. TaskType == ?TASK_TYPE_CHAPTER andalso NowTime > TriggerTime + LimitTime -> %% 限时章节任务,大于限时后不做触发
  1252. false;
  1253. true ->
  1254. F = fun(MarkItem, Update) ->
  1255. {NewMarkItem, NewUpdate} = content(MarkItem, RT#role_task.state, Event, ParamList),
  1256. case NewUpdate of
  1257. true -> {NewMarkItem, true};
  1258. false -> {NewMarkItem, Update}
  1259. end
  1260. end,
  1261. {NewMark, UpdateAble} = lists:mapfoldl(F, false, RT#role_task.mark),
  1262. case UpdateAble of
  1263. false ->
  1264. false;
  1265. true ->
  1266. NoFinishState = [EachState || [EachState, 0|_ ] <- NewMark],
  1267. if
  1268. NoFinishState == [] -> NewState = RT#role_task.end_state;
  1269. true -> NewState = lists:min(NoFinishState)
  1270. end,
  1271. %% 更新任务记录和任务状态
  1272. %% 更新数据,但是不更新步骤状态,先缓存,下线的时候再记录数据库
  1273. NewRT = if
  1274. RT#role_task.type == ?TASK_TYPE_TURN -> %% 转生任务比较难,默认保存数据
  1275. upd_trigger(RT#role_task.role_id, RT#role_task.task_id, NewState, NewMark),
  1276. RT#role_task{write_db = 0, state = NewState, mark = NewMark};
  1277. RT#role_task.state == NewState ->
  1278. RT#role_task{write_db = 1, mark = NewMark};
  1279. true ->
  1280. upd_trigger(RT#role_task.role_id, RT#role_task.task_id, NewState, NewMark),
  1281. RT#role_task{write_db = 0, state = NewState, mark = NewMark}
  1282. end,
  1283. put_task_bag_list(NewRT),
  1284. ?IF(NewState == RT#role_task.state, ok, refresh_npc_ico(Rid)),
  1285. % TEST
  1286. % Ticket = config:get_ticket(),
  1287. % case Ticket =:= ?INTERNAL_TICKET of
  1288. % true -> auto_finish_task(Rid, RT#role_task.task_id);
  1289. % false ->skip
  1290. % end,
  1291. case NewState == RT#role_task.end_state of
  1292. true ->
  1293. case lists:last(NewMark) of
  1294. [_, 1, ?TASK_CONTENT_END_TALK|_] ->
  1295. notify_client_new_mark(RT#role_task.task_id, Rid, NewState, NewMark);
  1296. _R when TaskType =:= ?TASK_TYPE_NUCLEON ->
  1297. notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark);
  1298. _R when TaskType =:= ?TASK_TYPE_FOUR ->
  1299. notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark);
  1300. _R when TaskType =:= ?TASK_TYPE_DAILY ->
  1301. notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark);
  1302. _R when TaskType =:= ?TASK_TYPE_GUILD ->
  1303. notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark);
  1304. _R when TaskType =/= ?TASK_TYPE_SIDE ->
  1305. auto_finish_task(Rid, RT#role_task.task_id);
  1306. _R ->
  1307. notify_client_new_state_mark(RT#role_task.task_id, Rid, NewState, NewMark)
  1308. end,
  1309. %lib_player:apply_cast(RT#role_task.role_id, ?APPLY_CAST_STATUS, ta_agent_fire, task_completed,
  1310. % [NowTime, [RT#role_task.task_id, 2, NowTime - TriggerTime]]),
  1311. true;
  1312. _ ->
  1313. notify_client_new_mark(RT#role_task.task_id, Rid, NewState, NewMark),
  1314. true
  1315. end
  1316. end
  1317. end.
  1318. %% 通知客户端刷新任务栏
  1319. notify_client_new_mark(TaskId, Rid, NowState, Mark) ->
  1320. {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(Mark),
  1321. F = fun([EState|_]) -> EState == NowState end,
  1322. {ok, BinData} = pt_300:write(30001, [TaskId, lists:filter(F, Mark), WitchState, NeedNum, NowNum]),
  1323. lib_server_send:send_to_uid(Rid, BinData).
  1324. %% 通知客户端刷新任务已完成状态
  1325. notify_client_new_state_mark(TaskId, Rid, _NowState, Mark) ->
  1326. {WitchState, NeedNum, NowNum} = get_mon_or_goods_nums(Mark),
  1327. F = fun([_, EState|_T]) -> EState >0 end,
  1328. {ok, BinData} = pt_300:write(30001, [TaskId, lists:filter(F, Mark), WitchState, NeedNum, NowNum]),
  1329. lib_server_send:send_to_uid(Rid, BinData).
  1330. get_mon_or_goods_nums([]) -> {0, 0, 0};
  1331. get_mon_or_goods_nums([H|Mark])->
  1332. case H of
  1333. [State, _, ContentType, Id, NeedNum, _, _, _, NowNum, _] when
  1334. ContentType == ?TASK_CONTENT_KILL;
  1335. ContentType == ?TASK_CONTENT_DUNGEON;
  1336. ContentType == ?TASK_CONTENT_ITEM;
  1337. ContentType == ?TASK_CONTENT_COLLECT;
  1338. ContentType == ?TASK_CONTENT_GOODS_COMPOSE;
  1339. ContentType == ?TASK_CONTENT_DAY_ACTIVITY;
  1340. ContentType == ?TASK_CONTENT_STREN;
  1341. ContentType == ?TASK_CONTENT_ARENA_TIMES;
  1342. ContentType == ?TASK_CONTENT_COMBAT ->
  1343. if
  1344. ContentType == ?TASK_CONTENT_STREN ->
  1345. {State, Id, NowNum};
  1346. NeedNum == 0 andalso NowNum == 0 ->
  1347. get_mon_or_goods_nums(Mark);
  1348. true ->
  1349. {State, NeedNum, NowNum}
  1350. end;
  1351. _ ->
  1352. get_mon_or_goods_nums(Mark)
  1353. end.
  1354. %% 自动完成任务
  1355. auto_finish_task(Player, TaskId) when is_record(Player, player_status) ->
  1356. TaskArgs = lib_task_api:ps2task_args(Player),
  1357. %% CellNum = lib_goods_api:get_cell_num(Player),
  1358. lib_role_task:finish(TaskId, [], TaskArgs),
  1359. ok;
  1360. auto_finish_task(PlayerId, TaskId) ->
  1361. case misc:get_player_process(PlayerId) of
  1362. Pid when is_pid(Pid) -> lib_player:apply_cast(Pid, ?APPLY_CAST_STATUS, ?NOT_HAND_OFFLINE, lib_task, auto_finish_task, [TaskId]);
  1363. _ -> skip
  1364. end.
  1365. %% 检查物品是否为任务需要 返回所需要的物品ID列表
  1366. can_gain_item() ->
  1367. case get_task_bag_id_list() of
  1368. [] -> [];
  1369. RTL ->
  1370. F = fun(RT) ->
  1371. %% MarkList = get_phase_unfinish(RT),
  1372. [Id || [_, _, ?TASK_CONTENT_ITEM, Id, Num, _SceneId, _X, _Y, NowNum | _T] <- RT#role_task.mark, NowNum =< Num]
  1373. end,
  1374. List = lists:flatmap(F, RTL),
  1375. List
  1376. end.
  1377. %% after_event(Rid) ->
  1378. %% %% TODO 后续事件提前完成检测
  1379. %% case preact_finish(Rid) of
  1380. %% true -> ok;
  1381. %% false ->
  1382. %% %% TODO 通知角色数据更新
  1383. %% refresh_npc_ico(Rid),
  1384. %% {ok, BinData} = pt_300:write(30006, []),
  1385. %% lib_server_send:send_to_uid(Rid, BinData)
  1386. %% end.
  1387. %% 兼容可以从完成状态变成没有完成状态
  1388. %% 到达某个位置
  1389. content([State, 0, ?TASK_CONTENT_ENTER_SCENE, Id, Num, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_ENTER_SCENE, {PlayerScene, PlayerX, PlayerY}) ->
  1390. case Scene == PlayerScene andalso abs(X - PlayerX) < 300 andalso abs(Y - PlayerY) < 300 of
  1391. true -> {[State, 1, ?TASK_CONTENT_ENTER_SCENE, Id, Num, Scene, X, Y, NowNum, PathFind], true};
  1392. false -> {[State, 0, ?TASK_CONTENT_ENTER_SCENE, Id, Num, Scene, X, Y, NowNum, PathFind], false}
  1393. end;
  1394. %% 装备套装中id是 X代, NeedNum是Y件, EqStrenList = [{代,品质,件数}]
  1395. content([State, 0, ?TASK_CONTENT_EQUIP_SUIT, Series, NeedNum, Color, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_EQUIP_SUIT, {id_num_list, SCNList}) ->
  1396. case check_equip_suit_con(SCNList, Series, Color, NeedNum, 0) of
  1397. {false, NowNum} ->
  1398. {[State, 0, ?TASK_CONTENT_EQUIP_SUIT, Series, NeedNum, Color, X, Y, NowNum, PathFind], false};
  1399. {false, Count} ->
  1400. {[State, 0, ?TASK_CONTENT_EQUIP_SUIT, Series, NeedNum, Color, X, Y, Count, PathFind], true};
  1401. {true, Count}->
  1402. {[State, 1, ?TASK_CONTENT_EQUIP_SUIT, Series, NeedNum, Color, X, Y, Count, PathFind], true}
  1403. end;
  1404. %% 装备强化中id是x级, NeedNum是y件, EqStrenList = [{lv, 件数}]
  1405. content([State, 0, ?TASK_CONTENT_STREN, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_STREN, {id_num_list, EqStrenList}) ->
  1406. case check_equip_num_con(EqStrenList, Id, NeedNum, 0) of
  1407. {false, NowNum} ->
  1408. {[State, 0, ?TASK_CONTENT_STREN, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false};
  1409. {false, Count} ->
  1410. {[State, 0, ?TASK_CONTENT_STREN, Id, NeedNum, Scene, X, Y, Count, PathFind], true};
  1411. {true, Count}->
  1412. {[State, 1, ?TASK_CONTENT_STREN, Id, NeedNum, Scene, X, Y, Count, PathFind], true}
  1413. end;
  1414. %% 装备强化中id是x级, NeedNum是y件, EqStrenList = [{lv, 件数}]
  1415. content([State, 0, ?TASK_CONTENT_EMPOWER, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_EMPOWER, {id_num_list, EqStrenList}) ->
  1416. case check_equip_num_con(EqStrenList, Id, NeedNum, 0) of
  1417. {false, NowNum} ->
  1418. {[State, 0, ?TASK_CONTENT_EMPOWER, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false};
  1419. {false, Count} ->
  1420. {[State, 0, ?TASK_CONTENT_EMPOWER, Id, NeedNum, Scene, X, Y, Count, PathFind], true};
  1421. {true, Count}->
  1422. {[State, 1, ?TASK_CONTENT_EMPOWER, Id, NeedNum, Scene, X, Y, Count, PathFind], true}
  1423. end;
  1424. %% 单次发条密室副本中获得xxx经验
  1425. content([State, 0, ?TASK_CONTENT_DUNGEON_EXP, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_DUNGEON_EXP, {num, Id, Num}) ->
  1426. %% 密室副本id是副本类型, num是所需要的经验
  1427. case Num >= NeedNum of
  1428. true -> {[State, 1, ?TASK_CONTENT_DUNGEON_EXP, Id, NeedNum, Scene, X, Y, Num, PathFind], true};
  1429. _ -> {[State, 0, ?TASK_CONTENT_DUNGEON_EXP, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false}
  1430. end;
  1431. content([State,0,?TASK_CONTENT_DUN_WAVE,Id,NeedNum,Scene,X,Y,NowNum, PathFind],State,?TASK_CONTENT_DUN_WAVE,{num, Id, Num})->
  1432. %%Num是波数
  1433. case Num >= NeedNum of
  1434. true -> {[State, 1, ?TASK_CONTENT_DUN_WAVE, Id, NeedNum, Scene, X, Y, Num, PathFind], true};
  1435. _ -> {[State, 0, ?TASK_CONTENT_DUN_WAVE, Id, NeedNum, Scene, X, Y, max(NowNum,Num), PathFind], true}
  1436. end;
  1437. %% 符文之塔的触发
  1438. content([State, _Finish, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DId, Scene, X, Y, Id, PathFind], _State, ?TASK_CONTENT_DUNGEON_RUNE, {id, DunType, DunId}) ->
  1439. case DunId >= DId of
  1440. true ->
  1441. if
  1442. _Finish == 1 ->
  1443. {[State, 1, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DId, Scene, X, Y, DunId, PathFind], false};
  1444. true ->
  1445. {[State, 1, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DId, Scene, X, Y, DunId, PathFind], true}
  1446. end;
  1447. _ ->
  1448. {[State, 0, ?TASK_CONTENT_DUNGEON_RUNE, DunType, DId, Scene, X, Y, Id, PathFind], false}
  1449. end;
  1450. %% 符文之塔的触发
  1451. %% content([ContentState, 1, ?TASK_CONTENT_DUNGEON_RUNE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], _FState, ?TASK_CONTENT_DUNGEON_RUNE, {id, DunId}) ->
  1452. %% case DunId >= Id of
  1453. %% true -> {[ContentState, 1, ?TASK_CONTENT_DUNGEON_RUNE, Id, NeedNum, Scene, X, Y, DunId, PathFind], false};
  1454. %% _ -> {[ContentState, 1, ?TASK_CONTENT_DUNGEON_RUNE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false}
  1455. %% end;
  1456. %% 公会回收装备(提交x阶y品质及以上品质装备完成任务(id=x阶,NeedNum = y品质)
  1457. content([State, 0, ?TASK_CONTENT_GUILD_EQ_RECYCLE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_GUILD_EQ_RECYCLE, {num, Stage, Color}) ->
  1458. case Stage >= Id andalso Color >= NeedNum of
  1459. true -> {[State, 1, ?TASK_CONTENT_GUILD_EQ_RECYCLE, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1460. _ -> {[State, 0, ?TASK_CONTENT_GUILD_EQ_RECYCLE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false}
  1461. end;
  1462. %% 吞噬装备(吞噬x阶y品质及以上品质装备完成任务(id=x阶,NeedNum = y品质)
  1463. content([State, 0, ?TASK_CONTENT_DEVOUR, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_DEVOUR, {num, Stage, Color}) ->
  1464. case Stage >= Id andalso Color >= NeedNum of
  1465. true -> {[State, 1, ?TASK_CONTENT_DEVOUR, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1466. _ -> {[State, 0, ?TASK_CONTENT_DEVOUR, Id, NeedNum, Scene, X, Y, NowNum, PathFind], false}
  1467. end;
  1468. %% 装备进化
  1469. content([State, 0, ?TASK_CONTENT_ERISE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_ERISE, {num, Num}) ->
  1470. if
  1471. Num >= NeedNum ->
  1472. {[State, 1, ?TASK_CONTENT_ERISE, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1473. Num > NowNum ->
  1474. {[State, 0, ?TASK_CONTENT_ERISE, Id, NeedNum, Scene, X, Y, Num, PathFind], true};
  1475. true ->
  1476. {[State, 0, ?TASK_CONTENT_ERISE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true}
  1477. end;
  1478. %% 竞技场
  1479. content([State, 0, ?TASK_CONTENT_ARENA_TIMES, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_ARENA_TIMES, {num, Num}) ->
  1480. if
  1481. Num >= NeedNum ->
  1482. {[State, 1, ?TASK_CONTENT_ARENA_TIMES, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1483. true->
  1484. {[State, 0, ?TASK_CONTENT_ARENA_TIMES, Id, NeedNum, Scene, X, Y, Num, PathFind], true}
  1485. end;
  1486. %% 战魂升级
  1487. content([State, 0, ?TASK_CONTENT_WAR_SOUL_LV, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_WAR_SOUL_LV, {num, Num}) ->
  1488. if
  1489. Num >= NeedNum ->
  1490. {[State, 1, ?TASK_CONTENT_WAR_SOUL_LV, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1491. Num > NowNum ->
  1492. {[State, 0, ?TASK_CONTENT_WAR_SOUL_LV, Id, NeedNum, Scene, X, Y, Num, PathFind], true};
  1493. true ->
  1494. {[State, 0, ?TASK_CONTENT_WAR_SOUL_LV, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true}
  1495. end;
  1496. %% 羁绊缔结就行
  1497. content([State, 0, ?TASK_CONTENT_MATE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_MATE, {num, Num}) ->
  1498. if
  1499. Num >= NeedNum ->
  1500. {[State, 1, ?TASK_CONTENT_MATE, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1501. Num > NowNum ->
  1502. {[State, 0, ?TASK_CONTENT_MATE, Id, NeedNum, Scene, X, Y, Num, PathFind], true};
  1503. true ->
  1504. {[State, 0, ?TASK_CONTENT_MATE, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true}
  1505. end;
  1506. %% 完成次数就行
  1507. content([State, 0, ?TASK_CONTENT_DAY_ACTIVITY, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_DAY_ACTIVITY, {num, Num}) ->
  1508. if
  1509. Num >= NeedNum ->
  1510. {[State, 1, ?TASK_CONTENT_DAY_ACTIVITY, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1511. true->
  1512. {[State, 0, ?TASK_CONTENT_DAY_ACTIVITY, Id, NeedNum, Scene, X, Y, Num, PathFind], true}
  1513. end;
  1514. %% 完成亲密度就行
  1515. content([State, 0, ?TASK_CONTENT_FRIEND_EXP, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_FRIEND_EXP, {num, Num}) ->
  1516. if
  1517. Num >= NeedNum ->
  1518. {[State, 1, ?TASK_CONTENT_FRIEND_EXP, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1519. Num > NowNum ->
  1520. {[State, 0, ?TASK_CONTENT_FRIEND_EXP, Id, NeedNum, Scene, X, Y, Num, PathFind], true};
  1521. true ->
  1522. {[State, 0, ?TASK_CONTENT_FRIEND_EXP, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true}
  1523. end;
  1524. %% 完成同心值就行
  1525. content([State, 0, ?TASK_CONTENT_CHILD_HEART, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_CHILD_HEART, {num, Num}) ->
  1526. if
  1527. Num >= NeedNum ->
  1528. {[State, 1, ?TASK_CONTENT_CHILD_HEART, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1529. Num > NowNum ->
  1530. {[State, 0, ?TASK_CONTENT_CHILD_HEART, Id, NeedNum, Scene, X, Y, Num, PathFind], true};
  1531. true ->
  1532. {[State, 0, ?TASK_CONTENT_CHILD_HEART, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true}
  1533. end;
  1534. %战力任务
  1535. content([State, 0, ?TASK_CONTENT_COMBAT, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_COMBAT, {num, Num}) ->
  1536. if
  1537. Num >= NeedNum ->
  1538. {[State, 1, ?TASK_CONTENT_COMBAT, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1539. Num > NowNum ->
  1540. {[State, 0, ?TASK_CONTENT_COMBAT, Id, NeedNum, Scene, X, Y, Num, PathFind], true};
  1541. true ->
  1542. {[State, 0, ?TASK_CONTENT_COMBAT, Id, NeedNum, Scene, X, Y, NowNum, PathFind], true}
  1543. end;
  1544. %%选项对话任务
  1545. content([State, 0, ?TASK_CONTENT_CHOOSE_TALK, NeedId, NeedNum, Scene, X, Y, _NowNum, PathFind], _, ?TASK_CONTENT_CHOOSE_TALK, {num,Id,TalkId}) ->
  1546. NewNpc = lib_role_task:exchange_npc(NeedId),
  1547. case NewNpc =:= Id of
  1548. true->
  1549. {[State, 1, ?TASK_CONTENT_CHOOSE_TALK, Id, NeedNum, Scene, X, Y, TalkId, PathFind], true};
  1550. _->
  1551. {[State, 0, ?TASK_CONTENT_CHOOSE_TALK, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], false}
  1552. end;
  1553. %% 任务对话
  1554. content([State, 0, ?TASK_CONTENT_TALK, NeedId, Num, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_TALK, {id, Id}) ->
  1555. NewNpc = lib_role_task:exchange_npc(NeedId),
  1556. case NewNpc =:= NeedId of
  1557. true->%%无变化
  1558. case NewNpc =:= Id of
  1559. true->
  1560. {[State, 1, ?TASK_CONTENT_TALK, Id, Num, Scene, X, Y, Num, PathFind], true};
  1561. _->
  1562. {[State, 0, ?TASK_CONTENT_TALK, Id, Num, Scene, X, Y, _NowNum, PathFind], false}
  1563. end;
  1564. _->
  1565. case NewNpc =:= Id of
  1566. true->
  1567. {[State, 1, ?TASK_CONTENT_TALK, NewNpc, Num, Scene, X, Y, Num, PathFind], true};
  1568. _->
  1569. {[State, 0, ?TASK_CONTENT_TALK, NewNpc, Num, Scene, X, Y, _NowNum, PathFind], false}
  1570. end
  1571. end;
  1572. %% 个人幻魔处理 数据初始
  1573. 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}) ->
  1574. if Num >= NeedNum ->
  1575. {[State, 1, ?TASK_CONTENT_DUNGEON_TYPE, ?DUNGEON_TYPE_PER_BOSS, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1576. Num>NowNum->
  1577. {[State, 0, ?TASK_CONTENT_DUNGEON_TYPE, ?DUNGEON_TYPE_PER_BOSS, NeedNum, Scene, X, Y, Num, PathFind], true};
  1578. true->
  1579. {[State, 0, ?TASK_CONTENT_DUNGEON_TYPE, ?DUNGEON_TYPE_PER_BOSS, NeedNum, Scene, X, Y, NowNum, PathFind], false}
  1580. end;
  1581. %% 次元幻魔处理 数据初始
  1582. 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}) ->
  1583. if Num >= NeedNum ->
  1584. {[State, 1, ?TASK_CONTENT_KILL_BOSS, ?MON_REWARD_BOSS, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1585. Num>NowNum->
  1586. {[State, 0, ?TASK_CONTENT_KILL_BOSS, ?MON_REWARD_BOSS, NeedNum, Scene, X, Y, Num, PathFind], true};
  1587. true->
  1588. {[State, 0, ?TASK_CONTENT_KILL_BOSS, ?MON_REWARD_BOSS, NeedNum, Scene, X, Y, NowNum, PathFind], false}
  1589. end;
  1590. %% 进阶 数据初始
  1591. content([State, 0, ?TASK_CONTENT_FOSTER_GRADE, Type, NeedNum, Scene, X, Y, NowNum, PathFind], State, ?TASK_CONTENT_FOSTER_GRADE, {num, Type, Num}) ->
  1592. if Num >= NeedNum ->
  1593. {[State, 1, ?TASK_CONTENT_FOSTER_GRADE, Type, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1594. Num>NowNum->
  1595. {[State, 0, ?TASK_CONTENT_FOSTER_GRADE, Type, NeedNum, Scene, X, Y, Num, PathFind], true};
  1596. true->
  1597. {[State, 0, ?TASK_CONTENT_FOSTER_GRADE, Type, NeedNum, Scene, X, Y, NowNum, PathFind], false}
  1598. end;
  1599. %%指定对话
  1600. content([State, 0, ?TASK_CONTENT_TALK, NeedId, TalkId, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_TALK, {id,TalkId,Id}) ->
  1601. NewNpc = lib_role_task:exchange_npc(NeedId),
  1602. case NewNpc =:= NeedId of
  1603. true->%%无变化
  1604. case NewNpc =:= Id of
  1605. true->
  1606. {[State, 1, ?TASK_CONTENT_TALK, Id, TalkId, Scene, X, Y, 1, PathFind], true};
  1607. _->
  1608. {[State, 0, ?TASK_CONTENT_TALK, Id, TalkId, Scene, X, Y, 1, PathFind], false}
  1609. end;
  1610. _->
  1611. case NewNpc =:= Id of
  1612. true->
  1613. {[State, 1, ?TASK_CONTENT_TALK, NewNpc, TalkId, Scene, X, Y, 1, PathFind], true};
  1614. _->
  1615. {[State, 0, ?TASK_CONTENT_TALK, NewNpc, TalkId, Scene, X, Y, 1, PathFind], false}
  1616. end
  1617. end;
  1618. %% 送信任务
  1619. content([State, 0, ?TASK_CONTENT_MAILER_RUN, NeedId, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ?TASK_CONTENT_MAILER_RUN, {id,Id}) ->
  1620. NewNpc = lib_role_task:exchange_npc(NeedId),
  1621. case NewNpc =:= NeedId of
  1622. true->%%无变化
  1623. case NewNpc =:= Id of
  1624. true->
  1625. {[State, 1, ?TASK_CONTENT_MAILER_RUN, NewNpc, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1626. _->
  1627. {[State, 0, ?TASK_CONTENT_MAILER_RUN, NewNpc, NeedNum, Scene, X, Y, _NowNum, PathFind], false}
  1628. end;
  1629. _->
  1630. case NewNpc =:= Id of
  1631. true->
  1632. {[State, 1, ?TASK_CONTENT_MAILER_RUN, NewNpc, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1633. _->
  1634. {[State, 0, ?TASK_CONTENT_MAILER_RUN, NewNpc, NeedNum, Scene, X, Y, _NowNum, PathFind], false}
  1635. end
  1636. end;
  1637. %% 某个特定的id(特定的副本,特定的活动)
  1638. content([State, 0, ContentType, Id, Num, Scene, X, Y, _NowNum, PathFind], State, ContentType, {id, Id}) ->
  1639. {[State, 1, ContentType, Id, Num, Scene, X, Y, Num, PathFind], true};
  1640. %% 完成次数就行
  1641. content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ContentType, {num, Num}) ->
  1642. case NowNum + Num >= NeedNum of
  1643. true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1644. _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum + Num, PathFind], true}
  1645. end;
  1646. %% 通用的id和次数
  1647. content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum, PathFind], State, ContentType, {num, Id, Num}) ->
  1648. case NowNum + Num >= NeedNum of
  1649. true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1650. _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum + Num, PathFind], true}
  1651. end;
  1652. %% 列表类型id和次数
  1653. content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum, PathFind]=H, _Taskstate, ContentType, {id_num_list, IdNumList}) ->
  1654. case lists:keyfind(Id, 1, IdNumList) of
  1655. false -> {H, false};
  1656. {Id, Num} ->
  1657. case NowNum + Num >= NeedNum of
  1658. true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1659. _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, NowNum + Num, PathFind], true}
  1660. end
  1661. end;
  1662. %% 收集物品减少触发状态变成
  1663. content([State, _Finsh, ?TASK_CONTENT_ITEM, Id, NeedNum, Scene, X, Y, _NowNum, PathFind]=H, _TaskState, ?TASK_CONTENT_ITEM, {reduce_id_num_list, IdNumList}) ->
  1664. case lists:keyfind(Id, 1, IdNumList) of
  1665. false -> {H, false};
  1666. {Id, _Num, GAllNum} ->
  1667. NewNowNum = min(GAllNum, NeedNum),
  1668. case NewNowNum >= NeedNum of
  1669. true -> {[State, 1, ?TASK_CONTENT_ITEM, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1670. _ -> {[State, 0, ?TASK_CONTENT_ITEM, Id, NeedNum, Scene, X, Y, NewNowNum, PathFind], true}
  1671. end
  1672. end;
  1673. %% 完成次数就行
  1674. content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ContentType, {value, Num}) ->
  1675. case Num >= NeedNum of
  1676. true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1677. _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, Num, PathFind], true}
  1678. end;
  1679. %% 通用的id和次数
  1680. content([State, 0, ContentType, Id, NeedNum, Scene, X, Y, _NowNum, PathFind], State, ContentType, {value, Id, Num}) ->
  1681. case Num >= NeedNum of
  1682. true -> {[State, 1, ContentType, Id, NeedNum, Scene, X, Y, NeedNum, PathFind], true};
  1683. _ -> {[State, 0, ContentType, Id, NeedNum, Scene, X, Y, Num, PathFind], true}
  1684. end;
  1685. %% 容错
  1686. content(MarkItem, _State, _Event, _Args) ->
  1687. {MarkItem, false}.
  1688. %% 检查装备的件数和强化数
  1689. check_equip_num_con([], _StrenNum, Num, Count)->
  1690. {Count >= Num, Count};
  1691. check_equip_num_con(_EqStrenList, _StrenNum, Num, Num)->
  1692. {true, Num};
  1693. check_equip_num_con([{StrNum, N}|EqStrenList], StrenNum, Num, Count)->
  1694. if
  1695. StrNum >= StrenNum andalso N >= Num ->
  1696. {true, Num};
  1697. StrNum >= StrenNum ->
  1698. check_equip_num_con(EqStrenList, StrenNum, Num, Count+N);
  1699. true ->
  1700. check_equip_num_con(EqStrenList, StrenNum, Num, Count)
  1701. end.
  1702. %%检查套件中装备品质数
  1703. check_equip_suit_con([], _Series, _Color, NeedNum, Count)->
  1704. {Count >= NeedNum, Count};
  1705. check_equip_suit_con(_SCNList, _Series, _Color, NeedNum, Count) when Count>=NeedNum->
  1706. {true, NeedNum};
  1707. check_equip_suit_con([{S,C,N}|SCNList], Series, Color, NeedNum, Count)->
  1708. if
  1709. S =:= Series andalso C>=Color ->
  1710. check_equip_suit_con(SCNList,Series,Color,NeedNum,Count+N);
  1711. true->
  1712. check_equip_suit_con(SCNList,Series,Color,NeedNum,Count)
  1713. end.
  1714. % %% 任务失败,算完成了任务一次(超时或者放弃)
  1715. % task_fail(PS, RT) ->
  1716. % add_log(PS#player_status.id, RT#role_task.task_id, RT#role_task.type, RT#role_task.trigger_time, utime:unixtime(), 0),
  1717. % refresh_active(PS).
  1718. %% ------------------------------
  1719. %% 自动完成任务
  1720. %% ------------------------------
  1721. %% 检测任务是否完成
  1722. % auto_finish(TaskId, Id) when is_integer(TaskId) ->
  1723. % case get_one_trigger(TaskId) of
  1724. % false ->
  1725. % Msg = data_task_text:get_auto_finish(1),
  1726. % {ok, BinData} = pt_300:write(30004, [0, Msg, []]),
  1727. % lib_server_send:send_to_uid(Id, BinData),
  1728. % false;
  1729. % RT ->
  1730. % case RT#role_task.state > 0 of
  1731. % true ->
  1732. % Msg = data_task_text:get_auto_finish(2),
  1733. % {ok, BinData} = pt_300:write(30004, [0, Msg, []]),
  1734. % lib_server_send:send_to_uid(Id, BinData),
  1735. % false;
  1736. % false ->
  1737. % auto_finish(RT, Id)
  1738. % end
  1739. % end;
  1740. % auto_finish(RT, Id) when is_record(RT, role_task) ->
  1741. % NewMark = auto_finish_mark(RT#role_task.mark, []),
  1742. % put_task_bag_list(RT#role_task{mark = NewMark, state=RT#role_task.state + 1}),
  1743. % %% 通知客户端刷新任务栏
  1744. % refresh_npc_ico(Id),
  1745. % TipList = get_tip(trigger, RT#role_task.task_id, Id),
  1746. % {ok, BinData} = pt_302:write(30200, [RT#role_task.task_id, TipList]),
  1747. % lib_server_send:send_to_uid(Id, BinData),
  1748. % true.
  1749. auto_finish_mark([], NewMark) ->
  1750. NewMark;
  1751. auto_finish_mark([MarkItem | T], NewMark) ->
  1752. auto_finish_mark(T, NewMark ++ [auto_check_content(MarkItem)]).
  1753. %% 检测任务内容是否完成
  1754. auto_check_content([D1, _Finish, kill, D2, Num, _NowNum]) ->
  1755. [D1, 1, kill, D2, Num, Num];
  1756. auto_check_content([D1, _Finish, item, D2, Num, _NowNum]) ->
  1757. [D1, 1, item, D2, Num, Num];
  1758. auto_check_content([D1, _Finish | D2]) ->
  1759. [D1, 1 | D2];
  1760. auto_check_content(Other) ->
  1761. Other.
  1762. %% ================================= 进程字段记录 =================================
  1763. put_task_log_list(TaskId,TaskInfo) ->
  1764. LogIdList = get_task_log_id_list(),
  1765. case find_task_log_list(TaskId) of
  1766. false ->
  1767. put(log_id_list,[TaskId|LogIdList]),
  1768. put({log, TaskId}, TaskInfo);
  1769. Data ->
  1770. C = Data#role_task_log.count + 1,
  1771. put({log, TaskId}, TaskInfo#role_task_log{count = C})
  1772. end.
  1773. find_task_log_list(TaskId) ->
  1774. case get({log, TaskId}) of
  1775. undefined -> false;
  1776. Data -> Data
  1777. end.
  1778. %% 已经完成任务的ID列表
  1779. get_task_log_id_list() ->
  1780. case get(log_id_list) of
  1781. undefined -> [];
  1782. Data -> Data
  1783. end.
  1784. find_task_log_exits(TaskId) ->
  1785. ?IF(find_task_log_list(TaskId) == false, false, true).
  1786. delete_task_log_list(TaskId) ->
  1787. erase({log, TaskId}).
  1788. get_task_bag_id_list() ->
  1789. get("lib_task_task_bag_id_list").
  1790. set_task_bag_list(Data) ->
  1791. put("lib_task_task_bag_id_list", Data).
  1792. %% 按type类型
  1793. get_task_bag_id_list_type(Type)->
  1794. L = get_task_bag_id_list(),
  1795. [ T || T <- L, T#role_task.type =:= Type].
  1796. %% 按TaskId类型
  1797. get_task_bag_id_list_task_id(TaskId)->
  1798. L = get_task_bag_id_list(),
  1799. [ T || T <- L, T#role_task.task_id =:= TaskId].
  1800. %% 按kind类型
  1801. get_task_bag_id_list_kind(Kind)->
  1802. L = get_task_bag_id_list(),
  1803. [ T || T <- L, T#role_task.kind =:= Kind].
  1804. put_task_bag_list(TaskInfo) ->
  1805. %% upd_trigger(TaskInfo#role_task.role_id, TaskInfo#role_task.task_id, TaskInfo#role_task.state, TaskInfo#role_task.mark),
  1806. List = lists:keydelete(TaskInfo#role_task.task_id, #role_task.task_id, get_task_bag_id_list()),
  1807. put("lib_task_task_bag_id_list", [TaskInfo|List]).
  1808. find_task_bag_list(TaskId) ->
  1809. lists:keyfind(TaskId, #role_task.task_id, get_task_bag_id_list()).
  1810. find_task_bag_exits(TaskId) ->
  1811. ?IF(find_task_bag_list(TaskId) == false, false, true).
  1812. %% 获取任务接取时间
  1813. get_trigger_time(TaskId) ->
  1814. case find_task_bag_list(TaskId) of
  1815. false -> false;
  1816. RT -> RT#role_task.trigger_time
  1817. end.
  1818. delete_task_bag_list(TaskId) ->
  1819. put("lib_task_task_bag_id_list", lists:keydelete(TaskId, #role_task.task_id, get_task_bag_id_list())).
  1820. get_query_cache_list() ->
  1821. get("lib_task_query_cache_list").
  1822. set_query_cache_list(Data) ->
  1823. put("lib_task_query_cache_list", Data).
  1824. %% 按类型
  1825. get_query_cache_list_type(Type)->
  1826. [ T || T <- get_query_cache_list(), T#task.type =:= Type].
  1827. put_query_cache_list(TaskInfo) ->
  1828. List = lists:keydelete(TaskInfo#task.id, 2, get_query_cache_list()),
  1829. List1 = List ++ [TaskInfo],
  1830. put("lib_task_query_cache_list", List1).
  1831. find_query_cache_list(TaskId) ->
  1832. lists:keyfind(TaskId, 2, get_query_cache_list()).
  1833. find_query_cache_exits(TaskId) ->
  1834. ?IF(find_query_cache_list(TaskId) == false, false, true).
  1835. delete_query_cache_list(TaskId) ->
  1836. put("lib_task_query_cache_list", lists:keydelete(TaskId, #task.id, get_query_cache_list())).
  1837. %% ================================= db op =================================
  1838. %% Type:1 2 3 4需要永久保存的,事物执行task 删除和记录日志操作
  1839. add_log(Rid, Tid, Type, TriggerTime, FinishTime, Count) ->
  1840. %% 删除已触发的任务缓存
  1841. delete_task_bag_list(Tid),
  1842. %% 记录任务日志缓存
  1843. put_task_log_list(Tid,#role_task_log{type = Type}),
  1844. %% db操作
  1845. F = fun() ->
  1846. if
  1847. Type =/= ?TASK_TYPE_MAIN -> skip;
  1848. true -> db:execute(io_lib:format(<<"update player_state set last_task_id = ~p where id= ~p">>, [Tid, Rid]))
  1849. end,
  1850. if
  1851. Type == ?TASK_TYPE_MAIN; Type == ?TASK_TYPE_SIDE;
  1852. Type == ?TASK_TYPE_TURN; Type == ?TASK_TYPE_CHAPTER;
  1853. Type == ?TASK_TYPE_NUCLEON; Type == ?TASK_TYPE_FOUR->
  1854. db:execute(lists:concat(["insert into `task_log`(`role_id`,`task_id`,`type`,`trigger_time`,`finish_time`)
  1855. values(",Rid,",",Tid,",",Type,",",TriggerTime,",",FinishTime,")"]));
  1856. true ->
  1857. db:execute(lists:concat(["insert into `task_log_clear`(`role_id`, `task_id`, `type`, `trigger_time`, `finish_time`, `count`)
  1858. values(",Rid,",",Tid,",",Type,",",TriggerTime,",",FinishTime,",",Count,")"]))
  1859. end,
  1860. db:execute(lists:concat(["delete from `task_bag` where role_id=", Rid, " and task_id=", Tid]))
  1861. end,
  1862. db:transaction(F).
  1863. %% 删除完成日志
  1864. del_log(Rid, Tid, Type) when Type == ?TASK_TYPE_MAIN; Type == ?TASK_TYPE_SIDE;
  1865. Type == ?TASK_TYPE_TURN; Type == ?TASK_TYPE_CHAPTER;
  1866. Type == ?TASK_TYPE_NUCLEON; Type == ?TASK_TYPE_FOUR ->
  1867. db:execute(lists:concat(["delete from `task_log` where role_id=",Rid," and task_id=",Tid]));
  1868. del_log(Rid, Tid, _Type) ->
  1869. db:execute(lists:concat(["delete from `task_log_clear` where role_id=",Rid," and task_id=",Tid])).
  1870. %% 删除完成日志
  1871. del_log_type(Type) when Type == ?TASK_TYPE_FOUR ->
  1872. db:execute(io_lib:format("delete from `task_log` where `type` = ~p", [Type]));
  1873. del_log_type(_Type) ->
  1874. ok.
  1875. %% 添加触发,新+到任务背包
  1876. add_trigger(Rid, Tid, TriggerTime, TaskState, TaskEndState, TaskMark, Type, Kind, RoleLv) ->
  1877. put_task_bag_list(#role_task{role_id = Rid, task_id = Tid, trigger_time = TriggerTime, lv = RoleLv,
  1878. state=TaskState, type=Type, kind=Kind, end_state=TaskEndState, mark = TaskMark}),
  1879. delete_query_cache_list(Tid),
  1880. db:execute( io_lib:format(<<"insert into `task_bag`(`role_id`, `task_id`, `trigger_time`, `state`,
  1881. `end_state`, `mark`, `type`, `lv`) values(~p,~p,~p,~p,~p,'~s',~p, ~p)">>,
  1882. [Rid, Tid, TriggerTime, TaskState, TaskEndState, util:term_to_bitstring(TaskMark), Type, RoleLv])).
  1883. %% 更新任务记录器
  1884. upd_trigger(Rid, Tid, TaskState, TaskMark) ->
  1885. 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])).
  1886. %% 玩家下线更新需要保存数据库的操作
  1887. task_offline_up(RoleTaskList)->
  1888. F = fun(TaskInfo, Args) ->
  1889. case TaskInfo#role_task.write_db =/= 1 of
  1890. true->
  1891. Args;
  1892. _->
  1893. [TaskInfo|Args]
  1894. end
  1895. end,
  1896. Tasks = lists:foldl(F, [], RoleTaskList),
  1897. DbList = format_task_bag([],Tasks),
  1898. Sql = ?SQL_ROLE_TASK_BAG_BATCH,
  1899. batch_save(Sql,DbList),
  1900. ok.
  1901. format_task_bag(DbList,[])->
  1902. DbList;
  1903. format_task_bag(DbList,[H|T])->
  1904. #role_task{
  1905. role_id = Rid,
  1906. task_id = Tid,
  1907. trigger_time = TriggerTime,
  1908. lv = RoleLv,
  1909. state=TaskState,
  1910. type=Type,
  1911. end_state=TaskEndState,
  1912. mark = TaskMark,
  1913. write_db = IsDb
  1914. }=H,
  1915. case IsDb >= 1 of
  1916. true->
  1917. Data0 = [Rid, Tid, TriggerTime, TaskState, TaskEndState, util:term_to_bitstring(TaskMark), Type, RoleLv],
  1918. Data1 = io_lib:format("(~p,~p,~p,~p,~p,'~ts',~p,~p)", Data0),
  1919. format_task_bag([Data1|DbList],T);
  1920. _->
  1921. format_task_bag(DbList,T)
  1922. end.
  1923. batch_save(_Sql,[])->
  1924. ok;
  1925. batch_save(Sql,DbList)->
  1926. ArgsString = string:join(DbList, ","),
  1927. SqlN = io_lib:format(Sql, [ArgsString]),
  1928. db:execute(SqlN),
  1929. ok.
  1930. %% 删除触发任务
  1931. del_trigger_from_sql(Rid, Tid) ->
  1932. db:execute(lists:concat(["delete from `task_bag` where role_id=", Rid, " and task_id=", Tid])).
  1933. %% 日常任务清理
  1934. daily_clear(Clock, DelaySec)->
  1935. spawn(fun() -> util:multiserver_delay(DelaySec, lib_task, daily_clear, [Clock]) end),
  1936. ok.
  1937. %% 每日清理
  1938. daily_clear(Clock) ->
  1939. case utime:day_of_week() of
  1940. 1 -> %% 周一4点重置公会周任务
  1941. if
  1942. Clock == ?TWELVE -> %% 周一0点清理可清理的任务日志和公会任务
  1943. skip;
  1944. Clock == ?FOUR -> %% 日常支线任务(悬赏任务)(日清理)
  1945. del_log_type(?TASK_TYPE_FOUR),
  1946. db:execute("TRUNCATE TABLE `task_log_clear`"),
  1947. db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_GUILD]) ),
  1948. db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_DAILY]) ),
  1949. db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_FOUR]) );
  1950. true ->
  1951. skip
  1952. end;
  1953. _ ->
  1954. if
  1955. Clock =/= ?FOUR -> skip;
  1956. true -> %% 日常支线任务(悬赏任务)(日清理)
  1957. del_log_type(?TASK_TYPE_FOUR),
  1958. db:execute("TRUNCATE TABLE `task_log_clear`"),
  1959. db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_GUILD]) ),
  1960. db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_DAILY]) ),
  1961. db:execute( io_lib:format("delete from `task_bag` where `type` = ~p", [?TASK_TYPE_FOUR]) )
  1962. end
  1963. end,
  1964. case Clock of
  1965. ?FOUR->
  1966. db:execute("delete from `task_log` where `task_id` = 3070002"),
  1967. db:execute("delete from `task_bag` where `task_id` = 3070002");
  1968. _->
  1969. ignore
  1970. end,
  1971. %% 每个玩家清理
  1972. [gen_server:cast(D#ets_online.pid, {'refresh_and_clear_task', Clock}) || D <- ets:tab2list(?ETS_ONLINE)],
  1973. ?ERR("task_clear_daily ~n", []),
  1974. ok.
  1975. %% ================================= 特殊的任务类型触发:悬赏任务和公会任务 =================================
  1976. %% return {false, ErrorCode} | {ok, ?SUCCESS}
  1977. trigger_type_task(TaskType, TaskArgs)->
  1978. %% 是否已经接取了同类型任务
  1979. case get_task_bag_id_list_type(TaskType) of
  1980. [] ->
  1981. %% 过滤出响应等级的任务
  1982. case filter_task_type_ids(TaskType, TaskArgs) of
  1983. [] ->
  1984. {false, ?ERRCODE(err300_lv_no_task)};
  1985. TD when TaskType =:= ?TASK_TYPE_DAILY-> %%日常不拼接
  1986. TaskMark = [content_to_mark(E, TD#task.content, TaskArgs)||E<-TD#task.content],
  1987. add_trigger(TaskArgs#task_args.id, TD#task.id, utime:unixtime(), 0, TD#task.state,
  1988. TaskMark, TD#task.type, TD#task.kind, TaskArgs#task_args.figure#figure.lv),
  1989. get_my_task_list(TaskType, TaskArgs),
  1990. refresh_npc_ico(TaskArgs),
  1991. {ok, ?SUCCESS};
  1992. TD->
  1993. %% npc显示
  1994. %% TaskArgs1 = do_dynamic_npc(TaskArgs, TD#task.npc_show),
  1995. TaskMark = [content_to_mark(E, TD#task.content, TaskArgs)||E<-TD#task.content]
  1996. ++ case TD#task.end_talk of
  1997. 0 -> []; %% end_talk = 0 则直接提交任务
  1998. _ -> [content_to_mark([TD#task.state, ?TASK_CONTENT_END_TALK, TD#task.end_npc,
  1999. TD#task.end_talk, 0, 0, 0, TD#task.finish_pathfind], TaskArgs)]
  2000. end,
  2001. add_trigger(TaskArgs#task_args.id, TD#task.id, utime:unixtime(), 0, TD#task.state,
  2002. TaskMark, TD#task.type, TD#task.kind, TaskArgs#task_args.figure#figure.lv),
  2003. get_my_task_list(TaskType, TaskArgs),
  2004. refresh_npc_ico(TaskArgs),
  2005. {ok, ?SUCCESS}
  2006. end;
  2007. _R ->
  2008. ?ERR("error have task type:~p~n _R:~p~n", [TaskType, _R]),
  2009. {false, ?ERRCODE(err300_task_trigger)}
  2010. end.
  2011. %% 过滤类型
  2012. filter_task_type_ids(TaskType, TaskArgs)->
  2013. ClsState = case czone_api:zone_enter_check_city() of
  2014. true when TaskType =:= ?TASK_TYPE_DAILY->
  2015. 2;
  2016. _->
  2017. 1
  2018. end,
  2019. case data_task_lv_dynamic:get_type_task_id(TaskType,ClsState,TaskArgs#task_args.figure#figure.lv) of
  2020. #task_lv_dynamic_id{task_ids = TaskIds} when TaskIds /= []->
  2021. TaskId = get_next_type_task_id(TaskType, TaskIds, TaskArgs#task_args.figure#figure.lv),
  2022. case data_task_lv_dynamic:get_type_task_dynamic(TaskId, TaskArgs#task_args.figure#figure.lv) of
  2023. #task_lv_dynamic_content{start_npc = StartNpc, end_npc = EndNpc, scene = SceneId,
  2024. x = X, y = Y, content_type = ContentType, id = Id, num = NeedNum} ->
  2025. case data_task:get(TaskId) of
  2026. #task{kind = LastKind} = TD->
  2027. put({'last_task_kind_type', TaskType}, LastKind),
  2028. format_task_dynamic_content(TD, StartNpc, EndNpc, SceneId, X, Y, ContentType, Id, NeedNum);
  2029. _ ->
  2030. ?ERR("error dynamic task_id :~p~n", [TaskId]),
  2031. []
  2032. end;
  2033. _ ->
  2034. ?ERR("error dynamic content :~p~n", [[TaskIds, TaskArgs#task_args.figure#figure.lv]]),
  2035. []
  2036. end;
  2037. _ ->
  2038. ?ERR("error dynamic task content :~p~n", [[TaskType, TaskArgs#task_args.figure#figure.lv]]),
  2039. []
  2040. end.
  2041. get_next_type_task_id(?TASK_TYPE_DAILY = TaskType, TaskIds, RoleLv) ->
  2042. case lists:member(RoleLv, ?DAILY_SPECIAL_LV) of
  2043. true -> get_special_task_id(TaskType, TaskIds);
  2044. false -> do_get_next_type_task_id(TaskType, TaskIds)
  2045. end;
  2046. get_next_type_task_id(TaskType, TaskIds, _RoleLv) ->
  2047. do_get_next_type_task_id(TaskType, TaskIds).
  2048. get_special_task_id(?TASK_TYPE_DAILY = TaskType, TaskIds) ->
  2049. Fun = fun({_, TaskId}, TmpList) ->
  2050. case is_finish_task_id(TaskId) of
  2051. true -> TmpList;
  2052. false -> [TaskId | TmpList]
  2053. end
  2054. end,
  2055. FilterList = lists:foldr(Fun, [], TaskIds),
  2056. case FilterList == [] of
  2057. true -> do_get_next_type_task_id(TaskType, TaskIds);
  2058. false -> hd(FilterList)
  2059. end;
  2060. get_special_task_id(TaskType, TaskIds) ->
  2061. do_get_next_type_task_id(TaskType, TaskIds).
  2062. %%日常非类型过滤
  2063. do_get_next_type_task_id(?TASK_TYPE_DAILY, TaskIds)->
  2064. {_, TaskId} = util:find_ratio(TaskIds, 1),
  2065. TaskId;
  2066. % case get({'last_task_kind_type', TaskType}) of
  2067. % undefined ->
  2068. % {_, TaskId} = util:find_ratio(TaskIds, 1),
  2069. % TaskId;
  2070. % LastKindType ->
  2071. % LessTaskIds = [{Weight, TId} || {Weight, TId} <- TaskIds, TaskInfo <- [data_task:get(TId)], TaskInfo#task.kind =/= LastKindType],
  2072. % {_, TaskId} = util:find_ratio(LessTaskIds, 1),
  2073. % TaskId
  2074. % end.
  2075. do_get_next_type_task_id(TaskType, TaskIds)->
  2076. case get({'last_task_kind_type', TaskType}) of
  2077. undefined ->
  2078. {_, TaskId} = util:find_ratio(TaskIds, 1),
  2079. TaskId;
  2080. LastKindType ->
  2081. LessTaskIds = [{Weight, TId} || {Weight, TId} <- TaskIds, TaskInfo <- [data_task:get(TId)], TaskInfo#task.kind =/= LastKindType],
  2082. {_, TaskId} = util:find_ratio(LessTaskIds, 1),
  2083. TaskId
  2084. end.
  2085. %% 组装动态任务内容
  2086. format_task_dynamic_content(TD, StartNpcId, EndNpcId, SceneId, X, Y, ContentType, Id, NeedNum)->
  2087. Content = if
  2088. StartNpcId == 0 -> [];
  2089. true ->
  2090. [[0, ?TASK_CONTENT_TALK, StartNpcId, TD#task.start_talk, 0, 0, 0, 1]]
  2091. end,
  2092. NewContent = if
  2093. ContentType == 0 orelse Id == 0 ->
  2094. [];
  2095. ContentType == 5 ->
  2096. Content;
  2097. Content == [] ->
  2098. [[0, ContentType, Id, NeedNum, SceneId, X, Y, 1]];
  2099. true ->
  2100. Content ++ [[1, ContentType, Id, NeedNum, SceneId, X, Y, 1]]
  2101. end,
  2102. State = length(NewContent),
  2103. if
  2104. EndNpcId == 0 -> EndTalk = 0;
  2105. true -> EndTalk = TD#task.end_talk
  2106. end,
  2107. TD#task{start_npc = StartNpcId, content = NewContent, end_npc = EndNpcId, state = State, end_talk = EndTalk}.
  2108. %% 获取赏金(日常)和公会周任务
  2109. get_special_task_reward(TaskId, Type, TaskArgs) ->
  2110. RoleId = TaskArgs#task_args.id,
  2111. case get_one_trigger(TaskId) of
  2112. false -> Goods = [], ExtraReward = [];
  2113. RT ->
  2114. Goods0 = calc_task_type_reward(Type, RT#role_task.lv),
  2115. Goods = get_award_item(data_task:get(TaskId), TaskArgs)++Goods0,
  2116. case data_task_lv_dynamic:get_task_type(Type) of
  2117. #task_type{module_id = ModuleId, counter_id = CounterId} ->
  2118. FinishCount = lib_daily:get_count(RoleId, ModuleId, CounterId)+1,
  2119. ExtraReward = calc_extra_task_type_reward(TaskId, Type, FinishCount, RT#role_task.lv);
  2120. _ ->
  2121. ExtraReward = []
  2122. end
  2123. end,
  2124. lib_server_send:send_to_uid(RoleId, pt_300, 30011, [TaskId, Goods, ExtraReward]).
  2125. %% ================================= 任务秘籍 =================================
  2126. %% 强制接取某个任务(秘籍使用)
  2127. force_trigger(TaskId, TaskArgs) ->
  2128. %% 删除缓存
  2129. delete_task_bag_list(TaskId),
  2130. delete_task_log_list(TaskId),
  2131. %% 删除db
  2132. TD = get_data(TaskId),
  2133. F = fun() ->
  2134. del_trigger_from_sql(TaskArgs#task_args.id, TaskId),
  2135. del_log(TaskArgs#task_args.id, TaskId, TD#task.type)
  2136. end,
  2137. db:transaction(F),
  2138. %% 刷新
  2139. refresh_active(TaskArgs),
  2140. TaskArgs1 = do_dynamic_npc(TaskArgs, TD#task.npc_show),
  2141. TaskMark = [content_to_mark(E, TaskArgs1)||E<-TD#task.content]
  2142. ++ case TD#task.end_talk of
  2143. 0 -> []; %% end_talk=0则直接提交任务
  2144. _ -> [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)]
  2145. end,
  2146. add_trigger(TaskArgs#task_args.id, TaskId, utime:unixtime(), 0, TD#task.state,
  2147. TaskMark, TD#task.type, TD#task.kind, TaskArgs#task_args.figure#figure.lv),
  2148. %% 转生任务接取了要通知其他模块
  2149. if
  2150. TD#task.type == ?TASK_TYPE_TURN ->
  2151. lib_player:apply_cast(TaskArgs#task_args.id, ?APPLY_CAST_SAVE, transform, trigger_task, [TD#task.id]);
  2152. true -> skip
  2153. end,
  2154. get_my_task_list(0, TaskArgs1),
  2155. refresh_npc_ico(TaskArgs1),
  2156. ok.
  2157. %% 清理自身触发的任务
  2158. gm_refresh_task(GmType, TaskArgs) ->
  2159. put("lib_task_task_bag_id_list", []),
  2160. db:execute(io_lib:format("delete from task_log_clear where role_id=~w", [TaskArgs#task_args.id])),
  2161. if
  2162. GmType == 0 -> %% 当前已接
  2163. db:execute(io_lib:format("delete from task_bag where role_id=~w", [TaskArgs#task_args.id]));
  2164. true -> %% 删除所有的任务,从0开始
  2165. [delete_task_log_list(Tid) || Tid <- data_task_lv:get_ids(TaskArgs#task_args.figure#figure.lv)],
  2166. db:execute(io_lib:format("delete from task_log where role_id=~w", [TaskArgs#task_args.id])),
  2167. db:execute(io_lib:format("delete from task_bag where role_id=~w", [TaskArgs#task_args.id]))
  2168. end,
  2169. flush_role_task(TaskArgs),
  2170. get_my_task_list(0, TaskArgs),
  2171. refresh_npc_ico(TaskArgs).
  2172. %% 直接移除某个任务(秘籍使用)
  2173. del_task(TaskId, TaskArgs) ->
  2174. %% 删除缓存
  2175. delete_task_bag_list(TaskId),
  2176. delete_task_log_list(TaskId),
  2177. TD = get_data(TaskId),
  2178. F = fun() ->
  2179. db:execute(io_lib:format("delete from task_bag where role_id=~w and task_id=~p",
  2180. [TaskArgs#task_args.id, TaskId])),
  2181. del_log(TaskArgs#task_args.id, TaskId, TD#task.type)
  2182. end,
  2183. db:transaction(F),
  2184. %% 刷新
  2185. refresh_active(TaskArgs),
  2186. get_my_task_list(0, TaskArgs),
  2187. refresh_npc_ico(TaskArgs),
  2188. ok.
  2189. %% 完成当前主线任务
  2190. gm_finitask(TaskArgs) ->
  2191. % spawn(fun()-> finish_lv_task(TaskArgs) end),
  2192. TaskList = get_task_bag_id_list(),
  2193. Fun = fun(#role_task{task_id = TaskId, type = TaskType})->
  2194. case TaskType == ?TASK_TYPE_MAIN of
  2195. true -> finish(TaskId, [], TaskArgs);
  2196. false -> ok
  2197. end
  2198. end,
  2199. lists:map(Fun, TaskList),
  2200. get_my_task_list(0, TaskArgs),
  2201. ok.
  2202. gm_finish_lv_task(Status)->
  2203. TaskArgs = lib_task_api:ps2task_args(Status),
  2204. finish_lv_task(TaskArgs).
  2205. %% 完成该等级前的所有任务
  2206. finish_lv_task(#task_args{id=RoleId, figure=#figure{lv=Lv}}=TaskArgs) ->
  2207. % Sql = io_lib:format(<<"delete from `role_npc_show` where id = ~p ">>, [RoleId]),
  2208. % db:execute(Sql),
  2209. AllIdList = data_task_lv:get_ids(Lv - 1),
  2210. F2 = fun(TaskId, Acc) ->
  2211. TD = data_task:get(TaskId),
  2212. case TD of
  2213. #task{type = 1} -> [TaskId|Acc];
  2214. _ -> Acc
  2215. end
  2216. end,
  2217. MainTaskIds = lists:droplast( lists:foldr(F2, [], AllIdList)), %% 过滤后把当前级即最后一个去掉
  2218. case db:get_all(io_lib:format(<<"select task_id from task_log WHERE role_id=~p">>, [RoleId])) of
  2219. LogIds when is_list(LogIds) -> LogIds2 = lists:usort(LogIds);
  2220. _ -> LogIds2 = []
  2221. end,
  2222. NowTime = utime:unixtime(),
  2223. F1 = fun(TaskId, Acc) ->
  2224. TD = data_task:get(TaskId),
  2225. case TD =/= null andalso TD =/= [] andalso TD#task.type == 1 andalso lists:member(TaskId, LogIds2) == false of
  2226. true ->
  2227. Sql3 = io_lib:format(<<"REPLACE INTO `task_log` set `role_id`=~p, `task_id`=~p, `type`=~p, `trigger_time`=~p, `finish_time`=~p">>,
  2228. [RoleId, TaskId, TD#task.type, NowTime, NowTime]),
  2229. db:execute(Sql3),
  2230. [TaskId|Acc];
  2231. false ->
  2232. Acc
  2233. end
  2234. end,
  2235. TIds = lists:foldl(F1, [], MainTaskIds),
  2236. Sql2 = io_lib:format(<<"delete from `task_bag` where role_id=~p and task_id in (~s)">>, [RoleId, util:link_list(TIds)]),
  2237. db:execute(Sql2),
  2238. flush_role_task(TaskArgs),
  2239. lv_up(TaskArgs),
  2240. List = get_task_log_id_list(),
  2241. lib_server_send:send_to_uid(RoleId, pt_300, 30017, [List]),
  2242. ok.
  2243. %%打包多个taskid
  2244. pack_task_id(TaskList)->
  2245. Fun = fun(TaskId) -> <<TaskId:32>> end,
  2246. ListBin = pt:write_array(Fun, TaskList),
  2247. ListBin.
  2248. %%解包多个taskid
  2249. unpack_task_id(TaskListBin)->
  2250. Fun = fun(<<Bin0/binary>>) ->
  2251. <<TaskId:32, _Args1/binary>> = Bin0,
  2252. {TaskId, _Args1}
  2253. end,
  2254. {TaskList, _Bin1} = pt:read_array(Fun, TaskListBin),
  2255. TaskList.
  2256. %%触发长剧情
  2257. event_to_story(PS, TaskId, EndTime) ->
  2258. #player_status{id = RoleId, sid = Sid, scene = SceneId, scene_pool_id = ScenePoolId, copy_id = CopyId, x = X, y = Y} = PS,
  2259. Utime = utime:unixtime(),
  2260. %%默认60s
  2261. DefaultTime = 60,
  2262. Times = ?IF( EndTime - Utime > DefaultTime, DefaultTime, max(1, EndTime - Utime)),
  2263. Ref = erlang:send_after(Times * 1000, self(), {mod, ?MODULE, event_to_cancel_story, [TaskId]}),
  2264. put({?MODULE, event_story, TaskId}, Ref),
  2265. lib_server_send:send_to_sid(Sid, pt_300, 30016, [?SUCCESS]),
  2266. {ok, BinData} = pt_300:write(30017, [RoleId, 1]),
  2267. lib_server_send:send_to_area_scene(SceneId, ScenePoolId, CopyId, X, Y, BinData),
  2268. ok.
  2269. %%触发结束长剧情
  2270. event_to_cancel_story(PS, TaskId) ->
  2271. #player_status{id = RoleId, scene = SceneId, scene_pool_id = ScenePoolId, copy_id = CopyId, x = X, y = Y} = PS,
  2272. lib_counter:increment(RoleId, ?MOD_TASK, 1, TaskId),
  2273. Ref = get({?MODULE, event_story, TaskId}),
  2274. util:cancel_timer(Ref),
  2275. erase({?MODULE, event_story, TaskId}),
  2276. {ok, BinData} = pt_300:write(30017, [RoleId, 0]),
  2277. lib_server_send:send_to_area_scene(SceneId, ScenePoolId, CopyId, X, Y, BinData),
  2278. {ok, PS}.
  2279. after_finish_round_task(RoleId, TaskType, Num) ->
  2280. if
  2281. TaskType == ?TASK_TYPE_DAILY -> %% 日常任务
  2282. custom_act_mobilize:update_mobilize_task(RoleId, dailytask, Num),
  2283. mod_hi_point:success_end(RoleId, ?MOD_TASK, 1, 1),
  2284. custom_act_adventure:do_trigger_adventure_task(RoleId, ?MOD_TASK, 1),
  2285. lib_activitycalen_api:role_success_end_activity(RoleId, ?MOD_TASK, 1, Num),
  2286. lib_role_legion:trigger_task(RoleId, ?MOD_TASK, 1);
  2287. TaskType == ?TASK_TYPE_GUILD -> %% 公会任务
  2288. lib_activitycalen_api:role_success_end_activity(RoleId, ?MOD_TASK, 2, Num),
  2289. mod_hi_point:success_end(RoleId, ?MOD_TASK, 2, 1),
  2290. custom_act_adventure:do_trigger_adventure_task(RoleId, ?MOD_TASK, 2),
  2291. lib_guild_labor:task_active(RoleId,?GTASK_TYPE_TASK);
  2292. true ->
  2293. skip
  2294. end.
  2295. %%过滤对话选项任务的完成TalkId
  2296. filter_task_talk([])->
  2297. 0;
  2298. filter_task_talk([H|T])->
  2299. case H of
  2300. [_, _, ?TASK_CONTENT_CHOOSE_TALK, _NeedId, _NeedNum, _Scene, _X, _Y,Talk, _PathFind]->
  2301. Talk;
  2302. _->
  2303. filter_task_talk(T)
  2304. end.
  2305. %%npc矫正
  2306. fix_task_npc([],NewTriggerList,_TaskArgs)->
  2307. NewTriggerList;
  2308. fix_task_npc([H|T],NewTriggerList,TaskArgs)->
  2309. #role_task{mark=Mark}=H,
  2310. NMark = fix_task_mark(Mark,[],TaskArgs),
  2311. fix_task_npc(T,[H#role_task{mark=NMark}|NewTriggerList],TaskArgs).
  2312. fix_task_mark([],Mark,_TaskArgs)->
  2313. lists:reverse(Mark);
  2314. fix_task_mark([[State,CurState,?TASK_CONTENT_CHOOSE_TALK,Id,Num,_SceneId,_X,_Y,NeedNum,PathFind]|Mark],NMark,TaskArgs)->
  2315. NewId=lib_role_task:exchange_npc(Id),
  2316. {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info),
  2317. fix_task_mark(Mark,[[State,CurState,?TASK_CONTENT_CHOOSE_TALK,NewId,Num,RealSceneId, RealX, RealY,NeedNum,PathFind]|NMark],TaskArgs);
  2318. fix_task_mark([[State,CurState,?TASK_CONTENT_TALK,Id,Num,_SceneId,_X,_Y,NeedNum,PathFind]|Mark],NMark,TaskArgs)->
  2319. NewId=lib_role_task:exchange_npc(Id),
  2320. {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info),
  2321. fix_task_mark(Mark,[[State,CurState,?TASK_CONTENT_TALK,NewId,Num,RealSceneId, RealX, RealY,NeedNum,PathFind]|NMark],TaskArgs);
  2322. fix_task_mark([[State,CurState,?TASK_CONTENT_END_TALK,Id,Num,_SceneId,_X,_Y,NeedNum,PathFind]|Mark],NMark,TaskArgs)->
  2323. NewId=lib_role_task:exchange_npc(Id),
  2324. {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info),
  2325. fix_task_mark(Mark,[[State,CurState,?TASK_CONTENT_END_TALK,NewId,Num,RealSceneId, RealX, RealY,NeedNum,PathFind]|NMark],TaskArgs);
  2326. fix_task_mark([[State,CurState,?TASK_CONTENT_MAILER_RUN,Id,Num,_SceneId,_X,_Y,NeedNum,PathFind]|Mark],NMark,TaskArgs)->
  2327. NewId=lib_role_task:exchange_npc(Id),
  2328. {RealSceneId, RealX, RealY} = get_npc_info(NewId, TaskArgs#task_args.npc_info),
  2329. fix_task_mark(Mark,[[State,CurState,?TASK_CONTENT_MAILER_RUN,NewId,Num,RealSceneId, RealX, RealY,NeedNum,PathFind]|NMark],TaskArgs);
  2330. fix_task_mark([H|T],NMark,TaskArgs)->
  2331. fix_task_mark(T,[H|NMark],TaskArgs).