414 lines
No EOL
12 KiB
Lua
414 lines
No EOL
12 KiB
Lua
MainLineTaskOBJ = {}
|
|
|
|
MainLineTaskOBJ._name = "MainLineTaskOBJ"
|
|
MainLineTaskOBJ.STATUS_WAIT_VISIT = 0
|
|
MainLineTaskOBJ.STATUS_DOING = 1
|
|
MainLineTaskOBJ.STATUS_FINISH = 9
|
|
|
|
MainLineTaskOBJ.cfg = Func.require("cfg_Ö÷ÏßÈÎÎñ")
|
|
|
|
local function appendCfgValue(list, value)
|
|
if value == nil or value == "" or tonumber(value) == 0 then
|
|
return
|
|
end
|
|
table.insert(list, value)
|
|
end
|
|
|
|
local function normalizeTaskCfg(cfg)
|
|
for id, task in pairs(cfg or {}) do
|
|
task.id = tonumber(task.id or id) or id
|
|
|
|
if not task.visit and task.visit_type and task.visit_type ~= "" then
|
|
local visit = { type = task.visit_type }
|
|
if visit.type == "module" then
|
|
visit.keys = {}
|
|
appendCfgValue(visit.keys, task.visit_keys_1)
|
|
if #visit.keys <= 0 and task.ShouChongOBJ ~= nil then
|
|
table.insert(visit.keys, "ShouChongOBJ")
|
|
end
|
|
if #visit.keys <= 0 and task.visit_open and task.visit_open ~= "" then
|
|
table.insert(visit.keys, string.gsub(task.visit_open, "_main$", ""))
|
|
end
|
|
if task.visit_open and task.visit_open ~= "" then
|
|
visit.open = task.visit_open
|
|
end
|
|
elseif visit.type == "npc" then
|
|
visit.ids = {}
|
|
appendCfgValue(visit.ids, task.visit_ids_1)
|
|
visit.scripts = {}
|
|
appendCfgValue(visit.scripts, task.visit_scripts_1)
|
|
end
|
|
task.visit = visit
|
|
end
|
|
|
|
if not task.target and task.target_type and task.target_type ~= "" then
|
|
task.target = {
|
|
type = task.target_type,
|
|
count = tonumber(task.target_count) or 0,
|
|
map = task.target_map,
|
|
mon = task.target_mon,
|
|
}
|
|
end
|
|
|
|
if not task.rewards then
|
|
task.rewards = {}
|
|
for _, reward in ipairs(task.reward or {}) do
|
|
table.insert(task.rewards, {
|
|
reward.type,
|
|
reward.name,
|
|
tonumber(reward.num) or 0,
|
|
tonumber(reward.bind) or 0,
|
|
})
|
|
end
|
|
end
|
|
end
|
|
return cfg
|
|
end
|
|
|
|
MainLineTaskOBJ.cfg = normalizeTaskCfg(MainLineTaskOBJ.cfg)
|
|
|
|
function MainLineTaskOBJ:getTask(id)
|
|
return self.cfg[tonumber(id or 1)]
|
|
end
|
|
|
|
function MainLineTaskOBJ:setTask(id, cfg)
|
|
if not id or not cfg then
|
|
return false
|
|
end
|
|
cfg.id = tonumber(id)
|
|
self.cfg[tonumber(id)] = cfg
|
|
return true
|
|
end
|
|
|
|
function MainLineTaskOBJ:deleteTask(id)
|
|
id = tonumber(id)
|
|
if not id then
|
|
return false
|
|
end
|
|
self.cfg[id] = nil
|
|
return true
|
|
end
|
|
|
|
function MainLineTaskOBJ:getValidTask(id)
|
|
id = tonumber(id)
|
|
if not id then
|
|
return nil
|
|
end
|
|
local task = self:getTask(id)
|
|
local guard = 0
|
|
while task and task.enabled == false and task.next and guard < 100 do
|
|
task = self:getTask(task.next)
|
|
guard = guard + 1
|
|
end
|
|
return task
|
|
end
|
|
|
|
function MainLineTaskOBJ:getTaskId(actor)
|
|
local id = Player.getint(actor, VarCfg.Player.int["Ö÷ÏßÈÎÎñID"]) or 0
|
|
if id <= 0 then
|
|
id = 1
|
|
self:setState(actor, id, self.STATUS_WAIT_VISIT, 0)
|
|
end
|
|
local task = self:getValidTask(id)
|
|
if task and task.id ~= id then
|
|
id = task.id
|
|
local status = task.finish and self.STATUS_FINISH or self.STATUS_WAIT_VISIT
|
|
self:setState(actor, id, status, 0)
|
|
elseif not task then
|
|
id = 9
|
|
self:setState(actor, id, self.STATUS_FINISH, 0)
|
|
end
|
|
return id
|
|
end
|
|
|
|
function MainLineTaskOBJ:getStatus(actor)
|
|
return Player.getint(actor, VarCfg.Player.int["Ö÷ÏßÈÎÎñ״̬"]) or self.STATUS_WAIT_VISIT
|
|
end
|
|
|
|
function MainLineTaskOBJ:getProgress(actor)
|
|
return Player.getint(actor, VarCfg.Player.int["Ö÷ÏßÈÎÎñ½ø¶È"]) or 0
|
|
end
|
|
|
|
function MainLineTaskOBJ:setState(actor, id, status, progress)
|
|
Player.setint(actor, VarCfg.Player.int["Ö÷ÏßÈÎÎñID"], id)
|
|
Player.setint(actor, VarCfg.Player.int["Ö÷ÏßÈÎÎñ״̬"], status)
|
|
Player.setint(actor, VarCfg.Player.int["Ö÷ÏßÈÎÎñ½ø¶È"], progress or 0)
|
|
end
|
|
|
|
function MainLineTaskOBJ:contains(list, value)
|
|
if not list then
|
|
return false
|
|
end
|
|
for _, v in ipairs(list) do
|
|
if tostring(v) == tostring(value) then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function MainLineTaskOBJ:visitMatched(task, visitKey, npcID, sScript)
|
|
if not task or not task.visit then
|
|
return false
|
|
end
|
|
local visit = task.visit
|
|
if visit.type == "module" then
|
|
return self:contains(visit.keys, visitKey)
|
|
end
|
|
if visit.type == "npc" then
|
|
return self:contains(visit.ids, npcID) or self:contains(visit.scripts, sScript)
|
|
end
|
|
return false
|
|
end
|
|
|
|
function MainLineTaskOBJ:getRewardView(task)
|
|
local itemRewards = {}
|
|
local moneyRewards = {}
|
|
for _, reward in ipairs((task and task.rewards) or {}) do
|
|
local rtype = reward[1]
|
|
local name = reward[2]
|
|
local num = tonumber(reward[3]) or 0
|
|
local bind = tonumber(reward[4]) or 0
|
|
if name and num > 0 then
|
|
if rtype == "item" then
|
|
table.insert(itemRewards, { name = name, count = num, bind = bind, type = rtype })
|
|
elseif rtype == "money" then
|
|
table.insert(itemRewards, { name = name, count = num, bind = 0, type = rtype })
|
|
table.insert(moneyRewards, { name = name, count = num })
|
|
end
|
|
end
|
|
end
|
|
return itemRewards, moneyRewards
|
|
end
|
|
function MainLineTaskOBJ:getTaskView(actor)
|
|
local id = self:getTaskId(actor)
|
|
local task = self:getValidTask(id)
|
|
if not task then
|
|
task = self.cfg[9]
|
|
id = 9
|
|
self:setState(actor, id, self.STATUS_FINISH, 0)
|
|
end
|
|
local status = self:getStatus(actor)
|
|
local progress = self:getProgress(actor)
|
|
local target = task and task.target or nil
|
|
local need = target and target.count or 0
|
|
if task and task.finish then
|
|
status = self.STATUS_FINISH
|
|
progress = 0
|
|
need = 0
|
|
end
|
|
local statusText = "´ý°Ý·Ã"
|
|
local desc = task and task.desc or ""
|
|
if status == self.STATUS_DOING then
|
|
statusText = "½øÐÐÖÐ"
|
|
desc = task.doingDesc or desc
|
|
elseif status == self.STATUS_FINISH or (task and task.finish) then
|
|
statusText = "ÒÑÍê³É"
|
|
desc = task.desc or "Ö÷ÏßÈÎÎñÒÑÍê³É¡£"
|
|
end
|
|
local rewardItems, rewardMoneys = self:getRewardView(task)
|
|
return {
|
|
id = task and task.id or id,
|
|
title = task and task.title or "[Ö÷Ïß]ÈÎÎñ",
|
|
desc = desc,
|
|
status = status,
|
|
statusText = statusText,
|
|
progress = progress,
|
|
need = need,
|
|
rewardText = task and task.rewardText or "",
|
|
rewardItems = rewardItems,
|
|
rewardMoneys = rewardMoneys,
|
|
finish = task and task.finish and true or false,
|
|
}
|
|
end
|
|
|
|
function MainLineTaskOBJ:sync(actor)
|
|
if not isnotnull(actor) then
|
|
return
|
|
end
|
|
if self:tryCompleteReady(actor) then
|
|
return
|
|
end
|
|
Message:SubLink(actor, self._name .. "_sync", self:getTaskView(actor))
|
|
end
|
|
|
|
function MainLineTaskOBJ:startTask(actor, task)
|
|
self:setState(actor, task.id, self.STATUS_DOING, 0)
|
|
Func.sendmsg9(actor, string.format("[Ö÷ÏßÈÎÎñ]:#70|ÒѽÓÈ¡£º%s", task.title))
|
|
self:sync(actor)
|
|
end
|
|
|
|
function MainLineTaskOBJ:onVisit(actor, visitKey)
|
|
local id = self:getTaskId(actor)
|
|
local task = self:getValidTask(id)
|
|
if not task or task.finish or self:getStatus(actor) ~= self.STATUS_WAIT_VISIT then
|
|
self:sync(actor)
|
|
return
|
|
end
|
|
if self:visitMatched(task, visitKey, nil, nil) then
|
|
self:startTask(actor, task)
|
|
else
|
|
self:sync(actor)
|
|
end
|
|
end
|
|
|
|
function MainLineTaskOBJ:onVisitNpc(actor, npcID, sScript)
|
|
local id = self:getTaskId(actor)
|
|
local task = self:getValidTask(id)
|
|
if not task or task.finish or self:getStatus(actor) ~= self.STATUS_WAIT_VISIT then
|
|
self:sync(actor)
|
|
return
|
|
end
|
|
if self:visitMatched(task, nil, npcID, sScript) then
|
|
self:startTask(actor, task)
|
|
else
|
|
self:sync(actor)
|
|
end
|
|
end
|
|
|
|
function MainLineTaskOBJ:giveItemRewards(actor, items)
|
|
if #items <= 0 then
|
|
return
|
|
end
|
|
local itemStrs = {}
|
|
for _, item in ipairs(items) do
|
|
table.insert(itemStrs, string.format("%s#%s#%s", item[1], item[2], item[3] or 0))
|
|
end
|
|
gives(actor, table.concat(itemStrs, "&"), "Ö÷ÏßÈÎÎñ")
|
|
end
|
|
|
|
function MainLineTaskOBJ:giveRewards(actor, rewards)
|
|
local items = {}
|
|
for _, reward in ipairs(rewards or {}) do
|
|
local rtype = reward[1]
|
|
local name = reward[2]
|
|
local num = tonumber(reward[3]) or 0
|
|
local bind = tonumber(reward[4]) or 0
|
|
if rtype == "money" then
|
|
local moneyId = ConstCfg.sysMoney[name]
|
|
if moneyId and num > 0 then
|
|
changemoney(actor, moneyId, "+", num, "Ö÷ÏßÈÎÎñ", true)
|
|
end
|
|
elseif rtype == "item" and name and num > 0 then
|
|
table.insert(items, { name, num, bind })
|
|
end
|
|
end
|
|
self:giveItemRewards(actor, items)
|
|
end
|
|
|
|
function MainLineTaskOBJ:completeTask(actor, task)
|
|
self:giveRewards(actor, task.rewards)
|
|
Func.sendmsg9(actor, string.format("[Ö÷ÏßÈÎÎñ]:#70|Íê³É%s£¬½±ÀøÒÑ·¢·Å¡£", task.title))
|
|
|
|
local nextTask = self:getValidTask(task.next)
|
|
if nextTask then
|
|
if nextTask.finish then
|
|
self:setState(actor, nextTask.id, self.STATUS_FINISH, 0)
|
|
else
|
|
self:setState(actor, nextTask.id, self.STATUS_WAIT_VISIT, 0)
|
|
end
|
|
else
|
|
self:setState(actor, 9, self.STATUS_FINISH, 0)
|
|
end
|
|
self:sync(actor)
|
|
end
|
|
|
|
function MainLineTaskOBJ:tryCompleteReady(actor)
|
|
if self:getStatus(actor) ~= self.STATUS_DOING then
|
|
return false
|
|
end
|
|
local id = self:getTaskId(actor)
|
|
local task = self:getValidTask(id)
|
|
if not task or not task.target or task.target.type ~= "kill_mon" then
|
|
return false
|
|
end
|
|
local need = tonumber(task.target.count) or 0
|
|
if need > 0 and self:getProgress(actor) >= need then
|
|
Player.setint(actor, VarCfg.Player.int["Ö÷ÏßÈÎÎñ½ø¶È"], need)
|
|
self:completeTask(actor, task)
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
function MainLineTaskOBJ:onKillMon(actor, mon, itype, kill, monName, mapID)
|
|
if self:getStatus(actor) ~= self.STATUS_DOING then
|
|
return
|
|
end
|
|
local id = self:getTaskId(actor)
|
|
local task = self:getValidTask(id)
|
|
if not task or not task.target or task.target.type ~= "kill_mon" then
|
|
return
|
|
end
|
|
local target = task.target
|
|
if target.map and target.map ~= "*" and tostring(target.map) ~= tostring(mapID) then
|
|
return
|
|
end
|
|
if target.mon and target.mon ~= "*" and tostring(target.mon) ~= tostring(monName) then
|
|
return
|
|
end
|
|
local need = tonumber(target.count) or 0
|
|
local progress = self:getProgress(actor) + 1
|
|
if progress >= need then
|
|
Player.setint(actor, VarCfg.Player.int["Ö÷ÏßÈÎÎñ½ø¶È"], need)
|
|
self:completeTask(actor, task)
|
|
else
|
|
Player.setint(actor, VarCfg.Player.int["Ö÷ÏßÈÎÎñ½ø¶È"], progress)
|
|
self:sync(actor)
|
|
end
|
|
end
|
|
|
|
GameEvent.add(EventCfg.onLogin, function(actor)
|
|
MainLineTaskOBJ:sync(actor)
|
|
end, MainLineTaskOBJ)
|
|
|
|
GameEvent.add(EventCfg.onqfloadend, function(actor)
|
|
MainLineTaskOBJ:sync(actor)
|
|
end, MainLineTaskOBJ)
|
|
|
|
GameEvent.add(EventCfg.onKillMon, function(actor, mon, itype, kill, monName, mapID)
|
|
MainLineTaskOBJ:onKillMon(actor, mon, itype, kill, monName, mapID)
|
|
end, MainLineTaskOBJ)
|
|
|
|
MainLineTaskOBJ.allowFunc = { "query", "visit", "route" }
|
|
|
|
function MainLineTaskOBJ:query(actor)
|
|
self:sync(actor)
|
|
end
|
|
|
|
function MainLineTaskOBJ:route(actor)
|
|
if not isnotnull(actor) then
|
|
return
|
|
end
|
|
if self:getStatus(actor) ~= self.STATUS_WAIT_VISIT then
|
|
return
|
|
end
|
|
local id = self:getTaskId(actor)
|
|
local task = self:getValidTask(id)
|
|
if not task or task.finish or not task.visit then
|
|
return
|
|
end
|
|
local visit = task.visit
|
|
if visit.type == "module" and visit.open then
|
|
if visit.keys and visit.keys[1] then
|
|
self:onVisit(actor, visit.keys[1])
|
|
end
|
|
Message:SubLink(actor, visit.open)
|
|
return
|
|
end
|
|
if visit.type == "npc" and visit.ids and visit.ids[1] then
|
|
opennpcshowex(actor, tonumber(visit.ids[1]), 6, 2)
|
|
end
|
|
end
|
|
function MainLineTaskOBJ:visit(actor, p1, p2, p3, data)
|
|
local visitKey = p1
|
|
if type(data) == "table" then
|
|
visitKey = data[1] or data.visitKey or visitKey
|
|
end
|
|
if visitKey then
|
|
self:onVisit(actor, visitKey)
|
|
else
|
|
self:sync(actor)
|
|
end
|
|
end
|
|
|
|
return MainLineTaskOBJ |