NpcChest.lua 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. NpcChest = {
  2. }
  3. local this = {}
  4. local shopOpenId = 25002 -- 商店开启等级全局表id
  5. local PriceInfo = {}
  6. PriceInfo.__index = PriceInfo
  7. function PriceInfo:new(cfgId, count, bind)
  8. local instance = {
  9. cfgId = cfgId,
  10. count = count,
  11. bind = bind
  12. }
  13. setmetatable(instance, self)
  14. return instance
  15. end
  16. -- 初始化全局数据
  17. function NpcChest.initGlobalGoods()
  18. local goodsList = ConfigDataManager.getList("cfg_npcchest")
  19. if table.isNullOrEmpty(goodsList) then
  20. error("袖珍罐子商店不存在商品")
  21. return
  22. end
  23. local globalGoods = {}
  24. for i, item in ipairs(goodsList) do
  25. local shopId = tonumber(item.shopid)
  26. local goosByShopId = globalGoods[shopId] or {}
  27. local goods = {}
  28. goods.id = tonumber(item.id)
  29. goods.cfgId = tonumber(string.splitByAll(item.itemid, "#")[1])
  30. goods.count = tonumber(string.splitByAll(item.itemid, "#")[2])
  31. local price = item.price
  32. local weightMap = this.convert(price)
  33. local randomItem = this.doRandom(weightMap)
  34. if randomItem then
  35. goods.costType = randomItem.cfgId
  36. goods.price = math.floor(randomItem.count)
  37. goods.bind = randomItem.bind
  38. goods.conditions = item.conditions
  39. goosByShopId[goods.id] = goods
  40. globalGoods[shopId] = goosByShopId
  41. end
  42. end
  43. this.saveGlobalGoods(globalGoods)
  44. end
  45. function this.saveBuyRecord(actor, data)
  46. setplaydef(actor, "T$npcChestBuyRecord", data)
  47. end
  48. function this.getBuyRecord(actor)
  49. return getplaydef(actor, "T$npcChestBuyRecord") or {}
  50. end
  51. function this.saveGlobalGoods(data)
  52. setsysvar("G$npcChestGoods", data)
  53. end
  54. function this.getGlobalGoods()
  55. return getsysvar("G$npcChestGoods") or {}
  56. end
  57. -- 获取商品列表
  58. function NpcChest.sendShopGoodsInfoList(actor, msgData)
  59. local sendList = {}
  60. local shopId = msgData.shopId
  61. if shopId <= 0 then
  62. this.toClient(actor, sendList)
  63. return
  64. end
  65. local openLv = ConfigDataManager.getTableValue("cfg_global", "value", "id", shopOpenId)
  66. local lv = getbaseinfo(actor, "level")
  67. if lv < tonumber(openLv) then
  68. tipinfo(actor, "等级不足")
  69. this.toClient(actor, sendList)
  70. return
  71. end
  72. local globalGoods = this.getGlobalGoods()
  73. local shopGoodsList = globalGoods[shopId] or {}
  74. local newGoods = this.filterGoods(actor, shopGoodsList)
  75. -- lg("检验条件后的商品列表", newGoods)
  76. if table.isNullOrEmpty(newGoods) then
  77. this.toClient(actor, sendList)
  78. return
  79. end
  80. local record = this.getBuyRecord(actor)
  81. local recordByShop = record[shopId] or {}
  82. for id, goods in pairs(newGoods) do
  83. local alreadyBuyNum = this.getAlreadyBuyNum(id, recordByShop)
  84. -- lg("goodsId", id, "buyNum", alreadyBuyNum)
  85. local sendGoods = this.buildSendGoods(goods, alreadyBuyNum)
  86. table.insert(sendList, sendGoods)
  87. end
  88. this.toClient(actor, sendList)
  89. end
  90. function this.toClient(actor, msg)
  91. -- lg("发送商品列表", msg)
  92. sendluamsg(actor, LuaMessageIdToClient.RES_NPC_CHEST_GOODS_INFO, msg)
  93. end
  94. -- 购买商品
  95. function NpcChest.buyGoods(actor, msgData)
  96. local shopId = msgData.shopId
  97. local goodsId = msgData.goodsId
  98. local count = msgData.count
  99. if count <= 0 then
  100. return
  101. end
  102. local globalGoods = this.getGlobalGoods()
  103. local shopGoodsList = globalGoods[shopId] or {}
  104. local goods = shopGoodsList[goodsId] or {}
  105. -- lg("购买商品", goodsId, goods)
  106. if table.isNullOrEmpty(goods) or table.isNullOrEmpty(shopGoodsList) then
  107. return
  108. end
  109. if tonumber(goods.count) ~= count then
  110. tipinfo(actor, "购买数量不合法")
  111. return
  112. end
  113. local totalPrice = 0
  114. local unitPrice = goods.price
  115. totalPrice = unitPrice * count
  116. -- lg("购买商品价格", totalPrice)
  117. local costType = goods.costType
  118. local enough = false
  119. local bind = goods.bind
  120. if bind == 1 then
  121. enough = Bag.checkItemWithBind(actor, costType, totalPrice)
  122. else
  123. enough = Bag.checkItem(actor, costType, totalPrice)
  124. end
  125. if not enough then
  126. tipinfo(actor, "货币不足")
  127. return
  128. end
  129. Bag.costBind(actor, costType, totalPrice, "宝箱商人")
  130. Bag.sendRewards(actor, { [goods.cfgId] = goods.count }, "宝箱商人")
  131. -- this.excHorseLamp(actor, { [goods.cfgId] = goods.count })
  132. local record = this.getBuyRecord(actor)
  133. local recordByShop = record[shopId] or {}
  134. local alreadyBuyNum = this.getAlreadyBuyNum(goods.id, recordByShop)
  135. this.saveBuyRecords(actor, shopId, count, goods, alreadyBuyNum)
  136. end
  137. -- 存储购买记录
  138. function this.saveBuyRecords(actor, shopId, count, goods, alreadyBuyNum)
  139. local buyRecords = this.getBuyRecord(actor)
  140. local buyRecordMap = buyRecords[shopId] or {}
  141. local id = goods.id
  142. local buyRecord = buyRecordMap[id] or { id = id, buyNum = 0 }
  143. buyRecord.buyNum = alreadyBuyNum + count
  144. buyRecordMap[id] = buyRecord
  145. buyRecords[shopId] = buyRecordMap
  146. -- lg("购买记录", buyRecords)
  147. this.saveBuyRecord(actor, buyRecords)
  148. end
  149. function this.convert(source)
  150. local priceInfoMap = {}
  151. if not source or string.trim(source) == "" then
  152. return priceInfoMap
  153. end
  154. local outerArray = string.splitByAll(source, "|")
  155. for _, o in ipairs(outerArray) do
  156. local innerArray = string.splitByAll(o, "#")
  157. local cfgId = tonumber(innerArray[1])
  158. local count = tonumber(innerArray[2])
  159. local bind = tonumber(innerArray[3])
  160. local weight = tonumber(innerArray[4])
  161. local priceInfo = PriceInfo:new(cfgId, count, bind)
  162. priceInfoMap[priceInfo] = weight
  163. end
  164. return priceInfoMap
  165. end
  166. function this.doRandom(weightMap)
  167. local allWeight = 0
  168. if not weightMap or next(weightMap) == nil then
  169. return nil
  170. end
  171. for _, weight in pairs(weightMap) do
  172. allWeight = allWeight + weight
  173. end
  174. if allWeight == 0 then
  175. return nil
  176. end
  177. local randomWeight = math.random(1, allWeight)
  178. for key, weight in pairs(weightMap) do
  179. randomWeight = randomWeight - weight
  180. if randomWeight <= 0 then
  181. return key
  182. end
  183. end
  184. return nil
  185. end
  186. function this.filterGoods(actor, goodsMap)
  187. local newGoodsMap = {}
  188. for id, goods in pairs(goodsMap) do
  189. local conditions = goods.conditions
  190. if conditions and #conditions > 0 then
  191. local result = checkcondition(actor, conditions)
  192. if tonumber(result) ~= 1 then
  193. goto continue
  194. end
  195. end
  196. newGoodsMap[id] = goods
  197. ::continue::
  198. end
  199. return newGoodsMap
  200. end
  201. function this.getAlreadyBuyNum(goodsId, recordByShop)
  202. local buyNum = 0
  203. if table.isNullOrEmpty(recordByShop) then
  204. return buyNum
  205. end
  206. local record = recordByShop[goodsId]
  207. if record then
  208. buyNum = record.buyNum
  209. end
  210. return buyNum
  211. end
  212. function this.buildSendGoods(goods, alreadyBuyNum)
  213. local item = {}
  214. item.cfgId = goods.cfgId
  215. item.unitPrice = goods.price
  216. item.bind = goods.bind
  217. item.coinType = goods.costType
  218. item.count = goods.count
  219. item.id = goods.id
  220. return item
  221. end
  222. function this.excHorseLamp(actor, itemMap)
  223. if table.isNullOrEmpty(itemMap) then
  224. return
  225. end
  226. local name = getbaseinfo(actor, "rolename")
  227. for cfgId, count in pairs(itemMap) do
  228. local item = ConfigDataManager.getById("cfg_item", cfgId)
  229. if not table.isNullOrEmpty(item) then
  230. local itemName = item.name
  231. local noticeId = item.runninghorselamp
  232. if #noticeId > 0 then
  233. noticeTip.noticeinfo(actor, noticeId, name, itemName)
  234. end
  235. end
  236. end
  237. end
  238. function initchest(actor)
  239. NpcChest.initGlobalGoods()
  240. end