--- 商店物品管理类 --- Generated by EmmyLua(https://github.com/EmmyLua) --- Created by aaa. --- DateTime: 2019/5/8 18:11 --- 管理商店的物品数据,包括物品的价格,名字,已经购买次数,限购次数等等 ShopManager = {} local this = ShopManager local _StoreItemIdFilter = 100000 -- 计算刷新时间的计时器 this._CountDownTimer = nil this._IsRefresh = 0 this._RefreshShopList = {} function this.Initialize() if not this._CountDownTimer then this._CountDownTimer = Timer.New(this.TimeUpdate, 1, -1, true) this._CountDownTimer:Start() end this.isOpenNoviceGift=false --默认第一次登陆未打开 -- 公会数据改变刷新公会商店排序 Game.GlobalEvent:AddEvent(GameEvent.Guild.DataUpdate, function() if MyGuildManager.GetMyGuildInfo() then this.SortItemList(SHOP_TYPE.GUILD_SHOP) -- 检测公会商店红点 this.CheckShopRedpot(SHOP_TYPE.GUILD_SHOP) end end) end -- 刷新 function this.TimeUpdate() this.CheckShopRefreshTime() end -- 初始化商店数据 function this.InitData(func) this.LoadRedpotDataFromLocal() this.RequestAllShopData(func) end --- 重新获取商店数据 function this.RequestAllShopData(func) NetManager.RequestMainShopData(func) end --- 根据服务器返回的数据返回当前商店的所有相关数据 this.allShopData = {} --- 登录时接受服务器发过来的所有商店数据 function this.ReceiveShopData(msg) -- 保存数据 this.allShopData = {} for _, data in ipairs(msg.storeInfo) do table.insert(this.allShopData, data) --Log(string.format("商店id = %d, lt = %s, startTime = %s, endTime = %s", data.id, data.lastRefreshTime, data.startTime, data.endTime)) end -- 刷新物品排序 this.SortItemList() -- 检测商店刷新时间 this.CheckShopRefreshTime() -- 更新事件 Game.GlobalEvent:DispatchEvent(GameEvent.Shop.OnShopInfoChange) --for _, shopData in ipairs(this.allShopData) do -- Log( "商店id = " .. shopData.id) -- for _, v in ipairs(shopData.storeItem) do -- Log(v.id .."::::::::::" .. v.buyNum) -- end --end end -- 更新商店数据 function this.UpdateShopData(msg) -- 更新 for _, newdata in ipairs(msg.storeInfo) do local _index = nil --local shopConfig = ConfigManager.GetConfigData(ConfigName.StoreTypeConfig, newdata.id) --if shopConfig.StoreType == SHOP_TYPE.SEVENDAY_CARNIVAL_SHOP then --- 对七日狂欢商店特殊处理,同时只能存在一个此类型的商店 -- for index, olddata in ipairs(this.allShopData) do -- local oldConfig = ConfigManager.GetConfigData(ConfigName.StoreTypeConfig, olddata.id) -- if oldConfig.StoreType == SHOP_TYPE.SEVENDAY_CARNIVAL_SHOP then -- _index = index -- break -- end -- end --else for index, olddata in ipairs(this.allShopData) do if olddata.id == newdata.id then _index = index break end end --end if _index then this.allShopData[_index] = newdata else table.insert(this.allShopData, newdata) end -- 刷新商店红点 local shopInfo = this.GetShopInfo(newdata.id) this.CheckShopRedpot(shopInfo.StoreType) --Log(string.format("服务器推送商店刷新,商店id = %d", newdata.id)) end -- 刷新物品排序 this.SortItemList() -- 检测商店刷新时间 this.CheckShopRefreshTime() -- 更新事件 Game.GlobalEvent:DispatchEvent(GameEvent.Shop.OnShopInfoChange) end --- 请求购买物品 function this.RequestBuyShopItem(shopType, shopItemId, num, func) if not shopType or not shopItemId or not num then return end -- 限购次数检测 local countLimitNum = this.GetShopItemLimitBuyCount(shopItemId) if countLimitNum >= 0 then local shopItemData = this.GetShopItemData(shopType, shopItemId) local countLeftNum = countLimitNum - shopItemData.buyNum if countLeftNum <= 0 or countLeftNum < num then PopupTipPanel.ShowTip(Language[11705]) return end end -- 判断物品是否足够 local itemLimitNum = this.GetShopItemMaxBuy(shopType, shopItemId) if itemLimitNum == 0 or itemLimitNum < num then PopupTipPanel.ShowTip(Language[11704]) return end -- 检测够买数量的正确性 if num == 0 then PopupTipPanel.ShowTip(Language[11699]) return end -- 判断商店是否激活 if not this.IsActive(shopType) then PopupTipPanel.ShowTip(Language[11934]) return end local shopItemData = this.GetShopItemData(shopType, shopItemId) if not shopItemData then PopupTipPanel.ShowTip(Language[11935]) return end -- 计算花费 local costId, costNum = this.calculateBuyCost(shopType, shopItemId, num) local haveNum = BagManager.GetTotalItemNum(costId) if haveNum < costNum then PopupTipPanel.ShowTip(Language[10847]) return end -- 请求购买 local shopId = this.GetShopDataByType(shopType).id NetManager.RequestBuyShopItem(shopId, shopItemId, num, function(msg) -- 显示掉落 if msg.drop.itemlist and #msg.drop.itemlist > 0 or msg.drop.equipId and #msg.drop.equipId > 0 or msg.drop.Hero and #msg.drop.Hero > 0 or msg.drop.soulEquip and #msg.drop.soulEquip > 0-- or -- msg.drop.especialEquipId and #msg.drop.especialEquipId > 0 then UIManager.OpenPanel(UIName.RewardItemPopup, msg.drop, 1) end -- 购买次数增加 local shopData = this.GetShopDataByType(shopType) for _, v in ipairs(shopData.storeItem) do if v.id == shopItemId then v.buyNum = v.buyNum + num break end end -- 消耗物品 改为后端刷新了 -- 完成回调 if func then func() end -- 如果是购买金币,刷新一下红点显示 if shopItemId == 10005 then CheckRedPointStatus(RedPointType.UpView_Gold) end -- 检测商店红点 this.CheckShopRedpot(shopType) -- 更新事件 Game.GlobalEvent:DispatchEvent(GameEvent.Shop.OnShopInfoChange) Game.GlobalEvent:DispatchEvent(GameEvent.Bag.BagGold) Game.GlobalEvent:DispatchEvent(GameEvent.Adventure.OnRefreshNextDayData) end) end -- 通过商店ID购买商品 function this.RequestBuyItemByShopId(shopId, shopItemId, num, func) if not shopId or not shopItemId or not num then return end NetManager.RequestBuyShopItem(shopId, shopItemId, num, function(msg) -- 显示掉落 if msg.drop.itemlist and #msg.drop.itemlist > 0 or msg.drop.equipId and #msg.drop.equipId > 0 or msg.drop.Hero and #msg.drop.Hero > 0 or msg.drop.soulEquip and #msg.drop.soulEquip > 0-- or -- msg.drop.especialEquipId and #msg.drop.especialEquipId > 0 then UIManager.OpenPanel(UIName.RewardItemPopup, msg.drop, 1) end -- 购买次数增加 local shopData = this.GetShopDataByShopId(shopId) for _, v in ipairs(shopData.storeItem) do if v.id == shopItemId then v.buyNum = v.buyNum + num break end end -- 消耗物品 改为后端刷新了 -- 完成回调 if func then func() end -- 如果是购买金币,刷新一下红点显示 if shopItemId == 10005 then CheckRedPointStatus(RedPointType.UpView_Gold) end -- 更新事件 Game.GlobalEvent:DispatchEvent(GameEvent.Shop.OnShopInfoChange) Game.GlobalEvent:DispatchEvent(GameEvent.Bag.BagGold) Game.GlobalEvent:DispatchEvent(GameEvent.Adventure.OnRefreshNextDayData) end) end -- 请求刷新商店数据 function this.RequestRefreshShop(shopType, isAuto, func) if not shopType or isAuto == nil then return end -- 判断商店是否激活 if not this.IsActive(shopType) then PopupTipPanel.ShowTip(Language[11934]) return end -- 判断物品是否足够 local shopId = this.GetShopDataByType(shopType).id local shopInfo = this.GetShopInfo(shopId) -- 自动恢复次数的类型不用消耗物品 local isAutoRecover = this.IsAutoRecoverCount(shopType) if not isAuto and not isAutoRecover then -- 判断是否有刷新次数 -- leftCount 为-1时为不限制刷新次数 local leftCount = this.GetShopLeftRefreshCount(shopType) if leftCount == -2 then PopupTipPanel.ShowTip(Language[11936]) return end if leftCount == 0 then PopupTipPanel.ShowTip(Language[11937]) return end local refreshNum = PrivilegeManager.GetPrivilegeUsedTimes(shopInfo.RefreshPrivilege) local costId, abcd = shopInfo.RefreshItem[1][1], shopInfo.RefreshItem[2] local costNum = CalculateCostCount(refreshNum, abcd) local haveNum = BagManager.GetItemCountById(costId) if haveNum < costNum then PopupTipPanel.ShowTip(Language[11938]) return end end NetManager.RequestRefreshShop(shopId, isAuto, function(msg) -- 数据刷新 local shopIndex = nil for index, v in ipairs(this.allShopData) do if v.id == shopId then shopIndex = index break end end if not shopIndex then return end -- 保存新数据,刷新排序 this.allShopData[shopIndex] = msg.storeInfo this.SortItemList(shopType) -- 不是自动刷新 if not isAuto and not isAutoRecover then -- 刷新次数 PrivilegeManager.RefreshPrivilegeUsedTimes(shopInfo.RefreshPrivilege, 1) end -- 完成回调 if func then func() end -- 检测红点显示 this.CheckShopRedpot(shopType) -- 更新事件 Game.GlobalEvent:DispatchEvent(GameEvent.Shop.OnShopInfoChange, true) end) end --- 获取主界面商店大页签数据 function ShopManager.GetMainShopPageList() -- 去重 local shopTypeData = ConfigManager.GetConfig(ConfigName.StoreTypeConfig) local tempList = {} for _, v in ConfigPairs(shopTypeData) do if v.IsShow == 1 then tempList[v.Pages] = v.Sort end end local _MainShopPages = {} for StoreType, _ in pairs(tempList) do table.insert(_MainShopPages, StoreType) end -- 排序 table.sort(_MainShopPages, function(a, b) return a < b end) return _MainShopPages end --- 获取商店主界面单个页签要显示的所有商店 function ShopManager.GetMainPageShopTypeList(page) -- 去重 local shopTypeData = ConfigManager.GetAllConfigsDataByKey(ConfigName.StoreTypeConfig, "Pages", page) local tempList = {} for _, v in ipairs(shopTypeData) do if v.IsShow == 1 then tempList[v.StoreType] = v.Sort end end local _ShopTypeList = {} for StoreType, _ in pairs(tempList) do table.insert(_ShopTypeList, StoreType) end -- 排序 table.sort(_ShopTypeList, function(a, b) return tempList[a] < tempList[b] end) return _ShopTypeList end -- 通过商店类型获取商店大页签 function ShopManager.GetShopPageByShopType(shopType) -- 去重 local shopTypeData = ConfigManager.GetConfigDataByKey(ConfigName.StoreTypeConfig, "StoreType", shopType) assert(shopTypeData, Language[11939]..shopType) return shopTypeData.Pages end -- 刷新商店物品列表排序 function this.SortItemList(shopType) -- 试炼副本商店不按sort字段排序 if shopType == SHOP_TYPE.TRIAL_SHOP then return end -- 排序 local shopData = nil for _, v in ipairs(this.allShopData) do local storeInfo = ConfigManager.GetConfigData(ConfigName.StoreTypeConfig, v.id) -- shopType不存在时全部刷新,否则按shoptype刷新 if not shopType or storeInfo.StoreType == shopType then -- 试炼副本商店不按sort字段排序 if storeInfo.StoreType ~= SHOP_TYPE.TRIAL_SHOP then table.sort(v.storeItem, function(a, b) local aId = a.id % _StoreItemIdFilter local bId = b.id % _StoreItemIdFilter local aInfo = ConfigManager.GetConfigData(ConfigName.StoreConfig, aId) local bInfo = ConfigManager.GetConfigData(ConfigName.StoreConfig, bId) -- 公会商店排序未解锁的往后排 if v.id == SHOP_TYPE.GUILD_SHOP and PlayerManager.familyId ~= 0 and MyGuildManager.GetMyGuildInfo() then local aIsUnLock = MyGuildManager.GetGuildShopSortIsUnLock(aInfo.Sort) local bIsUnLock = MyGuildManager.GetGuildShopSortIsUnLock(bInfo.Sort) if aIsUnLock and not bIsUnLock then return true end if not aIsUnLock and bIsUnLock then return false end end -- 免费的往前排 local _, a_price = this.calculateBuyCost(storeInfo.StoreType, aId, 1) local _, b_price = this.calculateBuyCost(storeInfo.StoreType, bId, 1) if a_price == 0 and b_price ~= 0 then return true end if a_price ~= 0 and b_price == 0 then return false end -- 按sort排序 return aInfo.Sort < bInfo.Sort end) end end end return shopData end -- 通过商店type获取商店数据 function this.GetShopDataByType(shopType) local shopData = nil for _, v in ipairs(this.allShopData) do local shopInfo = this.GetShopInfo(v.id) if shopInfo and shopInfo.StoreType == shopType then shopData = v break end end --assert(shopData, "未找到商店数据,请检查数据表及后端数据,商店类型 == "..shopType) return shopData end -- 通过商店id获取商店数据 function this.GetShopDataByShopId(shopId) local shopData = nil for _, v in ipairs(this.allShopData) do if v.id == shopId then shopData = v break end end --assert(shopData, "未找到商店数据,请检查数据表及后端数据,商店类型 == "..shopType) return shopData end -- 获取该类型所有商店数据 function this.GetAllShopDataByShopType(shopType) local list = {} for _, v in ipairs(this.allShopData) do local shopInfo = this.GetShopInfo(v.id) if shopInfo and shopInfo.StoreType == shopType then table.insert(list, v) end end return list end -- 通过商店id获取商店静态表数据 function this.GetShopInfo(shopId) return ConfigManager.GetConfigData(ConfigName.StoreTypeConfig, shopId) end -- 通过商店id获取商店静态表数据 function this.GetShopInfoByType(shopType) --local shopData = this.GetShopDataByType(shopType) --assert(shopData, "未找到商店数据,请检查服务器数据,商店类型 = "..shopType) --return this.GetShopInfo(shopData.id) return ConfigManager.GetConfigDataByKey(ConfigName.StoreTypeConfig, "StoreType", shopType) end -- 获取商品信息 function this.GetShopItemInfo(id) return ConfigManager.GetConfigData(ConfigName.StoreConfig, id % _StoreItemIdFilter) end -- 获取商品中包含的物品(物品数量要判断是否有玩家等级和vip等级加成) function ShopManager.GetShopItemGoodsInfo(id) local shopItemInfo = this.GetShopItemInfo(id) if not shopItemInfo.ExtraAdd then return shopItemInfo.Goods, 0 end local addValue = 0 local vipAdd = 0 for _, exAdd in ipairs(shopItemInfo.ExtraAdd) do local exType, exValue = exAdd[1], exAdd[2] if exType == 1 then local playerLevelExAdd = ConfigManager.GetConfigData(ConfigName.PlayerLevelConfig, PlayerManager.level).ExtraAdd addValue = addValue + (playerLevelExAdd/10000) elseif exType == 2 then vipAdd = PrivilegeManager.GetPrivilegeNumber(exValue) addValue = addValue + vipAdd end end local goods = {} for _, g in ipairs(shopItemInfo.Goods) do local id = g[1] local num = g[2] num = num * (1 + addValue) table.insert(goods, {id, num}) end return goods, addValue, vipAdd end -- 获取商品信息 function this.GetShopItemData(shopType, itemId) local shopData = this.GetShopDataByType(shopType) if not shopData then return end local itemData = nil for _, v in ipairs(shopData.storeItem) do if v.id == itemId then itemData = v end end assert(itemData, Language[11940]..itemId) return itemData end -- 获取商品信息 function this.GetRechargeItemInfo(id) return ConfigManager.GetConfigData(ConfigName.RechargeCommodityConfig, id) end -- 判断主界面大页签是否解锁 function this.IsPageActive(page) local shopTypeList = this.GetMainPageShopTypeList(page) for _, shopType in ipairs(shopTypeList) do if this.IsActive(shopType) then return true end end return false end -- 判断商店是否是激活状态 function ShopManager.IsActive(shopType) -- 获取数据 local shopData = this.GetShopDataByType(shopType) if not shopData then return false end -- 判断类型 local shopInfo = this.GetShopInfo(shopData.id) if not shopInfo then return false end -- 判断该商店是否受到商店系统解锁的影响 0 表示影响 if shopInfo.OpenSystem == 0 then if not ActTimeCtrlManager.SingleFuncState(FUNCTION_OPEN_TYPE.SHOP) then return false end end -- 判断是否解锁 if shopInfo.OpenLevel and shopInfo.OpenLevel[1] then local openType, openValue = shopInfo.OpenLevel[1], shopInfo.OpenLevel[2] if openType == 1 then if not FightPointPassManager.IsFightPointPass(openValue) then local fightConfig = ConfigManager.GetConfigData(ConfigName.MainLevelConfig, openValue) return false, string.format(Language[10774], fightConfig.Name) end elseif openType == 2 then if PlayerManager.level < openValue then return false, string.format(Language[10775], openValue) end elseif openType == 3 then if not ActTimeCtrlManager.SingleFuncState(openValue) then return false, ActTimeCtrlManager.GetFuncTip(openValue) end end end -- 公会商店特殊处理 if shopType == SHOP_TYPE.GUILD_SHOP and PlayerManager.familyId == 0 then return false, Language[10405] end if shopInfo.StoreOpenRule == 1 then return true end -- 判断时间戳(毫秒) local curTimeStamp = GetTimeStamp() * 1000 -- if curTimeStamp >= shopData.startTime and curTimeStamp <= shopData.endTime then return true end return false end -- 获取最大刷新次数 -- -2 不支持手动刷新 -- -1 无限制次数 function this.GetMaxRefreshCount(shopType) -- 判断是否开启手动刷新 local shopInfo = this.GetShopInfoByType(shopType) if shopInfo.IfManualRefresh[1] ~= 0 then -- 自动恢复次数的刷新类型 return shopInfo.IfManualRefresh[1] elseif shopInfo.IfManualRefresh[1] == 0 and shopInfo.IfManualRefresh[2] == 0 then return -2 end -- 判断是否是无限制次数 local privilege = shopInfo.RefreshPrivilege if not privilege or privilege == 0 then return -1 end -- 最大次数 local count = PrivilegeManager.GetPrivilegeNumber(privilege) return count end -- 获取商店剩余刷新次数 -2 不支持手动刷新 -1 无限制次数 function this.GetShopLeftRefreshCount(shopType) local isAutoRecover, leftCount = this.IsAutoRecoverCount(shopType) if isAutoRecover then return leftCount end -- 获取最大刷新次数 local maxRefreshCount = this.GetMaxRefreshCount(shopType) if maxRefreshCount < 0 then return maxRefreshCount end -- 计算剩余次数 local privilege = this.GetShopInfoByType(shopType).RefreshPrivilege local leftCount = PrivilegeManager.GetPrivilegeRemainValue(privilege) return leftCount end -- 判断当前商店时候有自动恢复的免费次数 function this.IsAutoRecoverCount(shopType) -- 判断是否是自动恢复免费次数的类型 local shopInfo = this.GetShopInfoByType(shopType) if shopInfo.IfManualRefresh[1] == 0 then -- 自动恢复次数的刷新类型 return false end -- 计算剩余免费次数 local maxTime = shopInfo.IfManualRefresh[1] local refreshTime = shopInfo.IfManualRefresh[2] * 3600 local curTimeStamp = GetTimeStamp() local shopData = this.GetShopDataByType(shopType) local lastRefreshTime = math.floor(shopData.lastRefreshTime / 1000) local leftCount = math.min(maxTime, math.floor(math.ceil(curTimeStamp - lastRefreshTime)/refreshTime)) -- 如果没有免费次数了,但是有特权刷新次数 if leftCount <= 0 and shopInfo.RefreshPrivilege ~= 0 then return false end -- return true, leftCount end --- 每秒检测商店刷新时间 function this.CheckShopRefreshTime() if this._IsRefresh > 0 then return end this._IsRefresh = 0 this._RefreshShopList = {} for _, v in ipairs(this.allShopData) do local leftTime = this.CountShopRefreshLeftTime(v.id) local shopInfo = this.GetShopInfo(v.id) local shopType = shopInfo.StoreType this._RefreshShopList[shopType] = leftTime -- 判断是否需要刷新商店 if leftTime == 0 then -- 只有按时间长度刷新的商店需要前端主动请求刷新 if #shopInfo.RefreshType ~= 0 and shopInfo.RefreshType[1] == 3 then this._IsRefresh = this._IsRefresh + 1 -- 延时一秒刷新 Timer.New(function() --Log("商店自动刷新 = "..shopType) this.RequestRefreshShop(shopType, true, function() --Log("商店自动刷新成功 = "..shopType) this._IsRefresh = this._IsRefresh - 1 end) end, 1, 1, true):Start() end end end end --- 计算商店刷新剩余时间 -1表示不刷新 function this.CountShopRefreshLeftTime(shopId) local shopInfo = this.GetShopInfo(shopId) if not shopInfo then return -1 end -- 判断商店是否激活 local shopType = shopInfo.StoreType if not this.IsActive(shopType) then return -1 end --local shopData = this.GetShopDataByType(shopType) if #shopInfo.RefreshType == 0 or shopInfo.RefreshType[1] == 1 then return -1 --- 固定时间点刷新 elseif shopInfo.RefreshType[1] == 2 then local shopData = this.GetShopDataByType(shopType) local lastRefreshTime = shopData.lastRefreshTime / 1000 local N_TimeStamp = Today_N_OClockTimeStamp(shopInfo.RefreshType[2]) -- 距离上次刷新时间大于一天 if N_TimeStamp - lastRefreshTime > 86400 then return 0 end -- 刷新时间正确修正 local curTimeStamp = GetTimeStamp() if curTimeStamp < lastRefreshTime then return -1 end -- 这里循环10次足矣,避免死循环 for day = 0, 10 do for i = 2, #shopInfo.RefreshType do N_TimeStamp = Today_N_OClockTimeStamp(shopInfo.RefreshType[i]) + (86400 * day) if N_TimeStamp > lastRefreshTime and curTimeStamp < N_TimeStamp then -- 计算剩余时间 local lastTime = N_TimeStamp - curTimeStamp return lastTime < 0 and 0 or lastTime end end end return -1 -- while N_TimeStamp < lastRefreshTime do -- N_TimeStamp = N_TimeStamp + 86400 -- end -- 计算剩余时间 -- local lastTime = N_TimeStamp - curTimeStamp -- return lastTime < 0 and 0 or lastTime --- 按时间长度刷新 elseif shopInfo.RefreshType[1] == 3 then local shopData = this.GetShopDataByType(shopType) local lastRefreshTime = shopData.lastRefreshTime / 1000 local deltaSeconds = shopInfo.RefreshType[2] * 60 * 60 local lastTime = lastRefreshTime + deltaSeconds - GetTimeStamp() return lastTime < 0 and 0 or lastTime end end --- 获取刷新剩余时间 function this.GetShopRefreshLeftTime(shopType) return this._RefreshShopList[shopType] or -1 end -- 获取商店剩余多少时间关闭 -1表示未开启/已关闭 function this.GetShopCloseTime(shopType) -- 常驻商店没有关闭时间 local shopData = this.GetShopDataByType(shopType) local shopInfo = this.GetShopInfo(shopData.id) if not shopInfo or shopInfo.StoreOpenRule == 1 then return -1 end local shopData = this.GetShopDataByType(shopType) if not shopData then return -1 end -- 判断时间戳 local curTimeStamp = GetTimeStamp() ---毫秒 -- 时间未到 --if curTimeStamp < shopData.startTime then -- return -1 --end -- 计算剩余时间 local leftTime = math.floor((shopData.endTime / 1000) - curTimeStamp) return leftTime end -- 获取商店自动恢复次数的刷新时间 function this.GetShopRefreshCountRecoverTime(shopType) local shopInfo = this.GetShopInfoByType(shopType) if shopInfo.IfManualRefresh[1] == 0 then -- 自动恢复次数的刷新类型 return -1 end local maxTime = shopInfo.IfManualRefresh[1] local refreshTime = shopInfo.IfManualRefresh[2] * 3600 local curTimeStamp = GetTimeStamp() local shopData = this.GetShopDataByType(shopType) local lastRefreshTime = shopData.lastRefreshTime / 1000 local leftCount = math.min(maxTime, math.floor((curTimeStamp - lastRefreshTime)/refreshTime)) if leftCount == maxTime then return 0 end -- 计算剩余时间 local refreshTime = refreshTime - (curTimeStamp - lastRefreshTime) % refreshTime return refreshTime end -- 获取商品限制购买数量(返回-1 表示不限购) function this.GetShopItemLimitBuyCount(itemId) local itemInfo = this.GetShopItemInfo(itemId) local count = 0 if itemInfo.RelatedtoVIP == 1 then local privilege = itemInfo.Limit count = PrivilegeManager.GetPrivilegeNumber(privilege) else if itemInfo.Limit == 0 then count = -1 else count = itemInfo.Limit end end return count end --获取商品已购买次数 function this.GetShopItemHadBuyTimes(shopType, itemId) local shopData = this.GetShopDataByType(shopType) for _, v in ipairs(shopData.storeItem) do if v.id == itemId then return v.buyNum end end return 0 end --获取商品剩余购买次数(-1表示不限次数) function this.GetShopItemRemainBuyTimes(shopType, itemId) if this.GetShopItemLimitBuyCount(itemId) == -1 then return -1 else return this.GetShopItemLimitBuyCount(itemId) - this.GetShopItemHadBuyTimes(shopType, itemId) end end -- 获取商品最多购买数量(跟据要消耗的物品计算) function this.GetShopItemMaxBuy(shopType, itemId) local shopData = this.GetShopDataByType(shopType) local startNum = nil for _, v in ipairs(shopData.storeItem) do if v.id == itemId then startNum = v.buyNum break end end -- 所需物品 local itemInfo = this.GetShopItemInfo(itemId) -- 计算折扣,0折直接返回999 local discount = itemInfo.IsDiscount == 1 and itemInfo.DiscountDegree * 0.1 or 1 if discount == 0 then return 999 end local costId = itemInfo.Cost[1][1] local ownValue = BagManager.GetTotalItemNum(costId) -- 计算消耗数量 local oriCostNum = 0 if itemInfo.PremiumType == 1 then -- 用公式计算 local abcd = itemInfo.Cost[2]-- 公式常数 for i = 0, 999 do oriCostNum = oriCostNum + CalculateCostCount(startNum + i, abcd) local finalNum = oriCostNum * discount if finalNum > ownValue then return i end end elseif itemInfo.PremiumType == 2 then -- 数组数量相加 local ary = itemInfo.Cost[2]-- 组数 for i = 1, 999 do local addValue = ary[startNum + i] or ary[#ary] oriCostNum = oriCostNum + addValue local finalNum = oriCostNum * discount if finalNum > ownValue then return i - 1 end end end return 999 end -- 计算商店够买物品所需要的花费 function this.calculateBuyCost(shopType, itemId, count) -- 计算已经购买的次数 local shopData = this.GetShopDataByType(shopType) return this.CalculateCostCountByShopId(shopData.id, itemId, count) end function this.CalculateCostCountByShopId(shopId, itemId, count) local shopData = this.GetShopDataByShopId(shopId) local startNum = nil for _, v in ipairs(shopData.storeItem) do if v.id == itemId then startNum = v.buyNum break end end -- 没有物品数据 if not startNum then return end -- 所需物品 local itemInfo = this.GetShopItemInfo(itemId) local costId = itemInfo.Cost[1][1] -- 计算消耗数量 local oriCostNum = 0 if itemInfo.PremiumType == 1 then -- 用公式计算 local abcd = itemInfo.Cost[2]-- 公式常数 for i = 0, count - 1 do oriCostNum = oriCostNum + CalculateCostCount(startNum + i, abcd) end elseif itemInfo.PremiumType == 2 then -- 数组数量相加 local ary = itemInfo.Cost[2]-- 组数 for i = 1, count do local addValue = ary[startNum + i] or ary[#ary] oriCostNum = oriCostNum + addValue end end -- 判断是否打折 local discount = itemInfo.IsDiscount == 1 and itemInfo.DiscountDegree * 0.1 or 1 local finalNum = oriCostNum * discount return costId, finalNum, oriCostNum end -- 外部增加商品购买次数,别瞎用 function this.AddShopItemBuyNum(shopType, shopItemId, num) -- 购买次数增加 local shopData = this.GetShopDataByType(shopType) for _, v in ipairs(shopData.storeItem) do if v.id == shopItemId then v.buyNum = v.buyNum + num break end end end -- 判断商店中是否有免费物品 function this.IsHaveFreeItem(shopType) -- 商店未解锁 if not this.IsActive(shopType) then return false end -- 没有商店数据 local shopData = this.GetShopDataByType(shopType) if not shopData then return false end -- 判断商店中是否有免费的商品(商品有提前排序,免费的商品一定在前面,只要碰到了不免费的商品,说明此商店中没有免费商品) for _, v in ipairs(shopData.storeItem) do if v.buyNum == 0 then local _, price = ShopManager.calculateBuyCost(shopType, v.id, 1) if price == 0 then if shopType == SHOP_TYPE.GUILD_SHOP then local Info = ConfigManager.GetConfigData(ConfigName.StoreConfig, v.id) local IsUnLock = MyGuildManager.GetGuildShopSortIsUnLock(Info.Sort) return IsUnLock end return true end return false end end return false end -- 获取主界面商店中的所有商店是否有拥有免费物品的商店 function this.GetMainShopFreeShop() for _, data in ipairs(this.allShopData) do local shopConfig = ConfigManager.GetConfigData(ConfigName.StoreTypeConfig, data.id) if shopConfig and shopConfig.IsShow == 1 then if this.IsHaveFreeItem(shopConfig.StoreType) then return shopConfig.StoreType end end end end ---===========================红点相关======================================== --- 商店的查看时间 local _ShopCheckTime = {} --- 商店刷新按钮的点击状态 local _RefreshBtnIsClick = {} -- 检测红点数据,shopType 为空时检测所有商店 function this.ShopCheckRPIsShow(shopType) -- 没有商店数据 local shopData = this.GetShopDataByType(shopType) if not shopData then return false end -- 商店未解锁 if not this.IsActive(shopType) then return false end -- 商店查看时间不存在, 都不显示红点 local _LastCheckTime = _ShopCheckTime[shopType] if _LastCheckTime and _LastCheckTime ~= 0 then -- 商店查看时间小于刷新时间,显示红点 --Log("商店红点检测: 上次查看时间 = ".._LastCheckTime..", 商店刷新时间 = "..shopData.lastRefreshTime/1000) if _LastCheckTime < shopData.lastRefreshTime/1000 then return true end end -- 判断商店中是否有免费的商品 local isFree = this.IsHaveFreeItem(shopType) return isFree end -- 检测商店刷新次数是否存在 function this.ShopRefreshRPIsShow(shopType) -- 判断今天商店的刷新按钮是否被点击过 if _RefreshBtnIsClick[shopType] then return false end -- 没有商店数据 local shopData = this.GetShopDataByType(shopType) if not shopData then return false end -- 商店未解锁 if not this.IsActive(shopType) then return false end -- 商店剩余刷新次数 local leftRefreshCount = this.GetShopLeftRefreshCount(shopType) return leftRefreshCount > 0 end -- 向红点注册的检测方法 function this.ShopRedCheck(redType) if redType == RedPointType.Guild_Shop or redType == RedPointType.Shop_Guild_Check then return this.ShopCheckRPIsShow(SHOP_TYPE.GUILD_SHOP) elseif redType == RedPointType.Arena_Shop or redType == RedPointType.Shop_Arena_Check then return this.ShopCheckRPIsShow(SHOP_TYPE.ARENA_SHOP) elseif redType == RedPointType.Shop_Roam_Check then return this.ShopCheckRPIsShow(SHOP_TYPE.ROAM_SHOP) elseif redType == RedPointType.Shop_Secret_Check then return this.ShopCheckRPIsShow(SHOP_TYPE.SECRET_BOX_SHOP) elseif redType == RedPointType.Shop_General_Check then return this.ShopCheckRPIsShow(SHOP_TYPE.GENERAL_SHOP) elseif redType == RedPointType.Shop_General_Refresh then return this.ShopRefreshRPIsShow(SHOP_TYPE.GENERAL_SHOP) end end -- 根据商店类型检测相应的红点 function this.CheckShopRedpot(shopType) if shopType == SHOP_TYPE.GUILD_SHOP then CheckRedPointStatus(RedPointType.Shop_Guild_Check) CheckRedPointStatus(RedPointType.Guild_Shop) elseif shopType == SHOP_TYPE.ARENA_SHOP then CheckRedPointStatus(RedPointType.Shop_Arena_Check) CheckRedPointStatus(RedPointType.Arena_Shop) elseif shopType == SHOP_TYPE.ROAM_SHOP then CheckRedPointStatus(RedPointType.Shop_Roam_Check) elseif shopType == SHOP_TYPE.SECRET_BOX_SHOP then CheckRedPointStatus(RedPointType.Shop_Secret_Check) elseif shopType == SHOP_TYPE.GENERAL_SHOP then CheckRedPointStatus(RedPointType.Shop_General_Check) CheckRedPointStatus(RedPointType.Shop_General_Refresh) elseif shopType == SHOP_TYPE.BUYCOIN_SHOP then CheckRedPointStatus(RedPointType.UpView_Gold) end end -- 从本地加载红点数据 function this.LoadRedpotDataFromLocal() -- 检测所有商店 for _, type in pairs(SHOP_TYPE) do _ShopCheckTime[type] = PlayerPrefs.GetInt(PlayerManager.uid.."_ShopRedPot_"..type) _RefreshBtnIsClick[type] = PlayerPrefs.GetInt(PlayerManager.uid.."_ShopBtnStatus_"..type) == 1 end end -- 刷新商店的查看时间到当前时间 function this.RefreshShopCheckTime(shopType) if not shopType then return end -- 保存查看的时间戳 local curTimeStamp = GetTimeStamp() PlayerPrefs.SetInt(PlayerManager.uid.."_ShopRedPot_"..shopType, curTimeStamp) _ShopCheckTime[shopType] = curTimeStamp this.CheckShopRedpot(shopType) end -- 设置商店刷新按钮是否被点击过 function this.SetShopRefreshBtnClickStatus(shopType, status) PlayerPrefs.SetInt(PlayerManager.uid.."_ShopBtnStatus_"..shopType, status and 1 or 0) _RefreshBtnIsClick[shopType] = status this.CheckShopRedpot(shopType) end -- 商店五点刷新红点状态重置 function this.FiveAMRedpotStatusReset() -- 检测所有商店 for _, type in pairs(SHOP_TYPE) do this.SetShopRefreshBtnClickStatus(type, false) end end -- 检测是否有免费的金币购买次数 function this.CheckGoldIsFree() local shopItemData = this.GetShopItemData(SHOP_TYPE.BUYCOIN_SHOP, 10005) if not shopItemData or shopItemData.buyNum ~= 0 then return false end return true end -- 检查是否有免费的可购买的商品 function this.HaveFreeBaby() local haveFree = false --新手礼包开启时 每天第一次登陆打开显示红点 if this.IsActive(SHOP_TYPE.NOVICE_GIFT_SHOP ) and this.CheckNoviceGiftData() then if PatFaceManager.isFirstLog==0 and this.isOpenNoviceGift==false then haveFree = true else haveFree = false end else local shopType = SHOP_TYPE.FREE_GIFT local shopData = ShopManager.GetShopDataByType(shopType) if not shopData then return false end for _, v in ipairs(shopData.storeItem) do local costId, finalNum, oriCostNum = ShopManager.calculateBuyCost(shopType, v.id, 1) local leftTimes = this.GetShopItemRemainBuyTimes(shopType, v.id) if finalNum == 0 and leftTimes > 0 then haveFree = true break end end end return haveFree end --检查是否有未购买的新手礼包 function this.CheckNoviceGiftData() for i, v in ipairs(ShopManager.GetShopDataByType(SHOP_TYPE.NOVICE_GIFT_SHOP).storeItem) do if v.buyNum==0 then return true end end return false end return this