AngelMajorGrail.lua 70 KB

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