放一起讲是觉得这两个功能比较类似,区别是公会数据保存在数据库里
组队数据结构
服务器队伍类,组队数据仅在内存中使用,如果做成支付宝种树,叠猫猫那类持久组队,可以新建张数据表
代码语言:javascript复制function TeamMgr:Init()
self.teamlist = {}
self.singlePersion = {}
end
玩家队伍数据
代码语言:javascript复制local Team = oo.class()
local _TEAM_MEM_NUM = 5 --一个队伍最多有5个成员,包括仙君和玩家--
function Team:ctor(teamid,player,targetid)
self.teamid = teamid
self.leader = player
self.targetid = targetid
self.cfgid = math.floor(targetid / 1000)
self.index = targetid % 1000
self.isAuto = 1--是否进行自动匹配
if self.targetid == 0 then
self.isAuto = 0--是否进行自动匹配
end
self.memlist = {player}
self.xianjunlist = {}
self.levelRange = {0,1000}
--self.xianjunStar = 0
end
组队功能
组队事件
注册onJoinTeam入队和onLeaveTeam离队方法
代码语言:javascript复制function TeamPerson:ctor(player,targetid)
self.player = player
self.targetid = targetid
self.cfgid = math.floor(targetid / 1000)
end
function TeamPerson:init()
self.config = server.configCenter.TeamTargetConfig[self.cfgid]
if not self.config then
return false
end
self.m_joinTeamE = self.player:SubEvent(server.enEvent.PlayerEvnt.EVENTID_ENTITY_JION_TEAM,self.onJoinTeam,self)
self.m_leaveTeamE = self.player:SubEvent(server.enEvent.PlayerEvnt.EVENTID_ENTITY_LEAVE_TEAM,self.onLeaveTeam,self)
return true
end
--示例
function TeamPerson:onLeaveTeam(args)
if args.entityID ~= self.player.entityID then
return
end
--删除定时器
if self.del_timer then
lua_app.del_timer(self.del_timer)
self.del_timer = nil
end
end
创建队伍
代码语言:javascript复制function TeamMgr:createTeam(player,targetid)
if player.prop.teamid ~= 0 then --已经有队伍不能再次创建
return false
end
local teamid = _Cur_TeamID 1
local team = Team.new(teamid,player,targetid)
if team and team:init(true) then
_Cur_TeamID = teamid
self.teamlist[teamid] = team
else
return false
end
--触发入队事件
local args = {}
args.entityID = player.entityID --创建队伍
args.teamid = teamid
args.EventID = server.enEvent.PlayerEvnt.EVENTID_ENTITY_JION_TEAM
player:FireEvent(args.EventID,args)
local function _matchTeam()
if self.matchTime then
lua_app.del_timer(self.matchTime)
end
if next(self.singlePersion) then
self:doMatch()
end
self.matchTime = lua_app.add_timer(5000, _matchTeam)
end
if not self.matchTime then
self.matchTime = lua_app.add_timer(5000, _matchTeam)
end
--存在目标的的可以进行发送超链接
if targetid and targetid > 0 then
local info = team:getTargetInfo()
local players = {}
for _, actor in pairs(server.playerCenter:GetOnlinePlayers()) do
if actor.prop.level >= team.levelRange[1] and
actor.prop.level <= team.levelRange[2] then
table.insert(players,actor)
end
end
server.chatCenter:SendLink2SomePalyers(1320,player,players,info.activeName,info.rangeName,
{server.ChatLinkType.team,teamid,player.entityID,"申请组队"})
end
return true
end
申请加入队伍
与客户端通信协议
代码语言:javascript复制--[[
#请求加入队伍
cs_team_jointeam 17002 {
request {
teamid 0 : integer
}
}
]]
function server.cs_team_jointeam(socketid, msg)
local player = server.playerCenter:GetPlayerBySocket(socketid)
server.teamMgr:joinTeam(msg.teamid,player.entityID)
end
服务器验证队伍信息
代码语言:javascript复制function TeamMgr:joinTeam(teamid,entityID)
local player = server.gameEntityCenter:GetEntityByID(entityID)
if not player then
return false
end
local team = self.teamlist[teamid]
if not team then
--链接已经失效
server.chatCenter:sendTipMsg(1321,player.dbid)
return false
end
if player.prop.teamid ~= 0 then
server.sendErr(player, "你已经有队伍了")
return false
end
--判断是否满组队伍的要求
if not team:canJoinTeam(player) then
server.chatCenter:sendTipMsg(1322,player.dbid,tostring(team.levelRange[1]))
return false
end
if team:GetMemberCount() >= _MaxCount then
server.chatCenter:sendTipMsg(1321,player.dbid)
return false
end
return team:joinTeam(player)
end
玩家队伍类处理
代码语言:javascript复制function Team:joinTeam(player)
if player.prop.teamid ~= 0 then
return false
end
if self:GetMemberCount() >= 3 then
return false
end
--加入者在战斗中
if player.prop.status == server.enDef.entityStatus.fighting then
return false
end
--队长在战斗中
if self.leader.prop.status == server.enDef.entityStatus.fighting then
return false
end
local targetEntity = self.memlist[#self.memlist]
if not server.mapMgr:Fly(player.entityID,targetEntity.prop.mapID,targetEntity.prop.sceneID,targetEntity.prop.x,targetEntity.prop.y,true) then
return false
end
table.insert(self.memlist,player)
player.prop.teamid = self.teamid
self:resetXianJun()
self:Broadcast("sc_team_info",{data = self:packMsg()})
local args = {}
args.entityID = player.entityID --加入队伍的实体id
args.teamid = self.teamid
args.EventID = server.enEvent.PlayerEvnt.EVENTID_ENTITY_JION_TEAM
for _,mem in pairs(self.memlist) do
mem:FireEvent(args.EventID,args)
end
return true
end
邀请加入队伍
代码语言:javascript复制function TeamMgr:inviteJoinTeam(player,beinviteid)
local team = self:getTeam(player.prop.teamid)
if not team then
server.sendErr(self.player, "你还没有队伍,无法邀请别人")
return false
end
local beinviter = server.playerCenter:GetPlayerByDBID(beinviteid)
--local beinviter = server.gameEntityCenter:GetEntityByID(beinviteid)
if not beinviter or beinviter.prop.teamid ~= 0 then
server.sendErr(self.player, "被邀请的人不存在,或者被邀请者已经有队伍了")
return false
end
if not team:canJoinTeam(beinviter) then
server.chatCenter:sendTipMsg(1323,player.dbid,tostring(team.levelRange[1]))
return false
end
--通知被邀请
local msg = {}
msg.inviteid = player.dbid
msg.inviteTeamid = player.prop.teamid
msg.targetid = team.targetid
msg.inviteName = player.prop.name
beinviter:sendReq("sc_team_invite",msg)
return true
end
响应邀请
teamid 0 : integer #响应的队伍id inviteid 1 : integer #邀请者的dbid isConfirm 2 : integer #同意 1, 拒绝0
代码语言:javascript复制function TeamMgr:responeInvite(teamid,inviteid,beInviteEnityid,isconfirm)
--local inviter = server.gameEntityCenter:GetEntityByID(inviteid)
local inviter = server.playerCenter:GetPlayerByDBID(inviteid)
if not inviter or inviter.prop.teamid ~= teamid then
return false
end
local team = self.teamlist[teamid]
if not team then
return false
end
local beinviter = server.gameEntityCenter:GetEntityByID(beInviteEnityid)
if not beinviter or beinviter.prop.teamid ~= 0 then
return false
end
if not team:canJoinTeam(beinviter) then
lua_app.log_info("忙活了半天,还是不能加入队伍, 被邀请者等级不符合条件,或者队长在战斗中")
return false
end
if isconfirm == 1 then
team:joinTeam(beinviter)
return true
end
--对邀请者发送 被邀请者拒绝入队的提示
server.sendErr(inviter,beinviter.prop.name.."拒绝加入队伍")
return true
end
踢出队伍
代码语言:javascript复制function TeamMgr:kickMem(player,entityID)
local kickPlayer = server.gameEntityCenter:GetEntityByID(entityID)
if not kickPlayer then
return false
end
local teamid = player.prop.teamid
if teamid ~= kickPlayer.prop.teamid then
return false
end
local team = self.teamlist[teamid]
if not team then
return false
end
if not team:isLeader(player.entityID) then
server.sendErr(self.player, "你不是队长,没有踢人的权限")
return false
end
local ret = team:kickTeam(player,kickPlayer)
if ret then
local teamPsersion = self.singlePersion[entityID]
if teamPsersion then
teamPsersion:sendMyInfo()
end
end
return ret
end
玩家组队类踢出
代码语言:javascript复制function Team:kickTeam(leader,beKicker)
if leader.dbid ~= self.leader.dbid then
return false
end
if beKicker.prop.teamid ~= self.teamid then
return false
end
if leader.entityID ~= self.leader.entityID then
return false
end
local args = {}
args.entityID = beKicker.entityID --离开队伍的的实体id
args.EventID = server.enEvent.PlayerEvnt.EVENTID_ENTITY_LEAVE_TEAM
args.teamid = self.teamid
for _,mem in pairs(self.memlist) do
mem:FireEvent(args.EventID,args)
end
for i = 1,#self.memlist do
if self.memlist[i].entityID == beKicker.entityID then
table.remove(self.memlist,i)
break
end
end
beKicker.prop.teamid = 0
--直接向客服端发送离开队伍
local leavemsg = {}
beKicker:sendReq("sc_team_leave",leavemsg)
--重新甚至队伍的仙君信息
self:resetXianJun()
self:Broadcast("sc_team_info",{data = self:packMsg()})
end
离开队伍
代码语言:javascript复制function TeamMgr:leaveTeam(player)
local teamid = player.prop.teamid
local team = self.teamlist[teamid]
if not team then
player.prop.teamid = 0
server.sendErr(self.player, "你没有队伍,无需离队")
return false
end
local ret = team:leaveTeam(player)
if ret then
--主动离队要删除自己的自动匹配
self:deletePerson(player.entityID)
end
return ret
end
玩家组队类离开队伍
代码语言:javascript复制function Team:leaveTeam(player)
if player.prop.teamid ~= self.teamid then
return false
end
local args = {}
args.entityID = player.entityID --离开队伍的实体id
args.EventID = server.enEvent.PlayerEvnt.EVENTID_ENTITY_LEAVE_TEAM
args.teamid = self.teamid
args.preStatus = server.enDef.teamStatues.mem
if self:isLeader(player.entityID) then
args.preStatus = server.enDef.teamStatues.leader
end
for _,mem in pairs(self.memlist) do
mem:FireEvent(args.EventID,args)
end
--确定可以离队了,先清掉队伍id吧
player.prop.teamid = 0
player.prop.leaderSign = 0
--直接向客服端发送离开队伍
local leavemsg = {}
player:sendReq("sc_team_leave",leavemsg)
--战斗中允许直接离队,先这样吧
if self.leader.entityID == player.entityID then
--离队的是队长
local mem = {}
for i = 2 ,#self.memlist do
table.insert(mem,self.memlist[i])
end
self.memlist = mem
if #self.memlist > 0 then
self.leader = self.memlist[1]
self.leader.prop.leaderSign = 1
local largs = {}
largs.newLeader = self.leader.entityID --新的队长
largs.oldLeader = player.entityID --老的队长 ,此处队长可能已经不再队伍里面了
largs.EventID = server.enEvent.PlayerEvnt.EVENTID_ENTITY_BE_TEAM_LEADER
largs.teamid = self.teamid
for _,mem in pairs(self.memlist) do
mem:FireEvent(largs.EventID,largs)
end
else
--队伍解散了
server.teamMgr:deleteTeam(self.teamid)
player.prop.teamid = 0
return true
end
else
for i = 2 ,#self.memlist do
if self.memlist[i].entityID == player.entityID then
table.remove(self.memlist,i)
break
end
end
end
self:resetXianJun()
self:Broadcast("sc_team_info",{data = self:packMsg()})
end
获取组队目标下的队伍列表
代码语言:javascript复制function TeamMgr:getAndSendTeamList(player,targetid)
if not targetid then
return false
end
local msg = {}
local cfgid = math.floor(targetid / 1000)
--获取目标相同的所有,可以匹配的队伍
for teamid,team in pairs(self.teamlist) do
if team.cfgid == cfgid and team:GetMemberCount() < 3 then
local teammsg = team:packTeamShowMsg()
table.insert(msg,teammsg)
end
end
if #msg > 0 then
player:sendReq("sc_team_list",{targetid = targetid,teamlist = msg})
table.print(msg)
return true
end
end
更改组队设置
targetid 0 : integer #如果是队长该id为cfgid*1000 index ,如果是队员改id直接是 cfgid isAuto 1 : integer #设置自动匹配或者取消自动匹配
代码语言:javascript复制function TeamMgr:setAutoMatch(player,targetid,isAuto)
local teamid = player.prop.teamid
if teamid == 0 then
if not isAuto then
self:deletePerson(player.entityID)
return true
end
local teamPsersion = self.singlePersion[player.entityID]
if teamPsersion and teamPsersion.release then
teamPsersion:release()
self.singlePersion[player.entityID] = nil
end
local persion = TeamPerson.new(player,targetid)
if not persion or not persion:init() then
return false
end
self.singlePersion[player.entityID] = persion
return true
end
--如果有队伍
local team = self.teamlist[teamid]
if not team then
player.prop.teamid = 0
return false
end
if not team:isLeader(player.entityID) then
return false
end
return team:setTarget(targetid,isAuto)
end
玩家组队类设置
代码语言:javascript复制function Team:setTarget(targetid,isAuto)
if #self.memlist >= 3 then
return false
end
if self.isAuto == isAuto and self.targetid == targetid then
--没有任何变化,不用继续去处理了
return true
end
self.isAuto = isAuto
if self.targetid == targetid then
local msg = {targetid = self.targetid ,isAuto = self.isAuto}
self:Broadcast("sc_team_target", msg)
return true
end
self.targetid = targetid
local cfgid = math.floor(targetid / 1000)
local index = targetid % 1000
if self.targetid > 0 then
self.config = server.configCenter.TeamTargetConfig[cfgid]
if not self.config then
return false
end
--等级段
local range = self.config.levelrange[index]
if not range then
return false
end
if range[0] == -1 then
if index <= 1 then
return false
end
local prerange = self.config.levelrange[index -1]
local minlvl = self.player.prop.level - 5
minlvl = math.max(minlvl,prerange[0] 5)
self.levelRange[1] = minlvl
self.levelRange[2] = range[2]
else
self.levelRange[1] = range[1]
self.levelRange[2] = range[2]
end
local info = self:getTargetInfo()
local players = {}
for _, player in pairs(server.playerCenter:GetOnlinePlayers()) do
if player.prop.level >= self.levelRange[1] and
player.prop.level <= self.levelRange[2] then
table.insert(players,player)
end
end
--发送超链接
server.chatCenter:SendLink2SomePalyers(1320,self.leader,players,info.activeName,info.rangeName, {server.ChatLinkType.team,self.teamid,self.leader.entityID,"申请组队"})
else
self.levelRange = {0,1000}
self.isAuto = 0
self.config = nil
end
self.targetid = targetid
self.cfgid = cfgid
self.index = index
local msg = {targetid = self.targetid ,isAuto = self.isAuto}
--广播目标改变信息
self:Broadcast("sc_team_target",msg)
return true
end
公会基本结构
公会和组队类似不多讲了,只是数据保存在公会表中
公会数据
玩家实体信息保存公会id和活动数据
代码语言:javascript复制 { "guildid" ,"bigint(20)" ,0 ,"公会ID" },
{ "guildcontribute" ,"bigint(20)" ,0 ,"公会贡献" },
{ "guild_data" ,"mediumblob" ,{
skillinfo = {skills = {}},
fuli = {},
pray = {},
} ,"玩家公会数据" },
公会表保存公会信息
代码语言:javascript复制guild = {
columns = {
{ "dbid" ,"bigint(20)" ,0 ,"公会id" },
{ "name" ,"varchar(128)" ,"" ,"公会名称" },
{ "serverid" ,"int(11)" ,0 ,"公会创建所在服务器" },
{ "changename_count","int(11)" ,0 ,"剩余改名次数" },
{ "players" ,"mediumblob" ,{} ,"公会成员表" },
{ "level" ,"int(11)" ,0 ,"帮派等级" },
{ "notice" ,"varchar(256)" ,"" ,"帮派签名" },
{ "fund" ,"int(11)" ,0 ,"帮派资金" },
{ "fuliawardtips" ,"mediumblob" ,{} ,"福利抽奖传闻列表" },
{ "partnerswapbit" ,"mediumblob" ,{} ,"仙君碎片交换区"},
{ "partnerswaphis" ,"mediumblob" ,{} ,"仙君交换历史数据"},
},
prikey = { "dbid" },
comment = "公会表",
initdbid = "platonly",
},
公会管理类
初始加载信息,对应guild表
代码语言:javascript复制function Guild:Init(cache)
self.cache = cache
self:RefrushData()
end
function Guild:RefrushData()
self.dbid = self.cache.dbid
self.players = {}
self.admin = {}
for _, v in ipairs(self.cache.players) do
self.players[v.playerid] = v
if v.office ~= _Office.Mem then
if v.office == _Office.Leader then
self.leader = self.players[v.playerid]
end
self.admin[v.playerid] = v
end
end
self.summary = {
id = self.dbid,
level = self.cache.level,
playercount = #self.cache.players,
name = self.cache.name,
leaderinfo = self.leader,
notice = self.cache.notice
}
end
创建公会
代码语言:javascript复制function Guild:Create(data)
data.serverid = server.serverID
self.cache = server.mysqlBlob:CreateDmg(tbname,data,true)
self:RefrushData()
self.sceneid = server.mapMgr:createMap(GuildConfig.MapID, self.cache.dbid)
self.guildmapid = GuildConfig.MapID
self.guildRobberCtrl = GuildRobberCtrl.new()
self.guildRobberCtrl:Create(self.dbid, self.sceneid)
end
玩家公会类
对应数据guild_data,主管管理活动信息
代码语言:javascript复制local GuildCtrl = oo.class()
function GuildCtrl:ctor(player)
self.player = player
self.guildSkill = GuildSkill.new(player,self)
self.guildFuLi = GuildFuLi.new(player,self)
self.guildPray = GuildPray.new(player,self)
end
function GuildCtrl:onCreate()
self:onLoad()
end
function GuildCtrl:onLoad()
self.cache = self.player.cache.guild_data
self:Init(self.cache)
end
公会活动示例
代码语言:javascript复制--帮派祈愿
local GuildPray = oo.class()
local MAX_TASKID = 3
function GuildPray:ctor(player, guildctrl)
self.player = player
self.guildctrl = guildctrl
end
function GuildPray:Init(datas)
self.cache = datas.pray or {}
self.cache.offerGoods = self.cache.offerGoods or {}
self.cache.circleCount = self.cache.circleCount or 0
self.cache.iscomplete = self.cache.iscomplete or 0
self.cache.updatetime = self.cache.updatetime or 0
end
function GuildPray:onJoinGuild(guild)
local playerinfo = guild:GetPlayerInfo(self.player.dbid)
if not playerinfo then
return
end
self:Refresh()
self:SendClientMsg()
end
公会和组队功能应该也很比较有参考意义