miduo_client/Assets/ManagedResources/~Lua/Modules/Shop/ShopManager.lua

1134 lines
38 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

--- 商店物品管理类
--- 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