game_sync/gamesrv/thirteen/scenepolicy.go

1578 lines
46 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 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)
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.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.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.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
}
}
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
}
}
}
if sceneEx.isCanAllHitPos != -1 {
hitNum++
}
// 每个打枪加1秒全垒打再加1秒
sceneEx.hitTime += time.Second * (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),
ClubRate: sceneEx.Scene.PumpCoin,
}
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
})
}