EquipLogic.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. local Msg = require("core.Msg")
  2. local Util = require("common.Util")
  3. local Grid = require("bag.Grid")
  4. local ItemDefine = require("bag.ItemDefine")
  5. local TuJianExcel = require("excel.equip").tujian
  6. local EquipExcel = require("excel.equip").equip
  7. local ItemExcel = require("excel.item").item
  8. local EquipLogicGrid = require("equip.EquipLogicGrid")
  9. local Log = require("common.Log")
  10. local LogDefine = require("common.LogDefine")
  11. local Lang = require("common.Lang")
  12. local Broadcast = require("broadcast.Broadcast")
  13. local MailManager = require("mail.MailManager")
  14. local MailExcel = require("excel.mail")
  15. local HeroLogic = require("hero.HeroLogic")
  16. local TriggerDefine = require("trigger.TriggerDefine")
  17. local TriggerLogic = require("trigger.TriggerLogic")
  18. EQUIP_BAG_MAX_CNT = 500
  19. EQUIP_BAG_OP_ADD = 1 -- 增
  20. EQUIP_BAG_OP_DEL = 2 -- 删
  21. EQUIP_BAG_OP_CHANGE = 3 -- 改
  22. EQUIP_QUALITY_MAX = 5
  23. EQUIP_QUALITY = { 5000, 3000, 1500, 500 }
  24. EQUIP_QUALITY_WEIGHT = 10000
  25. EQUIP_QUALITY_BASE_RATE = { 7000, 8000, 9000, 10000, 12000 }
  26. -- 转换装备洗练数据格式
  27. function AttrHashToArray(attrData)
  28. local _, attrInfo = next(attrData)
  29. if type(attrInfo) == "table" then
  30. return attrData
  31. end
  32. local len = 0
  33. local attrArray = {}
  34. for attrType, attrVal in pairs(attrData) do
  35. len = len + 1
  36. attrArray[len] = {attrType, attrVal, EquipLogicGrid.EQUIP_COLOR_3}
  37. end
  38. return attrArray
  39. end
  40. -- 随出单条洗练属性的品质 和 倍数
  41. local function randAttrValMul()
  42. local totalWeight = 0
  43. for _, weight in ipairs(EquipLogicGrid.EQUIPWASH_COLOR_WEIGHT) do
  44. totalWeight = totalWeight + weight
  45. end
  46. local color = 0
  47. local mul = 0
  48. local randNum = math.random(1, totalWeight)
  49. local weight = 0
  50. for k, v in ipairs(EquipLogicGrid.EQUIPWASH_COLOR_WEIGHT) do
  51. weight = weight + v
  52. if randNum <= weight then
  53. color = k
  54. break
  55. end
  56. end
  57. assert(color > 0, "============装备洗练配置错误===============")
  58. local mulTbl = EquipLogicGrid.EQUIPWASH_COLOR_MUL[color]
  59. mul = math.random(mulTbl[1], mulTbl[2]) / 100
  60. return color, mul
  61. end
  62. -- 随机装备品质
  63. local function randColor(randomAttrCfg)
  64. local color = 0
  65. local random = math.random(1, EQUIP_QUALITY_WEIGHT)
  66. for i = 1, #EQUIP_QUALITY do
  67. local weight = EQUIP_QUALITY[i]
  68. if random <= weight then
  69. color = i > #randomAttrCfg and #randomAttrCfg or i
  70. break
  71. else
  72. random = random - weight
  73. end
  74. end
  75. return color
  76. end
  77. -- 随机出装备洗练属性
  78. local function randAttrArray(randomAttrCfg, equipColor)
  79. --品质
  80. equipColor = equipColor or randColor(randomAttrCfg)
  81. -- 计算总权重
  82. local totalWeight = 0
  83. for k, v in pairs(randomAttrCfg) do
  84. totalWeight = totalWeight + v[3]
  85. end
  86. local len = 0
  87. local attr = {}
  88. local MathRandom = math.random
  89. -- for i = 1, equipColor do
  90. -- local weight = 0
  91. -- local randmWeight = MathRandom(1, totalWeight)
  92. -- for _, v in ipairs(randomAttrCfg) do
  93. -- weight = weight + v[3]
  94. -- if randmWeight <= weight then
  95. -- len = len + 1
  96. -- local attrColor, mul = randAttrValMul()
  97. -- local finalVal = math.floor(v[2] * mul)
  98. -- attr[len] = {v[1], finalVal, attrColor}
  99. -- break
  100. -- end
  101. -- end
  102. -- end
  103. for z = 1, equipColor do
  104. local randmWeight = MathRandom(1, totalWeight)
  105. for k, v in pairs(randomAttrCfg) do
  106. local key = v[1]
  107. local value = v[2]
  108. local weight = v[3]
  109. if randmWeight <= weight then
  110. len = len + 1
  111. local attrColor, mul = randAttrValMul()
  112. local finalVal = math.floor(value * mul)
  113. attr[len] = {key, finalVal, attrColor}
  114. randomAttrCfg[k] = nil
  115. -- 排除这个权重
  116. totalWeight = totalWeight - weight
  117. break
  118. else
  119. randmWeight = randmWeight - weight
  120. end
  121. end
  122. end
  123. return attr
  124. end
  125. -- 随机属性
  126. local attrCheck = {}
  127. function checkAttr(equipGrid)
  128. local quality = equipGrid.quality
  129. local len = 0
  130. -- for key, value in pairs(equipGrid.attr) do
  131. -- len = len + 1
  132. -- attrCheck[len] = {key, value}
  133. -- end
  134. for k, v in ipairs(equipGrid.attr) do
  135. len = len + 1
  136. attrCheck[len] = {v[1], v[2], v[3]}
  137. end
  138. -- 砍掉后面的
  139. if quality < len then
  140. equipGrid.attr = {}
  141. for z = 1, quality do
  142. -- equipGrid.attr[attrCheck[z][1]] = attrCheck[z][2]
  143. equipGrid.attr[z] = {
  144. attrCheck[z][1],
  145. attrCheck[z][2],
  146. attrCheck[z][3],
  147. }
  148. end
  149. end
  150. end
  151. -- 随机属性
  152. function randomAttr(itemID, isRandom, otherData)
  153. local equipConfig = EquipExcel[itemID]
  154. if not equipConfig then return end
  155. -- 固定属性
  156. local quality = 1
  157. -- local attr = {}
  158. -- 所有装备的随机属性使用同一套规则
  159. -- if equipConfig.random == 1 and not isRandom then
  160. -- quality = #equipConfig.randomAttr
  161. -- if quality > EQUIP_QUALITY_MAX then
  162. -- quality = EQUIP_QUALITY_MAX
  163. -- end
  164. -- for i = 1, quality do
  165. -- local key = equipConfig.randomAttr[i][1]
  166. -- local value = equipConfig.randomAttr[i][2]
  167. -- attr[key] = attr[key] or 0
  168. -- attr[key] = attr[key] + value
  169. -- end
  170. -- return attr, quality
  171. -- end
  172. if not otherData then
  173. -- 随机品质
  174. quality = randColor(equipConfig.randomAttr)
  175. else
  176. if type(otherData) == "number" then
  177. otherData = otherData < 0 and 1 or otherData
  178. quality = otherData > #equipConfig.randomAttr and #equipConfig.randomAttr or otherData
  179. end
  180. end
  181. if quality > EQUIP_QUALITY_MAX then
  182. quality = EQUIP_QUALITY_MAX
  183. end
  184. -- 计算总权重
  185. -- local totalWeight = 0
  186. -- for k, v in pairs(equipConfig.randomAttr) do
  187. -- totalWeight = totalWeight + v[3]
  188. -- end
  189. -- 随机条目属性
  190. -- local MathRandom = math.random
  191. local randomAttr = Util.copyTable(equipConfig.randomAttr)
  192. -- for z = 1, quality do
  193. -- local randmWeight = MathRandom(1, totalWeight)
  194. -- for k, v in pairs(randomAttr) do
  195. -- local key = v[1]
  196. -- local value = v[2]
  197. -- local weight = v[3]
  198. -- if randmWeight <= weight then
  199. -- attr[key] = attr[key] or 0
  200. -- attr[key] = attr[key] + value
  201. -- randomAttr[k] = nil
  202. -- -- 排除这个权重
  203. -- totalWeight = totalWeight - weight
  204. -- break
  205. -- else
  206. -- randmWeight = randmWeight - weight
  207. -- end
  208. -- end
  209. -- end
  210. local attr = randAttrArray(randomAttr, quality)
  211. return attr, quality
  212. end
  213. -- 检查背包空间
  214. function checkEmptyCnt(human, itemCnt)
  215. if itemCnt > getEmptyCnt(human) then
  216. Broadcast.sendErr(human, Lang.COMMON_BAG_FULL)
  217. return
  218. end
  219. return true
  220. end
  221. -- 获取装备对基础属性的影响
  222. function getEquipBaseRate(quality)
  223. local baseRate = EQUIP_QUALITY_BASE_RATE[quality]
  224. if not baseRate then return 1 end
  225. return baseRate / 10000
  226. end
  227. -- 获取装备品质
  228. function getEquipMaxQuality(equipConfig)
  229. if not equipConfig.randomAttr then return 0 end
  230. local maxQuality = 0
  231. if equipConfig.random == 1 then
  232. maxQuality = #equipConfig.randomAttr
  233. end
  234. return maxQuality
  235. end
  236. -- 获取装备附加属性
  237. function getEquipTzAttr(equipConfig)
  238. -- if not equipConfig.randomAttr then return end
  239. -- if equipConfig.random == 1 then
  240. -- return equipConfig.randomAttr
  241. -- end
  242. local attr = randAttrArray(Util.copyTable(equipConfig.randomAttr))
  243. return attr
  244. end
  245. -- 返回装备背包空余格子数
  246. function getEmptyCnt(human)
  247. local emptyCnt = 0
  248. for i = 1, EQUIP_BAG_MAX_CNT do
  249. if human.db.equipBag[i] == nil then
  250. emptyCnt = emptyCnt + 1
  251. end
  252. end
  253. return emptyCnt
  254. end
  255. -- 获得装备背包第一个空格子下标
  256. function getEmptyIndex(human)
  257. for index = 1, EQUIP_BAG_MAX_CNT do
  258. local grid = human.db.equipBag[index]
  259. if grid == nil then
  260. return index
  261. end
  262. end
  263. end
  264. -- 返回装备根据uuid
  265. function getEquipByUuid(human, uuid)
  266. local emptyCnt = 0
  267. for i = 1, EQUIP_BAG_MAX_CNT do
  268. local equipGrid = human.db.equipBag[i]
  269. if equipGrid and equipGrid.uuid == uuid then
  270. return equipGrid
  271. end
  272. end
  273. end
  274. -- 返回装备根据pos
  275. function getEquipByPos(human, star, pos)
  276. local emptyCnt = 0
  277. for i = 1, EQUIP_BAG_MAX_CNT do
  278. local equipGrid = human.db.equipBag[i]
  279. if equipGrid then
  280. local conf = EquipExcel[equipGrid.id]
  281. if conf and conf.subType == pos and star >= conf.star then
  282. return equipGrid
  283. end
  284. end
  285. end
  286. end
  287. -- 修复老数据
  288. function modifyEquip(human, equipGrid)
  289. if equipGrid.putUuid == nil then return end
  290. local heroGrid = HeroLogic.getHeroGridByUuid(human, equipGrid.putUuid)
  291. if heroGrid == nil then
  292. equipGrid.putUuid = nil
  293. end
  294. end
  295. -- 兼容老数据处理 : 修改装备的 wash 和 attr 的数据格式
  296. function TransformEuipAttrData(human)
  297. for index = 1, EQUIP_BAG_MAX_CNT do
  298. local equipGrid = human.db.equipBag[index]
  299. if equipGrid then
  300. if equipGrid.attr then
  301. equipGrid.attr = AttrHashToArray(equipGrid.attr)
  302. end
  303. if equipGrid.washAttr then
  304. equipGrid.washAttr = AttrHashToArray(equipGrid.washAttr)
  305. end
  306. end
  307. end
  308. end
  309. -- 推送装备背包信息
  310. function sendEquipBagList(human)
  311. local msgRet = Msg.gc.GC_EQUIP_BAG_LIST
  312. local len = 0
  313. for index = 1, EQUIP_BAG_MAX_CNT do
  314. local equipGrid = human.db.equipBag[index]
  315. if equipGrid then
  316. len = len + 1
  317. Grid.makeItem(msgRet.list[len], equipGrid.id, 1, nil, equipGrid, index, Grid.getOpflagAtBag(equipGrid.id))
  318. if len >= 30 then
  319. msgRet.list[0] = len
  320. len = 0
  321. Msg.send(msgRet, human.fd)
  322. end
  323. end
  324. end
  325. if len > 0 then
  326. msgRet.list[0] = len
  327. Msg.send(msgRet, human.fd)
  328. end
  329. end
  330. -- 制造一个获得列表
  331. function makeEquipItem(human, nets, len)
  332. if not human.getEquip then return len end
  333. for i = 1, #human.getEquip do
  334. len = len + 1
  335. if not nets[len] then
  336. len = len - 1
  337. break
  338. end
  339. local equipGrid = human.getEquip[i]
  340. Grid.makeItem(nets[len], equipGrid.id, 1, nil, equipGrid)
  341. end
  342. human.getEquip = nil
  343. return len
  344. end
  345. -- 制造一个装备获得
  346. function makeEquipItemOne(human, net)
  347. if not human.getEquip then return end
  348. local equipGrid = human.getEquip[1]
  349. Grid.makeItem(net, equipGrid.id, 1, nil, equipGrid)
  350. human.getEquip = nil
  351. end
  352. -- 制造一个装备
  353. function makeEquip(itemID, otherData)
  354. local equipGrid = EquipLogicGrid.createGrid(itemID)
  355. if not equipGrid then return end
  356. -- 随机属性
  357. local attr, quality = randomAttr(itemID, nil, otherData)
  358. equipGrid.attr = attr
  359. equipGrid.quality = quality
  360. checkAttr(equipGrid)
  361. return equipGrid
  362. end
  363. -- 添加装备
  364. function addEquip(human, itemID, itemCnt, logType, otherData)
  365. if not EquipExcel[itemID] then return end
  366. for i = 1, itemCnt do
  367. local equipGrid = makeEquip(itemID, otherData)
  368. if equipGrid then
  369. addByEquipGrid(human, equipGrid, logType)
  370. TriggerLogic.PublishEvent(TriggerDefine.EQUIP_GETQUALITY, human.db._id, equipGrid.quality, 1)
  371. end
  372. end
  373. end
  374. -- 通过gird添加装备
  375. function addByEquipGrid(human, equipGrid, logType, noSend)
  376. local index = getEmptyIndex(human)
  377. if not index then
  378. --邮件处理
  379. local items = {}
  380. items[1] = { equipGrid.id, equipGrid }
  381. local title = MailExcel.mail[1000].title
  382. local content = MailExcel.mail[1000].content
  383. local senderName = MailExcel.mail[1000].senderName
  384. MailManager.add(MailManager.SYSTEM, human.db._id, title, content, items, senderName)
  385. return
  386. end
  387. human.db.equipBag[index] = equipGrid
  388. sendEquipChange(human, index, equipGrid, EQUIP_BAG_OP_ADD)
  389. Log.write(Log.LOGID_OSS_EQUIP, human.db._id, human.db.account,
  390. human.db.name, human.db.lv, LogDefine.DEFINE[logType] + LogDefine.TYPE["equip"], equipGrid.id, 1, equipGrid.uuid)
  391. if not noSend then
  392. human.getEquip = human.getEquip or {}
  393. human.getEquip[#human.getEquip + 1] = equipGrid
  394. end
  395. return index
  396. end
  397. -- 从背包删除装备
  398. function delEquip(human, index, logType, sendNotify)
  399. local equipGrid = human.db.equipBag[index]
  400. if not equipGrid then return end
  401. Log.write(Log.LOGID_OSS_EQUIP, human.db._id, human.db.account,
  402. human.db.name, human.db.lv, LogDefine.DEFINE[logType] + LogDefine.TYPE["equip"], equipGrid.id, -1, equipGrid.uuid)
  403. human.db.equipBag[index] = nil
  404. if not sendNotify then
  405. sendEquipChange(human, index, nil, EQUIP_BAG_OP_DEL)
  406. end
  407. end
  408. -- 发送装备改变
  409. function sendEquipChange(human, bagIndex, equipGrid, op)
  410. local msgRet = Msg.gc.GC_EQUIP_BAG_CHANGE
  411. if op == EQUIP_BAG_OP_ADD or op == EQUIP_BAG_OP_CHANGE then
  412. msgRet.itemID = equipGrid.id
  413. msgRet.itemIndex = bagIndex
  414. msgRet.itemData[0] = 1
  415. Grid.makeItem(msgRet.itemData[1], equipGrid.id, 1, nil, equipGrid, bagIndex, Grid.getOpflagAtBag(equipGrid.id))
  416. elseif op == EQUIP_BAG_OP_DEL then
  417. msgRet.itemID = 0
  418. msgRet.itemIndex = bagIndex
  419. msgRet.itemData[0] = 0
  420. else
  421. assert(nil)
  422. end
  423. Msg.send(msgRet, human.fd)
  424. end
  425. function getNewAttrByItemID(itemID, equipGrid)
  426. local config = EquipExcel[itemID]
  427. -- if not config then return end
  428. -- for _, v in ipairs(config.randomAttr) do
  429. -- if attr[v[1]] then
  430. -- attr[v[1]] = v[2]
  431. -- end
  432. -- end
  433. equipGrid.attr = randAttrArray(Util.copyTable(config.randomAttr), equipGrid.quality)
  434. end