AngelMajorGrail_1.lua 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849
  1. --- 大天使圣杯
  2. --- Generated by EmmyLua(https://github.com/EmmyLua)
  3. --- Created by zhoutao.
  4. --- DateTime: 2024/11/19 20:36
  5. AngelMajorGrail = {}
  6. local this = AngelMajorGrail
  7. this.RedId = 102
  8. this.canWorshipRedId = 107
  9. --- 获取所有圣杯词条信息
  10. --- @param actor table 角色对象
  11. --- @param isInlaid boolean 是否镶嵌
  12. function AngelMajorGrail.sendGrailInfo(actor, isInlaid)
  13. local grailIds = AngelMajorGrail.getInlaidGrailIds(actor)
  14. local allGrailInfo = this.getAllGrailInfo(actor)
  15. local res = {}
  16. if not table.isNullOrEmpty(allGrailInfo) then
  17. for grailId, entry in pairs(allGrailInfo) do
  18. if not table.isNullOrEmpty(entry) then
  19. if not table.hasKey(entry, "score") then
  20. entry = this.calcGrailScore(entry)
  21. end
  22. if table.contains(grailIds, grailId) then
  23. entry["active"] = true
  24. if isInlaid then
  25. res[grailId] = entry
  26. end
  27. else
  28. if not isInlaid then
  29. res[grailId] = entry
  30. end
  31. end
  32. end
  33. end
  34. end
  35. sendluamsg(actor, LuaMessageIdToClient.RES_ALL_GRAIL_INFO, res)
  36. end
  37. -- 判断单个圣杯是否激活
  38. function this.isActiveGrail(actor, grailId)
  39. local grailIds = AngelMajorGrail.getInlaidGrailIds(actor)
  40. return table.contains(grailIds, grailId)
  41. end
  42. --- 获取装备下镶嵌的圣杯词条信息
  43. --- @param actor table 角色对象
  44. --- @param equipId number 装备id
  45. --- @param itemId number 圣杯id
  46. function AngelMajorGrail.getEquipAllEntryInfo(actor, equipId, itemId)
  47. local equipAttr = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA)
  48. if table.isNullOrEmpty(equipAttr) then
  49. gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.getEquipAllEntryInfo equipAttr is nil")
  50. return
  51. end
  52. local equipInfo = equipAttr[equipId]
  53. if table.isNullOrEmpty(equipInfo) then
  54. gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.getEquipAllEntryInfo equipInfo is nil")
  55. return
  56. end
  57. local grails = equipInfo["grails"]
  58. local res = {}
  59. if not table.isNullOrEmpty(grails) then
  60. if itemId then
  61. local info = grails[itemId]
  62. local temp = this.combineRes(itemId, info, this.getGrailInfo(actor, itemId))
  63. local attrInfo = temp["attrInfo"]
  64. if attrInfo and this.isActiveGrail(actor, itemId) then
  65. attrInfo["active"] = true
  66. end
  67. table.insert(res, temp)
  68. else
  69. for grailId, info in pairs(grails) do
  70. local temp = this.combineRes(grailId, info, this.getGrailInfo(actor, grailId))
  71. local attrInfo = temp["attrInfo"]
  72. if attrInfo and this.isActiveGrail(actor, grailId) then
  73. attrInfo["active"] = true
  74. end
  75. table.insert(res, temp)
  76. end
  77. end
  78. end
  79. sendluamsg(actor, LuaMessageIdToClient.RES_EQUIP_ALL_ENTRY_INFO, res)
  80. end
  81. --- 镶嵌圣杯
  82. --- @param actor table 角色对象
  83. --- @param msgData table 消息数据
  84. function AngelMajorGrail.inlayGrail(actor, msgData)
  85. -- 装备id
  86. local equipId = msgData["equipId"]
  87. -- 装备配置id
  88. local equipConfigId = msgData["equipConfigId"]
  89. -- 圣杯id
  90. local grailId = msgData["itemId"]
  91. -- 圣杯配置id
  92. local itemConfigId = msgData["itemConfigId"]
  93. local tableValue = this.isAngelGrail(itemConfigId)
  94. if not tableValue then
  95. return
  96. end
  97. -- 圣杯在背包中的索引,因为目前没有根据唯一id删除道具的接口,所以使用索引进行删除
  98. local index = msgData["index"]
  99. -- 镶嵌孔位
  100. local position = msgData["position"]
  101. -- 判断部位是否符合镶嵌
  102. local strPart = ConfigDataManager.getTableValue("cfg_item", "strPart", "id", equipConfigId)
  103. local partSplit = string.split(strPart, "#")
  104. local grailPart = tableValue[1]["strpart"]
  105. local grailParts = string.split(grailPart, "#")
  106. local isMatch = false
  107. for _, v in pairs(partSplit) do
  108. if table.contains(grailParts, v) then
  109. isMatch = true
  110. end
  111. end
  112. if not isMatch then
  113. gameDebug.print(
  114. getbaseinfo(actor, "rolename"),
  115. " AngelMajorGrail.inlayGrail part match false equipConfigId",
  116. equipConfigId,
  117. " grailConfigId",
  118. itemConfigId
  119. )
  120. return
  121. end
  122. -- 获取装备成长属性信息
  123. local equipAttr = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA)
  124. if table.isNullOrEmpty(equipAttr) then
  125. gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail equipAttr is nil")
  126. return
  127. end
  128. local equipInfo = equipAttr[equipId]
  129. if table.isNullOrEmpty(equipInfo) then
  130. gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail equipInfo is nil")
  131. return
  132. end
  133. -- 获取圣杯词条信息
  134. local entryInfo = this.getGrailInfo(actor, grailId)
  135. -- 判断圣杯等阶是否满足融合条件
  136. local equipRank = equipInfo["rank"]
  137. if table.isNullOrEmpty(entryInfo) then
  138. gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail entryInfo is nil")
  139. return
  140. end
  141. local grailGrade = entryInfo["grailGrade"]
  142. if grailGrade > equipRank then
  143. gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail grailGrade > equipRank")
  144. return
  145. end
  146. local grails = equipInfo["grails"]
  147. if not table.isNullOrEmpty(grails) then
  148. if table.getValue(grails, grailId) then
  149. gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail equip already has this grail")
  150. return
  151. else
  152. grails[grailId] = {
  153. ["itemConfigId"] = itemConfigId,
  154. ["grailPosition"] = position,
  155. ["level"] = entryInfo["level"]
  156. }
  157. end
  158. else
  159. grails = {}
  160. grails[grailId] = {
  161. ["itemConfigId"] = itemConfigId,
  162. ["grailPosition"] = position,
  163. ["level"] = entryInfo["level"]
  164. }
  165. end
  166. equipInfo["grails"] = grails
  167. setplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA, equipAttr)
  168. entryInfo["inlaid"] = true
  169. info(actor, actor, "镶嵌圣杯后的信息", "装备id", equipId, "圣杯id", grailId)
  170. this.saveOrRemoveGrailInfo(actor, grailId, entryInfo)
  171. -- 给角色添加属性
  172. AngelMajorGrail.grailAttrHandle(actor, entryInfo, grailId, true)
  173. -- 移除背包中的圣杯
  174. removeitembyidxlist(
  175. actor,
  176. {
  177. [index] = 1
  178. },
  179. 9999,
  180. "镶嵌圣杯"
  181. )
  182. AngelMajorGrail.getEquipAllEntryInfo(actor, equipId, grailId)
  183. -- 红点判断
  184. AngelMajorGrail.sendRedPoint(actor)
  185. -- 触发任务刷新
  186. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.TAKE_ON_GRAIL_COUNT)
  187. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.STRENGTHEN_GRAIL)
  188. -- 判断是否满足大天使圣杯套装并增加属性
  189. AngelMajorGrail.checkAngelGrailSuitCondition(actor)
  190. end
  191. --- 卸下圣杯
  192. --- @param actor table 角色对象
  193. --- @param msgData table 消息数据
  194. function AngelMajorGrail.unloadGrail(actor, msgData)
  195. -- 装备id
  196. local equipId = msgData["equipId"]
  197. -- 圣杯id
  198. local grailId = msgData["itemId"]
  199. local entryInfo = this.getGrailInfo(actor, grailId)
  200. if table.isNullOrEmpty(entryInfo) then
  201. error("grailId error")
  202. return
  203. end
  204. -- 道具配置id
  205. local itemConfigId = msgData["itemConfigId"]
  206. -- 判断背包是否能放得下,放不下不能卸并提示
  207. local paramMap = {}
  208. paramMap["cfgid"] = itemConfigId
  209. paramMap["itemcount"] = 1
  210. local param = {paramMap}
  211. local canPut = checkitemscanputbag(actor, param)
  212. if tonumber(canPut) == 0 then
  213. noticeTip.noticeinfo(actor, StringIdConst.TEXT29001)
  214. return
  215. end
  216. -- 去除装备属性中的指定圣杯信息
  217. local equipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA)
  218. if not table.isNullOrEmpty(equipInfo) then
  219. local equipAttr = equipInfo[equipId]
  220. if not table.isNullOrEmpty(equipAttr) then
  221. local grails = equipAttr["grails"] or {}
  222. if not table.hasKey(grails, grailId) then
  223. tipinfo(actor, "该装备下没有该圣杯")
  224. info(actor, actor, "该装备下没有该圣杯" .. " 装备id:" .. equipId .. " 圣杯id:" .. grailId)
  225. return
  226. end
  227. grails[grailId] = nil
  228. setplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA, equipInfo)
  229. end
  230. end
  231. -- 生成道具放入背包
  232. local itemId = Bag.addItemToBag(actor, itemConfigId, 1, 0, 9999, ItemAction.ANGEL_GRAIL_UNLOAD)
  233. if not itemId or tonumber(itemId) <= 0 then
  234. gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.unloadGrail additemtobag failed")
  235. return
  236. end
  237. entryInfo["inlaid"] = false
  238. entryInfo["active"] = false
  239. this.saveOrRemoveGrailInfo(actor, grailId)
  240. this.saveOrRemoveGrailInfo(actor, itemId, entryInfo)
  241. -- 移除之前增加的属性
  242. AngelMajorGrail.grailAttrHandle(actor, entryInfo, grailId, false)
  243. -- 响应客户端镶嵌的圣杯信息
  244. AngelMajorGrail.getEquipAllEntryInfo(actor, equipId)
  245. -- 响应圣杯信息
  246. sendluamsg(
  247. actor,
  248. LuaMessageIdToClient.RES_GRAIL_ENTRY_INFO,
  249. {
  250. [itemId] = entryInfo and entryInfo or {}
  251. }
  252. )
  253. -- 红点判断
  254. AngelMajorGrail.sendRedPoint(actor)
  255. -- 触发任务刷新
  256. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.TAKE_ON_GRAIL_COUNT)
  257. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.STRENGTHEN_GRAIL)
  258. -- 判断是否满足大天使圣杯套装并增加属性
  259. AngelMajorGrail.checkAngelGrailSuitCondition(actor)
  260. end
  261. --- 强化圣杯词条
  262. --- @param actor table 角色对象
  263. --- @param msgData table 消息数据
  264. function AngelMajorGrail.strengthenGrail(actor, msgData)
  265. -- 圣杯id
  266. local grailId = msgData["itemId"]
  267. -- 道具配置id
  268. local itemConfigId = msgData["itemConfigId"]
  269. -- 获取道具对应的强化组
  270. local strengthenGroup =
  271. ConfigDataManager.getTableValue("cfg_equip_angelStrengthen", "costGroup", "id", itemConfigId)
  272. -- 获取当前圣杯的等级
  273. local entryInfo = this.getGrailInfo(actor, grailId)
  274. if not table.isNullOrEmpty(entryInfo) then
  275. local grailLevel = entryInfo["level"]
  276. local tableValue =
  277. ConfigDataManager.getTable(
  278. "cfg_equip_angelStrengthenCost",
  279. "AngelstrengthenGroup",
  280. strengthenGroup,
  281. "AngelstrengthenLv",
  282. grailLevel
  283. )
  284. if table.isNullOrEmpty(tableValue) then
  285. gameDebug.print(
  286. getbaseinfo(actor, "rolename"),
  287. " AngelMajorGrail.strengthenGrail cfg_equip_angelStrengthenCost is nil"
  288. )
  289. return
  290. end
  291. -- 强化消耗材料充足判断
  292. local strengthenCost = tableValue[1]["angelstrengthencost"]
  293. local costMap = string.toIntIntMap(strengthenCost, "#", "|")
  294. local enough = Bag.checkCostMap(actor, costMap)
  295. if not enough then
  296. noticeTip.noticeinfo(actor, StringIdConst.TEXT351)
  297. return
  298. end
  299. -- 具体强化逻辑
  300. -- 消耗道具
  301. for cfgId, count in pairs(costMap) do
  302. Bag.cost(actor, cfgId, count, ItemAction.ANGEL_GRAIL_STRENGTHEN_COST)
  303. end
  304. -- 强化成功率
  305. local successRate = tableValue[1]["angelstrengthensuccessrate"]
  306. local success = math.random(1, 100) <= (tonumber(successRate) and tonumber(successRate) or 0)
  307. if success then
  308. -- 获取主副词条信息
  309. local mainEntry = entryInfo["main"]
  310. local secondaryEntry = entryInfo["secondary"]
  311. -- 主词条强化
  312. for _, entry in pairs(mainEntry) do
  313. if not entry["isMax"] then
  314. this.strengthen(entry)
  315. end
  316. end
  317. -- 副词条强化
  318. local entryWeightMap = {}
  319. for _, v in pairs(secondaryEntry) do
  320. for _, entry in pairs(v) do
  321. if not entry["isMax"] then
  322. entryWeightMap[entry] = entry["weight"]
  323. end
  324. end
  325. end
  326. -- 根据权重选择一条词条强化
  327. if not table.isNullOrEmpty(entryWeightMap) then
  328. local entry = randombyweight(entryWeightMap, 1, false)[1]
  329. this.strengthen(entry)
  330. -- 保存强化后的词条信息
  331. for k1, v in pairs(secondaryEntry) do
  332. for k2, value in pairs(v) do
  333. if value["id"] == entry["id"] then
  334. secondaryEntry[k1][k2] = entry
  335. end
  336. end
  337. end
  338. entryInfo["level"] = grailLevel + 1
  339. end
  340. entryInfo = this.calcGrailScore(entryInfo)
  341. -- 先去除属性再增加属性
  342. AngelMajorGrail.grailAttrHandle(actor, entryInfo, grailId, false)
  343. AngelMajorGrail.grailAttrHandle(actor, entryInfo, grailId, true)
  344. sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_ENTRY_STRENGTHEN_RESULT, success)
  345. if this.isActiveGrail(actor, grailId) then
  346. -- 正常这里应该是激活的
  347. entryInfo["active"] = true
  348. end
  349. this.saveOrRemoveGrailInfo(actor, grailId, entryInfo)
  350. sendluamsg(
  351. actor,
  352. LuaMessageIdToClient.RES_GRAIL_ENTRY_INFO,
  353. {
  354. [grailId] = entryInfo and entryInfo or {}
  355. }
  356. )
  357. -- 增加大天使装备下的圣杯等级
  358. AngelMajorEquipment.addGrailLevel(actor, grailId, grailLevel + 1)
  359. -- 触发任务刷新
  360. TaskHandler.TriggerTaskGoal(actor, TaskTargetType.STRENGTHEN_GRAIL)
  361. else
  362. sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_ENTRY_STRENGTHEN_RESULT, success)
  363. end
  364. end
  365. end
  366. --- 初始化大天使圣杯词条信息
  367. --- @param actor table 角色对象
  368. --- @param itemId number 道具id
  369. --- @param itemConfigId number 道具配置id
  370. function AngelMajorGrail.initGrailEntry(actor, itemId, itemConfigId)
  371. -- 延迟执行
  372. -- intervalcalldelay(actor, 500, 1000, 1, "initgrailinfo", itemId, itemConfigId)
  373. AngelMajorGrail.initGrailInfo(actor, itemId, itemConfigId)
  374. end
  375. function AngelMajorGrail.initGrailInfo(actor, itemId, itemConfigId)
  376. -- 判断道具是否为圣杯
  377. local tableValue = this.isAngelGrail(itemConfigId)
  378. if not tableValue then
  379. return
  380. end
  381. local entryInfo = this.getGrailInfo(actor, itemId)
  382. if not table.isNullOrEmpty(entryInfo) then
  383. AngelMajorGrail.sendGrailInfo(actor, false)
  384. AngelMajorGrail.sendRedPoint(actor)
  385. return
  386. end
  387. info(actor, actor, "尝试初始化圣杯词条信息", itemId, itemConfigId)
  388. -- 获取圣杯主词条组
  389. local mainEntryGroup = tableValue[1]["mainattgroup"]
  390. -- 获取圣杯随机词条组
  391. local randomEntryGroup = tableValue[1]["randomattgroup"]
  392. -- 获取圣杯词条数量权重
  393. local entryCountWeight = tableValue[1]["attcountweight"]
  394. -- 获取圣杯等阶
  395. local grailGrade = tableValue[1]["grailgrade"]
  396. -- 获取圣杯孔位
  397. local gradePosition = tableValue[1]["gradeposition"]
  398. local itemEntry = {}
  399. -- 圣杯主词条信息初始化
  400. local mainEntryInfo = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", mainEntryGroup)
  401. if table.isNullOrEmpty(mainEntryInfo) then
  402. jprint("AngelMajorGrail.initGrailAttr cfg_equip_angelEntry data is nil")
  403. return
  404. end
  405. local mainEntry = this.initEntry(mainEntryInfo[1])
  406. itemEntry["main"] = mainEntry
  407. -- 圣杯副词条信息初始化
  408. local secondary = {}
  409. local secondaryEntryInfo
  410. local secondaryCount
  411. --[[
  412. 1代表从1词条组随一个 1#2代表从1和2词条组中随一个 1|1代表从1词条组随两个
  413. 分两种情况:
  414. 1.randomAttGroup字符串带竖线,需要根据attCountWeight计算出词条数量再随机生成对应条数的词条
  415. 2.randomAttGroup字符串不带竖线,判断是否带井号,带井号分割字符串,根据获得的词条组随机生成一条词条
  416. 3.randomAttGroup字符串不带竖线也不带井号,根据词条组随机生成一条词条
  417. ]]
  418. if string.contains(randomEntryGroup, "|") then
  419. -- 第一种情况
  420. local weightMap = string.toIntIntMap(entryCountWeight, "#", "|")
  421. -- 副词条初始化条数
  422. secondaryCount = randombyweight(weightMap, 1, true)[1]
  423. local entryGroup = string.split(randomEntryGroup, "|")[1]
  424. secondaryEntryInfo = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", entryGroup)
  425. elseif string.contains(randomEntryGroup, "#") then
  426. -- 第二种情况
  427. local group1 = string.split(randomEntryGroup, "#")[1]
  428. local group2 = string.split(randomEntryGroup, "#")[2]
  429. secondaryEntryInfo = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", group1)
  430. local tempEntry = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", group2)
  431. table.insertArray(secondaryEntryInfo, tempEntry)
  432. secondaryCount = 1
  433. else
  434. -- 第三种情况
  435. secondaryEntryInfo = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", randomEntryGroup)
  436. secondaryCount = 1
  437. end
  438. -- 获取根据权重生成的随机词条并设置
  439. if not table.isNullOrEmpty(secondaryEntryInfo) then
  440. local randomResult = this.getRandomEntry(secondaryEntryInfo, secondaryCount)
  441. for _, v in pairs(randomResult) do
  442. local secondaryEntry = this.initEntry(secondaryEntryInfo[v])
  443. table.insert(secondary, secondaryEntry)
  444. end
  445. itemEntry["secondary"] = secondary
  446. end
  447. itemEntry["grailGrade"] = tonumber(grailGrade)
  448. itemEntry["itemConfigId"] = itemConfigId
  449. itemEntry["grailPosition"] = tonumber(gradePosition)
  450. itemEntry["level"] = 0
  451. itemEntry["inlaid"] = false
  452. info(actor, actor, "初始化圣杯 id:", itemId)
  453. -- 计算评分
  454. itemEntry = this.calcGrailScore(itemEntry)
  455. this.saveOrRemoveGrailInfo(actor, itemId, itemEntry)
  456. sendluamsg(
  457. actor,
  458. LuaMessageIdToClient.RES_GRAIL_ENTRY_INFO,
  459. {
  460. [itemId] = itemEntry and itemEntry or {}
  461. }
  462. )
  463. -- 红点判断
  464. AngelMajorGrail.sendRedPoint(actor)
  465. -- end
  466. end
  467. --- 销毁圣杯
  468. --- @param actor table 角色对象
  469. --- @param cfgId number 道具配置id
  470. --- @param itemId number 道具id
  471. function AngelMajorGrail.destroyAngelGrail(actor, cfgId, itemId)
  472. local tableValue = this.isAngelGrail(cfgId)
  473. if not table.isNullOrEmpty(tableValue) then
  474. info(actor, actor, "销毁圣杯", itemId)
  475. local entryInfo = this.getGrailInfo(actor, itemId)
  476. if not table.isNullOrEmpty(entryInfo) then
  477. if entryInfo["inlaid"] then
  478. tipinfo(actor, "含有镶嵌的圣杯不能销毁")
  479. return
  480. end
  481. end
  482. this.saveOrRemoveGrailInfo(actor, itemId)
  483. -- 红点判断
  484. local result = AngelMajorGrail.checkEnter(actor)
  485. RedPoint.sendOneRedPoint(actor, this.RedId, result)
  486. end
  487. end
  488. --- 给角色增加圣杯词条属性
  489. --- @param actor table 角色对象
  490. --- @param entryInfo table 词条信息
  491. --- @param grailId number 圣杯唯一id
  492. --- @param isAdd boolean 是否增加词条
  493. function AngelMajorGrail.grailAttrHandle(actor, entryInfo, grailId, isAdd)
  494. if isAdd then
  495. local attrMap = {}
  496. local mainAttr = entryInfo["main"]
  497. if table.isNullOrEmpty(mainAttr) then
  498. return
  499. end
  500. for _, v in pairs(mainAttr) do
  501. local attrId = tonumber(v["attrId"])
  502. local attrValue = tonumber(v["value"])
  503. if table.getValue(attrMap, attrId) then
  504. attrMap[attrId] = attrMap[attrId] + attrValue
  505. else
  506. attrMap[attrId] = attrValue
  507. end
  508. end
  509. local secondaryAttr = entryInfo["secondary"]
  510. if table.isNullOrEmpty(secondaryAttr) then
  511. return
  512. end
  513. for _, v in pairs(secondaryAttr) do
  514. for _, value in pairs(v) do
  515. local attrId = tonumber(value["attrId"])
  516. local attrValue = tonumber(value["value"])
  517. if table.getValue(attrMap, attrId) then
  518. attrMap[attrId] = attrMap[attrId] + attrValue
  519. else
  520. attrMap[attrId] = attrValue
  521. end
  522. end
  523. end
  524. RoleAttr.addAndSaveRoleAttr(actor, string.format(RoleAttrKey.ANGEL_GRAIL, grailId), attrMap)
  525. else
  526. RoleAttr.clearRoleAttrAndDB(actor, string.format(RoleAttrKey.ANGEL_GRAIL, grailId))
  527. end
  528. end
  529. --- 大天使圣杯分解
  530. --- @param actor table 角色对象
  531. --- @param msgData table 消息数据
  532. function AngelMajorGrail.grailDecompose(actor, msgData)
  533. -- 圣杯索引集合
  534. local indexList = msgData["indexList"]
  535. -- 圣杯唯一id集合
  536. local grailIds = msgData["grailIds"]
  537. info(actor, actor, "大天使圣杯分解", "圣杯ids:", grailIds)
  538. if table.isNullOrEmpty(grailIds) then
  539. return
  540. end
  541. local costMap = {}
  542. local getMap = {}
  543. for _, grailId in pairs(grailIds) do
  544. local entryInfo = this.getGrailInfo(actor, grailId)
  545. if not table.isNullOrEmpty(entryInfo) then
  546. if entryInfo["inlaid"] then
  547. tipinfo(actor, "含有镶嵌的圣杯不能分解")
  548. return
  549. end
  550. local itemConfigId = entryInfo["itemConfigId"]
  551. local level = entryInfo["level"]
  552. local group = ConfigDataManager.getTableValue("cfg_equip_angelStrengthen", "SplitGroup", "id", itemConfigId)
  553. if group then
  554. local tableValue =
  555. ConfigDataManager.getTable(
  556. "cfg_equip_angelStrengthenCost",
  557. "AngelstrengthenGroup",
  558. group,
  559. "AngelstrengthenLv",
  560. level
  561. )
  562. local recoveryCost = tableValue[1]["recoverycost"]
  563. if recoveryCost then
  564. -- 检查消耗道具是否充足
  565. costMap = string.putIntIntMap(costMap, recoveryCost, "#", "|")
  566. local enough = Bag.checkCostMap(actor, costMap)
  567. if not enough then
  568. noticeTip.noticeinfo(actor, StringIdConst.TEXT351)
  569. return
  570. end
  571. end
  572. local angelStrengthenGet = tableValue[1]["angelstrengthenget"]
  573. if angelStrengthenGet then
  574. -- 封装奖励map
  575. local itemMap = string.toIntIntMap(angelStrengthenGet, "#", "|")
  576. for k, v in pairs(itemMap) do
  577. local itemId = tonumber(k)
  578. local count = tonumber(v)
  579. if getMap[itemId] then
  580. getMap[itemId] = getMap[itemId] + count
  581. else
  582. getMap[itemId] = count
  583. end
  584. end
  585. end
  586. end
  587. end
  588. end
  589. -- 消耗道具并发放奖励
  590. if not table.isNullOrEmpty(getMap) and not table.isNullOrEmpty(costMap) then
  591. Bag.costMap(actor, costMap, ItemAction.ANGEL_GRAIL_DECOMPOSE_RECOVERY)
  592. Bag.sendRewards(actor, getMap, ItemAction.ANGEL_GRAIL_DECOMPOSE_REWARD)
  593. removeitembyidxlist(actor, indexList, 9999, ItemAction.ANGEL_GRAIL_DECOMPOSE)
  594. sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_DECOMPOSE_RESULT, true)
  595. -- 删除存储的圣杯词条信息
  596. for _, grailId in pairs(grailIds) do
  597. this.saveOrRemoveGrailInfo(actor, grailId)
  598. end
  599. -- 红点判断
  600. local result = AngelMajorGrail.checkEnter(actor)
  601. RedPoint.sendOneRedPoint(actor, this.RedId, result)
  602. return
  603. end
  604. -- 红点判断
  605. AngelMajorGrail.sendRedPoint(actor)
  606. sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_DECOMPOSE_RESULT, false)
  607. end
  608. --- 登录红点判断
  609. --- @param actor table 角色对象
  610. --- @return boolean 是否展示红点
  611. function AngelMajorGrail.checkEnter(actor)
  612. -- 获取所有圣杯
  613. local grailInfo = AngelMajorGrail.getBagGrailIds(actor)
  614. if not table.isNullOrEmpty(grailInfo) then
  615. for _, grailId in pairs(grailInfo) do
  616. local entryInfo = this.getGrailInfo(actor, grailId)
  617. if not table.isNullOrEmpty(entryInfo) then
  618. if
  619. not entryInfo["inlaid"] and
  620. this.checkRedPoint(
  621. actor,
  622. entryInfo["grailGrade"],
  623. entryInfo["grailPosition"],
  624. entryInfo["itemConfigId"]
  625. )
  626. then
  627. return true
  628. end
  629. end
  630. end
  631. end
  632. return false
  633. end
  634. --- 获取指定玩家的指定大天使圣杯词条信息
  635. ---@param actor table 角色对象
  636. ---@param msgData table 消息数据
  637. function AngelMajorGrail.getPlayerAngelGrailInfo(actor, msgData)
  638. local rid = msgData["rid"]
  639. local itemId = msgData["itemId"]
  640. local targetActor = getactor(actor, rid)
  641. local entryInfo = this.getGrailInfo(targetActor, itemId)
  642. sendluamsg(
  643. actor,
  644. LuaMessageIdToClient.RES_OTHER_ANGE_GRAIL_INFO,
  645. {
  646. [itemId] = entryInfo or {}
  647. }
  648. )
  649. end
  650. --- 获取身上穿戴的大天使装备镶嵌的所有圣杯id
  651. ---@param actor table 角色对象
  652. ---@return table 圣杯id列表
  653. function AngelMajorGrail.getInlaidGrailIds(actor)
  654. local grailIds = {}
  655. local grailInfo = this.getAllGrailInfo(actor)
  656. if table.isNullOrEmpty(grailInfo) then
  657. return grailIds
  658. end
  659. for grailId, v in pairs(grailInfo) do
  660. local inlaid = v["inlaid"]
  661. if inlaid then
  662. table.insert(grailIds, grailId)
  663. end
  664. end
  665. return grailIds
  666. end
  667. --- 获取指定玩家的指定大天使圣杯数量
  668. ---@param actor table 角色对象
  669. ---@param grailGrade number 圣杯等阶
  670. ---@param grailQuality number 圣杯品质
  671. ---@return number 数量
  672. function AngelMajorGrail.getGrailCountByCondition(actor, grailGrade, grailQuality)
  673. grailGrade = tonumber(grailGrade)
  674. grailQuality = tonumber(grailQuality)
  675. local count = 0
  676. local inlaidGrailIds = AngelMajorGrail.getInlaidGrailIds(actor)
  677. if table.isNullOrEmpty(inlaidGrailIds) then
  678. return 0
  679. end
  680. for _, grailId in pairs(inlaidGrailIds) do
  681. local entryInfo = this.getGrailInfo(actor, grailId)
  682. if table.isNullOrEmpty(entryInfo) then
  683. goto next
  684. end
  685. if grailGrade ~= 0 then
  686. local grade = entryInfo["grailGrade"]
  687. if grade < grailGrade then
  688. goto next
  689. end
  690. end
  691. if grailQuality ~= 0 then
  692. local cfgId = entryInfo["itemConfigId"]
  693. local quality = ConfigDataManager.getTableValue("cfg_equip_angelGrail", "grailQuality", "id", cfgId)
  694. if tonumber(quality) < grailQuality then
  695. goto next
  696. end
  697. end
  698. count = count + 1
  699. ::next::
  700. end
  701. return count
  702. end
  703. --- 获取身上所有已镶嵌的大天使圣杯达到指定强化等级的数量
  704. ---@param actor table 角色对象
  705. ---@param strengthLevel number 强化等级
  706. ---@return number 数量
  707. function AngelMajorGrail.getGrailCountByStrengthLevel(actor, strengthLevel)
  708. local inlaidGrailIds = AngelMajorGrail.getInlaidGrailIds(actor)
  709. if table.isNullOrEmpty(inlaidGrailIds) then
  710. return 0
  711. end
  712. local count = 0
  713. for _, grailId in pairs(inlaidGrailIds) do
  714. local entryInfo = this.getGrailInfo(actor, grailId)
  715. if not table.isNullOrEmpty(entryInfo) then
  716. local level = entryInfo["level"]
  717. if level >= tonumber(strengthLevel) then
  718. count = count + 1
  719. end
  720. end
  721. end
  722. return count
  723. end
  724. --- 检查是否满足大天使圣杯套装
  725. ---@param actor table 角色对象
  726. function AngelMajorGrail.checkAngelGrailSuitCondition(actor)
  727. local maxGrade = 0
  728. local temp = {}
  729. -- 获取身上镶嵌的所有圣杯id
  730. local inlaidGrailIds = AngelMajorGrail.getInlaidGrailIds(actor)
  731. -- 遍历获取圣杯数量与最大圣杯阶数
  732. for _, grailId in pairs(inlaidGrailIds) do
  733. local v = this.getGrailInfo(actor, grailId)
  734. if not table.isNullOrEmpty(v) then
  735. local cfgId = v["itemConfigId"]
  736. temp[cfgId] = (temp[cfgId] and temp[cfgId] or 0) + 1
  737. maxGrade = v["grailGrade"] > maxGrade and v["grailGrade"] or maxGrade
  738. end
  739. end
  740. local grailSuitId = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_SUIT_ID)
  741. local tableId
  742. local attrInfo = {}
  743. -- 倒序循环判断是否满足套装
  744. for i = maxGrade, 1, -1 do
  745. local total = 0
  746. for j = 4, 1, -1 do
  747. local tableValue = ConfigDataManager.getTable("cfg_equip_angelGrailSuit", "group", i, "level", j)
  748. if table.isNullOrEmpty(tableValue) then
  749. error("cfg_equip_angelGrailSuit is null group:", i, " level:", j)
  750. return
  751. end
  752. local value = tableValue[1]
  753. local suitGrailId = value["suitgrailid"]
  754. local suitEffect = value["suiteffect"]
  755. if not string.isNullOrEmpty(suitGrailId) and not string.isNullOrEmpty(suitEffect) then
  756. local grailIds = string.split(suitGrailId, "#")
  757. for _, configId in pairs(grailIds) do
  758. configId = tonumber(configId)
  759. total = total + (temp[configId] and temp[configId] or 0)
  760. end
  761. if total > 0 then
  762. local split = string.split(suitEffect, "|")
  763. for _, item in pairs(split) do
  764. local split2 = string.split(item, "#")
  765. local count = tonumber(split2[1])
  766. if total >= count then
  767. tableId = tonumber(value["id"])
  768. local attrId = tonumber(split2[2])
  769. local attrValue = tonumber(split2[3])
  770. attrInfo[attrId] = attrValue
  771. end
  772. end
  773. if not table.isNullOrEmpty(attrInfo) then
  774. if tableId ~= grailSuitId then
  775. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_SUIT_ID, tableId)
  776. RoleAttr.clearRoleAttrAndDB(actor, RoleAttrKey.ANGEL_GRAIL_SUIT)
  777. end
  778. local attr = getplaydef(actor, "T$_" .. RoleAttrKey.ANGEL_GRAIL_SUIT)
  779. if not table.isNullOrEmpty(attr) then
  780. local attrLength = table.count(attr)
  781. local attrInfoLength = table.count(attrInfo)
  782. if attrLength > attrInfoLength then
  783. for attrId, _ in pairs(attr) do
  784. if table.hasKey(attrInfo, attrId) then
  785. attrInfo[attrId] = 0
  786. else
  787. attrInfo[attrId] = -attr[attrId]
  788. end
  789. end
  790. else
  791. for attrId, _ in pairs(attrInfo) do
  792. if table.hasKey(attr, attrId) and attr[attrId] > 0 then
  793. attrInfo[attrId] = 0
  794. end
  795. end
  796. end
  797. end
  798. RoleAttr.addAndSaveRoleAttr(actor, RoleAttrKey.ANGEL_GRAIL_SUIT, attrInfo)
  799. return
  800. end
  801. end
  802. end
  803. end
  804. end
  805. -- 清除套装属性加成
  806. RoleAttr.clearRoleAttrAndDB(actor, RoleAttrKey.ANGEL_GRAIL_SUIT)
  807. end
  808. --- 初始化大天使圣杯排行榜信息
  809. function AngelMajorGrail.initGrailRanking()
  810. -- 本服圣杯排行榜初始化
  811. local allRole = getsysvar("Q$allRankRoles")
  812. if not table.isNullOrEmpty(allRole) then
  813. -- gameDebug.print(string.format("初始化大天使圣杯排行榜信息 now:%s", TimeUtil.timeFormat(getbaseinfo("nowsec"))))
  814. local ranking = getsysvar(SystemVarConst.ANGEL_GRAIL_RANKING_INFO) or {}
  815. local rankingInfo = ranking["rankingInfo"]
  816. local actor
  817. if table.isNullOrEmpty(rankingInfo) then
  818. rankingInfo = {}
  819. for _, v in pairs(allRole) do
  820. actor = v["actor"]
  821. local career = v["career"]
  822. local roleName = v["name"]
  823. local serverId = v["serverid"]
  824. this.grailRankingHandle(actor, career, roleName, serverId, rankingInfo)
  825. end
  826. else
  827. for _, v in pairs(allRole) do
  828. actor = v["actor"]
  829. local career = v["career"]
  830. local roleName = v["name"]
  831. local serverId = v["serverid"]
  832. local onlineState = getbaseinfo(actor, "onlinestate")
  833. if onlineState == 1 then
  834. for key, value in pairs(rankingInfo) do
  835. if value["roleId"] == tonumber(actor:toString()) then
  836. table.remove(rankingInfo, key)
  837. break
  838. end
  839. end
  840. this.grailRankingHandle(actor, career, roleName, serverId, rankingInfo)
  841. end
  842. end
  843. end
  844. if not table.isNullOrEmpty(rankingInfo) then
  845. rankingInfo = this.calcGrailRanking(rankingInfo)
  846. end
  847. ranking = {}
  848. ranking["rankingInfo"] = rankingInfo
  849. local rankingIndex = {}
  850. for key, rank in pairs(rankingInfo) do
  851. rankingIndex[rank["roleId"]] = key
  852. end
  853. ranking["rankingIndex"] = rankingIndex
  854. setsysvar(actor, SystemVarConst.ANGEL_GRAIL_RANKING_INFO, ranking)
  855. end
  856. -- 跨服圣杯排行榜数据初始化
  857. local serverType = getbaseinfo("servertype")
  858. if serverType == 2 then
  859. return
  860. -- local hosts = gethosts()
  861. -- if not table.isNullOrEmpty(hosts) then
  862. -- --gameDebug.print(string.format("初始化大天使圣杯跨服排行榜信息 now:%s", TimeUtil.timeFormat(getbaseinfo("nowsec"))))
  863. -- local rankingInfo = {}
  864. -- for _, host in pairs(hosts) do
  865. -- local all = getallrolesummaryinfos(host)
  866. -- if not table.isNullOrEmpty(all) then
  867. -- for _, v in pairs(all) do
  868. -- local actor = v["actor"]
  869. -- local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  870. -- if not table.isNullOrEmpty(grailInfo) then
  871. -- this.grailRankingHandle(actor, grailInfo, rankingInfo)
  872. -- end
  873. -- end
  874. -- end
  875. -- end
  876. -- if not table.isNullOrEmpty(rankingInfo) then
  877. -- rankingInfo = this.calcGrailRanking(rankingInfo)
  878. -- end
  879. -- local ranking = {}
  880. -- ranking["rankingInfo"] = rankingInfo
  881. -- local rankingIndex = {}
  882. -- for key, rank in pairs(rankingInfo) do
  883. -- rankingIndex[rank["roleId"]] = key
  884. -- end
  885. -- ranking["rankingIndex"] = rankingIndex
  886. -- for _, host in ipairs(hosts) do
  887. -- setsysvar(host, SystemVarConst.ANGEL_GRAIL_CROSS_RANKING_INFO, ranking)
  888. -- end
  889. -- end
  890. end
  891. end
  892. --- 获取大天使圣杯排行榜信息
  893. ---@param actor table 角色对象
  894. ---@param grailGrade number 圣杯等阶
  895. function AngelMajorGrail.getGrailRankingInfo(actor, msgData)
  896. -- 排行榜类型
  897. local type = msgData["type"]
  898. local ranking = {}
  899. if type == 1 then
  900. -- ranking = getsysvar(SystemVarConst.ANGEL_GRAIL_CROSS_RANKING_INFO, 1)
  901. return
  902. else
  903. ranking = getsysvar(actor, SystemVarConst.ANGEL_GRAIL_RANKING_INFO)
  904. end
  905. local worshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO)
  906. worshipInfo = worshipInfo or {}
  907. local crossWorshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO)
  908. crossWorshipInfo = crossWorshipInfo or {}
  909. local res = {}
  910. res["worshipCount"] = table.count(worshipInfo) + table.count(crossWorshipInfo)
  911. res["roleIds"] = type == 1 and crossWorshipInfo or worshipInfo
  912. local rankingInfo = ranking["rankingInfo"]
  913. local rankingIndex = ranking["rankingIndex"]
  914. local roleId = tonumber(actor:toString())
  915. local my = {}
  916. if table.hasKey(rankingIndex, roleId) then
  917. my = rankingInfo[rankingIndex[roleId]]
  918. end
  919. if not table.isNullOrEmpty(rankingInfo) then
  920. res["rankingInfo"] = {
  921. ["all"] = {table.unpack(rankingInfo, 1, 30)},
  922. ["my"] = my
  923. }
  924. else
  925. res["rankingInfo"] = {}
  926. end
  927. sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_RANKING_INFO, res)
  928. end
  929. --- 膜拜圣杯
  930. ---@param actor table 角色对象
  931. ---@param msgData table 消息数据
  932. function AngelMajorGrail.worshipGrail(actor, msgData)
  933. -- 排行榜类型
  934. local type = tonumber(msgData["type"])
  935. -- 圣杯id
  936. local roleId = tonumber(msgData["roleId"])
  937. local worshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO)
  938. worshipInfo = worshipInfo or {}
  939. local crossWorshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO)
  940. crossWorshipInfo = crossWorshipInfo or {}
  941. if type == 1 then
  942. if not table.isNullOrEmpty(crossWorshipInfo) then
  943. if table.hasKey(crossWorshipInfo, roleId) then
  944. gameDebug.print(string.format("玩家%s重复膜拜跨服圣杯排行榜的%s", getbaseinfo(actor, "rolename"), roleId))
  945. return
  946. end
  947. end
  948. else
  949. if not table.isNullOrEmpty(worshipInfo) then
  950. if table.hasKey(worshipInfo, roleId) then
  951. gameDebug.print(string.format("玩家%s重复膜拜圣杯排行榜的%s", getbaseinfo(actor, "rolename"), roleId))
  952. return
  953. end
  954. end
  955. end
  956. -- 已经膜拜次数
  957. local count = table.count(worshipInfo) + table.count(crossWorshipInfo)
  958. -- 每日膜拜次数限制校验
  959. local limit = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.ANGEL_GRAIL_WORSHIP_LIMIT)
  960. if string.isNullOrEmpty(limit) then
  961. error("cfg_global is null id:", GlobalConfigId.ANGEL_GRAIL_WORSHIP_LIMIT)
  962. return
  963. end
  964. if count >= tonumber(limit) then
  965. gameDebug.print(string.format("玩家%s超过每日膜拜次数限制", getbaseinfo(actor, "rolename")))
  966. return
  967. end
  968. local reward =
  969. ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.ANGEL_GRAIL_WORSHIP_REWARD)
  970. if not string.isNullOrEmpty(reward) then
  971. if type == 1 then
  972. crossWorshipInfo[roleId] = 1
  973. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO, crossWorshipInfo)
  974. else
  975. worshipInfo[roleId] = 1
  976. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO, worshipInfo)
  977. end
  978. Bag.sendRewards4String(actor, reward, ItemAction.ANGEL_GRAIL_RANKING_WORSHIP_REWARD)
  979. -- 发送膜拜圣杯红点
  980. RedPoint.sendOneRedPoint(actor, this.canWorshipRedId, this.checkWorshipRedPoint(actor))
  981. -- 响应客户端
  982. sendluamsg(
  983. actor,
  984. LuaMessageIdToClient.RES_GRAIL_RANKING_WORSHIP_INFO,
  985. {
  986. ["worshipCount"] = count + 1,
  987. ["grailIds"] = type == 1 and crossWorshipInfo or worshipInfo
  988. }
  989. )
  990. end
  991. end
  992. --- 获取指定玩家身上穿着的大天使装备与镶嵌的圣杯信息
  993. ---@param actor table 角色对象
  994. ---@param rid number 玩家id
  995. function AngelMajorGrail.getPlayerAllAngelEquipAndGrail(actor, rid)
  996. local player = getactor(rid)
  997. if not player then
  998. return
  999. end
  1000. local res = {}
  1001. -- 获取大天使装备信息
  1002. local equipAttr = {}
  1003. local equipInfo = getplaydef(player, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA)
  1004. local putOnIds = AngelMajorEquipment.getPutOnEquipIds(player)
  1005. if not table.isNullOrEmpty(equipInfo) then
  1006. for _, v in pairs(putOnIds) do
  1007. equipAttr[v] = equipInfo[v]
  1008. end
  1009. end
  1010. -- 获取大天使圣杯信息
  1011. local grailInfo = {}
  1012. local grailIds = AngelMajorGrail.getInlaidGrailIds(player)
  1013. if not table.isNullOrEmpty(grailIds) then
  1014. for _, v in pairs(grailIds) do
  1015. local entryInfo = this.getGrailInfo(player, v)
  1016. if not table.isNullOrEmpty(entryInfo) then
  1017. grailInfo[v] = entryInfo
  1018. end
  1019. end
  1020. end
  1021. res["equip"] = equipAttr
  1022. res["grail"] = grailInfo
  1023. sendluamsg(actor, LuaMessageIdToClient.RES_PLAYER_EQUIP_GRAIL_INFO, res)
  1024. end
  1025. ---登录事件检查红点
  1026. function this.loginRed(red_data, actor)
  1027. if AngelMajorGrail.checkEnter(actor) then
  1028. -- 上线false可以不发送
  1029. red_data[this.RedId] = true
  1030. end
  1031. if this.checkWorshipRedPoint(actor) then
  1032. red_data[this.canWorshipRedId] = true
  1033. end
  1034. end
  1035. --- 圣杯镶嵌红点判断
  1036. --- @param actor table 角色对象
  1037. --- @param grailGrade number 圣杯等阶
  1038. --- @param grailPosition number 孔位
  1039. --- @param grailConfigId number 圣杯配置id
  1040. --- @return boolean 是否展示红点
  1041. function this.checkRedPoint(actor, grailGrade, grailPosition, grailConfigId)
  1042. local equipData = getputonequipinfo(actor)
  1043. local equipAttr = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA)
  1044. if table.isNullOrEmpty(equipAttr) then
  1045. return false
  1046. end
  1047. for _, v in pairs(equipData) do
  1048. local attr = equipAttr[v["id"]]
  1049. if table.isNullOrEmpty(attr) then
  1050. goto next
  1051. end
  1052. local cfgId = v["cfgid"]
  1053. local strPart = ConfigDataManager.getTableValue("cfg_item", "strPart", "id", cfgId)
  1054. local partSplit = string.split(strPart, "#")
  1055. local grailStrPart = ConfigDataManager.getTableValue("cfg_equip_angelGrail", "strPart", "id", grailConfigId)
  1056. local grailPartSplit = string.split(grailStrPart, "#")
  1057. local flag = false
  1058. for _, part in pairs(partSplit) do
  1059. if table.contains(grailPartSplit, part) then
  1060. flag = true
  1061. end
  1062. end
  1063. if not flag then
  1064. goto next
  1065. end
  1066. local equipRank = attr["rank"]
  1067. if equipRank < grailGrade then
  1068. goto next
  1069. else
  1070. local grails = attr["grails"]
  1071. if not table.isNullOrEmpty(grails) then
  1072. for _, value in pairs(grails) do
  1073. if value["grailPosition"] == grailPosition then
  1074. goto next
  1075. end
  1076. end
  1077. return true
  1078. else
  1079. return true
  1080. end
  1081. end
  1082. ::next::
  1083. end
  1084. return false
  1085. end
  1086. --- 圣杯排行榜膜拜红点判断
  1087. --- @param actor table 角色对象
  1088. function this.checkWorshipRedPoint(actor)
  1089. local worshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO)
  1090. worshipInfo = worshipInfo or {}
  1091. local crossWorshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO)
  1092. crossWorshipInfo = crossWorshipInfo or {}
  1093. local ranking = getsysvar(actor, SystemVarConst.ANGEL_GRAIL_RANKING_INFO)
  1094. if table.isNullOrEmpty(ranking) then
  1095. return false
  1096. end
  1097. local rankingInfo = ranking["rankingInfo"]
  1098. if table.isNullOrEmpty(rankingInfo) then
  1099. return false
  1100. end
  1101. if table.isNullOrEmpty(worshipInfo) and table.isNullOrEmpty(crossWorshipInfo) then
  1102. return true
  1103. end
  1104. local limit = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.ANGEL_GRAIL_WORSHIP_LIMIT)
  1105. local count = table.count(worshipInfo) + table.count(crossWorshipInfo)
  1106. if count < tonumber(limit) then
  1107. return true
  1108. end
  1109. return false
  1110. end
  1111. --- 组装圣杯信息
  1112. --- @param itemId number 道具id
  1113. --- @param info table 孔位信息
  1114. --- @param entryInfo table 词条信息
  1115. function this.combineRes(itemId, info, entryInfo)
  1116. local temp = {}
  1117. temp["itemId"] = itemId
  1118. temp["itemConfigId"] = info["itemConfigId"]
  1119. temp["position"] = info["grailPosition"]
  1120. temp["attrInfo"] = entryInfo
  1121. temp["inlaid"] = info["inlaid"]
  1122. return temp
  1123. end
  1124. --- 强化词条
  1125. --- @param entry table 词条对象
  1126. function this.strengthen(entry)
  1127. local id = entry["id"]
  1128. local attrValue = entry["value"]
  1129. local entryTableValue = ConfigDataManager.getTable("cfg_equip_angelEntry", "id", id)
  1130. local max = entryTableValue[1]["attmax"]
  1131. local maxSplit = string.split(max, "#")
  1132. local index = 1
  1133. -- 获取最大值索引
  1134. if string.contains(max, "#") then
  1135. local attrId = entry["attrId"]
  1136. local att = entryTableValue[1]["att"]
  1137. local attSplit = string.split(att, "|")
  1138. for k, v in pairs(attSplit) do
  1139. if tonumber(string.split(v, "#")[1]) == attrId then
  1140. index = k
  1141. break
  1142. end
  1143. end
  1144. end
  1145. local strengthen = entryTableValue[1]["strengthen"]
  1146. local split = string.split(strengthen, "|")
  1147. local temp = {}
  1148. for _, v in pairs(split) do
  1149. local split2 = string.split(v, "#")
  1150. local randomValue = math.random(split2[1], split2[2])
  1151. temp[
  1152. {
  1153. [index] = randomValue
  1154. }
  1155. ] = split2[3]
  1156. end
  1157. local randomInfo = randombyweight(temp)[1]
  1158. if not table.isNullOrEmpty(randomInfo) then
  1159. for k, v in pairs(randomInfo) do
  1160. -- 判断增加完的词条是否超过了最大值,如果超过了最大值则赋值为最大值
  1161. if attrValue + tonumber(v) >= tonumber(maxSplit[k] and maxSplit[k] or max) then
  1162. entry["value"] = maxSplit[k] and maxSplit[k] or max
  1163. entry["isMax"] = true
  1164. else
  1165. entry["value"] = attrValue + v
  1166. end
  1167. end
  1168. end
  1169. end
  1170. --- 获取圣杯词条信息
  1171. --- @param entryInfo table cfg_equip_angelEntry表词条信息
  1172. --- @return table 随机词条信息
  1173. function this.initEntry(entryInfo)
  1174. local split = string.split(entryInfo["att"], "|")
  1175. local res = {}
  1176. for _, v in pairs(split) do
  1177. local attSplit = string.split(v, "#")
  1178. local attrId = tonumber(attSplit[1])
  1179. local minValue = tonumber(attSplit[2])
  1180. local maxValue = tonumber(attSplit[3])
  1181. local weight = tonumber(attSplit[4])
  1182. local randomValue = math.random(minValue, maxValue)
  1183. table.insert(
  1184. res,
  1185. {
  1186. ["id"] = tonumber(entryInfo["id"]),
  1187. ["attrId"] = attrId,
  1188. ["value"] = randomValue,
  1189. ["weight"] = weight,
  1190. ["isMax"] = false
  1191. }
  1192. )
  1193. end
  1194. return res
  1195. end
  1196. --- 根据权重随机生成词条
  1197. --- @param secondaryEntryInfo table 词条信息
  1198. --- @param secondaryCount number 词条数量
  1199. --- @return table 随机词条索引集合
  1200. function this.getRandomEntry(secondaryEntryInfo, secondaryCount)
  1201. local temp = {}
  1202. for k, v in pairs(secondaryEntryInfo) do
  1203. local att = v["att"]
  1204. if string.contains(att, "|") then
  1205. local split = string.split(att, "|")
  1206. for _, value in pairs(split) do
  1207. local weight = string.split(value, "#")[4]
  1208. temp[k] = weight
  1209. end
  1210. else
  1211. local weight = string.split(att, "#")[4]
  1212. temp[k] = weight
  1213. end
  1214. end
  1215. local randomResult = randombyweight(temp, secondaryCount, false)
  1216. return randomResult
  1217. end
  1218. --- 判断是否开启大天使圣杯
  1219. --- @param actor table 角色对象
  1220. --- @return boolean 是否开启
  1221. function this.isOpen(actor)
  1222. -- 获取当前角色等级
  1223. local level = getbaseinfo(actor, "level")
  1224. -- 获取等级限制配置
  1225. local levelLimit =
  1226. ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.ANGEL_EQUIPMENT_LEVEL_LIMIT)
  1227. if string.isNullOrEmpty(levelLimit) then
  1228. return false
  1229. end
  1230. -- 返回结果
  1231. return level >= tonumber(levelLimit)
  1232. end
  1233. --- 判断是否是大天使圣杯
  1234. --- @param itemConfigId number 道具配置id
  1235. --- @return table 大天使圣杯信息
  1236. function this.isAngelGrail(itemConfigId)
  1237. return ConfigDataManager.getTable("cfg_equip_angelGrail", "id", itemConfigId)
  1238. end
  1239. --- 计算圣杯评分
  1240. ---@param grailEntry table 圣杯属性信息
  1241. function this.calcGrailScore(grailEntry)
  1242. local score = 0
  1243. if not table.isNullOrEmpty(grailEntry) then
  1244. local main = grailEntry["main"]
  1245. score = score + this.scoreHandle(main)
  1246. local secondary = grailEntry["secondary"]
  1247. for _, v in pairs(secondary) do
  1248. score = score + this.scoreHandle(v)
  1249. end
  1250. grailEntry["score"] = score
  1251. end
  1252. return grailEntry
  1253. end
  1254. --- 评分处理
  1255. --- @param entry table 词条数据
  1256. function this.scoreHandle(entry)
  1257. if not table.isNullOrEmpty(entry) then
  1258. local score = 0
  1259. for _, v in pairs(entry) do
  1260. local attrId = v["attrId"]
  1261. local value = v["value"]
  1262. local tableValue = ConfigDataManager.getTable("cfg_att_info", "id", attrId)
  1263. if not table.isNullOrEmpty(tableValue) then
  1264. local remarks = tableValue[1]["remarks"]
  1265. if tonumber(remarks) == 2 then
  1266. value = value / 100
  1267. end
  1268. local tableScore = tableValue[1]["score"]
  1269. score = math.ceil(score + value * tableScore)
  1270. end
  1271. end
  1272. return score
  1273. end
  1274. end
  1275. --- 计算圣杯排名
  1276. --- @param rankingTable table 要排的圣杯数据
  1277. --- @return table 排序后的圣杯数据
  1278. function this.calcGrailRanking(rankingTable)
  1279. -- 快速排序算法,对score进行降序排序,对于大数据集速度相较于插入排序更快,长远考虑选择快排
  1280. this.quickSortRecursive(rankingTable, 1, #rankingTable)
  1281. -- 更新排名
  1282. for i = 1, #rankingTable do
  1283. rankingTable[i].ranking = i
  1284. end
  1285. -- 返回排序结果
  1286. return rankingTable
  1287. end
  1288. --- 快速排序的分区函数
  1289. --- @param arr table 要排序的列表
  1290. --- @param low number 排序区间的下界
  1291. --- @param high number 排序区间的上界
  1292. function this.partition(arr, low, high)
  1293. local pivot = arr[high].score
  1294. local i = low - 1
  1295. for j = low, high - 1 do
  1296. if arr[j].score > pivot then
  1297. i = i + 1
  1298. -- 交换 arr[i] 和 arr[j]
  1299. local temp = arr[i]
  1300. arr[i] = arr[j]
  1301. arr[j] = temp
  1302. end
  1303. end
  1304. -- 交换 arr[i+1] 和 arr[high] (或者 pivot)
  1305. local temp = arr[i + 1]
  1306. arr[i + 1] = arr[high]
  1307. arr[high] = temp
  1308. return i + 1
  1309. end
  1310. --- 快速排序的递归函数
  1311. --- @param arr table 要排序的列表
  1312. --- @param low number 排序区间的下界
  1313. --- @param high number 排序区间的上界
  1314. function this.quickSortRecursive(arr, low, high)
  1315. if low < high then
  1316. local pi = this.partition(arr, low, high)
  1317. this.quickSortRecursive(arr, low, pi - 1)
  1318. this.quickSortRecursive(arr, pi + 1, high)
  1319. end
  1320. end
  1321. --- 圣杯排名处理
  1322. --- @param actor table 角色对象
  1323. --- @param career number 职业
  1324. --- @param roleName string 角色名
  1325. --- @param serverId number 服务器id
  1326. --- @param rankingInfo table 排行榜信息
  1327. function this.grailRankingHandle(actor, career, roleName, serverId, rankingInfo)
  1328. local inlaidGrailIds = AngelMajorGrail.getInlaidGrailIds(actor)
  1329. local score = 0
  1330. for _, itemId in pairs(inlaidGrailIds) do
  1331. local info = this.getGrailInfo(actor, itemId)
  1332. if not table.isNullOrEmpty(info) then
  1333. if not table.hasKey(info, "score") then
  1334. info = this.calcGrailScore(info)
  1335. end
  1336. score = score + info["score"]
  1337. end
  1338. end
  1339. if score > 0 then
  1340. table.insert(
  1341. rankingInfo,
  1342. {
  1343. ["roleId"] = tonumber(actor:toString()),
  1344. ["roleName"] = roleName,
  1345. ["career"] = career,
  1346. ["score"] = score,
  1347. ["ranking"] = 0,
  1348. ["serverId"] = serverId
  1349. }
  1350. )
  1351. end
  1352. end
  1353. --- 凌晨事件
  1354. function this.zeroEvent(play)
  1355. -- local allRole = getallrolesummaryinfos()
  1356. -- if not table.isNullOrEmpty(allRole) then
  1357. -- local logText = "开始重置大天使圣杯排行榜膜拜信息 now:%s"
  1358. -- gameDebug.print(string.format(logText, TimeUtil.timeFormat(getbaseinfo("nowsec"))))
  1359. -- for _, v in pairs(allRole) do
  1360. -- local actor = v["actor"]
  1361. -- setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO, {})
  1362. -- setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO, {})
  1363. -- end
  1364. -- end
  1365. -- 备用
  1366. ---- 只对传入的 play 做重置,不再遍历所有玩家
  1367. -- if not play then
  1368. -- return
  1369. -- end
  1370. -- -- 记录一次性日志(可选)
  1371. -- local logText = "重置大天使圣杯排行榜膜拜信息 for play:%s now:%s"
  1372. -- gameDebug.print(string.format(logText, tostring(getbaseinfo(play, "rolename") or "unknown"), TimeUtil.timeFormat(getbaseinfo("nowsec"))))
  1373. -- setplaydef(play, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO, {})
  1374. -- setplaydef(play, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO, {})
  1375. end
  1376. --- 玩家登录清除圣杯分解造成的脏数据
  1377. --- @param actor table 角色对象
  1378. function this.loginDirtyDataClear(actor)
  1379. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1380. if table.isNullOrEmpty(grailInfo) then
  1381. return
  1382. end
  1383. local flag = "2024_03_28_10_00"
  1384. local mark = getplaydef(actor, "T$_angelGrailDirtyDataClear")
  1385. if type(mark) ~= "string" or mark ~= flag then
  1386. jprint(
  1387. string.format(
  1388. "==============================>%s开始清除圣杯脏数据now:%s",
  1389. getbaseinfo(actor, "rolename"),
  1390. TimeUtil.timeFormat(getbaseinfo("nowsec"))
  1391. )
  1392. )
  1393. local itemIds = {}
  1394. -- 交易行圣杯id汇总,不做脏数据清理
  1395. local goodsList = getsysvar(actor, SYS_TRADE_WORLD_GOODS)
  1396. if not table.isNullOrEmpty(goodsList) then
  1397. local goods = goodsList[actor:toString()]
  1398. if not table.isNullOrEmpty(goods) then
  1399. for itemId, value in pairs(goods) do
  1400. local itemCfgId = value["itemcfgid"]
  1401. if this.isAngelGrail(itemCfgId) then
  1402. table.insert(itemIds, tonumber(itemId))
  1403. end
  1404. end
  1405. end
  1406. end
  1407. local bagItems = getallbagitem(actor)
  1408. if not table.isNullOrEmpty(bagItems) then
  1409. for _, v in pairs(bagItems) do
  1410. local cfgId = v["cfg_id"]
  1411. if this.isAngelGrail(cfgId) then
  1412. local id = v["id"]
  1413. if table.isNullOrEmpty(grailInfo[id]) then
  1414. this.initGrailInfo(actor, id, cfgId)
  1415. end
  1416. table.insert(itemIds, id)
  1417. end
  1418. end
  1419. end
  1420. local storeMaxPage = getstoremaxpage(actor)
  1421. for i = 1, storeMaxPage do
  1422. local storeItem = getalliteminfoinstore(actor, i)
  1423. if not table.isNullOrEmpty(storeItem) then
  1424. for _, v in pairs(storeItem) do
  1425. local cfgId = v["cfgid"]
  1426. if this.isAngelGrail(cfgId) then
  1427. local id = v["id"]
  1428. if table.isNullOrEmpty(grailInfo[id]) then
  1429. this.initGrailInfo(actor, id, cfgId)
  1430. end
  1431. table.insert(itemIds, id)
  1432. end
  1433. end
  1434. end
  1435. end
  1436. -- fixtodo 如果玩家存在卸下的带有圣杯的装备,这样清理会把玩家卸下装备上面的圣杯数据丢失
  1437. local equipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA)
  1438. if not table.isNullOrEmpty(equipInfo) then
  1439. for _, v in pairs(equipInfo) do
  1440. local grails = v["grails"]
  1441. if not table.isNullOrEmpty(grails) then
  1442. for grailId, value in pairs(grails) do
  1443. local cfgId = value["itemConfigId"]
  1444. if table.isNullOrEmpty(grailInfo[grailId]) then
  1445. this.initGrailInfo(actor, grailId, cfgId)
  1446. end
  1447. table.insert(itemIds, grailId)
  1448. end
  1449. end
  1450. end
  1451. end
  1452. grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1453. local allGrailIds = {}
  1454. for itemId, _ in pairs(grailInfo) do
  1455. if not table.contains(itemIds, itemId) then
  1456. grailInfo[itemId] = nil
  1457. end
  1458. table.insert(allGrailIds, itemId)
  1459. end
  1460. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo)
  1461. -- 大天使装备上圣杯数据清理
  1462. if not table.isNullOrEmpty(equipInfo) then
  1463. for k, v in pairs(equipInfo) do
  1464. local grails = v["grails"]
  1465. if not table.isNullOrEmpty(grails) then
  1466. for grailId, _ in pairs(grails) do
  1467. if not table.contains(allGrailIds, grailId) then
  1468. grails[grailId] = nil
  1469. end
  1470. end
  1471. end
  1472. end
  1473. end
  1474. setplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA, equipInfo)
  1475. -- 设置脏数据清理标识符
  1476. setplaydef(actor, "T$_angelGrailDirtyDataClear", flag)
  1477. end
  1478. end
  1479. --- 定时清除圣杯的脏数据
  1480. --- @param actor table 角色对象
  1481. function this.dirtyDataClear(actor)
  1482. -- local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1483. -- if table.isNullOrEmpty(grailInfo) then
  1484. -- return
  1485. -- end
  1486. -- jprint(string.format("==============================>%s开始清除圣杯脏数据now:%s",
  1487. -- getbaseinfo(actor, "rolename"), TimeUtil.timeFormat(getbaseinfo("nowsec"))))
  1488. -- local itemIds = {}
  1489. -- local existsGrailId = {}
  1490. -- -- 交易行圣杯id汇总,不做脏数据清理
  1491. -- local goodsList = getsysvar(actor, SYS_TRADE_WORLD_GOODS)
  1492. -- if not table.isNullOrEmpty(goodsList) then
  1493. -- local goods = goodsList[actor:toString()]
  1494. -- if not table.isNullOrEmpty(goods) then
  1495. -- for itemId, value in pairs(goods) do
  1496. -- local itemCfgId = value["itemcfgid"]
  1497. -- if this.isAngelGrail(itemCfgId) then
  1498. -- table.insert(itemIds, tonumber(itemId))
  1499. -- end
  1500. -- end
  1501. -- end
  1502. -- end
  1503. -- local bagItems = getallbagitem(actor)
  1504. -- if not table.isNullOrEmpty(bagItems) then
  1505. -- for _, v in pairs(bagItems) do
  1506. -- local cfgId = v["cfg_id"]
  1507. -- if this.isAngelGrail(cfgId) then
  1508. -- local id = v["id"]
  1509. -- if table.isNullOrEmpty(grailInfo[id]) then
  1510. -- this.initGrailInfo(actor, id, cfgId)
  1511. -- end
  1512. -- table.insert(itemIds, id)
  1513. -- table.insert(existsGrailId, id)
  1514. -- end
  1515. -- end
  1516. -- end
  1517. -- local storeMaxPage = getstoremaxpage(actor)
  1518. -- for i = 1, storeMaxPage do
  1519. -- local storeItem = getalliteminfoinstore(actor, i)
  1520. -- if not table.isNullOrEmpty(storeItem) then
  1521. -- for _, v in pairs(storeItem) do
  1522. -- local cfgId = v["cfgid"]
  1523. -- if this.isAngelGrail(cfgId) then
  1524. -- local id = v["id"]
  1525. -- if table.isNullOrEmpty(grailInfo[id]) then
  1526. -- this.initGrailInfo(actor, id, cfgId)
  1527. -- end
  1528. -- table.insert(itemIds, id)
  1529. -- end
  1530. -- end
  1531. -- end
  1532. -- end
  1533. -- -- fixtodo 如果玩家存在卸下的带有圣杯的装备,这样清理会把玩家卸下装备上面的圣杯数据丢失
  1534. -- local equipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA)
  1535. -- if not table.isNullOrEmpty(equipInfo) then
  1536. -- for _, v in pairs(equipInfo) do
  1537. -- local grails = v["grails"]
  1538. -- if not table.isNullOrEmpty(grails) then
  1539. -- for grailId, value in pairs(grails) do
  1540. -- local cfgId = value["itemConfigId"]
  1541. -- if table.isNullOrEmpty(grailInfo[grailId]) then
  1542. -- this.initGrailInfo(actor, grailId, cfgId)
  1543. -- end
  1544. -- table.insert(itemIds, grailId)
  1545. -- end
  1546. -- end
  1547. -- end
  1548. -- end
  1549. -- grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1550. -- local allGrailIds = {}
  1551. -- for itemId, _ in pairs(grailInfo) do
  1552. -- if not table.contains(itemIds, itemId) then
  1553. -- local itemExtData = getitemextdata(actor, itemId)
  1554. -- if table.isNullOrEmpty(itemExtData) then
  1555. -- grailInfo[itemId] = nil
  1556. -- end
  1557. -- end
  1558. -- table.insert(allGrailIds, itemId)
  1559. -- end
  1560. -- setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo)
  1561. -- -- 大天使装备上圣杯数据清理
  1562. -- if not table.isNullOrEmpty(equipInfo) then
  1563. -- for _, v in pairs(equipInfo) do
  1564. -- local grails = v["grails"]
  1565. -- if not table.isNullOrEmpty(grails) then
  1566. -- for grailId, _ in pairs(grails) do
  1567. -- if not table.contains(allGrailIds, grailId) then
  1568. -- grails[grailId] = nil
  1569. -- end
  1570. -- end
  1571. -- end
  1572. -- end
  1573. -- end
  1574. -- setplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA, equipInfo)
  1575. -- for _, grailId in pairs(existsGrailId) do
  1576. -- local entryInfo = this.getGrailInfo(actor, grailId)
  1577. -- if not table.isNullOrEmpty(entryInfo) then
  1578. -- info(actor, "将玩家变量中的圣杯信息放入道具lua扩展数据中 grailId", grailId, "entryInfo", entryInfo)
  1579. -- setitemextdata(actor, grailId, entryInfo)
  1580. -- end
  1581. -- end
  1582. end
  1583. --- 合服清空排行榜数据
  1584. function AngelMajorGrail.combine()
  1585. local hosts = gethosts()
  1586. for _, host in ipairs(hosts) do
  1587. setsysvar(host, SystemVarConst.ANGEL_GRAIL_RANKING_INFO, {})
  1588. setsysvar(host, SystemVarConst.ANGEL_GRAIL_CROSS_RANKING_INFO, {})
  1589. end
  1590. end
  1591. --- 保存/移除圣杯信息
  1592. --- @param actor table 角色对象
  1593. --- @param grailId number 圣杯id
  1594. --- @param itemEntry table 圣杯信息
  1595. function this.saveOrRemoveGrailInfo(actor, grailId, itemEntry)
  1596. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1597. if table.isNullOrEmpty(grailInfo) then
  1598. grailInfo = {}
  1599. end
  1600. if table.isNullOrEmpty(itemEntry) then
  1601. grailInfo[grailId] = nil
  1602. else
  1603. grailInfo[grailId] = itemEntry
  1604. setitemextdata(actor, grailId, itemEntry)
  1605. end
  1606. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo)
  1607. end
  1608. --- 获取圣杯信息
  1609. --- @param actor table 角色对象
  1610. --- @param grailId number 圣杯id
  1611. --- @return table 所有圣杯信息
  1612. function this.getGrailInfo(actor, grailId)
  1613. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1614. if table.isNullOrEmpty(grailInfo) then
  1615. grailInfo = {}
  1616. end
  1617. local itemExtData = getitemextdata(actor, grailId)
  1618. if not table.isNullOrEmpty(grailInfo) and not table.isNullOrEmpty(grailInfo[grailId]) then
  1619. local entryInfo = grailInfo[grailId]
  1620. local inlaid = entryInfo["inlaid"]
  1621. if table.isNullOrEmpty(itemExtData) and not inlaid then
  1622. setitemextdata(actor, grailId, grailInfo[grailId])
  1623. end
  1624. return grailInfo[grailId]
  1625. else
  1626. if not table.isNullOrEmpty(itemExtData) then
  1627. grailInfo[grailId] = itemExtData
  1628. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo)
  1629. end
  1630. return itemExtData
  1631. end
  1632. end
  1633. --- 获取所有圣杯信息
  1634. --- @param actor table 角色对象
  1635. --- @return table 所有圣杯信息
  1636. function this.getAllGrailInfo(actor)
  1637. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1638. return grailInfo
  1639. end
  1640. --- 发送圣杯红点
  1641. --- @param actor table 角色对象
  1642. function AngelMajorGrail.sendRedPoint(actor)
  1643. local result = AngelMajorGrail.checkEnter(actor)
  1644. local res = getplaydef(actor, "@tempangelgrailredpointresult")
  1645. if string.isNullOrEmpty(res) or res ~= result then
  1646. setplaydef(actor, "@tempangelgrailredpointresult", result)
  1647. RedPoint.sendOneRedPoint(actor, this.RedId, result)
  1648. end
  1649. end
  1650. --- 获取背包中的圣杯id
  1651. function AngelMajorGrail.getBagGrailIds(actor)
  1652. local bagItems = getallbagitem(actor)
  1653. local grailIds = {}
  1654. if not table.isNullOrEmpty(bagItems) then
  1655. for _, v in pairs(bagItems) do
  1656. local cfgId = v["cfg_id"]
  1657. if this.isAngelGrail(cfgId) then
  1658. table.insert(grailIds, v["id"])
  1659. end
  1660. end
  1661. end
  1662. return grailIds
  1663. end
  1664. --- 获取圣杯融合总数与平均强化等级
  1665. --- @param actor table 角色对象
  1666. --- @param mathType number 计算方式 1:向下取整 2:向上取整 3:四舍五入
  1667. --- @return number count, number level 融合总数,平均强化等级
  1668. function AngelMajorGrail.getAverageInfo(actor, mathType)
  1669. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1670. if table.isNullOrEmpty(grailInfo) then
  1671. return 0, 0
  1672. end
  1673. local level = 0
  1674. local count = 0
  1675. for _, v in pairs(grailInfo) do
  1676. if v["inlaid"] then
  1677. level = level + v["level"]
  1678. count = count + 1
  1679. end
  1680. end
  1681. if MathType.FLOOR == mathType then
  1682. return count, math.floor(level / count)
  1683. elseif MathType.CEIL == mathType then
  1684. return count, math.ceil(level / count)
  1685. else
  1686. return count, math.round(level / count)
  1687. end
  1688. end
  1689. --- 配表修改后数据错乱清理
  1690. --- @param actor table 角色对象
  1691. function this.angelGrailDataClean(actor)
  1692. local isClean = getplaydef(actor, "T$_angelGrailDataClean")
  1693. if string.isNullOrEmpty(isClean) then
  1694. jprint(
  1695. string.format(
  1696. "==============================>%s圣杯数据开始清洗now:%s",
  1697. getbaseinfo(actor, "rolename"),
  1698. TimeUtil.timeFormat(getbaseinfo("nowsec"))
  1699. )
  1700. )
  1701. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1702. if not table.isNullOrEmpty(grailInfo) then
  1703. for _, entry in pairs(grailInfo) do
  1704. local mainEntry = entry["main"]
  1705. local secondaryEntry = entry["secondary"]
  1706. if not table.isNullOrEmpty(mainEntry) then
  1707. for _, v in pairs(mainEntry) do
  1708. local id = v["id"]
  1709. local fixValues = ConfigDataManager.getTable("cfg_equip_angelEntry_fixes", "oldid", id)
  1710. if not table.isNullOrEmpty(fixValues) then
  1711. local newId = tonumber(fixValues[1]["newid"])
  1712. local oldAttMax = tonumber(fixValues[1]["oldattmax"])
  1713. local value = tonumber(v["value"])
  1714. local attMax =
  1715. ConfigDataManager.getTableValue("cfg_equip_angelEntry", "attMax", "id", newId)
  1716. if not string.isNullOrEmpty(attMax) then
  1717. if string.contains(attMax, "#") then
  1718. local att =
  1719. ConfigDataManager.getTableValue("cfg_equip_angelEntry", "att", "id", newId)
  1720. local attrId = v["attrId"]
  1721. local split1 = string.split(att, "|")
  1722. local split2 = string.split(split1[1], "#")
  1723. if table.contains(split2, tostring(attrId)) then
  1724. attMax = tonumber(string.split(attMax, "#")[1])
  1725. else
  1726. attMax = tonumber(string.split(attMax, "#")[2])
  1727. end
  1728. else
  1729. attMax = tonumber(attMax)
  1730. end
  1731. if value > tonumber(attMax) then
  1732. value = tonumber(math.floor(tonumber(attMax) * (value / oldAttMax)))
  1733. end
  1734. end
  1735. v["id"] = newId
  1736. v["value"] = value
  1737. end
  1738. end
  1739. end
  1740. if not table.isNullOrEmpty(secondaryEntry) then
  1741. for _, v in pairs(secondaryEntry) do
  1742. for _, secondEntry in pairs(v) do
  1743. local id = secondEntry["id"]
  1744. local fixValues = ConfigDataManager.getTable("cfg_equip_angelEntry_fixes", "oldid", id)
  1745. if not table.isNullOrEmpty(fixValues) then
  1746. local newId = tonumber(fixValues[1]["newid"])
  1747. local oldAttMax = tonumber(fixValues[1]["oldattmax"])
  1748. local value = tonumber(secondEntry["value"])
  1749. local attMax =
  1750. ConfigDataManager.getTableValue("cfg_equip_angelEntry", "attMax", "id", newId)
  1751. if not string.isNullOrEmpty(attMax) then
  1752. if string.contains(attMax, "#") then
  1753. local att =
  1754. ConfigDataManager.getTableValue("cfg_equip_angelEntry", "att", "id", newId)
  1755. local attrId = v["attrId"]
  1756. local split1 = string.split(att, "|")
  1757. local split2 = string.split(split1[1], "#")
  1758. if table.contains(split2, tostring(attrId)) then
  1759. attMax = tonumber(string.split(attMax, "#")[1])
  1760. else
  1761. attMax = tonumber(string.split(attMax, "#")[2])
  1762. end
  1763. else
  1764. attMax = tonumber(attMax)
  1765. end
  1766. if value > tonumber(attMax) then
  1767. value = tonumber(math.floor(tonumber(attMax) * (value / oldAttMax)))
  1768. end
  1769. end
  1770. secondEntry["id"] = newId
  1771. secondEntry["value"] = value
  1772. end
  1773. end
  1774. end
  1775. end
  1776. end
  1777. end
  1778. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo)
  1779. setplaydef(actor, "T$_angelGrailDataClean", 1)
  1780. end
  1781. end
  1782. RedPointEventListerTable:eventLister("0", "大天使圣杯", this.loginRed)
  1783. ZeroEventListerTable:eventLister("0", "大天使圣杯排行榜膜拜重置", this.zeroEvent)
  1784. ZeroEventListerTable:eventLister("0", "大天使圣杯脏数据清理", this.dirtyDataClear)
  1785. LoginEventListerTable:eventLister("0", "大天使圣杯脏数据清理", this.loginDirtyDataClear)
  1786. LoginEventListerTable:eventLister("0", "大天使圣杯改表数据错乱清理", this.angelGrailDataClean)