game_sync/gamesrv/chess/scenepolicy.go

1527 lines
42 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 chesstitians
import (
"math/rand"
"time"
"mongo.games.com/goserver/core"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/game/common"
rule "mongo.games.com/game/gamerule/chess"
"mongo.games.com/game/gamesrv/base"
"mongo.games.com/game/model"
"mongo.games.com/game/proto"
"mongo.games.com/game/protocol/chesstitians"
)
var ScenePolicyEntitySingleton = &ScenePolicyEntity{}
type ScenePolicyEntity struct {
base.BaseScenePolicy
states [rule.SceneStateMax]base.SceneState
}
// 创建场景扩展数据
func (this *ScenePolicyEntity) CreateSceneExData(s *base.Scene) interface{} {
sceneEx := NewSceneEx(s)
if sceneEx != nil {
if sceneEx.init() {
sceneEx.Clear()
s.SetExtraData(sceneEx)
}
}
return sceneEx
}
// 创建玩家扩展数据
func (this *ScenePolicyEntity) CreatePlayerExData(s *base.Scene, p *base.Player) interface{} {
playerEx := &PlayerEx{Player: p}
if playerEx != nil {
playerEx.init()
p.SetExtraData(playerEx)
}
return playerEx
}
// 场景开启事件
func (this *ScenePolicyEntity) OnStart(s *base.Scene) {
logger.Logger.Trace("(this *ScenePolicyEntity) OnStart, GetSceneId()=", s.GetSceneId())
sceneEx := NewSceneEx(s)
if sceneEx != nil {
if sceneEx.init() {
sceneEx.Clear()
s.SetExtraData(sceneEx)
s.ChangeSceneState(rule.SceneStateWaitPlayer)
}
}
}
// 场景心跳事件
func (this *ScenePolicyEntity) OnTick(s *base.Scene) {
if s == nil {
return
}
if s.GetSceneState() != nil {
s.GetSceneState().OnTick(s)
}
}
// 玩家进入事件
func (this *ScenePolicyEntity) OnPlayerEnter(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerEnter, GetSceneId()=", s.GetSceneId(), " player=", p.GetName())
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
//自动带入金币
pos := sceneEx.FindOnePos()
if p.Pos != rule.InvalidPos && sceneEx.seats[p.Pos] == nil {
pos = p.Pos
}
if pos < 0 || pos > 1 || sceneEx.seats[pos] != nil {
p.MarkFlag(base.PlayerState_EnterSceneFailed)
cnt := len(sceneEx.players)
logger.Logger.Warnf("ScenePolicyEntity.OnPlayerEnter(scene:%v, player:%v) no found fit GetPos(), current player count:%v NumOfGames:%v", s.GetSceneId(), p.SnId, cnt, sceneEx.NumOfGames)
return
}
playerEx := &PlayerEx{Player: p}
playerEx.init()
playerEx.SetPos(pos)
if sceneEx.GetGaming() {
playerEx.MarkFlag(base.PlayerState_WaitNext)
}
p.SetExtraData(playerEx)
sceneEx.seats[pos] = playerEx
sceneEx.players[p.SnId] = playerEx
if sceneEx.GetSeatPlayerCnt() == 1 {
sceneEx.masterSnId = playerEx.SnId
sceneEx.BroadcastUpdateMasterSnId(false)
}
//广播个人信息
playerData := CreatePlayerData(p)
if sceneEx.IsMatchScene() && p.IsRob {
if len(p.MatchParams) > 2 {
if p.MatchParams[2] != 0 {
playerData.CopySnid = p.MatchParams[2]
}
}
if len(p.MatchParams) > 3 {
if p.MatchParams[3] != 0 {
playerData.CopyRoleId = p.MatchParams[3]
}
}
}
pack := &chesstitians.SCChesstitiansPlayerEnter{
Data: playerData,
}
proto.SetDefaults(pack)
s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerEnter), pack, p.GetSid())
//给自己发送房间信息
SendRoomInfo(s, p, sceneEx, playerEx)
s.FirePlayerEvent(p, base.PlayerEventEnter, nil)
}
}
// 玩家离开事件
func (this *ScenePolicyEntity) OnPlayerLeave(s *base.Scene, p *base.Player, reason int) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerLeave, GetSceneId()=", s.GetSceneId(), " player=", p.SnId)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
if playerEx, ok := p.GetExtraData().(*PlayerEx); ok {
if this.CanChangeCoinScene(s, p) {
LeavePlayerSnid := playerEx.SnId
sceneEx.OnPlayerLeave(p, reason)
s.FirePlayerEvent(p, base.PlayerEventLeave, []int64{int64(reason)})
if LeavePlayerSnid == sceneEx.masterSnId {
findOne := false
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
playerExSeat := sceneEx.seats[i]
if playerExSeat != nil && playerExSeat.SnId != sceneEx.masterSnId {
sceneEx.masterSnId = playerExSeat.SnId
sceneEx.BroadcastUpdateMasterSnId(true)
findOne = true
break
}
}
if !findOne {
sceneEx.masterSnId = 0
sceneEx.BroadcastUpdateMasterSnId(false)
}
}
if !playerEx.IsRob { //真人离开
hadSeat := false
for _, seat := range sceneEx.seats {
if seat != nil {
hadSeat = true
break
}
}
if !hadSeat { //座位上没有人了,把观众踢出去
audiences := sceneEx.GetAudiences()
for _, audience := range audiences {
if audience != nil {
s.AudienceLeave(audience, common.PlayerLeaveReason_RoomClose)
}
}
}
}
}
}
}
}
// 玩家掉线
func (this *ScenePolicyEntity) OnPlayerDropLine(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerDropLine, GetSceneId()=", s.GetSceneId(), " player=", p.Name)
s.FirePlayerEvent(p, base.PlayerEventDropLine, nil)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
if sceneEx.GetGaming() {
if s.IsMatchScene() || s.IsCoinScene() {
p.MarkFlag(base.PlayerState_Auto)
p.SyncFlag()
}
return
}
s.PlayerLeave(p, common.PlayerLeaveReason_DropLine, true)
}
}
// 玩家重连
func (this *ScenePolicyEntity) OnPlayerRehold(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerRehold, GetSceneId()=", s.GetSceneId(), " player=", p.Name)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
if playerEx, ok := p.GetExtraData().(*PlayerEx); ok {
if p.IsMarkFlag(base.PlayerState_Auto) {
p.UnmarkFlag(base.PlayerState_Auto)
p.SyncFlag()
}
//发送房间信息给自己
SendRoomInfo(s, p, sceneEx, playerEx)
s.FirePlayerEvent(p, base.PlayerEventRehold, nil)
}
}
}
// 返回房间
func (this *ScenePolicyEntity) OnPlayerReturn(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerReturn, GetSceneId()=", s.GetSceneId(), " player=", p.Name)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
if playerEx, ok := p.GetExtraData().(*PlayerEx); ok {
if p.IsMarkFlag(base.PlayerState_Auto) {
p.UnmarkFlag(base.PlayerState_Auto)
p.SyncFlag()
}
//发送房间信息给自己
SendRoomInfo(s, p, sceneEx, playerEx)
s.FirePlayerEvent(p, base.PlayerEventReturn, nil)
}
}
}
func (this *ScenePolicyEntity) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
if s == nil || p == nil {
return false
}
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerOp, GetSceneId()=", s.GetSceneId(), " player=", p.GetName(), " opcode=", opcode, " params=", params)
if s.GetSceneState() != nil {
if s.GetSceneState().OnPlayerOp(s, p, opcode, params) {
p.LastOPTimer = time.Now()
return true
}
return false
}
return true
}
func (this *ScenePolicyEntity) OnPlayerDevOp(s *base.Scene, p *base.Player, opcode int, paramStr []string, param int64) bool {
if s == nil || p == nil {
return false
}
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerDevOp, GetSceneId()=", s.GetSceneId(), " player=", p.GetName(), " opcode=", opcode, " paramsStr=", paramStr, " param=", param)
sceneEx, _ := s.GetExtraData().(*SceneEx)
sceneEx.chess.SetChess(paramStr)
//sceneEx.opPos = int32(param)
snid := int32(param)
for idx, seat := range sceneEx.seats {
if seat.GetSnId() == snid {
sceneEx.opPos = idx
break
}
}
sceneEx.lastMove = []int32{}
//playerEx, _ := p.GetExtraData().(*PlayerEx)
//pack := CreateRoomInfoPacket(s, p, sceneEx, playerEx)
//s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomInfo), pack, 0)
for _, seat := range sceneEx.seats {
if seat != nil {
pack := CreateRoomInfoPacket(s, seat.Player, sceneEx, seat)
ok := seat.Player.SendToClient(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomInfo), pack)
logger.Logger.Trace("SCChesstitiansSendRoomInfo isok : ", ok, ",pack", pack)
}
}
return true
}
func (this *ScenePolicyEntity) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.GetName(), " eventcode=", evtcode, " params=", params)
if s.GetSceneState() != nil {
s.GetSceneState().OnPlayerEvent(s, p, evtcode, params)
}
}
func (this *ScenePolicyEntity) OnAudienceEnter(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("ScenePolicyEntity OnAudienceEnter, sceneId=", s.SceneId, " player=", p.SnId)
this.BaseScenePolicy.OnAudienceEnter(s, p)
if sceneEx, ok := s.ExtraData.(*SceneEx); ok {
//给自己发送房间信息
p.UnmarkFlag(base.PlayerState_Leave)
SendRoomInfo(s, p, sceneEx, nil)
sceneEx.BroadcastAudienceNum(p)
}
}
func (this *ScenePolicyEntity) OnAudienceLeave(s *base.Scene, p *base.Player, reason int) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("ScenePolicyEntity OnAudienceLeave, sceneId=", s.SceneId, " player=", p.SnId, " reason=", reason)
if sceneEx, ok := s.ExtraData.(*SceneEx); ok {
sceneEx.BroadcastAudienceNum(p)
}
}
func (this *ScenePolicyEntity) OnAudienceSit(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("ScenePolicyEntity OnAudienceSit, sceneId=", s.SceneId, " player=", p.SnId)
sceneEx, ok := s.GetExtraData().(*SceneEx)
if !ok {
return
}
if s.Gaming && !s.GetBEnterAfterStart() {
return
}
//自动带入金币
pos := sceneEx.FindOnePos()
if pos < 0 || pos > 3 || sceneEx.seats[pos] != nil {
p.MarkFlag(base.PlayerState_EnterSceneFailed)
cnt := len(sceneEx.players)
logger.Logger.Warnf("ScenePolicyEntity.OnAudienceSit(scene:%v, player:%v) no found fit GetPos(), current player count:%v NumOfGames:%v", s.GetSceneId(), p.SnId, cnt, sceneEx.NumOfGames)
return
}
playerEx := &PlayerEx{Player: p}
playerEx.init()
playerEx.SetPos(pos)
p.UnmarkFlag(base.PlayerState_Audience)
p.UnmarkFlag(base.PlayerState_Leave)
if sceneEx.GetGaming() {
playerEx.MarkFlag(base.PlayerState_WaitNext)
p.SyncFlag()
}
p.SetExtraData(playerEx)
sceneEx.seats[pos] = playerEx
sceneEx.players[p.SnId] = playerEx
//logger.Logger.Trace("广播个人信息,curSeatsNum: ", sceneEx.GetSeatPlayerCnt())
if sceneEx.GetSeatPlayerCnt() == 1 {
sceneEx.masterSnId = playerEx.SnId
sceneEx.BroadcastUpdateMasterSnId(false)
}
//广播个人信息
playerData := CreatePlayerData(p)
pack := &chesstitians.SCChesstitiansPlayerEnter{
Data: playerData,
}
proto.SetDefaults(pack)
s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerEnter), pack, p.GetSid())
//给自己发送房间信息
SendRoomInfo(s, p, sceneEx, playerEx)
sceneEx.BroadcastAudienceNum(p)
s.FirePlayerEvent(p, base.PlayerEventEnter, nil)
}
func (this *ScenePolicyEntity) OnAudienceDropLine(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("ScenePolicyEntity OnAudienceDropLine, sceneId=", s.SceneId, " player=", p.SnId)
s.AudienceLeave(p, common.PlayerLeaveReason_DropLine)
if sceneEx, ok := s.ExtraData.(*SceneEx); ok {
sceneEx.BroadcastAudienceNum(p)
}
}
// 是否完成了整个牌局
func (this *ScenePolicyEntity) IsCompleted(s *base.Scene) bool {
if s == nil {
return false
}
return false
}
// 是否可以强制开始
func (this *ScenePolicyEntity) IsCanForceStart(s *base.Scene) bool {
return false
}
// 当前状态能否换桌
func (this *ScenePolicyEntity) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
if s == nil || p == nil {
return false
}
if s.GetSceneState() != nil {
return s.GetSceneState().CanChangeCoinScene(s, p)
}
return true
}
func (this *ScenePolicyEntity) ForceStart(s *base.Scene) {
s.ChangeSceneState(rule.SceneStateWaitStart)
}
func CreatePlayerData(p *base.Player) *chesstitians.ChesstitiansPlayerData {
pd := &chesstitians.ChesstitiansPlayerData{
Name: proto.String(p.Name),
SnId: proto.Int32(p.SnId),
Head: proto.Int32(p.Head),
Sex: proto.Int32(p.Sex),
Coin: proto.Int64(p.GetCoin()),
Flag: proto.Int(p.GetFlag()),
Longitude: proto.Int32(p.Longitude),
Latitude: proto.Int32(p.Latitude),
City: proto.String(p.City),
VIP: proto.Int32(p.VIP),
HeadOutLine: proto.Int32(p.HeadOutLine),
NiceId: proto.Int32(p.NiceId),
Pos: proto.Int(p.GetPos()),
ChessGrade: proto.Int64(p.ChessGrade),
IsRob: proto.Bool(p.IsRob),
Level: proto.Int64(p.Level),
Exp: proto.Int64(p.Exp),
}
ex, ok := p.GetExtraData().(*PlayerEx)
if ok {
pd.IsWin = ex.isWin
pd.WinTimes = ex.winTimes
pd.OtherScore = ex.otherScore
pd.NextRank = ex.nextRank
pd.WinScore = ex.winScore
pd.WinCoin = ex.winCoin
pd.OldChessGrade = ex.oldGrade
pd.TotalTime = ex.GetTotalTime()
}
if p.Roles != nil {
pd.RoleId = proto.Int32(p.Roles.ModId)
}
if p.Items != nil {
pd.Items = make(map[int32]int32)
for id, num := range p.Items {
pd.Items[id] = int32(num)
}
}
if len(p.MatchParams) > 0 {
pd.MatchRankId = p.MatchParams[0]
}
if len(p.MatchParams) > 1 {
pd.Lv = p.MatchParams[1]
}
logger.Logger.Trace("ChesstitiansCreatePlayerData pd : ", pd)
return pd
}
func CreateRoomInfoPacket(s *base.Scene, p *base.Player, sceneEx *SceneEx, playerEx *PlayerEx) *chesstitians.SCChesstitiansRoomInfo {
pack := &chesstitians.SCChesstitiansRoomInfo{
RoomId: proto.Int(s.GetSceneId()),
Creator: proto.Int32(s.GetCreator()),
GameId: proto.Int(s.GetGameId()),
RoomMode: proto.Int(s.GetSceneMode()),
Params: common.CopySliceInt64ToInt32(s.GetParams()),
State: proto.Int32(int32(s.GetSceneState().GetState())),
TimeOut: proto.Int(s.GetSceneState().GetTimeout(s)),
NumOfGames: proto.Int(sceneEx.NumOfGames),
TotalOfGames: sceneEx.TotalOfGames,
CurOpIdx: proto.Int(-1),
MasterSnid: proto.Int32(sceneEx.masterSnId),
AudienceNum: proto.Int(s.GetAudiencesNum()),
BaseScore: proto.Int32(s.BaseScore),
MaxPlayerNum: proto.Int(s.GetPlayerNum()),
GameFreeId: proto.Int32(s.GetDBGameFree().GetId()),
SceneType: proto.Int32(s.GetDBGameFree().GetSceneType()),
// 计步
StepSnId: proto.Int32(sceneEx.stepSnId),
StepNum: int64(sceneEx.stepNum),
StepLimit: int64(sceneEx.stepLimit),
// 求和
DrawSnId: proto.Int32(sceneEx.drawSnId),
// 发起再来一局的玩家
NextSnId: proto.Int32(sceneEx.nextSnId),
}
pack.Variant = int32(sceneEx.chess.GetVariant())
// 生成棋数据
pack.Chess = sceneEx.chess.GetChess()
pack.Act = sceneEx.chess.GetAct()
pack.Castling = sceneEx.chess.GetCastling()
pack.CambodianMove = sceneEx.chess.GetCambodianMove()
pack.Enpassant = int32(sceneEx.chess.GetEnPassant())
pack.ChessRound = int32(sceneEx.chess.GetRound())
pack.Check = sceneEx.chess.GetCheck()
pack.Checkmate = sceneEx.chess.GetCheckmate()
for _, v := range sceneEx.lastMove {
pack.LastMove = append(pack.LastMove, int32(v))
}
pack.IsMatch = int32(0)
// 0.普通场 1.锦标赛 2.冠军赛 3.vip专属
if s.IsMatchScene() {
}
pack.MatchFinals = 0
if s.GetMatch().GetIsFinals() {
pack.MatchFinals = 1
if s.NumOfGames >= 2 {
pack.MatchFinals = 2
}
}
if s.GetSceneState().GetState() == rule.SceneStateBilled {
sceneEx.opPos = -1
pack.CurOpIdx = proto.Int32(-1)
}
if s.GetSceneState().GetState() >= rule.SceneStatePlayerOp {
pack.CurOpIdx = proto.Int32(int32(sceneEx.opPos))
}
//玩家信息.第一个必然是自己
pd := CreatePlayerData(p)
if playerEx != nil {
// 是黑棋的标记1黑棋0白棋
if playerEx.isBlack {
pd.IsBlack = proto.Int32(1)
} else {
pd.IsBlack = proto.Int32(0)
}
}
pack.Players = append(pack.Players, pd)
//剩下的按座位排序
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
nowPlayer := sceneEx.seats[i]
if nowPlayer != nil {
if nowPlayer.SnId != p.SnId {
pd1 := CreatePlayerData(nowPlayer.Player)
if sceneEx.IsMatchScene() && nowPlayer.IsRob {
if len(nowPlayer.MatchParams) > 2 {
if nowPlayer.MatchParams[2] != 0 {
pd1.CopySnid = nowPlayer.MatchParams[2]
}
}
if len(nowPlayer.MatchParams) > 3 {
if nowPlayer.MatchParams[3] != 0 {
pd1.CopyRoleId = nowPlayer.MatchParams[3]
}
}
}
// 是黑棋的标记1黑棋0白棋
if nowPlayer.isBlack {
pd1.IsBlack = proto.Int32(1)
} else {
pd1.IsBlack = proto.Int32(0)
}
pack.Players = append(pack.Players, pd1)
}
}
}
proto.SetDefaults(pack)
return pack
}
func SendRoomInfo(s *base.Scene, p *base.Player, sceneEx *SceneEx, playerEx *PlayerEx) {
pack := CreateRoomInfoPacket(s, p, sceneEx, playerEx)
ok := p.SendToClient(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomInfo), pack)
logger.Logger.Trace("SCChesstitiansSendRoomInfo isok : ", ok, ",pack", pack)
}
//=====================================
// SceneStateBase 状态基类
//=====================================
type SceneStateBase struct {
}
func (this *SceneStateBase) GetTimeout(s *base.Scene) int {
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
return int(time.Now().Sub(sceneEx.StateStartTime) / time.Second)
}
return 0
}
func (this *SceneStateBase) CanChangeTo(s base.SceneState) bool {
return true
}
func (this *SceneStateBase) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
return !p.IsGameing() || s.GetDestroyed()
}
func (this *SceneStateBase) OnEnter(s *base.Scene) {
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
sceneEx.StateStartTime = time.Now()
}
}
func (this *SceneStateBase) OnLeave(s *base.Scene) {}
func (this *SceneStateBase) OnTick(s *base.Scene) {
}
func (this *SceneStateBase) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
logger.Logger.Trace("SceneBaseStateChesstitians.", " s.GetSceneId() : ", s.GetSceneId(), " p.SnId : ", p.SnId, " opcode : ", opcode, " params ", params)
sceneEx, _ := s.GetExtraData().(*SceneEx)
if sceneEx == nil {
return true
}
playerEx, _ := p.GetExtraData().(*PlayerEx)
if playerEx == nil {
return true
}
return false
}
func (this *SceneStateBase) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
}
// BroadcastRoomState 广播房间状态
func (this *SceneStateBase) BroadcastRoomState(s *base.Scene, state int, params ...int64) {
pack := &chesstitians.SCChesstitiansRoomState{
State: proto.Int(state),
Params: params,
}
proto.SetDefaults(pack)
s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomState), pack, 0)
}
//=====================================
// SceneStateWaitPlayer 等待玩家进入
//=====================================
type SceneStateWaitPlayer struct {
SceneStateBase
}
func (this *SceneStateWaitPlayer) GetState() int {
return rule.SceneStateWaitPlayer
}
func (this *SceneStateWaitPlayer) CanChangeTo(s base.SceneState) bool {
switch s.GetState() {
case rule.SceneStateWaitStart:
return true
default:
return false
}
}
func (this *SceneStateWaitPlayer) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
if s.IsMatchScene() {
return false
}
return true
}
func (this *SceneStateWaitPlayer) OnEnter(s *base.Scene) {
this.SceneStateBase.OnEnter(s)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
sceneEx.Clear()
sceneEx.SetGaming(false)
this.BroadcastRoomState(s, this.GetState())
}
}
// 状态离开时
func (this *SceneStateWaitPlayer) OnLeave(s *base.Scene) {
this.SceneStateBase.OnLeave(s)
logger.Logger.Tracef("(this *SceneWaitPlayerStateChesstitians) OnLeave, sceneid=%v", s.GetSceneId())
}
// 玩家操作
func (this *SceneStateWaitPlayer) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
return true
}
return true
}
// 玩家事件
func (this *SceneStateWaitPlayer) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
logger.Logger.Trace("(this *SceneWaitPlayerStateChesstitians) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.Name, " evtcode=", evtcode)
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
if _, ok := p.GetExtraData().(*PlayerEx); ok {
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
switch evtcode {
case base.PlayerEventEnter:
// 段位等级没有设置不能玩游戏,不应该有这个错误的
if len(sceneEx.ChessRank) == 0 && s.GetGameId() != common.GameId_ChesstitiansCambodianRobot {
logger.Logger.Errorf("ChessRank not found Platform:%v", sceneEx.Platform)
sceneEx.SceneDestroy(true)
return
}
//如果有人进入, 检查在线人是否能够开启游戏,够的话,切换到延迟开启状态
if sceneEx.CanStart() {
logger.Logger.Tracef("(this *SceneWaitPlayerStateChesstitians) OnPlayerEvent s.ChangeSceneState(SceneStateWaitStart) %v", s.GetSceneId())
s.ChangeSceneState(rule.SceneStateWaitStart)
}
}
}
}
}
func (this *SceneStateWaitPlayer) OnTick(s *base.Scene) {
this.SceneStateBase.OnTick(s)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
if s.CheckNeedDestroy() {
sceneEx.SceneDestroy(true)
return
}
if sceneEx.CanStart() {
logger.Logger.Tracef("(this *SceneWaitPlayerStateChesstitians) OnTick s.ChangeSceneState(SceneStateWaitStart) %v", s.GetSceneId())
s.ChangeSceneState(rule.SceneStateWaitStart)
} else if !s.GetGaming() && s.GetRobotNum() == 1 {
tNow := time.Now()
for _, p := range s.Players {
if p.IsRob && tNow.Sub(p.GetLastOPTimer()) > time.Second*time.Duration(30+rand.Int63n(60)) {
//p.LastOPTimer = tNow.Add(time.Minute * 30)
s.PlayerLeave(p, common.PlayerLeaveReason_Normal, true)
}
}
}
}
}
//=====================================
// SceneStateWaitStart 开始游戏
//=====================================
type SceneStateWaitStart struct {
SceneStateBase
}
func (this *SceneStateWaitStart) GetState() int {
return rule.SceneStateWaitStart
}
func (this *SceneStateWaitStart) CanChangeTo(s base.SceneState) bool {
switch s.GetState() {
case rule.SceneStateWaitPlayer, rule.SceneStateWaitStart, rule.SceneStateChessInit:
return true
default:
return false
}
}
// 当前状态能否换桌
func (this *SceneStateWaitStart) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
if s.IsMatchScene() {
return false
}
return true
}
func (this *SceneStateWaitStart) OnEnter(s *base.Scene) {
this.SceneStateBase.OnEnter(s)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
sceneEx.Clear()
sceneEx.SetGaming(false)
this.BroadcastRoomState(s, this.GetState())
logger.Logger.Trace("(this *SceneWaitStartStateChesstitians) OnEnter", this.GetState())
}
}
// 状态离开时
func (this *SceneStateWaitStart) OnLeave(s *base.Scene) {
this.SceneStateBase.OnLeave(s)
logger.Logger.Tracef("(this *SceneWaitStartStateChesstitians) OnLeave", this.GetState())
}
// 玩家操作
func (this *SceneStateWaitStart) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
return true
}
sceneEx, _ := s.GetExtraData().(*SceneEx)
if sceneEx != nil {
playerEx, _ := p.GetExtraData().(*PlayerEx)
if playerEx != nil {
opRetCode := chesstitians.OpResultCode_OPRC_Error
if playerEx.SnId == sceneEx.masterSnId && this.GetState() == rule.SceneStateWaitStart {
if sceneEx.IsMatchScene() {
return false
}
switch int32(opcode) {
case rule.PlayerOpStart: //房主开始游戏
if sceneEx.CanStart() == false {
s.ChangeSceneState(rule.SceneStateWaitPlayer)
} else {
opRetCode = chesstitians.OpResultCode_OPRC_Sucess
s.ChangeSceneState(rule.SceneStateChessInit)
}
}
}
if opRetCode == chesstitians.OpResultCode_OPRC_Sucess {
sceneEx.OnPlayerSCOp(p, opcode, opRetCode, params)
} else {
logger.Logger.Tracef("SceneWaitStartStateChesstitians OnPlayerOp snid:%v, masterSnId:%v", playerEx.SnId, sceneEx.masterSnId)
}
}
}
return true
}
// 玩家事件
func (this *SceneStateWaitStart) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
logger.Logger.Trace("(this *SceneWaitStartStateChesstitians) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.Name, " evtcode=", evtcode)
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
switch evtcode {
case base.PlayerEventLeave:
//如果有人退出, 检查在线人是否能够开启游戏,不够的话,切换到等待状态
if !sceneEx.CanStart() {
s.ChangeSceneState(rule.SceneStateWaitPlayer)
}
}
}
}
func (this *SceneStateWaitStart) OnTick(s *base.Scene) {
this.SceneStateBase.OnTick(s)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
if sceneEx.IsMatchScene() {
delayT := time.Second * 2
if sceneEx.GetMatch().GetCurrRound() != 1 { //第一轮延迟2s其他延迟3s 配合客户端播放动画
delayT = time.Second * 4
}
if time.Now().Sub(sceneEx.StateStartTime) > delayT {
s.ChangeSceneState(rule.SceneStateChessInit) // 比赛场直接发牌
return
}
}
if time.Now().Sub(sceneEx.StateStartTime) > rule.WaitStartTimeout {
//开始前再次检查开始条件
if sceneEx.CanStart() {
s.ChangeSceneState(rule.SceneStateChessInit)
} else {
s.ChangeSceneState(rule.SceneStateWaitPlayer)
}
}
}
}
//=====================================
// SceneStateChessInit 棋盘初始化
//=====================================
type SceneStateChessInit struct {
SceneStateBase
}
func (this *SceneStateChessInit) GetState() int {
return rule.SceneStateChessInit
}
func (this *SceneStateChessInit) CanChangeTo(s base.SceneState) bool {
if s.GetState() == rule.SceneStatePlayerOp {
return true
}
return false
}
func (this *SceneStateChessInit) OnEnter(s *base.Scene) {
this.SceneStateBase.OnEnter(s)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
sceneEx.Clear()
sceneEx.SetGaming(true)
sceneEx.GameNowTime = time.Now()
sceneEx.AllPlayerEnterGame()
//参与游戏次数
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
playerEx := sceneEx.seats[i]
if playerEx != nil {
if playerEx.IsGameing() {
playerEx.GameTimes++
}
}
}
s.NumOfGames++
s.NotifySceneRoundStart(s.NumOfGames)
this.BroadcastRoomState(s, this.GetState(), int64(s.NumOfGames))
//发牌
sceneEx.ChessInit()
}
}
// 状态离开时
func (this *SceneStateChessInit) OnLeave(s *base.Scene) {
this.SceneStateBase.OnLeave(s)
logger.Logger.Tracef("(this *SceneHandCardStateChesstitians) OnLeave, sceneid=%v", s.GetSceneId())
}
// 玩家操作
func (this *SceneStateChessInit) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
return true
}
return true
}
// 玩家事件
func (this *SceneStateChessInit) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
logger.Logger.Trace("(this *SceneHandCardStateChesstitians) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.Name, " evtcode=", evtcode)
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
}
func (this *SceneStateChessInit) OnTick(s *base.Scene) {
this.SceneStateBase.OnTick(s)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
if time.Now().Sub(sceneEx.StateStartTime) > rule.HandCardTimeout {
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
seat := sceneEx.seats[i]
if !seat.isBlack {
sceneEx.SetCurOpPos(seat.GetPos())
}
}
s.ChangeSceneState(rule.SceneStatePlayerOp)
}
}
}
//=====================================
// SceneStatePlayerOp 玩家操作状态
//=====================================
type SceneStatePlayerOp struct {
SceneStateBase
}
func (this *SceneStatePlayerOp) GetState() int {
return rule.SceneStatePlayerOp
}
func (this *SceneStatePlayerOp) CanChangeTo(s base.SceneState) bool {
if s.GetState() == rule.SceneStateBilled {
return true
}
return false
}
func (this *SceneStatePlayerOp) OnEnter(s *base.Scene) {
this.SceneStateBase.OnEnter(s)
this.BroadcastRoomState(s, this.GetState())
}
// 状态离开时
func (this *SceneStatePlayerOp) OnLeave(s *base.Scene) {
this.SceneStateBase.OnLeave(s)
logger.Logger.Tracef("(this *SceneHandCardStateChesstitians) OnLeave, sceneid=%v", s.GetSceneId())
}
// 玩家操作
func (this *SceneStatePlayerOp) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
return true
}
this.OnPlayerOpNormal(s, p, opcode, params)
this.OnPlayerOpAI(s, p, opcode, params)
return true
}
func (this *SceneStatePlayerOp) OnPlayerOpNormal(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
sceneEx, ok := s.GetExtraData().(*SceneEx)
if !ok {
return true
}
if sceneEx == nil {
return true
}
playerEx, ok := p.GetExtraData().(*PlayerEx)
if !ok {
return true
}
if playerEx == nil {
return true
}
returnFunc := func(code chesstitians.OpResultCode) {
if code == chesstitians.OpResultCode_OPRC_Sucess {
// 可以成功行棋,则同步给所有的玩家
sceneEx.BroadcastPlayerSCOp(playerEx.SnId, opcode, code, params)
if sceneEx.winSnId != 0 {
sceneEx.ChangeSceneState(rule.SceneStateBilled)
}
} else {
// 若不能成功操作,仅发给操作的玩家
sceneEx.OnPlayerSCOp(p, opcode, code, params)
}
}
switch int32(opcode) {
case rule.PlayerOpPlay: // 玩家行棋
if sceneEx.GetCurOpPos() != playerEx.GetPos() {
return false
}
if len(params) != 2 {
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
}
if sceneEx.PlayChess(params) {
// 轮换当前操作标记
sceneEx.NextOpPos()
sceneEx.StateStartTime = time.Now()
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
return true
}
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
case rule.PlayerOpSurrender: // 投降
for _, seat := range sceneEx.seats {
if seat != nil {
if seat.GetSnId() != playerEx.GetSnId() {
sceneEx.winSnId = seat.GetSnId()
break
}
}
}
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
return true
case rule.PlayerOpDraw: // 求和
if len(params) == 0 {
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
}
switch params[0] {
case rule.RequestDraw:
if sceneEx.RequestDraw(playerEx) {
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
return true
}
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
case rule.CancelDraw:
if sceneEx.CancelDraw(playerEx) {
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
return true
}
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
case rule.RefuseDraw:
if sceneEx.RefuseDraw(playerEx) {
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
return true
}
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
case rule.AgreeDraw:
if sceneEx.AgreeDraw(playerEx) {
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
return true
}
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
}
case rule.PlayerOpStep: // 计步操作
// 参数校验
if len(params) == 0 {
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
}
switch params[0] {
case rule.StepStart: // 开始计步
if sceneEx.StartStep(playerEx) {
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
return true
}
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
case rule.StepCancel: // 取消计步
if sceneEx.CancelStep(playerEx) {
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
return true
}
returnFunc(chesstitians.OpResultCode_OPRC_Error)
return true
}
case rule.PlayerOpTest: // 测试 强制同步给所有的玩家
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
return true
case rule.PlayerOpWin:
if common.Config.IsDevMode {
for _, seat := range sceneEx.seats {
if seat != nil {
if seat.GetSnId() == playerEx.GetSnId() {
sceneEx.winSnId = seat.GetSnId()
break
}
}
}
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
}
return true
}
return true
}
func (this *SceneStatePlayerOp) OnPlayerOpAI(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
return true
}
// 玩家事件
func (this *SceneStatePlayerOp) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
logger.Logger.Trace("(this *SceneHandCardStateChesstitians) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.Name, " evtcode=", evtcode)
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
}
func (this *SceneStatePlayerOp) OnTick(s *base.Scene) {
this.SceneStateBase.OnTick(s)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
now := time.Now()
f := func() {
// 玩家操作超时,输
for k, v := range sceneEx.seats {
if k != sceneEx.GetCurOpPos() && v != nil {
sceneEx.winSnId = v.GetSnId()
sceneEx.ChangeSceneState(rule.SceneStateBilled)
break
}
}
}
if sceneEx.chess.GetRound() == 1 || sceneEx.chess.GetRound() == 2 {
if now.Sub(sceneEx.StateStartTime) > rule.PlayerFirstOpTimeout {
f()
}
} else {
if now.Sub(sceneEx.StateStartTime) > rule.PlayerOpTimeout {
f()
}
}
curPlayer := sceneEx.seats[sceneEx.GetCurOpPos()]
if time.Duration(curPlayer.getTotalTime())*time.Second >= rule.PlayerTotalTime {
f()
}
}
}
//=====================================
// SceneStateBilled 结算
//=====================================
type SceneStateBilled struct {
SceneStateBase
}
func (this *SceneStateBilled) GetState() int {
return rule.SceneStateBilled
}
func (this *SceneStateBilled) CanChangeTo(s base.SceneState) bool {
switch s.GetState() {
case rule.SceneStateWaitPlayer, rule.SceneStateWaitStart:
return true
default:
return false
}
}
func (this *SceneStateBilled) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
return true
}
func (this *SceneStateBilled) OnEnter(s *base.Scene) {
this.SceneStateBase.OnEnter(s)
this.BroadcastRoomState(s, this.GetState())
sceneEx, ok := s.GetExtraData().(*SceneEx)
if !ok {
return
}
pack := &chesstitians.SCChesstitiansGameBilled{}
chessType := model.ChesstitiansType{
GameId: int(sceneEx.GameId),
RoomId: int32(sceneEx.GetSceneId()),
RoomType: sceneEx.Scene.GetDBGameFree().GetSceneType(),
NumOfGames: int32(sceneEx.Scene.NumOfGames),
BankId: sceneEx.masterSnId,
PlayerCount: rule.MaxNumOfPlayer,
BaseScore: s.BaseScore,
TaxRate: s.GetDBGameFree().GetTaxRate(),
RoomMode: s.GetSceneMode(),
}
var winPlayer *PlayerEx
var losePlayer *PlayerEx
var draw bool
for _, seat := range sceneEx.seats {
if seat != nil {
if sceneEx.winSnId == seat.GetSnId() {
winPlayer = seat
} else {
losePlayer = seat
}
}
}
if winPlayer == nil {
draw = true
winPlayer = sceneEx.seats[0]
losePlayer = sceneEx.seats[1]
}
if draw { // 平局
billData, chessPerson := sceneEx.ToBilled(winPlayer, losePlayer, rule.Draw)
pack.Datas = append(pack.Datas, billData)
chessType.PlayerData = append(chessType.PlayerData, chessPerson)
//玩家2
billData1, chessPerson1 := sceneEx.ToBilled(losePlayer, winPlayer, rule.Draw)
pack.Datas = append(pack.Datas, billData1)
chessType.PlayerData = append(chessType.PlayerData, chessPerson1)
} else { // 有输赢
billData, chessPerson := sceneEx.ToBilled(winPlayer, losePlayer, rule.Win)
pack.Datas = append(pack.Datas, billData)
chessType.PlayerData = append(chessType.PlayerData, chessPerson)
// 输家
billData1, chessPerson1 := sceneEx.ToBilled(losePlayer, winPlayer, rule.Lose)
pack.Datas = append(pack.Datas, billData1)
chessType.PlayerData = append(chessType.PlayerData, chessPerson1)
}
proto.SetDefaults(pack)
s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansGameBilled), pack, 0)
logger.Logger.Trace("ChesstitiansPacketID_PACKET_SCChesstitiansGameBilled gameFreeId:", sceneEx.GetGameFreeId(), ";pack:", pack)
info, err := model.MarshalGameNoteByFIGHT(&chessType)
if err == nil {
isSave := false
var logid string
for _, o_player := range chessType.PlayerData {
if !sceneEx.Testing && !o_player.IsRob {
if logid == "" {
logid, _ = model.AutoIncGameLogId()
}
var totalin, totalout int64
if o_player.GainCoin < 0 {
totalin -= (o_player.GainCoin + o_player.GainTaxCoin)
} else {
totalout += (o_player.GainCoin + o_player.GainTaxCoin)
}
sceneEx.SaveFriendRecord(o_player.UserId, o_player.IsWin, o_player.GainCoin, sceneEx.GetBaseScore())
// 游戏数据统计
sceneEx.Statistics(&base.StaticParam{
SnId: o_player.UserId,
Gain: o_player.GainCoin,
GainTax: o_player.GainTaxCoin,
IsAddTimes: true,
HasRobotGaming: sceneEx.GetGamingRobotCnt() > 0,
})
// 玩家游戏记录
sceneEx.SaveGamePlayerListLog(&base.SaveGamePlayerListLogParam{
LogId: logid,
Platform: o_player.Platform,
Snid: o_player.UserId,
PlayerName: "",
Channel: o_player.Channel,
ChannelId: o_player.ChannelId,
TotalIn: totalin,
TotalOut: totalout,
TaxCoin: o_player.GainTaxCoin,
BetAmount: 0,
WinAmountNoAnyTax: o_player.GainCoin,
IsFirstGame: o_player.IsFirst,
})
isSave = true
}
}
if isSave {
// 牌局记录
sceneEx.SaveGameDetailedLog(&base.SaveGameDetailedParam{
LogId: logid,
Detail: info,
})
}
}
sceneEx.NotifySceneRoundPause()
}
// 玩家操作
func (this *SceneStateBilled) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
return true
}
sceneEx, ok := s.GetExtraData().(*SceneEx)
if !ok {
return true
}
if sceneEx == nil {
return true
}
playerEx, ok := p.GetExtraData().(*PlayerEx)
if !ok {
return true
}
if playerEx == nil {
return true
}
returnFunc := func(code chesstitians.OpResultCode) {
if code == chesstitians.OpResultCode_OPRC_Sucess {
sceneEx.BroadcastPlayerSCOp(playerEx.SnId, opcode, code, params)
} else {
// 若不能成功操作,仅发给操作的玩家
sceneEx.OnPlayerSCOp(p, opcode, code, params)
}
}
switch int32(opcode) {
case rule.PlayerOpNextPlay: // 再来一局
if playerEx.nextPlay {
return false
}
playerEx.nextPlay = true
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
if sceneEx.nextSnId == 0 {
sceneEx.nextSnId = playerEx.GetSnId()
}
if sceneEx.seats[0].nextPlay && sceneEx.seats[1].nextPlay ||
sceneEx.GetGameId() == common.GameId_ChesstitiansCambodianRobot {
s.ChangeSceneState(rule.SceneStateWaitStart)
}
return true
}
return true
}
// 玩家事件
func (this *SceneStateBilled) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
switch evtcode {
case base.PlayerEventLeave:
// 有人离开,解散房间
for _, v := range sceneEx.seats {
if v != nil {
sceneEx.PlayerLeave(v.Player, common.PlayerLeaveReason_OnBilled, true)
}
}
}
}
}
func (this *SceneStateBilled) OnTick(s *base.Scene) {
this.SceneStateBase.OnTick(s)
sceneEx, ok := s.GetExtraData().(*SceneEx)
if !ok {
return
}
// 有机器人,让机器人离开
for _, v := range sceneEx.seats {
if v != nil && v.IsRob {
sceneEx.PlayerLeave(v.Player, common.PlayerLeaveReason_OnBilled, true)
}
}
if sceneEx.GetRealPlayerNum() == 1 {
for _, v := range sceneEx.seats {
if v != nil {
sceneEx.PlayerLeave(v.Player, common.PlayerLeaveReason_OnBilled, true)
}
}
}
if sceneEx.GetPlayerCnt() == 0 {
sceneEx.SceneDestroy(true)
}
}
// 状态离开时
func (this *SceneStateBilled) OnLeave(s *base.Scene) {
this.SceneStateBase.OnLeave(s)
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
sceneEx.SetGaming(false)
switch sceneEx.GetGameId() {
case common.GameId_Chesstitians, common.GameId_ChesstitiansMakruk, common.GameId_ChesstitiansCambodian:
hasLeave := false
//剔除下线玩家
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
playerEx := sceneEx.seats[i]
if playerEx == nil {
continue
}
playerEx.Clear()
if sceneEx.IsMatchScene() {
continue
}
if !playerEx.IsOnLine() {
sceneEx.PlayerLeave(playerEx.Player, common.PlayerLeaveReason_DropLine, true)
hasLeave = true
continue
}
// 机器人金币离场检查
if playerEx.IsRob {
if s.CoinOverMaxLimit(playerEx.GetCoin(), playerEx.Player) {
sceneEx.PlayerLeave(playerEx.Player, common.PlayerLeaveReason_Normal, true)
hasLeave = true
continue
}
}
// 低于进场限额
if !s.CoinInLimit(playerEx.GetCoin()) {
sceneEx.PlayerLeave(playerEx.Player, s.NotCoinInLimitType(playerEx.GetCoin()), true)
hasLeave = true
continue
}
}
if !hasLeave && !sceneEx.IsRobFightGame() && !sceneEx.IsMatchScene() {
s.TryDismissRob()
}
case common.GameId_ChesstitiansCambodianRobot:
sceneEx.SceneDestroy(true)
return
}
if s.CheckNeedDestroy() || (s.IsMatchScene() && (!s.GetMatch().GetIsFinals() || (s.GetMatch().GetIsFinals() && s.NumOfGames >= 2))) { // 非决赛打一场 决赛打两场
sceneEx.SceneDestroy(true)
}
s.TryRelease()
}
}
func (this *ScenePolicyEntity) RegisteSceneState(state base.SceneState) {
if state == nil {
return
}
stateId := state.GetState()
if stateId < 0 || stateId >= rule.SceneStateMax {
return
}
this.states[stateId] = state
}
func (this *ScenePolicyEntity) GetSceneState(s *base.Scene, stateId int) base.SceneState {
if stateId >= 0 && stateId < rule.SceneStateMax {
return this.states[stateId]
}
return nil
}
func init() {
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStateWaitPlayer{})
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStateWaitStart{})
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStateChessInit{})
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStatePlayerOp{})
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStateBilled{})
core.RegisteHook(core.HOOK_BEFORE_START, func() error {
base.RegisteScenePolicy(common.GameId_Chesstitians, 0, ScenePolicyEntitySingleton)
base.RegisteScenePolicy(common.GameId_ChesstitiansMakruk, 0, ScenePolicyEntitySingleton)
base.RegisteScenePolicy(common.GameId_ChesstitiansCambodian, 0, ScenePolicyEntitySingleton)
base.RegisteScenePolicy(common.GameId_ChesstitiansCambodianRobot, 0, ScenePolicyEntitySingleton)
return nil
})
}