AngelMajorGrail.lua 71 KB

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