package main import ( "time" "mongo.games.com/goserver/core/logger" "mongo.games.com/game/common" "mongo.games.com/game/proto" "mongo.games.com/game/protocol/server" "mongo.games.com/game/srvdata" ) var MatchSceneMgrSingleton = &MatchSceneMgr{} // MatchSceneMgr 比赛场房间管理器 type MatchSceneMgr struct{} // NewScene 创建比赛场房间 // tm 一场比赛,数据 // isFinals 是否决赛 // round 第几轮 func (ms *MatchSceneMgr) NewScene(tm *TmMatch, isFinals bool, round int32) *Scene { // 平台 limitPlatform := PlatformMgrSingleton.GetPlatform(tm.Platform) if limitPlatform == nil || !limitPlatform.Isolated { limitPlatform = PlatformMgrSingleton.GetPlatform(DefaultPlatform) } sceneId := SceneMgrSingleton.GenOneMatchSceneId() // 是否决赛 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] } } rule := srvdata.PBDB_GameRuleMgr.GetData(tm.dbGameFree.GetGameRule()) scene := SceneMgrSingleton.CreateScene(&CreateSceneParam{ RoomId: sceneId, SceneMode: common.SceneModeMatch, Params: common.CopySliceInt32ToInt64(rule.GetParams()), Platform: limitPlatform, GF: tm.dbGameFree, MatchParam: &server.MatchParam{ MatchId: tm.TMId, MatchSortId: tm.SortId, IsFinals: finals == 1, CurrRound: round, CurrPlayerNum: curPlayerNum, NextPlayerNum: nextNeed, MatchType: tm.gmd.MatchType, }, }) if scene != nil { return scene } return nil } // MatchStart 开始首轮比赛 func (ms *MatchSceneMgr) MatchStart(tm *TmMatch) { var scene *Scene csp := CoinSceneMgrSingleton.GetCoinScenePool(tm.Platform, tm.dbGameFree.GetId()) if csp == nil { logger.Logger.Errorf("MatchStart: csp is nil, TMID=%v", tm.TMId) return } for _, tmp := range tm.TmPlayer { //先进真人 if scene == nil || scene.IsFull() { scene = ms.NewScene(tm, false, 1) if scene == nil { logger.Logger.Errorf("MatchStart NewScene failed, TMID=%v", tm.TMId) return } csp.AddScene(scene) } p := PlayerMgrSington.GetPlayerBySnId(tmp.SnId) if p == nil { continue } if p.scene != nil { logger.Logger.Errorf("MatchStart error: snid:%v in scene %v", p.SnId, p.scene.sceneId) continue } mc := TournamentMgr.CreatePlayerMatchContext(p, tm, tmp.seq) if mc != nil { mc.gaming = true if !scene.PlayerEnter(p, -1, true) { logger.Logger.Errorf("MatchStart error: snid:%v enter scene %v failed", p.SnId, scene.sceneId) continue } } } // 填充机器人 if scene != nil && !scene.IsFull() { 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) } } // NewRoundStart 开始非首轮比赛 func (ms *MatchSceneMgr) NewRoundStart(tm *TmMatch, mct []*PlayerMatchContext, finals bool, round int32) { tm.RoundTime = time.Now() var scene *Scene csp := CoinSceneMgrSingleton.GetCoinScenePool(tm.Platform, tm.dbGameFree.GetId()) if csp == nil { logger.Logger.Errorf("NewRoundStart: csp is nil, TMID=%v", tm.TMId) return } for _, tmp := range mct { if scene == nil || scene.IsFull() { scene = ms.NewScene(tm, finals, round) if scene == nil { logger.Logger.Errorf("NewRoundStart NewScene failed, TMID=%v", tm.TMId) return } csp.AddScene(scene) } p := tmp.p if p == nil { continue } if p.scene != nil { logger.Logger.Errorf("NewRoundStart error: snid:%v in scene %v gameId:%v", p.SnId, p.scene.sceneId, p.scene.gameId) continue } if mc, ok := TournamentMgr.players[tm.SortId][p.SnId]; ok { mc.gaming = true mc.grade = mc.grade * 75 / 100 //积分衰减 mc.rank = tmp.rank if !scene.PlayerEnter(p, -1, true) { logger.Logger.Errorf("NewRoundStart error: snid:%v enter scene %v failed", p.SnId, scene.sceneId) continue } } } // 填充机器人 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) } } // MatchStop 强制停止比赛 func (ms *MatchSceneMgr) MatchStop(tm *TmMatch) { if SceneMgrSingleton.scenes != nil && tm != nil { for _, scene := range SceneMgrSingleton.scenes { if scene.IsMatchScene() && scene.MatchSortId == tm.SortId { scene.SendGameDestroy(false) } } } }