game_sync/gamesrv/fruits/scenepolicy_fruits.go

550 lines
18 KiB
Go

package fruits
import (
"math"
"time"
"mongo.games.com/goserver/core"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/game/common"
"mongo.games.com/game/gamerule/fruits"
"mongo.games.com/game/gamesrv/base"
"mongo.games.com/game/proto"
protocol "mongo.games.com/game/protocol/fruits"
)
// ////////////////////////////////////////////////////////////
var ScenePolicyFruitsSington = &ScenePolicyFruits{}
type ScenePolicyFruits struct {
base.BaseScenePolicy
states [fruits.FruitsStateMax]base.SceneState
}
// 创建场景扩展数据
func (this *ScenePolicyFruits) CreateSceneExData(s *base.Scene) interface{} {
sceneEx := NewFruitsSceneData(s)
if sceneEx != nil {
if sceneEx.GetInit() {
s.SetExtraData(sceneEx)
}
}
return sceneEx
}
// 创建玩家扩展数据
func (this *ScenePolicyFruits) CreatePlayerExData(s *base.Scene, p *base.Player) interface{} {
playerEx := &FruitsPlayerData{Player: p}
p.SetExtraData(playerEx)
return playerEx
}
// 场景开启事件
func (this *ScenePolicyFruits) OnStart(s *base.Scene) {
logger.Logger.Trace("(this *ScenePolicyFruits) OnStart, sceneId=", s.GetSceneId())
sceneEx := NewFruitsSceneData(s)
if sceneEx != nil {
if sceneEx.GetInit() {
s.SetExtraData(sceneEx)
s.ChangeSceneState(fruits.FruitsStateStart)
}
}
}
// 场景关闭事件
func (this *ScenePolicyFruits) OnStop(s *base.Scene) {
logger.Logger.Trace("(this *ScenePolicyFruits) OnStop , sceneId=", s.GetSceneId())
}
// 场景心跳事件
func (this *ScenePolicyFruits) OnTick(s *base.Scene) {
if s == nil {
return
}
if s.GetSceneState() != nil {
s.GetSceneState().OnTick(s)
}
}
// 玩家进入事件
func (this *ScenePolicyFruits) OnPlayerEnter(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyFruits) OnPlayerEnter, sceneId=", s.GetSceneId(), " player=", p.Name)
if sceneEx, ok := s.GetExtraData().(*FruitsSceneData); ok {
playerEx := &FruitsPlayerData{Player: p}
playerEx.init()
playerEx.Clear()
sceneEx.players[p.SnId] = playerEx
p.SetExtraData(playerEx)
FruitsSendRoomInfo(s, sceneEx, playerEx)
s.FirePlayerEvent(p, base.PlayerEventEnter, nil)
}
}
// 玩家离开事件
func (this *ScenePolicyFruits) OnPlayerLeave(s *base.Scene, p *base.Player, reason int) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyFruits) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId)
if sceneEx, ok := s.ExtraData.(*FruitsSceneData); ok {
s.FirePlayerEvent(p, base.PlayerEventLeave, nil)
sceneEx.OnPlayerLeave(p, reason)
}
}
// 玩家掉线
func (this *ScenePolicyFruits) OnPlayerDropLine(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyFruits) OnPlayerDropLine, sceneId=", s.GetSceneId(), " player=", p.SnId)
s.FirePlayerEvent(p, base.PlayerEventDropLine, nil)
}
// 玩家重连
func (this *ScenePolicyFruits) OnPlayerRehold(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyFruits) OnPlayerRehold, sceneId=", s.GetSceneId(), " player=", p.SnId)
if sceneEx, ok := s.GetExtraData().(*FruitsSceneData); ok {
if playerEx, ok := p.GetExtraData().(*FruitsPlayerData); ok {
FruitsSendRoomInfo(s, sceneEx, playerEx)
}
}
}
// 返回房间
func (this *ScenePolicyFruits) OnPlayerReturn(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyFruits) OnPlayerReturn, GetSceneId()=", s.GetSceneId(), " player=", p.Name)
if sceneEx, ok := s.GetExtraData().(*FruitsSceneData); ok {
if playerEx, ok := p.GetExtraData().(*FruitsPlayerData); ok {
//if p.IsMarkFlag(base.PlayerState_Auto) {
// p.UnmarkFlag(base.PlayerState_Auto)
// p.SyncFlag()
//}
//发送房间信息给自己
FruitsSendRoomInfo(s, sceneEx, playerEx)
s.FirePlayerEvent(p, base.PlayerEventReturn, nil)
}
}
}
func FruitsSendRoomInfo(s *base.Scene, sceneEx *FruitsSceneData, playerEx *FruitsPlayerData) {
pack := FruitsCreateRoomInfoPacket(s, sceneEx, playerEx)
logger.Logger.Trace("RoomInfo: ", pack)
playerEx.SendToClient(int(protocol.FruitsPID_PACKET_FRUITS_SCFruitsRoomInfo), pack)
}
func FruitsCreateRoomInfoPacket(s *base.Scene, sceneEx *FruitsSceneData, playerEx *FruitsPlayerData) interface{} {
//房间信息
pack := &protocol.SCFruitsRoomInfo{
RoomId: s.SceneId,
GameId: s.GameId,
RoomMode: s.SceneMode,
SceneType: s.GetSceneType(),
Params: common.CopySliceInt64ToInt32(s.Params),
NumOfGames: proto.Int(sceneEx.NumOfGames),
State: proto.Int(s.SceneState.GetState()),
ParamsEx: s.GetDBGameFree().OtherIntParams,
GameFreeId: proto.Int32(s.GetDBGameFree().Id),
//BetLimit: s.GetDBGameFree().BetLimit,
}
//自己的信息
if playerEx != nil {
pd := &protocol.FruitsPlayerData{
SnId: proto.Int32(playerEx.SnId),
Name: proto.String(playerEx.Name),
Head: proto.Int32(playerEx.Head),
Sex: proto.Int32(playerEx.Sex),
Coin: proto.Int64(playerEx.Coin),
Pos: proto.Int(playerEx.Pos),
Flag: proto.Int(playerEx.GetFlag()),
City: proto.String(playerEx.City),
HeadOutLine: proto.Int32(playerEx.HeadOutLine),
VIP: proto.Int32(playerEx.VIP),
}
pack.Player = pd
pack.NowGameState = proto.Int(playerEx.gameState)
pack.BetIdx = proto.Int(playerEx.betIdx)
pack.FreeTimes = proto.Int(playerEx.freeTimes)
pack.MaryFreeTimes = proto.Int(playerEx.maryFreeTimes)
//玛丽
pack.MaryTotalWin = proto.Int64(playerEx.winOutMaryCoin + playerEx.winMidMaryCoin)
pack.Cards = playerEx.result.EleValue
if playerEx.maryFreeTimes > 0 && playerEx.result != nil {
pack.MaryWinId = proto.Int32(playerEx.result.MaryOutSide)
pack.MaryCards = playerEx.result.MaryMidArray
}
//免费 当局的
if playerEx.freeTimes > 0 && playerEx.result != nil {
pack.Cards = playerEx.result.EleValue
}
pack.WinLineCoin = proto.Int64(playerEx.winLineCoin)
pack.WinJackpot = proto.Int64(playerEx.winNowJackPotCoin)
pack.WinEle777Coin = proto.Int64(playerEx.winEle777Coin)
pack.FreeTotalWin = proto.Int64(playerEx.winFreeCoin)
pack.WinRate = proto.Int64(playerEx.winLineRate + playerEx.JackPot7Rate)
pack.WinFreeTimes = proto.Int(playerEx.winFreeTimes)
var wl []*protocol.FruitsWinLine
for _, r := range playerEx.result.WinLine {
wl = append(wl, &protocol.FruitsWinLine{
Poss: r.Poss,
LineId: proto.Int(r.LineId),
})
}
pack.WinLines = wl
}
proto.SetDefaults(pack)
return pack
}
func (this *ScenePolicyFruits) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
if s == nil || p == nil {
return false
}
logger.Logger.Trace("(this *ScenePolicyFruits) OnPlayerOp, sceneId=", s.GetSceneId(), " player=", p.SnId, " opcode=", opcode, " params=", params)
if s.GetSceneState() != nil {
if s.GetSceneState().OnPlayerOp(s, p, opcode, params) {
p.SetLastOPTimer(time.Now())
return true
}
return false
}
return true
}
func (this *ScenePolicyFruits) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyFruits) OnPlayerEvent, sceneId=", s.GetSceneId(), " player=", p.SnId, " eventcode=", evtcode, " params=", params)
if s.GetSceneState() != nil {
s.GetSceneState().OnPlayerEvent(s, p, evtcode, params)
}
}
// 当前状态能否换桌
func (this *ScenePolicyFruits) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
if s == nil || p == nil {
return false
}
if s.GetSceneState() != nil {
return s.GetSceneState().CanChangeCoinScene(s, p)
}
return false
}
// 状态基类
type SceneBaseStateFruits struct {
}
func (this *SceneBaseStateFruits) GetTimeout(s *base.Scene) int {
if sceneEx, ok := s.GetExtraData().(*FruitsSceneData); ok {
return int(time.Now().Sub(sceneEx.GetStateStartTime()) / time.Second)
}
return 0
}
func (this *SceneBaseStateFruits) CanChangeTo(s base.SceneState) bool {
return true
}
// 当前状态能否换桌
func (this *SceneBaseStateFruits) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
return true
}
func (this *SceneBaseStateFruits) OnEnter(s *base.Scene) {
if sceneEx, ok := s.GetExtraData().(*FruitsSceneData); ok {
sceneEx.SetStateStartTime(time.Now())
}
}
func (this *SceneBaseStateFruits) OnLeave(s *base.Scene) {}
func (this *SceneBaseStateFruits) OnTick(s *base.Scene) {
if time.Now().Sub(s.GameStartTime) > time.Second*3 {
if sceneEx, ok := s.ExtraData.(*FruitsSceneData); ok {
prizePool := int64(math.Floor(float64(sceneEx.jackpot.GetTotalSmall()) / 10000))
pack := &protocol.SCFruitsPrize{
PrizePool: proto.Int64(prizePool),
}
proto.SetDefaults(pack)
//logger.Logger.Trace("SCFruitsPrize: ", pack)
s.Broadcast(int(protocol.FruitsPID_PACKET_FRUITS_SCFruitsPrize), pack, 0)
for _, p := range sceneEx.players {
if p.IsOnLine() {
p.leaveTime = 0
continue
}
p.leaveTime++
if p.leaveTime < 60*2 {
continue
}
//踢出玩家
sceneEx.PlayerLeave(p.Player, common.PlayerLeaveReason_LongTimeNoOp, true)
}
}
s.GameStartTime = time.Now()
}
if sceneEx, ok := s.ExtraData.(*FruitsSceneData); ok {
//for _, p := range sceneEx.players {
// //游戏次数达到目标值
// todayGamefreeIDSceneData, _ := p.GetDaliyGameData(int(sceneEx.GetDBGameFree().GetId()))
// if !p.IsRob &&
// todayGamefreeIDSceneData != nil &&
// sceneEx.GetDBGameFree().GetPlayNumLimit() != 0 &&
// todayGamefreeIDSceneData.GameTimes >= int64(sceneEx.GetDBGameFree().GetPlayNumLimit()) {
// s.PlayerLeave(p.Player, common.PlayerLeaveReason_GameTimes, true)
// }
//}
if sceneEx.CheckNeedDestroy() {
for _, player := range sceneEx.players {
if !player.IsRob {
if player.freeTimes == 0 && player.maryFreeTimes == 0 {
//离开有统计
sceneEx.PlayerLeave(player.Player, common.PlayerLeaveReason_OnDestroy, true)
}
}
}
if s.GetRealPlayerCnt() == 0 {
sceneEx.SceneDestroy(true)
}
}
}
//if sceneEx, ok := s.GetExtraData().(*FruitsSceneData); ok {
// if time.Now().Sub(sceneEx.mqLogTime) >= time.Minute*1 {
// now := time.Now()
// sceneEx.mqLogTime = now.Add(-time.Second * time.Duration(now.Second()))
//
// waterVal := base.CoinPoolMgr.LoadCoin(s.GetGameFreeId(), s.Platform, s.GroupId)
// waterVal = int64(math.Floor(float64(waterVal) / float64(fruits.NowByte)))
//
// jkVal1 := int64(math.Floor(float64(sceneEx.jackpot.GetTotalSmall()) / float64(fruits.NowByte)))
// base.JackPotMgr.WJackPotUpdate(sceneEx.GetGameFreeId(), sceneEx.Platform, waterVal, jkVal1, 0, 0, 0)
// }
//}
}
func (this *SceneBaseStateFruits) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
return false
}
func (this *SceneBaseStateFruits) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
}
// ////////////////////////////////////////////////////////////
// 开始状态
// ////////////////////////////////////////////////////////////
type SceneStateStartFruits struct {
SceneBaseStateFruits
}
func (this *SceneStateStartFruits) GetState() int {
return fruits.FruitsStateStart
}
func (this *SceneStateStartFruits) CanChangeTo(s base.SceneState) bool {
return false
}
// 当前状态能否换桌
func (this *SceneStateStartFruits) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
if playerEx, ok := p.GetExtraData().(*FruitsPlayerData); ok {
if playerEx.IsOnLine() && (playerEx.freeTimes > 0 || playerEx.maryFreeTimes > 0) {
return false
}
}
return true
}
func (this *SceneStateStartFruits) GetTimeout(s *base.Scene) int {
return 0
}
func (this *SceneStateStartFruits) OnEnter(s *base.Scene) {
this.SceneBaseStateFruits.OnEnter(s)
if sceneEx, ok := s.GetExtraData().(*FruitsSceneData); ok {
sceneEx.SetGameNowTime(time.Now())
}
}
// 状态离开时
func (this *SceneStateStartFruits) OnLeave(s *base.Scene) {
this.SceneBaseStateFruits.OnLeave(s)
logger.Logger.Tracef("(this *SceneStateStartFruits) OnLeave, sceneid=%v", s.GetSceneId())
}
// 玩家操作
func (this *SceneStateStartFruits) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
logger.Logger.Tracef("(this *SceneStateStartFruits) OnPlayerOp, sceneid=%v params=%v", s.GetSceneId(), params)
if this.SceneBaseStateFruits.OnPlayerOp(s, p, opcode, params) {
return true
}
if sceneEx, ok := s.GetExtraData().(*FruitsSceneData); ok {
if playerEx, ok := p.GetExtraData().(*FruitsPlayerData); ok {
switch opcode {
case fruits.FruitsPlayerOpStart:
playerEx.Clear()
if len(params) > 0 {
//只有开始算操作
p.LastOPTimer = time.Now()
idx := int(params[0])
if len(sceneEx.GetDBGameFree().GetOtherIntParams()) <= idx {
pack := &protocol.SCFruitsOp{
OpCode: proto.Int(opcode),
OpRetCode: proto.Int(3),
}
playerEx.SendToClient(int(protocol.FruitsPID_PACKET_FRUITS_SCFruitsOp), pack)
return false
}
if playerEx.maryFreeTimes > 0 {
playerEx.gameState = fruits.MaryGame
playerEx.maryFreeTimes--
playerEx.nowMaryTimes++
} else if playerEx.freeTimes > 0 {
playerEx.gameState = fruits.FreeGame
playerEx.freeTimes--
playerEx.nowFreeTimes++
}
//水池上下文环境
playerEx.cpCtx = base.CoinPoolMgr.GetCoinPoolCtx(sceneEx.Platform, sceneEx.GetGameFreeId(), sceneEx.GroupId)
if playerEx.gameState == fruits.Normal {
playerEx.freeTotal = 0
playerEx.betIdx = idx
playerEx.betCoin = int64(sceneEx.GetDBGameFree().GetOtherIntParams()[idx])
playerEx.oneBetCoin = playerEx.betCoin / 9
//playerEx.isReportGameEvent = true
playerEx.noWinTimes++
if playerEx.Coin < int64(s.GetDBGameFree().GetBetLimit()) {
//押注限制(低于该值不能押注)
pack := &protocol.SCFruitsOp{
OpCode: proto.Int(opcode),
OpRetCode: proto.Int(2),
}
playerEx.SendToClient(int(protocol.FruitsPID_PACKET_FRUITS_SCFruitsOp), pack)
return false
}
if playerEx.betCoin > playerEx.Coin {
//金币不足
pack := &protocol.SCFruitsOp{
OpCode: proto.Int(opcode),
OpRetCode: proto.Int(1),
}
playerEx.SendToClient(int(protocol.FruitsPID_PACKET_FRUITS_SCFruitsOp), pack)
return false
}
playerEx.CurrentBet = playerEx.betCoin
playerEx.CurrentTax = 0
//SysProfitCoinMgr.Add(sceneEx.sysProfitCoinKey, playerEx.betCoin, -playerEx.betCoin)
//没有免费次数 扣钱
p.Statics(s.KeyGameId, s.KeyGamefreeId, -playerEx.betCoin, false)
playerEx.AddCoin(-playerEx.betCoin, common.GainWay_HundredSceneLost, 0, "system", s.GetSceneName())
sceneEx.AddPrizeCoin(playerEx)
}
if !s.Testing {
//sceneEx.Regulation(playerEx, 0)
}
norms, frees, marys, key := sceneEx.GetEleWeight(playerEx.WBState)
playerEx.weightPos = key
if playerEx.gameState == fruits.MaryGame {
playerEx.result.CreateMary(marys)
playerEx.CreateMary()
} else if playerEx.gameState == fruits.FreeGame {
playerEx.freeTotal++
playerEx.CreateResult(frees, sceneEx)
} else {
playerEx.CreateResult(norms, sceneEx)
}
sceneEx.Win(playerEx)
if playerEx.gameState == fruits.FreeGame && playerEx.freeTotal >= 100 {
playerEx.freeTotal = 0
playerEx.freeTimes = 0
}
//发送结算
sceneEx.SendBilled(playerEx)
sceneEx.SaveLog(playerEx, 0)
if playerEx.gameState == fruits.Normal {
playerEx.winJackPotCoin = 0
playerEx.winEle777Coin = 0
playerEx.winLineCoin = 0
}
playerEx.wl = nil
}
case fruits.FruitsPlayerOpSwitch:
if len(params) > 0 && playerEx.freeTimes == 0 && playerEx.maryFreeTimes == 0 {
idx := int(params[0])
if len(sceneEx.GetDBGameFree().GetOtherIntParams()) > idx {
playerEx.betIdx = idx
playerEx.betCoin = int64(sceneEx.GetDBGameFree().GetOtherIntParams()[idx])
playerEx.oneBetCoin = playerEx.betCoin / 9
}
}
}
}
}
return true
}
// 玩家事件
func (this *SceneStateStartFruits) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
logger.Logger.Trace("(this *SceneStateStartFruits) OnPlayerEvent, sceneId=", s.GetSceneId(), " player=", p.SnId, " evtcode=", evtcode)
this.SceneBaseStateFruits.OnPlayerEvent(s, p, evtcode, params)
if sceneEx, ok := s.GetExtraData().(*FruitsSceneData); ok {
switch evtcode {
case base.PlayerEventEnter:
prizePool := int64(math.Floor(float64(sceneEx.jackpot.GetTotalSmall()) / 10000))
pack := &protocol.SCFruitsPrize{
PrizePool: proto.Int64(prizePool),
}
proto.SetDefaults(pack)
//logger.Logger.Trace("SCFruitsPrize: ", pack)
p.SendToClient(int(protocol.FruitsPID_PACKET_FRUITS_SCFruitsPrize), pack)
}
}
}
func (this *SceneStateStartFruits) OnTick(s *base.Scene) {
this.SceneBaseStateFruits.OnTick(s)
}
// //////////////////////////////////////////////////////////////////////////////
func (this *ScenePolicyFruits) RegisteSceneState(state base.SceneState) {
if state == nil {
return
}
stateid := state.GetState()
if stateid < 0 || stateid >= fruits.FruitsStateMax {
return
}
this.states[stateid] = state
}
func (this *ScenePolicyFruits) GetSceneState(s *base.Scene, stateid int) base.SceneState {
if stateid >= 0 && stateid < fruits.FruitsStateMax {
return this.states[stateid]
}
return nil
}
func init() {
//主状态
ScenePolicyFruitsSington.RegisteSceneState(&SceneStateStartFruits{})
core.RegisteHook(core.HOOK_BEFORE_START, func() error {
base.RegisteScenePolicy(common.GameId_Fruits, fruits.RoomMode_Classic, ScenePolicyFruitsSington)
return nil
})
}