local tableInsert = table.insert local tableSort = table.sort XChristmasTreeManagerCreator = function () local XChristmasTreeManager = {} local ActivityInfo = nil local OrnamentsPos = {} local TempOrnamentsPos = {} local PosChangeList = {} local OrnamentsInfo = {} local OrnamentsReadList = {} local OrnamentsReadKey = "ChristmasTreeOrnamentRead" local OpenKey = "ChristmasTreeOpen" local ACTIVITY_PROTO = { ChristmasTreeActivityDataRequest = "ChristmasTreeActivityDataRequest", ActiveOrnamentsRequest = "ActiveOrnamentsRequest", ChangeOrnamentsRequest = "ChangeOrnamentsRequest", } local function GetKey(keyword) if not ActivityInfo then return end return string.format("%d_%s_%d", XPlayer.Id, keyword, ActivityInfo.Id) end function XChristmasTreeManager.Init() local activityTemplates = XChristmasTreeConfig.GetActivityTemplates() local nowTime = XTime.GetServerNowTimestamp() for _, template in pairs(activityTemplates) do local TimeId = template.TimeId local startTime, endTime = XFunctionManager.GetTimeByTimeId(TimeId) if nowTime > startTime and nowTime < endTime then if not ActivityInfo then ActivityInfo = XChristmasTreeConfig.GetActivityTemplateById(template.Id) end end end if ActivityInfo then XChristmasTreeManager.RequestData() for _,ornament in pairs(XChristmasTreeConfig.GetOrnamentCfg()) do XEventManager.AddEventListener(XEventId.EVENT_ITEM_COUNT_UPDATE_PREFIX .. ornament.SubItemId, XChristmasTreeManager.OnSubItemCountChange) end OrnamentsReadList = XSaveTool.GetData(GetKey(OrnamentsReadKey)) or OrnamentsReadList end end function XChristmasTreeManager.RequestData() XNetwork.Call(ACTIVITY_PROTO.ChristmasTreeActivityDataRequest, {ActId = ActivityInfo.Id}, function (res) if res.Code ~= XCode.Success then XUiManager.TipCode(res.Code) return end XChristmasTreeManager.HandleData(res) end) end function XChristmasTreeManager.Reset(actId) if actId then ActivityInfo = XChristmasTreeConfig.GetActivityTemplateById(actId) end XChristmasTreeManager.ResetChange() return ActivityInfo end function XChristmasTreeManager.HandleData(data) if data == nil then return end OrnamentsPos = data.Tree for _, id in pairs(OrnamentsPos) do if id and id ~= 0 then OrnamentsReadList[id] = true end end XChristmasTreeManager.SetOrnamentRead() OrnamentsInfo = {} for _,id in ipairs(data.Ornaments) do OrnamentsInfo[id] = true end end -- 获得临时布局位置(刚进入时获得已保存的位置) function XChristmasTreeManager.GetCurrentOrnamentPos() if not next(PosChangeList) then return OrnamentsPos end if not next(TempOrnamentsPos) then TempOrnamentsPos = XTool.Clone(OrnamentsPos) end for partId, ornamentId in pairs(PosChangeList) do TempOrnamentsPos[partId] = ornamentId end return TempOrnamentsPos end function XChristmasTreeManager.PutOrnament(partId ,ornamentId) local isValid = false for _, v in ipairs(XChristmasTreeConfig.GetOrnamentById(ornamentId).PartId) do if v == partId then isValid = true break; end end if isValid then PosChangeList[partId] = ornamentId XChristmasTreeManager.SetOrnamentRead(ornamentId) return true end return false end function XChristmasTreeManager.SwapOrnamentPos(partId1 ,partId2) if XChristmasTreeConfig.GetGrpIdByTreePart(partId1) == XChristmasTreeConfig.GetGrpIdByTreePart(partId2) then local tempPos = XChristmasTreeManager.GetCurrentOrnamentPos() PosChangeList[partId1] = tempPos[partId2] or 0 PosChangeList[partId2] = tempPos[partId1] or 0 return true end return false end function XChristmasTreeManager.RemoveOrnament(partId) XChristmasTreeManager.SetOrnamentRead(PosChangeList[partId]) PosChangeList[partId] = 0 return true end function XChristmasTreeManager.RemoveOrnamentGrp(grpId) local partCount, partGrpCount = XChristmasTreeConfig.GetTreePartCount() if not grpId or grpId > partGrpCount then for partId = 1, partCount do PosChangeList[partId] = 0 end else local partGrp = XChristmasTreeConfig.GetTreePartByGroup(grpId) for _, part in ipairs(partGrp) do PosChangeList[part.Id] = 0 end end return true end function XChristmasTreeManager.CheckPartGrpEmpty(grpId) local _, partGrpCount = XChristmasTreeConfig.GetTreePartCount() local tempPos = XChristmasTreeManager.GetCurrentOrnamentPos() if not grpId or grpId > partGrpCount then for _, v in pairs(tempPos) do if v and v ~= 0 then return false end end else local partGrp = XChristmasTreeConfig.GetTreePartByGroup(grpId) for _, part in ipairs(partGrp) do if tempPos[part.Id] and tempPos[part.Id] ~= 0 then return false end end end return true end function XChristmasTreeManager.CheckOrnamentGrpUnread(grpId) if not ActivityInfo then return end local _, partGrpCount = XChristmasTreeConfig.GetTreePartCount() if not grpId or grpId > partGrpCount then for _, ornament in pairs(XChristmasTreeConfig.GetOrnamentCfg()) do local id = ornament.Id if XChristmasTreeManager.CheckOrnamentOwn(id) and not OrnamentsReadList[id] then return true end end else --XLog.Warning("CheckOrnamentGrpUnread",OrnamentsInfo,grpId, OrnamentsReadList) for _, ornament in pairs(XChristmasTreeConfig.GetOrnamentByGroup(grpId)) do local id = ornament.Id if XChristmasTreeManager.CheckOrnamentOwn(id) and not OrnamentsReadList[id] then -- XLog.Warning(" true" .. grpId .. "") return true end --XLog.Warning("single",grpId, XChristmasTreeManager.CheckOrnamentOwn(id), OrnamentsReadList[id]) end end --XLog.Warning(" false" .. grpId .. "") return false end function XChristmasTreeManager.CheckOrnamentUnread(id) return XChristmasTreeManager.CheckOrnamentOwn(id) and not OrnamentsReadList[id] end function XChristmasTreeManager.SetOrnamentRead(id) if id then if OrnamentsReadList[id] or not OrnamentsInfo[id] then return end OrnamentsReadList[id] = true end XSaveTool.SaveData(GetKey(OrnamentsReadKey), OrnamentsReadList) XEventManager.DispatchEvent(XEventId.EVENT_CHRISTMAS_TREE_ORNAMENT_READ) end function XChristmasTreeManager.CheckChange() return next(PosChangeList) ~= nil end function XChristmasTreeManager.SubmitChange(cb) if not PosChangeList or not next(PosChangeList) then XUiManager.TipMsg("No changes made") return end local tempOrnamentsPos = XChristmasTreeManager.GetCurrentOrnamentPos() XMessagePack.MarkAsTable(tempOrnamentsPos) XNetwork.Call(ACTIVITY_PROTO.ChangeOrnamentsRequest, {Changes = tempOrnamentsPos}, function (res) if res.Code ~= XCode.Success then XUiManager.TipCode(res.Code) return end if res.Changes and next(res.Changes) then XChristmasTreeManager.ApplyChange(res.Changes) XChristmasTreeManager.ResetChange() XEventManager.DispatchEvent(XEventId.EVENT_CHRISTMAS_TREE_GOT_REWARD) end if cb then cb() end end) end function XChristmasTreeManager.ApplyChange(changes) for partId, ornamentId in pairs(changes) do OrnamentsPos[partId] = ornamentId OrnamentsReadList[ornamentId] = true end XChristmasTreeManager.SetOrnamentRead() end function XChristmasTreeManager.ResetChange() PosChangeList = {} TempOrnamentsPos = {} end function XChristmasTreeManager.GetAttrName(index) if ActivityInfo then if index then return ActivityInfo.AttrName[index] else return ActivityInfo.AttrName end end return {} end function XChristmasTreeManager.GetAttrDeltaValue() local delta = {} for i in ipairs(XChristmasTreeManager.GetAttrName()) do delta[i] = 0 end for partId, ornamentId in pairs(PosChangeList) do local oldItem = XChristmasTreeConfig.GetOrnamentById(OrnamentsPos[partId]) local newItem = XChristmasTreeConfig.GetOrnamentById(ornamentId) if oldItem then for i, v in ipairs(oldItem.Attr) do delta[i] = delta[i] - v end end if newItem then for i, v in ipairs(newItem.Attr) do delta[i] = delta[i] + v end end end return delta end function XChristmasTreeManager.GetAttrValue() local value = {} local countIndex = #ActivityInfo.AttrName + 1 for i = 1, countIndex do value[i] = 0 end for _, ornamentId in pairs(OrnamentsPos) do local item = XChristmasTreeConfig.GetOrnamentById(ornamentId) if item then for i, v in ipairs(item.Attr) do value[i] = value[i] + v value[countIndex] = value[countIndex] + v end end end return value end function XChristmasTreeManager.GetTempItemData(id) local ornamentData = XChristmasTreeConfig.GetOrnamentById(id) local itemId = ornamentData.ItemId -- 获取属性总分文本 local attrHead = CS.XTextManager.GetText("ChristmasTreeOrnamentDescHead", "\t\t\t", " ", XChristmasTreeConfig.GetAttrCount(ornamentData.Id)) local list = {attrHead} -- 获取单项属性文本 for i, name in ipairs(XChristmasTreeManager.GetAttrName()) do local attrInfo = string.format("%s %d", name, ornamentData.Attr[i]) tableInsert(list, attrInfo) end -- 合并各属性文本 local attrFull = table.concat(list, "\n\t\t\t\t\t") local data = XTool.Clone(XGoodsCommonManager.GetGoodsShowParamsByTemplateId(itemId)) data.IsTempItemData = true data.Count = XChristmasTreeManager.CheckOrnamentOwn(id) and "1" or "0" data.Description = XGoodsCommonManager.GetGoodsDescription(itemId) -- attrFull = string.gsub(attrFull, "\\t", "\t") -- 合并世界观描述与属性描述文本 data.WorldDesc = string.format("%s\n%s", XGoodsCommonManager.GetGoodsWorldDesc(itemId), attrFull) return data end --排序 local getSortFunc = function (sortType) if not sortType or sortType == 0 then return function(a, b) return a.Id < b.Id end else return function(a, b) if a.Attr[sortType] ~= b.Attr[sortType] then -- 按属性从大到小排序 return a.Attr[sortType] > b.Attr[sortType] else -- 其次按 Id 从小到大排序 return a.Id < b.Id end end end end function XChristmasTreeManager.GetAvailableOrnaments(grpId, sortType) local list = {} local rawData = nil --if not grpId or grpId > PartGrpCount then -- rawData = XChristmasTreeConfig.GetOrnamentCfg() --else rawData = XChristmasTreeConfig.GetOrnamentByGroup(grpId) or {} --end for _, item in pairs(rawData) do -- XChristmasTreeManager.CheckOrnamentOwn(item.Id) and if XChristmasTreeManager.GetOrnamentAvailability(item.Id) then tableInsert(list, item) end end if next(list) then tableSort(list ,getSortFunc(sortType)) end --XLog.Warning(grpId, sortType, list, OrnamentsInfo) return list end function XChristmasTreeManager.CheckOrnamentOwn(id) return OrnamentsInfo[id] end function XChristmasTreeManager.GetOrnamentAvailability(id) for _, v in pairs(XChristmasTreeManager.GetCurrentOrnamentPos()) do if v == id then return false end end return true end function XChristmasTreeManager.GetActivityInfo() return ActivityInfo end function XChristmasTreeManager.CheckCanGetOrnament() if not ActivityInfo then return false end local minItemCount = XMath.IntMax() local minItemId = nil local isFull = true for _, ornament in pairs(XChristmasTreeConfig.GetOrnamentCfg()) do if not OrnamentsInfo[ornament.Id] then if XDataCenter.ItemManager.CheckItemCountById(ornament.SubItemId, ornament.SubItemCount) then return true, ornament.SubItemId, ornament.SubItemCount elseif ornament.SubItemCount < minItemCount then minItemCount = ornament.SubItemCount minItemId = ornament.SubItemId isFull = false end end end if isFull then return false, XChristmasTreeConfig.GetOrnamentById(1).SubItemId, 0 end return false, minItemId, minItemCount end function XChristmasTreeManager.OnSubItemCountChange() XEventManager.DispatchEvent(XEventId.EVENT_CHRISTMAS_TREE_ORNAMENT_ACTIVE) end function XChristmasTreeManager.CheckOrnamentFull() for _,ornament in pairs(XChristmasTreeConfig.GetOrnamentCfg()) do if not OrnamentsInfo[ornament.Id] then return false end end return true end function XChristmasTreeManager.GetOrnamentCount() local own, count = 0, 0 for _,ornament in pairs(XChristmasTreeConfig.GetOrnamentCfg()) do count = count + 1 if OrnamentsInfo[ornament.Id] then own = own + 1 end end return own, count end function XChristmasTreeManager.ActiveOrnament(id, cb) XNetwork.Call(ACTIVITY_PROTO.ActiveOrnamentsRequest, {OrnamentId = id}, function (res) if res.Code ~= XCode.Success then XUiManager.TipCode(res.Code) return end -- 本地构造 local rewardGoodsList = {{TemplateId = XChristmasTreeConfig.GetOrnamentById(res.OrnamentId).ItemId , RewardType = XRewardManager.XRewardType.Item, Count = 1}} XUiManager.OpenUiObtain(rewardGoodsList) OrnamentsInfo[res.OrnamentId] = true XEventManager.DispatchEvent(XEventId.EVENT_CHRISTMAS_TREE_ORNAMENT_READ) if cb then cb() end end) end --- 获取完成的挑战任务数与总数 function XChristmasTreeManager.GetTaskProgress() local taskIds = ActivityInfo.TaskId local totalTaskNum = #taskIds local finishNum = 0 if taskIds == nil or next(taskIds) == nil then return end for _, id in pairs(taskIds) do if XDataCenter.TaskManager.CheckTaskFinished(id) then finishNum = finishNum + 1 end end return finishNum, totalTaskNum end --- 检查任务是否全部领取奖励 function XChristmasTreeManager.CheckTaskAllFinish() local taskIds = ActivityInfo.TaskId if taskIds == nil or next(taskIds) == nil then return end for _, id in pairs(taskIds) do if not XDataCenter.TaskManager.CheckTaskFinished(id) then return false end end return true end --- 检查是否有奖励可以领取 function XChristmasTreeManager.HasTaskReward() if not ActivityInfo then return end local taskIds = ActivityInfo.TaskId if taskIds == nil or next(taskIds) == nil then return false end for _, id in pairs(taskIds) do -- XLog.Warning("HasTaskReward", id, XDataCenter.TaskManager.GetTaskDataById(id)) if XDataCenter.TaskManager.CheckTaskAchieved(id) then return true end end return false end -- 判断是否为指定时间点后第一次打开 function XChristmasTreeManager.CheckFirstOpen() if not ActivityInfo then return end local nowTime = XTime.GetServerNowTimestamp() local lastOpen = XSaveTool.GetData(GetKey(OpenKey)) or 0 local currentOpen = lastOpen + 1 if lastOpen < #ActivityInfo.Time and nowTime > XTime.ParseToTimestamp(ActivityInfo.Time[currentOpen]) then return true, currentOpen, ActivityInfo.StoryId[currentOpen] else return false end end -- 设置第一次打开 function XChristmasTreeManager.SetOpen(currentOpen) XSaveTool.SaveData(GetKey(OpenKey), tonumber(currentOpen)) end XEventManager.AddEventListener(XEventId.EVENT_LOGIN_DATA_LOAD_COMPLETE, function() XChristmasTreeManager.Init() end) return XChristmasTreeManager end