game_sync/worldsrv/matchscenemgr.go

198 lines
5.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"mongo.games.com/game/srvdata"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/game/common"
"mongo.games.com/game/proto"
hallproto "mongo.games.com/game/protocol/gamehall"
"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 {
// 平台
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.SceneMode_Match,
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
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 {
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
scene.PlayerEnter(p, -1, true)
}
}
// 填充机器人
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
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 {
continue
}
if p.scene != nil {
logger.Logger.Errorf("NewRoundStart error: snid:%v in scene %v", p.SnId, p.scene.sceneId)
continue
}
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(p, -1, true)
}
}
// 填充机器人
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.MatchSortId == 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) AudienceEnter(p *Player, id int32, roomId int, exclude []int32, ischangeroom bool) hallproto.OpResultCode {
scene, ok := ms.scenes[roomId]
if !ok {
return hallproto.OpResultCode_OPRC_RoomHadClosed
}
if !scene.AudienceEnter(p, ischangeroom) {
return hallproto.OpResultCode_OPRC_RoomHadClosed
}
return hallproto.OpResultCode_OPRC_Sucess
}
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)
}
}
}
}