manager.lua 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. -- 任务系统开发
  2. local stats = require "model.stats"
  3. local schema = require "model.schema"
  4. local util = require "util"
  5. local logger = require "logger"
  6. local min = math.min
  7. local max = math.max
  8. local _M = schema.new("quest_manager")
  9. local MODULE = {}
  10. local quest = {}
  11. -- 创建一个任务对象
  12. function quest:new(character, rawdata, conf, func)
  13. local o = {
  14. rawdata = rawdata, -- 存放数据 eg: d.daily/d.achievementd等
  15. required = conf.required, -- 要求1
  16. required2 = conf.required2,
  17. model = assert(conf.model), -- 模块 eg:每日任务/成就/历练
  18. send = func.send,
  19. save = assert(func.save), -- 保存数据的函数
  20. }
  21. if rawdata.state == QUEST_PROGRESS then -- 进行中的任务
  22. if rawdata.progress >= o.required then
  23. rawdata.state = QUEST_REACHED
  24. rawdata.progress = o.required
  25. end
  26. elseif rawdata.state == QUEST_REACHED then -- 已达成任务
  27. if rawdata.progress < o.required then
  28. rawdata.state = QUEST_PROGRESS
  29. end
  30. elseif rawdata.state == QUEST_END then -- 已结束任务
  31. if rawdata.progress ~= o.required then
  32. rawdata.progress = o.required
  33. end
  34. else
  35. assert(false, rawdata.state)
  36. end
  37. self.__index = self
  38. return setmetatable(o, self)
  39. end
  40. -- 任务进度处理
  41. function quest:progress(character, value, added)
  42. assert(value > 0)
  43. local rawdata = self.rawdata
  44. if rawdata.state == QUEST_PROGRESS then
  45. if added then
  46. rawdata.progress = min(self.required, rawdata.progress + value)
  47. else
  48. rawdata.progress = min(self.required, max(rawdata.progress, value))
  49. end
  50. if rawdata.progress == self.required then
  51. rawdata.state = QUEST_REACHED
  52. end
  53. if MAIN_QUEST == self.model or rawdata.state == QUEST_REACHED then
  54. if self.send then
  55. self.send(character, rawdata)
  56. end
  57. end
  58. self.save(character) -- 保存数据
  59. return true
  60. end
  61. end
  62. -- 多条件
  63. function quest:progress2(character, value, value2, added)
  64. assert(value > 0)
  65. local rawdata = self.rawdata
  66. if self.required2 ~= value2 then
  67. return true
  68. end
  69. if rawdata.state == QUEST_PROGRESS then
  70. if added then
  71. rawdata.progress = min(self.required, rawdata.progress + value)
  72. else
  73. rawdata.progress = min(self.required, max(rawdata.progress, value))
  74. end
  75. if rawdata.progress == self.required then
  76. rawdata.state = QUEST_REACHED
  77. end
  78. if rawdata.state == QUEST_REACHED then
  79. if self.send then
  80. self.send(character, rawdata)
  81. end
  82. end
  83. self.save(character) -- 保存数据
  84. return true
  85. end
  86. end
  87. local prototype = {}
  88. local function assert_check(rawdata)
  89. assert(rawdata.id > 0, rawdata.id)
  90. assert(rawdata.progress, rawdata.id)
  91. assert(rawdata.state, rawdata.id)
  92. end
  93. local function create_quest(character, rawdata, conf, quest_func, addnew, func)
  94. if addnew then
  95. rawdata.state = QUEST_PROGRESS
  96. if conf.reset then
  97. rawdata.progress = 0
  98. else
  99. rawdata.progress = assert(func())
  100. end
  101. end
  102. assert_check(rawdata)
  103. return quest:new(character, rawdata, conf, quest_func)
  104. end
  105. local function simple_creator(character, rawdata, conf, quest_func, addnew, ...)
  106. local args = {...}
  107. return create_quest(character, rawdata, conf, quest_func, addnew, function()
  108. return assert(stats.fetch(character, table.unpack(args)))
  109. end)
  110. end
  111. prototype[1] = function(character, rawdata, conf, quest_func, addnew)
  112. assert(quest_func.save)
  113. local list = {}
  114. function list:progress()
  115. if list.time and list.time == util.today() then
  116. list.time = nil
  117. return
  118. end
  119. if rawdata.state == QUEST_PROGRESS then
  120. rawdata.progress = min(conf.required, rawdata.progress + 1)
  121. if rawdata.progress == conf.required then
  122. rawdata.state = QUEST_REACHED
  123. end
  124. if rawdata.state == QUEST_REACHED then
  125. if self.send then
  126. self.send(character, rawdata)
  127. end
  128. end
  129. quest_func.save(character) -- 保存数据
  130. return true
  131. end
  132. end
  133. if addnew then
  134. rawdata.state = QUEST_PROGRESS
  135. rawdata.progress = 1
  136. list.time = util.today()
  137. end
  138. if rawdata.state == QUEST_PROGRESS then -- 进行中的任务
  139. if rawdata.progress >= conf.required then
  140. rawdata.state = QUEST_REACHED
  141. rawdata.progress = conf.required
  142. end
  143. elseif rawdata.state == QUEST_REACHED then -- 已达成任务
  144. if rawdata.progress < conf.required then
  145. rawdata.state = QUEST_PROGRESS
  146. end
  147. elseif rawdata.state == QUEST_END then -- 已结束任务
  148. if rawdata.progress ~= conf.required then
  149. rawdata.progress = conf.required
  150. end
  151. else
  152. assert(false, rawdata.state)
  153. end
  154. return list
  155. end
  156. prototype[2] = function(character, rawdata, conf, quest_func, addnew)
  157. return simple_creator(character, rawdata, conf, quest_func, addnew, "enter_simple_battle")
  158. end
  159. prototype[3] = function(character, rawdata, conf, quest_func, addnew)
  160. return simple_creator(character, rawdata, conf, quest_func, addnew, "daily_battle")
  161. end
  162. prototype[4] = function(character, rawdata, conf, quest_func, addnew)
  163. return simple_creator(character, rawdata, conf, quest_func, addnew, "buy_shop_item")
  164. end
  165. prototype[5] = function(character, rawdata, conf, quest_func, addnew)
  166. return simple_creator(character, rawdata, conf, quest_func, addnew, "hero_upgrade")
  167. end
  168. prototype[6] = function(character, rawdata, conf, quest_func, addnew)
  169. return simple_creator(character, rawdata, conf, quest_func, addnew, "draw_times")
  170. end
  171. prototype[7] = function(character, rawdata, conf, quest_func, addnew)
  172. return simple_creator(character, rawdata, conf, quest_func, addnew, "recharge_times")
  173. end
  174. prototype[8] = function(character, rawdata, conf, quest_func, addnew)
  175. return simple_creator(character, rawdata, conf, quest_func, addnew, "equip_upgrade")
  176. end
  177. prototype[9] = function(character, rawdata, conf, quest_func, addnew)
  178. return simple_creator(character, rawdata, conf, quest_func, addnew, "telent_activate")
  179. end
  180. prototype[10] = function(character, rawdata, conf, quest_func, addnew)
  181. return simple_creator(character, rawdata, conf, quest_func, addnew, "skill_card_upgrade")
  182. end
  183. prototype[11] = function(character, rawdata, conf, quest_func, addnew)
  184. return simple_creator(character, rawdata, conf, quest_func, addnew, "add_stm_times")
  185. end
  186. prototype[12] = function(character, rawdata, conf, quest_func, addnew)
  187. return simple_creator(character, rawdata, conf, quest_func, addnew, "buy_stm_times")
  188. end
  189. prototype[13] = function(character, rawdata, conf, quest_func, addnew)
  190. return simple_creator(character, rawdata, conf, quest_func, addnew, "watch_ad_times")
  191. end
  192. -- prototype[14] = function(character, rawdata, conf, quest_func, addnew)
  193. -- return simple_creator(character, rawdata, conf, quest_func, addnew, "tower_battle")
  194. -- end
  195. prototype[14] = function(character, rawdata, conf, quest_func, addnew)
  196. return simple_creator(character, rawdata, conf, quest_func, addnew, "relic_battle_num")
  197. end
  198. prototype[15] = function(character, rawdata, conf, quest_func, addnew)
  199. return simple_creator(character, rawdata, conf, quest_func, addnew, "elite_battle")
  200. end
  201. prototype[16] = function(character, rawdata, conf, quest_func, addnew)
  202. return simple_creator(character, rawdata, conf, quest_func, addnew, "hero_upstart")
  203. end
  204. prototype[17] = function(character, rawdata, conf, quest_func, addnew)
  205. return simple_creator(character, rawdata, conf, quest_func, addnew, "equip_upstart")
  206. end
  207. prototype[18] = function(character, rawdata, conf, quest_func, addnew)
  208. return simple_creator(character, rawdata, conf, quest_func, addnew, "skill_card_upstart")
  209. end
  210. prototype[19] = function(character, rawdata, conf, quest_func, addnew)
  211. return simple_creator(character, rawdata, conf, quest_func, addnew, "building_upgrade")
  212. end
  213. prototype[20] = function(character, rawdata, conf, quest_func, addnew)
  214. return create_quest(character, rawdata, conf, quest_func, addnew, function()
  215. return character.level
  216. end)
  217. end
  218. prototype[21] = function(character, rawdata, conf, quest_func, addnew)
  219. return simple_creator(character, rawdata, conf, quest_func, addnew, "hero_max_level")
  220. end
  221. prototype[22] = function(character, rawdata, conf, quest_func, addnew)
  222. return create_quest(character, rawdata, conf, quest_func, addnew, function()
  223. return assert(stats.hero_lv(character, conf.require2))
  224. end)
  225. end
  226. prototype[23] = function(character, rawdata, conf, quest_func, addnew)
  227. return simple_creator(character, rawdata, conf, quest_func, addnew, "simple_battle_pass")
  228. end
  229. prototype[24] = function(character, rawdata, conf, quest_func, addnew)
  230. return simple_creator(character, rawdata, conf, quest_func, addnew, "elite_battle_pass")
  231. end
  232. prototype[25] = function(character, rawdata, conf, quest_func, addnew)
  233. return simple_creator(character, rawdata, conf, quest_func, addnew, "relic_battle_num")
  234. end
  235. prototype[26] = function(character, rawdata, conf, quest_func, addnew)
  236. return simple_creator(character, rawdata, conf, quest_func, addnew, "add_coin")
  237. end
  238. prototype[27] = function(character, rawdata, conf, quest_func, addnew)
  239. return simple_creator(character, rawdata, conf, quest_func, addnew, "consume_diamond")
  240. end
  241. prototype[28] = function(character, rawdata, conf, quest_func, addnew)
  242. return simple_creator(character, rawdata, conf, quest_func, addnew, "hero_add_num")
  243. end
  244. prototype[29] = function(character, rawdata, conf, quest_func, addnew)
  245. return simple_creator(character, rawdata, conf, quest_func, addnew, "equip_add_num")
  246. end
  247. prototype[30] = function(character, rawdata, conf, quest_func, addnew)
  248. return simple_creator(character, rawdata, conf, quest_func, addnew, "skill_card_add_num")
  249. end
  250. prototype[31] = function(character, rawdata, conf, quest_func, addnew)
  251. return simple_creator(character, rawdata, conf, quest_func, addnew, "building_explore_times")
  252. end
  253. prototype[32] = function(character, rawdata, conf, quest_func, addnew)
  254. return simple_creator(character, rawdata, conf, quest_func, addnew, "city_skill_upgrade")
  255. end
  256. prototype[33] = function(character, rawdata, conf, quest_func, addnew)
  257. return simple_creator(character, rawdata, conf, quest_func, addnew, "draw_equip_times")
  258. end
  259. local function update_progress(character, type, value, added)
  260. local ctx = _M.assert_runtime(character)
  261. for _, list in pairs(ctx.trigger) do
  262. local trigger = list[type]
  263. if trigger then
  264. for k, child in ipairs(trigger) do
  265. child:progress(character, value, added)
  266. end
  267. end
  268. end
  269. end
  270. local function update_progress2(character, type, value, value2, added)
  271. local ctx = _M.assert_runtime(character)
  272. for _, list in pairs(ctx.trigger) do
  273. local trigger = list[type]
  274. if trigger then
  275. for k, child in ipairs(trigger) do
  276. child:progress2(character, value, value2, added)
  277. end
  278. end
  279. end
  280. end
  281. local function register_event_interests(character)
  282. local monitor = character.monitor
  283. monitor("stats.login", function(_, value)
  284. update_progress(character, 1, value, true)
  285. end)
  286. monitor("stats.enter_simple_battle", function(_, value)
  287. update_progress(character, 2, value, true)
  288. end)
  289. monitor("stats.daily_battle", function(_, value)
  290. update_progress(character, 3, value, true)
  291. end)
  292. monitor("stats.buy_shop_item", function(_, value)
  293. update_progress(character, 4, value, true)
  294. end)
  295. monitor("stats.hero_upgrade", function(_, value)
  296. update_progress(character, 5, value, true)
  297. end)
  298. monitor("stats.draw_times", function(_, value)
  299. update_progress(character, 6, value, true)
  300. end)
  301. monitor("stats.recharge_times", function(_, value)
  302. update_progress(character, 7, value, true)
  303. end)
  304. monitor("stats.equip_upgrade", function(_, value)
  305. update_progress(character, 8, value, true)
  306. end)
  307. monitor("stats.telent_activate", function(_, value)
  308. update_progress(character, 9, value, true)
  309. end)
  310. monitor("stats.skill_card_upgrade", function(_, value)
  311. update_progress(character, 10, value, true)
  312. end)
  313. monitor("stats.add_stm_times", function(_, value)
  314. update_progress(character, 11, value, true)
  315. end)
  316. monitor("stats.buy_stm_times", function(_, value)
  317. update_progress(character, 12, value, true)
  318. end)
  319. monitor("stats.watch_ad_times", function(_, value)
  320. update_progress(character, 13, value, true)
  321. end)
  322. -- monitor("stats.tower_battle", function(_, value)
  323. -- update_progress(character, 14, value, true)
  324. -- end)
  325. monitor("stats.relic_battle_num", function(_, value)
  326. update_progress(character, 14, value, true)
  327. end)
  328. monitor("stats.elite_battle", function(_, value)
  329. update_progress(character, 15, value, true)
  330. end)
  331. monitor("stats.hero_upstart", function(_, value)
  332. update_progress(character, 16, value, true)
  333. end)
  334. monitor("stats.equip_upstart", function(_, value)
  335. update_progress(character, 17, value, true)
  336. end)
  337. monitor("stats.skill_card_upstart", function(_, value)
  338. update_progress(character, 18, value, true)
  339. end)
  340. monitor("stats.building_upgrade", function(_, value)
  341. update_progress(character, 19, value, true)
  342. end)
  343. monitor("role_level", function(_, pre, cur)
  344. update_progress(character, 20, cur, false)
  345. end)
  346. monitor("stats.hero_max_level", function(_, value)
  347. update_progress(character, 21, value, false)
  348. end)
  349. monitor("stats.hero_lv", function(_, value, value2)
  350. update_progress2(character, 22, value, value2, false)
  351. end)
  352. monitor("stats.simple_battle_pass", function(_, value)
  353. update_progress(character, 23, value, false)
  354. end)
  355. monitor("stats.elite_battle_pass", function(_, value)
  356. update_progress(character, 24, value, false)
  357. end)
  358. monitor("stats.relic_battle_num", function(_, value)
  359. update_progress(character, 25, value, true)
  360. end)
  361. monitor("stats.add_coin", function(_, value)
  362. update_progress(character, 26, value, true)
  363. end)
  364. monitor("stats.consume_diamond", function(_, value)
  365. update_progress(character, 27, value, true)
  366. end)
  367. monitor("stats.hero_add_num", function(_, value)
  368. update_progress(character, 28, value, true)
  369. end)
  370. monitor("stats.equip_add_num", function(_, value)
  371. update_progress(character, 29, value, true)
  372. end)
  373. monitor("stats.skill_card_add_num", function(_, value)
  374. update_progress(character, 30, value, true)
  375. end)
  376. monitor("stats.building_explore_times", function(_, value)
  377. update_progress(character, 31, value, true)
  378. end)
  379. monitor("stats.city_skill_upgrade", function(_, value)
  380. update_progress(character, 32, value, true)
  381. end)
  382. monitor("stats.draw_equip_times", function(_, value)
  383. update_progress(character, 33, value, true)
  384. end)
  385. end
  386. function MODULE.monitor(character)
  387. end
  388. function MODULE.parse(character)
  389. _M.load(character)
  390. local ctx = _M.assert_runtime(character)
  391. ctx.trigger = {}
  392. register_event_interests(character)
  393. end
  394. -- 加载一个任务
  395. function MODULE.load(character, rawdata, conf, quest_func)
  396. local ctx = _M.assert_runtime(character)
  397. local type = conf.type or 0
  398. local name = conf.model
  399. assert(type > 0)
  400. local gen = assert(prototype[type], type)
  401. ctx.trigger[name] = ctx.trigger[name] or {}
  402. ctx.trigger[name][type] = ctx.trigger[name][type] or {}
  403. table.insert(ctx.trigger[name][type], gen(character, rawdata, conf, quest_func, false))
  404. end
  405. -- 接受一个新任务
  406. function MODULE.accept(character, rawdata, conf, quest_func)
  407. local ctx = _M.assert_runtime(character)
  408. local type = conf.type or 0
  409. local name = conf.model
  410. assert(type > 0)
  411. local gen = assert(prototype[type], type)
  412. ctx.trigger[name] = ctx.trigger[name] or {}
  413. ctx.trigger[name][type] = ctx.trigger[name][type] or {}
  414. table.insert(ctx.trigger[name][type], gen(character, rawdata, conf, quest_func, true))
  415. end
  416. -- 清空内存数据
  417. function MODULE.clear(character, name)
  418. assert(name)
  419. local ctx = _M.assert_runtime(character)
  420. ctx.trigger[name] = {}
  421. -- logger.trace("清空任务的 %s模块的内存", name)
  422. end
  423. -- 清空内存数据
  424. function MODULE.del(character, conf)
  425. local name = conf.model
  426. local type = conf.type or 0
  427. assert(type > 0)
  428. local ctx = _M.assert_runtime(character)
  429. local trigger = ctx.trigger[name] or {}
  430. for k, v in ipairs(trigger[type] or {}) do
  431. if v.rawdata.id == conf.id then
  432. table.remove(trigger[type], k)
  433. return true
  434. end
  435. end
  436. return false
  437. -- logger.trace("清空任务的 %s模块的内存", name)
  438. end
  439. return MODULE