HomeServer/Server/AllServer/GameServer/Bag.lua
2024-11-20 15:41:37 +08:00

671 lines
26 KiB
Lua

local skynet = require "skynet"
local oo = require "Class"
local log = require "Log"
local pb = require "pb"
local dataType = require "DataType"
local errorInfo = require "ErrorInfo"
local Bag = oo.class()
Bag.SortType_New = 1 --最新
Bag.SortType_Rarity = 2 --稀有度
Bag.SortType_Default = 3 --默认
Bag.SortType_FuncOrder = 4 --功能顺序
--local dobuleFure = {}
function Bag:Init()
end
--商店排序
function Bag:Sort( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SBagSort", c2sData.data ))
local data = {}
local sortType = c2sData.data.sortType
if not sortType then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
if sortType < self.SortType_New or sortType > self.SortType_FuncOrder then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
player.gameData.curBagSort = sortType
data.sortType = sortType
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_BagSort")
s2cData.data = assert(pb.encode("S2CBagSort", data))
end
--背包展示
function Bag:Show( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SBagShow", c2sData.data ))
local data = {}
data.bagInfo = {}
local goodsType = c2sData.data.goodsType
if not goodsType then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
data.sortType = player.gameData.curBagSort
for k1, v1 in pairs( goodsType ) do
if v1 >= dataType.GoodsType_Furniture and v1 < dataType.GoodsType_End then
if v1 == dataType.GoodsType_Prop then
skynet.server.msgTips:ReduceAll(player , 35)
elseif v1 == dataType.GoodsType_Seed or v1 == dataType.GoodsType_Plant or v1 == dataType.GoodsType_Fish or
v1 == dataType.GoodsType_CuisineMenu or v1 == dataType.GoodsType_CuisineMaterial or v1 == dataType.GoodsType_Coffee then
skynet.server.msgTips:ReduceAll(player , 36)
end
local bagInfo = {}
bagInfo.goodsType = v1 --商品类型
bagInfo.goodsInfo = {} --商品信息
for k2, v2 in pairs( player.gameData.bag ) do
if v1 == v2.type then
table.insert( bagInfo.goodsInfo , { type = v2.type , id = v2.id , count = v2.count , gainTime = v2.gainTime , isNew = v2.isNew })
v2.isNew = false
end
end
table.insert( data.bagInfo , bagInfo )
end
end
--[[
--商品信息
data.goodsType = goodsType
--排序类型
data.sortType = player.gameData.curBagSort
--根据商品类型来取数据
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type then
table.insert( data.goodsInfo , { type = v.type , id = v.id , count = v.count , gainTime = v.gainTime })
end
end
]]
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_BagShow")
s2cData.data = assert(pb.encode("S2CBagShow", data))
end
--背包点击
function Bag:Click( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SBagClick", c2sData.data ))
local data = {}
local goodsType = c2sData.data.goodsType
local goodsId = c2sData.data.goodsId
if not goodsType or not goodsId or goodsType < dataType.GoodsType_Furniture or goodsType >= dataType.GoodsType_End then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
data.goodsType = goodsType
data.goodsId = goodsId
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type and goodsId == v.id then
v.isNew = false
break
end
end
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_BagClick")
s2cData.data = assert(pb.encode("S2CBagClick", data))
end
--背包更新
function Bag:Update( player , type , id , count )
local data = {}
data.goodsInfo = {}
for k, v in pairs( player.gameData.bag ) do
if type == v.type and id == v.id then
local lastCount = v.count + count
table.insert( data.goodsInfo , { type = v.type , id = v.id , count = lastCount > 0 and lastCount or 0 , gainTime = v.gainTime , isNew = v.isNew })
break
end
end
skynet.server.gameServer:SendMsgToUser( player.userId , "CMD_S2C_BagUpdate" , data )
end
--获取新的家具索引
function Bag:GetUniqueID( player )
player.gameData.curUniqueID = player.gameData.curUniqueID + 1
if player.gameData.curUniqueID >= 1000000000 then --大于10亿就置1
player.gameData.curUniqueID = 1
end
return player.gameData.curUniqueID
end
--添加物品
function Bag:AddGoods( player , goodsType , goodsId , count )
--检查各参数
if not player or not goodsType or not goodsId or not count or goodsId <= 0 then
log.warning("无法添加物品到背包,请求参数错误", player,goodsType , goodsId , count)
return false
end
--检查物品的合法性
if not self:IsValidGoodsType( goodsType ) then
log.warning("无法添加物品到背包,商品类型错误", goodsType)
return false
end
local data = {}
data.goodsInfo = {}
local userId = player.basicInfo.userID
local gainTime = skynet.GetTime()
local goodInfo = {}
local lastCount = 0 --最新数量
if player:IsBuyGoods( goodsType , goodsId ) then
--存在家具
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type and goodsId == v.id then
v.count = v.count + count
v.gainTime = gainTime
goodInfo = { type = v.type , id = v.id , count = v.count , gainTime = v.gainTime , isNew = false}
break
end
end
else
--不存在家具
goodInfo = { type = goodsType , id = goodsId , count = count , gainTime = gainTime , isNew = true}
table.insert( player.gameData.bag , goodInfo )
if goodsType == dataType.GoodsType_Prop then
skynet.server.msgTips:Add(player , 35)
elseif goodsType == dataType.GoodsType_Seed or goodsType == dataType.GoodsType_Plant or goodsType == dataType.GoodsType_Fish or goodsType == dataType.GoodsType_CuisineMenu or goodsType == dataType.GoodsType_CuisineMaterial or goodsType == dataType.GoodsType_Coffee then
skynet.server.msgTips:Add(player , 36)
end
end
self:AddGoodsStat( player , goodsType , goodsId , count )
skynet.server.illustration:Add( player , goodsType , goodsId )
skynet.server.playerRecord:Add( userId , dataType.RecordType_100 , 0 , goodInfo.type , goodInfo.id , goodInfo.count )
if dataType.GoodsType_Furniture == goodsType then --家具
player:AddOneUnUsedGoods( goodsType , goodsId , count )
--染色的家具id进行还原
if goodsId > 100000 then
goodsId = goodsId % 100000
end
local cfgFurniture = skynet.server.gameConfig:GetPlayerCurCfg( player , "Furniture" , goodsId )
local quality = cfgFurniture.quality
--不凡品种特殊处理(之前的规则无法兼容)
if quality==4 then
quality=18
end
player:AddExpForType( 1 , quality , count )
--检查下在图鉴里是不是套间
if skynet.server.illustration:IsSuit( player , skynet.server.illustration.IllustrationType_Furniture , cfgFurniture.suitType ) then
skynet.server.npcTask:Modify( player , 106 , 1 )
skynet.server.taskListEvent:Modify( player , 106 , 1 )
end
if dataType.FurnitureQuality_Special == cfgFurniture.quality then
skynet.server.levelTask:Modify( player , 71 , 1)
skynet.server.taskListEvent:Modify( player , 71 , 1)
elseif dataType.FurnitureQuality_Rare == cfgFurniture.quality then
--skynet.server.achieveTask:Modify( player , 60 , 1) --获取罕见家具
skynet.server.levelTask:Modify( player , 68 , 1)
skynet.server.taskListEvent:Modify( player ,68, 1)
end
elseif dataType.GoodsType_Decorate == goodsType then --装修
local cfgDecoration = skynet.server.gameConfig:GetPlayerCurCfg( player , "Decoration" , goodsId )
--检查下在图鉴里是不是套间
if skynet.server.illustration:IsSuit( player , skynet.server.illustration.IllustrationType_Furniture , cfgDecoration.suitType ) then
skynet.server.npcTask:Modify( player , 106 , 1 )
skynet.server.taskListEvent:Modify( player , 106 , 1 )
end
local quality = cfgDecoration.quality
--不凡品种特殊处理(之前的规则无法兼容)
if quality==4 then
quality=18
end
player:AddExpForType( 1 , quality , count )
elseif dataType.GoodsType_Flowerpot == goodsType then --花盆
skynet.server.levelTask:Modify( player , 67 , 1)
skynet.server.taskListEvent:Modify( player , 67 , 1)
elseif dataType.GoodsType_Plant == goodsType then --植物
local cfgPlant = skynet.server.gameConfig:GetPlayerCurCfg( player , "Plant" , goodsId )
--player:AddExpForType( 5 , cfgPlant.quality , count )
if dataType.PlantType_AquaticPlant == cfgPlant.type then
skynet.server.levelTask:Modify( player , 83 , 1 )
skynet.server.taskListEvent:Modify( player , 83 , 1 )
end
elseif dataType.GoodsType_Clothes == goodsType then --人物衣服
local cfgClothes = skynet.server.gameConfig:GetPlayerCurCfg( player , "Clothes" , goodsId )
if cfgClothes and 1 == cfgClothes.shopType and ( cfgClothes.type == dataType.ClothesType_HeadWear or cfgClothes.type == dataType.ClothesType_Clothes
or cfgClothes.type == dataType.ClothesType_Trousers or cfgClothes.type == dataType.ClothesType_Shoes ) then
local passCheck = player.gameData.passCheck
passCheck.clothesBuyCount = passCheck.clothesBuyCount + 1
end
local quality = cfgClothes.quality
--不凡品种特殊处理(之前的规则无法兼容)
if quality==4 then
quality=18
end
player:AddExpForType( 7 , quality , count )
local clothesType = cfgClothes.type
--头型,眼型,发型
--if dataType.ClothesType_Head == clothesType or dataType.ClothesType_Eyes == clothesType or dataType.ClothesType_Hair == clothesType then
skynet.server.achieveTask:Modify( player , 59 , 1)
skynet.server.taskListEvent:Modify( player , 59 , 1)
if dataType.ClothesType_Clothes == clothesType or dataType.ClothesType_Trousers == clothesType or
dataType.ClothesType_Suit == clothesType or dataType.ClothesType_Shoes == clothesType then
skynet.server.levelTask:Modify( player , 14 , 1)
skynet.server.taskListEvent:Modify( player , 14 , 1)
end
elseif dataType.GoodsType_PetClothes == goodsType then --宠物衣服
local cfgPetClothes = skynet.server.gameConfig:GetPlayerCurCfg( player , "PetClothes" , goodsId )
if cfgPetClothes and 1 == cfgPetClothes.shopType then
local passCheck = player.gameData.passCheck
passCheck.clothesBuyCount = passCheck.clothesBuyCount + 1
end
local quality = cfgPetClothes.quality
--不凡品种特殊处理(之前的规则无法兼容)
if quality==4 then
quality=18
end
player:AddExpForType( 12 , quality , count )
skynet.server.achieveTask:Modify( player , 15 , 1 )
skynet.server.levelTask:Modify( player , 15 , 1 )
skynet.server.taskListEvent:Modify( player , 15 , 1 )
end
table.insert( data.goodsInfo , goodInfo )
data.goodsStat = { goodsType = goodsType , goodsCount = self:GetGoodsStat( player , goodsType )}
skynet.server.gameServer:SendMsgToUser( player.userId , "CMD_S2C_BagUpdate" , data )
player:AddSaveLevel( dataType.SaveLevel_KeyDataChange )
log.debug(string.format("玩家 %d 背包更新 商品类型 %d 商品ID %d 数量 %d" , userId , goodInfo.type , goodInfo.id , goodInfo.count))
return true
end
--添加物品但不增加经验
function Bag:AddGoodsNoExp( player , goodsType , goodsId , count ,isAddIllustration )
count = count or 1
isAddIllustration = isAddIllustration or false --是否增加图鉴
--检查各参数
if not player or not goodsType or not goodsId or goodsId <= 0 then
log.warning("无法添加物品到背包,请求参数错误", player,goodsType , goodsId )
return false
end
--检查物品的合法性
if not self:IsValidGoodsType( goodsType ) then
log.warning("无法添加物品到背包,商品类型错误", goodsType)
return false
end
local data = {}
data.goodsInfo = {}
local userId = player.basicInfo.userID
local gainTime = skynet.GetTime()
local goodInfo = {}
local lastCount = 0 --最新数量
if player:IsBuyGoods( goodsType , goodsId ) then
--存在家具
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type and goodsId == v.id then
v.count = v.count + count
v.gainTime = gainTime
goodInfo = { type = v.type , id = v.id , count = v.count , gainTime = v.gainTime , isNew = false}
break
end
end
else
--不存在家具
goodInfo = { type = goodsType , id = goodsId , count = count , gainTime = gainTime , isNew = true}
table.insert( player.gameData.bag , goodInfo )
if goodsType == dataType.GoodsType_Prop then
skynet.server.msgTips:Add(player , 35)
elseif goodsType == dataType.GoodsType_Seed or goodsType == dataType.GoodsType_Plant or goodsType == dataType.GoodsType_Fish or goodsType == dataType.GoodsType_CuisineMenu or goodsType == dataType.GoodsType_CuisineMaterial or goodsType == dataType.GoodsType_Coffee then
skynet.server.msgTips:Add(player , 36)
end
end
self:AddGoodsStat( player , goodsType , goodsId , count )
if isAddIllustration then
skynet.server.illustration:Add( player , goodsType , goodsId )
end
skynet.server.playerRecord:Add( userId , dataType.RecordType_100 , 0 , goodInfo.type , goodInfo.id , goodInfo.count )
table.insert( data.goodsInfo , goodInfo )
data.goodsStat = { goodsType = goodsType , goodsCount = self:GetGoodsStat( player , goodsType )}
skynet.server.gameServer:SendMsgToUser( player.userId , "CMD_S2C_BagUpdate" , data )
player:AddSaveLevel( dataType.SaveLevel_KeyDataChange )
player:AddOneUnUsedGoods( goodsType , goodsId , count )
log.debug(string.format("玩家 %d 背包更新不增加经验 商品类型 %d 商品ID %d 数量 %d" , userId , goodInfo.type , goodInfo.id , goodInfo.count))
return true
end
--删除背包中的道具
function Bag:RemoveGoods( player , goodsType , id , count )
--检查各参数
if not player or not goodsType or not id or not count then
log.warning("无法删除物品从背包,请求参数错误", player,goodsType , id, count)
return false
end
--检查物品的合法性
if not self:IsValidGoodsType( goodsType ) then
log.warning("无法删除物品从背包,商品类型错误", goodsType)
return false
end
local data = {}
data.goodsInfo = {}
local userId = player.basicInfo.userID
local goodInfo = {}
local lastCount = 0 --最新数量
local isSuc = false
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type and id == v.id then
--背包减去数量
--v.count = v.count - count
local tmpCount = v.count - count
if tmpCount < 0 then
log.warning("无法删除物品从背包,商品数量错误", tmpCount)
return false
elseif tmpCount == 0 then
if goodsType == dataType.GoodsType_Prop or goodsType == dataType.GoodsType_Fish or goodsType == dataType.GoodsType_Coffee then
v.count = 0
else
table.remove( player.gameData.bag , k)
end
else
v.count = v.count - count
end
goodInfo = { goodsType = goodsType , id = v.id , count = v.count, gainTime = v.gainTime }
log.debug(string.format("玩家 %d 背包删除 商品类型 %d 商品ID %d 数量 %d 最新数量 %d" , userId , goodsType ,id , count, v.count))
isSuc = true
break
end
end
if isSuc then
player:RemoveOneUnUsedGoods( goodsType , id , count )
self:RemoveGoodsStat( player , goodsType , count )
skynet.server.playerRecord:Add( userId , dataType.RecordType_101 , 0 , goodInfo.goodsType , goodInfo.id , goodInfo.count )
table.insert( data.goodsInfo , goodInfo )
data.goodsStat = { goodsType = goodsType , goodsCount = self:GetGoodsStat( player , goodsType )}
skynet.server.gameServer:SendMsgToUser( player.userId , "CMD_S2C_BagUpdate" , data )
end
return isSuc
end
--获取背包中的道具数量
function Bag:GetGoodsCount( player , goodsType , id )
--检查各参数
if not player or not goodsType or not id then
log.warning("获取背包中的道具数量,请求参数错误", player,goodsType , id)
return 0
end
--检查物品的合法性
if not self:IsValidGoodsType( goodsType ) then
log.warning("获取背包中的道具数量,商品类型错误", goodsType)
return 0
end
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type and id == v.id then
return v.count
end
end
return 0
end
--是否正常的商品类型
function Bag:IsValidGoodsType( goodsType )
if goodsType >= dataType.GoodsType_Furniture and goodsType < dataType.GoodsType_End then
return true
end
return false
end
--获取未使用的商品信息
function Bag:GetUnusedGoodsInfo( player , goodsType )
local goodsInfo = player:GetAllUnUsedGoods( goodsType )
if not goodsInfo then
goodsInfo = {}
--没有缓存,就硬算一次
local t1 = skynet.GetTime()
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type then
local cfgFurniture = skynet.server.gameConfig:GetPlayerCurCfg( player , "Furniture" , v.id )
if cfgFurniture.shopType ~= skynet.server.doubleSpace.ShopTypeNo then --双人空间的家具不能计算在里面
local maxCount1 = skynet.server.house:GetCurFurnitureMaxCount( player , v.type , v.id )
local maxCount2 = self:GetPutGoodsMaxCount( player , dataType.GoodsType_Furniture , v.id )
--maxCount2 = 0 --暂时不判断双人空间的家具数量,后面优化这块,
maxCount1 = v.count - maxCount1
maxCount2 = v.count - maxCount2
if maxCount1 > 0 and maxCount2 > 0 then
table.insert( goodsInfo , { type = v.type , id = v.id , count = math.min(maxCount1 , maxCount2) , gainTime = v.gainTime })
end
end
end
end
t1 = skynet.GetTime() - t1
if t1 >= 1 then
local errorText = string.format("玩家 %d 背包 未使用的商品信息 用时太长 超过 %d 秒" , player.basicInfo.userID , t1 )
log.warning(errorText)
end
player:AddAllUnUsedGoods( goodsType , goodsInfo )
end
return goodsInfo
end
--是否能移除商品
function Bag:IsRemoveGoods( player , goodsType , goodsId , takeOutCount )
for k, v in pairs( player.gameData.bag ) do
--找到对应的商品
if goodsType == v.type and goodsId == v.id then
local maxCount = skynet.server.house:GetCurFurnitureMaxCount( player , v.type , v.id )
--剩余数量 = 当前数量 - 房间最大数量
maxCount = v.count - maxCount
--剩余数量 - 扣除的数量 >=0 表示可以扣除
if maxCount - takeOutCount >= 0 then
return true
else
return false
end
end
end
return false
end
--添加商品数量
function Bag:AddGoodsStat( player , goodsType , goodsId , goodsCount )
local bagCount = player.gameData.bagCount
local isExist = false
for k, v in pairs( bagCount ) do
if goodsType == v.type then
isExist = true
v.count = v.count + goodsCount
break
end
end
if not isExist then
table.insert( bagCount , { type = goodsType , count = goodsCount })
end
--[[ 暂时不用
if dataType.GoodsType_Plant == goodsType then --目前只有植物会统计历史最大数量
local goodsHistoryMaxCount = player.gameData.goodsHistoryMaxCount
if not skynet.server.common:IsExist( goodsId , goodsHistoryMaxCount ) then
--不存在,就初始化
table.insert( goodsHistoryMaxCount , { type = goodsType , id = goodsId , count = 1 })
else
--存在就累加
for k, v in pairs( goodsHistoryMaxCount ) do
if goodsType == v.type and goodsId == v.id then
v.count = v.count + goodsCount
break
end
end
end
end
]]
end
--减少商品数量
function Bag:RemoveGoodsStat( player , goodsType , goodsCount )
local bagCount = player.gameData.bagCount
local isExist = false
for k, v in pairs( bagCount ) do
if goodsType == v.type then
v.count = v.count - goodsCount
if v.count < 0 then
v.count = 0
end
break
end
end
end
--获取商品统计
function Bag:GetGoodsStat( player , goodsType )
local bagCount = player.gameData.bagCount
for k, v in pairs( bagCount ) do
if goodsType == v.type then
return v.count
end
end
return 0
end
--获取商品历史最大数量(需求改动,暂时不用)
function Bag:GetGoodsHistoryMaxCount( player , goodsType , goodsId )
local goodsHistoryMaxCount = player.gameData.goodsHistoryMaxCount
--存在就累加
for k, v in pairs( goodsHistoryMaxCount ) do
if goodsType == v.type and goodsId == v.id then
return v.count
end
end
return 0
end
--获取今天购买商品的数量
function Bag:GetTodayBuyGoodsCount( player , goodsType , goodsId )
local buyGoodsCount = player.gameData.todayGain.buyGoodsCount
for k, v in pairs( buyGoodsCount ) do
if goodsType == v.type and goodsId == v.id then
return v.count
end
end
return 0
end
--添加今天购买商品的数量
function Bag:AddTodayBuyGoodsCount( player , goodsType , goodsId , count )
local buyGoodsCount = player.gameData.todayGain.buyGoodsCount
local isExist = false
for k, v in pairs( buyGoodsCount ) do
if goodsType == v.type and goodsId == v.id then
v.count = v.count + count
isExist = true
break
end
end
if not isExist then
table.insert( buyGoodsCount , { type = goodsType , id = goodsId , count = count })
end
end
--添加放置商品数量
function Bag:AddPutGoodsMaxCount( player , goodsType , goodsId , maxPutCount )
local putMaxCount = player.gameData.putMaxCount
local isExist = false
for k, v in pairs( putMaxCount ) do
if goodsType == v.type and goodsId == v.id then
isExist = true
--当前放置数量大于保存的数量,就更新
if maxPutCount > v.maxCount then
v.maxCount = maxPutCount
end
break
end
end
if not isExist then
table.insert( putMaxCount , { type = goodsType , id = goodsId , maxCount = maxPutCount })
end
end
--移除商品数量
function Bag:RemovePutGoodsMaxCount( player , goodsType , goodsId , maxPutCount )
local putMaxCount = player.gameData.putMaxCount
local isExist = false
for k, v in pairs( putMaxCount ) do
if goodsType == v.type and goodsId == v.id then
isExist = true
--当前放置数量大于保存的数量,就更新
if v.maxCount >= maxPutCount then
v.maxCount = v.maxCount - maxPutCount
else
v.maxCount = 0
end
break
end
end
end
--获取放置商品数量
function Bag:GetPutGoodsMaxCount( player , goodsType , goodsId )
local putMaxCount = player.gameData.putMaxCount
for k, v in pairs( putMaxCount ) do
if goodsType == v.type and goodsId == v.id then
return v.maxCount
end
end
return 0
end
--获取背包中单个物品所有信息
function Bag:GetGoodsInfo( player , goodsType , goodsId)
--检查各参数
if not player or not goodsType or not goodsId then
log.warning("获取背包中的道具数量,请求参数错误", player,goodsType , goodsId)
return 0
end
--检查物品的合法性
if not self:IsValidGoodsType( goodsType ) then
log.warning("获取背包中的道具数量,商品类型错误", goodsType)
return 0
end
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type and goodsId == v.id then
return v
end
end
return {}
end
skynet.server.bag = Bag
return Bag