------------------------------------------------ --作者: 杨全福 --日期: 2021-02-23 --文件: AuctionHouseSystem.lua --模块: AuctionHouseSystem --描述: 拍卖行系统 ------------------------------------------------ local L_AuctionItem = require "Logic.AuctionHouse.AuctionItem" local L_ItemBase = CS.Thousandto.Code.Logic.ItemBase local AuctionHouseSystem = { --所有物品的容器 Items = Dictionary:New(), --用于查找的缓存列表 FindCacheList = List:New(), --是否已经载入了配置 IsLoadCareData = false, --关注的物品列表 CareItemList = {}, --关注的物品匹配值,用于计算是否属于关注的物品 CareItemMatchValues = {}, CareItemCount = 0, --推送关注间隔时间 CareIntervalTime = 60, --弹出关注信息的计时器 ShowCareTimer = 0, --缓存的展示关注界面的物品 ChcheCareItems = List:New(), ChcheCarePoss = List:New(), ShowCareFormTimer = 0, --已经弹出过关注提示的物品 NotShowCareItems = Dictionary:New(), --是否已经接受过数据 IsFirstResiveData = true, --是否显示真的物品给玩家购买 IsShowRealItems = true, FakeItem = nil, --是否有可上架红点 AuctionRedPoint = false, --当前自己上架的物品数量 SelfAuctionCount = 0, --配置的最大上架数量 MaxAuctionCount = 0, } --初始化 function AuctionHouseSystem:Initialize() self.IsLoadCareData = false local _gCfg = DataConfig.DataGlobal[GlobalName.Auction_ShowCare_IntervalTime] if _gCfg ~= nil then --推送间隔时间 self.CareIntervalTime = tonumber(_gCfg.Params) end _gCfg = DataConfig.DataGlobal[GlobalName.Trade_maxrecord] if _gCfg ~= nil then --最大上架数量 self.MaxAuctionCount = tonumber(_gCfg.Params) end end --反初始化 function AuctionHouseSystem:UnInitialize() for _, v in pairs(self.Items) do L_AuctionItem.Free(v, true) end self.Items:Clear() end --根据战力升序 local function L_SortByPowerUP(left, right) if left.EquipCfg ~= nil and right.EquipCfg ~= nil then return left.EquipCfg.Score < right.EquipCfg.Score else return right.CfgID < left.CfgID end end --根据战力降序 local function L_SortByPowerDown(left, right) if left.EquipCfg ~= nil and right.EquipCfg ~= nil then return right.EquipCfg.Score < left.EquipCfg.Score else return right.CfgID < left.CfgID end end --根据剩余时间升序 local function L_SortByTimeUP(left, right) return left:GetRemainTime() < right:GetRemainTime() end --根据剩余时间升序 local function L_SortByTimeDown(left, right) return right:GetRemainTime() < left:GetRemainTime() end --根据当前竞价升序 local function L_SortByCurPriceUP(left, right) local _lPrice = left.CurPrice if left.HasMiMa then _lPrice = 0 end local _rPrice = right.CurPrice if right.HasMiMa then _rPrice = 0 end return _lPrice < _rPrice end --根据当前竞价降序 local function L_SortByCurPriceDown(left, right) local _lPrice = left.CurPrice if left.HasMiMa then _lPrice = 0 end local _rPrice = right.CurPrice if right.HasMiMa then _rPrice = 0 end return _rPrice < _lPrice end --根据最大竞价升序 local function L_SortByMaxPriceUP(left, right) local _lPrice = left.MaxPrice if left.HasMiMa then _lPrice = left.CurPrice end local _rPrice = right.MaxPrice if right.HasMiMa then _rPrice = right.CurPrice end return _lPrice < _rPrice end --根据最大竞价降序 local function L_SortByMaxPriceDown(left, right) local _lPrice = left.MaxPrice if left.HasMiMa then _lPrice = left.CurPrice end local _rPrice = right.MaxPrice if right.HasMiMa then _rPrice = right.CurPrice end return _rPrice < _lPrice end --关闭字符串模式匹配,用于查找 local function CloseStringMatch(searchName) searchName = string.gsub(searchName, "%[", "%%[") searchName = string.gsub(searchName, "%]", "%%]") return searchName end --根据条件获取物品列表,列表类型tyoe:0世界,1公会; 排序类型sortType:0战力,1剩余时间,2当前价格,3最大价格 function AuctionHouseSystem:GetItemList(type, menuID, grade, star, quality, sortType, upSort, searchName) self.FindCacheList:Clear() if searchName ~= nil and string.len(searchName) > 0 then searchName = CloseStringMatch(searchName) end if not self.IsShowRealItems then if self.FakeItem == nil or self.FakeItem:GetRemainTime() <= 0 then local _itemId = 0 local _lp = GameCenter.GameSceneSystem:GetLocalPlayer() local _gCfg = DataConfig.DataGlobal[GlobalName.Trade_First_Buy_Item] if _gCfg ~= nil and _lp ~= nil then local _occ = _lp.IntOcc local _occParams = Utils.SplitStrByTableS(_gCfg.Params, {';', '_'}) for i = 1, #_occParams do if _occParams[i][1] == _occ then _itemId = _occParams[i][2] break end end end if self.FakeItem ~= nil then L_AuctionItem.Free(self.FakeItem) end self.FakeItem = L_AuctionItem.Get() local msgAuction = {} msgAuction.item = {} msgAuction.item.itemId = 0 msgAuction.item.itemModelId = _itemId msgAuction.item.num = 1 msgAuction.item.gridId = 0 msgAuction.item.isbind = false msgAuction.item.lostTime = 0 msgAuction.item.cdTime = 0 msgAuction.item.suitId = 0 msgAuction.item.strengLv = 0 msgAuction.isPassword = false msgAuction.guildId = 0 msgAuction.price = 0 msgAuction.ownId = 0 msgAuction.roleId = 0 msgAuction.id = 0 self.FakeItem:RefreshData(msgAuction) self.FakeItem:RefreshTempData() end if self.FakeItem ~= nil then self.FindCacheList:Add(self.FakeItem) end return self.FindCacheList end if type == 1 and not GameCenter.GuildSystem:HasJoinedGuild() then --没有加入公会获取公会拍卖列表为空 return self.FindCacheList; end local _findedCount = 0 local _guildID = 0 if GameCenter.GuildSystem:HasJoinedGuild() then _guildID = GameCenter.GuildSystem.GuildInfo.guildId end local _menuCfg = DataConfig.DataAuctionMenu[menuID] if _menuCfg ~= nil then local _partCount = 0 local _partList = {} local _partParams = Utils.SplitNumber(_menuCfg.EquipPart, '_') if _partParams ~= nil and #_partParams > 0 then for i = 1, #_partParams do _partList[_partParams[i]] = true _partCount = _partCount + 1 end end for _, ahItem in pairs(self.Items) do if type == 0 and ahItem.OwnerGuild > 0 then --选择世界拍卖时不展示公会商店的物品 elseif type == 1 and ahItem.OwnerGuild ~= _guildID then --选择公会拍卖时只展示自身公会的物品 elseif ahItem:GetRemainTime() <= 0 then --时间小于0的道具不展示 elseif (_menuCfg.EquipOrItem == 0 and ahItem.ItemInst.Type == ItemType.Equip) or (_menuCfg.EquipOrItem == 1 and (ahItem.ItemInst.Type ~= ItemType.Equip and ahItem.ItemInst.Type ~= ItemType.HolyEquip and ahItem.ItemInst.Type ~= ItemType.UnrealEquip)) or (_menuCfg.EquipOrItem == 2 and ahItem.ItemInst.Type == ItemType.HolyEquip) or (_menuCfg.EquipOrItem == 3 and ahItem.ItemInst.Type == ItemType.UnrealEquip) or _menuCfg.EquipOrItem < 0 then local _canAddItem = nil --物品 local _name = nil if ahItem.ItemCfg ~= nil and (_menuCfg.ItemTradeType < 0 or _menuCfg.ItemTradeType == ahItem.ItemCfg.TradeType) and (quality < 0 or ahItem.ItemCfg.Color >= quality) then _canAddItem = ahItem _name = ahItem.ItemCfg.Name end --装备 if ahItem.EquipCfg ~= nil and (_menuCfg.EquipOcc < 0 or string.find(ahItem.EquipCfg.Gender, tostring(_menuCfg.EquipOcc)) ~= nil) and (_partCount <= 0 or _partList[ahItem.EquipCfg.Part]) and (grade < 0 or ahItem.EquipCfg.Grade >= grade) and (star < 0 or ahItem.EquipCfg.DiamondNumber >= star) and (quality < 0 or ahItem.EquipCfg.Quality >= quality) then _canAddItem = ahItem _name = ahItem.EquipCfg.Name end if _canAddItem ~= nil then if searchName ~= nil and string.len(searchName) > 0 then if string.find(_name, searchName) then self.FindCacheList:Add(_canAddItem) _findedCount = _findedCount + 1 end else self.FindCacheList:Add(_canAddItem) _findedCount = _findedCount + 1 end end end end end if _findedCount > 1 then local _sortFunc = nil --进行排序 if sortType == 0 then if upSort then _sortFunc = L_SortByPowerUP else _sortFunc = L_SortByPowerDown end elseif sortType == 1 then if upSort then _sortFunc = L_SortByTimeUP else _sortFunc = L_SortByTimeDown end elseif sortType == 2 then if upSort then _sortFunc = L_SortByCurPriceUP else _sortFunc = L_SortByCurPriceDown end elseif sortType == 3 then if upSort then _sortFunc = L_SortByMaxPriceUP else _sortFunc = L_SortByMaxPriceDown end end if _sortFunc ~= nil then self.FindCacheList:Sort(_sortFunc) end end return self.FindCacheList end --获取自身拍卖的物品列表 function AuctionHouseSystem:GetSelBuyItemList(sortType, upSort) self.FindCacheList:Clear() local _findedCount = 0 for _, ahItem in pairs(self.Items) do if ahItem.IsSefJion and ahItem:GetRemainTime() > 0 then self.FindCacheList:Add(ahItem) _findedCount = _findedCount + 1 end end if _findedCount > 1 then local _sortFunc = nil --进行排序 if sortType == 0 then if upSort then _sortFunc = L_SortByPowerUP else _sortFunc = L_SortByPowerDown end elseif sortType == 1 then if upSort then _sortFunc = L_SortByTimeUP else _sortFunc = L_SortByTimeDown end elseif sortType == 2 then if upSort then _sortFunc = L_SortByCurPriceUP else _sortFunc = L_SortByCurPriceDown end elseif sortType == 3 then if upSort then _sortFunc = L_SortByMaxPriceUP else _sortFunc = L_SortByMaxPriceDown end end if _sortFunc ~= nil then self.FindCacheList:Sort(_sortFunc) end end return self.FindCacheList end --获取自己上架的道具 function AuctionHouseSystem:GetSelfSellItems() local _lpID = GameCenter.GameSceneSystem:GetLocalPlayerID() self.FindCacheList:Clear() for _, ahItem in pairs(self.Items) do if ahItem.OwnerID == _lpID and ahItem:GetRemainTime() > 0 then self.FindCacheList:Add(ahItem) end end return self.FindCacheList end --出售的物品排序 local function L_SoryItemBase(left, right) local _leftValue = left.CfgID if left.Type == ItemType.Equip or left.Type == ItemType.HolyEquip then if left:CheckCanEquip() then _leftValue = 2 else _leftValue = 1 end end local _rightValue = right.CfgID if right.Type == ItemType.Equip or right.Type == ItemType.HolyEquip then if right:CheckCanEquip() then _rightValue = 2 else _rightValue = 1 end end return _leftValue < _rightValue end --获取背包中可以出售的道具 function AuctionHouseSystem:GetCanSellItems(onlyQuick) self.FindCacheList:Clear() local _bagItemList = GameCenter.ItemContianerSystem:GetItemListByBind(ContainerType.ITEM_LOCATION_BAG, false) local _bagCount = _bagItemList.Count for i = 1, _bagCount do local _item = _bagItemList[i - 1] local _itemCfg = DataConfig.DataItem[_item.CfgID] if _itemCfg ~= nil and _itemCfg.AuctionMaxPrice ~= 0 then if onlyQuick then if _itemCfg.AuctionPriceType ~= 1 then self.FindCacheList:Add(_item) end else self.FindCacheList:Add(_item) end end local _equipCfg = DataConfig.DataEquip[_item.CfgID] if _equipCfg ~= nil and _equipCfg.AuctionMaxPrice ~= 0 then if onlyQuick then if _equipCfg.AuctionPriceType ~= 1 then self.FindCacheList:Add(_item) end else self.FindCacheList:Add(_item) end end end self.FindCacheList:Sort(L_SoryItemBase) return self.FindCacheList end --获取圣装中可以出售的道具 function AuctionHouseSystem:GetCanSellHolyEquips() self.FindCacheList:Clear() local _list = GameCenter.HolyEquipSystem.BagList local _count = #_list for i = 1, _count do local _holyEquip = _list[i] local _cfg = DataConfig.DataEquip[_holyEquip.CfgID] if _cfg ~= nil and not _holyEquip.IsBind and _cfg.AuctionMaxPrice ~= 0 then self.FindCacheList:Add(_holyEquip) end end self.FindCacheList:Sort(L_SoryItemBase) return self.FindCacheList end --获取幻装中可以出售的道具 function AuctionHouseSystem:GetCanSellUnrealEquips() self.FindCacheList:Clear() local _list = GameCenter.UnrealEquipSystem.BagList local _count = #_list for i = 1, _count do local _unrealEquip = _list[i] local _cfg = DataConfig.DataEquip[_unrealEquip.CfgID] if _cfg ~= nil and not _unrealEquip.IsBind and _cfg.AuctionMaxPrice ~= 0 then self.FindCacheList:Add(_unrealEquip) end end self.FindCacheList:Sort(L_SoryItemBase) return self.FindCacheList end --根据id获取单个商品 function AuctionHouseSystem:GetItemByID(id) local _item = self.Items[id] if _item ~= nil and _item:GetRemainTime() > 0 then return _item end return nil end --增加关注的物品 function AuctionHouseSystem:AddCareItem(itemID, itemOrEquip) if self.CareItemList[itemID] == nil then self.CareItemList[itemID] = true self:SaveCareData() end end --删除关注的物品 function AuctionHouseSystem:RemoveCareItem(itemID) if self.CareItemList[itemID] ~= nil then self.CareItemList[itemID] = nil self:SaveCareData() end end --进入场景 function AuctionHouseSystem:OnEnterScene() self:LoadCareData() --进入场景一秒后展示关注 self.ShowCareTimer = 1 self.IsFirstResiveData = true end --关注界面关闭 function AuctionHouseSystem:OnCareFormClose() if #self.ChcheCareItems > 0 then self.ShowCareFormTimer = 1 end end --更新 function AuctionHouseSystem:Update(deltaTime) if self.IsFirstResiveData or self.SelfAuctionCount > 0 or (self.IsLoadCareData and self.CareItemCount > 0) then --在有关注数据的情况下才执行请求 if self.ShowCareTimer > 0 then self.ShowCareTimer = self.ShowCareTimer - deltaTime if self.ShowCareTimer <= 0 then self:ReqItemList() self.IsFirstResiveData = false self.ShowCareTimer = -1 end end end local _cacheCount = #self.ChcheCareItems if _cacheCount > 0 then if self.ShowCareFormTimer > 0 then self.ShowCareFormTimer = self.ShowCareFormTimer - deltaTime if self.ShowCareFormTimer <= 0 then GameCenter.PushFixEvent(UIEventDefine.UIAuctionCareForm_Open, {self.ChcheCareItems[_cacheCount], self.ChcheCarePoss[_cacheCount]}) self.ChcheCareItems:RemoveAt(_cacheCount) self.ChcheCarePoss:RemoveAt(_cacheCount) self.ShowCareFormTimer = -1 end end end end --请求商品列表 function AuctionHouseSystem:ReqItemList() GameCenter.Network.Send("MSG_Auction.ReqAuctionInfoList", {}) end --物品列表 function AuctionHouseSystem:ResAuctionInfoList(result) for _, v in pairs(self.Items) do L_AuctionItem.Free(v) end self.Items:Clear() local _lpID = GameCenter.GameSceneSystem:GetLocalPlayerID() local _careItem = nil self.SelfAuctionCount = 0 local _msgCount = 0 if result.auctionInfoList ~= nil then _msgCount = #result.auctionInfoList end for i = 1, _msgCount do local _item = L_AuctionItem.Get() _item:RefreshData(result.auctionInfoList[i]) self.Items:Add(_item.ID, _item) --自身的物品和已经弹出过的不能关注 if _lpID ~= _item.OwnerID and self.NotShowCareItems[_item.ID] == nil then if _careItem == nil and self:IsCareItem(_item) then _careItem = _item end end if _lpID == _item.OwnerID then self.SelfAuctionCount = self.SelfAuctionCount + 1 end end if self.ShowCareTimer <= 0 then if self.CareItemCount > 0 then if self.NotShowCareItems:Count() >= 200 then self.NotShowCareItems:Clear() end self.ShowCareTimer = self.CareIntervalTime self.ChcheCareItems:Clear() self.ChcheCarePoss:Clear() if _careItem ~= nil then self.NotShowCareItems:Add(_careItem.ID, true) self.ChcheCareItems:Add(_careItem.ItemInst) if _careItem.OwnerGuild > 0 then self.ChcheCarePoss:Add(1) else self.ChcheCarePoss:Add(0) end end if #self.ChcheCareItems > 0 then self.ShowCareFormTimer = 1 end end end --检测上架红点 self.AuctionRedPoint = false if self.SelfAuctionCount < self.MaxAuctionCount then local _bagItemList = GameCenter.ItemContianerSystem:GetItemListByBind(ContainerType.ITEM_LOCATION_BAG, false) local _bagCount = _bagItemList.Count for i = 1, _bagCount do local _item = _bagItemList[i - 1] if _item:CanAuction() then --可以上架 self.AuctionRedPoint = true break end end end GameCenter.PushFixEvent(LogicLuaEventDefine.EID_EVENT_AUCTION_UPDATELIST) GameCenter.PushFixEvent(LogicLuaEventDefine.EID_EVENT_AUCTION_REDPOINT_UPDATED) end --上架成功,更新物品 function AuctionHouseSystem:ResAuctionInfoPutSuccess(result) self.SelfAuctionCount = self.SelfAuctionCount + 1 self:UpdateData(result.auctionInfo) GameCenter.PushFixEvent(LogicLuaEventDefine.EID_EVENT_AUCTION_UP_SUCC) end --下架返回 0:成功删除对象 1:失败更新对象 提示玩家已经在竞拍中 2:删除对象 提示物品不存在了 function AuctionHouseSystem:ResAuctionInfoOut(result) if result.res == 0 then --成功,删除对象 self:RemoveData(result.auctionInfo.id) Utils.ShowPromptByEnum("C_AUCTION_DOWN_SUCC") self.SelfAuctionCount = self.SelfAuctionCount - 1 if self.SelfAuctionCount < 0 then self.SelfAuctionCount = 0 end elseif result.res == 1 then --失败,更新对象 self:UpdateData(result.auctionInfo) Utils.ShowPromptByEnum("C_AUCTION_DOWNFIAL_JINGPAI") elseif result.res == 2 then self:UpdateData(result.auctionInfo) Utils.ShowPromptByEnum("C_AUCTION_DOWNFAIL_NOITEM") end GameCenter.PushFixEvent(LogicLuaEventDefine.EID_EVENT_AUCTION_DOWN_RESULT) end --一口价购买返回//0:成功 1:对象不存在 function AuctionHouseSystem:ResAuctionInfoPur(result) if result.res == 0 then Utils.ShowPromptByEnum("C_AUCTION_BUY_SUCC") elseif result.res == 1 then Utils.ShowPromptByEnum("C_AUCTION_BUYFAIL_NOITEM") end --删除对象 self:RemoveData(result.auctionId) GameCenter.PushFixEvent(LogicLuaEventDefine.EID_EVENT_AUCTION_BUY_RESULT, result.auctionId) end --竞价返回 0:成功更新对象 1:失败更新对象 提示价格已经变动 2:删除对象 提示物品不存在了,3:已经出价最高,不能继续出价 function AuctionHouseSystem:ResAuctionInfo(result) if result.res == 0 then Utils.ShowPromptByEnum("C_AUCTION_JINGJIA_SUCC") self:UpdateData(result.auctionInfo) elseif result.res == 1 then Utils.ShowPromptByEnum("C_AUCTION_JINGJIAFAIL_GENGGAO") self:UpdateData(result.auctionInfo) elseif result.res == 2 then Utils.ShowPromptByEnum("C_AUCTION_JINGJIAFAIL_NOITEM") self:RemoveData(result.auctionInfo.id) elseif result.res == 3 then Utils.ShowPromptByEnum("C_AUCTION_JINGJIAFAIL_ZUIGAO") self:UpdateData(result.auctionInfo) end GameCenter.PushFixEvent(LogicLuaEventDefine.EID_EVENT_AUCTION_JINGJIA_RESULT, result.auctionInfo.id) end --是否使用假拍卖行 function AuctionHouseSystem:ResAuctionPur(result) self.IsShowRealItems = result.isPur end --刷新数据 function AuctionHouseSystem:ResAuctionUpdate(result) self:UpdateData(result.auctionInfo); GameCenter.PushFixEvent(LogicLuaEventDefine.EID_EVENT_AUCTION_JINGJIA_RESULT, result.auctionInfo.id) end --删除物品 function AuctionHouseSystem:ResAuctionDelete(result) self:RemoveData(result.id) if result.ownId == GameCenter.GameSceneSystem:GetLocalPlayerID() then self.SelfAuctionCount = self.SelfAuctionCount - 1 if self.SelfAuctionCount < 0 then self.SelfAuctionCount = 0 end end GameCenter.PushFixEvent(LogicLuaEventDefine.EID_EVENT_AUCTION_BUY_RESULT, result.id) end --更新对象 function AuctionHouseSystem:UpdateData(info) local _item = self.Items[info.id] if _item ~= nil then _item:RefreshData(info) else _item = L_AuctionItem.Get() _item:RefreshData(info) self.Items:Add(info.id, _item) end end --删除对象 function AuctionHouseSystem:RemoveData(id) local _item = self.Items[id] if _item ~= nil then L_AuctionItem.Free(_item) self.Items:Remove(id) end end local function CovertCareMatchId(itemId) local _eqCfg = DataConfig.DataEquip[itemId] if _eqCfg ~= nil then local _occ = Utils.SplitNumber(_eqCfg.Gender, '_')[1] local _grade = _eqCfg.Grade local _part = _eqCfg.Part local _quality = _eqCfg.Quality return _occ * 1000000000 + _grade * 100000000 + _quality * 1000000 + _part * 10000 end return itemId end --是否是关注的材料 function AuctionHouseSystem:IsCareItem(item) if item.OwnerGuild > 0 then local _lp = GameCenter.GameSceneSystem:GetLocalPlayer() if _lp == nil then return false end if _lp.GuildID ~= item.OwnerGuild then return false end end return self.CareItemMatchValues[CovertCareMatchId(item.CfgID)] ~= nil end --读取关注配置 function AuctionHouseSystem:LoadCareData() if self.IsLoadCareData then return end local _lp = GameCenter.GameSceneSystem:GetLocalPlayer() if _lp == nil then return end self.IsLoadCareData = true local _param = PlayerPrefs.GetString(string.format("NewAuctionCareData2_%d", _lp.ID), "") if _param == nil or string.len(_param) <= 0 then return end local _numberTable = Utils.SplitNumber(_param, ';') self.CareItemList = {} self.CareItemMatchValues = {} for i = 1, #_numberTable do local _itemId = _numberTable[i] self.CareItemList[_itemId] = true self.CareItemMatchValues[CovertCareMatchId(_itemId)] = true end self.CareItemCount = #_numberTable end --保存关注配置 function AuctionHouseSystem:SaveCareData() local _lp = GameCenter.GameSceneSystem:GetLocalPlayer() if _lp == nil then return end self.CareItemMatchValues = {} local _saveText = "" local _count = 0 for k, _ in pairs(self.CareItemList) do _saveText = _saveText .. k ..';' _count = _count + 1 self.CareItemMatchValues[CovertCareMatchId(k)] = true end self.CareItemCount = _count PlayerPrefs.SetString(string.format("NewAuctionCareData2_%d", _lp.ID), _saveText) end return AuctionHouseSystem