EquipOverlay.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. ---
  2. --- Created by zhouzhipeng.
  3. --- DateTime: 2024/8/26 上午11:13
  4. ---
  5. EquipOverlay = {}
  6. local this = {}
  7. --- 请求装备叠加
  8. function EquipOverlay.reqEquipOverlay(actor, msgData)
  9. EquipOverlay.print("reqEquipOverlay actor:" .. actor:toString() .. "装备叠加开始:\n", msgData)
  10. local firstItemId = msgData["firstItemId"]
  11. local secondItemId = msgData["secondItemId"]
  12. local costItem = msgData["costItem"]
  13. local lockEntryIds = msgData["lockEntryIds"]
  14. local firstEquip = getequipinfo(actor, firstItemId, 1)
  15. if table.isNullOrEmpty(firstEquip) then
  16. noticeTip.noticeinfo(actor, StringIdConst.TEXT394)
  17. return
  18. end
  19. local secondEquip = getequipinfo(actor, secondItemId, 1)
  20. if table.isNullOrEmpty(secondEquip) then
  21. noticeTip.noticeinfo(actor, StringIdConst.TEXT395)
  22. return
  23. end
  24. local firstItemCfgId = firstEquip.cfgid
  25. if firstItemCfgId ~= secondEquip.cfgid then
  26. noticeTip.noticeinfo(actor, StringIdConst.TEXT396)
  27. return
  28. end
  29. local firstEntries = firstEquip.entries
  30. local secondEntries = secondEquip.entries
  31. local firstCount = table.count(firstEntries)
  32. if firstCount == 0 or table.count(secondEntries) == 0 then
  33. noticeTip.noticeinfo(actor, StringIdConst.TEXT397)
  34. return
  35. end
  36. -- 主装备词条 用于遍历
  37. local firstEntryIds = {}
  38. for _, v in pairs(firstEntries) do
  39. table.insert(firstEntryIds, v.entryid)
  40. end
  41. -- 副装备中需要有与主装备不同词条才能进行叠加
  42. -- 主装备未拥有的词条
  43. local entryTable = {}
  44. for _, v in pairs(secondEntries) do
  45. if not table.contains(firstEntryIds, v.entryid) then
  46. table.insert(entryTable, v)
  47. end
  48. end
  49. if table.isNullOrEmpty(entryTable) then
  50. EquipOverlay.print("reqEquipOverlay actor:" .. actor:toString() .. "副装备的词条主装备都已拥有:\n", "主装备词条", firstEntries, "副装备词条", secondEntries, "主词条", firstEntryIds, "主装备未拥有的词条", entryTable)
  51. noticeTip.noticeinfo(actor, StringIdConst.TEXT398)
  52. return
  53. end
  54. local overlayList = ConfigDataManager.getTable("cfg_equip_overlay", "id", firstItemCfgId)
  55. if table.isNullOrEmpty(overlayList) then
  56. noticeTip.noticeinfo(actor, StringIdConst.TEXT399)
  57. return
  58. end
  59. local grade = firstEquip.grade
  60. local maxEntry = ConfigDataManager.getTableValue("cfg_equip_quality", "maximums", "id", grade)
  61. if string.isNullOrEmpty(maxEntry) then
  62. noticeTip.noticeinfo(actor, StringIdConst.TEXT400)
  63. return
  64. end
  65. local lockEntryCount = table.count(lockEntryIds)
  66. if lockEntryCount >= tonumber(maxEntry) then
  67. noticeTip.noticeinfo(actor, StringIdConst.TEXT401)
  68. return
  69. end
  70. local overlayCfg = overlayList[1]
  71. EquipOverlay.print("reqEquipOverlay actor:" .. actor:toString() .. "装备叠加cfg_equip_overlay表配置:\n", overlayCfg)
  72. -- 校验消耗 cost
  73. local cost = overlayCfg.cost
  74. local costTable = string.toIntIntMap(cost, "#", "|")
  75. if table.isNullOrEmpty(costTable) then
  76. noticeTip.noticeinfo(actor, StringIdConst.TEXT402)
  77. return
  78. end
  79. for k, v in pairs(costTable) do
  80. local itemId = tonumber(k)
  81. local count = tonumber(v)
  82. if this.checkCost(actor, itemId, count) then
  83. return
  84. end
  85. end
  86. -- 计算额外成功率
  87. local costItemCfg = overlayCfg.costitem
  88. local costItemTable = string.toIntIntMap(costItemCfg, "#", "|")
  89. if table.count(costItem) > 0 then
  90. for _, value in pairs(costItem) do
  91. local itemCfgId = value.itemCfgId
  92. local count = value.count
  93. for k, _ in pairs(costItemTable) do
  94. if itemCfgId ~= tonumber(k) then
  95. --EquipOverlay.print("reqEquipOverlay actor:" .. actor:toString() .. ",itemCfgId:" .. type(itemCfgId) .. itemCfgId .. ",count:" .. count .. ",配置表的itemCfgId:" .. type(k) .. k .. ",配置表的count:" .. type(count) .. count .. ",装备叠加cfg_equip_overlay表配置:\n", costItemTable)
  96. noticeTip.noticeinfo(actor, StringIdConst.TEXT403)
  97. return
  98. end
  99. end
  100. if this.checkCost(actor, itemCfgId, count) then
  101. return
  102. end
  103. end
  104. end
  105. -- 校验锁定词条消耗
  106. if lockEntryCount > 0 then
  107. local lockCost = overlayCfg.lockcost
  108. local lockCostShuXian = string.split(lockCost, "|")
  109. if table.count(lockCostShuXian) < lockEntryCount then
  110. noticeTip.noticeinfo(actor, StringIdConst.TEXT404)
  111. return
  112. end
  113. for i = 1, lockEntryCount do
  114. local value = lockCostShuXian[i]
  115. local lockCostJinHao = string.split(value, "#")
  116. local itemId = tonumber(lockCostJinHao[1])
  117. local count = tonumber(lockCostJinHao[2])
  118. if this.checkCost(actor, itemId, count) then
  119. return
  120. end
  121. end
  122. end
  123. -- 扣除消耗
  124. for itemCfgId, count in pairs(costTable) do
  125. removeitemfrombag(actor, itemCfgId, count,0,9999,'装备叠加')
  126. end
  127. -- 额外成功率
  128. local extraRate = 0
  129. for _, value in pairs(costItem) do
  130. local itemCfgId = value.itemCfgId
  131. local count = value.count
  132. local rate = costItemTable[tonumber(itemCfgId)]
  133. --EquipOverlay.print("reqEquipOverlay actor:" .. actor:toString() .. ",itemCfgId:" .. type(itemCfgId) .. itemCfgId .. ",count:" .. count .. ",rate:" .. tostring(rate) .. ",装备叠加cfg_equip_overlay表配置:\n", costItemTable)
  134. local addRate = rate * count
  135. extraRate = extraRate + addRate
  136. removeitemfrombag(actor, itemCfgId, count,0,9999,'装备叠加')
  137. end
  138. if lockEntryCount > 0 then
  139. local lockCost = overlayCfg.lockcost
  140. local lockCostShuXian = string.split(lockCost, "|")
  141. -- local lockCostTable = strtomap(lockCost, "#", "|")
  142. for i = 1, lockEntryCount do
  143. local value = lockCostShuXian[i]
  144. local lockCostJinHao = string.split(value, "#")
  145. local itemId = tonumber(lockCostJinHao[1])
  146. local count = tonumber(lockCostJinHao[2])
  147. removeitemfrombag(actor, itemId, count,0,9999,'装备叠加')
  148. end
  149. end
  150. -- 销毁副装备
  151. local equipindex = secondEquip.equipindex
  152. if equipindex ~= 0 then
  153. -- todo 脱装要触发属性计算
  154. -- 脱装 传穿戴拦索引
  155. takeofftheequip(actor, equipindex)
  156. -- 根据唯一id找背包索引
  157. local bagIdx = gainbagidxbyitemid(actor, secondEquip.id)
  158. -- 通过背包索引删除该道具
  159. removeitembyidxlist(actor, { bagIdx },9999,'装备叠加')
  160. EquipOverlay.print("reqEquipOverlay actor:" .. actor:toString() .. "装备叠加 从穿戴拦装备删除:\n")
  161. else
  162. -- 通过背包索引删除该道具
  163. local bagIdx = gainbagidxbyitemid(actor, secondEquip.id)
  164. removeitembyidxlist(actor, { bagIdx },9999,'装备叠加')
  165. EquipOverlay.print("reqEquipOverlay actor:" .. actor:toString() .. "装备叠加 从背包删除:\n")
  166. end
  167. -- 叠加成功率成功率
  168. local minRate = tonumber(overlayCfg.minrate)
  169. local maxRate = tonumber(overlayCfg.maxrate)
  170. local rate = math.min(minRate + extraRate, maxRate)
  171. local randomNumber = math.random(1, 10000)
  172. if rate < randomNumber then
  173. -- 失败
  174. tipinfo(actor, "叠加失败")
  175. sendluamsg(actor, LuaMessageIdToClient.RES_EQUIP_OVERLAY, { result = 0 })
  176. return
  177. end
  178. -- 成功 进行叠加
  179. -- 随机副装备差异词条
  180. local entry = table.count(entryTable)
  181. local number = math.random(1, entry)
  182. local newEntry = entryTable[number]
  183. local currEntrys = {}
  184. local newRate = overlayCfg.rate
  185. local newEntryRate = 0
  186. if table.count(firstEntryIds) < tonumber(maxEntry) then
  187. -- 主装备存在空词条位,从消耗装备的卓越属性中和主装备词条不同的随机一条卓越属性,填充至主装备的空词条
  188. -- 新增词条概率
  189. newEntryRate = math.random(1, 10000)
  190. if tonumber(newRate) < newEntryRate then
  191. -- 替换词条 重置词条
  192. this.resetEntry(actor, firstEquip.id, firstEntries, lockEntryIds, newEntry, currEntrys)
  193. else
  194. -- 添加词条
  195. addequipentry(actor, firstEquip.id, newEntry)
  196. for _, entryInfo in ipairs(firstEntries) do
  197. this.buildEntry(currEntrys, entryInfo)
  198. end
  199. this.buildEntry(currEntrys, newEntry)
  200. end
  201. else
  202. -- 主装备不存在空词条位,从消耗装备的卓越属性中和主装备词条不同的随机一条卓越属性,随机替换主词条的一条未锁定的词条
  203. -- 重置词条
  204. this.resetEntry(actor, firstEquip.id, firstEntries, lockEntryIds, newEntry, currEntrys)
  205. --local max = firstCount - lockEntryCount
  206. --local number = math.random(1, max)
  207. --
  208. --local entrys = {}
  209. --local num = 1
  210. --for i, entry in ipairs(firstEntries) do
  211. -- if table.contains(lockEntryIds, entry.entryid) then
  212. -- table.insert(entrys, entry)
  213. -- else
  214. -- if num == number then
  215. -- table.insert(entrys, newEntry)
  216. -- else
  217. -- table.insert(entrys, entry)
  218. -- end
  219. -- num = num + 1
  220. -- end
  221. --end
  222. --for _, entry in ipairs(entrys) do
  223. -- this.buildEntry(currEntrys, entry)
  224. --end
  225. --resetequipentry(actor, firstEquip.id, entrys)
  226. end
  227. sendluamsg(actor, LuaMessageIdToClient.RES_EQUIP_OVERLAY, { result = 1, firstEntries = currEntrys })
  228. EquipOverlay.print("reqEquipOverlay actor:" .. actor:toString() .. "装备叠加结束信息:\n", "主装备词条数据:", firstEntries, "副装备词条数据:", secondEntries, "主装备未拥有的词条:"
  229. , entryTable, "主装备拥有的词条", firstEntryIds, "额外成功率:", extraRate, "总成功率", tostring(rate), "成功率随机结果:", randomNumber, "随机到的未拥有的第几条", number
  230. , "主装备最大配置词条", maxEntry, "当前词条数据:", currEntrys, ",新增词条概率:", newRate, ",新增词条随机结果(为0未词条没有空位):",newEntryRate)
  231. ---更新最大词条记录
  232. EquipAndAppear.TryUpdateEquipInfoRecorde(actor, EquipAndAppear.RecordeType.MAX_ENTRY_COUNT)
  233. -- 更新任务进度
  234. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.EQUIP_SUPERPOSITION, firstItemCfgId)
  235. TaskHandler.TriggerTaskGoal(actor, TaskTargetType. EXCELLENCE_ATTR)
  236. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.EQUIP_EXCELLENCE_ATTR_COUNT)
  237. end
  238. function this.buildEntry(currEntrys, entry)
  239. local entry1 = {}
  240. entry1.entryId = entry.entryid
  241. entry1.type = entry.attrid
  242. entry1.num = entry.value
  243. table.insert(currEntrys, entry1)
  244. end
  245. function this.checkCost(actor, itemId, count)
  246. local bagCount = getbagitemcountbyid(actor, itemId)
  247. if bagCount < count then
  248. noticeTip.noticeinfo(actor, StringIdConst.TEXT253)
  249. return true
  250. end
  251. return false
  252. end
  253. function this.resetEntry(actor, firstEquipId, firstEntries, lockEntryIds, newEntry, currEntrys)
  254. local firstCount = table.count(firstEntries)
  255. local lockEntryCount = table.count(lockEntryIds)
  256. local max = firstCount - lockEntryCount
  257. local number = math.random(1, max)
  258. local entrys = {}
  259. local num = 1
  260. for i, entry in ipairs(firstEntries) do
  261. if table.contains(lockEntryIds, entry.entryid) then
  262. table.insert(entrys, entry)
  263. else
  264. if num == number then
  265. table.insert(entrys, newEntry)
  266. else
  267. table.insert(entrys, entry)
  268. end
  269. num = num + 1
  270. end
  271. end
  272. for _, entry in ipairs(entrys) do
  273. this.buildEntry(currEntrys, entry)
  274. end
  275. resetequipentry(actor, firstEquipId, entrys)
  276. end
  277. -----------------------------------------------------------测试方法-------------------------------------------------------------
  278. --- 打印日志
  279. function EquipOverlay.print(...)
  280. local isPrintLog = true
  281. if isPrintLog then
  282. return
  283. end
  284. jprint(...)
  285. end
  286. --- 测试方法
  287. function equipoverlaytest(actor)
  288. jprint("equipoverlaytest actor:" ..actor:toString() .. ", equipoverlaytest 开始")
  289. local bebaoshuju = getallequipinfo(actor)
  290. sendluamsg(actor, 999999, { bebaoshuju = bebaoshuju })
  291. --local overlayList1 = ConfigDataManager.getTable("cfg_equip_overlay", "id", 99)
  292. --jprint(overlayList1)
  293. --if string.isNullOrEmpty(overlayList1) then
  294. -- jprint(tostring(overlayList1))
  295. -- jprint("nil")
  296. --end
  297. --local overlayList2 = ConfigDataManager.getTable("cfg_equip_overlay", "id", 20100003)
  298. --jprint(overlayList2)
  299. --print("hello")
  300. --jprint(getputonequipinfo(actor))
  301. jprint("equipoverlaytest actor:" .. actor:toString() .. ", equipoverlaytest 结束 ")
  302. end