game_sync/worldsrv/matchscenemgr.go

184 lines
5.3 KiB
Go

package main
import (
"mongo.games.com/game/srvdata"
"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{}
// 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) {
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)
}
}
}
}