AngelMajorGrail_1.lua 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788
  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. }, 9999, "镶嵌圣杯")
  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. -- 备用
  1309. ---- 只对传入的 play 做重置,不再遍历所有玩家
  1310. -- if not play then
  1311. -- return
  1312. -- end
  1313. -- -- 记录一次性日志(可选)
  1314. -- local logText = "重置大天使圣杯排行榜膜拜信息 for play:%s now:%s"
  1315. -- gameDebug.print(string.format(logText, tostring(getbaseinfo(play, "rolename") or "unknown"), TimeUtil.timeFormat(getbaseinfo("nowsec"))))
  1316. -- setplaydef(play, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO, {})
  1317. -- setplaydef(play, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO, {})
  1318. end
  1319. --- 玩家登录清除圣杯分解造成的脏数据
  1320. --- @param actor table 角色对象
  1321. function this.loginDirtyDataClear(actor)
  1322. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1323. if table.isNullOrEmpty(grailInfo) then
  1324. return
  1325. end
  1326. local flag = "2024_03_28_10_00"
  1327. local mark = getplaydef(actor, "T$_angelGrailDirtyDataClear")
  1328. if type(mark) ~= "string" or mark ~= flag then
  1329. jprint(string.format("==============================>%s开始清除圣杯脏数据now:%s",
  1330. getbaseinfo(actor, "rolename"), TimeUtil.timeFormat(getbaseinfo("nowsec"))))
  1331. local itemIds = {}
  1332. -- 交易行圣杯id汇总,不做脏数据清理
  1333. local goodsList = getsysvar(actor, SYS_TRADE_WORLD_GOODS)
  1334. if not table.isNullOrEmpty(goodsList) then
  1335. local goods = goodsList[actor:toString()]
  1336. if not table.isNullOrEmpty(goods) then
  1337. for itemId, value in pairs(goods) do
  1338. local itemCfgId = value["itemcfgid"]
  1339. if this.isAngelGrail(itemCfgId) then
  1340. table.insert(itemIds, tonumber(itemId))
  1341. end
  1342. end
  1343. end
  1344. end
  1345. local bagItems = getallbagitem(actor)
  1346. if not table.isNullOrEmpty(bagItems) then
  1347. for _, v in pairs(bagItems) do
  1348. local cfgId = v["cfg_id"]
  1349. if this.isAngelGrail(cfgId) then
  1350. local id = v["id"]
  1351. if table.isNullOrEmpty(grailInfo[id]) then
  1352. this.initGrailInfo(actor, id, cfgId)
  1353. end
  1354. table.insert(itemIds, id)
  1355. end
  1356. end
  1357. end
  1358. local storeMaxPage = getstoremaxpage(actor)
  1359. for i = 1, storeMaxPage do
  1360. local storeItem = getalliteminfoinstore(actor, i)
  1361. if not table.isNullOrEmpty(storeItem) then
  1362. for _, v in pairs(storeItem) do
  1363. local cfgId = v["cfgid"]
  1364. if this.isAngelGrail(cfgId) then
  1365. local id = v["id"]
  1366. if table.isNullOrEmpty(grailInfo[id]) then
  1367. this.initGrailInfo(actor, id, cfgId)
  1368. end
  1369. table.insert(itemIds, id)
  1370. end
  1371. end
  1372. end
  1373. end
  1374. -- fixtodo 如果玩家存在卸下的带有圣杯的装备,这样清理会把玩家卸下装备上面的圣杯数据丢失
  1375. local equipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA)
  1376. if not table.isNullOrEmpty(equipInfo) then
  1377. for _, v in pairs(equipInfo) do
  1378. local grails = v["grails"]
  1379. if not table.isNullOrEmpty(grails) then
  1380. for grailId, value in pairs(grails) do
  1381. local cfgId = value["itemConfigId"]
  1382. if table.isNullOrEmpty(grailInfo[grailId]) then
  1383. this.initGrailInfo(actor, grailId, cfgId)
  1384. end
  1385. table.insert(itemIds, grailId)
  1386. end
  1387. end
  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. --- @param actor table 角色对象
  1419. function this.dirtyDataClear(actor)
  1420. -- local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1421. -- if table.isNullOrEmpty(grailInfo) then
  1422. -- return
  1423. -- end
  1424. -- jprint(string.format("==============================>%s开始清除圣杯脏数据now:%s",
  1425. -- getbaseinfo(actor, "rolename"), TimeUtil.timeFormat(getbaseinfo("nowsec"))))
  1426. -- local itemIds = {}
  1427. -- local existsGrailId = {}
  1428. -- -- 交易行圣杯id汇总,不做脏数据清理
  1429. -- local goodsList = getsysvar(actor, SYS_TRADE_WORLD_GOODS)
  1430. -- if not table.isNullOrEmpty(goodsList) then
  1431. -- local goods = goodsList[actor:toString()]
  1432. -- if not table.isNullOrEmpty(goods) then
  1433. -- for itemId, value in pairs(goods) do
  1434. -- local itemCfgId = value["itemcfgid"]
  1435. -- if this.isAngelGrail(itemCfgId) then
  1436. -- table.insert(itemIds, tonumber(itemId))
  1437. -- end
  1438. -- end
  1439. -- end
  1440. -- end
  1441. -- local bagItems = getallbagitem(actor)
  1442. -- if not table.isNullOrEmpty(bagItems) then
  1443. -- for _, v in pairs(bagItems) do
  1444. -- local cfgId = v["cfg_id"]
  1445. -- if this.isAngelGrail(cfgId) then
  1446. -- local id = v["id"]
  1447. -- if table.isNullOrEmpty(grailInfo[id]) then
  1448. -- this.initGrailInfo(actor, id, cfgId)
  1449. -- end
  1450. -- table.insert(itemIds, id)
  1451. -- table.insert(existsGrailId, id)
  1452. -- end
  1453. -- end
  1454. -- end
  1455. -- local storeMaxPage = getstoremaxpage(actor)
  1456. -- for i = 1, storeMaxPage do
  1457. -- local storeItem = getalliteminfoinstore(actor, i)
  1458. -- if not table.isNullOrEmpty(storeItem) then
  1459. -- for _, v in pairs(storeItem) do
  1460. -- local cfgId = v["cfgid"]
  1461. -- if this.isAngelGrail(cfgId) then
  1462. -- local id = v["id"]
  1463. -- if table.isNullOrEmpty(grailInfo[id]) then
  1464. -- this.initGrailInfo(actor, id, cfgId)
  1465. -- end
  1466. -- table.insert(itemIds, id)
  1467. -- end
  1468. -- end
  1469. -- end
  1470. -- end
  1471. -- -- fixtodo 如果玩家存在卸下的带有圣杯的装备,这样清理会把玩家卸下装备上面的圣杯数据丢失
  1472. -- local equipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA)
  1473. -- if not table.isNullOrEmpty(equipInfo) then
  1474. -- for _, v in pairs(equipInfo) do
  1475. -- local grails = v["grails"]
  1476. -- if not table.isNullOrEmpty(grails) then
  1477. -- for grailId, value in pairs(grails) do
  1478. -- local cfgId = value["itemConfigId"]
  1479. -- if table.isNullOrEmpty(grailInfo[grailId]) then
  1480. -- this.initGrailInfo(actor, grailId, cfgId)
  1481. -- end
  1482. -- table.insert(itemIds, grailId)
  1483. -- end
  1484. -- end
  1485. -- end
  1486. -- end
  1487. -- grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1488. -- local allGrailIds = {}
  1489. -- for itemId, _ in pairs(grailInfo) do
  1490. -- if not table.contains(itemIds, itemId) then
  1491. -- local itemExtData = getitemextdata(actor, itemId)
  1492. -- if table.isNullOrEmpty(itemExtData) then
  1493. -- grailInfo[itemId] = nil
  1494. -- end
  1495. -- end
  1496. -- table.insert(allGrailIds, itemId)
  1497. -- end
  1498. -- setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo)
  1499. -- -- 大天使装备上圣杯数据清理
  1500. -- if not table.isNullOrEmpty(equipInfo) then
  1501. -- for _, v in pairs(equipInfo) do
  1502. -- local grails = v["grails"]
  1503. -- if not table.isNullOrEmpty(grails) then
  1504. -- for grailId, _ in pairs(grails) do
  1505. -- if not table.contains(allGrailIds, grailId) then
  1506. -- grails[grailId] = nil
  1507. -- end
  1508. -- end
  1509. -- end
  1510. -- end
  1511. -- end
  1512. -- setplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA, equipInfo)
  1513. -- for _, grailId in pairs(existsGrailId) do
  1514. -- local entryInfo = this.getGrailInfo(actor, grailId)
  1515. -- if not table.isNullOrEmpty(entryInfo) then
  1516. -- info(actor, "将玩家变量中的圣杯信息放入道具lua扩展数据中 grailId", grailId, "entryInfo", entryInfo)
  1517. -- setitemextdata(actor, grailId, entryInfo)
  1518. -- end
  1519. -- end
  1520. end
  1521. --- 合服清空排行榜数据
  1522. function AngelMajorGrail.combine()
  1523. local hosts = gethosts()
  1524. for _, host in ipairs(hosts) do
  1525. setsysvar(host, SystemVarConst.ANGEL_GRAIL_RANKING_INFO, {})
  1526. setsysvar(host, SystemVarConst.ANGEL_GRAIL_CROSS_RANKING_INFO, {})
  1527. end
  1528. end
  1529. --- 保存/移除圣杯信息
  1530. --- @param actor table 角色对象
  1531. --- @param grailId number 圣杯id
  1532. --- @param itemEntry table 圣杯信息
  1533. function this.saveOrRemoveGrailInfo(actor, grailId, itemEntry)
  1534. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1535. if table.isNullOrEmpty(grailInfo) then
  1536. grailInfo = {}
  1537. end
  1538. if table.isNullOrEmpty(itemEntry) then
  1539. grailInfo[grailId] = nil
  1540. else
  1541. grailInfo[grailId] = itemEntry
  1542. setitemextdata(actor, grailId, itemEntry)
  1543. end
  1544. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo)
  1545. end
  1546. --- 获取圣杯信息
  1547. --- @param actor table 角色对象
  1548. --- @param grailId number 圣杯id
  1549. --- @return table 所有圣杯信息
  1550. function this.getGrailInfo(actor, grailId)
  1551. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1552. if table.isNullOrEmpty(grailInfo) then
  1553. grailInfo = {}
  1554. end
  1555. local itemExtData = getitemextdata(actor, grailId)
  1556. if not table.isNullOrEmpty(grailInfo) and not table.isNullOrEmpty(grailInfo[grailId]) then
  1557. local entryInfo = grailInfo[grailId]
  1558. local inlaid = entryInfo["inlaid"]
  1559. if table.isNullOrEmpty(itemExtData) and not inlaid then
  1560. setitemextdata(actor, grailId, grailInfo[grailId])
  1561. end
  1562. return grailInfo[grailId]
  1563. else
  1564. if not table.isNullOrEmpty(itemExtData) then
  1565. grailInfo[grailId] = itemExtData
  1566. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo)
  1567. end
  1568. return itemExtData
  1569. end
  1570. end
  1571. --- 获取所有圣杯信息
  1572. --- @param actor table 角色对象
  1573. --- @return table 所有圣杯信息
  1574. function this.getAllGrailInfo(actor)
  1575. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1576. return grailInfo
  1577. end
  1578. --- 发送圣杯红点
  1579. --- @param actor table 角色对象
  1580. function AngelMajorGrail.sendRedPoint(actor)
  1581. local result = AngelMajorGrail.checkEnter(actor)
  1582. local res = getplaydef(actor, "@tempangelgrailredpointresult")
  1583. if string.isNullOrEmpty(res) or res ~= result then
  1584. setplaydef(actor, "@tempangelgrailredpointresult", result)
  1585. RedPoint.sendOneRedPoint(actor, this.RedId, result)
  1586. end
  1587. end
  1588. --- 获取背包中的圣杯id
  1589. function AngelMajorGrail.getBagGrailIds(actor)
  1590. local bagItems = getallbagitem(actor)
  1591. local grailIds = {}
  1592. if not table.isNullOrEmpty(bagItems) then
  1593. for _, v in pairs(bagItems) do
  1594. local cfgId = v["cfg_id"]
  1595. if this.isAngelGrail(cfgId) then
  1596. table.insert(grailIds, v["id"])
  1597. end
  1598. end
  1599. end
  1600. return grailIds
  1601. end
  1602. --- 获取圣杯融合总数与平均强化等级
  1603. --- @param actor table 角色对象
  1604. --- @param mathType number 计算方式 1:向下取整 2:向上取整 3:四舍五入
  1605. --- @return number count, number level 融合总数,平均强化等级
  1606. function AngelMajorGrail.getAverageInfo(actor, mathType)
  1607. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1608. if table.isNullOrEmpty(grailInfo) then
  1609. return 0, 0
  1610. end
  1611. local level = 0
  1612. local count = 0
  1613. for _, v in pairs(grailInfo) do
  1614. if v["inlaid"] then
  1615. level = level + v["level"]
  1616. count = count + 1
  1617. end
  1618. end
  1619. if MathType.FLOOR == mathType then
  1620. return count, math.floor(level / count)
  1621. elseif MathType.CEIL == mathType then
  1622. return count, math.ceil(level / count)
  1623. else
  1624. return count, math.round(level / count)
  1625. end
  1626. end
  1627. --- 配表修改后数据错乱清理
  1628. --- @param actor table 角色对象
  1629. function this.angelGrailDataClean(actor)
  1630. local isClean = getplaydef(actor, "T$_angelGrailDataClean")
  1631. if string.isNullOrEmpty(isClean) then
  1632. jprint(string.format("==============================>%s圣杯数据开始清洗now:%s",
  1633. getbaseinfo(actor, "rolename"), TimeUtil.timeFormat(getbaseinfo("nowsec"))))
  1634. local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO)
  1635. if not table.isNullOrEmpty(grailInfo) then
  1636. for _, entry in pairs(grailInfo) do
  1637. local mainEntry = entry["main"]
  1638. local secondaryEntry = entry["secondary"]
  1639. if not table.isNullOrEmpty(mainEntry) then
  1640. for _, v in pairs(mainEntry) do
  1641. local id = v["id"]
  1642. local fixValues = ConfigDataManager.getTable("cfg_equip_angelEntry_fixes", "oldid", id)
  1643. if not table.isNullOrEmpty(fixValues) then
  1644. local newId = tonumber(fixValues[1]["newid"])
  1645. local oldAttMax = tonumber(fixValues[1]["oldattmax"])
  1646. local value = tonumber(v["value"])
  1647. local attMax = ConfigDataManager.getTableValue("cfg_equip_angelEntry", "attMax", "id", newId)
  1648. if not string.isNullOrEmpty(attMax) then
  1649. if string.contains(attMax, "#") then
  1650. local att = ConfigDataManager.getTableValue("cfg_equip_angelEntry", "att", "id", newId)
  1651. local attrId = v["attrId"]
  1652. local split1 = string.split(att, "|")
  1653. local split2 = string.split(split1[1], "#")
  1654. if table.contains(split2, tostring(attrId)) then
  1655. attMax = tonumber(string.split(attMax, "#")[1])
  1656. else
  1657. attMax = tonumber(string.split(attMax, "#")[2])
  1658. end
  1659. else
  1660. attMax = tonumber(attMax)
  1661. end
  1662. if value > tonumber(attMax) then
  1663. value = tonumber(math.floor(tonumber(attMax) * (value / oldAttMax)))
  1664. end
  1665. end
  1666. v["id"] = newId
  1667. v["value"] = value
  1668. end
  1669. end
  1670. end
  1671. if not table.isNullOrEmpty(secondaryEntry) then
  1672. for _, v in pairs(secondaryEntry) do
  1673. for _, secondEntry in pairs(v) do
  1674. local id = secondEntry["id"]
  1675. local fixValues = ConfigDataManager.getTable("cfg_equip_angelEntry_fixes", "oldid", id)
  1676. if not table.isNullOrEmpty(fixValues) then
  1677. local newId = tonumber(fixValues[1]["newid"])
  1678. local oldAttMax = tonumber(fixValues[1]["oldattmax"])
  1679. local value = tonumber(secondEntry["value"])
  1680. local attMax = ConfigDataManager.getTableValue("cfg_equip_angelEntry", "attMax", "id", newId)
  1681. if not string.isNullOrEmpty(attMax) then
  1682. if string.contains(attMax, "#") then
  1683. local att = ConfigDataManager.getTableValue("cfg_equip_angelEntry", "att", "id", newId)
  1684. local attrId = v["attrId"]
  1685. local split1 = string.split(att, "|")
  1686. local split2 = string.split(split1[1], "#")
  1687. if table.contains(split2, tostring(attrId)) then
  1688. attMax = tonumber(string.split(attMax, "#")[1])
  1689. else
  1690. attMax = tonumber(string.split(attMax, "#")[2])
  1691. end
  1692. else
  1693. attMax = tonumber(attMax)
  1694. end
  1695. if value > tonumber(attMax) then
  1696. value = tonumber(math.floor(tonumber(attMax) * (value / oldAttMax)))
  1697. end
  1698. end
  1699. secondEntry["id"] = newId
  1700. secondEntry["value"] = value
  1701. end
  1702. end
  1703. end
  1704. end
  1705. end
  1706. end
  1707. setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo)
  1708. setplaydef(actor, "T$_angelGrailDataClean", 1)
  1709. end
  1710. end
  1711. RedPointEventListerTable:eventLister("0", "大天使圣杯", this.loginRed)
  1712. ZeroEventListerTable:eventLister("0", "大天使圣杯排行榜膜拜重置", this.zeroEvent)
  1713. ZeroEventListerTable:eventLister("0", "大天使圣杯脏数据清理", this.dirtyDataClear)
  1714. LoginEventListerTable:eventLister("0", "大天使圣杯脏数据清理", this.loginDirtyDataClear)
  1715. LoginEventListerTable:eventLister("0", "大天使圣杯改表数据错乱清理", this.angelGrailDataClean)