c1_lua/lua/app/userdata/bag/item_data.lua
2023-09-19 18:11:52 +08:00

355 lines
9.2 KiB
Lua

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