package player import ( "f1-game/internal/code" "f1-game/internal/constant" "f1-game/internal/data" nameLocal "f1-game/internal/name/local" "f1-game/internal/pb" "f1-game/internal/types" "f1-game/nodes/game/internal/db" dbLineup "f1-game/nodes/game/internal/db/data/lineup" "f1-game/nodes/game/player/lineup" cslice "github.com/cherry-game/cherry/extend/slice" cproto "github.com/cherry-game/cherry/net/proto" ) func (p *actorPlayer) initLineup() { p.Local().Register(nameLocal.Player_LineupUp, p.lineupUp) p.Local().Register(nameLocal.Player_LineupLeave, p.lineupLeave) p.Local().Register(nameLocal.Player_LineupChange, p.lineupChange) p.Local().Register(nameLocal.Player_LineupAdjust, p.lineupAdjust) } // lineupUp 阵容英雄上阵 func (p *actorPlayer) lineupUp(session *cproto.Session, req *pb.LineupUpRequest) { var ( heroTable = p.HeroTable() teamTable = p.TeamTable() heroGUID = req.HeroGUID lineupType = req.LineupType lineupID = req.LineupID index = req.Index ) if !constant.CheckLineupTypeValid(lineupType) { p.ResponseCode(session, code.TeamLineupTypeError) return } // 检测上阵位置是否正确 if !constant.ValidateLineupMemberIndex(index) { p.ResponseCode(session, code.TeamIndexError) return } // 判断当前英雄是否已上阵 if exist := teamTable.LineupMap.CheckHeroAlreadyUp(heroGUID); exist { p.ResponseCode(session, code.TeamHeroAlreadyUp) return } heroEntity, ok := heroTable.Heroes.Get(heroGUID) if !ok { p.ResponseCode(session, code.HeroNotExist) return } if _, ok = data.HeroTeam.Get(lineupID); !ok { p.ResponseCode(session, code.ConfigNotFound_HeroTeam) return } lineups, found := teamTable.LineupMap.GetLineups(lineupType) if !found { p.Warn("[lineupUp] lineupType not found %d", lineupType) p.ResponseCode(session, code.TeamLineupNotUnlock) return } // 检测是否上阵相同英雄 if p.checkLineupSameHero(heroTable, lineups, 0, 0, lineupID, index, heroEntity.HeroID) { p.ResponseCode(session, code.TeamAlreadySameHero) return } // 获取阵容数据 lineup, found := lineups.GetLineup(lineupID) if !found { p.ResponseCode(session, code.TeamNotUnlock) return } // 获取上阵英雄数据 lineupMember, found := lineup.GetLineupMember(index) if !found { // 上阵人数已达上限 if lineup.IsLineupMemberLimit() { p.ResponseCode(session, code.TeamMemberLimit) return } lineup.AddLineupMember(index, heroGUID) } else { lineupMember.HeroGUID = heroGUID } teamTable.Save2Queue() // 更新阵容羁绊列表 p.updateLineupFetterList(lineup) proto := lineup.ToProto() resp := &pb.LineupInfo{ LineupType: lineupType, Lineup: &proto, } p.Response(session, resp) } // lineupLeave 阵容英雄下阵 func (p *actorPlayer) lineupLeave(session *cproto.Session, req *pb.LineupLeaveRequest) { var ( teamTable = p.TeamTable() lineupType = req.LineupType lineupID = req.LineupID index = req.Index ) lineups, found := teamTable.LineupMap.GetLineups(lineupType) if !found { p.ResponseCode(session, code.TeamLineupTypeError) return } lineup, found := lineups.GetLineup(lineupID) if !found { p.ResponseCode(session, code.TeamNotUnlock) return } if !lineup.DelLineupMember(index) { p.ResponseCode(session, code.HeroNotInTeam) return } teamTable.Save2Queue() // 更新阵容羁绊列表 p.updateLineupFetterList(lineup) proto := lineup.ToProto() resp := &pb.LineupInfo{ LineupType: lineupType, Lineup: &proto, } p.Response(session, resp) } // lineupChange 阵容英雄换阵 func (p *actorPlayer) lineupChange(session *cproto.Session, req *pb.LineupChangeRequest) { var ( heroTable = p.HeroTable() teamTable = p.TeamTable() lineupType = req.LineupType srcLineupID = req.SrcLineupID dstLineupID = req.DstLineupID srcIndex = req.SrcIndex dstIndex = req.DstIndex ) if srcLineupID == dstLineupID && srcIndex == dstIndex { p.ResponseCode(session, code.TeamIndexNotChange) return } //判断队伍索引是否合法 if !constant.ValidateLineupMemberIndex(srcIndex, dstIndex) { p.ResponseCode(session, code.TeamIndexError) return } lineups, found := teamTable.LineupMap.GetLineups(lineupType) if !found { p.ResponseCode(session, code.TeamLineupTypeError) return } srcLineup, found := lineups.GetLineup(srcLineupID) if !found { p.ResponseCode(session, code.TeamNotUnlock) return } srcLineupMember, ok := srcLineup.GetLineupMember(srcIndex) if !ok || srcLineupMember.HeroGUID == 0 { p.ResponseCode(session, code.HeroNotInTeam) return } srcHero, ok := heroTable.Heroes.Get(srcLineupMember.HeroGUID) if !ok { p.ResponseCode(session, code.HeroNotExist) return } dstLineup, ok := lineups.GetLineup(dstLineupID) if !ok { p.ResponseCode(session, code.TeamNotUnlock) return } //不同队伍 检测是否上阵相同英雄 if srcLineupID != dstLineupID && p.checkLineupSameHero(heroTable, lineups, srcLineupID, srcIndex, dstLineupID, dstIndex, srcHero.HeroID) { p.ResponseCode(session, code.TeamAlreadySameHero) return } // 被替换位置检测英雄下阵 dstLineupMember, found := dstLineup.GetLineupMember(dstIndex) if found { dstLineupMember.HeroGUID = srcLineupMember.HeroGUID } else { // 判断人数是否上限 if dstLineup.IsLineupMemberLimit() { p.ResponseCode(session, code.TeamMemberLimit) return } dstLineup.AddLineupMember(dstIndex, srcLineupMember.HeroGUID) } // 原阵容英雄下阵 srcLineup.DelLineupMember(srcIndex) teamTable.Save2Queue() // 更新阵容羁绊列表 p.updateLineupFetterList(srcLineup, dstLineup) // 同步给客户端 lineup.Service().LineupChangePush(p.playerID, lineupType, srcLineupID, dstLineupID) p.ResponseCode(session, code.OK) } // lineupTune 阵容英雄阵容设置 func (p *actorPlayer) lineupAdjust(session *cproto.Session, req *pb.LineupAdjustRequest) { var ( teamTable = p.TeamTable() lineupType = req.LineupType lineupID = req.LineupID index = req.Index toIndex = req.ToIndex ) //检测部队位置是否合法 if !constant.ValidateLineupMemberIndex(index, toIndex) { p.ResponseCode(session, code.TeamIndexError) return } // 获取阵容类型下的阵容列表 lineups, found := teamTable.LineupMap.GetLineups(lineupType) if !found { p.ResponseCode(session, code.TeamLineupTypeError) return } // 获取阵容信息 lineup, found := lineups.GetLineup(lineupID) if !found { p.ResponseCode(session, code.TeamNotUnlock) return } // 获取阵容成员信息 fromLineupMember, found := lineup.GetLineupMember(index) if !found || fromLineupMember.HeroGUID == 0 { p.ResponseCode(session, code.HeroNotInTeam) return } if fromLineupMember.Index != toIndex { //获取交换对象 如果原来位置存在英雄 则交换阵容位置 否则直接修改位置 toLineupMember, found := lineup.GetLineupMember(toIndex) if found { //交换 fromLineupMember.Index, toLineupMember.Index = toLineupMember.Index, fromLineupMember.Index } else { fromLineupMember.Index = toIndex } teamTable.Save2Queue() } proto := lineup.ToProto() resp := &pb.LineupInfo{ LineupType: lineupType, Lineup: &proto, } p.Response(session, resp) } // 检测同队伍是否存在相同英雄 func (p *actorPlayer) checkLineupSameHero(heroTable *db.HeroTable, lineups dbLineup.Lineups, srcLineupID, srcLineupIndex, excludeLineupID, excludeIndex int32, heroIDs ...int32) bool { if len(lineups) <= 0 { return false } for _, lineup := range lineups { // 如果排除的位置为0 且 排除的阵容ID相同 则排除整个阵容 if excludeIndex == 0 && lineup.LineupID == excludeLineupID { continue } for _, member := range lineup.Members { // 如果是不同阵容切换位置 则排除原位置 if lineup.LineupID == srcLineupID && member.Index == srcLineupIndex { continue } // 排除上阵位置 if lineup.LineupID == excludeLineupID && member.Index == excludeIndex { continue } hero, ok := heroTable.Heroes.Get(member.HeroGUID) if !ok { // 没找到返回true 防止上阵相同英雄 return true } if _, ok := cslice.Int32In(hero.HeroID, heroIDs); ok { return true } } } return false } // 更新队伍羁绊列表 func (p *actorPlayer) updateLineupFetterList(updateTeams ...*dbLineup.Lineup) { if len(updateTeams) < 1 { return } heroTable := p.HeroTable() for _, curTeam := range updateTeams { if len(curTeam.Members) < 1 { curTeam.FetterIDs.Clear() continue } // 获取英雄列表 heroIDSet := types.Set[int32]{} for _, member := range curTeam.Members { curHeroEntity, found := heroTable.Heroes.Get(member.HeroGUID) if found { heroIDSet.Add(curHeroEntity.HeroID) } } // 刷新队伍羁绊 fetterIDs := lineup.Service().GetFetterListByHeroList(p.playerID, heroIDSet) curTeam.FetterIDs = fetterIDs } }