--- 大天使圣杯 --- Generated by EmmyLua(https://github.com/EmmyLua) --- Created by zhoutao. --- DateTime: 2024/11/19 20:36 AngelMajorGrail = {} local this = AngelMajorGrail this.RedId = 102 this.canWorshipRedId = 107 --- 获取所有圣杯词条信息 --- @param actor table 角色对象 --- @param isInlaid boolean 是否镶嵌 function AngelMajorGrail.getAllGrailInfo(actor, isInlaid) local grailIds = AngelMajorGrail.getInlaidGrailIds(actor) local entryInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) local res = {} if not table.isNullOrEmpty(entryInfo) then for key, entry in pairs(entryInfo) do if not table.hasKey(entry, "score") then entry = this.calcGrailScore(entry) end if table.contains(grailIds, key) then entry["active"] = true if isInlaid then res[key] = entry end else if not isInlaid then res[key] = entry end end end end sendluamsg(actor, LuaMessageIdToClient.RES_ALL_GRAIL_INFO, res) end -- 判断单个圣杯是否激活 function this.isActiveGrail(actor, grailId) local grailIds = AngelMajorGrail.getInlaidGrailIds(actor) return table.contains(grailIds, grailId) end --- 获取装备下镶嵌的圣杯词条信息 --- @param actor table 角色对象 --- @param equipId number 装备id --- @param itemId number 圣杯id function AngelMajorGrail.getEquipAllEntryInfo(actor, equipId, itemId) local equipAttr = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA) if table.isNullOrEmpty(equipAttr) then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.getEquipAllEntryInfo equipAttr is nil") return end local equipInfo = equipAttr[equipId] if table.isNullOrEmpty(equipInfo) then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.getEquipAllEntryInfo equipInfo is nil") return end local grails = equipInfo["grails"] local res = {} if not table.isNullOrEmpty(grails) then local entryInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if itemId then local info = grails[itemId] local temp = this.combineRes(itemId, info, entryInfo) local attrInfo = temp["attrInfo"] if attrInfo and this.isActiveGrail(actor, itemId) then attrInfo["active"] = true end table.insert(res, temp) else for grailId, info in pairs(grails) do local temp = this.combineRes(grailId, info, entryInfo) local attrInfo = temp["attrInfo"] if attrInfo and this.isActiveGrail(actor, grailId) then attrInfo["active"] = true end table.insert(res, temp) end end end sendluamsg(actor, LuaMessageIdToClient.RES_EQUIP_ALL_ENTRY_INFO, res) end --- 镶嵌圣杯 --- @param actor table 角色对象 --- @param msgData table 消息数据 function AngelMajorGrail.inlayGrail(actor, msgData) -- 装备id local equipId = msgData["equipId"] -- 装备配置id local equipConfigId = msgData["equipConfigId"] -- 圣杯id local grailId = msgData["itemId"] -- 圣杯配置id local itemConfigId = msgData["itemConfigId"] local tableValue = this.isAngelGrail(itemConfigId) if not tableValue then return end -- 圣杯在背包中的索引,因为目前没有根据唯一id删除道具的接口,所以使用索引进行删除 local index = msgData["index"] -- 镶嵌孔位 local position = msgData["position"] -- 判断部位是否符合镶嵌 local strPart = ConfigDataManager.getTableValue("cfg_item", "strPart", "id", equipConfigId) local partSplit = string.split(strPart, "#") local grailPart = tableValue[1]["strpart"] local grailParts = string.split(grailPart, "#") local isMatch = false for _, v in pairs(partSplit) do if table.contains(grailParts, v) then isMatch = true end end if not isMatch then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail part match false equipConfigId", equipConfigId, " grailConfigId", itemConfigId) return end -- 获取装备成长属性信息 local equipAttr = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA) if table.isNullOrEmpty(equipAttr) then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail equipAttr is nil") return end local equipInfo = equipAttr[equipId] if table.isNullOrEmpty(equipInfo) then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail equipInfo is nil") return end -- 获取圣杯词条信息 local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if table.isNullOrEmpty(grailInfo) then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail grailInfo is nil") return end -- 判断圣杯等阶是否满足融合条件 local equipRank = equipInfo["rank"] local entryInfo = grailInfo[grailId] if table.isNullOrEmpty(entryInfo) then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail entryInfo is nil") return end local grailGrade = entryInfo["grailGrade"] if grailGrade > equipRank then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail grailGrade > equipRank") return end local grails = equipInfo["grails"] if not table.isNullOrEmpty(grails) then if table.getValue(grails, grailId) then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.inlayGrail equip already has this grail") return else grails[grailId] = { ["itemConfigId"] = itemConfigId, ["grailPosition"] = position, ["level"] = entryInfo["level"], } end else grails = {} grails[grailId] = { ["itemConfigId"] = itemConfigId, ["grailPosition"] = position, ["level"] = entryInfo["level"], } end equipInfo["grails"] = grails setplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA, equipAttr) entryInfo["inlaid"] = true info(actor, actor,"镶嵌圣杯后的信息", "装备id", equipId, "圣杯id", grailId) setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo) -- 给角色添加属性 AngelMajorGrail.grailAttrHandle(actor, entryInfo, grailId, true) -- 移除背包中的圣杯 removeitembyidxlist(actor, { [index] = 1 }) AngelMajorGrail.getEquipAllEntryInfo(actor, equipId, grailId) -- 红点判断 local result = AngelMajorGrail.checkEnter(actor) RedPoint.sendOneRedPoint(actor, this.RedId, result) -- 触发任务刷新 TaskHandler.TriggerTaskGoal(actor, TaskTargetType.TAKE_ON_GRAIL_COUNT) TaskHandler.TriggerTaskGoal(actor, TaskTargetType.STRENGTHEN_GRAIL) -- 判断是否满足大天使圣杯套装并增加属性 AngelMajorGrail.checkAngelGrailSuitCondition(actor) end --- 卸下圣杯 --- @param actor table 角色对象 --- @param msgData table 消息数据 function AngelMajorGrail.unloadGrail(actor, msgData) -- 装备id local equipId = msgData["equipId"] -- 圣杯id local grailId = msgData["itemId"] local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) local entryInfo = grailInfo[grailId] if table.isNullOrEmpty(entryInfo) then error("grailId error") return end -- 道具配置id local itemConfigId = msgData["itemConfigId"] -- 判断背包是否能放得下,放不下不能卸并提示 local paramMap = {} paramMap["cfgid"] = itemConfigId paramMap["itemcount"] = 1 local param = { paramMap } local canPut = checkitemscanputbag(actor, param) if tonumber(canPut) == 0 then noticeTip.noticeinfo(actor, StringIdConst.TEXT29001) return end -- 去除装备属性中的指定圣杯信息 local equipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA) if not table.isNullOrEmpty(equipInfo) then local equipAttr = equipInfo[equipId] if not table.isNullOrEmpty(equipAttr) then local grails = equipAttr["grails"] or {} if not table.hasKey(grails, grailId) then tipinfo(actor, "该装备下没有该圣杯") info(actor, actor, "该装备下没有该圣杯".." 装备id:"..equipId.." 圣杯id:"..grailId) return end grails[grailId] = nil setplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA, equipInfo) end end -- 生成道具放入背包 local itemId = additemtobag(actor, itemConfigId, 1, 0, 9999, ItemAction.ANGEL_GRAIL_UNLOAD) if not itemId or tonumber(itemId) <= 0 then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.unloadGrail additemtobag failed") return end -- 将旧的圣杯id替换为新的圣杯id grailInfo[itemId] = entryInfo grailInfo[grailId] = nil grailInfo[itemId]["inlaid"] = false info(actor, actor,"卸下后的圣杯信息: ","装备id",equipId,"原圣杯id",grailId,"新生杯id",itemId,"卸下后的原圣杯信息",grailInfo[itemId]) setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo) -- 移除之前增加的属性 AngelMajorGrail.grailAttrHandle(actor, grailInfo[itemId], grailId, false) -- 响应客户端镶嵌的圣杯信息 AngelMajorGrail.getEquipAllEntryInfo(actor, equipId) -- 响应圣杯信息 local info = grailInfo[itemId] -- if this.isActiveGrail(actor, itemId) then -- 正常这里肯定是没激活 -- info["active"] = true -- end sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_ENTRY_INFO, { [itemId] = info and info or {} }) -- 红点判断 local result = AngelMajorGrail.checkEnter(actor) RedPoint.sendOneRedPoint(actor, this.RedId, result) -- 触发任务刷新 TaskHandler.TriggerTaskGoal(actor, TaskTargetType.TAKE_ON_GRAIL_COUNT) TaskHandler.TriggerTaskGoal(actor, TaskTargetType.STRENGTHEN_GRAIL) -- 判断是否满足大天使圣杯套装并增加属性 AngelMajorGrail.checkAngelGrailSuitCondition(actor) end --- 强化圣杯词条 --- @param actor table 角色对象 --- @param msgData table 消息数据 function AngelMajorGrail.strengthenGrail(actor, msgData) -- 圣杯id local grailId = msgData["itemId"] -- 道具配置id local itemConfigId = msgData["itemConfigId"] -- 获取道具对应的强化组 local strengthenGroup = ConfigDataManager.getTableValue("cfg_equip_angelStrengthen", "costGroup", "id", itemConfigId) -- 获取当前圣杯的等级 local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if not table.isNullOrEmpty(grailInfo) then local entryInfo = grailInfo[grailId] if not table.isNullOrEmpty(entryInfo) then local grailLevel = entryInfo["level"] local tableValue = ConfigDataManager.getTable("cfg_equip_angelStrengthenCost", "AngelstrengthenGroup", strengthenGroup, "AngelstrengthenLv", grailLevel) if table.isNullOrEmpty(tableValue) then gameDebug.print(getbaseinfo(actor, "rolename"), " AngelMajorGrail.strengthenGrail cfg_equip_angelStrengthenCost is nil") return end -- 强化消耗材料充足判断 local strengthenCost = tableValue[1]["angelstrengthencost"] local costMap = string.toIntIntMap(strengthenCost, "#", "|") local enough = Bag.checkCostMap(actor, costMap) if not enough then noticeTip.noticeinfo(actor, StringIdConst.TEXT351) return end -- 具体强化逻辑 -- 消耗道具 for cfgId, count in pairs(costMap) do Bag.cost(actor, cfgId, count, ItemAction.ANGEL_GRAIL_STRENGTHEN_COST) end -- 强化成功率 local successRate = tableValue[1]["angelstrengthensuccessrate"] local success = math.random(1, 100) <= (tonumber(successRate) and tonumber(successRate) or 0) if success then -- 获取主副词条信息 local mainEntry = entryInfo["main"] local secondaryEntry = entryInfo["secondary"] -- 主词条强化 for _, entry in pairs(mainEntry) do if not entry["isMax"] then this.strengthen(entry) end end -- 副词条强化 local entryWeightMap = {} for _, v in pairs(secondaryEntry) do for _, entry in pairs(v) do if not entry["isMax"] then entryWeightMap[entry] = entry["weight"] end end end -- 根据权重选择一条词条强化 if not table.isNullOrEmpty(entryWeightMap) then local entry = randombyweight(entryWeightMap, 1, false)[1] this.strengthen(entry) -- 保存强化后的词条信息 for k1, v in pairs(secondaryEntry) do for k2, value in pairs(v) do if value["id"] == entry["id"] then secondaryEntry[k1][k2] = entry end end end entryInfo["level"] = grailLevel + 1 end grailInfo[grailId] = this.calcGrailScore(entryInfo) setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo) -- 先去除属性再增加属性 AngelMajorGrail.grailAttrHandle(actor, entryInfo, grailId, false) AngelMajorGrail.grailAttrHandle(actor, entryInfo, grailId, true) sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_ENTRY_STRENGTHEN_RESULT, success) if this.isActiveGrail(actor, grailId) then -- 正常这里应该是激活的 entryInfo["active"] = true end sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_ENTRY_INFO, { [grailId] = entryInfo and entryInfo or {} }) -- 增加大天使装备下的圣杯等级 AngelMajorEquipment.addGrailLevel(actor, grailId, grailLevel + 1) -- 触发任务刷新 TaskHandler.TriggerTaskGoal(actor, TaskTargetType.STRENGTHEN_GRAIL) else sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_ENTRY_STRENGTHEN_RESULT, success) end end end end --- 初始化大天使圣杯词条信息 --- @param actor table 角色对象 --- @param itemId number 道具id --- @param itemConfigId number 道具配置id function AngelMajorGrail.initGrailEntry(actor, itemId, itemConfigId) -- 延迟执行 -- intervalcalldelay(actor, 500, 1000, 1, "initgrailinfo", itemId, itemConfigId) AngelMajorGrail.initGrailInfo(actor, itemId, itemConfigId) end function AngelMajorGrail.initGrailInfo(actor, itemId, itemConfigId) -- 判断道具是否为圣杯 local tableValue = this.isAngelGrail(itemConfigId) if not tableValue then return end info(actor, actor,"尝试初始化圣杯词条信息", itemId, itemConfigId) local grailEntryInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if table.isNullOrEmpty(grailEntryInfo) then grailEntryInfo = {} end -- 获取圣杯主词条组 local mainEntryGroup = tableValue[1]["mainattgroup"] -- 获取圣杯随机词条组 local randomEntryGroup = tableValue[1]["randomattgroup"] -- 获取圣杯词条数量权重 local entryCountWeight = tableValue[1]["attcountweight"] -- 获取圣杯等阶 local grailGrade = tableValue[1]["grailgrade"] -- 获取圣杯孔位 local gradePosition = tableValue[1]["gradeposition"] local itemEntry = grailEntryInfo[itemId] if table.isNullOrEmpty(itemEntry) then itemEntry = {} -- 圣杯主词条信息初始化 local mainEntryInfo = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", mainEntryGroup) if table.isNullOrEmpty(mainEntryInfo) then jprint("AngelMajorGrail.initGrailAttr cfg_equip_angelEntry data is nil") return end local mainEntry = this.initEntry(mainEntryInfo[1]) itemEntry["main"] = mainEntry -- 圣杯副词条信息初始化 local secondary = {} local secondaryEntryInfo local secondaryCount --[[ 1代表从1词条组随一个 1#2代表从1和2词条组中随一个 1|1代表从1词条组随两个 分两种情况: 1.randomAttGroup字符串带竖线,需要根据attCountWeight计算出词条数量再随机生成对应条数的词条 2.randomAttGroup字符串不带竖线,判断是否带井号,带井号分割字符串,根据获得的词条组随机生成一条词条 3.randomAttGroup字符串不带竖线也不带井号,根据词条组随机生成一条词条 ]] if string.contains(randomEntryGroup, "|") then -- 第一种情况 local weightMap = string.toIntIntMap(entryCountWeight, "#", "|") -- 副词条初始化条数 secondaryCount = randombyweight(weightMap, 1, true)[1] local entryGroup = string.split(randomEntryGroup, "|")[1] secondaryEntryInfo = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", entryGroup) elseif string.contains(randomEntryGroup, "#") then -- 第二种情况 local group1 = string.split(randomEntryGroup, "#")[1] local group2 = string.split(randomEntryGroup, "#")[2] secondaryEntryInfo = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", group1) local tempEntry = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", group2) table.insertArray(secondaryEntryInfo, tempEntry) secondaryCount = 1 else -- 第三种情况 secondaryEntryInfo = ConfigDataManager.getTable("cfg_equip_angelEntry", "group", randomEntryGroup) secondaryCount = 1 end -- 获取根据权重生成的随机词条并设置 if not table.isNullOrEmpty(secondaryEntryInfo) then local randomResult = this.getRandomEntry(secondaryEntryInfo, secondaryCount) for _, v in pairs(randomResult) do local secondaryEntry = this.initEntry(secondaryEntryInfo[v]) table.insert(secondary, secondaryEntry) end itemEntry["secondary"] = secondary end itemEntry["grailGrade"] = tonumber(grailGrade) itemEntry["itemConfigId"] = itemConfigId itemEntry["grailPosition"] = tonumber(gradePosition) itemEntry["level"] = 0 itemEntry["inlaid"] = false grailEntryInfo[itemId] = itemEntry info(actor, actor,"初始化圣杯 id:",itemId) -- 计算评分 itemEntry = this.calcGrailScore(itemEntry) -- 保存词条信息 setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailEntryInfo) -- 响应客户端 -- if this.isActiveGrail(actor, itemId) then -- -- 正常这里肯定没激活 -- itemEntry["active"] = true -- end sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_ENTRY_INFO, { [itemId] = itemEntry and itemEntry or {} }) -- 红点判断 local result = AngelMajorGrail.checkEnter(actor) RedPoint.sendOneRedPoint(actor, this.RedId, result) end end --- 销毁圣杯 --- @param actor table 角色对象 --- @param cfgId number 道具配置id --- @param itemId number 道具id function AngelMajorGrail.destroyAngelGrail(actor, cfgId, itemId) local tableValue = this.isAngelGrail(cfgId) if not table.isNullOrEmpty(tableValue) then info(actor, actor,"销毁圣杯",itemId) local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if not table.isNullOrEmpty(grailInfo) then local grail = grailInfo[itemId] if not table.isNullOrEmpty(grail) then if grail["inlaid"] then tipinfo(actor, "含有镶嵌的圣杯不能消毁") return end -- 删除圣杯 grailInfo[itemId] = nil end end setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo) -- 红点判断 local result = AngelMajorGrail.checkEnter(actor) RedPoint.sendOneRedPoint(actor, this.RedId, result) end end --- 给角色增加圣杯词条属性 --- @param actor table 角色对象 --- @param entryInfo table 词条信息 --- @param grailId number 圣杯唯一id --- @param isAdd boolean 是否增加词条 function AngelMajorGrail.grailAttrHandle(actor, entryInfo, grailId, isAdd) if isAdd then local attrMap = {} local mainAttr = entryInfo["main"] if table.isNullOrEmpty(mainAttr) then return end for _, v in pairs(mainAttr) do local attrId = tonumber(v["attrId"]) local attrValue = tonumber(v["value"]) if table.getValue(attrMap, attrId) then attrMap[attrId] = attrMap[attrId] + attrValue else attrMap[attrId] = attrValue end end local secondaryAttr = entryInfo["secondary"] if table.isNullOrEmpty(secondaryAttr) then return end for _, v in pairs(secondaryAttr) do for _, value in pairs(v) do local attrId = tonumber(value["attrId"]) local attrValue = tonumber(value["value"]) if table.getValue(attrMap, attrId) then attrMap[attrId] = attrMap[attrId] + attrValue else attrMap[attrId] = attrValue end end end RoleAttr.addAndSaveRoleAttr(actor, string.format(RoleAttrKey.ANGEL_GRAIL, grailId), attrMap) else RoleAttr.clearRoleAttrAndDB(actor, string.format(RoleAttrKey.ANGEL_GRAIL, grailId)) end end --- 大天使圣杯分解 --- @param actor table 角色对象 --- @param msgData table 消息数据 function AngelMajorGrail.grailDecompose(actor, msgData) -- 圣杯索引集合 local indexList = msgData["indexList"] -- 圣杯唯一id集合 local grailIds = msgData["grailIds"] info(actor, actor,"大天使圣杯分解","圣杯ids:",grailIds) if table.isNullOrEmpty(grailIds) then return end local costMap = {} local getMap = {} local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) for _, grailId in pairs(grailIds) do local entryInfo = grailInfo[grailId] if not table.isNullOrEmpty(entryInfo) then if entryInfo["inlaid"] then tipinfo(actor, "含有镶嵌的圣杯不能分解") return end local itemConfigId = entryInfo["itemConfigId"] local level = entryInfo["level"] local group = ConfigDataManager.getTableValue("cfg_equip_angelStrengthen", "SplitGroup", "id", itemConfigId) if group then local tableValue = ConfigDataManager.getTable("cfg_equip_angelStrengthenCost", "AngelstrengthenGroup", group, "AngelstrengthenLv", level) local recoveryCost = tableValue[1]["recoverycost"] if recoveryCost then -- 检查消耗道具是否充足 costMap = string.putIntIntMap(costMap, recoveryCost, "#", "|") local enough = Bag.checkCostMap(actor, costMap) if not enough then noticeTip.noticeinfo(actor, StringIdConst.TEXT351) return end end local angelStrengthenGet = tableValue[1]["angelstrengthenget"] if angelStrengthenGet then -- 封装奖励map local itemMap = string.toIntIntMap(angelStrengthenGet, "#", "|") for k, v in pairs(itemMap) do local itemId = tonumber(k) local count = tonumber(v) if getMap[itemId] then getMap[itemId] = getMap[itemId] + count else getMap[itemId] = count end end end end end grailInfo[grailId] = nil end -- 消耗道具并发放奖励 if not table.isNullOrEmpty(getMap) and not table.isNullOrEmpty(costMap) then Bag.costMap(actor, costMap, ItemAction.ANGEL_GRAIL_DECOMPOSE_RECOVERY) Bag.sendRewards(actor, getMap, ItemAction.ANGEL_GRAIL_DECOMPOSE_REWARD) removeitembyidxlist(actor, indexList, 9999, ItemAction.ANGEL_GRAIL_DECOMPOSE) setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo) sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_DECOMPOSE_RESULT, true) -- 红点判断 local result = AngelMajorGrail.checkEnter(actor) RedPoint.sendOneRedPoint(actor, this.RedId, result) return end -- 红点判断 local result = AngelMajorGrail.checkEnter(actor) RedPoint.sendOneRedPoint(actor, this.RedId, result) sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_DECOMPOSE_RESULT, false) end --- 登录红点判断 --- @param actor table 角色对象 --- @return boolean 是否展示红点 function AngelMajorGrail.checkEnter(actor) -- 获取所有圣杯 local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if not table.isNullOrEmpty(grailInfo) then for _, v in pairs(grailInfo) do if not v["inlaid"] and this.checkRedPoint(actor, v["grailGrade"], v["grailPosition"], v["itemConfigId"]) then return true end end end return false end --- 获取指定玩家的指定大天使圣杯词条信息 ---@param actor table 角色对象 ---@param msgData table 消息数据 function AngelMajorGrail.getPlayerAngelGrailInfo(actor, msgData) local rid = msgData["rid"] local itemId = msgData["itemId"] local targetActor = getactor(actor, rid) local grailInfo = getplaydef(targetActor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if table.isNullOrEmpty(grailInfo) then return end local entryInfo = grailInfo[itemId] if table.isNullOrEmpty(entryInfo) then return end sendluamsg(actor, LuaMessageIdToClient.RES_OTHER_ANGE_GRAIL_INFO, { [itemId] = entryInfo }) end --- 获取身上穿戴的大天使装备镶嵌的所有圣杯id ---@param actor table 角色对象 ---@return table 圣杯id列表 function AngelMajorGrail.getInlaidGrailIds(actor) local grailIds = {} local equipIds = AngelMajorEquipment.getPutOnEquipIds(actor) if table.isNullOrEmpty(equipIds) then return grailIds end local equipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA) if table.isNullOrEmpty(equipInfo) then return grailIds end for k, v in pairs(equipInfo) do if table.contains(equipIds, k) then local grails = v["grails"] if not table.isNullOrEmpty(grails) then for grailId, _ in pairs(grails) do table.insert(grailIds, grailId) end end end end return grailIds end --- 获取指定玩家的指定大天使圣杯数量 ---@param actor table 角色对象 ---@param grailGrade number 圣杯等阶 ---@param grailQuality number 圣杯品质 ---@return number 数量 function AngelMajorGrail.getGrailCountByCondition(actor, grailGrade, grailQuality) grailGrade = tonumber(grailGrade) grailQuality = tonumber(grailQuality) local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if table.isNullOrEmpty(grailInfo) then return 0 end local count = 0 local inlaidGrailIds = AngelMajorGrail.getInlaidGrailIds(actor) if table.isNullOrEmpty(inlaidGrailIds) then return 0 end for k, v in pairs(grailInfo) do if table.contains(inlaidGrailIds, k) then if grailGrade ~= 0 then local grade = v["grailGrade"] if grade < grailGrade then goto next end end if grailQuality ~= 0 then local cfgId = v["itemConfigId"] local quality = ConfigDataManager.getTableValue("cfg_equip_angelGrail", "grailQuality", "id", cfgId) if tonumber(quality) < grailQuality then goto next end end count = count + 1 end :: next :: end return count end --- 获取身上所有已镶嵌的大天使圣杯达到指定强化等级的数量 ---@param actor table 角色对象 ---@param strengthLevel number 强化等级 ---@return number 数量 function AngelMajorGrail.getGrailCountByStrengthLevel(actor, strengthLevel) local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if table.isNullOrEmpty(grailInfo) then return 0 end local inlaidGrailIds = AngelMajorGrail.getInlaidGrailIds(actor) if table.isNullOrEmpty(inlaidGrailIds) then return 0 end local count = 0 for k, v in pairs(grailInfo) do if table.contains(inlaidGrailIds, k) then local level = v["level"] if level >= tonumber(strengthLevel) then count = count + 1 end end end return count end --- 检查是否满足大天使圣杯套装 ---@param actor table 角色对象 function AngelMajorGrail.checkAngelGrailSuitCondition(actor) local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if not table.isNullOrEmpty(grailInfo) then local maxGrade = 0 local temp = {} -- 获取身上镶嵌的所有圣杯id local inlaidGrailIds = AngelMajorGrail.getInlaidGrailIds(actor) -- 遍历获取圣杯数量与最大圣杯阶数 for _, grailId in pairs(inlaidGrailIds) do local v = grailInfo[grailId] local cfgId = v["itemConfigId"] temp[cfgId] = (temp[cfgId] and temp[cfgId] or 0) + 1 maxGrade = v["grailGrade"] > maxGrade and v["grailGrade"] or maxGrade end local grailSuitId = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_SUIT_ID) local tableId local attrInfo = {} -- 倒序循环判断是否满足套装 for i = maxGrade, 1, -1 do local total = 0 for j = 4, 1, -1 do local tableValue = ConfigDataManager.getTable("cfg_equip_angelGrailSuit", "group", i, "level", j) if table.isNullOrEmpty(tableValue) then error("cfg_equip_angelGrailSuit is null group:", i, " level:", j) return end local value = tableValue[1] local suitGrailId = value["suitgrailid"] local suitEffect = value["suiteffect"] if not string.isNullOrEmpty(suitGrailId) and not string.isNullOrEmpty(suitEffect) then local grailIds = string.split(suitGrailId, "#") for _, configId in pairs(grailIds) do configId = tonumber(configId) total = total + (temp[configId] and temp[configId] or 0) end if total > 0 then local split = string.split(suitEffect, "|") for _, item in pairs(split) do local split2 = string.split(item, "#") local count = tonumber(split2[1]) if total >= count then tableId = tonumber(value["id"]) local attrId = tonumber(split2[2]) local attrValue = tonumber(split2[3]) attrInfo[attrId] = attrValue end end if not table.isNullOrEmpty(attrInfo) then if tableId ~= grailSuitId then setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_SUIT_ID, tableId) RoleAttr.clearRoleAttrAndDB(actor, RoleAttrKey.ANGEL_GRAIL_SUIT) end local attr = getplaydef(actor, "T$_" .. RoleAttrKey.ANGEL_GRAIL_SUIT) if not table.isNullOrEmpty(attr) then local attrLength = table.count(attr) local attrInfoLength = table.count(attrInfo) if attrLength > attrInfoLength then for attrId, _ in pairs(attr) do if table.hasKey(attrInfo, attrId) then attrInfo[attrId] = 0 else attrInfo[attrId] = -attr[attrId] end end else for attrId, _ in pairs(attrInfo) do if table.hasKey(attr, attrId) and attr[attrId] > 0 then attrInfo[attrId] = 0 end end end end RoleAttr.addAndSaveRoleAttr(actor, RoleAttrKey.ANGEL_GRAIL_SUIT, attrInfo) return end end end end end end -- 清除套装属性加成 RoleAttr.clearRoleAttrAndDB(actor, RoleAttrKey.ANGEL_GRAIL_SUIT) end --- 初始化大天使圣杯排行榜信息 function AngelMajorGrail.initGrailRanking() -- 本服圣杯排行榜初始化 local allRole = getallrolesummaryinfos() if not table.isNullOrEmpty(allRole) then --gameDebug.print(string.format("初始化大天使圣杯排行榜信息 now:%s", TimeUtil.timeFormat(getbaseinfo("nowsec")))) local rankingInfo = {} local actor for _, v in pairs(allRole) do actor = v["actor"] local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if not table.isNullOrEmpty(grailInfo) then this.grailRankingHandle(actor, grailInfo, rankingInfo) end end if not table.isNullOrEmpty(rankingInfo) then rankingInfo = this.calcGrailRanking(rankingInfo) end local ranking = {} ranking["rankingInfo"] = rankingInfo local rankingIndex = {} for key, rank in pairs(rankingInfo) do rankingIndex[rank["roleId"]] = key end ranking["rankingIndex"] = rankingIndex setsysvar(actor, SystemVarConst.ANGEL_GRAIL_RANKING_INFO, ranking) end -- 跨服圣杯排行榜数据初始化 local serverType = getbaseinfo("servertype") if serverType == 2 then return -- local hosts = gethosts() -- if not table.isNullOrEmpty(hosts) then -- --gameDebug.print(string.format("初始化大天使圣杯跨服排行榜信息 now:%s", TimeUtil.timeFormat(getbaseinfo("nowsec")))) -- local rankingInfo = {} -- for _, host in pairs(hosts) do -- local all = getallrolesummaryinfos(host) -- if not table.isNullOrEmpty(all) then -- for _, v in pairs(all) do -- local actor = v["actor"] -- local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) -- if not table.isNullOrEmpty(grailInfo) then -- this.grailRankingHandle(actor, grailInfo, rankingInfo) -- end -- end -- end -- end -- if not table.isNullOrEmpty(rankingInfo) then -- rankingInfo = this.calcGrailRanking(rankingInfo) -- end -- local ranking = {} -- ranking["rankingInfo"] = rankingInfo -- local rankingIndex = {} -- for key, rank in pairs(rankingInfo) do -- rankingIndex[rank["roleId"]] = key -- end -- ranking["rankingIndex"] = rankingIndex -- for _, host in ipairs(hosts) do -- setsysvar(host, SystemVarConst.ANGEL_GRAIL_CROSS_RANKING_INFO, ranking) -- end -- end end end --- 获取大天使圣杯排行榜信息 ---@param actor table 角色对象 ---@param grailGrade number 圣杯等阶 function AngelMajorGrail.getGrailRankingInfo(actor, msgData) -- 排行榜类型 local type = msgData["type"] local ranking = {} if type == 1 then -- ranking = getsysvar(SystemVarConst.ANGEL_GRAIL_CROSS_RANKING_INFO, 1) return else ranking = getsysvar(actor, SystemVarConst.ANGEL_GRAIL_RANKING_INFO) end local worshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO) worshipInfo = worshipInfo or {} local crossWorshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO) crossWorshipInfo = crossWorshipInfo or {} local res = {} res["worshipCount"] = table.count(worshipInfo) + table.count(crossWorshipInfo) res["roleIds"] = type == 1 and crossWorshipInfo or worshipInfo local rankingInfo = ranking["rankingInfo"] local rankingIndex = ranking["rankingIndex"] local roleId = tonumber(actor:toString()) local my = {} if table.hasKey(rankingIndex, roleId) then my = rankingInfo[rankingIndex[roleId]] end if not table.isNullOrEmpty(rankingInfo) then res["rankingInfo"] = { ["all"] = { table.unpack(rankingInfo, 1, 30) }, ["my"] = my, } else res["rankingInfo"] = {} end sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_RANKING_INFO, res) end --- 膜拜圣杯 ---@param actor table 角色对象 ---@param msgData table 消息数据 function AngelMajorGrail.worshipGrail(actor, msgData) -- 排行榜类型 local type = tonumber(msgData["type"]) -- 圣杯id local roleId = tonumber(msgData["roleId"]) local worshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO) worshipInfo = worshipInfo or {} local crossWorshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO) crossWorshipInfo = crossWorshipInfo or {} if type == 1 then if not table.isNullOrEmpty(crossWorshipInfo) then if table.hasKey(crossWorshipInfo, roleId) then gameDebug.print(string.format("玩家%s重复膜拜跨服圣杯排行榜的%s", getbaseinfo(actor, "rolename"), roleId)) return end end else if not table.isNullOrEmpty(worshipInfo) then if table.hasKey(worshipInfo, roleId) then gameDebug.print(string.format("玩家%s重复膜拜圣杯排行榜的%s", getbaseinfo(actor, "rolename"), roleId)) return end end end -- 已经膜拜次数 local count = table.count(worshipInfo) + table.count(crossWorshipInfo) -- 每日膜拜次数限制校验 local limit = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.ANGEL_GRAIL_WORSHIP_LIMIT) if string.isNullOrEmpty(limit) then error("cfg_global is null id:", GlobalConfigId.ANGEL_GRAIL_WORSHIP_LIMIT) return end if count >= tonumber(limit) then gameDebug.print(string.format("玩家%s超过每日膜拜次数限制", getbaseinfo(actor, "rolename"))) return end local reward = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId .ANGEL_GRAIL_WORSHIP_REWARD) if not string.isNullOrEmpty(reward) then if type == 1 then crossWorshipInfo[roleId] = 1 setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO, crossWorshipInfo) else worshipInfo[roleId] = 1 setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO, worshipInfo) end Bag.sendRewards4String(actor, reward, ItemAction.ANGEL_GRAIL_RANKING_WORSHIP_REWARD) -- 发送膜拜圣杯红点 RedPoint.sendOneRedPoint(actor, this.canWorshipRedId, this.checkWorshipRedPoint(actor)) -- 响应客户端 sendluamsg(actor, LuaMessageIdToClient.RES_GRAIL_RANKING_WORSHIP_INFO, { ["worshipCount"] = count + 1, ["grailIds"] = type == 1 and crossWorshipInfo or worshipInfo }) end end --- 获取指定玩家身上穿着的大天使装备与镶嵌的圣杯信息 ---@param actor table 角色对象 ---@param rid number 玩家id function AngelMajorGrail.getPlayerAllAngelEquipAndGrail(actor, rid) local player = getactor(rid) if not player then return end local res = {} -- 获取大天使装备信息 local equipAttr = {} local equipInfo = getplaydef(player, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA) local putOnIds = AngelMajorEquipment.getPutOnEquipIds(player) if not table.isNullOrEmpty(equipInfo) then for _, v in pairs(putOnIds) do equipAttr[v] = equipInfo[v] end end -- 获取大天使圣杯信息 local grailInfo = {} local grailIds = AngelMajorGrail.getInlaidGrailIds(player) local entryInfo = getplaydef(player, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if not table.isNullOrEmpty(grailIds) then for _, v in pairs(grailIds) do grailInfo[v] = entryInfo[v] end end res["equip"] = equipAttr res["grail"] = grailInfo sendluamsg(actor, LuaMessageIdToClient.RES_PLAYER_EQUIP_GRAIL_INFO, res) end ---登录事件检查红点 function this.loginRed(red_data, actor) if AngelMajorGrail.checkEnter(actor) then --上线false可以不发送 red_data[this.RedId] = true end if this.checkWorshipRedPoint(actor) then red_data[this.canWorshipRedId] = true end end --- 圣杯镶嵌红点判断 --- @param actor table 角色对象 --- @param grailGrade number 圣杯等阶 --- @param grailPosition number 孔位 --- @param grailConfigId number 圣杯配置id --- @return boolean 是否展示红点 function this.checkRedPoint(actor, grailGrade, grailPosition, grailConfigId) local equipData = getputonequipinfo(actor) local equipAttr = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA) if table.isNullOrEmpty(equipAttr) then return false end for _, v in pairs(equipData) do local attr = equipAttr[v["id"]] if table.isNullOrEmpty(attr) then goto next end local cfgId = v["cfgid"] local strPart = ConfigDataManager.getTableValue("cfg_item", "strPart", "id", cfgId) local partSplit = string.split(strPart, "#") local grailStrPart = ConfigDataManager.getTableValue("cfg_equip_angelGrail", "strPart", "id", grailConfigId) local grailPartSplit = string.split(grailStrPart, "#") local flag = false for _, part in pairs(partSplit) do if table.contains(grailPartSplit, part) then flag = true end end if not flag then goto next end local equipRank = attr["rank"] if equipRank < grailGrade then goto next else local grails = attr["grails"] if not table.isNullOrEmpty(grails) then for _, value in pairs(grails) do if value["grailPosition"] == grailPosition then goto next end end return true else return true end end :: next :: end return false end --- 圣杯排行榜膜拜红点判断 --- @param actor table 角色对象 function this.checkWorshipRedPoint(actor) local worshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO) worshipInfo = worshipInfo or {} local crossWorshipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO) crossWorshipInfo = crossWorshipInfo or {} local ranking = getsysvar(actor, SystemVarConst.ANGEL_GRAIL_RANKING_INFO) if table.isNullOrEmpty(ranking) then return false end local rankingInfo = ranking["rankingInfo"] if table.isNullOrEmpty(rankingInfo) then return false end if table.isNullOrEmpty(worshipInfo) and table.isNullOrEmpty(crossWorshipInfo) then return true end local limit = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.ANGEL_GRAIL_WORSHIP_LIMIT) local count = table.count(worshipInfo) + table.count(crossWorshipInfo) if count < tonumber(limit) then return true end return false end --- 组装圣杯信息 --- @param itemId number 道具id --- @param info table 孔位信息 --- @param entryInfo table 词条信息 function this.combineRes(itemId, info, entryInfo) local temp = {} temp["itemId"] = itemId temp["itemConfigId"] = info["itemConfigId"] temp["position"] = info["grailPosition"] local attrInfo = entryInfo[itemId] temp["attrInfo"] = attrInfo temp["inlaid"] = info["inlaid"] return temp end --- 强化词条 --- @param entry table 词条对象 function this.strengthen(entry) local id = entry["id"] local attrValue = entry["value"] local entryTableValue = ConfigDataManager.getTable("cfg_equip_angelEntry", "id", id) local max = entryTableValue[1]["attmax"] local maxSplit = string.split(max, "#") local index = 1 -- 获取最大值索引 if string.contains(max, "#") then local attrId = entry["attrId"] local att = entryTableValue[1]["att"] local attSplit = string.split(att, "|") for k, v in pairs(attSplit) do if tonumber(string.split(v, "#")[1]) == attrId then index = k break end end end local strengthen = entryTableValue[1]["strengthen"] local split = string.split(strengthen, "|") local temp = {} for _, v in pairs(split) do local split2 = string.split(v, "#") local randomValue = math.random(split2[1], split2[2]) temp[{ [index] = randomValue }] = split2[3] end local randomInfo = randombyweight(temp)[1] if not table.isNullOrEmpty(randomInfo) then for k, v in pairs(randomInfo) do -- 判断增加完的词条是否超过了最大值,如果超过了最大值则赋值为最大值 if attrValue + tonumber(v) >= tonumber(maxSplit[k] and maxSplit[k] or max) then entry["value"] = maxSplit[k] and maxSplit[k] or max entry["isMax"] = true else entry["value"] = attrValue + v end end end end --- 获取圣杯词条信息 --- @param entryInfo table cfg_equip_angelEntry表词条信息 --- @return table 随机词条信息 function this.initEntry(entryInfo) local split = string.split(entryInfo["att"], "|") local res = {} for _, v in pairs(split) do local attSplit = string.split(v, "#") local attrId = tonumber(attSplit[1]) local minValue = tonumber(attSplit[2]) local maxValue = tonumber(attSplit[3]) local weight = tonumber(attSplit[4]) local randomValue = math.random(minValue, maxValue) table.insert(res, { ["id"] = tonumber(entryInfo["id"]), ["attrId"] = attrId, ["value"] = randomValue, ["weight"] = weight, ["isMax"] = false, }) end return res end --- 根据权重随机生成词条 --- @param secondaryEntryInfo table 词条信息 --- @param secondaryCount number 词条数量 --- @return table 随机词条索引集合 function this.getRandomEntry(secondaryEntryInfo, secondaryCount) local temp = {} for k, v in pairs(secondaryEntryInfo) do local att = v["att"] if string.contains(att, "|") then local split = string.split(att, "|") for _, value in pairs(split) do local weight = string.split(value, "#")[4] temp[k] = weight end else local weight = string.split(att, "#")[4] temp[k] = weight end end local randomResult = randombyweight(temp, secondaryCount, false) return randomResult end --- 判断是否开启大天使圣杯 --- @param actor table 角色对象 --- @return boolean 是否开启 function this.isOpen(actor) -- 获取当前角色等级 local level = getbaseinfo(actor, "level") -- 获取等级限制配置 local levelLimit = ConfigDataManager.getTableValue("cfg_global", "value", "id", GlobalConfigId.ANGEL_EQUIPMENT_LEVEL_LIMIT) if string.isNullOrEmpty(levelLimit) then return false end -- 返回结果 return level >= tonumber(levelLimit) end --- 判断是否是大天使圣杯 --- @param itemConfigId number 道具配置id --- @return table 大天使圣杯信息 function this.isAngelGrail(itemConfigId) return ConfigDataManager.getTable("cfg_equip_angelGrail", "id", itemConfigId) end --- 计算圣杯评分 ---@param grailEntry table 圣杯属性信息 function this.calcGrailScore(grailEntry) local score = 0 if not table.isNullOrEmpty(grailEntry) then local main = grailEntry["main"] score = score + this.scoreHandle(main) local secondary = grailEntry["secondary"] for _, v in pairs(secondary) do score = score + this.scoreHandle(v) end grailEntry["score"] = score end return grailEntry end --- 评分处理 --- @param entry table 词条数据 function this.scoreHandle(entry) if not table.isNullOrEmpty(entry) then local score = 0 for _, v in pairs(entry) do local attrId = v["attrId"] local value = v["value"] local tableValue = ConfigDataManager.getTable("cfg_att_info", "id", attrId) if not table.isNullOrEmpty(tableValue) then local remarks = tableValue[1]["remarks"] if tonumber(remarks) == 2 then value = value / 100 end local tableScore = tableValue[1]["score"] score = math.ceil(score + value * tableScore) end end return score end end --- 计算圣杯排名 --- @param rankingTable table 要排的圣杯数据 --- @return table 排序后的圣杯数据 function this.calcGrailRanking(rankingTable) -- 快速排序算法,对score进行降序排序,对于大数据集速度相较于插入排序更快,长远考虑选择快排 this.quickSortRecursive(rankingTable, 1, #rankingTable) -- 更新排名 for i = 1, #rankingTable do rankingTable[i].ranking = i end -- 返回排序结果 return rankingTable end --- 快速排序的分区函数 --- @param arr table 要排序的列表 --- @param low number 排序区间的下界 --- @param high number 排序区间的上界 function this.partition(arr, low, high) local pivot = arr[high].score local i = low - 1 for j = low, high - 1 do if arr[j].score > pivot then i = i + 1 -- 交换 arr[i] 和 arr[j] local temp = arr[i] arr[i] = arr[j] arr[j] = temp end end -- 交换 arr[i+1] 和 arr[high] (或者 pivot) local temp = arr[i + 1] arr[i + 1] = arr[high] arr[high] = temp return i + 1 end --- 快速排序的递归函数 --- @param arr table 要排序的列表 --- @param low number 排序区间的下界 --- @param high number 排序区间的上界 function this.quickSortRecursive(arr, low, high) if low < high then local pi = this.partition(arr, low, high) this.quickSortRecursive(arr, low, pi - 1) this.quickSortRecursive(arr, pi + 1, high) end end --- 圣杯排名处理 --- @param actor table 角色对象 --- @param grailInfo table 圣杯信息 --- @param rankingInfo table 排行榜信息 function this.grailRankingHandle(actor, grailInfo, rankingInfo) local roleName = getbaseinfo(actor, "rolename") local career = getbaseinfo(actor, "getbasecareer") local serverId = getbaseinfo(actor, "originalserverid") local inlaidGrailIds = AngelMajorGrail.getInlaidGrailIds(actor) local score = 0 for itemId, info in pairs(grailInfo) do if not table.hasKey(info, "score") then info = this.calcGrailScore(info) end if table.contains(inlaidGrailIds, itemId) then score = score + info["score"] end end if score > 0 then table.insert(rankingInfo, { ["roleId"] = tonumber(actor:toString()), ["roleName"] = roleName, ["career"] = career, ["score"] = score, ["ranking"] = 0, ["serverId"] = serverId, }) end end --- 凌晨事件 function this.zeroEvent(play) local allRole = getallrolesummaryinfos() if not table.isNullOrEmpty(allRole) then local logText = "开始重置大天使圣杯排行榜膜拜信息 now:%s" gameDebug.print(string.format(logText, TimeUtil.timeFormat(getbaseinfo("nowsec")))) for _, v in pairs(allRole) do local actor = v["actor"] setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_WORSHIP_INFO, {}) setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_CROSS_WORSHIP_INFO, {}) end end end --- 玩家登录清除圣杯分解造成的脏数据 --- @param actor table 角色对象 function this.loginDirtyDataClear(actor) local grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) if table.isNullOrEmpty(grailInfo) then return end local flag = "2024_01_24_15_10" local mark = getplaydef(actor, "T$_angelGrailDirtyDataClear") if type(mark) ~= "string" or mark ~= flag then jprint(string.format("==============================>%s开始清除圣杯脏数据now:%s", getbaseinfo(actor, "rolename"), TimeUtil.timeFormat(getbaseinfo("nowsec")))) local itemIds = {} local bagItems = getallbagitem(actor) if not table.isNullOrEmpty(bagItems) then for _, v in pairs(bagItems) do local cfgId = v["cfg_id"] if this.isAngelGrail(cfgId) then local id = v["id"] if table.isNullOrEmpty(grailInfo[id]) then this.initGrailInfo(actor, id, cfgId) end table.insert(itemIds, id) end end end local storeMaxPage = getstoremaxpage(actor) for i = 1, storeMaxPage do local storeItem = getalliteminfoinstore(actor, i) if not table.isNullOrEmpty(storeItem) then for _, v in pairs(storeItem) do local cfgId = v["cfgid"] if this.isAngelGrail(cfgId) then local id = v["id"] if table.isNullOrEmpty(grailInfo[id]) then this.initGrailInfo(actor, id, cfgId) end table.insert(itemIds, id) end end end end -- fixtodo 如果玩家存在卸下的带有圣杯的装备,这样清理会把玩家卸下装备上面的圣杯数据丢失 local equipInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA) if not table.isNullOrEmpty(equipInfo) then for _, v in pairs(equipInfo) do local grails = v["grails"] if not table.isNullOrEmpty(grails) then for grailId, value in pairs(grails) do local cfgId = value["itemConfigId"] if table.isNullOrEmpty(grailInfo[grailId]) then this.initGrailInfo(actor, grailId, cfgId) end table.insert(itemIds, grailId) end end end end if not table.isNullOrEmpty(itemIds) then for k, v in pairs(itemIds) do jprint("========================>itemId k", k, " v", v) end end grailInfo = getplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO) local allGrailIds = {} for itemId, _ in pairs(grailInfo) do if not table.contains(itemIds, itemId) then grailInfo[itemId] = nil end table.insert(allGrailIds, itemId) end setplaydef(actor, PlayerDefKey.angel.ANGEL_GRAIL_ENTRY_INFO, grailInfo) -- 大天使装备上圣杯数据清理 if not table.isNullOrEmpty(equipInfo) then for k, v in pairs(equipInfo) do local grails = v["grails"] if not table.isNullOrEmpty(grails) then for grailId, _ in pairs(grails) do if not table.contains(allGrailIds, grailId) then grails[grailId] = nil end end end end end setplaydef(actor, PlayerDefKey.angel.ANGEL_EQUIPMENT_ATTR_DATA, equipInfo) -- 设置脏数据清理标识符 setplaydef(actor, "T$_angelGrailDirtyDataClear", flag) end end --- 合服清空排行榜数据 function AngelMajorGrail.combine() local hosts = gethosts() for _, host in ipairs(hosts) do setsysvar(host, SystemVarConst.ANGEL_GRAIL_RANKING_INFO, {}) setsysvar(host, SystemVarConst.ANGEL_GRAIL_CROSS_RANKING_INFO, {}) end end RedPointEventListerTable:eventLister("0", "大天使圣杯", this.loginRed) ZeroEventListerTable:eventLister("0", "大天使圣杯排行榜膜拜重置", this.zeroEvent) LoginEventListerTable:eventLister("0", "大天使圣杯脏数据清理", this.loginDirtyDataClear)