HomeServer/lualib-src/Server-main/AllServer/GameServer/Used.lua
2024-11-20 15:41:37 +08:00

478 lines
20 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 Used = oo.class()
Used.SellOPType_StartSell = 1 --开始出售
Used.SellOPType_StopSell = 2 --停止出售
Used.SellOPType_ConfirmSell = 3 --确定出售
Used.SellStatus_NoSell = 1 --未卖出
Used.SellStatus_SomeoneWant = 2 --有人购买
Used.SellStatus_AlreadySell = 3 --已经出售
Used.GoodsStatus_NoReach = 1 --未到达
Used.GoodsStatus_AlreadyReach = 2 --已到达
Used.GoodsStatus_AlreadyGet = 3 --已领取
Used.CopyType_Seller = 1 --卖家
Used.CopyType_Buyer = 2 --买家
function Used:Init()
end
--闲菜展示
function Used:Show( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SUsedShow", c2sData.data ))
local data = {}
self:CheckRefreshGoods( player )
log.info(string.format("玩家 %d 闲菜 展示操作" , player.basicInfo.userID))
local count = 0
--多出的20个已签收物流就删除前面的
for k, v in pairs(player.gameData.used.logisticsInfo ) do
if self.GoodsStatus_AlreadyGet == v.goodsStatus then
count = count + 1
end
end
if count > 20 then
for k, v in pairs(player.gameData.used.logisticsInfo ) do
if self.GoodsStatus_AlreadyGet == v.goodsStatus then
player.gameData.used.logisticsInfo[ k ] = nil
break
end
end
end
--多出的15个卖出记录就删除前面的
count = 0
for k, v in pairs(player.gameData.used.sellInfo ) do
if self.SellStatus_AlreadySell == v.status then
count = count + 1
end
end
if count >= 15 then
local deleteCount = count - 15
local tmpCount = 0
for k, v in pairs(player.gameData.used.sellInfo ) do
if tmpCount >= deleteCount then
break
end
if self.SellStatus_AlreadySell == v.status then
player.gameData.used.sellInfo[ k ] = nil
tmpCount = tmpCount + 1
end
end
end
data.buyRefreshTime = player.gameData.used.buyRefreshTime
data.buyInfo = player.gameData.used.buyInfo
data.sellInfo = self:GetSellInfo( player )
data.logisticsInfo = self:GetLogisticsInfo( player )
skynet.server.msgTips:Reduce( player , 3)
skynet.server.msgTips:Reduce( player , 16)
s2cData.cmd = pb.enum("MsgType","CMD_S2C_UsedShow")
s2cData.data = assert(pb.encode("S2CUsedShow", data))
end
--闲菜购买
function Used:Buy( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SUsedBuy", c2sData.data ))
local data = {}
local goodsId = c2sData.data.goodsId
if not goodsId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
for k, v in pairs( player.gameData.used.buyInfo ) do
if goodsId == v.goodsId then
--找到对应的商品,扣除金额
if player:MoneyChange( dataType.GoodsType_Coin , -v.coin ) then
player.gameData.used.buyInfo[ k ].isBuy = true
--计算物流到达时间
local cfgGoods = skynet.server.gameConfig:GetCurFurnitureCfg( v.goodsId )
local discount = skynet.server.gameConfig.SValue.picklesSellDiscount
local calcDeliverTime = math.floor(skynet.server.gameConfig.SValue.picklesDeliveryTime * discount * cfgGoods.coin ) * 60
local reachTime = skynet.GetTime() + calcDeliverTime
table.insert( player.gameData.used.logisticsInfo , { goodsId = v.goodsId , npcNameId = v.npcNameId , copyId = v.copyId , goodsStatus = self.GoodsStatus_NoReach , reachTime = reachTime , deliverTime = calcDeliverTime } )
skynet.server.levelTask:Modify( player , dataType.GeneralTaskType_BuyUsed , 1)
skynet.server.dailyTask:Modify( player , 4 , 1)
skynet.server.passCheck:Modify( player , 3 , v.coin )
skynet.server.passCheck:Modify( player , 21 , 1 )
--增加经验
local exp = skynet.server.bag:CalcExp( dataType.GoodsType_Furniture , goodsId, 1 )
player:AddExp( exp )
log.info(string.format("玩家 %d 闲菜 购买商品 商品ID %d NPC名字ID %d 对白ID %d 购买金币 %d 到达时间 %d" , player.basicInfo.userID , goodsId , v.npcNameId , v.copyId , v.coin , reachTime))
else
s2cData.code = errorInfo.ErrorCode.NoEnoughMoney
end
break
end
end
end
self:CheckRefreshGoods( player )
data.buyInfo = player.gameData.used.buyInfo
data.logisticsInfo = self:GetLogisticsInfo( player )
s2cData.cmd = pb.enum("MsgType","CMD_S2C_UsedBuy")
s2cData.data = assert(pb.encode("S2CUsedBuy", data))
end
--闲菜刷新
function Used:Refresh( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SUsedRefresh", c2sData.data ))
local data = {}
local cfgSValue = skynet.server.gameConfig.SValue
if player:MoneyChange( dataType.MoneyType_Volute , -cfgSValue.sellRefreshCost ) then
player.gameData.used.buyRefreshTime = skynet.GetTime() + cfgSValue.picklesRefreshTime * 60
log.info(string.format("玩家 %d 闲菜 刷新操作 下一次刷新时间 %d" , player.basicInfo.userID , player.gameData.used.buyRefreshTime))
player.gameData.used.buyInfo = self:RefreshGoods( player )
skynet.server.achieveTask:Modify( player , 34 , 1)
else
s2cData.code = errorInfo.ErrorCode.NoEnoughMoney
end
data.buyRefreshTime = player.gameData.used.buyRefreshTime
data.buyInfo = player.gameData.used.buyInfo
s2cData.cmd = pb.enum("MsgType","CMD_S2C_UsedRefresh")
s2cData.data = assert(pb.encode("S2CUsedRefresh", data))
end
--闲菜出售
function Used:Sell( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SUsedSell", c2sData.data ))
local data = {}
local opType = c2sData.data.opType
local goodsType = c2sData.data.goodsType
local goodsId = c2sData.data.goodsId
if not opType or not goodsType or not goodsId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
if self.SellOPType_StartSell == opType then --开始出售
local isSell = false
if goodsType >= dataType.GoodsType_Furniture and goodsType < dataType.GoodsType_End and
goodsType ~= dataType.GoodsType_Decorate and goodsType ~= dataType.GoodsType_Flowerpot then
isSell = true
end
if player:IsBuyGoods( goodsType , goodsId ) then
if isSell then
--从背包中移出该商品
skynet.server.bag:RemoveGoods( player , dataType.GoodsType_Furniture , goodsId , 1 )
--加入闲菜卖家数据
local cfgGoods = skynet.server.gameConfig:GetCurFurnitureCfg( goodsId )
local discount = skynet.server.gameConfig.SValue.picklesSellDiscount
local sellTime = skynet.GetTime() + (math.floor(skynet.server.gameConfig.SValue.picklesDeliveryTime * discount * cfgGoods.coin ) * 60) --计算售卖时间
table.insert( player.gameData.used.sellInfo , { goodsId = goodsId , status = self.SellStatus_NoSell , npcNameId = 0 , copyId = 0 , coin = math.floor(cfgGoods.coin * discount) , sellTime = sellTime })
log.info(string.format("玩家 %d 闲菜 售卖操作 开始售卖 商品ID %d" , player.basicInfo.userID , goodsId))
end
else
s2cData.code = errorInfo.ErrorCode.NoGoodsID
end
elseif self.SellOPType_StopSell == opType then --停止出售
for k, v in pairs( player.gameData.used.sellInfo ) do
if self.SellStatus_NoSell == v.status and goodsId == v.goodsId then
--未卖出并且找到对应的商品ID
local cfgGoods = skynet.server.gameConfig:GetCurFurnitureCfg( goodsId )
skynet.server.bag:AddGoods( player , dataType.GoodsType_Furniture , goodsId , 1 )
player.gameData.used.sellInfo[ k ] = nil
log.info(string.format("玩家 %d 闲菜 售卖操作 停止售卖 商品ID %d" , player.basicInfo.userID , goodsId))
break
end
end
elseif self.SellOPType_ConfirmSell == opType then --确定出售
for k, v in pairs( player.gameData.used.sellInfo ) do
if self.SellStatus_SomeoneWant == v.status and goodsId == v.goodsId then
player.gameData.used.sellInfo[ k ].status = self.SellStatus_AlreadySell
--领取金币
player:MoneyChange( dataType.MoneyType_Coin , v.coin )
--增加经验
--local exp = skynet.server.bag:CalcExp( dataType.GoodsType_Furniture , goodsId, 1 )
--player:AddExp( exp )
skynet.server.levelTask:Modify( player , dataType.GeneralTaskType_SellUsed , 1)
skynet.server.dailyTask:Modify( player , 9 , 1)
skynet.server.passCheck:Modify( player , 4 , v.coin )
skynet.server.passCheck:Modify( player , 22 , 1 )
log.info(string.format("玩家 %d 闲菜 售卖操作 领取奖励 商品ID %d" , player.basicInfo.userID , goodsId))
break
end
end
end
end
self:CheckRefreshGoods( player )
data.sellInfo = self:GetSellInfo( player )
s2cData.cmd = pb.enum("MsgType","CMD_S2C_UsedSell")
s2cData.data = assert(pb.encode("S2CUsedSell", data))
end
--闲菜物流
function Used:Logistics( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SUsedLogistics", c2sData.data ))
local data = {}
data.goodsId = {}
local goodsId = c2sData.data.goodsId
if 0 == #goodsId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
end
for k, oneGoodsId in pairs( goodsId ) do
if not oneGoodsId then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
for k, v in pairs( player.gameData.used.logisticsInfo ) do
if self.GoodsStatus_AlreadyReach == v.goodsStatus and oneGoodsId == v.goodsId then
--签收物流中商品
skynet.server.bag:AddGoods( player , dataType.GoodsType_Furniture , oneGoodsId , 1 )
v.goodsStatus = self.GoodsStatus_AlreadyGet
skynet.server.levelTask:Modify( player , dataType.GeneralTaskType_ReciveUsed , 1)
skynet.server.dailyTask:Modify( player , 10 , 1)
table.insert( data.goodsId , oneGoodsId )
skynet.server.msgTips:Reduce( player , 4)
log.info(string.format("玩家 %d 闲菜 物流签收 领取奖励 商品ID %d" , player.basicInfo.userID , oneGoodsId))
end
end
end
end
self:CheckRefreshGoods( player )
data.logisticsInfo = self:GetLogisticsInfo( player )
s2cData.cmd = pb.enum("MsgType","CMD_S2C_UsedLogistics")
s2cData.data = assert(pb.encode("S2CUsedLogistics", data))
end
--闲菜物流展示
function Used:LogisticsShow( player , c2sData , s2cData )
local data = {}
data.logisticsInfo =self:GetLogisticsInfo( player )
s2cData.cmd = pb.enum("MsgType","CMD_S2C_UsedLogisticsShow")
s2cData.data = assert(pb.encode("S2CUsedLogisticsShow", data))
end
--闲菜查看仓库
function Used:StorageShow( player , c2sData , s2cData )
c2sData.data = assert(pb.decode("C2SUsedStorageShow", c2sData.data ))
local data = {}
local goodsType = c2sData.data.goodsType
if not goodsType then
s2cData.code = errorInfo.ErrorCode.ErrRequestParam
else
data.goodsType = goodsType
data.goodsInfo = skynet.server.bag:GetUnusedGoodsInfo( player , goodsType )
end
self:CheckRefreshGoods( player )
s2cData.cmd = pb.enum("MsgType","CMD_S2C_UsedStorageShow")
s2cData.data = assert(pb.encode("S2CUsedStorageShow", data))
end
--闲菜出售加速
function Used:SellAccelerate( player , c2sData , s2cData )
local data = {}
local cfgSValue = skynet.server.gameConfig.SValue
if not player:MoneyChange( dataType.MoneyType_Volute , -cfgSValue.pickleCustomerCost ) then
s2cData.code = errorInfo.ErrorCode.NoEnoughMoney
else
self:AccSell( player ) --加速
data.sellInfo = self:GetSellInfo( player )
end
s2cData.cmd = pb.enum("MsgType","CMD_S2C_UsedSellAccelerate")
s2cData.data = assert(pb.encode("S2CUsedSellAccelerate", data))
end
--检查商品是否能刷新
function Used:CheckRefreshGoods( player )
--刷新商店购买时间
if skynet.GetTime() >= player.gameData.used.buyRefreshTime then
local cfgSValue = skynet.server.gameConfig.SValue
player.gameData.used.buyRefreshTime = skynet.GetTime() + cfgSValue.picklesRefreshTime * 60
player.gameData.used.buyInfo = self:RefreshGoods( player )
end
--刷新已经卖出的商品
for k, v in pairs( player.gameData.used.sellInfo ) do
if skynet.GetTime() >= v.sellTime and self.SellStatus_NoSell == v.status then
--成功售卖
player.gameData.used.sellInfo[ k ].status = self.SellStatus_SomeoneWant
--随机NPC名字ID
local npcNameList = skynet.server.common:RandNoRepeatItem( 1 , skynet.server.gameConfig.NPCName )
if not npcNameList then
log.info("闲菜随机的NPC名字异常 ", npcNameList )
end
--随机文案ID
local cfgCopy = {}
for k, v in pairs( skynet.server.gameConfig.Copy ) do
if self.CopyType_Buyer == v.type then
table.insert( cfgCopy , v)
end
end
local copyList = skynet.server.common:RandNoRepeatItem( 1 , cfgCopy )
if not copyList then
log.info("闲菜随机的文案ID异常 ", copyList , #copyList)
end
player.gameData.used.sellInfo[ k ].npcNameId = npcNameList[1]
player.gameData.used.sellInfo[ k ].copyId = copyList[1]
end
end
--刷新物流是否到了
for k, v in pairs( player.gameData.used.logisticsInfo ) do
if skynet.GetTime() >= v.reachTime and self.GoodsStatus_NoReach == v.goodsStatus then
--商品已到达
player.gameData.used.logisticsInfo[ k ].goodsStatus = self.GoodsStatus_AlreadyReach
end
end
end
--刷新购买商品
function Used:RefreshGoods( player )
local count = 0
local buyInfo = {}
local maxItem = 6 --最大生成
local newFurniture = {}
for k, v in pairs( skynet.server.gameConfig.Furniture ) do
--找出配置中闲菜可以买的数据
if 1 == v.marketType and player.gameData.level >= v.level then
table.insert( newFurniture , v )
end
end
--随机商品ID
local goodsList = skynet.server.common:RandNoRepeatItem( maxItem , newFurniture )
if not goodsList or maxItem ~= #goodsList then
log.info("闲菜随机的商品异常 ", goodsList , #goodsList)
end
if player.gameData.used.isFirstRefresh then
--第一次刷新,给指定商品
player.gameData.used.isFirstRefresh = false
goodsList = {}
table.insert( goodsList , 206)
table.insert( goodsList , 209)
table.insert( goodsList , 99)
table.insert( goodsList , 106)
table.insert( goodsList , 7)
table.insert( goodsList , 205)
end
--随机NPC名字ID
local npcNameList = skynet.server.common:RandNoRepeatItem( maxItem , skynet.server.gameConfig.NPCName )
if not npcNameList or maxItem ~= #npcNameList then
log.info("闲菜随机的NPC名字异常 ", npcNameList , #npcNameList)
end
--随机文案ID
local cfgCopy = {}
for k, v in pairs( skynet.server.gameConfig.Copy ) do
if self.CopyType_Seller == v.type then
table.insert( cfgCopy , v)
end
end
local copyList = skynet.server.common:RandNoRepeatItem( maxItem , cfgCopy )
if not copyList or maxItem ~= #copyList then
log.info("闲菜随机的文案ID异常 ", copyList , #copyList)
end
--从3个配置中去随机万一哪个配置被动了可能会遇到没有随机到指定数量的配置那么在3个中找一个数量最少的去生成
local count1 = #goodsList
local count2 = #npcNameList
local count3 = #copyList
if maxItem < count1 then
maxItem = count1
end
if maxItem < count2 then
maxItem = count2
end
if maxItem < count3 then
maxItem = count3
end
--获取最终商品
local discountCoin = 0
for i = 1, maxItem, 1 do
discountCoin = self:GetDiscountPrice( goodsList[i] )
table.insert( buyInfo , { goodsId = goodsList[i] , npcNameId = npcNameList[i] , copyId = copyList[i] , isBuy = false , coin = discountCoin })
log.info(string.format("玩家 %d 闲菜 刷新商品 商品ID %d NPC名字ID %d 对白ID %d 金币 %d" , player.basicInfo.userID , goodsList[i] , npcNameList[i] , copyList[i] , discountCoin ))
end
return buyInfo
end
--广告加速卖出
function Used:AccSell( player )
for k, v in pairs( player.gameData.used.sellInfo ) do
--所有未卖出商品全部可以卖出
if self.SellStatus_NoSell == v.status then
v.sellTime = 0
end
end
--刷新一下
self:CheckRefreshGoods( player )
--重新发送一下展示消息
--[[
local data = {}
data.buyRefreshTime = player.gameData.used.buyRefreshTime
data.buyInfo = player.gameData.used.buyInfo
data.sellInfo = self:GetSellInfo( player )
data.logisticsInfo = self:GetLogisticsInfo( player )
skynet.server.gameServer:SendMsgToUser( player.userId , "CMD_S2C_UsedShow" , data )
]]
end
--获取折扣价格
function Used:GetDiscountPrice( id )
local cfgFurniture = skynet.server.gameConfig.Furniture
local picklesBuyDiscount = skynet.server.gameConfig.SValue.picklesBuyDiscount
local ratio = math.random( picklesBuyDiscount[1] , picklesBuyDiscount[2]) / 100
for k, v in pairs( cfgFurniture ) do
if id == v.id then
local price = math.ceil(ratio * v.coin)
log.info(string.format("闲菜计算商品折扣 最终金币数价格 %d 折扣率 %f 原需要金币数 %d" , price , ratio , v.coin))
return price
end
end
end
--获取售卖数据
function Used:GetSellInfo( player )
local data = {}
for k, v in pairs( player.gameData.used.sellInfo ) do
--上面删除指定记录后,为什么无法直接 赋值= 的方式必须要这样拷贝难道数组没有1以后就找不到首地址
table.insert( data , v)
end
return data
end
--获取物流数据
function Used:GetLogisticsInfo( player )
local data = {}
for k, v in pairs( player.gameData.used.logisticsInfo ) do
--上面删除指定记录后,为什么无法直接 赋值= 的方式必须要这样拷贝难道数组没有1以后就找不到首地址
table.insert( data , v)
end
return data
end
skynet.server.used = Used
return Used