HomeServer/Server/AllServer/GameServer/Activity/ActivityPuzzle.lua

468 lines
21 KiB
Lua
Raw 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 activity = require "Activity"
local json =require "json"
local taskListEvent = require "TaskListEvent"
local ActivityPuzzle = oo.class()
ActivityPuzzle.ActivityType = dataType.ActivityType_Puzzle
--当前盲盒矩阵模板
ActivityPuzzle.BoxInfosModel = {}
function ActivityPuzzle:Init()
--对当前盲盒矩阵初始化
for i = 1, 16 do
self.BoxInfosModel[i] ={
blindBoxId = i,
blindBoxState = 1
}
end
end
--拼图任务事件注册
local function onEventFired(player , taskId , count)
local activityId = skynet.server.activity:GetActivityInfo(player, ActivityPuzzle.ActivityType)
--活动是否开启
if not player:IsUnlockSystem( dataType.UnlockSystem_ActivityPuzzle) or activityId == 0 then
return
end
local cfgPuzzleTask = skynet.server.gameConfig:GetPlayerAllCfg(player, "JigsawPuzzleTask")
local task = {}
for k, v in pairs(cfgPuzzleTask) do
if v.puzzleId == activityId then
table.insert(task,v)
end
end
--存在配置
if task == nil or not next(task) then
return
end
--防止数据为空报错
if player.gameData.activity[ActivityPuzzle.ActivityType] == nil or next(player.gameData.activity[ActivityPuzzle.ActivityType]) == nil or player.gameData.activity[ActivityPuzzle.ActivityType].curData == nil or next(player.gameData.activity[ActivityPuzzle.ActivityType].curData) == nil then
skynet.server.activityPuzzle:InitData(player)
end
--触发完成任务
local finishIds = taskListEvent:Condition(player , taskId , count , player.gameData.activity[ActivityPuzzle.ActivityType].curData.puzzleTask , task)
--后续处理逻辑 红点逻辑此处处理
if next(finishIds) then
skynet.server.msgTips:Add(player, 112)
end
end
function ActivityPuzzle:LoginInitData(player)
-- 检查应该初始还是结束活动
local activityId, startTime, endTime , id = activity:GetActivityInfo(player, self.ActivityType)
if activityId == 0 and player.gameData.activity[self.ActivityType] ~= nil and next(player.gameData.activity[self.ActivityType]) ~= nil then
--如果活动结束玩家身上还有未使用的拼图碎片则清空
if not player.gameData.activity[self.ActivityType].isClear then
skynet.server.msgTips:Reset(player, 110)
skynet.server.msgTips:Reset(player, 111)
skynet.server.msgTips:Reset(player, 112)
skynet.server.bag:RemoveGoods(player, dataType.GoodsType_Prop, 31, skynet.server.bag:GetGoodsCount(player, dataType.GoodsType_Prop, 31))
player.gameData.activity[self.ActivityType].isClear = true
end
end
if id == 0 then
return
end
if player:IsUnlockSystem( dataType.UnlockSystem_ActivityPuzzle ) then
if player.gameData.activity[self.ActivityType] == nil or next(player.gameData.activity[self.ActivityType]) == nil or player.gameData.activity[self.ActivityType].curData == nil or next(player.gameData.activity[self.ActivityType].curData) == nil then
self:InitData(player)
else
if player.gameData.activity[self.ActivityType].curId ~= id then
self:InitData(player)
else
skynet.server.msgTips:Reset(player, 110)
skynet.server.msgTips:Reset(player, 111)
skynet.server.msgTips:Reset(player, 112)
self:CheckRedHot( player )
end
end
end
end
function ActivityPuzzle:InitData(player)
local activityId, startTime, endTime , id = skynet.server.activity:GetActivityInfo(player, self.ActivityType)
if player.gameData.activity[self.ActivityType] == nil or player.gameData.activity[self.ActivityType].curData == nil then
player.gameData.activity[self.ActivityType] = {}
player.gameData.activity[self.ActivityType].curId = 0
player.gameData.activity[self.ActivityType].isClear = false
player.gameData.activity[self.ActivityType].activedata = {}
player.gameData.activity[self.ActivityType].curData = {}
end
if activityId == 0 then
return
end
player.gameData.activity[self.ActivityType].curId = id
player.gameData.activity[self.ActivityType].isClear = false
player.gameData.activity[self.ActivityType].activedata = {}
player.gameData.activity[self.ActivityType].curData = {}
local puzzleData = player.gameData.activity[self.ActivityType].curData
-- 玩家对应配置
puzzleData.puzzleId = activityId -- 本次活动id
puzzleData.curLevelId = 1 -- 当前关卡id
puzzleData.jigsawProgressStates = {1,1,1} --拼图进度进度奖励状态 1未解锁 2解锁未领取 3 已领取
puzzleData.fourDirRewardState = 1 --四向拼图奖励状态1未解锁 2解锁未领取 3 已领取
puzzleData.coreRewardState = 1 --中心拼图奖励状态1未解锁 2解锁未领取 3 已领取
puzzleData.JigsawPosInfos = {} --当前已经有拼图的位置
puzzleData.jigsawBlindBoxInfos = skynet.server.common:DeepCopy(self.BoxInfosModel) --当前盲盒矩阵信息
puzzleData.remainingUniversal = 2 --剩余万能碎片数量
puzzleData.remainingRandom = 14 --剩余随机碎片数量
puzzleData.puzzleTask = {} --拼图任务集合
puzzleData.stateLock = 1 --活动状态锁 1正常 2上锁 在活动展示接口如果为上锁状态说明有异常操作需要回溯
puzzleData.lastedBoxInfo = { boxId = 0,blindBoxContent = 0 } --最近一次解锁的盲盒id,碎片类型 用于回溯开盒操作
local cfgPuzzleTask = skynet.server.gameConfig:GetPlayerAllCfg(player, "JigsawPuzzleTask")
for k, v in pairs(cfgPuzzleTask) do
-- 任务数据 id , 任务类型 , 进度 , 状态
if v.puzzleId == activityId then
puzzleData.puzzleTask[v.id] =
{
id = v.id,
taskType = v.taskType,
value = 0,
status = dataType.TaskStatus_UnFinish
}
end
end
end
-- 拼图 展示
function ActivityPuzzle:Show(player, c2sData, s2cData)
c2sData.data = assert(pb.decode("C2SActivityJigsawShow", c2sData.data))
local data = {}
local puzzleData = player.gameData.activity[self.ActivityType].curData
-- 判断一下是否需要初始化玩家数据
if puzzleData == nil or next(puzzleData) == nil then
self:InitData(player)
puzzleData = player.gameData.activity[self.ActivityType].curData
end
-- 玩家拼图的相关信息
data.curLevelId = puzzleData.curLevelId
data.jigsawProgressStates = {}
data.fourDirRewardState = puzzleData.fourDirRewardState
data.coreRewardState = puzzleData.coreRewardState
data.JigsawPosInfos = {}
--活动安全锁进行判断,如果需要回溯执行以下逻辑
if puzzleData.stateLock == 2 then
puzzleData.jigsawBlindBoxInfos[puzzleData.lastedBoxInfo.boxId].blindBoxState = 1
if puzzleData.lastedBoxInfo.blindBoxContent == 1 then
puzzleData.remainingRandom = puzzleData.remainingRandom + 1
elseif puzzleData.lastedBoxInfo.blindBoxContent == 2 then
puzzleData.remainingUniversal = puzzleData.remainingUniversal + 1
end
puzzleData.stateLock = 1
end
for k, v in pairs(puzzleData.jigsawProgressStates) do
table.insert(data.jigsawProgressStates, v)
end
for k, v in pairs(puzzleData.JigsawPosInfos) do
table.insert(data.JigsawPosInfos, v)
end
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityJigsawShow")
s2cData.data = assert(pb.encode("S2CActivityJigsawShow", data))
end
--领取拼图进度奖励
function ActivityPuzzle:GetPuzzleReward(player, c2sData, s2cData)
c2sData.data = assert(pb.decode("C2SActivityJigsawRewardGet", c2sData.data))
local data = {}
local cfgJigsawPuzzle = skynet.server.gameConfig:GetPlayerAllCfg(player, "JigsawPuzzle")
local puzzleData = player.gameData.activity[self.ActivityType].curData
data.rewardId = -1
data.levelIdOrFinisType = c2sData.data.levelIdOrFinisType
--奖励类型 1拼图完成奖励 2四向拼图奖励或者中心拼图奖励
if c2sData.data.rewardType == 1 then
--关卡id或者拼图完成奖励的类型1四向或2中心
if c2sData.data.levelIdOrFinisType and puzzleData.jigsawProgressStates[c2sData.data.levelIdOrFinisType]==2 then
for i, v in pairs(cfgJigsawPuzzle) do
if v.activityId == puzzleData.puzzleId and c2sData.data.levelIdOrFinisType == v.levelID then
data.rewardId = v.puzzleReward
data.levelIdOrFinisType = v.levelID
break
end
end
--发放奖励
if data.rewardId ~= -1 then
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_129")
player:GiveReward( data.rewardId , eventId , 1)
--更新奖励获取情况
puzzleData.jigsawProgressStates[c2sData.data.levelIdOrFinisType]=3
--清除红点逻辑
skynet.server.msgTips:Reduce(player, 110)
else
s2cData.code = errorInfo.ErrorCode.OPFailed
end
end
elseif c2sData.data.rewardType == 2 then
if c2sData.data.levelIdOrFinisType == 1 and puzzleData.fourDirRewardState == 1 then
--此处处理当关卡最后一块拼图完成时领取上一关卡的奖励问题
if next(puzzleData.JigsawPosInfos)~= nil then
puzzleData.fourDirRewardState = 2
for i, v in pairs(cfgJigsawPuzzle) do
if v.activityId == puzzleData.puzzleId and puzzleData.curLevelId == v.levelID then
data.rewardId = v.aroundPuzzleReward
break
end
end
else
for i, v in pairs(cfgJigsawPuzzle) do
if v.activityId == puzzleData.puzzleId and puzzleData.curLevelId - 1 == v.levelID then
data.rewardId = v.aroundPuzzleReward
break
end
end
end
elseif c2sData.data.levelIdOrFinisType == 2 and puzzleData.coreRewardState ==1 then
if next(puzzleData.JigsawPosInfos) ~= nil then
puzzleData.coreRewardState = 2
for i, v in pairs(cfgJigsawPuzzle) do
if v.activityId == puzzleData.puzzleId and puzzleData.curLevelId == v.levelID then
data.rewardId = v.midPuzzleReward
break
end
end
else
for i, v in pairs(cfgJigsawPuzzle) do
if v.activityId == puzzleData.puzzleId and puzzleData.curLevelId - 1 == v.levelID then
data.rewardId = v.midPuzzleReward
break
end
end
end
end
if data.rewardId ~= -1 then
local eventId = pb.enum("EnumMoneyChangeEventID","EventID_129")
player:GiveReward( data.rewardId , eventId , 1)
else
s2cData.code = errorInfo.ErrorCode.OPFailed
end
end
data.rewardType = c2sData.data.rewardType
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityJigsawRewardGet")
s2cData.data = assert(pb.encode("S2CActivityJigsawRewardGet", data))
end
--盲盒展示
function ActivityPuzzle:BoxShow(player, c2sData, s2cData)
c2sData.data = assert(pb.decode("C2SActivityJigsawBlindBoxShow", c2sData.data))
local data = {}
data.jigsawBlindBoxInfos = {}
data.jigsawBlindBoxInfos = player.gameData.activity[self.ActivityType].curData.jigsawBlindBoxInfos
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityJigsawBlindBoxShow")
s2cData.data = assert(pb.encode("S2CActivityJigsawBlindBoxShow", data))
end
--开盲盒
function ActivityPuzzle:OpenBox(player, c2sData, s2cData)
c2sData.data = assert(pb.decode("C2SActivityJigsawBlindBoxOpen", c2sData.data))
local puzzleData = player.gameData.activity[self.ActivityType].curData
local data = {}
if puzzleData.stateLock == 2 then
s2cData.code=errorInfo.ErrorCode.OPFailed
else
if not c2sData.data.blindBoxId or puzzleData.jigsawBlindBoxInfos[c2sData.data.blindBoxId].blindBoxState == nil or puzzleData.jigsawBlindBoxInfos[c2sData.data.blindBoxId].blindBoxState == 2 then
s2cData.code=errorInfo.ErrorCode.InvaildOpForCurActivityStatus
else
--将对应盲盒状态设置成已开启 此处暂不做验证
puzzleData.jigsawBlindBoxInfos[c2sData.data.blindBoxId].blindBoxState=2
data.blindBoxContent = 1
--随机发放1个尚未获得的碎片
if puzzleData.remainingUniversal>0 and puzzleData.remainingRandom>0 then
if math.random(puzzleData.remainingUniversal + puzzleData.remainingRandom) > puzzleData.remainingRandom then
data.blindBoxContent = 2
puzzleData.remainingUniversal = puzzleData.remainingUniversal - 1
else
puzzleData.remainingRandom = puzzleData.remainingRandom - 1
end
else
if puzzleData.remainingUniversal == 0 then
puzzleData.remainingRandom = puzzleData.remainingRandom - 1
else
data.blindBoxContent = 2
puzzleData.remainingUniversal = puzzleData.remainingUniversal - 1
end
end
--加锁并记录操作,用于回溯状态
puzzleData.stateLock = 2
puzzleData.lastedBoxInfo.boxId = c2sData.data.blindBoxId
puzzleData.lastedBoxInfo.blindBoxContent = data.blindBoxContent
end
end
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityJigsawBlindBoxOpen")
s2cData.data = assert(pb.encode("S2CActivityJigsawBlindBoxOpen", data))
end
--拼图任务展示
function ActivityPuzzle:TaskShow(player, c2sData, s2cData)
c2sData.data = assert(pb.decode("C2SActivityJigsawTaskShow", c2sData.data))
local data = {}
data.taskInfos = self:GetShowTaskData(player)
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityJigsawTaskShow")
s2cData.data = assert(pb.encode("S2CActivityJigsawTaskShow", data))
end
--拼图任务领取奖励
function ActivityPuzzle:TaskRewardGet(player, c2sData, s2cData)
c2sData.data = assert(pb.decode("C2SActivityJigsawTaskRewardGet", c2sData.data))
local data = {}
local puzzletask = player.gameData.activity[self.ActivityType].curData.puzzleTask[c2sData.data.taskId]
if puzzletask and puzzletask.status == dataType.TaskStatus_Finish then
local cfgPuzzleTask = skynet.server.gameConfig:GetPlayerCurCfg(player, "JigsawPuzzleTask", puzzletask.id)
skynet.server.bag:AddGoods(player, dataType.GoodsType_Prop, 31, cfgPuzzleTask.puzzleFragmentReward)
puzzletask.status = dataType.TaskStatus_Receive
--清除红点逻辑
skynet.server.msgTips:Reduce(player, 112)
self:BoxRedGotCheck(player)
end
data.taskId = c2sData.data.taskId
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityJigsawTaskRewardGet")
s2cData.data = assert(pb.encode("S2CActivityJigsawTaskRewardGet", data))
end
--解锁指定拼图块
function ActivityPuzzle:ClickPuzzle(player, c2sData, s2cData)
c2sData.data = assert(pb.decode("C2SActivityJigsawOnClick", c2sData.data))
local puzzleData = player.gameData.activity[self.ActivityType].curData
local data = {}
if puzzleData.stateLock == 1 then
s2cData.code=errorInfo.ErrorCode.OPFailed
else
--将前端传来的新解锁拼图坐标信息插入玩家拼图矩阵信息中 此处不做验证,如果需要的话再加上重复/合法性验证
table.insert(puzzleData.JigsawPosInfos,c2sData.data.jigsawPosInfo)
--将解锁所需的拼图碎片减去
local cfgPuzzle = skynet.server.gameConfig:GetPlayerAllCfg(player, "JigsawPuzzle")
local activityId = skynet.server.activity:GetActivityInfo(player, self.ActivityType)
for k , v in pairs(cfgPuzzle) do
if v.activityId == activityId and v.levelID == puzzleData.curLevelId then
skynet.server.bag:RemoveGoods(player, dataType.GoodsType_Prop, 31, v.puzzleFragmentNum)
break
end
end
skynet.server.msgTips:ReduceAll(player, 111)
--当前拼图是该关卡最后一块时的逻辑
if #puzzleData.JigsawPosInfos==16 and puzzleData.curLevelId ~=3 then
puzzleData.jigsawProgressStates[puzzleData.curLevelId] =2
puzzleData.curLevelId =puzzleData.curLevelId + 1
puzzleData.fourDirRewardState = 1
puzzleData.coreRewardState = 1
puzzleData.JigsawPosInfos = {}
puzzleData.remainingUniversal = 2
puzzleData.remainingRandom = 14
puzzleData.jigsawBlindBoxInfos = skynet.server.common:DeepCopy(self.BoxInfosModel)
--红点逻辑
skynet.server.msgTips:Add(player, 110)
elseif #puzzleData.JigsawPosInfos==16 and puzzleData.curLevelId ==3 then
puzzleData.jigsawProgressStates[puzzleData.curLevelId] =2
puzzleData.fourDirRewardState = 1
puzzleData.coreRewardState = 1
--红点逻辑
skynet.server.msgTips:Add(player, 110)
end
--释放安全锁
puzzleData.stateLock = 1
self:BoxRedGotCheck(player)
end
s2cData.cmd = pb.enum("MsgType", "CMD_S2C_ActivityJigsawOnClick")
s2cData.data = assert(pb.encode("S2CActivityJigsawOnClick", data))
end
--拼图任务展示 数据处理
function ActivityPuzzle:GetShowTaskData(player)
local data = {}
local puzzletask = player.gameData.activity[self.ActivityType].curData.puzzleTask
for k, v in pairs(puzzletask) do
table.insert(data, {
id = v.id,
progress = v.value,
status = v.status + 1
})
end
-- 将完成的任务排到最后
local sortData = {}
for k, v in pairs(data) do
if dataType.TaskStatus_Finish == v.status -1 then
table.insert(sortData, v)
end
end
for k, v in pairs(data) do
if dataType.TaskStatus_Receive ~= v.status -1 and dataType.TaskStatus_Finish ~= v.status -1 then
table.insert(sortData, v)
end
end
for k, v in pairs(data) do
if dataType.TaskStatus_Receive == v.status -1 then
table.insert(sortData, v)
end
end
data = sortData
return data
end
--红点检测
function ActivityPuzzle:CheckRedHot( player )
local puzzleData = player.gameData.activity[self.ActivityType].curData
local activityId = skynet.server.activity:GetActivityInfo(player, self.ActivityType)
local cfgPuzzle = skynet.server.gameConfig:GetPlayerAllCfg(player, "JigsawPuzzle")
--拼图进度奖励红点
for k , v in pairs(puzzleData.jigsawProgressStates) do
if v == 2 then
skynet.server.msgTips:Add(player, 110)
end
end
--盲盒按钮红点
for k , v in pairs(cfgPuzzle) do
if v.activityId == activityId and puzzleData.curLevelId == v.levelID and skynet.server.bag:GetGoodsCount(player, dataType.GoodsType_Prop, 31) >= v.puzzleFragmentNum then
if puzzleData.jigsawProgressStates[3] < 2 then
skynet.server.msgTips:Add(player, 111)
break
end
end
end
--活动任务红点
for k, v in pairs(player.gameData.activity[self.ActivityType].curData.puzzleTask) do
if v.status == dataType.TaskStatus_Finish then
skynet.server.msgTips:Add(player, 112)
end
end
end
function ActivityPuzzle:BoxRedGotCheck(player)
local puzzleData = player.gameData.activity[self.ActivityType].curData
local activityId = skynet.server.activity:GetActivityInfo(player, self.ActivityType)
local cfgPuzzle = skynet.server.gameConfig:GetPlayerAllCfg(player, "JigsawPuzzle")
--盲盒按钮红点
for k , v in pairs(cfgPuzzle) do
if v.activityId == activityId and puzzleData.curLevelId == v.levelID and skynet.server.bag:GetGoodsCount(player, dataType.GoodsType_Prop, 31) >= v.puzzleFragmentNum then
if puzzleData.jigsawProgressStates[3] < 2 then
skynet.server.msgTips:Add(player, 111)
break
end
end
end
end
--注册拼图任务
taskListEvent:Register(onEventFired,"拼图任务")
skynet.server.activityPuzzle = ActivityPuzzle
return ActivityPuzzle