AngelMajorGrail.lua 59 KB

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