package main import ( "mongo.games.com/goserver/core/logger" "mongo.games.com/game/common" "mongo.games.com/game/proto" "mongo.games.com/game/protocol/server" ) var MatchSceneMgrSingleton = &MatchSceneMgr{ scenes: make(map[int]*Scene), } // MatchSceneMgr 比赛场房间管理器 type MatchSceneMgr struct { scenes map[int]*Scene // 比赛场房间,房间id:房间数据 } // NewScene 创建比赛场房间 // tm 一场比赛,数据 // isFinals 是否决赛 // round 第几轮 func (ms *MatchSceneMgr) NewScene(tm *TmMatch, isFinals bool, round int32) *Scene { sceneId := SceneMgrSingleton.GenOneMatchSceneId() gameId := int(tm.dbGameFree.GameId) gameMode := tm.dbGameFree.GetGameMode() gs := GameSessMgrSington.GetMinLoadSess(gameId) if gs == nil { logger.Logger.Warn("not found game server, gameid: ", gameId) return nil } limitPlatform := PlatformMgrSingleton.GetPlatform(tm.Platform) if limitPlatform == nil || !limitPlatform.Isolated { limitPlatform = PlatformMgrSingleton.GetPlatform(DefaultPlatform) } finals := int32(0) // 是否决赛 if isFinals { finals = 1 } curPlayerNum := int32(1) // 本轮比赛总人数 nextNeed := int32(0) // 下一轮比赛总人数 if tm.gmd != nil && len(tm.gmd.MatchPromotion) >= int(round) { curPlayerNum = tm.gmd.MatchPromotion[round-1] if curPlayerNum == 1 { //最后一局特殊处理下,取倒数第二局人数 curPlayerNum = tm.gmd.MatchPromotion[round-2] } if len(tm.gmd.MatchPromotion) > int(round) { nextNeed = tm.gmd.MatchPromotion[round] } } groupId := PlatformMgrSingleton.GetGameFreeGroup(tm.Platform, tm.dbGameFree.Id) // 建房参数 // 比赛唯一索引,是否决赛,第几轮,本轮总人数,下一轮总人数,赛制类型 params := []int32{tm.SortId, finals, round, curPlayerNum, nextNeed, tm.gmd.MatchType} scene := SceneMgrSingleton.CreateScene(0, 0, sceneId, gameId, int(gameMode), common.SceneMode_Match, 1, 0, params, gs, limitPlatform, groupId, tm.dbGameFree) if scene != nil { scene.matchId = tm.SortId return scene } return nil } func (ms *MatchSceneMgr) MatchStart(tm *TmMatch) { scene := ms.NewScene(tm, false, 1) if scene != nil { ms.scenes[scene.sceneId] = scene } for _, tmp := range tm.TmPlayer { //先进真人 if scene == nil || scene.IsFull() { scene = ms.NewScene(tm, false, 1) if scene != nil { ms.scenes[scene.sceneId] = scene } } p := PlayerMgrSington.GetPlayerBySnId(tmp.SnId) if p != nil && p.scene == nil { mc := TournamentMgr.CreatePlayerMatchContext(p, tm, tmp.seq) if mc != nil { mc.gaming = true scene.PlayerEnter(mc.p, -1, true) } } else { if p != nil { logger.Logger.Error("MatchStart error: snid: ", p.SnId, " p.scene: ", p.scene) } } } if scene != nil && !scene.IsFull() { //填充机器人 tm.RobotGradesDecline(1) needRobotNum := scene.playerNum - len(scene.players) logger.Logger.Trace("MatchStart 填充机器人", needRobotNum) pack := &server.WGInviteMatchRob{ Platform: proto.String(tm.Platform), MatchId: proto.Int32(tm.TMId), RobNum: proto.Int(needRobotNum), NeedAwait: proto.Bool(true), RoomId: proto.Int(scene.sceneId), } SendToGame(int(tm.dbGameFree.GameId), int(server.SSPacketID_PACKET_WG_INVITEMATCHROB), pack) } } func (ms *MatchSceneMgr) NewRoundStart(tm *TmMatch, mct []*PlayerMatchContext, finals bool, round int32) { scene := ms.NewScene(tm, finals, round) if scene != nil { ms.scenes[scene.sceneId] = scene } for _, tmp := range mct { if scene == nil || scene.IsFull() { scene = ms.NewScene(tm, finals, round) if scene != nil { ms.scenes[scene.sceneId] = scene } } p := tmp.p if p != nil && p.scene == nil { if mc, ok := TournamentMgr.players[tm.SortId][p.SnId]; ok { mc.gaming = true mc.grade = mc.grade * 75 / 100 //积分衰减 mc.rank = tmp.rank scene.PlayerEnter(mc.p, -1, true) } } else { if p != nil { logger.Logger.Error("NewRoundStart error: snid: ", p.SnId, " p.scene: ", p.scene) } } } if scene != nil && !scene.IsFull() { //填充机器人 tm.RobotGradesDecline(int(round)) needRobotNum := scene.playerNum - len(scene.players) logger.Logger.Trace("NewRoundStart 填充机器人", needRobotNum) pack := &server.WGInviteMatchRob{ Platform: proto.String(tm.Platform), MatchId: proto.Int32(tm.TMId), RobNum: proto.Int(needRobotNum), NeedAwait: proto.Bool(true), RoomId: proto.Int(scene.sceneId), } SendToGame(int(tm.dbGameFree.GameId), int(server.SSPacketID_PACKET_WG_INVITEMATCHROB), pack) } } func (ms *MatchSceneMgr) PlayerLeave(p *Player, reason int) bool { if p == nil || p.scene == nil { return true } if p.scene.matchId == 0 { return true } p.scene.PlayerLeave(p, reason) return true } func (ms *MatchSceneMgr) OnDestroyScene(sceneId int) { _, has := ms.scenes[sceneId] if !has { return } delete(ms.scenes, sceneId) } func (ms *MatchSceneMgr) MatchStop(tm *TmMatch) { if SceneMgrSingleton.scenes != nil && tm != nil { for _, scene := range SceneMgrSingleton.scenes { if scene.IsMatchScene() && scene.matchId == tm.SortId { scene.ForceDelete(false) } } } }