198 lines
5.4 KiB
Go
198 lines
5.4 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"
|
||
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)
|
||
}
|
||
}
|
||
}
|
||
}
|