package thirteen import ( "strconv" "time" "mongo.games.com/goserver/core" "mongo.games.com/goserver/core/logger" "mongo.games.com/game/common" rule "mongo.games.com/game/gamerule/thirteen" "mongo.games.com/game/gamesrv/base" "mongo.games.com/game/model" "mongo.games.com/game/proto" "mongo.games.com/game/protocol/thirteen" ) var PolicyThirteenSingleton = &PolicyThirteen{} type PolicyThirteen struct { base.BaseScenePolicy states [rule.ThirteenWaterSceneStateMax]base.SceneState } func (this *PolicyThirteen) CreateSceneExData(s *base.Scene) interface{} { sceneEx := NewThirteenWaterSceneData(s) if sceneEx != nil { if sceneEx.init() { s.ExtraData = sceneEx } } return sceneEx } func (this *PolicyThirteen) CreatePlayerExData(s *base.Scene, p *base.Player) interface{} { playerEx := &PlayerEx{Player: p} if playerEx != nil { p.ExtraData = playerEx } return playerEx } func (this *PolicyThirteen) OnStart(s *base.Scene) { logger.Logger.Trace("(this *PolicyThirteen) OnStart, sceneId=", s.GetSceneId()) sceneEx := NewThirteenWaterSceneData(s) if sceneEx != nil { if sceneEx.init() { s.ExtraData = sceneEx s.ChangeSceneState(rule.ThirteenWaterSceneStateWait) } } } func (this *PolicyThirteen) OnStop(s *base.Scene) { logger.Logger.Trace("(this *PolicyThirteen) OnStop , sceneId=", s.GetSceneId()) } func (this *PolicyThirteen) OnTick(s *base.Scene) { if s == nil { return } if s.SceneState != nil { s.SceneState.OnTick(s) } } func (this *PolicyThirteen) OnPlayerEnter(s *base.Scene, p *base.Player) { if s == nil || p == nil { return } logger.Logger.Trace("(this *PolicyThirteen) OnPlayerEnter, sceneId=", s.GetSceneId(), " player=", p.SnId) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { pos := -1 for i := 0; i < sceneEx.GetPlayerNum(); i++ { if sceneEx.seats[i] == nil { pos = i break } } if pos != -1 { playerEx := &PlayerEx{Player: p} sceneEx.seats[pos] = playerEx sceneEx.players[p.SnId] = playerEx p.Pos = pos p.ExtraData = playerEx playerEx.Clear() if sceneEx.Gaming { p.MarkFlag(base.PlayerState_WaitNext) p.UnmarkFlag(base.PlayerState_Ready) } //send msg if len(s.Players) > 1 { //向其他人广播玩家进入信息 pack := &thirteen.SCThirteenPlayerEnter{ Data: &thirteen.ThirteenPlayerData{ SnId: proto.Int32(p.SnId), Name: proto.String(p.Name), Head: proto.Int32(p.Head), Sex: proto.Int32(p.Sex), Coin: proto.Int64(p.Coin), Pos: proto.Int(pos), Flag: proto.Int(p.GetFlag()), Longitude: proto.Int32(p.Longitude), Latitude: proto.Int32(p.Latitude), City: proto.String(p.City), //Params: proto.String(p.Params), AgentCode: proto.String(p.AgentCode), HeadOutLine: proto.Int32(p.HeadOutLine), VIP: proto.Int32(p.VIP), RoleId: p.PlayerData.GetRoleId(), Level: proto.Int64(p.Level), Exp: proto.Int64(p.Exp), }, } proto.SetDefaults(pack) logger.Logger.Trace("SCThirteenWaterPlayerEnter:", pack) s.Broadcast(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerEnter), pack, p.GetSid()) } //给自己发送房间信息 this.SendRoomInfo(s, p, sceneEx) s.FirePlayerEvent(p, base.PlayerEventEnter, nil) } } } func (this *PolicyThirteen) OnPlayerLeave(s *base.Scene, p *base.Player, reason int) { logger.Logger.Trace("(this *PolicyThirteen) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId) if s == nil || p == nil { return } if !this.CanChangeCoinScene(s, p) { return } sceneEx, ok := s.ExtraData.(*SceneEx) if !ok { return } playerEx, ok := p.ExtraData.(*PlayerEx) if !ok { return } if !playerEx.IsGameing() { sceneEx.OnPlayerLeave(p, reason) s.FirePlayerEvent(p, base.PlayerEventLeave, nil) return } isBilled := false switch sceneEx.GetSceneState().GetState() { case rule.ThirteenWaterSceneStateSendCards, rule.ThirteenWaterSceneStateOptCard: // 发牌,选牌,离场扣分 n := sceneEx.GetLeaveDeductCoin() if playerEx.Coin < n { // 不够扣,不能离开 return } playerEx.AddCoin(-n, common.GainWay_LeaveDeduct, base.SyncFlag_ToClient, "system", s.GetSceneName()) sceneEx.LeaveNum++ case rule.ThirteenWaterSceneStateShowCards, rule.ThirteenWaterSceneStateHit: // 亮牌,打枪,提前结算;(重连和结算使用备份数据) isBilled = true if playerEx.gainCoin > 0 { //税前赢的钱 税收 下注额 playerEx.AddServiceFee(playerEx.taxCoin) playerEx.AddCoin(int64(playerEx.gainCoin), common.GainWay_CoinSceneWin, base.SyncFlag_ToClient, "system", s.GetSceneName()) playerEx.CurIsWin = 1 } else if playerEx.gainCoin < 0 { playerEx.AddCoin(playerEx.gainCoin, common.GainWay_CoinSceneLost, base.SyncFlag_ToClient, "system", s.GetSceneName()) playerEx.CurIsWin = -1 } // 离场补偿分 if playerEx.score[6] > 0 { playerEx.AddCoin(playerEx.score[6]*int64(sceneEx.GetBaseScore()), common.GainWay_LeaveCombat, base.SyncFlag_ToClient, "system", s.GetSceneName()) } if playerEx.IsGameing() && !playerEx.IsRob { totalin, totalout := int64(0), int64(0) if playerEx.CurIsWin > 0 { totalout = playerEx.gainCoin + playerEx.taxCoin } else { totalin -= playerEx.gainCoin } //validFlow := totalin + totalout //validBet := common.AbsI64(totalin - totalout) sceneEx.SaveGamePlayerListLog(&base.SaveGamePlayerListLogParam{ LogId: sceneEx.logid, Platform: playerEx.Platform, Snid: playerEx.SnId, PlayerName: playerEx.Name, Channel: playerEx.Channel, ChannelId: playerEx.ChannelId, TotalIn: totalin, TotalOut: totalout, TaxCoin: playerEx.taxCoin, BetAmount: 0, WinAmountNoAnyTax: playerEx.gainCoin, IsFirstGame: sceneEx.IsPlayerFirst(sceneEx.GetPlayer(playerEx.SnId)), }) sceneEx.Statistics(&base.StaticParam{ SnId: playerEx.SnId, Gain: playerEx.gainCoin, GainTax: playerEx.taxCoin, IsAddTimes: true, HasRobotGaming: sceneEx.robotNum > 0, }) } } // 游戏已开始但未结算,玩家离开,备份玩家数据 if sceneEx.Gaming && playerEx.IsGameing() { sceneEx.BackupPlayer(playerEx, isBilled) } // 清理玩家数据 sceneEx.OnPlayerLeave(p, reason) s.FirePlayerEvent(p, base.PlayerEventLeave, nil) } func (this *PolicyThirteen) OnPlayerDropLine(s *base.Scene, p *base.Player) { if s == nil || p == nil { return } logger.Logger.Trace("(this *PolicyThirteen) OnPlayerDropLine, sceneId=", s.GetSceneId(), " player=", p.SnId) s.FirePlayerEvent(p, base.PlayerEventDropLine, nil) } func (this *PolicyThirteen) OnPlayerRehold(s *base.Scene, p *base.Player) { if s == nil || p == nil { return } logger.Logger.Trace("(this *PolicyThirteen) OnPlayerRehold, sceneId=", s.GetSceneId(), " player=", p.SnId) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { if _, ok := p.ExtraData.(*PlayerEx); ok { //发送房间信息给自己 if p.IsGameing() { p.MarkFlag(base.PlayerState_Ready) } this.SendRoomInfo(s, p, sceneEx) s.FirePlayerEvent(p, base.PlayerEventRehold, nil) } } } func (this *PolicyThirteen) OnPlayerReturn(s *base.Scene, p *base.Player) { if s == nil || p == nil { return } logger.Logger.Trace("(this *PolicyThirteen) OnPlayerRehold, sceneId=", s.GetSceneId(), " player=", p.SnId) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { if _, ok := p.ExtraData.(*PlayerEx); ok { //发送房间信息给自己 if p.IsGameing() { p.MarkFlag(base.PlayerState_Ready) } this.SendRoomInfo(s, p, sceneEx) s.FirePlayerEvent(p, base.PlayerEventReturn, nil) } } } func (this *PolicyThirteen) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool { if s == nil || p == nil { return false } logger.Logger.Trace("(this *PolicyThirteen) OnPlayerOp, sceneId=", s.GetSceneId(), " player=", p.SnId, " opcode=", opcode, " params=", params) if s.SceneState != nil { p.LastOPTimer = time.Now() p.Trusteeship = 0 return s.SceneState.OnPlayerOp(s, p, opcode, params) } return true } func (this *PolicyThirteen) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) { if s == nil || p == nil { return } logger.Logger.Trace("(this *PolicyThirteen) OnPlayerEvent, sceneId=", s.GetSceneId(), " player=", p.SnId, " eventcode=", evtcode, " params=", params) if s.SceneState != nil { s.SceneState.OnPlayerEvent(s, p, evtcode, params) } } func (this *PolicyThirteen) OnAudienceEnter(s *base.Scene, p *base.Player) { if s == nil || p == nil { return } logger.Logger.Trace("(this *PolicyThirteen) OnAudienceEnter, sceneId=", s.GetSceneId(), " player=", p.SnId) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { //给自己发送房间信息 this.SendRoomInfo(s, p, sceneEx) s.FirePlayerEvent(p, base.AudienceEventEnter, nil) } } func (this *PolicyThirteen) OnAudienceLeave(s *base.Scene, p *base.Player, reason int) { if s == nil || p == nil { return } logger.Logger.Trace("(this *PolicyThirteen) OnAudienceLeave, sceneId=", s.GetSceneId(), " player=", p.SnId) s.FirePlayerEvent(p, base.AudienceEventLeave, nil) } func (this *PolicyThirteen) OnAudienceDropLine(s *base.Scene, p *base.Player) { if s == nil || p == nil { return } logger.Logger.Trace("(this *PolicyThirteen) OnAudienceDropLine, sceneId=", s.GetSceneId(), " player=", p.SnId) s.AudienceLeave(p, common.PlayerLeaveReason_DropLine) s.FirePlayerEvent(p, base.AudienceEventDropLine, nil) } func (this *PolicyThirteen) OnAudienceSit(s *base.Scene, p *base.Player) { //十三水观众坐下 if s == nil || p == nil { return } logger.Logger.Trace("(this *PolicyThirteen) OnAudienceSit, sceneId=", s.GetSceneId(), " player=", p.GetName()) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { pos := p.Pos if pos != -1 && sceneEx.seats[pos] == nil { playerEx := &PlayerEx{Player: p} sceneEx.seats[pos] = playerEx sceneEx.players[p.SnId] = playerEx p.Pos = pos p.ExtraData = playerEx playerEx.Clear() if sceneEx.Gaming { p.MarkFlag(base.PlayerState_WaitNext) p.UnmarkFlag(base.PlayerState_Ready) p.SyncFlag() } //send msg if len(s.Players) > 1 { //向其他人广播玩家进入信息 pack := &thirteen.SCThirteenPlayerEnter{ Data: &thirteen.ThirteenPlayerData{ SnId: proto.Int32(p.SnId), Name: proto.String(p.Name), Head: proto.Int32(p.Head), Sex: proto.Int32(p.Sex), Coin: proto.Int64(p.Coin), Pos: proto.Int(pos), Flag: proto.Int(p.GetFlag()), Longitude: proto.Int32(p.Longitude), Latitude: proto.Int32(p.Latitude), City: proto.String(p.City), HeadOutLine: proto.Int32(p.HeadOutLine), VIP: proto.Int32(p.VIP), RoleId: p.PlayerData.GetRoleId(), Level: proto.Int64(p.Level), Exp: proto.Int64(p.Exp), }, } proto.SetDefaults(pack) s.Broadcast(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerEnter), pack, p.GetSid()) } //给自己发送房间信息 this.SendRoomInfo(s, p, sceneEx) //sceneEx.CheckAndSendDisbandInfo(p) } s.FirePlayerEvent(p, base.PlayerEventEnter, nil) } } func (this *PolicyThirteen) IsCompleted(s *base.Scene) bool { if s == nil { return false } if sceneEx, ok := s.ExtraData.(*SceneEx); ok { return !sceneEx.Gaming } return false } func (this *PolicyThirteen) IsCanForceStart(s *base.Scene) bool { if sceneEx, ok := s.ExtraData.(*SceneEx); ok { return len(s.Players) >= 2 && !sceneEx.Gaming } return false } func (this *PolicyThirteen) ForceStart(s *base.Scene) { if sceneEx, ok := s.ExtraData.(*SceneEx); ok { if sceneEx.SceneState.GetState() == rule.ThirteenWaterSceneStateWait { s.ChangeSceneState(rule.ThirteenWaterSceneStateStart) } } } func (this *PolicyThirteen) CanChangeCoinScene(s *base.Scene, p *base.Player) bool { if s == nil || p == nil { return false } if s.SceneState != nil { return s.SceneState.CanChangeCoinScene(s, p) } return false } func (this *PolicyThirteen) SendRoomInfo(s *base.Scene, p *base.Player, sceneEx *SceneEx) { pack := sceneEx.ThirteenWaterCreateRoomInfoPacket(s, p) p.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenRoomInfo), pack) } func ThirteenWaterBroadcastRoomState(s *base.Scene, params ...int32) { pack := &thirteen.SCThirteenRoomState{ State: proto.Int(s.SceneState.GetState()), Params: params, } s.Broadcast(int(thirteen.TWMmoPacketID_PACKET_SCThirteenRoomState), pack, 0) } //===================================== // BaseState 状态基类 //===================================== type BaseState struct { } func (this *BaseState) GetTimeout(s *base.Scene) int { if sceneEx, ok := s.ExtraData.(*SceneEx); ok { return int(time.Now().Sub(sceneEx.StateStartTime) / time.Second) } return 0 } func (this *BaseState) CanChangeTo(s base.SceneState) bool { return true } func (this *BaseState) CanChangeCoinScene(s *base.Scene, p *base.Player) bool { sceneEx, ok := s.ExtraData.(*SceneEx) if !ok { return false } playerEx, ok := p.ExtraData.(*PlayerEx) if !ok { return false } if !playerEx.IsGameing() { return true } switch sceneEx.GetSceneState().GetState() { case rule.ThirteenWaterSceneStateSendCards, rule.ThirteenWaterSceneStateOptCard: if playerEx.Coin < sceneEx.GetLeaveDeductCoin() { // 不够扣,不能离开 return false } } return true } func (this *BaseState) OnEnter(s *base.Scene) { if sceneEx, ok := s.ExtraData.(*SceneEx); ok { sceneEx.StateStartTime = time.Now() } } func (this *BaseState) OnLeave(s *base.Scene) {} func (this *BaseState) OnTick(s *base.Scene) {} func (this *BaseState) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool { playerEx, ok := p.ExtraData.(*PlayerEx) if !ok { return false } sceneEx, ok := s.ExtraData.(*SceneEx) if !ok { return false } switch opcode { case rule.ThirteenWaterPlayerOpStandup: if len(params) > 0 { if params[0] == 0 { playerEx.isStand = true } else { playerEx.isStand = false } pack := &thirteen.SCThirteenPlayerOp{ OpRetCode: thirteen.OpResultCode_OPRC_Sucess, OpCode: int32(opcode), OpParam: params, Pos: int32(playerEx.GetPos()), } playerEx.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack) logger.Logger.Trace("TWMmoPacketID_PACKET_SCThirteenPlayerOp:", pack) } return true case rule.ThirteenWaterPlayerOpTest: if !common.Config.IsDevMode { return false } sceneEx.testPokers = make([]int64, len(params)) copy(sceneEx.testPokers, params) return true case rule.ThirteenWaterPlayerJoin: // 发牌和选牌阶段,给玩家发牌 if s.GetSceneState().GetState() == rule.ThirteenWaterSceneStateSendCards || (s.GetSceneState().GetState() == rule.ThirteenWaterSceneStateOptCard && int(sceneEx.GetBaiPai().Seconds())-sceneEx.GetSceneState().GetTimeout(s) > 15) { if len(sceneEx.cardsArr) > 0 && playerEx.cards[0] == -1 { playerEx.MarkFlag(base.PlayerState_Ready) playerEx.UnmarkFlag(base.PlayerState_WaitNext) p.SyncFlag() playerEx.cards = sceneEx.cardsArr[0] playerEx.allGroup = sceneEx.cardsGroup[0] sceneEx.cardsArr = sceneEx.cardsArr[1:] sceneEx.cardsGroup = sceneEx.cardsGroup[1:] sceneEx.SendToPlayerCardsBySnid(p.SnId) logger.Logger.Tracef("游戏开始后给玩家发牌, sceneId=%v, player=%v, cards=%v", s.GetSceneId(), p.SnId, playerEx.cards) } } } return false } func (this *BaseState) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {} //===================================== // StateWait 匹配中 //===================================== type StateWait struct { BaseState } func (this *StateWait) GetState() int { return rule.ThirteenWaterSceneStateWait } func (this *StateWait) CanChangeTo(s base.SceneState) bool { if s.GetState() == rule.ThirteenWaterSceneStateStart { return true } return false } func (this *StateWait) GetTimeout(s *base.Scene) int { return 0 } func (this *StateWait) OnEnter(s *base.Scene) { this.BaseState.OnEnter(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { if s.Gaming { s.NotifySceneRoundPause() } s.Gaming = false ThirteenWaterBroadcastRoomState(s) if sceneEx.CanStart() { s.ChangeSceneState(rule.ThirteenWaterSceneStateStart) } } } // 玩家事件 func (this *StateWait) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) { logger.Logger.Trace("(this *StateWait) OnPlayerEvent, sceneId=", s.GetSceneId(), " player=", p.SnId, " evtcode=", evtcode) this.BaseState.OnPlayerEvent(s, p, evtcode, params) if _, ok := s.ExtraData.(*SceneEx); ok { switch evtcode { case base.PlayerEventLeave: case base.PlayerEventEnter: if !p.IsReady() { p.MarkFlag(base.PlayerState_Ready) p.SyncFlag() } } } } func (this *StateWait) OnTick(s *base.Scene) { this.BaseState.OnTick(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { if s.CheckNeedDestroy() { sceneEx.SceneDestroy(true) return } if time.Now().Sub(sceneEx.StateStartTime) > rule.ThirteenWaterSceneWaitTimeout { //切换到准备开局状态 if sceneEx.CanStart() { s.ChangeSceneState(rule.ThirteenWaterSceneStateStart) } else if s.GetRobotNum() == 1 { tNow := time.Now() for _, p := range s.Players { if p.IsRob && tNow.Sub(p.GetLastOPTimer()) > time.Second*time.Duration(30+s.Rand.Int63n(60)) { //p.LastOPTimer = tNow.Add(time.Minute * 30) s.PlayerLeave(p, common.PlayerLeaveReason_Normal, true) } } } } } } //===================================== // StateStart 开始倒计时 //===================================== type StateStart struct { BaseState } func (this *StateStart) GetState() int { return rule.ThirteenWaterSceneStateStart } func (this *StateStart) CanChangeTo(s base.SceneState) bool { switch s.GetState() { case rule.ThirteenWaterSceneStateSendCards, rule.ThirteenWaterSceneStateBilled, rule.ThirteenWaterSceneStateWait: return true } return false } func (this *StateStart) OnEnter(s *base.Scene) { this.BaseState.OnEnter(s) if _, ok := s.ExtraData.(*SceneEx); ok { ThirteenWaterBroadcastRoomState(s) s.Gaming = false } } func (this *StateStart) OnTick(s *base.Scene) { this.BaseState.OnTick(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { var second = rule.ThirteenWaterStartTimeout sub := rule.GetTimeout(sceneEx.GetDBGameFree().GetOtherIntParams(), rule.TimeoutStart) if sub > 0 { second = sub } if time.Now().Sub(sceneEx.StateStartTime) > second { if sceneEx.Creator != 0 && sceneEx.GetRealPlayerNum() == 0 { sceneEx.Destroy(true) return } //切换到等待操作状态 if sceneEx.CanStart() { s.ChangeSceneState(rule.ThirteenWaterSceneStateSendCards) } else { s.ChangeSceneState(rule.ThirteenWaterSceneStateWait) } } } } func (this *StateStart) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) { logger.Logger.Trace("(this *StateStart) OnPlayerEvent, sceneId=", s.GetSceneId(), " player=", p.SnId, " evtcode=", evtcode) this.BaseState.OnPlayerEvent(s, p, evtcode, params) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { switch evtcode { case base.PlayerEventLeave: if !sceneEx.CanStart() { logger.Logger.Tracef("(this *StateStart) OnPlayerEvent s.ChangeSceneState(ThirteenWaterSceneStateWait) %v", s.GetSceneId()) s.ChangeSceneState(rule.ThirteenWaterSceneStateWait) } case base.PlayerEventEnter: if !p.IsReady() { p.MarkFlag(base.PlayerState_Ready) p.SyncFlag() } } } } //===================================== // StateSendCard 发牌状态 //===================================== type StateSendCard struct { BaseState } func (this *StateSendCard) GetState() int { return rule.ThirteenWaterSceneStateSendCards } func (this *StateSendCard) CanChangeTo(s base.SceneState) bool { switch s.GetState() { case rule.ThirteenWaterSceneStateOptCard, rule.ThirteenWaterSceneStateWait: return true } return false } func (this *StateSendCard) OnEnter(s *base.Scene) { logger.Logger.Tracef("(this *StateSendCard) OnEnter, sceneid=%v", s.GetSceneId()) this.BaseState.OnEnter(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { s.Gaming = true sceneEx.GameNowTime = time.Now() sceneEx.logid, _ = model.AutoIncGameLogId() //通知world开始第几局 sceneEx.NumOfGames++ s.NotifySceneRoundStart(sceneEx.NumOfGames) //开始记录录像 //if !s.Testing && s.rr != nil { // pack := sceneEx.ThirteenWaterCreateRoomInfoPacket(s, nil) // if pack != nil { // s.rr.Init(int(thirteen.MmoPacketID_PACKET_SC_WINTHREE_ROOMINFO), pack) // } //} sceneEx.Clear() sceneEx.GetInGameNum() ThirteenWaterBroadcastRoomState(s, int32(sceneEx.NumOfGames)) if len(sceneEx.testPokers) > 0 { // 调试 for _, v := range sceneEx.seats { if v == nil || !v.IsGameing() { continue } if len(sceneEx.testPokers) >= 13 { for k, vv := range sceneEx.testPokers[:13] { v.cards[k] = int(vv) } v.allGroup = sceneEx.logic.Suggest(v.cards) sceneEx.testPokers = sceneEx.testPokers[13:] } else { sceneEx.testPokers = nil v.cards = sceneEx.poker.Get13Crads() } } } else { //for i := 0; i < 10; i++ { // isHaveQingLong := false // lessCoin := 0 // isF := false // for _, player := range sceneEx.players { // if player != nil && player.IsGameing() { // if isF && !player.IsRob { // player.cards = sceneEx.GetRandsType() // isF = false // } else { // player.cards = sceneEx.poker.Get13Crads() // } // player.allGroup = sceneEx.logic.Suggest(player.cards) // //todo 遇到清龙重新发牌 十次之后 不处理 // for k, v := range player.allGroup { // if k == 1000 || v.PokerType == 1 { // isHaveQingLong = true // break // } // } // if player.Coin < 108*int64(sceneEx.GetBaseScore()) { // lessCoin++ // } // } // } // if isHaveQingLong && lessCoin > 0 { // sceneEx.poker.Init() // } else { // break // } //} sceneEx.SendHandCardOdds() } sceneEx.SendToPlayerCardsBySnid(0) } } func (this *StateSendCard) OnTick(s *base.Scene) { this.BaseState.OnTick(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { var second = rule.ThirteenWaterSendCardsTimeout sub := rule.GetTimeout(sceneEx.GetDBGameFree().GetOtherIntParams(), rule.TimeoutSendCards) if sub > 0 { second = sub } if time.Now().Sub(sceneEx.StateStartTime) > second { if sceneEx.CheckNeedDestroy() { s.ChangeSceneState(rule.ThirteenWaterSceneStateWait) } else { s.ChangeSceneState(rule.ThirteenWaterSceneStateOptCard) } } } } //===================================== // StateOp 选牌状态 //===================================== type StateOp struct { BaseState } func (this *StateOp) GetState() int { return rule.ThirteenWaterSceneStateOptCard } func (this *StateOp) CanChangeTo(s base.SceneState) bool { switch s.GetState() { case rule.ThirteenWaterSceneStateShowCards: return true } return false } // 状态进入时 func (this *StateOp) OnEnter(s *base.Scene) { logger.Logger.Tracef("(this *StateOp) OnEnter, sceneid=%v", s.GetSceneId()) this.BaseState.OnEnter(s) ThirteenWaterBroadcastRoomState(s) } // 玩家操作 func (this *StateOp) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool { logger.Logger.Infof("(this *StateOp) OnPlayerOp p.snid (%v) opcode (%v)", p.SnId, opcode) if this.BaseState.OnPlayerOp(s, p, opcode, params) { return true } sceneEx, ok := s.ExtraData.(*SceneEx) if !ok { return false } playerEx, ok := p.ExtraData.(*PlayerEx) if !ok { return false } returnFunc := func(code thirteen.OpResultCode) { pack := &thirteen.SCThirteenPlayerOp{ OpRetCode: code, OpCode: int32(opcode), OpParam: params, Pos: int32(playerEx.GetPos()), } if code == thirteen.OpResultCode_OPRC_Error { proto.SetDefaults(pack) logger.Logger.Trace("SCThirteenPlayerOp:", pack) playerEx.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack) return } } if !playerEx.IsGameing() { returnFunc(thirteen.OpResultCode_OPRC_Error) return true } switch opcode { case rule.ThirteenWaterPlayerOpMS: //确定牌 //if playerEx.deterMine { // 确认牌型 // returnFunc(thirteen.OpResultCode_OPRC_Error) // return false //} if len(params) == 13 { //校验牌 a := rule.DelCards(playerEx.cards[:], common.Int64Toint(params)) if len(a) != 0 { logger.Logger.Error("the cards is error.") returnFunc(thirteen.OpResultCode_OPRC_Error) return true } //牌赋值 copy(playerEx.cardsO.Head[:], common.Int64Toint(params[:3])) copy(playerEx.cardsO.Mid[:], common.Int64Toint(params[3:8])) copy(playerEx.cardsO.End[:], common.Int64Toint(params[8:])) playerEx.cardsO.PokerType = 0 sceneEx.SendSelectCards(playerEx, 0, int64(opcode)) } else { sceneEx.SendSelectCards(playerEx, int(params[0]), int64(opcode)) } playerEx.preCardsO = &rule.Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}, PokerType: -1} playerEx.Trusteeship = 0 playerEx.UnmarkFlag(base.PlayerState_Auto) playerEx.deterMine = true //如果所有玩家都确认牌之后 可以直接开始下一阶段 a := true for _, v := range sceneEx.players { if v != nil && v.IsGameing() { if !v.deterMine { a = false } } } if a { //提前进入亮牌阶段 s.ChangeSceneState(rule.ThirteenWaterSceneStateShowCards) } case rule.ThirteenWaterPlayerOpSelect: playerEx.deterMine = false playerEx.cardsO = &rule.Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}, PokerType: -1} playerEx.Trusteeship = 0 playerEx.UnmarkFlag(base.PlayerState_Auto) pack := &thirteen.SCThirteenPlayerOp{ OpRetCode: thirteen.OpResultCode_OPRC_Sucess, OpCode: int32(opcode), OpParam: params, Pos: int32(playerEx.GetPos()), } if len(params) == 13 { //校验牌 a := rule.DelCards(playerEx.cards[:], common.Int64Toint(params)) if len(a) != 0 { logger.Logger.Error("the cards is error.") returnFunc(thirteen.OpResultCode_OPRC_Error) return true } //牌赋值 copy(playerEx.preCardsO.Head[:], common.Int64Toint(params[:3])) copy(playerEx.preCardsO.Mid[:], common.Int64Toint(params[3:8])) copy(playerEx.preCardsO.End[:], common.Int64Toint(params[8:])) playerEx.preCardsO.PokerType = 0 } playerEx.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack) case rule.ThirteenWaterPlayerOpReset: // 取消确认 playerEx.deterMine = false pack := &thirteen.SCThirteenPlayerOp{ OpRetCode: thirteen.OpResultCode_OPRC_Sucess, OpCode: int32(opcode), OpParam: params, Pos: int32(playerEx.GetPos()), } playerEx.Broadcast(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack, 0) default: return false } return false } func (this *StateOp) OnLeave(s *base.Scene) { logger.Logger.Tracef("(this *StateOp) OnLeave, sceneid=%v", s.GetSceneId()) this.BaseState.OnLeave(s) sceneEx, ok := s.ExtraData.(*SceneEx) if !ok { return } for _, player := range sceneEx.players { if player != nil && player.IsGameing() { // 使用预选牌 if player.preCardsO != nil && player.preCardsO.PokerType != -1 && (player.cardsO == nil || player.cardsO.PokerType == -1) { player.cardsO = player.preCardsO } // 判断是否倒水 if player.cardsO != nil && player.cardsO.PokerType != -1 { if player.cardsO.PokerType < 1000000 { player.isDP = sceneEx.logic.IsDP(player.cardsO.Head, player.cardsO.Mid, player.cardsO.End) } continue } //没有确定牌的玩家帮他确定牌 sceneEx.SelectCards(player, -2) player.deterMine = true player.Trusteeship++ // 标记托管状态 player.MarkFlag(base.PlayerState_Auto) } } // test //type CC struct { // Cards [13]int // Card0 *rule.Group // Coin int64 //} //if len(sceneEx.players) == 3 { // sceneEx.Params[3] = 200000 // ls := []CC{ // { // Cards: [13]int{3, 9, 30, 40, 39, 14, 18, 47, 27, 4, 19, 6, 22}, // Card0: &rule.Group{ // Head: [3]int{39, 18, 47}, // Mid: [5]int{30, 4, 19, 6, 3}, // End: [5]int{40, 27, 14, 22, 9}, // //PokerType: 100804, // }, // Coin: 550900, // }, // { // Cards: [13]int{43, 53, 24, 34, 28, 36, 12, 20, 52, 5, 8, 25, 2}, // Card0: &rule.Group{ // Head: [3]int{36, 20, 5}, // Mid: [5]int{28, 2, 34, 8, 43}, // End: [5]int{25, 12, 53, 24, 52}, // //PokerType: 100803, // }, // Coin: 560500, // }, // } // var i int // for _, v := range sceneEx.players { // if v.SnId != 33424700 { // info := ls[i] // v.cards = info.Cards // v.cardsO = info.Card0 // v.Coin = info.Coin // i++ // } else { // // 真人 // v.cards = [13]int{10, 35, 16, 29, 45, 0, 33, 37, 1, 50, 46, 31, 44} // v.cardsO = &rule.Group{ // Head: [3]int{10, 46, 44}, // Mid: [5]int{50, 16, 45, 0, 1}, // End: [5]int{37, 35, 33, 31, 29}, // //PokerType: 101005, // } // v.Coin = 8968339671 // } // } //} //type CC struct { // Cards [13]int // Card0 *rule.Group // Coin int64 //} //if len(sceneEx.players) == 3 { // sceneEx.Params[3] = 200000 // ls := []CC{ // { // Cards: [13]int{10, 21, 35, 34, 19, 31, 47, 15, 44, 2, 23, 18, 38}, // Card0: &rule.Group{ // Head: [3]int{35, 19, 38}, // Mid: [5]int{44, 31, 18, 15, 2}, // End: [5]int{47, 34, 21, 23, 10}, // }, // Coin: 179758402, // }, // { // Cards: [13]int{20, 3, 39, 14, 52, 25, 7, 53, 22, 16, 43, 30, 17}, // Card0: &rule.Group{ // Head: [3]int{3, 39, 7}, // Mid: [5]int{25, 22, 20, 16, 14}, // End: [5]int{43, 30, 17, 53, 52}, // }, // Coin: 993000, // }, // } // var i int // for _, v := range sceneEx.players { // if v.SnId != 33424700 { // info := ls[i] // v.cards = info.Cards // v.cardsO = info.Card0 // v.Coin = info.Coin // i++ // } else { // // 真人 // v.cards = [13]int{12, 13, 9, 36, 49, 24, 32, 48, 4, 33, 6, 45, 50} // v.cardsO = &rule.Group{ // Head: [3]int{13, 4, 33}, // Mid: [5]int{48, 9, 49, 36, 12}, // End: [5]int{45, 32, 6, 50, 24}, // } // v.Coin = 1150000 // } // } //} //type CC struct { // Cards [13]int // Card0 *rule.Group // Coin int64 //} //if len(sceneEx.players) == 3 { // sceneEx.Params[3] = 200000 // ls := []CC{ // { // Cards: [13]int{18, 12, 3, 10, 9, 8, 19, 14, 51, 25, 28, 24, 33}, // Card0: &rule.Group{ // Head: [3]int{51, 28, 33}, // Mid: [5]int{12, 10, 9, 8, 3}, // End: [5]int{25, 24, 19, 18, 14}, // }, // Coin: 298348695, // }, // { // Cards: [13]int{26, 43, 44, 1, 0, 16, 50, 48, 34, 29, 17, 32, 37}, // Card0: &rule.Group{ // Head: [3]int{16, 50, 48}, // Mid: [5]int{44, 1, 43, 17, 0}, // End: [5]int{37, 34, 32, 29, 26}, // }, // Coin: 263600, // }, // } // var i int // for _, v := range sceneEx.players { // if v.SnId != 33424700 { // info := ls[i] // v.cards = info.Cards // v.cardsO = info.Card0 // v.Coin = info.Coin // i++ // } else { // // 真人 // v.cards = [13]int{20, 47, 2, 36, 38, 39, 6, 15, 46, 21, 40, 52, 7} // v.cardsO = &rule.Group{ // Head: [3]int{39, 6, 40}, // Mid: [5]int{15, 2, 47, 21, 38}, // End: [5]int{46, 20, 7, 52, 36}, // } // v.Coin = 586000 // } // } //} // test // 计算总分数 sceneEx.CountScore() // 预结算,玩家余额在结算状态修改 sceneEx.CountBilled() } func (this *StateOp) OnTick(s *base.Scene) { this.BaseState.OnTick(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { if time.Now().Sub(sceneEx.StateStartTime) > sceneEx.GetBaiPai() { s.ChangeSceneState(rule.ThirteenWaterSceneStateShowCards) } } } //===================================== // StateOp 看牌状态 //===================================== type StateShow struct { BaseState } func (this *StateShow) GetState() int { return rule.ThirteenWaterSceneStateShowCards } func (this *StateShow) CanChangeTo(s base.SceneState) bool { switch s.GetState() { case rule.ThirteenWaterSceneStateShowCards, rule.ThirteenWaterSceneStateHit, rule.ThirteenWaterSceneStateBilled: //玩家操作状态 return true } return false } // 状态进入 func (this *StateShow) OnEnter(s *base.Scene) { this.BaseState.OnEnter(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { ThirteenWaterBroadcastRoomState(s) logger.Logger.Tracef("(this *StateShow) OnEnter, sceneid=%v currpos:%v", s.GetSceneId(), sceneEx.currOpPos) sceneEx.ShowCards() // 每人看牌5秒,特殊牌型不算; //var n int //var has bool //for _, v := range sceneEx.players { // if v != nil && v.IsGameing() && v.cardsO != nil { // n++ // if v.cardsO.PokerType == 1 { // 有青龙 // has = true // } // } //} //n -= sceneEx.specialTypeNum //sceneEx.specialTime = time.Second * time.Duration(n*5) //// pk动画 2秒 //sceneEx.specialTime += time.Second * 2 //// 特殊牌型 4.5秒;至尊青龙5.5秒 //if sceneEx.specialTypeNum > 0 { // if has { // sceneEx.specialTime += time.Millisecond * 5500 // } else { // sceneEx.specialTime += time.Millisecond * 4500 // } //} sceneEx.specialTime = 0 // pk动画 2秒 sceneEx.specialTime += time.Second * 2 // 2人且有特殊牌型,直接播放特殊牌型动画 var n int // 玩家数量 var has bool // 是否有青龙 var hasDP bool // 是否有倒水 for _, v := range sceneEx.players { if v != nil && v.IsGameing() && v.cardsO != nil { n++ if v.cardsO.PokerType == 1 { // 有青龙 has = true } if v.isDP { hasDP = true } } } normalNum := n - sceneEx.specialTypeNum if hasDP { sceneEx.specialTime += time.Second } if normalNum > 1 { sceneEx.specialTime += time.Second * time.Duration(5) } if sceneEx.specialTypeNum > 0 { if has { sceneEx.specialTime += time.Millisecond * 5500 } else { sceneEx.specialTime += time.Millisecond * 4500 } } logger.Logger.Tracef("show cards: %v %v", n, sceneEx.specialTime) if sceneEx.specialTime <= 0 { sceneEx.specialTime = time.Second } } } func (this *StateShow) OnTick(s *base.Scene) { this.BaseState.OnTick(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { if time.Now().Sub(sceneEx.StateStartTime) > sceneEx.specialTime { if sceneEx.entryHitState { s.ChangeSceneState(rule.ThirteenWaterSceneStateHit) } else { s.ChangeSceneState(rule.ThirteenWaterSceneStateBilled) } } } } //===================================== // StateHit 打枪状态 //===================================== type StateHit struct { BaseState } func (this *StateHit) GetState() int { return rule.ThirteenWaterSceneStateHit } func (this *StateHit) CanChangeTo(s base.SceneState) bool { switch s.GetState() { case rule.ThirteenWaterSceneStateBilled: return true } return false } // 状态进入 func (this *StateHit) OnEnter(s *base.Scene) { this.BaseState.OnEnter(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { ThirteenWaterBroadcastRoomState(s) logger.Logger.Tracef("(this *StateHit) OnEnter, sceneid=%v currpos:%v", s.GetSceneId(), sceneEx.currOpPos) hitNum := 0 //打枪人数 for _, playerEx := range sceneEx.players { if playerEx != nil && playerEx.IsGameing() { hitSum := len(playerEx.winThreePos) if hitSum > 0 { hitNum += hitSum } } } // 每个打枪加2秒,全垒打再加2秒 sceneEx.hitTime += time.Second * 2 * (time.Duration(hitNum)) sceneEx.ShowCards() } } func (this *StateHit) OnTick(s *base.Scene) { this.BaseState.OnTick(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { if time.Now().Sub(sceneEx.StateStartTime) > sceneEx.hitTime { s.ChangeSceneState(rule.ThirteenWaterSceneStateBilled) } } } //===================================== // StateBilled 结算 //===================================== type StateBilled struct { BaseState } func (this *StateBilled) GetState() int { return rule.ThirteenWaterSceneStateBilled } func (this *StateBilled) CanChangeTo(s base.SceneState) bool { switch s.GetState() { case rule.ThirteenWaterSceneStateStart, rule.ThirteenWaterSceneStateWait: return true } return false } func (this *StateBilled) OnEnter(s *base.Scene) { logger.Logger.Tracef("(this *StateBilled) OnEnter, sceneid=%v", s.GetSceneId()) this.BaseState.OnEnter(s) ThirteenWaterBroadcastRoomState(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { //通知客户端结算结果 var billed []*thirteen.Billed playerPool := map[int]int{} // 没离开,剩余玩家结算 for _, playerEx := range sceneEx.players { if playerEx != nil && playerEx.IsGameing() { playerPool[int(playerEx.SnId)] = playerEx.playerPool if playerEx.gainCoin > 0 { //税前赢的钱 税收 下注额 playerEx.AddServiceFee(playerEx.taxCoin) playerEx.AddCoin(playerEx.gainCoin, common.GainWay_CoinSceneWin, base.SyncFlag_ToClient, "system", s.GetSceneName()) playerEx.CurIsWin = 1 } else if playerEx.gainCoin < 0 { playerEx.AddCoin(playerEx.gainCoin, common.GainWay_CoinSceneLost, base.SyncFlag_ToClient, "system", s.GetSceneName()) playerEx.CurIsWin = -1 } // 离场补偿分 if playerEx.score[6] > 0 { playerEx.AddCoin(playerEx.score[6]*int64(sceneEx.GetBaseScore()), common.GainWay_LeaveCombat, base.SyncFlag_ToClient, "system", s.GetSceneName()) } billed = append(billed, &thirteen.Billed{ Pos: proto.Int32(int32(playerEx.Pos)), Coin: proto.Int64(playerEx.Coin), WinCoin: proto.Int64(playerEx.gainCoin + playerEx.score[6]*int64(sceneEx.GetBaseScore())), CombatCoin: playerEx.score[6] * int64(sceneEx.GetBaseScore()), }) } } // 提前离开的 for _, playerEx := range sceneEx.PlayerBackup { if playerEx != nil && playerEx.isBilled { playerPool[int(playerEx.SnId)] = playerEx.PlayerPool billed = append(billed, &thirteen.Billed{ Pos: proto.Int32(int32(playerEx.Pos)), Coin: proto.Int64(playerEx.Coin), WinCoin: proto.Int64(playerEx.gainCoin + playerEx.score[6]*int64(sceneEx.GetBaseScore())), CombatCoin: playerEx.score[6] * int64(sceneEx.GetBaseScore()), }) } } pack := &thirteen.SCThirteenBilled{ AllBilled: billed, } logger.Logger.Trace("SCThirteenWaterBilled is pack: ", pack) sceneEx.Broadcast(int(thirteen.TWMmoPacketID_PACKET_SCThirteenBilled), pack, 0) //体验场不走统计 if !sceneEx.Testing { if sceneEx.gamePlayerNum-sceneEx.robotNum > 0 { /////////////////////////////////////统计牌局详细记录 thirteenWaterType := model.ThirteenWaterType{ RoomId: sceneEx.SceneId, RoomRounds: int32(sceneEx.NumOfGames), RoomType: sceneEx.GetSceneType(), BaseScore: int32(sceneEx.GetBaseScore()), NowRound: int32(sceneEx.NumOfGames), TaxRate: s.GetDBGameFree().GetTaxRate(), } var person []model.ThirteenWaterPerson for _, o_player := range sceneEx.players { if o_player != nil && o_player.IsGameing() { p := model.ThirteenWaterPerson{ UserId: o_player.SnId, ChangeCoin: o_player.gainCoin + o_player.score[6]*int64(sceneEx.GetBaseScore()), Cardinfo: o_player.cards[:], StartCoin: o_player.StartCoin, UserIcon: o_player.Head, IsRob: o_player.IsRob, Flag: o_player.GetFlag(), Tax: o_player.taxCoin, Platform: o_player.Platform, Channel: o_player.Channel, Promoter: strconv.Itoa(int(o_player.PromoterTree)), PackageTag: o_player.PackageID, InviterId: o_player.InviterId, WBLevel: o_player.WBLevel, IsFirst: sceneEx.IsPlayerFirst(sceneEx.GetPlayer(o_player.SnId)), TableScore: o_player.tableScore, LeaveCombat: int(o_player.score[6]), AllFight: int(o_player.score[5]), GunScore: int(o_player.score[4]), TestLog: o_player.TestLog, } score := int64(0) for _, v := range o_player.score { score += v } p.AllScore = int(score) p.CardsO = model.ThirteenWaterPoker{ Head: o_player.cardsO.Head, Mid: o_player.cardsO.Mid, End: o_player.cardsO.End, PokerType: sceneEx.FormatCards(o_player.cardsO), } if p.CardsO.PokerType > 1000000 { p.SpecialName = rule.SpecialTypeName[p.CardsO.PokerType/1000000] copy(p.CardsO.Head[:], o_player.cards[:3]) copy(p.CardsO.Mid[:], o_player.cards[3:8]) copy(p.CardsO.End[:], o_player.cards[8:]) } else if p.CardsO.PokerType > 10000 { p.HeadName = rule.PokersTypeName[p.CardsO.PokerType%1000000/10000] p.MidName = rule.PokersTypeName[p.CardsO.PokerType%10000/100] p.EndName = rule.PokersTypeName[p.CardsO.PokerType%100] p.IsDP = o_player.isDP } p.IsWin = int32(o_player.CurIsWin) person = append(person, p) /// if !o_player.IsRob { sceneEx.Statistics(&base.StaticParam{ SnId: o_player.SnId, Gain: o_player.gainCoin, GainTax: o_player.taxCoin, IsAddTimes: true, HasRobotGaming: sceneEx.robotNum > 0, }) //有真人 存真人的映射表 totalin, totalout := int64(0), int64(0) if o_player.CurIsWin > 0 { totalout = o_player.gainCoin + o_player.taxCoin } else { totalin -= o_player.gainCoin } sceneEx.SaveGamePlayerListLog(&base.SaveGamePlayerListLogParam{ LogId: sceneEx.logid, Platform: o_player.Platform, Snid: o_player.SnId, PlayerName: o_player.Name, Channel: o_player.Channel, ChannelId: o_player.ChannelId, TotalIn: totalin, TotalOut: totalout, TaxCoin: o_player.taxCoin, BetAmount: 0, WinAmountNoAnyTax: o_player.gainCoin, IsFirstGame: p.IsFirst, }) } } } for _, o_player := range sceneEx.PlayerBackup { if o_player != nil && o_player.isBilled { p := model.ThirteenWaterPerson{ UserId: o_player.SnId, ChangeCoin: o_player.gainCoin + o_player.score[6]*int64(sceneEx.GetBaseScore()), Cardinfo: o_player.cards[:], StartCoin: o_player.StartCoin, UserIcon: o_player.Head, IsRob: o_player.IsRob, Flag: o_player.flag, Tax: o_player.taxCoin, ClubPump: o_player.clubPump, Platform: o_player.Platform, Channel: o_player.Channel, Promoter: strconv.Itoa(int(o_player.PromoterTree)), PackageTag: o_player.PackageID, InviterId: o_player.InviterId, WBLevel: o_player.WBLevel, IsFirst: sceneEx.IsPlayerFirst(sceneEx.GetPlayer(o_player.SnId)), TableScore: o_player.tableScore, LeaveCombat: int(o_player.score[6]), AllFight: int(o_player.score[5]), GunScore: int(o_player.score[4]), TestLog: o_player.TestLog, } score := int64(0) for _, v := range o_player.score { score += v } p.AllScore = int(score) p.CardsO = model.ThirteenWaterPoker{ Head: o_player.cardsO.Head, Mid: o_player.cardsO.Mid, End: o_player.cardsO.End, PokerType: sceneEx.FormatCards(o_player.cardsO), } if p.CardsO.PokerType > 1000000 { p.SpecialName = rule.SpecialTypeName[p.CardsO.PokerType/1000000] copy(p.CardsO.Head[:], o_player.cards[:3]) copy(p.CardsO.Mid[:], o_player.cards[3:8]) copy(p.CardsO.End[:], o_player.cards[8:]) } else if p.CardsO.PokerType > 10000 { p.HeadName = rule.PokersTypeName[p.CardsO.PokerType%1000000/10000] p.MidName = rule.PokersTypeName[p.CardsO.PokerType%10000/100] p.EndName = rule.PokersTypeName[p.CardsO.PokerType%100] p.IsDP = o_player.isDP } p.IsWin = int32(o_player.CurIsWin) person = append(person, p) } } thirteenWaterType.PlayerData = person thirteenWaterType.PlayerCount = len(person) info, err := model.MarshalGameNoteByFIGHT(&thirteenWaterType) if err == nil { sceneEx.SaveGameDetailedLog(&base.SaveGameDetailedParam{ LogId: sceneEx.logid, Detail: info, CtrlType: sceneEx.ctrlType, PlayerPool: playerPool, }) } } } } } func (this *StateBilled) OnLeave(s *base.Scene) { logger.Logger.Tracef("(this *StateBilled) OnLeave, sceneid=%v", s.GetSceneId()) this.BaseState.OnLeave(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { //结束记录回放录像 sceneEx.RecordReplayOver() for _, v := range sceneEx.players { if v != nil { v.UnmarkFlag(base.PlayerState_WaitNext) v.UnmarkFlag(base.PlayerState_GameBreak) v.MarkFlag(base.PlayerState_Ready) v.SyncFlag() } } hasLeave := false //剔除下线玩家 for i := 0; i < sceneEx.GetPlayerNum(); i++ { player_data := sceneEx.seats[i] if player_data == nil { continue } if sceneEx.IsMatchScene() { continue } if !player_data.IsOnLine() { sceneEx.PlayerLeave(player_data.Player, common.PlayerLeaveReason_DropLine, true) hasLeave = true continue } if player_data.IsRob { if s.CoinOverMaxLimit(player_data.GetCoin(), player_data.Player) { sceneEx.PlayerLeave(player_data.Player, common.PlayerLeaveReason_Normal, true) hasLeave = true continue } } if !s.CoinInLimit(player_data.GetCoin()) { sceneEx.PlayerLeave(player_data.Player, s.NotCoinInLimitType(player_data.GetCoin()), true) hasLeave = true continue } if player_data.Trusteeship >= 1 { s.PlayerLeave(player_data.Player, common.PlayerLeaveReason_LongTimeNoOp, true) hasLeave = true continue } if player_data.isStand { // 站起离开 s.PlayerLeave(player_data.Player, common.PlayerLeaveReason_Normal, true) hasLeave = true continue } } if !hasLeave && !sceneEx.IsRobFightGame() && !sceneEx.IsMatchScene() { s.TryDismissRob() } if s.CheckNeedDestroy() || (s.IsMatchScene() && (!s.GetMatch().GetIsFinals() || (s.GetMatch().GetIsFinals() && s.NumOfGames >= 2))) { // 非决赛打一场 决赛打两场 sceneEx.SceneDestroy(true) } s.TryRelease() } } func (this *StateBilled) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool { if this.BaseState.OnPlayerOp(s, p, opcode, params) { return true } return false } func (this *StateBilled) OnTick(s *base.Scene) { this.BaseState.OnTick(s) if sceneEx, ok := s.ExtraData.(*SceneEx); ok { var second = rule.ThirteenWaterBilledTimeout sub := rule.GetTimeout(sceneEx.GetDBGameFree().GetOtherIntParams(), rule.TimeoutBill) if sub > 0 { second = sub } if time.Now().Sub(sceneEx.StateStartTime) > second { if sceneEx.CanStart() { s.ChangeSceneState(rule.ThirteenWaterSceneStateStart) } else { s.ChangeSceneState(rule.ThirteenWaterSceneStateWait) } return } } } // ////////////////////////////////////////////////////////////////////////////// func (this *PolicyThirteen) RegisteSceneState(state base.SceneState) { if state == nil { return } stateid := state.GetState() if stateid < 0 || stateid >= rule.ThirteenWaterSceneStateMax { return } this.states[stateid] = state } func (this *PolicyThirteen) GetSceneState(s *base.Scene, stateid int) base.SceneState { if stateid >= 0 && stateid < rule.ThirteenWaterSceneStateMax { return this.states[stateid] } return nil } func init() { PolicyThirteenSingleton.RegisteSceneState(&StateWait{}) PolicyThirteenSingleton.RegisteSceneState(&StateStart{}) PolicyThirteenSingleton.RegisteSceneState(&StateSendCard{}) PolicyThirteenSingleton.RegisteSceneState(&StateOp{}) PolicyThirteenSingleton.RegisteSceneState(&StateShow{}) PolicyThirteenSingleton.RegisteSceneState(&StateHit{}) PolicyThirteenSingleton.RegisteSceneState(&StateBilled{}) core.RegisteHook(core.HOOK_BEFORE_START, func() error { base.RegisteScenePolicy(common.GameID_Thirteen4, 0, PolicyThirteenSingleton) base.RegisteScenePolicy(common.GameID_Thirteen8, 0, PolicyThirteenSingleton) base.RegisteScenePolicy(common.GameID_ThirteenFree, 0, PolicyThirteenSingleton) base.RegisteScenePolicy(common.GameID_ThirteenFreeLaiZi, 0, PolicyThirteenSingleton) return nil }) }