1593 lines
46 KiB
Go
1593 lines
46 KiB
Go
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(playerEx.SnId, base.GetSaveGamePlayerListLogParam(playerEx.Platform, playerEx.Channel, playerEx.BeUnderAgentCode,
|
||
playerEx.PackageID, sceneEx.logid, playerEx.InviterId, totalin, totalout, playerEx.taxCoin,
|
||
0, 0, playerEx.gainCoin, validBet, validFlow, sceneEx.IsPlayerFirst(sceneEx.GetPlayer(playerEx.SnId)), false))
|
||
|
||
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.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
|
||
// }
|
||
//}
|
||
|
||
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
|
||
}
|
||
}
|
||
}
|
||
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
|
||
}
|
||
validFlow := totalin + totalout
|
||
validBet := common.AbsI64(totalin - totalout)
|
||
sceneEx.SaveGamePlayerListLog(o_player.SnId, base.GetSaveGamePlayerListLogParam(o_player.Platform, o_player.Channel, o_player.BeUnderAgentCode,
|
||
o_player.PackageID, sceneEx.logid, o_player.InviterId, totalin, totalout, o_player.taxCoin,
|
||
0, 0, o_player.gainCoin, validBet, validFlow, p.IsFirst, false))
|
||
}
|
||
}
|
||
}
|
||
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(sceneEx.logid, info, &base.GameDetailedParam{
|
||
Trend20Lately: "",
|
||
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
|
||
})
|
||
}
|