-- 任务 local skynet = require "skynet" require "skynet.manager" local socket = require "skynet.socket" local logger = require "logger" local asset = require "model.asset" local util = require "util" local stringify = require "stringify" local skynet_retpack = skynet.retpack -- 日常任务 local daily = { --[[ [等级] = {{ id = id, type = type, required = required required2 = required2 }} ]] } -- 周常任务 local weekly = { --[[ [等级] = {{ id = id, type = type, required = required required2 = required2 }} ]] } -- 成就任务 local achi = { --[[ [类型] = {{ id = id, type = type, required = required required2 = required2 }} ]] } -- 主线任务 local main_quest = { first = nil, list = { --[[ [id] = { next = next_index } ]] } } local function new_quest(desc, reset) local ret = { id = desc.ID, type = desc.touch, -- 触发器 model = desc.type, required = desc.parameter, -- 数值要求 required2 = desc.data, -- 品质要求 reset = reset or desc.timely == 1, } -- 特殊原因需要将21触发器多条件任务的主条件和副条件对调. if ret.type == 22 then ret.required, ret.required2 = ret.required2, ret.required end return ret end local function register_level_quest(t, conf) local quest = new_quest(conf, true) if conf.interval[2] then for i = conf.interval[1], conf.interval[2] do t[i] = t[i] or {} t[i][conf.ID] = quest end end end local function register_type_quest(t, conf) local quest = new_quest(conf) t[conf.touch] = t[conf.touch] or {} table.insert(t[conf.touch], quest) end local function register_main_quest(t, conf) local quest = new_quest(conf) t.list = t.list or {} t.index = t.index or {} assert(not t.list[quest.id], quest.id) t.list[quest.id] = quest table.insert(t.index, quest.id) end local function register_quest(list, config) for _, desc in pairs(config) do if desc.type == DAILY_QUEST then register_level_quest(list.daily, desc) elseif desc.type == WEEKLY_QUEST then register_level_quest(list.weekly, desc) elseif desc.type == ACHI_QUEST then register_type_quest(list.achi, desc) elseif desc.type == MAIN_QUEST then register_main_quest(list.main, desc) end end end local function optimize() -- 首先,构建关卡的任务列表 local list = { daily = {}, weekly = {}, achi = {}, main = {}, } register_quest(list, asset.TaskConfig_proto) for _, v in pairs(list.achi or {}) do table.sort(v, function(a, b) if a.required < b.required then return true end if a.required > b.required then return false end if a.required2 and b.required2 then if a.required2 < b.required2 then return true end end return false end) end if list.main.index then table.sort(list.main.index) list.main.first = list.main.index[1] for i = 1, #list.main.index do local cur_index = list.main.index[i] local nex_index = list.main.index[i+1] if nex_index then list.main.list[cur_index].next = nex_index end end end daily = list.daily weekly = list.weekly achi = list.achi if list.main then main_quest.first = list.main.first main_quest.list = list.main.list end logger.trace("main_quest:"..stringify(main_quest or {})) end local CMD = {} function CMD.start() optimize() end function CMD.daily_qlst(lv) return daily[lv] or {} end function CMD.weekly_qlst(lv) return weekly[lv] or {} end function CMD.achi_qlst(list) local ret = {} local temp ={} for _, id in ipairs(list or {}) do local conf = asset.TaskConfig_proto[id] if conf and conf.touch and conf.type == ACHI_QUEST then temp[conf.touch] = id end end for type, v in pairs(achi) do local find = false if temp[type] then for _, quest in ipairs(v) do if quest.id == temp[type] then ret[quest.id] = quest find = true break end end end if not find then local quest = v[1] if quest then ret[quest.id] = quest end end end return ret end function CMD.newx_achi(id) local conf = asset.TaskConfig_proto[id] local list = achi[conf.touch] if not list then return end for k, quest in ipairs(list) do if quest.id == id then return list[k+1] end end end function CMD.quest(id) local conf = asset.TaskConfig_proto[id] if conf then return new_quest(conf) end return nil end function CMD.get_main(id) if not id or not main_quest.list[id] then return CMD.next_main(id) else return main_quest.list[id] end end function CMD.next_main(id) if not main_quest.first then return end if not id then return main_quest.list[main_quest.first] else if main_quest.list[id] then if main_quest.list[id].next then return main_quest.list[main_quest.list[id].next] end return else local index = main_quest.first while(main_quest.list[index]) do if index > id then return main_quest.list[index] else local next_index = main_quest.list[index].next if next_index and next_index ~= index then index = next_index else return end end end end end end function CMD.hotfix(list) if list.TaskConfig_proto then logger.info("=============== quest hotfix ===================") local ok, msg = pcall(optimize) if not ok then logger.warn("=============== quest hotfix ERR===================\n, msg:"..msg) end end end skynet.init(function() skynet.register(".quest") end) skynet.start(function() logger.label(",") skynet.dispatch("lua", function(session,_, cmd, ...) local f = assert(CMD[cmd]) if session == 0 then f(...) else skynet_retpack(f(...)) end end) end)