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 Friend = oo.class() local json = require "json" Friend.UserType_AI = 1 --AI Friend.UserType_Player= 2 --用户 Friend.MsgStatus_Start = 1 --消息开始 Friend.MsgStatus_End = 2 --消息结束 Friend.MsgType_Detail = 0; --文本消息 Friend.MsgType_Friend = 1; --推荐好友消息 Friend.MsgType_Scene = 2; --场景邀请消息 Friend.MsgType_Gift = 3; --赠送礼物消息 Friend.NewsTriggerType_Dialogue = 1 --对话ID Friend.NewsTriggerType_Favorable = 2 --好感值 Friend.NewsTriggerType_Level = 3 --等级 Friend.MsgStaus_No = 1 --无状态 Friend.MsgStaus_NoClick = 2 --未点击(推荐好友、赠送礼物、场景邀请三个消息会有该状态 Friend.MsgStaus_AlreadyClick = 3 --已点击(推荐好友、赠送礼物、场景邀请点击后的状态) Friend.Unlock_FavorabilityLevel = 1 --好感等级 Friend.Unlock_Level = 2 --玩家等级 Friend.Unlock_FinishFunc = 3 --完成某功能 function Friend:Init() end --登陆初始化数据 function Friend:LoginInitData( player ) self:CheckNewMsg( player ) end --朋友圈消息列表 function Friend:MsgList( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendMsgList", c2sData.data )) local data ={} --self:CheckAddFriend( player ) self:CheckNewMsg( player ) data.msgList = self:GetMsgList( player ) s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendMsgList") s2cData.data = assert(pb.encode("S2CFriendMsgList", data)) end --朋友圈消息详情 function Friend:MsgDetail( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendMsgDetail", c2sData.data )) local data ={} local npcId = c2sData.data.npcId if not npcId then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else data = self:GetMsgDetail( player , npcId ) end s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendMsgDetail") s2cData.data = assert(pb.encode("S2CFriendMsgDetail", data)) end --朋友圈客户端发送消息 function Friend:MsgClient( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendMsgClient", c2sData.data )) local data ={} local npcId = c2sData.data.npcId local userType = c2sData.data.userType or 0 local msgId = c2sData.data.msgId local msgBranch = c2sData.data.msgBranch log.debug(string.format("玩家 %d 通用朋友圈客户端发送消息 参数 " , player.basicInfo.userID ), npcId , userType ,msgId ,msgBranch) local curNpc = player.gameData.friend[ npcId ] if not npcId or not msgId or not userType or not curNpc then log.debug(string.format("玩家 %d 通用朋友圈客户端发送消息 错误参数1" , player.basicInfo.userID )) s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local isExistMsgId = false --是否存在消息ID local segIndex = 0 local isOver = false --消息是否结束 --验证消息ID合法性 isExistMsgId , segIndex ,isOver = self:IsVaildMsg( player , npcId , userType , msgId , curNpc.lastUserType , curNpc.lastMsgId ) if not isExistMsgId then log.debug(string.format("玩家 %d 通用朋友圈客户端发送消息 错误参数2" , player.basicInfo.userID )) s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local isFirstPlayerMsg = false --第一句是否为玩家消息,这样肯定会有问题, for k, v in pairs( curNpc.msgDetail ) do if segIndex == v.detail.segIndex and 0 == #v.detail.record and userType == self.UserType_Player then isFirstPlayerMsg = true end end if isFirstPlayerMsg then s2cData.code = errorInfo.ErrorCode.ErrRequestParam log.debug(string.format("玩家 %d 通用朋友圈客户端发送消息 错误参数3" , player.basicInfo.userID )) else self:CheckNews( player , npcId , segIndex ) --检查这个ID是否存在,可能新一轮还没开始 local isExistSameId = false for k1, v1 in pairs( curNpc.msgDetail ) do if segIndex == v1.detail.segIndex then for k2, v2 in pairs( v1.detail.record ) do if userType == v2.userType and msgId == v2.msgId then isExistSameId = true end end end end --不存在这个ID,就插入进去 if not isExistSameId then for k, v in pairs( curNpc.msgDetail ) do if segIndex == v.detail.segIndex and #v.detail.record <= 10 then --把玩家的对话加入记录中 local msgStatus = self.MsgStaus_No local cfgNpcDialog = skynet.server.gameConfig:GetPlayerCurCfg( player , "NPCDialog" , msgId ) if cfgNpcDialog and 0 ~= cfgNpcDialog.notifyType then msgStatus = self.MsgStaus_NoClick if 2 == cfgNpcDialog.notifyType then curNpc.isUnlockHouse = true log.debug(string.format("玩家 %d 朋友圈 解锁NPC %d 的房间 " , player.userId , npcId)) end end --是否能解锁 table.insert( v.detail.record , { userType = userType , msgType = cfgNpcDialog.notifyType , msgId = msgId , msgBranch = msgBranch , msgStatus = msgStatus } ) log.debug(string.format("玩家 %d 朋友圈客户端发送消息 用户类型 %d 消息ID %d 消息分支 %d " , player.userId , userType ,msgId ,msgBranch )) curNpc.lastUserType = userType curNpc.lastMsgId = msgId curNpc.msgCount = curNpc.msgCount - 1 --玩家发送了消息后,计算下后面AI还有多少条数据 if self.UserType_Player == userType then curNpc.msgCount = self:GetEndMsgCount( player , npcId , msgBranch) log.debug(string.format("玩家 %d 朋友圈客户端发送消息 玩家发送 计算AI剩余条数 %d " , player.userId ,curNpc.msgCount)) end --星级+1 if isOver then v.detail.isOver = isOver curNpc.starLevel = curNpc.starLevel + 1 curNpc.lastUserType = self.UserType_AI curNpc.lastMsgId = msgId curNpc.msgCount = self:GetStartMsgCount( player , npcId ) log.debug(string.format("玩家 %d 朋友圈客户端发送消息 一轮对话结束 下一轮星级 %d 下一轮AI消息ID %d 下一轮AI消息数量 %d" , player.basicInfo.userID ,curNpc.starLevel , curNpc.lastMsgId , curNpc.msgCount)) skynet.server.levelTask:Modify( player , 36 , 1 ) skynet.server.achieveTask:Modify( player , 36 , 1) skynet.server.taskListEvent:Modify( player , 36 , 1) --计算最新的TIPS数量 self:GetMsgTipsCount( player ) player:AddExpForType( 2 ) end break end end else s2cData.code = errorInfo.ErrorCode.ErrRequestParam log.debug(string.format("玩家 %d 通用朋友圈客户端发送消息 错误参数4" , player.basicInfo.userID )) end end end end data = self:GetMsgDetail( player , npcId ) s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendMsgClient") s2cData.data = assert(pb.encode("S2CFriendMsgClient", data)) end --朋友圈消息添加好友 function Friend:AddFriend( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendMsgAddFriend", c2sData.data )) local data ={} local npcId = c2sData.data.npcId local addNpcId = c2sData.data.addNpcId local msgId = c2sData.data.msgId if not npcId or not msgId then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local npcInfo = player.gameData.friend[ npcId ] local isExistMsg = false for k1, v1 in pairs( npcInfo.msgDetail ) do --找到对应的消息 for k2, v2 in pairs( v1.detail.record ) do if msgId == v2.msgId and self.MsgType_Friend == v2.msgType and self.MsgStaus_NoClick == v2.msgStatus then isExistMsg = true v2.msgStatus = self.MsgStaus_AlreadyClick --添加好友 self:InitNpc( player , addNpcId ) data = self:GetMsgDetail( player , npcId ) data.msgId = msgId data.addNpcId = addNpcId log.debug(string.format("玩家 %d 朋友圈 添加好友成功 参数 %d %d %d" , player.userId , npcId, addNpcId , msgId )) break end end if isExistMsg then break end end if not isExistMsg then s2cData.code = errorInfo.ErrorCode.NoExistFriendMsg end end s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendMsgAddFriend") s2cData.data = assert(pb.encode("S2CFriendMsgAddFriend", data)) end --朋友圈消息获取礼物 function Friend:GetGift( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendMsgGetGift", c2sData.data )) local data ={} local npcId = c2sData.data.npcId local msgIndex = c2sData.data.msgIndex local msgId = c2sData.data.msgId if not npcId or not msgIndex or not msgId then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local npcInfo = player.gameData.friend[ npcId ] local isExistMsg = false for k1, v1 in pairs( npcInfo.msgDetail ) do --找到对应的消息 --if msgIndex == v1.detail.segIndex then for k2, v2 in pairs( v1.detail.record ) do if msgId == v2.msgId and self.MsgType_Gift == v2.msgType and self.MsgStaus_NoClick == v2.msgStatus then isExistMsg = true v2.msgStatus = self.MsgStaus_AlreadyClick --赠送礼物 local cfgNpcDialog = skynet.server.gameConfig:GetPlayerCurCfg( player , "NPCDialog" , msgId ) local rewardId = cfgNpcDialog.notifyValue if rewardId > 0 then local eventId = pb.enum("EnumMoneyChangeEventID","EventID_63") player:GiveReward( rewardId ,eventId) end skynet.server.achieveTask:Modify( player , 57 , 1 ) skynet.server.npcTask:Modify( player , 57 , 1 ) skynet.server.taskListEvent:Modify( player , 57 , 1 ) data = self:GetMsgDetail( player , npcId ) data.msgId = msgId break end end --end if isExistMsg then break end end if not isExistMsg then s2cData.code = errorInfo.ErrorCode.NoExistFriendMsg end end s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendMsgGetGift") s2cData.data = assert(pb.encode("S2CFriendMsgGetGift", data)) end --朋友圈消息进入场景 function Friend:EnterScene( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendMsgEnterScene", c2sData.data )) local data ={} local npcId = c2sData.data.npcId if not npcId then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else data.npcId = npcId data.friend = self:GetFriendDetail( player , npcId ) local npcInfo = player.gameData.friend[ npcId ] npcInfo.scene.enterCount = npcInfo.scene.enterCount + 1 --场景进入次数 npcInfo.scene.enterTime = skynet.GetTime() --场景进入时间 skynet.server.levelTask:Modify( player , 50 , 1 ) skynet.server.taskListEvent:Modify( player , 50 , 1 ) end s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendMsgEnterScene") s2cData.data = assert(pb.encode("S2CFriendMsgEnterScene", data)) end --朋友圈消息离开场景 function Friend:LeaveScene( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendMsgLeaveScene", c2sData.data )) local data ={} local npcId = c2sData.data.npcId if not npcId or not player.gameData.friend[ npcId ] then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local npcInfo = player.gameData.friend[ npcId ] npcInfo.scene.enterCount = npcInfo.scene.enterCount + 1 --场景进入次数 if 0 ~= npcInfo.scene.enterTime then --计算停留时间 local stayTime = skynet.GetTime() - npcInfo.scene.enterTime npcInfo.scene.stayTime = npcInfo.scene.stayTime + stayTime npcInfo.scene.enterTime = 0 end end s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendMsgLeaveScene") s2cData.data = assert(pb.encode("S2CFriendMsgLeaveScene", data)) end --好友列表展示 function Friend:ListShow( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendListShow", c2sData.data )) local data ={} data.friends = {} for k, v in pairs( player.gameData.friend ) do table.insert( data.friends , self:GetFriendDetail( player , v.npcId )) end skynet.server.msgTips:Reduce( player , 42 ) s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendListShow") s2cData.data = assert(pb.encode("S2CFriendListShow", data)) end --礼物背包 function Friend:GiftBag( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendGiftBag", c2sData.data )) local data ={} local npcId = c2sData.data.npcId local goodsType = c2sData.data.goodsType if not npcId or not goodsType then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local bagItem = {} local allGoods = {} local curNpc = player.gameData.friend[ npcId ] local isGiveGoods = function( goodsType , goodsId ) for k, v in pairs( curNpc.giftGoods ) do if v.goodsType == goodsType and v.goodsId == goodsId then return true end end return false end --是否存在商品 local isExistGoods = function( goodsId ) goodsId = skynet.server.gameConfig:RestoreGeneralID( goodsId ) for k, v in pairs( allGoods ) do if goodsId == v.id then return true end end return false end if dataType.GoodsType_Furniture == goodsType then self:GetFeatureGoods( player ,npcId ,goodsType , allGoods ) --获取满足特征的商品 local unUsedBag = skynet.server.bag:GetUnusedGoodsInfo( player , goodsType ) --找到未使用的才能赠送 for k, v in pairs( unUsedBag ) do if v.count > 0 then --未赠送过并且满足条件的商品才加入 if not isGiveGoods( v.type , v.id ) and isExistGoods( v.id ) then --符合特征的商品才去查看 --local maxCount = skynet.server.house:GetCurFurnitureMaxCount( player , v.type , v.id ) --maxCount = v.count - maxCount table.insert( bagItem , { type = v.type , id = v.id , count = v.count > 0 and v.count or 0 , gainTime = v.gainTime }) end end end elseif dataType.GoodsType_Plant == goodsType then for k, v in pairs( player.gameData.bag ) do if goodsType == v.type and not isGiveGoods( v.type , v.id ) then table.insert( bagItem , { type = v.type , id = v.id , count = v.count , gainTime = v.gainTime }) end end end data.npcId = npcId data.goodsType = goodsType data.bagItem = bagItem end s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendGiftBag") s2cData.data = assert(pb.encode("S2CFriendGiftBag", data)) end --赠送礼物 function Friend:GiftGive( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendGiftGive", c2sData.data )) local data ={} local npcId = c2sData.data.npcId local goodsInfo = c2sData.data.goodsInfo if not npcId or not goodsInfo then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local goodsType = goodsInfo.goodsType local goodsId = goodsInfo.goodsId --检查礼物是否合法 local cfgNpc = skynet.server.gameConfig:GetPlayerCurCfg( player , "NPC" , npcId ) local cfgGoods = {} if not cfgNpc then s2cData.code = errorInfo.ErrorCode.NoExistCfg else local featureCount = 0 --特征满足次数 local favorabilityValue = 0 local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue") --根据商品类型获取配置 if dataType.GoodsType_Furniture == goodsType then local tmpGoodsId = skynet.server.gameConfig:RestoreGeneralID( goodsId ) cfgGoods = skynet.server.gameConfig:GetPlayerCurCfg( player , "Furniture" , tmpGoodsId ) for k1, v1 in pairs( cfgNpc.featureTag ) do for k2, v2 in pairs( cfgGoods.featureTag ) do if v1 == v2 then featureCount = featureCount + 1 end end end favorabilityValue = featureCount * cfgSValue.relationValueTagGift elseif dataType.GoodsType_Plant == goodsType then favorabilityValue = cfgSValue.relationValuePlantGift featureCount = 1 end if 0 == featureCount then s2cData.code = errorInfo.ErrorCode.NoSameFeatureGoods else local removeCount = 1 local isSuc = skynet.server.bag:IsRemoveGoods( player , goodsType , goodsId , removeCount ) if not isSuc then s2cData.code = errorInfo.ErrorCode.NoEnoughGoods else --这里开是合法的商品 local curNpc = player.gameData.friend[ npcId ] --增加好感度 self:AddFavorability( player, curNpc , favorabilityValue) table.insert( curNpc.giftGoods , { goodsType = goodsType , goodsId = goodsId }) player:AddExpForType( 3 ) curNpc.giveFriendGift = curNpc.giveFriendGift + 1 --扣除商品 skynet.server.bag:RemoveGoods( player , goodsType , goodsId , removeCount ) skynet.server.levelTask:Modify( player , 17, 1 ) skynet.server.dailyTask:Modify( player , 17 , 1) skynet.server.achieveTask:Modify( player , 17 , 1 ) skynet.server.npcTask:Modify( player , 17 , 1 ) skynet.server.taskListEvent:Modify( player , 20 , 1 ) skynet.server.taskListEvent:Modify( player , 17 , 1 ) data.npcId = npcId data.goodsInfo = {} data.goodsInfo.goodsType = goodsType data.goodsInfo.goodsId = goodsId data.goodsInfo.goodsCount = 1 data.friends = self:GetFriendDetail( player , npcId ) end end end end s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendGiftGive") s2cData.data = assert(pb.encode("S2CFriendGiftGive", data)) end --友圈动态 function Friend:NewsShow( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendNewsShow", c2sData.data )) local data ={} data.news = {} for k1, v1 in pairs( player.gameData.friend ) do for k2, v2 in pairs( v1.news ) do table.insert( data.news , { npcId = v1.npcId , newsId = v2.id , isLike = v2.isLike , updateTime = v2.updateTime}) end end --降序 table.sort(data.news,function (a,b) return a.updateTime > b.updateTime end) skynet.server.msgTips:Reduce( player , 43 ) s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendNewsShow") s2cData.data = assert(pb.encode("S2CFriendNewsShow", data)) end --友圈点赞 function Friend:LikeNews( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendLikeNews", c2sData.data )) local data ={} data.news ={} local news = c2sData.data.news if not news then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local curNpc = player.gameData.friend[ news.npcId ] if not curNpc then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local isExist = false for k, v in pairs( curNpc.news ) do if news.newsId == v.id then --v.isLike = news.isLike if v.isLike then v.isLike = false else v.isLike = true end data.news.npcId = news.npcId data.news.newsId = news.newsId data.news.isLike = v.isLike isExist = true break end end if not isExist then s2cData.code = errorInfo.ErrorCode.ErrRequestParam end end end s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendLikeNews") s2cData.data = assert(pb.encode("S2CFriendLikeNews", data)) end --友圈互动 function Friend:Interact( player , c2sData , s2cData ) c2sData.data = assert(pb.decode("C2SFriendInteract", c2sData.data )) local data ={} local npcId = c2sData.data.npcId if not npcId then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else local curNpc = player.gameData.friend[ npcId ] if not curNpc then s2cData.code = errorInfo.ErrorCode.ErrRequestParam else if not curNpc.isInteract then curNpc.isInteract = true --增加好感度 self:AddFavorability( player, curNpc , 1 ) end data.friend = self:GetFriendDetail( player , npcId ) end end s2cData.cmd = pb.enum("MsgType","CMD_S2C_FriendInteract") s2cData.data = assert(pb.encode("S2CFriendInteract", data)) end --检查是否有新消息 function Friend:CheckNewMsg( player ) if not player:IsUnlockSystem( dataType.UnlockSystem_Friend ) then return end local cfgPlayerDialog = skynet.server.gameConfig:GetPlayerAllCfg( player , "PlayerDialog") for k, v in pairs( cfgPlayerDialog ) do local npcId = v.NPCId local curNpc = player.gameData.friend[ npcId ] if curNpc and self:IsUnlockDialog( player , v , v.segIndex ) then local detail = { segIndex = v.segIndex , isOver = false , record = {} } table.insert( curNpc.msgDetail , { msgType = self.MsgType_Detail , msgIndex = curNpc.curMsgIndex , detail = detail} ) skynet.server.msgTips:AddNoNotice( player , 15 ) end end end --初始化新NPC function Friend:InitNpc( player , npcId ) if not player.gameData.friend[ npcId ] then local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue") player.gameData.friend[ npcId ] = {} local curNpc = player.gameData.friend[ npcId ] curNpc.npcId = npcId curNpc.starLevel = 0 --星级 curNpc.msgCount = self:GetStartMsgCount( player , npcId ) curNpc.lastUserType = self.UserType_AI curNpc.lastMsgId = self:GetLastInitMsgID( player , npcId ) curNpc.isMsgTips = false curNpc.msgDetail = {} --消息 curNpc.isUnlockHouse = false --是否解锁房间 curNpc.isInteract = false curNpc.favorabilityLevel = 0 --好感等级 curNpc.favorabilityValue = 0 --好感值 curNpc.giftGoods = {} --玩家赠与过的家具 curNpc.scene = {} --场景信息 curNpc.scene.enterCount = 0 --场景进入次数 curNpc.scene.enterTime = 0 --进入时间 curNpc.scene.stayTime = 0 --场景停留时间 curNpc.news = {} curNpc.giveFriendGift = 0 --赠送给好友的礼物数量 self:CheckNewMsg( player ) skynet.server.msgTips:Reset( player , 42 ) skynet.server.msgTips:Add( player , 42 ) log.debug(string.format("玩家 %d 朋友圈 初始化NPC %d" , player.userId , npcId )) end end --新消息生成 function Friend:NewMsg( npcId , segIndex ) local record = {} local lastMsgId = 0 local cfgNPCDialog = skynet.server.gameConfig.NPCDialog for k, v in pairs( cfgNPCDialog ) do if npcId == v.NPCId and segIndex == v.segIndex then table.insert( record , { userType = self.UserType_AI , msgId = v.id } ) if 1 == v.triggerId then lastMsgId = v.id break end end end return record,lastMsgId end --是否存在对话 function Friend:IsExistDialog( player , npcId , segIndex ) local npcInfo = player.gameData.friend[ npcId ] if npcInfo then for npcId, v in pairs( npcInfo.msgDetail ) do if self.MsgType_Detail == v.msgType and segIndex == v.detail.segIndex then return true end end end return false end --是否有消息提示 function Friend:IsExistMsgTips( player , npcId ) local npcInfo = player.gameData.friend[ npcId ] if npcInfo then for k, v in pairs( npcInfo.msgDetail ) do --有消息没有结束 if self.MsgType_Detail == v.msgType and false == v.detail.isOver then return true end end end return false end --获取朋友圈消息列表 function Friend:GetMsgList( player ) local data = {} for k, v in pairs( player.gameData.friend ) do table.insert( data , { npcId = k , starLevel = v.favorabilityLevel , msgCount = v.msgCount ,lastUserType = v.lastUserType , lastMsgId = v.lastMsgId , isMsgTips = self:IsExistMsgTips( player , k)}) end return data end --获取朋友圈消息详情 function Friend:GetMsgDetail( player , npcId ) local data = {} data.npcId = npcId data.msgDetail = {} local count = 0 --没有结束的只能有一条发给客户端 local npcInfo = player.gameData.friend[ npcId ] if npcInfo then for k, v in pairs(npcInfo.msgDetail) do if self.MsgType_Detail == v.msgType and count < 1 then table.insert( data.msgDetail , v.detail) if not v.detail.isOver then count = count+ 1 end end end end return data end --获取初始化的消息ID function Friend:GetLastInitMsgID( player , npcId ) --local segIndex =player.gameData.friend[ npcId ].curMsgIndex local startSegIndex = 1 --[[if 1 == npcId then startSegIndex = 13 end]] local cfgNPCDialog = skynet.server.gameConfig:GetPlayerAllCfg( player , "NPCDialog") for k, v in pairs( cfgNPCDialog ) do --if npcId == v.NPCId and segIndex == v.segIndex and 1 == v.beginOrEnd then if npcId == v.NPCId and 1 == v.beginOrEnd and startSegIndex == v.segIndex then return v.id end end end --获取最新开始消息ID function Friend:GetLastStartMsgID( player , npcId , segIndex ) local cfgNPCDialog = skynet.server.gameConfig:GetPlayerAllCfg( player , "NPCDialog") for k, v in pairs( cfgNPCDialog ) do if npcId == v.NPCId and 1 == v.beginOrEnd and segIndex == v.segIndex then return v.id end end end --获取最新的消息ID function Friend:GetStartMsgCount( player , npcId ) local id1,id2 =0,0 local startSegIndex = 1 --[[if 1 == npcId then startSegIndex = 13 end]] --local segIndex =player.gameData.friend[ npcId ].curMsgIndex local cfgNPCDialog = skynet.server.gameConfig:GetPlayerAllCfg( player , "NPCDialog") for k, v in pairs( cfgNPCDialog ) do --if npcId == v.NPCId and segIndex == v.segIndex then if npcId == v.NPCId and startSegIndex == v.segIndex then if 1 == v.beginOrEnd then id1 = v.id end if 1 == v.triggerId then id2 = v.id end end end return (id2 - id1) + 1 end --获取最新的消息ID function Friend:GetEndMsgCount( player , npcId , msgBranch ) local count = 0 local segIndex =player.gameData.friend[ npcId ].starLevel + 1 local cfgNPCDialog = skynet.server.gameConfig:GetPlayerAllCfg( player , "NPCDialog") for k, v in pairs( cfgNPCDialog ) do if npcId == v.NPCId and segIndex == v.segIndex and msgBranch == v.branch then count = count + 1 end end return count end --是否有效的消息 function Friend:IsVaildMsg( player , npcId , userType , curMsgId , lastUserType , lastMsgId ) local isExistMsgId = false --是否存在消息ID local segIndex = 0 local isOver = false --消息是否结束 local isCheck = true --是否开记检测 这个功能复杂,线上会先10%的检测 if isCheck and self.UserType_AI == lastUserType then local cfgLastNPCDialog = skynet.server.gameConfig:GetCurCfg("NPCDialog" , lastMsgId ) if not cfgLastNPCDialog then log.warning(string.format("玩家 %d 友圈检测消息出错 NPCDialog找不到配置 %d", player.userId , lastMsgId or 0)) return isExistMsgId ,segIndex ,isOver end --如果上一条未触发玩家对话,那么这一条肯定不是玩家对话,需要报错返回 --[[ if 0 == cfgLastNPCDialog.triggerId and userType == self.UserType_Player then log.warning(string.format("玩家 %d 友圈检测消息出错1 消息不对", player.userId )) return isExistMsgId ,segIndex ,isOver end ]] --如果上一条触发玩家对话,则当前消息不可能是AI消息,需要报错返回 if 1 == cfgLastNPCDialog.triggerId and userType == self.UserType_AI and 1 ~= cfgLastNPCDialog.beginOrEnd then log.warning(string.format("玩家 %d 友圈检测消息出错2 消息不对", player.userId )) return isExistMsgId ,segIndex ,isOver end elseif isCheck and self.UserType_Player == lastUserType then local cfgPlayerDialog = skynet.server.gameConfig:GetCurCfg("PlayerDialog" , lastMsgId ) if not cfgPlayerDialog then log.warning(string.format("玩家 %d 友圈检测消息出错 PlayerDialog找不到配置 %d", player.userId , lastMsgId or 0)) return isExistMsgId ,segIndex ,isOver end --如果上一条是玩家对话,则当前消息不可能是又是玩家对话,需要报错返回 if userType == self.UserType_Player then log.warning(string.format("玩家 %d 友圈检测消息出错3 消息不对", player.userId )) return isExistMsgId ,segIndex ,isOver end end if self.UserType_AI == userType then local cfgNPCDialog = skynet.server.gameConfig:GetPlayerAllCfg( player , "NPCDialog") for k, v in pairs( cfgNPCDialog ) do if npcId == v.NPCId and curMsgId == v.id then isExistMsgId = true segIndex = v.segIndex if v.beginOrEnd == self.MsgStatus_End then isOver = true end end end elseif self.UserType_Player == userType then local cfgPlayerDialog = skynet.server.gameConfig:GetPlayerAllCfg( player , "PlayerDialog") for k, v in pairs( cfgPlayerDialog ) do if npcId == v.NPCId and curMsgId == v.id then isExistMsgId = true segIndex = v.segIndex end end end return isExistMsgId ,segIndex ,isOver end --获取消息提示数量 function Friend:GetMsgTipsCount( player ) skynet.server.msgTips:Reset( player , 15 ) for k1, v1 in pairs( player.gameData.friend ) do local isTips = false for k2, v2 in pairs( v1.msgDetail ) do if self.MsgType_Detail == v2.msgType and false == v2.detail.isOver then isTips = true break end end if isTips then skynet.server.msgTips:Add( player , 15 ) end end end --检查是不是有新的朋友圈消息 function Friend:CheckNews( player , npcId , segIndex ) local cfgNpcNews = skynet.server.gameConfig:GetPlayerAllCfg( player , "NpcNews") for k, v in pairs( cfgNpcNews ) do if npcId == v.npcId and segIndex == v.typeValue then if self.NewsTriggerType_Dialogue == v.type then self:AddNews( player , npcId , v.id) elseif self.NewsTriggerType_Favorable == v.type then elseif self.NewsTriggerType_Level == v.type then end end end end --新增朋友圈消息 function Friend:AddNews( player , npcId , newsId ) local curNews = player.gameData.friend[ npcId ].news local isExist = false for k, v in pairs( curNews ) do if newsId == v.id then isExist = true break end end if not isExist then table.insert( curNews , { id = newsId , isLike = false , updateTime = skynet.GetTime()}) skynet.server.msgTips:Reset( player , 43 ) skynet.server.msgTips:Add( player , 43 ) skynet.server.npcTask:Modify( player , 95 , 1 ) skynet.server.taskListEvent:Modify( player , 95 , 1 ) end end --获取特征商品 function Friend:GetFeatureGoods( player , npcId , goodsType , allGoods) local cfgNpc = skynet.server.gameConfig:GetPlayerCurCfg( player , "NPC" , npcId ) local cfgGoods = {} --符合当前NPC的商品 --根据商品类型获取配置 if dataType.GoodsType_Furniture == goodsType then cfgGoods = skynet.server.gameConfig:GetPlayerAllCfg( player , "Furniture") end --从配置中查找符合特征的商品 for k1, v1 in pairs( cfgNpc.featureTag ) do --当前NPC特征 for k2, v2 in pairs( cfgGoods ) do for k3, v3 in pairs( v2.featureTag ) do if v1 == v3 then table.insert( allGoods , { id = v2.id }) break end end end end end --获取朋友详情 function Friend:GetFriendDetail( player , npcId ) local friends = {} for k1, v1 in pairs( player.gameData.friend ) do if npcId == v1.npcId then friends.id = npcId friends.favorabilityLevel = v1.favorabilityLevel friends.favorabilityValue = v1.favorabilityValue friends.isUnlockHouse = v1.isUnlockHouse friends.furnitures = {} friends.isInteract = v1.isInteract for k2, v2 in pairs(v1.giftGoods) do if dataType.GoodsType_Furniture == v2.type then table.insert(friends.furnitures , v2.id) end end break end end return friends end --增加好感度 function Friend:AddFavorability( player, curNpc , count ) local data = {} data.preFriend = self:GetFriendDetail( player , curNpc.npcId ) --改变前 --11级后就不再增加好感度 if curNpc.favorabilityLevel >= 11 then return end local cfgNPCFavorability = skynet.server.gameConfig:GetPlayerAllCfg( player , "NPCFavorability") local cfgOne = nil for k, v in pairs( cfgNPCFavorability ) do if curNpc.favorabilityLevel == v.relationLevel then cfgOne = v break end end if not cfgOne then return end --增加好感值 curNpc.favorabilityValue = curNpc.favorabilityValue + count --好感度升级 if curNpc.favorabilityValue >= cfgOne.targetValue then curNpc.favorabilityLevel = curNpc.favorabilityLevel + 1 curNpc.favorabilityValue = curNpc.favorabilityValue - cfgOne.targetValue --最大只有11级 if curNpc.favorabilityLevel >= 11 then curNpc.favorabilityLevel = 11 else self:CheckNewMsg( player ) if 4 == curNpc.npcId then skynet.server.levelTask:Modify( player , 56 , 1 , 7 ) skynet.server.taskListEvent:Modify( player , 56 , 1 ) elseif 6 == curNpc.npcId then skynet.server.levelTask:Modify( player , 56 , 1 , 8 ) skynet.server.taskListEvent:Modify( player , 56 , 1 ) elseif 7 == curNpc.npcId then skynet.server.levelTask:Modify( player , 56 , 1 , 9 ) skynet.server.taskListEvent:Modify( player , 56 , 1 ) elseif 9 == curNpc.npcId then skynet.server.levelTask:Modify( player , 56 , 1 , 11 ) skynet.server.taskListEvent:Modify( player , 56 , 1 ) end skynet.server.npcTask:Modify( player , 56 , 1 ) skynet.server.taskListEvent:Modify( player , 56 , 1 ) end end data.friend = self:GetFriendDetail( player , curNpc.npcId ) --改变后 skynet.server.gameServer:SendMsgToUser( player.userId , "CMD_S2C_FriendFavorabilityChange" , data ) end --检查是不是有好友没有添加 function Friend:CheckAddFriend( player ) for k1, v1 in pairs( player.gameData.friend ) do for k2, v2 in pairs( v1.msgDetail ) do for k3, v3 in pairs( v2.detail.record ) do if self.MsgType_Friend == v3.msgType and self.MsgStaus_NoClick == v3.msgStatus then v3.msgStatus = self.MsgStaus_AlreadyClick local cfgNpcDialog = skynet.server.gameConfig:GetPlayerCurCfg( player , "NPCDialog" , v3.msgId ) local addNpcId = cfgNpcDialog.notifyValue --添加好友 self:InitNpc( player , addNpcId ) log.debug(string.format("玩家 %d 朋友圈 自动添加好友 %d 成功" , player.userId , addNpcId )) break end end end end end --是否解锁对话 function Friend:IsUnlockDialog( player , cfgOnePlayerDialog , segIndex ) local npcId = cfgOnePlayerDialog.NPCId if 0 == cfgOnePlayerDialog.unlockType then return false end --存在对话就返回 if self:IsExistDialog( player , npcId , segIndex ) then return false end local level = player.gameData.level local curNpc = player.gameData.friend[ npcId ] local isAdd = false if curNpc then --到达指定等级就解锁对话 if 1 == cfgOnePlayerDialog.unlockType and cfgOnePlayerDialog.unlockValue <= curNpc.favorabilityLevel then isAdd = true elseif 2 == cfgOnePlayerDialog.unlockType and cfgOnePlayerDialog.unlockValue <= level then isAdd = true elseif 3 == cfgOnePlayerDialog.unlockType then local cfgSValue = skynet.server.gameConfig:GetPlayerAllCfg( player , "SValue") local cfgCuisineMenu = skynet.server.gameConfig:GetPlayerAllCfg( player , "CuisineMenu") local count = 0 if 1 == cfgOnePlayerDialog.unlockValue then --在植物小铺出售n次植物 count = cfgSValue.flowerShopSell local shopType = dataType.ShopType_Plant local sellCount = player.gameData.shop[ shopType ].sellCount if sellCount >= count then isAdd = true end elseif 2 == cfgOnePlayerDialog.unlockValue then --地图花店解锁 if skynet.server.map:IsUnlock( player , 2 ) then isAdd = true end elseif 3 == cfgOnePlayerDialog.unlockValue then --言叶小屋解锁 if level >= cfgSValue.npcYYHouseUnlockLvl then isAdd = true end elseif 4 == cfgOnePlayerDialog.unlockValue and player:IsUnlockSystem( dataType.UnlockSystem_CoffeeShop ) then --玩家在咖啡店完成n次材料合成 count = cfgSValue.coffeeMaterialMerge local shopType = dataType.ShopType_Coffee local mergeCount = player.gameData.shop[ shopType ].mergeCount if mergeCount >= count then isAdd = true end elseif 5 == cfgOnePlayerDialog.unlockValue and player:IsUnlockSystem( dataType.UnlockSystem_CoffeeShop ) then --玩家在咖啡店收集n种新咖啡 count = cfgSValue.coffeeNewComplete local shopType = dataType.ShopType_Coffee local coffeesCount = #player.gameData.shop[ shopType ].coffees if coffeesCount >= count then isAdd = true end elseif 6 == cfgOnePlayerDialog.unlockValue and player:IsUnlockSystem( dataType.UnlockSystem_StyleRoom ) then --玩家在造型室完成n次阶段设计 count = cfgSValue.styleProgressComplete local shopType = dataType.ShopType_Style local curStyleId = player.gameData.shop[ shopType ].curStyleId if curStyleId > count then isAdd = true end elseif 7 == cfgOnePlayerDialog.unlockValue and player:IsUnlockSystem( dataType.UnlockSystem_CuisineShop ) then --玩家在料理店解锁1道隐藏料理 --等配置 count = 1 local shopType = dataType.ShopType_Cuisine local attemptCount = 0 --玩家解锁隐藏料理的数量 for k ,v in pairs(player.gameData.shop[ shopType ].cuisineInfos) do if v.status == 1 and cfgCuisineMenu[ v.id ].foodType == 2 then attemptCount = attemptCount + 1 end end if attemptCount >= count then isAdd = true end elseif 8 == cfgOnePlayerDialog.unlockValue and player:IsUnlockSystem( dataType.UnlockSystem_CuisineShop ) then --玩家在料理店完成4级常规料理 local shopType = dataType.ShopType_Cuisine if player.gameData.shop[ shopType ].menuInfos[ 4 ].status > 0 then isAdd = true end elseif 9 == cfgOnePlayerDialog.unlockValue and player:IsUnlockSystem( dataType.UnlockSystem_FishShop ) then --玩家解锁所有鱼竿 local shopType = dataType.ShopType_Fish local isFinish = true for k,v in pairs(player.gameData.shop[ shopType ].fishingRodInfos) do if v.status == 0 then isFinish = false end end --isAdd = isFinish elseif 10 == cfgOnePlayerDialog.unlockValue then --完成小家拜访 if curNpc.scene.enterCount >= 1 then isAdd = true end elseif 11 == cfgOnePlayerDialog.unlockValue then --搬至仕居 local curHouse = player.gameData.house[1] if curHouse and not curHouse.isFirstEnter then isAdd = true end elseif 12 == cfgOnePlayerDialog.unlockValue then --搬至晨曦小筑 local curHouse = player.gameData.house[2] if curHouse and not curHouse.isFirstEnter then isAdd = true end elseif 13 == cfgOnePlayerDialog.unlockValue then --搬至两室标间 local curHouse = player.gameData.house[3] if curHouse and not curHouse.isFirstEnter then isAdd = true end elseif 14 == cfgOnePlayerDialog.unlockValue then --在宠物店完成所有课程 local petShop = player.gameData.shop[dataType.ShopType_PetShop] local isTrue = true for k, v in pairs(petShop.courseType) do if petShop.petStudy[v].studyLvl == 4 and petShop.petStudy[v].studyStage == 5 and petShop.petStudy[v].studyExp == 40000 then else isTrue = false end end isAdd = isTrue elseif 15 == cfgOnePlayerDialog.unlockValue then --在恋家置业购买LOFT if skynet.server.house:IsBuyHouse( player , 7 ) then isAdd = true end elseif 16 == cfgOnePlayerDialog.unlockValue and player:IsUnlockSystem( dataType.UnlockSystem_PetShop ) then --在宠物店完成所有魔法课程 local petShop = player.gameData.shop[dataType.ShopType_PetShop] if petShop.petStudy[3].studyLvl == 4 and petShop.petStudy[3].studyStage == 5 and petShop.petStudy[3].studyExp == 40000 then isAdd = true end elseif 17 == cfgOnePlayerDialog.unlockValue and player:IsUnlockSystem( dataType.UnlockSystem_PetShop ) then --在宠物店完成所有体育课程 local petShop = player.gameData.shop[dataType.ShopType_PetShop] if petShop.petStudy[2].studyLvl == 4 and petShop.petStudy[2].studyStage == 5 and petShop.petStudy[2].studyExp == 40000 then isAdd = true end elseif 18 == cfgOnePlayerDialog.unlockValue and player:IsUnlockSystem( dataType.UnlockSystem_PetShop ) then --在宠物店完成所有语言课程 local petShop = player.gameData.shop[dataType.ShopType_PetShop] if petShop.petStudy[1].studyLvl == 4 and petShop.petStudy[1].studyStage == 5 and petShop.petStudy[1].studyExp == 40000 then isAdd = true end end elseif 4 == cfgOnePlayerDialog.unlockType and skynet.server.map:IsVisitMap( player , cfgOnePlayerDialog.unlockValue ) then isAdd = true elseif 5 == cfgOnePlayerDialog.unlockType and curNpc.giveFriendGift >= cfgOnePlayerDialog.unlockValue then isAdd = true elseif 6 == cfgOnePlayerDialog.unlockType and self:IsExistDialog( player , npcId , 1 ) and skynet.server.birthday:IsUnlockNpcDialog( player ) then --生日解锁对话 NPC必须要解锁1这个对话 isAdd = true end else return false end return isAdd end --检查解锁NPC function Friend:CheckUnlockNpc( player ) local level = player.gameData.level local cfgNPC = skynet.server.gameConfig:GetPlayerAllCfg( player , "NPC") for k, v in pairs( cfgNPC ) do if 1 == v.unlockType and level == v.unlockValue then self:InitNpc( player , v.id ) end end end skynet.server.friend = Friend return Friend