currency.lua 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. local schema = require "model.schema"
  2. local logger = require "logger"
  3. local asset = require "model.asset"
  4. local common_fun = require "model.common_fun"
  5. local skynet = require "lualib.skynet"
  6. local role
  7. local MODULE_NAME = "currency"
  8. local MAX_CHANGE = 20000000000
  9. local logger_trace = logger.trace
  10. local table_insert = table.insert
  11. local statistics_list = {
  12. CURRENCY_ID_COINS,
  13. CURRENCY_ID_STM,
  14. }
  15. local _M = schema.new(MODULE_NAME, {
  16. first = false,
  17. data = {
  18. -- [id] = {
  19. -- id = 货币id;
  20. -- num = 货币数量;
  21. -- }
  22. }
  23. })
  24. local REQUEST = {}
  25. local CMD = {}
  26. local MODULE = {}
  27. local THIS = {}
  28. function MODULE.list_request_interests() return REQUEST end
  29. function MODULE.list_command_interests() return CMD end
  30. -- TODO: 解析/升级模块数据
  31. function MODULE.parse(character)
  32. local d = _M.load(character)
  33. if not d then
  34. return
  35. end
  36. if not d.first then
  37. d.data[CURRENCY_ID_STM] = d.data[CURRENCY_ID_STM] or {id = CURRENCY_ID_STM, num = asset.DataConfig_proto[1].data3}
  38. d.first = true
  39. _M.persist(character)
  40. end
  41. -- 加载货币配置 设置为0
  42. -- local conf = assert(asset.GoodsConfig_proto, "GoodsConfig_proto")
  43. -- for k, _ in pairs(conf) do
  44. -- if not d.data[k] then
  45. -- d.data[k] = {
  46. -- id = k,
  47. -- num = 0,
  48. -- }
  49. -- end
  50. -- end
  51. end
  52. -- TODO: 侦听事件
  53. function MODULE.monitor(character)
  54. local d = _M.assert_get(character)
  55. character.monitor("daily_refresh", function()
  56. local data = d.data[CURRENCY_ID_DACTIVITY]
  57. if data then
  58. local num = data.num
  59. d.data[CURRENCY_ID_DACTIVITY] = nil
  60. _M.persist(character)
  61. character.send("pay_currency", {now = {{id = CURRENCY_ID_DACTIVITY, num = 0}}, pay = {{id = CURRENCY_ID_DACTIVITY, num = num}}})
  62. end
  63. end)
  64. character.monitor("weekly_refresh", function()
  65. local data = d.data[CURRENCY_ID_WACTIVITY]
  66. if data then
  67. local num = data.num
  68. d.data[CURRENCY_ID_WACTIVITY] = nil
  69. _M.persist(character)
  70. character.send("pay_currency", {now = {{id = CURRENCY_ID_WACTIVITY, num = 0}}, pay = {{id = CURRENCY_ID_WACTIVITY, num = num}}})
  71. end
  72. end)
  73. end
  74. -- TODO: 类似泰利的 prepare 接口
  75. function MODULE.launch(character)
  76. local d = _M.assert_get(character)
  77. role = role or require "model.role"
  78. end
  79. -- TODO: 与客户端同步数据
  80. function MODULE.ready(character)
  81. local d = _M.assert_get(character)
  82. end
  83. -- TODO: 玩家下线时的处理
  84. function MODULE.saybye(character)
  85. local d = _M.assert_get(character)
  86. local ret = {
  87. level = character.level,
  88. list = {}
  89. }
  90. -- for _ , key in ipairs(statistics_list) do
  91. -- if d.data[key] then
  92. -- table.insert(ret.list, d.data[key])
  93. -- end
  94. -- end
  95. -- local itemavg = skynet.localname(".itemavg")
  96. -- if next(ret.list) then
  97. -- skynet.send(itemavg, "lua", "updata", ret)
  98. -- end
  99. end
  100. function MODULE.get_client_data(character)
  101. local d = _M.assert_get(character) or {}
  102. return common_fun.tqueue(d.data)
  103. end
  104. -- list = {{id =1 , num = 1}} 物品id, 物品数量
  105. function MODULE.add_money(character, id, num, collect, dispose, addition)
  106. local d = _M.assert_get(character)
  107. local conf_list = assert(asset.GoodsConfig_proto, "GoodsConfig_proto")
  108. local conf = conf_list[id]
  109. if not conf and dispose then
  110. dispose(nil, id, num)
  111. return
  112. end
  113. -- 一次超过2000亿是什么数值
  114. if num >= 1 and num < MAX_CHANGE then
  115. d.data[id] = d.data[id] or {id = id, num = 0}
  116. d.data[id].num = d.data[id].num + math.floor(num) -- 向下取下整避免意外
  117. character.dispatch("currency_add", id, num)
  118. if addition then
  119. addition(GOODS_MONEY, id, num)
  120. end
  121. if collect then
  122. collect(GOODS_MONEY, d.data[id])
  123. end
  124. _M.persist(character)
  125. return true, num, d.data[id].num
  126. else
  127. if dispose then
  128. dispose(nil, id, num)
  129. end
  130. end
  131. end
  132. -- 支付一旦异常玩家直接报错
  133. function MODULE.pay_money(character, id, num)
  134. local d = _M.assert_get(character)
  135. if num < 0 then
  136. assert(false)
  137. end
  138. local cur_num = 0
  139. if d.data and d.data[id] and d.data[id].num then
  140. cur_num = d.data[id].num
  141. else
  142. assert(false)
  143. end
  144. if cur_num < num then
  145. assert(false)
  146. end
  147. d.data[id].num = d.data[id].num - math.floor(num)
  148. _M.persist(character)
  149. if id == CURRENCY_ID_STM then
  150. role.stm_change(character)
  151. end
  152. character.dispatch("pay_money", id, num)
  153. return d.data[id].num
  154. end
  155. function MODULE.check_money(character, id, num)
  156. local d = _M.assert_get(character)
  157. -- 数量至少为1
  158. if num < 0 then
  159. return STD_ERR.PAYMENT_NUM_ERR
  160. end
  161. if not d.data or not d.data[id] then
  162. local conf = assert(asset.GoodsConfig_proto, "GoodsConfig_proto")
  163. if not conf[id] then
  164. return STD_ERR.PAYMENT_UNKNOWN_ITEM
  165. end
  166. return STD_ERR.PAYMENT_NOT_ENOUGH
  167. end
  168. if not d.data[id].num then
  169. return STD_ERR.COMMON_SYS_ERR
  170. end
  171. if d.data[id].num < num then
  172. return STD_ERR.PAYMENT_NOT_ENOUGH
  173. end
  174. return 0
  175. end
  176. function MODULE.set_money(character, id, num)
  177. local d = _M.assert_get(character)
  178. if num < 0 then
  179. return STD_ERR.PAYMENT_NUM_ERR
  180. end
  181. if not d.data or not d.data[id] then
  182. local conf = assert(asset.GoodsConfig_proto, "GoodsConfig_proto")
  183. if not conf[id] then
  184. return STD_ERR.PAYMENT_UNKNOWN_ITEM
  185. end
  186. end
  187. d.data[id].num = num
  188. _M.persist(character)
  189. return 0
  190. end
  191. function MODULE.get_money(character, id)
  192. local d = _M.assert_get(character)
  193. return d.data[id] and d.data[id].num or 0
  194. end
  195. -- 获取所有随机宝箱
  196. function MODULE.get_all_random_box(character, args)
  197. local d = _M.assert_get(character)
  198. local conf_list = assert(asset.GoodsConfig_proto, "GoodsConfig_proto")
  199. local temp = {}
  200. for _, data in pairs(d.data) do
  201. local conf = conf_list[data.id]
  202. if conf and conf.type == CURRENCY_TYPE_RANDOM_BOX and data.num > 0 then
  203. table.insert(temp, {id = data.id, num = data.num})
  204. end
  205. end
  206. return temp
  207. end
  208. return MODULE