440 lines
No EOL
14 KiB
Lua
440 lines
No EOL
14 KiB
Lua
MainLineTaskOBJ = {}
|
||
|
||
MainLineTaskOBJ._name = "MainLineTaskOBJ"
|
||
MainLineTaskOBJ.STATUS_WAIT_VISIT = 0
|
||
MainLineTaskOBJ.STATUS_DOING = 1
|
||
MainLineTaskOBJ.STATUS_FINISH = 9
|
||
|
||
MainLineTaskOBJ.cfg = {
|
||
[1] = {
|
||
id = 1,
|
||
next = 2,
|
||
enabled = true,
|
||
title = "[主线]了解首充",
|
||
desc = "了解首充后,前往任意地图击杀任意怪物5只。",
|
||
doingDesc = "前往任意地图击杀任意怪物。",
|
||
rewardText = "经验100万、金币5000",
|
||
visit = { type = "module", keys = { "ShouChongOBJ" } },
|
||
target = { type = "kill_mon", count = 5, map = "*", mon = "*" },
|
||
rewards = { { "money", "经验", 1000000 }, { "money", "金币", 5000 } },
|
||
},
|
||
[2] = {
|
||
id = 2,
|
||
next = 3,
|
||
enabled = true,
|
||
title = "[主线]拜访渡劫天尊",
|
||
desc = "拜访渡劫天尊后,前往任意地图击杀怪物5只。",
|
||
doingDesc = "前往任意地图击杀怪物。",
|
||
rewardText = "经验100万、金币10000",
|
||
visit = { type = "npc", ids = { 6 }, scripts = { "转生" } },
|
||
target = { type = "kill_mon", count = 5, map = "*", mon = "*" },
|
||
rewards = { { "money", "经验", 1000000 }, { "money", "金币", 10000 } },
|
||
},
|
||
[3] = {
|
||
id = 3,
|
||
next = 4,
|
||
enabled = true,
|
||
title = "[主线]拜访神兽淬体",
|
||
desc = "拜访神兽淬体后,前往任意地图击杀怪物5只。",
|
||
doingDesc = "前往任意地图击杀怪物。",
|
||
rewardText = "神兽之血*50、神兽之骨*50",
|
||
visit = { type = "npc", ids = { 5 }, scripts = { "神兽淬体" } },
|
||
target = { type = "kill_mon", count = 5, map = "*", mon = "*" },
|
||
rewards = { { "item", "神兽之血", 50, 0 }, { "item", "神兽之骨", 50, 0 } },
|
||
},
|
||
[4] = {
|
||
id = 4,
|
||
next = 5,
|
||
enabled = true,
|
||
title = "[主线]拜访紫金仙人",
|
||
desc = "拜访紫金仙人后,前往任意地图击杀怪物5只。",
|
||
doingDesc = "前往任意地图击杀怪物。",
|
||
rewardText = "经验100万、千年玄石*50、金币10000",
|
||
visit = { type = "npc", ids = { 189 }, scripts = { "紫金葫芦" } },
|
||
target = { type = "kill_mon", count = 5, map = "*", mon = "*" },
|
||
rewards = { { "money", "经验", 1000000 }, { "item", "千年玄石", 50, 0 }, { "money", "金币", 10000 } },
|
||
},
|
||
[5] = {
|
||
id = 5,
|
||
next = 6,
|
||
enabled = true,
|
||
title = "[主线]了解绝学NPC",
|
||
desc = "了解绝学NPC后,前往任意地图击杀怪物5只。",
|
||
doingDesc = "前往任意地图击杀怪物。",
|
||
rewardText = "灵石*50、武林秘籍*1",
|
||
visit = { type = "npc", ids = { 12 }, scripts = { "绝学修炼" } },
|
||
target = { type = "kill_mon", count = 5, map = "*", mon = "*" },
|
||
rewards = { { "item", "灵石", 50, 0 }, { "item", "武林秘籍", 1, 0 } },
|
||
},
|
||
[6] = {
|
||
id = 6,
|
||
next = 7,
|
||
enabled = true,
|
||
title = "[主线]拜访幸运仙子",
|
||
desc = "拜访幸运仙子后,前往任意地图击杀怪物5只。",
|
||
doingDesc = "前往任意地图击杀怪物。",
|
||
rewardText = "经验100万、金币10000",
|
||
visit = { type = "npc", ids = { 11 }, scripts = { "幸运项链" } },
|
||
target = { type = "kill_mon", count = 5, map = "*", mon = "*" },
|
||
rewards = { { "money", "经验", 1000000 }, { "money", "金币", 10000 } },
|
||
},
|
||
[7] = {
|
||
id = 7,
|
||
next = 8,
|
||
enabled = true,
|
||
title = "[主线]前往装备重铸",
|
||
desc = "前往装备重铸后,前往任意地图击杀怪物5只。",
|
||
doingDesc = "前往任意地图击杀怪物。",
|
||
rewardText = "经验100万、金币10000",
|
||
visit = { type = "npc", ids = { 10 }, scripts = { "装备重铸" } },
|
||
target = { type = "kill_mon", count = 5, map = "*", mon = "*" },
|
||
rewards = { { "money", "经验", 1000000 }, { "money", "金币", 10000 } },
|
||
},
|
||
[8] = {
|
||
id = 8,
|
||
next = 9,
|
||
enabled = true,
|
||
title = "[主线]前往武器升级",
|
||
desc = "前往武器升级后,前往任意地图击杀怪物5只。",
|
||
doingDesc = "前往任意地图击杀怪物。",
|
||
rewardText = "黑铁矿石*4、金币10000",
|
||
visit = { type = "npc", ids = { 13 }, scripts = { "武器升级" } },
|
||
target = { type = "kill_mon", count = 5, map = "*", mon = "*" },
|
||
rewards = { { "item", "黑铁矿石", 4, 0 }, { "money", "金币", 10000 } },
|
||
},
|
||
[9] = {
|
||
id = 9,
|
||
next = nil,
|
||
enabled = true,
|
||
title = "[主线]任务结束",
|
||
desc = "主线任务已完成。",
|
||
doingDesc = "主线任务已完成。",
|
||
rewardText = "无",
|
||
visit = nil,
|
||
target = nil,
|
||
rewards = {},
|
||
finish = true,
|
||
},
|
||
}
|
||
|
||
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" }
|
||
|
||
function MainLineTaskOBJ:query(actor)
|
||
self:sync(actor)
|
||
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 |