ro-webgl/Assets/Lua/Logic/FashionData.lua
2021-12-21 09:40:39 +08:00

520 lines
18 KiB
Lua

local FashionData = class("FashionData", require("DataBase"))
local JSON = require('json')
local CACHE_FASHION_KEY_NAME = "Cache_Fashion_Key"
function FashionData:ctor()
self.data = {}
self.data.fashionMap = {}
self.data.fashionSuitMap = {}
end
function FashionData:RegisterNetEvents()
ManagerContainer.NetManager:NetRegister(ProtoMsgId.SC_FASHION_NTF, function(data)
if ManagerContainer.NetManager:IsErrorData(data) then
return
end
if data.lvs then
for _,v in pairs(data.lvs) do
local lv = self:GetSuitLvByFashionLv(v.key, v.value)
local lvUp = false
local oldLv = self.data.fashionSuitMap[v.key]
local isNew = oldLv == nil
if oldLv then
lvUp = lv > oldLv
end
self.data.fashionSuitMap[v.key] = lv
self:FashionSuitClacAttrs(v.key, lv, lvUp, isNew)
end
end
local changed, addFashionMap, upFashionList, downFashionList = self:RefreshFashionData(data.fashion_data)
if changed then
ManagerContainer.DataMgr.UserData:CalcFashionAttrs()
ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.FASHION_LIST_CHANGE)
ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.EID_FASHION_ADD, addFashionMap)
else
-- upFashionList 表示新穿的时装
-- 需要跟原来身上的时装进行比较
local viewChanged = false
local viewData = ManagerContainer.DataMgr.UserData:GetViewData()
local totalUpFashionList = {}
if viewData and viewData.fashionData then
for _,v in pairs(viewData.fashionData) do
totalUpFashionList[#totalUpFashionList + 1] = v
end
end
if upFashionList then
for _,v in pairs(upFashionList) do
local result, idx = CommonUtil.EleInTable(v, totalUpFashionList)
if not result then
totalUpFashionList[#totalUpFashionList + 1] = v
viewChanged = true
end
end
end
if downFashionList then
for _,v in pairs(downFashionList) do
local result, idx = CommonUtil.EleInTable(v, totalUpFashionList)
if result then
table.remove(totalUpFashionList, idx)
viewChanged = true
end
end
end
if viewChanged then
ManagerContainer.DataMgr.UserData:UpdateFashionUpData(totalUpFashionList)
ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.FASHION_WEAR_CHANGE)
end
end
end)
ManagerContainer.NetManager:NetRegister(ProtoMsgId.SC_FASHION_UP_LVL_ACK,self.OnFashionLvUpAck, self)
ManagerContainer.NetManager:NetRegister(ProtoMsgId.SC_FASHION_RESET_ATTR_ACK,self.OnFashionWashAck, self)
ManagerContainer.NetManager:NetRegister(ProtoMsgId.SC_FASHION_PAPER_DECOMPOSE_ACK,self.OnFashionPagerDecomposeAck, self)
end
function FashionData:Clear()
self.data = {}
self.data.fashionMap = {}
self.data.fashionSuitMap = {}
end
function FashionData:Destroy()
if self.Clear then
self:Clear()
end
self:UnRegisterNetEvents()
end
function FashionData:UnRegisterNetEvents()
end
function FashionData:InitFashionData(roleFashion)
if not roleFashion or not roleFashion.fashion_data then return end
self.washState = false
local userSex = ManagerContainer.DataMgr.UserData:GetSex()
local cacheFashionData = self:ReadCacheFashionData()
local fashionData = roleFashion.fashion_data
local cfgMgr = ManagerContainer.CfgMgr
for _,v in pairs(fashionData) do
local cfgId = v.fashion_id
local fashionCfgData = cfgMgr:GetFashionById(cfgId)
if not fashionCfgData then
LogError("[Wboy] .. ".. cfgId .. " 时装ID不存在")
elseif not fashionCfgData.FashionOpen then
LogError("[Wboy] 无力吐槽 不能获得的时装,策划竟然让玩家获得了 ".. cfgId)
elseif fashionCfgData.FashionSex > 0 and fashionCfgData.FashionSex ~= userSex then
LogError("[Wboy] 无力吐槽 不能获得异性的时装,策划竟然让玩家获得了 ".. cfgId)
else
local isNew
if cacheFashionData then
isNew = cacheFashionData[cfgId]
if isNew == nil then
isNew = false
end
else
isNew = false
end
local data = self.data.fashionMap[cfgId]
if not data then
data = {cfgId = cfgId}
self.data.fashionMap[cfgId] = data
end
data.isNew = isNew
data.lv = v.fashion_lvl
data.wear = v.fashion_wear
data.oldAttrs = {}
data.attrs = {}
for _,v1 in pairs(v.attrs) do
data.attrs[#data.attrs + 1] = v1
end
data.resetAttrs = {}
for _,v1 in pairs(v.resetAttrs) do
data.resetAttrs[#data.resetAttrs + 1] = v1
end
self:FashionLvUpCanState(data)
end
end
if roleFashion.lvs then
for _,v in pairs(roleFashion.lvs) do
local lv = self:GetSuitLvByFashionLv(v.key, v.value)
self.data.fashionSuitMap[v.key] = lv
end
end
self:ClacFashionAttrs()
self:FashionDataNotify()
end
function FashionData:FashionDataNotify()
local result = false
for _,v in pairs(self.data.fashionMap) do
if v.canLvUp then
result = true
end
end
ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.RED_POINT_MGR_NOTICE, Enum.RPNotifyType.FashionLvUp, result)
end
function FashionData:RefreshAllFashionLvUpNotify()
local result = false
for _,v in pairs(self.data.fashionMap) do
self:FashionLvUpCanState(v)
if v.canLvUp then
result = true
end
end
ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.RED_POINT_MGR_NOTICE, Enum.RPNotifyType.FashionLvUp, result)
end
function FashionData:ClacFashionAttrs()
self.data.fashionAttrs = {}
for k,v in pairs(self.data.fashionMap) do
for _,v1 in pairs(v.attrs) do
local jobType = v1.jobType + 1
local attrId = v1.attrId
local value = v1.value
if not self.data.fashionAttrs[jobType] then
self.data.fashionAttrs[jobType] = {}
end
if not self.data.fashionAttrs[jobType][attrId] then
self.data.fashionAttrs[jobType][attrId] = 0
end
value = attrId > 21 and CommonUtil.GetPreciseDecimal(value, 4) or math.floor(value)
self.data.fashionAttrs[jobType][attrId] = self.data.fashionAttrs[jobType][attrId] + value
end
end
self.data.suitAttrs = {}
for k,v in pairs(self.data.fashionSuitMap) do
local suitCfgData = ManagerContainer.CfgMgr:GetFashionSuitDataById(k)
if suitCfgData and v > 0 then
local curAttrs = suitCfgData.Attribute[v]
if curAttrs then
for _,v in pairs(curAttrs) do
local str = string.split(v, '-')
local key = tonumber(str[1])
local val = tonumber(str[2])
if not self.data.suitAttrs[key] then
self.data.suitAttrs[key] = 0
end
val = key > 21 and CommonUtil.GetPreciseDecimal(val, 4) or math.floor(val)
self.data.suitAttrs[key] = self.data.suitAttrs[key] + val
end
end
end
end
end
function FashionData:FashionLvUpCanState(data)
data.canLvUp = false
local lvUpState = ManagerContainer.UIFuncUnlockMgr:GetFuncLockStatusById(68)
if not lvUpState then
return
end
local fashionCfgData = ManagerContainer.CfgMgr:GetFashionById(data.cfgId)
local lvCfgData = ManagerContainer.CfgMgr:GetFashionLvDataByLv(data.lv + 1)
if not lvCfgData then
data.canLvUp = false
return
end
local quality = fashionCfgData.FashionQuality
local costs = lvCfgData['UpMaterial'..quality]
for i = 1, 3 do
local cost = costs and costs[i] or nil
if cost then
local ownedCount = CommonUtil.GetOwnResCountByItemId(cost[1])
if ownedCount < cost[2] then
data.canLvUp = false
return
end
end
end
data.canLvUp = true
end
function FashionData:FashionLvUpOrNewClacAttrs(data, isNew)
if not self.data.fashionAttrs then return end
if not isNew and not next(data.oldAttrs) then return end
for _,v1 in pairs(data.oldAttrs) do
local jobType = v1.jobType + 1
local attrId = v1.attrId
local value = v1.value
if self.data.fashionAttrs[jobType] and self.data.fashionAttrs[jobType][attrId] then
value = attrId > 21 and CommonUtil.GetPreciseDecimal(value, 4) or math.floor(value)
self.data.fashionAttrs[jobType][attrId] = self.data.fashionAttrs[jobType][attrId] - value
end
end
for _,v1 in pairs(data.attrs) do
local jobType = v1.jobType + 1
local attrId = v1.attrId
local value = v1.value
if not self.data.fashionAttrs[jobType] then
self.data.fashionAttrs[jobType] = {}
end
if not self.data.fashionAttrs[jobType][attrId] then
self.data.fashionAttrs[jobType][attrId] = 0
end
value = attrId > 21 and CommonUtil.GetPreciseDecimal(value, 4) or math.floor(value)
self.data.fashionAttrs[jobType][attrId] = self.data.fashionAttrs[jobType][attrId] + value
end
if isNew or (next(data.oldAttrs) and not next(data.resetAttrs)) then
ManagerContainer.DataMgr.UserData:CalcFashionAttrs()
ManagerContainer.DataMgr.PartnerData:CalcAllPartnerFashionAttrs()
data.oldAttrs = {}
end
end
function FashionData:FashionSuitClacAttrs(suitId, lv, isLvUp, isNew)
if not isNew and not isLvUp then return end
if not self.data.suitAttrs then return end
local suitCfgData = ManagerContainer.CfgMgr:GetFashionSuitDataById(suitId)
if not suitCfgData then return end
if lv > 1 then
local lastLv = lv - 1
local lastAttrs = suitCfgData.Attribute[lastLv]
if lastAttrs then
for _,v in pairs(lastAttrs) do
local str = string.split(v, '-')
local key = tonumber(str[1])
local val = tonumber(str[2])
if self.data.suitAttrs[key] then
val = key > 21 and CommonUtil.GetPreciseDecimal(val, 4) or math.floor(val)
self.data.suitAttrs[key] = self.data.suitAttrs[key] - val
end
end
end
end
local curAttrs = suitCfgData.Attribute[lv]
if curAttrs then
for _,v in pairs(curAttrs) do
local str = string.split(v, '-')
local key = tonumber(str[1])
local val = tonumber(str[2])
if not self.data.suitAttrs[key] then
self.data.suitAttrs[key] = 0
end
val = key > 21 and CommonUtil.GetPreciseDecimal(val, 4) or math.floor(val)
self.data.suitAttrs[key] = self.data.suitAttrs[key] + val
end
end
ManagerContainer.DataMgr.UserData:CalcFashionAttrs()
--套装升级提示
ManagerContainer.LuaUIMgr:ErrorNoticeDisplayWithParam("SuitLevelUp", I18N.T(suitCfgData.SuitName), lv)
end
function FashionData:GetSuitLvByFashionLv(suitId, fashionLv)
local suitCfgData = ManagerContainer.CfgMgr:GetFashionSuitDataById(suitId)
if not suitCfgData then
return 0
end
local result, idx = CommonUtil.EleInTable(fashionLv, suitCfgData.LevelCondition)
return idx or 0
end
function FashionData:GetFashionAllAttrs()
return self.data.fashionAttrs
end
function FashionData:GetFashionAllAttrsByJobType(jobType)
return self.data.fashionAttrs and self.data.fashionAttrs[jobType + 1] or nil
end
function FashionData:GetFashionSuitLvById(suitId)
return self.data.fashionSuitMap[suitId] or 0
end
function FashionData:GetFashionSuitAttrs()
return self.data.suitAttrs
end
--- 获得已合成的时装列表
---@return table
function FashionData:GetFashionMap()
return self.data.fashionMap
end
--- 查询是否已获得该时装
function FashionData:Contains(cfgId)
return self.data.fashionMap[cfgId] ~= nil
end
function FashionData:GetFashionById(cfgId)
return self.data.fashionMap[cfgId]
end
function FashionData:IsNew(cfgId)
local fashionData = self.data.fashionMap[cfgId]
if fashionData then
if fashionData.isNew then
return true
end
end
return false
end
function FashionData:CanLvUp(cfgId)
local fashionData = self.data.fashionMap[cfgId]
if fashionData then
if fashionData.canLvUp then
return true
end
end
return false
end
function FashionData:CancelNewState(cfgId)
local fashionData = self.data.fashionMap[cfgId]
if fashionData then
if not fashionData.isNew then
return false
end
fashionData.isNew = false
self:WriteCacheFashionData()
ManagerContainer.RedPointMgr.HeroRPCtr:FashionDataNotify()
return true
end
return false
end
function FashionData:ReadCacheFashionData()
local cacheFashionDataStr = ManagerContainer.PlayerPrefsMgr:GetString(CACHE_FASHION_KEY_NAME, '')
local cacheFashionDatas = JSON:decode(cacheFashionDataStr)
local cacheFashionDataMap = {}
if cacheFashionDatas then
for key, value in pairs(cacheFashionDatas) do
cacheFashionDataMap[value] = true
end
end
return cacheFashionDataMap
end
function FashionData:WriteCacheFashionData()
local cacheFashionDatas = {}
if self.data.fashionMap then
for cfgId, fashionData in pairs(self.data.fashionMap) do
if fashionData.isNew then
table.insert(cacheFashionDatas, cfgId)
end
end
end
local valueStr = JSON:encode(cacheFashionDatas)
ManagerContainer.PlayerPrefsMgr:SetString(CACHE_FASHION_KEY_NAME, valueStr)
end
function FashionData:RefreshFashionData(fashionData)
if not fashionData then return end
local addFashionMap = {}
local downFashionList = {}
local upFashionList = {}
local addNum = 0
local cfgMgr = ManagerContainer.CfgMgr
for _,v in pairs(fashionData) do
local cfgId = v.fashion_id
local fashionCfgData = cfgMgr:GetFashionById(cfgId)
if not fashionCfgData then
LogError("[Wboy] .. ".. cfgId .. " 时装ID不存在")
elseif not fashionCfgData.FashionOpen then
LogError("[Wboy] 无力吐槽 不能获得的时装,策划竟然让玩家获得了 ".. cfgId)
else
local oldWearState
local data = self.data.fashionMap[cfgId]
local isNew = false
if not data then
isNew = true
data = {cfgId = cfgId, isNew = true, wear = false,lv=1}
addNum = addNum + 1
addFashionMap[cfgId] = 1
self.data.fashionMap[cfgId] = data
end
oldWearState = data.wear
local lvUpState = v.fashion_lvl > data.lv
data.lv = v.fashion_lvl
data.wear = v.fashion_wear
data.oldAttrs = {}
if (lvUpState or #v.resetAttrs == 0) and not isNew then
data.oldAttrs = clone(data.attrs)
end
data.attrs = {}
for _,v1 in pairs(v.attrs) do
data.attrs[#data.attrs + 1] = v1
end
data.resetAttrs = {}
for _,v1 in pairs(v.resetAttrs) do
data.resetAttrs[#data.resetAttrs + 1] = v1
end
if data.wear then
upFashionList[#upFashionList + 1] = cfgId
else
downFashionList[#downFashionList + 1] = cfgId
end
self:FashionLvUpOrNewClacAttrs(data, isNew)
--self:FashionLvUpCanState(data)
end
end
-- 新获得
if addNum > 0 then
self:WriteCacheFashionData()
ManagerContainer.RedPointMgr.HeroRPCtr:FashionDataNotify()
end
self:FashionDataNotify()
self:RefreshAllFashionLvUpNotify()
return addNum > 0, addFashionMap, upFashionList, downFashionList
end
function FashionData:SendFashionLvUp(fashionId)
ManagerContainer.NetManager:SendMessage(ProtoMsgId.CS_FASHION_UP_LVL_REQ, {fashion_cfg_id = fashionId})
end
function FashionData:SendFashionWash(fashionId, state)
if self.washState then
return
end
self.washState = true
ManagerContainer.NetManager:SendMessage(ProtoMsgId.CS_FASHION_RESET_ATTR_REQ, {enter = state, fashion_cfg_id = fashionId})
end
function FashionData:OnFashionLvUpAck(data)
if data.error ~= Enum.NetErrorCode.ERROR_OK then return end
ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.FASHION_LV_UP_CHANGE, true)
end
function FashionData:OnFashionWashAck(data)
if data.error ~= Enum.NetErrorCode.ERROR_OK then return end
self.washState = false
ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.FASHION_WASH_CHANGE)
end
function FashionData:OnFashionPagerDecomposeAck(data)
if data.error ~= Enum.NetErrorCode.ERROR_OK then return end
CommonUtil.ACKShowRewardList(data.item_list)
end
return FashionData