FashionData.lua 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. local FashionData = class("FashionData", require("DataBase"))
  2. local JSON = require('json')
  3. local CACHE_FASHION_KEY_NAME = "Cache_Fashion_Key"
  4. function FashionData:ctor()
  5. self.data = {}
  6. self.data.fashionMap = {}
  7. self.data.fashionSuitMap = {}
  8. end
  9. function FashionData:RegisterNetEvents()
  10. ManagerContainer.NetManager:NetRegister(ProtoMsgId.SC_FASHION_NTF, function(data)
  11. if ManagerContainer.NetManager:IsErrorData(data) then
  12. return
  13. end
  14. if data.lvs then
  15. for _,v in pairs(data.lvs) do
  16. local lv = self:GetSuitLvByFashionLv(v.key, v.value)
  17. local lvUp = false
  18. local oldLv = self.data.fashionSuitMap[v.key]
  19. local isNew = oldLv == nil
  20. if oldLv then
  21. lvUp = lv > oldLv
  22. end
  23. self.data.fashionSuitMap[v.key] = lv
  24. self:FashionSuitClacAttrs(v.key, lv, lvUp, isNew)
  25. end
  26. end
  27. local changed, addFashionMap, upFashionList, downFashionList = self:RefreshFashionData(data.fashion_data)
  28. if changed then
  29. ManagerContainer.DataMgr.UserData:CalcFashionAttrs()
  30. ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.FASHION_LIST_CHANGE)
  31. ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.EID_FASHION_ADD, addFashionMap)
  32. else
  33. -- upFashionList 表示新穿的时装
  34. -- 需要跟原来身上的时装进行比较
  35. local viewChanged = false
  36. local viewData = ManagerContainer.DataMgr.UserData:GetViewData()
  37. local totalUpFashionList = {}
  38. if viewData and viewData.fashionData then
  39. for _,v in pairs(viewData.fashionData) do
  40. totalUpFashionList[#totalUpFashionList + 1] = v
  41. end
  42. end
  43. if upFashionList then
  44. for _,v in pairs(upFashionList) do
  45. local result, idx = CommonUtil.EleInTable(v, totalUpFashionList)
  46. if not result then
  47. totalUpFashionList[#totalUpFashionList + 1] = v
  48. viewChanged = true
  49. end
  50. end
  51. end
  52. if downFashionList then
  53. for _,v in pairs(downFashionList) do
  54. local result, idx = CommonUtil.EleInTable(v, totalUpFashionList)
  55. if result then
  56. table.remove(totalUpFashionList, idx)
  57. viewChanged = true
  58. end
  59. end
  60. end
  61. if viewChanged then
  62. ManagerContainer.DataMgr.UserData:UpdateFashionUpData(totalUpFashionList)
  63. ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.FASHION_WEAR_CHANGE)
  64. end
  65. end
  66. end)
  67. ManagerContainer.NetManager:NetRegister(ProtoMsgId.SC_FASHION_UP_LVL_ACK,self.OnFashionLvUpAck, self)
  68. ManagerContainer.NetManager:NetRegister(ProtoMsgId.SC_FASHION_RESET_ATTR_ACK,self.OnFashionWashAck, self)
  69. ManagerContainer.NetManager:NetRegister(ProtoMsgId.SC_FASHION_PAPER_DECOMPOSE_ACK,self.OnFashionPagerDecomposeAck, self)
  70. end
  71. function FashionData:Clear()
  72. self.data = {}
  73. self.data.fashionMap = {}
  74. self.data.fashionSuitMap = {}
  75. end
  76. function FashionData:Destroy()
  77. if self.Clear then
  78. self:Clear()
  79. end
  80. self:UnRegisterNetEvents()
  81. end
  82. function FashionData:UnRegisterNetEvents()
  83. end
  84. function FashionData:InitFashionData(roleFashion)
  85. if not roleFashion or not roleFashion.fashion_data then return end
  86. self.washState = false
  87. local userSex = ManagerContainer.DataMgr.UserData:GetSex()
  88. local cacheFashionData = self:ReadCacheFashionData()
  89. local fashionData = roleFashion.fashion_data
  90. local cfgMgr = ManagerContainer.CfgMgr
  91. for _,v in pairs(fashionData) do
  92. local cfgId = v.fashion_id
  93. local fashionCfgData = cfgMgr:GetFashionById(cfgId)
  94. if not fashionCfgData then
  95. LogError("[Wboy] .. ".. cfgId .. " 时装ID不存在")
  96. elseif not fashionCfgData.FashionOpen then
  97. LogError("[Wboy] 无力吐槽 不能获得的时装,策划竟然让玩家获得了 ".. cfgId)
  98. elseif fashionCfgData.FashionSex > 0 and fashionCfgData.FashionSex ~= userSex then
  99. LogError("[Wboy] 无力吐槽 不能获得异性的时装,策划竟然让玩家获得了 ".. cfgId)
  100. else
  101. local isNew
  102. if cacheFashionData then
  103. isNew = cacheFashionData[cfgId]
  104. if isNew == nil then
  105. isNew = false
  106. end
  107. else
  108. isNew = false
  109. end
  110. local data = self.data.fashionMap[cfgId]
  111. if not data then
  112. data = {cfgId = cfgId}
  113. self.data.fashionMap[cfgId] = data
  114. end
  115. data.isNew = isNew
  116. data.lv = v.fashion_lvl
  117. data.wear = v.fashion_wear
  118. data.oldAttrs = {}
  119. data.attrs = {}
  120. for _,v1 in pairs(v.attrs) do
  121. data.attrs[#data.attrs + 1] = v1
  122. end
  123. data.resetAttrs = {}
  124. for _,v1 in pairs(v.resetAttrs) do
  125. data.resetAttrs[#data.resetAttrs + 1] = v1
  126. end
  127. self:FashionLvUpCanState(data)
  128. end
  129. end
  130. if roleFashion.lvs then
  131. for _,v in pairs(roleFashion.lvs) do
  132. local lv = self:GetSuitLvByFashionLv(v.key, v.value)
  133. self.data.fashionSuitMap[v.key] = lv
  134. end
  135. end
  136. self:ClacFashionAttrs()
  137. self:FashionDataNotify()
  138. end
  139. function FashionData:FashionDataNotify()
  140. local result = false
  141. for _,v in pairs(self.data.fashionMap) do
  142. if v.canLvUp then
  143. result = true
  144. end
  145. end
  146. ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.RED_POINT_MGR_NOTICE, Enum.RPNotifyType.FashionLvUp, result)
  147. end
  148. function FashionData:RefreshAllFashionLvUpNotify()
  149. local result = false
  150. for _,v in pairs(self.data.fashionMap) do
  151. self:FashionLvUpCanState(v)
  152. if v.canLvUp then
  153. result = true
  154. end
  155. end
  156. ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.RED_POINT_MGR_NOTICE, Enum.RPNotifyType.FashionLvUp, result)
  157. end
  158. function FashionData:ClacFashionAttrs()
  159. self.data.fashionAttrs = {}
  160. for k,v in pairs(self.data.fashionMap) do
  161. for _,v1 in pairs(v.attrs) do
  162. local jobType = v1.jobType + 1
  163. local attrId = v1.attrId
  164. local value = v1.value
  165. if not self.data.fashionAttrs[jobType] then
  166. self.data.fashionAttrs[jobType] = {}
  167. end
  168. if not self.data.fashionAttrs[jobType][attrId] then
  169. self.data.fashionAttrs[jobType][attrId] = 0
  170. end
  171. value = attrId > 21 and CommonUtil.GetPreciseDecimal(value, 4) or math.floor(value)
  172. self.data.fashionAttrs[jobType][attrId] = self.data.fashionAttrs[jobType][attrId] + value
  173. end
  174. end
  175. self.data.suitAttrs = {}
  176. for k,v in pairs(self.data.fashionSuitMap) do
  177. local suitCfgData = ManagerContainer.CfgMgr:GetFashionSuitDataById(k)
  178. if suitCfgData and v > 0 then
  179. local curAttrs = suitCfgData.Attribute[v]
  180. if curAttrs then
  181. for _,v in pairs(curAttrs) do
  182. local str = string.split(v, '-')
  183. local key = tonumber(str[1])
  184. local val = tonumber(str[2])
  185. if not self.data.suitAttrs[key] then
  186. self.data.suitAttrs[key] = 0
  187. end
  188. val = key > 21 and CommonUtil.GetPreciseDecimal(val, 4) or math.floor(val)
  189. self.data.suitAttrs[key] = self.data.suitAttrs[key] + val
  190. end
  191. end
  192. end
  193. end
  194. end
  195. function FashionData:FashionLvUpCanState(data)
  196. data.canLvUp = false
  197. local lvUpState = ManagerContainer.UIFuncUnlockMgr:GetFuncLockStatusById(68)
  198. if not lvUpState then
  199. return
  200. end
  201. local fashionCfgData = ManagerContainer.CfgMgr:GetFashionById(data.cfgId)
  202. local lvCfgData = ManagerContainer.CfgMgr:GetFashionLvDataByLv(data.lv + 1)
  203. if not lvCfgData then
  204. data.canLvUp = false
  205. return
  206. end
  207. local quality = fashionCfgData.FashionQuality
  208. local costs = lvCfgData['UpMaterial'..quality]
  209. for i = 1, 3 do
  210. local cost = costs and costs[i] or nil
  211. if cost then
  212. local ownedCount = CommonUtil.GetOwnResCountByItemId(cost[1])
  213. if ownedCount < cost[2] then
  214. data.canLvUp = false
  215. return
  216. end
  217. end
  218. end
  219. data.canLvUp = true
  220. end
  221. function FashionData:FashionLvUpOrNewClacAttrs(data, isNew)
  222. if not self.data.fashionAttrs then return end
  223. if not isNew and not next(data.oldAttrs) then return end
  224. for _,v1 in pairs(data.oldAttrs) do
  225. local jobType = v1.jobType + 1
  226. local attrId = v1.attrId
  227. local value = v1.value
  228. if self.data.fashionAttrs[jobType] and self.data.fashionAttrs[jobType][attrId] then
  229. value = attrId > 21 and CommonUtil.GetPreciseDecimal(value, 4) or math.floor(value)
  230. self.data.fashionAttrs[jobType][attrId] = self.data.fashionAttrs[jobType][attrId] - value
  231. end
  232. end
  233. for _,v1 in pairs(data.attrs) do
  234. local jobType = v1.jobType + 1
  235. local attrId = v1.attrId
  236. local value = v1.value
  237. if not self.data.fashionAttrs[jobType] then
  238. self.data.fashionAttrs[jobType] = {}
  239. end
  240. if not self.data.fashionAttrs[jobType][attrId] then
  241. self.data.fashionAttrs[jobType][attrId] = 0
  242. end
  243. value = attrId > 21 and CommonUtil.GetPreciseDecimal(value, 4) or math.floor(value)
  244. self.data.fashionAttrs[jobType][attrId] = self.data.fashionAttrs[jobType][attrId] + value
  245. end
  246. if isNew or (next(data.oldAttrs) and not next(data.resetAttrs)) then
  247. ManagerContainer.DataMgr.UserData:CalcFashionAttrs()
  248. ManagerContainer.DataMgr.PartnerData:CalcAllPartnerFashionAttrs()
  249. data.oldAttrs = {}
  250. end
  251. end
  252. function FashionData:FashionSuitClacAttrs(suitId, lv, isLvUp, isNew)
  253. if not isNew and not isLvUp then return end
  254. if not self.data.suitAttrs then return end
  255. local suitCfgData = ManagerContainer.CfgMgr:GetFashionSuitDataById(suitId)
  256. if not suitCfgData then return end
  257. if lv > 1 then
  258. local lastLv = lv - 1
  259. local lastAttrs = suitCfgData.Attribute[lastLv]
  260. if lastAttrs then
  261. for _,v in pairs(lastAttrs) do
  262. local str = string.split(v, '-')
  263. local key = tonumber(str[1])
  264. local val = tonumber(str[2])
  265. if self.data.suitAttrs[key] then
  266. val = key > 21 and CommonUtil.GetPreciseDecimal(val, 4) or math.floor(val)
  267. self.data.suitAttrs[key] = self.data.suitAttrs[key] - val
  268. end
  269. end
  270. end
  271. end
  272. local curAttrs = suitCfgData.Attribute[lv]
  273. if curAttrs then
  274. for _,v in pairs(curAttrs) do
  275. local str = string.split(v, '-')
  276. local key = tonumber(str[1])
  277. local val = tonumber(str[2])
  278. if not self.data.suitAttrs[key] then
  279. self.data.suitAttrs[key] = 0
  280. end
  281. val = key > 21 and CommonUtil.GetPreciseDecimal(val, 4) or math.floor(val)
  282. self.data.suitAttrs[key] = self.data.suitAttrs[key] + val
  283. end
  284. end
  285. ManagerContainer.DataMgr.UserData:CalcFashionAttrs()
  286. --套装升级提示
  287. ManagerContainer.LuaUIMgr:ErrorNoticeDisplayWithParam("SuitLevelUp", I18N.T(suitCfgData.SuitName), lv)
  288. end
  289. function FashionData:GetSuitLvByFashionLv(suitId, fashionLv)
  290. local suitCfgData = ManagerContainer.CfgMgr:GetFashionSuitDataById(suitId)
  291. if not suitCfgData then
  292. return 0
  293. end
  294. local result, idx = CommonUtil.EleInTable(fashionLv, suitCfgData.LevelCondition)
  295. return idx or 0
  296. end
  297. function FashionData:GetFashionAllAttrs()
  298. return self.data.fashionAttrs
  299. end
  300. function FashionData:GetFashionAllAttrsByJobType(jobType)
  301. return self.data.fashionAttrs and self.data.fashionAttrs[jobType + 1] or nil
  302. end
  303. function FashionData:GetFashionSuitLvById(suitId)
  304. return self.data.fashionSuitMap[suitId] or 0
  305. end
  306. function FashionData:GetFashionSuitAttrs()
  307. return self.data.suitAttrs
  308. end
  309. --- 获得已合成的时装列表
  310. ---@return table
  311. function FashionData:GetFashionMap()
  312. return self.data.fashionMap
  313. end
  314. --- 查询是否已获得该时装
  315. function FashionData:Contains(cfgId)
  316. return self.data.fashionMap[cfgId] ~= nil
  317. end
  318. function FashionData:GetFashionById(cfgId)
  319. return self.data.fashionMap[cfgId]
  320. end
  321. function FashionData:IsNew(cfgId)
  322. local fashionData = self.data.fashionMap[cfgId]
  323. if fashionData then
  324. if fashionData.isNew then
  325. return true
  326. end
  327. end
  328. return false
  329. end
  330. function FashionData:CanLvUp(cfgId)
  331. local fashionData = self.data.fashionMap[cfgId]
  332. if fashionData then
  333. if fashionData.canLvUp then
  334. return true
  335. end
  336. end
  337. return false
  338. end
  339. function FashionData:CancelNewState(cfgId)
  340. local fashionData = self.data.fashionMap[cfgId]
  341. if fashionData then
  342. if not fashionData.isNew then
  343. return false
  344. end
  345. fashionData.isNew = false
  346. self:WriteCacheFashionData()
  347. ManagerContainer.RedPointMgr.HeroRPCtr:FashionDataNotify()
  348. return true
  349. end
  350. return false
  351. end
  352. function FashionData:ReadCacheFashionData()
  353. local cacheFashionDataStr = ManagerContainer.PlayerPrefsMgr:GetString(CACHE_FASHION_KEY_NAME, '')
  354. local cacheFashionDatas = JSON:decode(cacheFashionDataStr)
  355. local cacheFashionDataMap = {}
  356. if cacheFashionDatas then
  357. for key, value in pairs(cacheFashionDatas) do
  358. cacheFashionDataMap[value] = true
  359. end
  360. end
  361. return cacheFashionDataMap
  362. end
  363. function FashionData:WriteCacheFashionData()
  364. local cacheFashionDatas = {}
  365. if self.data.fashionMap then
  366. for cfgId, fashionData in pairs(self.data.fashionMap) do
  367. if fashionData.isNew then
  368. table.insert(cacheFashionDatas, cfgId)
  369. end
  370. end
  371. end
  372. local valueStr = JSON:encode(cacheFashionDatas)
  373. ManagerContainer.PlayerPrefsMgr:SetString(CACHE_FASHION_KEY_NAME, valueStr)
  374. end
  375. function FashionData:RefreshFashionData(fashionData)
  376. if not fashionData then return end
  377. local addFashionMap = {}
  378. local downFashionList = {}
  379. local upFashionList = {}
  380. local addNum = 0
  381. local cfgMgr = ManagerContainer.CfgMgr
  382. for _,v in pairs(fashionData) do
  383. local cfgId = v.fashion_id
  384. local fashionCfgData = cfgMgr:GetFashionById(cfgId)
  385. if not fashionCfgData then
  386. LogError("[Wboy] .. ".. cfgId .. " 时装ID不存在")
  387. elseif not fashionCfgData.FashionOpen then
  388. LogError("[Wboy] 无力吐槽 不能获得的时装,策划竟然让玩家获得了 ".. cfgId)
  389. else
  390. local oldWearState
  391. local data = self.data.fashionMap[cfgId]
  392. local isNew = false
  393. if not data then
  394. isNew = true
  395. data = {cfgId = cfgId, isNew = true, wear = false,lv=1}
  396. addNum = addNum + 1
  397. addFashionMap[cfgId] = 1
  398. self.data.fashionMap[cfgId] = data
  399. end
  400. oldWearState = data.wear
  401. local lvUpState = v.fashion_lvl > data.lv
  402. data.lv = v.fashion_lvl
  403. data.wear = v.fashion_wear
  404. data.oldAttrs = {}
  405. if (lvUpState or #v.resetAttrs == 0) and not isNew then
  406. data.oldAttrs = clone(data.attrs)
  407. end
  408. data.attrs = {}
  409. for _,v1 in pairs(v.attrs) do
  410. data.attrs[#data.attrs + 1] = v1
  411. end
  412. data.resetAttrs = {}
  413. for _,v1 in pairs(v.resetAttrs) do
  414. data.resetAttrs[#data.resetAttrs + 1] = v1
  415. end
  416. if data.wear then
  417. upFashionList[#upFashionList + 1] = cfgId
  418. else
  419. downFashionList[#downFashionList + 1] = cfgId
  420. end
  421. self:FashionLvUpOrNewClacAttrs(data, isNew)
  422. --self:FashionLvUpCanState(data)
  423. end
  424. end
  425. -- 新获得
  426. if addNum > 0 then
  427. self:WriteCacheFashionData()
  428. ManagerContainer.RedPointMgr.HeroRPCtr:FashionDataNotify()
  429. end
  430. self:FashionDataNotify()
  431. self:RefreshAllFashionLvUpNotify()
  432. return addNum > 0, addFashionMap, upFashionList, downFashionList
  433. end
  434. function FashionData:SendFashionLvUp(fashionId)
  435. ManagerContainer.NetManager:SendMessage(ProtoMsgId.CS_FASHION_UP_LVL_REQ, {fashion_cfg_id = fashionId})
  436. end
  437. function FashionData:SendFashionWash(fashionId, state)
  438. if self.washState then
  439. return
  440. end
  441. self.washState = true
  442. ManagerContainer.NetManager:SendMessage(ProtoMsgId.CS_FASHION_RESET_ATTR_REQ, {enter = state, fashion_cfg_id = fashionId})
  443. end
  444. function FashionData:OnFashionLvUpAck(data)
  445. if data.error ~= Enum.NetErrorCode.ERROR_OK then return end
  446. ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.FASHION_LV_UP_CHANGE, true)
  447. end
  448. function FashionData:OnFashionWashAck(data)
  449. if data.error ~= Enum.NetErrorCode.ERROR_OK then return end
  450. self.washState = false
  451. ManagerContainer.LuaEventMgr:Dispatch(UIEventNames.FASHION_WASH_CHANGE)
  452. end
  453. function FashionData:OnFashionPagerDecomposeAck(data)
  454. if data.error ~= Enum.NetErrorCode.ERROR_OK then return end
  455. CommonUtil.ACKShowRewardList(data.item_list)
  456. end
  457. return FashionData