local Default = { _Id = 0, --目标Id _CharacterId = 0, --目标角色Id _Progress = 0, --当前目标进度 _IsFinish = false, --目标是否完成 _RecommendId = 0, --装备推荐Id, 同时是VoteId _SuitType = XEquipGuideConfigs.ChipSuitType.SixSuits, --意识套装类型 _WeaponModel = {}, _ChipModelList = {}, _PutOnPosList = {}, --穿戴装备位置列表 _Pos2IsPut = {}, } local XEquipGuideModel = require("XEntity/XEquipGuide/XEquipGuideModel") local tableSort = table.sort local tableInsert = table.insert local tableRemove = table.remove local tableIndexOf = table.indexof local XEquipTarget = XClass(XDataEntityBase, "XEquipTarget") function XEquipTarget:Ctor(targetId) self:Init(Default, targetId) end function XEquipTarget:InitData(id) self:SetProperty("_Id", id) self._RecommendId = XEquipGuideConfigs.TargetConfig:GetProperty(id, "EquipRecommendId") local template = XCharacterConfigs.GetCharDetailEquipTemplate(self._RecommendId) local suitIds = template.SuitId local suitLength = #suitIds if suitLength == 1 then self._SuitType = XEquipGuideConfigs.ChipSuitType.SixSuits elseif suitLength == 2 then self._SuitType = XEquipGuideConfigs.ChipSuitType.FourPlusTwoSuits elseif suitLength == 3 then self._SuitType = XEquipGuideConfigs.ChipSuitType.TwoPlusTwoPlusTwoSuits end end function XEquipTarget:UpdateData(data) for key, value in pairs(data) do self:SetProperty(key, value) end end function XEquipTarget:UpdatePutOnPosList(list) list = list or {} self._Pos2IsPut = {} local tmpList = {} local recommend = XCharacterConfigs.GetCharDetailEquipTemplate(self._RecommendId) for _, pos in ipairs(list or {}) do if self:CheckIsTargetEquipByPos(recommend, pos) then tableInsert(tmpList, pos) end end self:SetProperty("_PutOnPosList", tmpList) for _, pos in ipairs(tmpList) do self._Pos2IsPut[pos] = true end self:RefreshEquip() end function XEquipTarget:RefreshEquip() self:UpdateWeapon() self:UpdateChips() self:UpdateProgress() end function XEquipTarget:UpdateProgress() local config = XEquipGuideConfigs.JudgeConfig:GetConfig(XEquipGuideConfigs.JudgeConfigKey) local maxScore = config.GrossScore local weaponScore, chipScore = 0, 0 if self._WeaponModel:IsExist() and self._WeaponModel:IsWearing(self._CharacterId) then self._WeaponModel:Refresh(self._WeaponModel:GetProperty("_Id")) local breakthrough = self._WeaponModel:GetProperty("_Breakthrough") local level = self._WeaponModel:GetProperty("_Level") weaponScore = weaponScore + config.WeaponPutOnScore + breakthrough * config.WeaponBreakThroughScore + level * config.WeaponUpLevelScore end for _, model in ipairs(self._ChipModelList) do if model:IsExist() and model:IsWearing(self._CharacterId) then model:Refresh(model:GetProperty("_Id")) local breakthrough = model:GetProperty("_Breakthrough") local level = model:GetProperty("_Level") chipScore = chipScore + config.ChipPutOnScore + breakthrough * config.ChipBreakThroughScore + level * config.ChipUpLevelScore end end local score = weaponScore + chipScore if score >= maxScore then XDataCenter.EquipGuideManager.EquipGuideTargetFinishRequest(self._CharacterId, function() XLuaUiManager.Open("UiEquipGuideSuccess", self._CharacterId) end) end self:SetProperty("_Progress", XUiHelper.GetFillAmountValue(score, maxScore)) end function XEquipTarget:UpdateWeapon() local template = XCharacterConfigs.GetCharDetailEquipTemplate(self._RecommendId) local weaponId = template.EquipRecomend local model = XEquipGuideModel.New(template.EquipRecomend) local equipId --该位置已装备 if self._Pos2IsPut[XEquipConfig.EquipSite.Weapon] then equipId = XDataCenter.EquipManager.GetCharacterWearingWeaponId(self._CharacterId) else equipId = self:__FindBestOneEquip(weaponId) end model:Refresh(equipId) self:SetProperty("_WeaponModel", model) end function XEquipTarget:UpdateChips() if self._SuitType == XEquipGuideConfigs.ChipSuitType.SixSuits then self:__UpdateSixChips() elseif self._SuitType == XEquipGuideConfigs.ChipSuitType.FourPlusTwoSuits then self:__UpdateFourPlusTwoChips() elseif self._SuitType == XEquipGuideConfigs.ChipSuitType.TwoPlusTwoPlusTwoSuits then self:__Update3ThTwoChips() end end --六件套 function XEquipTarget:__UpdateSixChips() local list = {} local template = XCharacterConfigs.GetCharDetailEquipTemplate(self._RecommendId) local chips = XEquipConfig.GetEquipTemplateIdsBySuitId(template.SuitId[1]) for site, chipId in ipairs(chips) do local model = XEquipGuideModel.New(chipId) if self._Pos2IsPut[site] then local equipId = XDataCenter.EquipManager.GetWearingEquipIdBySite(self._CharacterId, site) model:Refresh(equipId) else model:Refresh(self:__FindBestOneEquip(chipId)) end list[site] = model end self:SetProperty("_ChipModelList", list) end --4+2件套 function XEquipTarget:__UpdateFourPlusTwoChips() local template = XCharacterConfigs.GetCharDetailEquipTemplate(self._RecommendId) --套装1的意识 local templateAIds = XEquipConfig.GetEquipTemplateIdsBySuitId(template.SuitId[1]) --套装2的意识 local templateBIds = XEquipConfig.GetEquipTemplateIdsBySuitId(template.SuitId[2]) --套装1,2的数量 local numA, numB = template.Number[1], template.Number[2] --除去已经装备的意识,剩下的数量 local leftNumA, leftNumB = numA, numB local scores = {} local equips = {} --确认有争议位置(不判断已经装备的) for site = 1, XEquipConfig.MAX_SUIT_COUNT do if not self._Pos2IsPut[site] then local tAId, tBId = templateAIds[site], templateBIds[site] local activeA = XDataCenter.EquipManager.IsEquipActive(tAId, self._CharacterId) local activeB = XDataCenter.EquipManager.IsEquipActive(tBId, self._CharacterId) scores[site] = (activeA and numA or 0) + (activeB and numB or 0) else --该位置已经装备了对应的意识 local equipId = XDataCenter.EquipManager.GetWearingEquipIdBySite(self._CharacterId, site) if XTool.IsNumberValid(equipId) and leftNumA > 0 and leftNumB > 0 then local equip = XDataCenter.EquipManager.GetEquip(equipId) local templateId = equip.TemplateId --已经装备A套 if table.contains(templateAIds, templateId) then leftNumA = leftNumA - 1 end --已经装备B套 if table.contains(templateBIds, templateId) then leftNumB = leftNumB - 1 end equips[site] = equipId else local tAId, tBId = templateAIds[site], templateBIds[site] local activeA = XDataCenter.EquipManager.IsEquipActive(tAId, self._CharacterId) local activeB = XDataCenter.EquipManager.IsEquipActive(tBId, self._CharacterId) scores[site] = (activeA and numA or 0) + (activeB and numB or 0) end end end local tmpChips = { [numA] = {}, [numB] = {} } --意识排序(不判断已经装备的) local sort = function(a, b) local baseScoreA = XEquipGuideConfigs.CalEquipBaseScore(a) local baseScoreB = XEquipGuideConfigs.CalEquipBaseScore(b) if baseScoreA ~= baseScoreB then return baseScoreA > baseScoreB end local resonanceScoreA = XEquipGuideConfigs.CalEquipResonanceScore(a, self._CharacterId) local resonanceScoreB = XEquipGuideConfigs.CalEquipResonanceScore(b, self._CharacterId) if resonanceScoreA ~= resonanceScoreB then return resonanceScoreA > resonanceScoreB end if numA ~= numB then return numA > numB end return a < b end for pos, score in pairs(scores) do --该位置存在两个意识 if score == (numA + numB) then local tAId, tBId = templateAIds[pos], templateBIds[pos] local equipAId, equipBId = self:__FindBestOneEquip(tAId), self:__FindBestOneEquip(tBId) local twoEquips = {equipAId, equipBId} table.sort(twoEquips, sort) equips[pos] = twoEquips if twoEquips[1] == equipAId then table.insert(tmpChips[numA], pos) else table.insert(tmpChips[numB], pos) end elseif score == numA then local tmpId = templateAIds[pos] local equipId = self:__FindBestOneEquip(tmpId) equips[pos] = {equipId, 0} table.insert(tmpChips[numA], pos) elseif score == numB then local tmpId = templateBIds[pos] local equipId = self:__FindBestOneEquip(tmpId) equips[pos] = {equipId, 0} table.insert(tmpChips[numB], pos) else equips[pos] = {0, 0} end end local suitFitter = function(arrayA, arrayB) local t = {} for _, pos in ipairs(arrayA) do local eIdA, eIdB = equips[pos][1], equips[pos][2] tableInsert(t, { Pos = pos, Score = XEquipGuideConfigs.CalEquipBaseScore(eIdA) - XEquipGuideConfigs.CalEquipBaseScore(eIdB), EquipId = { eIdA, eIdB } }) end tableSort(t, function(a, b) if a.Score ~= b.Score then return a.Score > b.Score end return a.Pos < b.Pos end ) local tmp = t[#t] if not tmp then return end local index = tableIndexOf(arrayA, tmp.Pos) if index then tableRemove(arrayA, index) end if XTool.IsNumberValid(tmp.EquipId[2]) then tableInsert(arrayB, tmp.Pos) end equips[tmp.Pos] = tmp.EquipId[2] end --评分差值调整 while true do local tmpNumA, tmpNumB = #tmpChips[numA], #tmpChips[numB] if tmpNumA <= leftNumA and tmpNumB <= leftNumB then break end if leftNumA < 0 or leftNumB < 0 then break end if tmpNumA > leftNumA and tmpNumA ~= 0 then suitFitter(tmpChips[numA], tmpChips[numB]) end if tmpNumB > leftNumB and tmpNumB ~= 0 then suitFitter(tmpChips[numB], tmpChips[numA]) end end local first, second local firstTemplateIds, secondTemplateIds if numA > numB then first, second = leftNumA - #tmpChips[numA], leftNumB - #tmpChips[numB] firstTemplateIds, secondTemplateIds = templateAIds, templateBIds else first, second = leftNumB - #tmpChips[numB], leftNumA - #tmpChips[numA] firstTemplateIds, secondTemplateIds = templateBIds, templateAIds end --待定处理 local models = {} for pos, data in pairs(equips) do local equipId local model equipId = type(data) == "table" and data[1] or data if XTool.IsNumberValid(equipId) then local equip = XDataCenter.EquipManager.GetEquip(equipId) model = XEquipGuideModel.New(equip.TemplateId) else if first > 0 then model = XEquipGuideModel.New(firstTemplateIds[pos]) first = first - 1 elseif second > 0 then model = XEquipGuideModel.New(secondTemplateIds[pos]) second = second - 1 end end model:Refresh(equipId) table.insert(models, model) end self:SetProperty("_ChipModelList", models) end function XEquipTarget:__Update3ThTwoChips() end function XEquipTarget:__Sort(equipIdA, equipIdB) local baseScoreA = XEquipGuideConfigs.CalEquipBaseScore(equipIdA) local baseScoreB = XEquipGuideConfigs.CalEquipBaseScore(equipIdB) if baseScoreA ~= baseScoreB then return baseScoreA > baseScoreB end local resonanceScoreA = XEquipGuideConfigs.CalEquipResonanceScore(equipIdA, self._CharacterId) local resonanceScoreB = XEquipGuideConfigs.CalEquipResonanceScore(equipIdB, self._CharacterId) if resonanceScoreA ~= resonanceScoreB then return resonanceScoreA > resonanceScoreB end return equipIdA < equipIdB end function XEquipTarget:__FindBestOneEquip(templateId) local equipIds = XDataCenter.EquipManager.GetEnableEquipIdsByTemplateId(templateId, self._CharacterId) local equipId, equipCount = 0, #equipIds if equipCount == 0 then equipId = 0 elseif equipCount == 1 then equipId = equipIds[1] else local sort = handler(self, self.__Sort) table.sort(equipIds, sort) equipId = equipIds[1] end return equipId end function XEquipTarget:CreatePutOnPosList() local putOnPosList = {} --武器 self:UpdateWeapon() local weaponId = self._WeaponModel:GetProperty("_Id") if XDataCenter.EquipGuideManager.CheckEquipIsWearingOnCharacter(weaponId, self._CharacterId) then tableInsert(putOnPosList, XEquipConfig.EquipSite.Weapon) end --意识 self:UpdateChips() for i, model in ipairs(self._ChipModelList) do local equipId = model:GetProperty("_Id") if XDataCenter.EquipGuideManager.CheckEquipIsWearingOnCharacter(equipId, self._CharacterId) then tableInsert(putOnPosList, i) end end return putOnPosList end function XEquipTarget:CheckIsTargetEquipByTemplateId(templateId) if self._WeaponModel:GetProperty("_TemplateId") == templateId then return true end local template = XCharacterConfigs.GetCharDetailEquipTemplate(self._RecommendId) local suitIds = template.SuitId local suitId = XDataCenter.EquipManager.GetSuitIdByTemplateId(templateId) for _, id in ipairs(suitIds) do if id == suitId then return true end end return false end --检测模板与身上穿戴的装备是否一致 function XEquipTarget:CheckIsFullEquipped() local template = XCharacterConfigs.GetCharDetailEquipTemplate(self._RecommendId) local weaponId = template.EquipRecomend local weapon = XDataCenter.EquipManager.GetWearingEquipBySite(self._CharacterId, XEquipConfig.EquipSite.Weapon) if not weapon then return false end if weaponId ~= weapon.TemplateId then return false end local tmpSuit = {} for site = 1, XEquipConfig.MAX_SUIT_COUNT do local eId = XDataCenter.EquipManager.GetWearingEquipIdBySite(self._CharacterId, site) if not XTool.IsNumberValid(eId) then return false end local suitId = XDataCenter.EquipManager.GetSuitId(eId) tmpSuit[suitId] = tmpSuit[suitId] or 0 tmpSuit[suitId] = tmpSuit[suitId] + 1 end local suitIds, numbers = template.SuitId, template.Number for i, suit in ipairs(suitIds) do local num = numbers[i] if num ~= tmpSuit[suit] then return false end end return true end function XEquipTarget:CheckIsTargetEquipByPos(recommend, pos) local equip = XDataCenter.EquipManager.GetWearingEquipBySite(self._CharacterId, pos) if not equip then return false end local templateId = equip.TemplateId if XDataCenter.EquipManager.IsWeaponByTemplateId(templateId) then if templateId == recommend.EquipRecomend then return true end else local suitId = XDataCenter.EquipManager.GetSuitIdByTemplateId(templateId) for _, sId in ipairs(recommend.SuitId or {}) do if suitId == sId then return true end end end return false end --region ------------------红点检查 start------------------- function XEquipTarget:CheckEquipCanEquip(templateId) local check = function(tId) local equipIds = XDataCenter.EquipManager.GetEnableEquipIdsByTemplateId(tId, self._CharacterId) if XTool.IsTableEmpty(equipIds) then return false end table.sort(equipIds, handler(self, self.__Sort)) local equipId = equipIds[1] local equip = XDataCenter.EquipManager.GetEquip(equipId) return equip and equip.CharacterId ~= self._CharacterId end if XTool.IsNumberValid(templateId) then return check(templateId) else if check(self._WeaponModel:GetProperty("_TemplateId")) then return true end for _, model in ipairs(self._ChipModelList) do if check(model:GetProperty("_TemplateId")) then return true end end return false end return false end function XEquipTarget:CheckHasStrongerWeapon() --不存在目标 local curTarget = XDataCenter.EquipGuideManager.GetCurrentTarget() if not curTarget or curTarget:GetProperty("_Id") == self._Id then return false end local weaponModel = curTarget:GetProperty("_WeaponModel") if not weaponModel then return false end local templateId = curTarget:GetProperty("_RecommendId") local template = XCharacterConfigs.GetCharDetailEquipTemplate(templateId) local weaponId = template.EquipRecomend local star = XDataCenter.EquipManager.GetEquipStar(weaponId) --当前的目标武器需小于6星 if star >= XEquipConfig.MAX_STAR_COUNT then return false end --当前组合 local recommendId = self._RecommendId if not XTool.IsNumberValid(recommendId) then return false end local recommend = XCharacterConfigs.GetCharDetailEquipTemplate(recommendId) local selfWeaponId = recommend.EquipRecomend local selfStar = XDataCenter.EquipManager.GetEquipStar(selfWeaponId) if selfStar < XEquipConfig.MAX_STAR_COUNT then return false end local suitIds, numbers = template.SuitId, template.Number local selfSuitIds, selfNumbers = template.SuitId, template.Number --检查意识组合是否一致 for i, suitId in ipairs(suitIds or {}) do if suitId ~= selfSuitIds[i] or numbers[i] ~= selfNumbers[i] then return false end end local isActive = XDataCenter.EquipManager.IsEquipActive(selfWeaponId, self._CharacterId) return isActive end --endregion------------------红点检查 finish------------------ function XEquipTarget:Clear() self._Progress = 0 self._IsFinish = false self._WeaponModel = {} self._ChipModelList = {} self._Pos2IsPut = {} self._PutOnPosList = {} end --region ------------------运营埋点 start------------------- function XEquipTarget:__GetEquipState(model) if not model then return XEquipGuideConfigs.EquipState.None end local exist = model:IsExist() if not exist then return XEquipGuideConfigs.EquipState.None end local wearing = model:IsWearing(self._CharacterId) if not wearing then return XEquipGuideConfigs.EquipState.WaitWear end local max = XDataCenter.EquipManager.IsMaxLevelAndBreakthrough(model:GetProperty("_Id")) return max and XEquipGuideConfigs.EquipState.Complete or XEquipGuideConfigs.EquipState.Culture end function XEquipTarget:GetWeaponState() return self:__GetEquipState(self._WeaponModel) end function XEquipTarget:GetChipsState() local states = {} for pos, model in ipairs(self._ChipModelList or {}) do --Key只能为字符串,否则在C#层解析不了 states[tostring(pos)] = self:__GetEquipState(model) end return states end --endregion------------------运营埋点 finish------------------ return XEquipTarget