local ItemEntity = require "app/userdata/bag/item_entity" local ItemConst = require "app/module/item/item_const" local ItemData = class("ItemData", BaseData) local RECOVERY_TYPE_TIME = 1 local RECOVERY_TYPE_DAILY = 2 local CACHE_ITEM = { id = 0, count = 0 } function ItemData:ctor() self.items = {} end function ItemData:init(data) self.items = {} data = data or {} if data.items then for _, info in pairs(data.items) do if info.id == GConst.ItemConst.ITEM_ID_GEM then local parmas = {} parmas.user_gem = info.count CS.ThinkingAnalytics.ThinkingAnalyticsAPI.UserSet(parmas) elseif info.id == GConst.ItemConst.ITEM_ID_GOLD then local parmas = {} parmas.user_gold = info.count CS.ThinkingAnalytics.ThinkingAnalyticsAPI.UserSet(parmas) end if info.id == GConst.ItemConst.ITEM_ID_VIT then DataManager.PlayerData:setVit(info.count) end if info.id == GConst.ItemConst.ITEM_ID_ARENA_TICKET then DataManager.PlayerData:setArenaTicket(info.count) end self:_add(info.id, info.count) end end self.recoveryList = {} self.recoveryMap = {} if data.recoveries then local recoveryCfg = ConfigManager:getConfig("recovery") for k, v in pairs(data.recoveries) do local recoveryInfo = recoveryCfg[v.id] if recoveryInfo then local obj = { id = v.id, ts = v.ts // 1000, limit = recoveryInfo.limit, recoveryType = recoveryInfo.type, time = recoveryInfo.time } self.recoveryMap[v.id] = obj table.insert(self.recoveryList, obj) end end end self.initDay = Time:getBeginningOfServerToday() self.data.dirty = false end function ItemData:_add(id, num) self.items[id] = ItemEntity:create(id, num) end function ItemData:clear() self.items = {} end -- 根据id获取道具 function ItemData:getItemById(id) if self.items[id] then return self.items[id] end local item = ItemEntity:create(id, 0) self.items[id] = item return self.items[id] end -- 获取所有道具数据 function ItemData:getAllItems() return self.items end function ItemData:getItemNumById(id) local num if self.items[id] then num = self.items[id]:getNum() else num = 0 end return num end function ItemData:getVit() return self:getItemNumById(GConst.ItemConst.ITEM_ID_VIT) end function ItemData:addItemReward(item, itemGetType) CACHE_ITEM.id = GFunc.getRewardId(item) CACHE_ITEM.count = GFunc.getRewardNum(item) self:addItem(CACHE_ITEM, itemGetType) end function ItemData:addItemCost(cost, itemGetType) CACHE_ITEM.id = GFunc.getRewardId(cost) CACHE_ITEM.count = -GFunc.getRewardNum(cost) self:addItem(CACHE_ITEM, itemGetType) self:setDirty() end function ItemData:addItemCosts(costs, itemGetType) if not costs then return end for _, cost in ipairs(costs) do self:addItemCost(cost, itemGetType) end end function ItemData:addItem(data, itemGetType) if data == nil then return end if EDITOR_MODE then if not itemGetType then local params = { content = "ItemData addItem has no itemGetType", boxType = GConst.MESSAGE_BOX_TYPE.MB_OK, okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK), } GFunc.showMessageBox(params) Logger.log("ItemData addItem has no itemGetType") end end self:_addItemNumById(data.id, data.count) if data.id == GConst.ItemConst.ITEM_ID_GEM then if data.count < 0 then ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_GEM_COST, -data.count) BIReport:postGemUse(data.count, itemGetType, data.id) else ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_GEM_GOT, data.count) BIReport:postGemGet(data.count, itemGetType, data.id) end CS.ThinkingAnalytics.ThinkingAnalyticsAPI.UserAdd("user_gem", data.count) elseif data.id == GConst.ItemConst.ITEM_ID_GOLD then if data.count < 0 then ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_GOLD_COST, -data.count) BIReport:postGemUse(data.count, itemGetType, data.id) else ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_GOLD_GOT, data.count) BIReport:postGemGet(data.count, itemGetType, data.id) end CS.ThinkingAnalytics.ThinkingAnalyticsAPI.UserAdd("user_gold", data.count) elseif data.id == GConst.ItemConst.ITEM_ID_VIT then if data.count < 0 then ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_VIT_COST, -data.count) BIReport:postVitUse(data.count, itemGetType) else BIReport:postVitGet(data.count, itemGetType) end elseif data.id == GConst.ItemConst.ITEM_ID_RUNES then if data.count > 0 then ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_RUNES_GETED_MATERIALS, data.count) BIReport:postItemGet(data.count, data.id, itemGetType) else BIReport:postItemUse(data.count, data.id, itemGetType) end else if data.count < 0 then BIReport:postItemUse(data.count, data.id, itemGetType) else BIReport:postItemGet(data.count, data.id, itemGetType) end end end function ItemData:addItemNumById(id, num, itemGetType) CACHE_ITEM.id = id CACHE_ITEM.count = num self:addItem(CACHE_ITEM, itemGetType) end function ItemData:_addItemNumById(id, num) if num == nil then return end local isFull = false if id == ItemConst.ITEM_ID_VIT then local maxVit = DataManager.PlayerData:getMaxVit() local currentCount = DataManager.PlayerData:getVit() isFull = currentCount >= maxVit end if self.items[id] then self.items[id]:addNum(num) else if id == ItemConst.ITEM_ID_VIT then DataManager.PlayerData:setVit(num) end self:_add(id, num) end if self.items[id]:getItemType() == ItemConst.ITEM_TYPE.HERO_FRAGMENT then if num > 0 then ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_HERO_FRAGMENT_GOT, num) end DataManager.HeroData:setDirty() end if id == ItemConst.ITEM_ID_VIT then DataManager.PlayerData:setVit(self.items[id]:getNum()) if isFull then local maxVit = DataManager.PlayerData:getMaxVit() local currentCount = DataManager.PlayerData:getVit() local isNewFull = currentCount >= maxVit if not isNewFull then self:resetItemRecoveryTime(ItemConst.ITEM_ID_VIT) end end -- elseif id == ItemConst.ITEM_ID_BOUNTY_EXP then -- DataManager.BountyData:addExp(num) elseif id == ItemConst.ITEM_ID_ARENA_BOUNTY_EXP then DataManager.ArenaBountyData:addExp(num) elseif id == ItemConst.ITEM_ID_EXP then DataManager.PlayerData:addExp(num) end self:setDirty() end -- 清空道具,用于活动重开的时候清除对应道具 function ItemData:clearItemCount(id) if not self.items[id] then return end self.items[id]:setNum(0) self:setDirty() end function ItemData:setDirty() self.data.dirty = not self.data.dirty end -- 是否按时间恢复 function ItemData:isTimingRecovery(itemId) local data = self.recoveryMap[itemId] if not data then return -1 end return data.type == RECOVERY_TYPE_TIME end function ItemData:getTimelyItemRecoveryTime(itemId) local data = self.recoveryMap[itemId] if not data then return -1 end -- 计算当前值和最大值 local currNum = self:getItemNumById(itemId) -- 如果是最大,则重置上一次时间为当前时间 if currNum >= data.limit then return -1 end -- 计算时间 if self:isTimingRecovery(itemId) then local remainTime = data.ts + data.time - Time:getServerTime() return remainTime else -- 无自动恢复时间 return -1 end end -- 按时间回复的在此回复 function ItemData:recoveryItem(data) -- 计算已经达到上限 local itemId = data.id local currNum = self:getItemNumById(itemId) if currNum >= data.limit then return end -- 计算恢复间隔 local nowTime = Time:getServerTime() local diffTime = nowTime - data.ts -- 上次回复时间,此处计算离线总共回复多少个 if diffTime <= 0 then return end -- 计算增加数量 local recoverTime = data.time local addCount = math.floor(diffTime / recoverTime) if addCount <= 0 then return end -- 计算此次实际增加数量 local addAfterNum = currNum + addCount if addAfterNum > data.limit then addCount = data.limit - currNum end -- 根据实际增加的数量,计算恢复时间 data.ts = data.ts + recoverTime * addCount self:addItemNumById(itemId, addCount, BIReport.ITEM_GET_TYPE.RECOVERY_TIME) end -- 每日回复的在此回复 function ItemData:recoveryDailyItem(data) if not self:isDayChange() then return end local itemId = data.id local currNum = self:getItemNumById(itemId) if currNum < data.limit then self:addItemNumById(itemId, data.limit - currNum, BIReport.ITEM_GET_TYPE.CROSS_DAY) end end function ItemData:resetItemRecoveryTime(itemId) local obj = self.recoveryMap[itemId] if obj then obj.ts = Time:getServerTime() -- else -- local obj = { -- id = v.id, -- ts = v.ts // 1000, -- limit = recoveryInfo.limit, -- recoveryType = recoveryInfo.type, -- time = recoveryInfo.time -- } -- self.recoveryMap[v.id] = obj -- table.insert(self.recoveryList, obj) end end function ItemData:updateCd() if not self.recoveryList then return end for i, v in ipairs(self.recoveryList) do if v.recoveryType == RECOVERY_TYPE_DAILY then self:recoveryDailyItem(v) -- 每日的直接加满 else self:recoveryItem(v) -- 根据间隔时间增加 end end self.initDay = Time:getBeginningOfServerToday() end function ItemData:isDayChange() return self.initDay ~= Time:getBeginningOfServerToday() end return ItemData