HomeServer/lualib-src/Server-main/AllServer/GameServer/Bag.lua

374 lines
13 KiB
Lua
Raw Permalink Normal View History

2024-11-20 15:41:09 +08:00
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 --功能顺序
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
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 })
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 , id , count )
--检查各参数
if not player or not goodsType or not id or not count or id <= 0 then
log.info("无法添加物品到背包,请求参数错误", player,goodsType , id, count)
return false
end
--检查物品的合法性
if not self:IsValidGoodsType( goodsType ) then
log.info("无法添加物品到背包,商品类型错误", 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 , id ) then
--存在家具
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type and id == 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 = id , count = count , gainTime = gainTime , isNew = true}
table.insert( player.gameData.bag , goodInfo )
end
self:AddGoodsStat( player , goodsType , count )
--任务完成
if dataType.GoodsType_Clothes == goodsType then --人物衣服
local cfgClothes = skynet.server.gameConfig:GetCurCfg("Clothes" , id)
local clothesType = cfgClothes.type
if dataType.ClothesType_Head == clothesType then --头型
skynet.server.achieveTask:Modify( player , 30 , 1)
elseif dataType.ClothesType_Eyes == clothesType then --眼型
skynet.server.achieveTask:Modify( player , 31 , 1)
elseif dataType.ClothesType_Hair == clothesType then --发型
skynet.server.achieveTask:Modify( player , 32 , 1)
end
elseif dataType.GoodsType_PetClothes == goodsType then --宠物衣服
skynet.server.achieveTask:Modify( player , 15 , 1 )
end
skynet.server.illustration:Add( player , goodsType , id )
skynet.server.playerRecord:Add( userId , dataType.RecordType_100 , 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 )
log.info(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.info("无法删除物品从背包,请求参数错误", player,goodsType , id, count)
return false
end
--检查物品的合法性
if not self:IsValidGoodsType( goodsType ) then
log.info("无法删除物品从背包,商品类型错误", 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
goodInfo = { goodsType = goodsType , id = v.id , count = v.count, gainTime = v.gainTime }
if v.count <= 0 then
table.remove( player.gameData.bag , k)
end
log.info(string.format("玩家 %d 背包删除 商品类型 %d 商品ID %d 数量 %d 最新数量 %d" , userId , goodsType ,id , count, v.count))
isSuc = true
break
end
end
if isSuc then
self:RemoveGoodsStat( player , goodsType , count )
skynet.server.playerRecord:Add( userId , dataType.RecordType_101 , 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.info("获取背包中的道具数量,请求参数错误", player,goodsType , id)
return 0
end
--检查物品的合法性
if not self:IsValidGoodsType( goodsType ) then
log.info("获取背包中的道具数量,商品类型错误", 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:CalcExp( goodsType , id , count )
local cfgGoods = {}
local addExp = 0
--获取指定类型配置
if dataType.GoodsType_Furniture == goodsType then
cfgGoods = skynet.server.gameConfig:GetCurFurnitureCfg( id )
if cfgGoods then
addExp = count * cfgGoods.exp
end
elseif dataType.GoodsType_Decorate == goodsType then
cfgGoods = skynet.server.gameConfig:GetCurDecorationCfg( id )
if cfgGoods then
addExp = count * cfgGoods.exp
end
end
return addExp
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 = {}
local t1 = skynet.GetTime()
for k, v in pairs( player.gameData.bag ) do
if goodsType == v.type then
local maxCount = skynet.server.house:GetCurFurnitureMaxCount( player , v.type , v.id )
maxCount = v.count - maxCount
table.insert( goodsInfo , { type = v.type , id = v.id , count = maxCount > 0 and maxCount or 0 , gainTime = v.gainTime })
end
end
t1 = skynet.GetTime() - t1
if t1 >= 1 then
local errorText = string.format("玩家 %d 背包 未使用的商品信息 用时太长 超过 %d 秒" , player.basicInfo.userID , t1 )
log.info(errorText)
skynet.server.gameServer:SendErrorInfoToCenter( errorInfo.ErrorCode.CalcTimeTooLong , errorText )
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 , 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
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
skynet.server.bag = Bag
return Bag