diff --git a/gamerule/fortunedragon/constants.go b/gamerule/fortunedragon/constants.go index 4b8b104..266ae53 100644 --- a/gamerule/fortunedragon/constants.go +++ b/gamerule/fortunedragon/constants.go @@ -19,4 +19,4 @@ const ( ) const NowByte int64 = 10000 -const GameDataKey = "FortuneData" +const GameDataKey = "FortuneDragonData" diff --git a/gamerule/fortunemouse/constants.go b/gamerule/fortunemouse/constants.go index e99fda7..2c8569c 100644 --- a/gamerule/fortunemouse/constants.go +++ b/gamerule/fortunemouse/constants.go @@ -19,4 +19,4 @@ const ( ) const NowByte int64 = 10000 -const GameDataKey = "FortuneData" +const GameDataKey = "FortuneMouseData" diff --git a/gamerule/fortuneox/constants.go b/gamerule/fortuneox/constants.go index 4d09722..abea427 100644 --- a/gamerule/fortuneox/constants.go +++ b/gamerule/fortuneox/constants.go @@ -19,4 +19,4 @@ const ( ) const NowByte int64 = 10000 -const GameDataKey = "FortuneData" +const GameDataKey = "FortuneOxData" diff --git a/gamerule/fortunerabbit/constants.go b/gamerule/fortunerabbit/constants.go index b91e331..eb9a87b 100644 --- a/gamerule/fortunerabbit/constants.go +++ b/gamerule/fortunerabbit/constants.go @@ -19,4 +19,4 @@ const ( ) const NowByte int64 = 10000 -const GameDataKey = "FortuneData" +const GameDataKey = "FortuneRabbit" diff --git a/gamerule/fortunetiger/constants.go b/gamerule/fortunetiger/constants.go index ae36f3c..5b8c02d 100644 --- a/gamerule/fortunetiger/constants.go +++ b/gamerule/fortunetiger/constants.go @@ -19,4 +19,4 @@ const ( ) const NowByte int64 = 10000 -const GameDataKey = "FortuneData" +const GameDataKey = "FortuneTigerData" diff --git a/gamerule/gatesofolympus/constants.go b/gamerule/gatesofolympus/constants.go index 7a61b2e..6080765 100644 --- a/gamerule/gatesofolympus/constants.go +++ b/gamerule/gatesofolympus/constants.go @@ -19,4 +19,4 @@ const ( ) const NowByte int64 = 10000 -const GameDataKey = "FortuneData" +const GameDataKey = "GatesOfOlympusData" diff --git a/gamerule/sugarrush/constants.go b/gamerule/sugarrush/constants.go new file mode 100644 index 0000000..b77df58 --- /dev/null +++ b/gamerule/sugarrush/constants.go @@ -0,0 +1,22 @@ +package sugarrush + +// 房间类型 +const ( + RoomMode_Classic int = iota //经典 + RoomMode_Max +) + +// 场景状态 +const ( + SugarRushStateStart int = iota //默认状态 + SugarRushStateMax +) + +// 玩家操作 +const ( + SugarRushPlayerOpStart int = iota + SugarRushPlayerOpSwitch +) +const NowByte int64 = 10000 + +const GameDataKey = "SugarRushData" diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Bet.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Bet.xlsx new file mode 100644 index 0000000..d7734ae Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Bet.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/Multiplier.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/Multiplier.xlsx new file mode 100644 index 0000000..3007d51 Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/Multiplier.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/Others.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/Others.xlsx new file mode 100644 index 0000000..bbfe1c9 Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/Others.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_BaseSymbolShow.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_BaseSymbolShow.xlsx new file mode 100644 index 0000000..d71bb0c Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_BaseSymbolShow.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_BaseSymbolShowNumber.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_BaseSymbolShowNumber.xlsx new file mode 100644 index 0000000..1ace453 Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_BaseSymbolShowNumber.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_BuyFreeScatterShow.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_BuyFreeScatterShow.xlsx new file mode 100644 index 0000000..31a0521 Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_BuyFreeScatterShow.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_FreeSymbolShow.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_FreeSymbolShow.xlsx new file mode 100644 index 0000000..5078fbe Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_FreeSymbolShow.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_FreeSymbolShowNumber.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_FreeSymbolShowNumber.xlsx new file mode 100644 index 0000000..d906d62 Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/S_FreeSymbolShowNumber.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/Scatter.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/Scatter.xlsx new file mode 100644 index 0000000..ffb5e7b Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Feature/Scatter.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/Formation.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/Formation.xlsx new file mode 100644 index 0000000..f655f17 Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/Formation.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/ReelBaseSpin.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/ReelBaseSpin.xlsx new file mode 100644 index 0000000..081bede Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/ReelBaseSpin.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/ReelFreeSpin.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/ReelFreeSpin.xlsx new file mode 100644 index 0000000..20116be Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/ReelFreeSpin.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/Symbol.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/Symbol.xlsx new file mode 100644 index 0000000..440a115 Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Generic/Symbol.xlsx differ diff --git a/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Settings.xlsx b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Settings.xlsx new file mode 100644 index 0000000..decea05 Binary files /dev/null and b/gamesrv/slotspkg/external/excel/Base/Slots/SugarRush/Settings.xlsx differ diff --git a/gamesrv/slotspkg/internal/module/player/player.go b/gamesrv/slotspkg/internal/module/player/player.go index 1fc0c53..4232f72 100644 --- a/gamesrv/slotspkg/internal/module/player/player.go +++ b/gamesrv/slotspkg/internal/module/player/player.go @@ -70,6 +70,7 @@ type ( FortuneMouse JSON CashMania JSON GatesOfOlympus JSON + SugarRush JSON Test JSON } } diff --git a/gamesrv/slotspkg/slots/formation/symbol_way.go b/gamesrv/slotspkg/slots/formation/symbol_way.go index f9b43c0..9ab4fa7 100644 --- a/gamesrv/slotspkg/slots/formation/symbol_way.go +++ b/gamesrv/slotspkg/slots/formation/symbol_way.go @@ -3,7 +3,9 @@ package formation import ( "github.com/tomas-qstarrs/boost/mathx" "mongo.games.com/game/gamesrv/slotspkg/internal/generic/errors" + "mongo.games.com/game/gamesrv/slotspkg/internal/module/shared" "mongo.games.com/game/gamesrv/slotspkg/slots/desc" + "mongo.games.com/game/gamesrv/slotspkg/slots/types/cli" ) // SymbolWay is the symbols of same symbol id @@ -16,6 +18,7 @@ type SymbolWay struct { Pay float64 // Pay of this symbol way LinkPositions []int64 // Link result LinkDirection int64 // Link direction for this Symbol way + Times int64 //n ways } // GenerateSymbolWays genertates all symbols ways and sum pays and links @@ -36,6 +39,14 @@ func (f *Formation) GenerateSymbolWays() { f.Pay += float64(symbolway.Pay) f.LinePays = append(f.LinePays, float64(symbolway.Pay)) f.addSymbolPay(symbolway.Symbol, symbolway.LinkCount, float64(symbolway.Pay)) + + f.RewardInfo = append(f.RewardInfo, &shared.RewardInfo{ + Type: 2, + Index: int(symbolway.Times), + Item: symbolway.Symbol, + Reward: symbolway.Pay, + Pos: cli.ToPoss(f.MatrixForm, symbolway.LinkPositions), + }) } } } @@ -70,9 +81,9 @@ func (s *SymbolWay) Win() bool { return s.Pay > 0 } -func (s *SymbolWay) pay(colCounts []int64) (float64, int64) { +func (s *SymbolWay) pay(colCounts []int64) (float64, int64, int64) { if colCounts[0] == 0 { - return 0, 0 + return 0, 0, 0 } symbolDesc, ok := s.SymbolsDesc[s.Symbol] if !ok { @@ -90,7 +101,7 @@ func (s *SymbolWay) pay(colCounts []int64) (float64, int64) { if linkCount > int64(len(symbolDesc.PayRate)) { panic(errors.Errorf("link %d pay is not found", linkCount)) } - return symbolDesc.Ratio(times * symbolDesc.PayRate[linkCount-1]), linkCount + return symbolDesc.Ratio(times * symbolDesc.PayRate[linkCount-1]), linkCount, times } func (s *SymbolWay) getSymbolDesc(symbol int64) *desc.SymbolDesc { @@ -169,7 +180,7 @@ func (s *SymbolWay) calculatePayFromLeftToRight(positions []int64, allPositions } } - s.Pay, s.LinkCount = s.pay(colCounts) + s.Pay, s.LinkCount, s.Times = s.pay(colCounts) var hasSymbol bool for index := 0; index < len(positions); index++ { @@ -185,6 +196,7 @@ func (s *SymbolWay) calculatePayFromLeftToRight(positions []int64, allPositions if !hasSymbol { s.LinkPositions = nil s.Pay = 0 + s.Times = 0 s.LinkCount = 0 } } @@ -209,7 +221,7 @@ func (s *SymbolWay) calculatePayFromRightToLeft(positions []int64, allPositions } } - s.Pay, s.LinkCount = s.pay(colCounts) + s.Pay, s.LinkCount, s.Times = s.pay(colCounts) colCounts = make([]int64, len(s.MatrixDesc.Form)) end = int64(len(positions) - 1) @@ -235,6 +247,7 @@ func (s *SymbolWay) calculatePayFromRightToLeft(positions []int64, allPositions if sumColCount == 0 { s.LinkPositions = nil s.Pay = 0 + s.Times = 0 s.LinkCount = 0 } } diff --git a/gamesrv/sugarrush/action_sugarrush.go b/gamesrv/sugarrush/action_sugarrush.go new file mode 100644 index 0000000..db553cd --- /dev/null +++ b/gamesrv/sugarrush/action_sugarrush.go @@ -0,0 +1,46 @@ +package sugarrush + +import ( + "mongo.games.com/game/common" + "mongo.games.com/game/gamesrv/base" + "mongo.games.com/game/protocol/sugarrush" + "mongo.games.com/goserver/core/logger" + "mongo.games.com/goserver/core/netlib" +) + +type CSSugarRushOpPacketFactory struct { +} +type CSSugarRushOpHandler struct { +} + +func (this *CSSugarRushOpPacketFactory) CreatePacket() interface{} { + pack := &sugarrush.CSSugarRushOp{} + return pack +} + +func (this *CSSugarRushOpHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { + if op, ok := data.(*sugarrush.CSSugarRushOp); ok { + p := base.PlayerMgrSington.GetPlayer(sid) + if p == nil { + logger.Logger.Warn("CSSugarRushOpHandler p == nil") + return nil + } + scene := p.GetScene() + if scene == nil { + logger.Logger.Warn("CSSugarRushOpHandler p.scene == nil") + return nil + } + if !scene.HasPlayer(p) { + return nil + } + if scene.GetScenePolicy() != nil { + scene.GetScenePolicy().OnPlayerOp(scene, p, int(op.GetOpCode()), op.GetParams()) + } + return nil + } + return nil +} +func init() { + common.RegisterHandler(int(sugarrush.SugarRushPID_PACKET_SUGARRUSH_CSSUGARRUSHOP), &CSSugarRushOpHandler{}) + netlib.RegisterFactory(int(sugarrush.SugarRushPID_PACKET_SUGARRUSH_CSSUGARRUSHOP), &CSSugarRushOpPacketFactory{}) +} diff --git a/gamesrv/sugarrush/playerdata_sugarrush.go b/gamesrv/sugarrush/playerdata_sugarrush.go new file mode 100644 index 0000000..b21a4f5 --- /dev/null +++ b/gamesrv/sugarrush/playerdata_sugarrush.go @@ -0,0 +1,68 @@ +package sugarrush + +import ( + "mongo.games.com/game/gamerule/sugarrush" + "mongo.games.com/game/gamesrv/base" + "mongo.games.com/game/gamesrv/slotspkg/slots" +) + +type SugarRushPlayerData struct { + *base.Player + base.LabaLog + leaveTime int32 //离开时间 + SlotsSession *base.SlotsSession + + BetSizeIndex int64 `json:"bsi"` //选中的单注下标 + BetLevelIndex int64 `json:"bli"` //选中的等级下标 + BetLineIndex int64 `json:"bii"` //选中的线数下标 + BetMode int64 `json:"bm,optional"` //0.常规 1.%125 2.购买 + + taxCoin int64 + winCoin int64 + currentLogId string + totalBet int64 + + isFree bool //只用于判断是否可以离开 +} +type LinkPositions struct { + Positions []int64 `json:"Positions,omitempty"` +} +type CustomEliminate struct { + LinkPositions []*LinkPositions `json:"LinkPositions,omitempty"` //消除的位置 + AppendSymbols [][]int64 `json:"AppendSymbols,omitempty"` //新增 + FormattedSymbols [][]int64 `json:"FormattedSymbols,omitempty"` //最终的结果 + LinePays []float64 `json:"LinePays,omitempty"` //赔付 + WinCoins []float64 `json:"WinCoins,omitempty"` //输赢 + MultiStr string `json:"multi_str,omitempty"` + MultiStrVal string `json:"multi_str_val,omitempty"` + SymbolsAbove []int64 `json:"symbols_above,omitempty"` + SymbolsBelow []int64 `json:"symbols_below,omitempty"` +} +type SpinLock struct { + CustomEliminates []CustomEliminate `json:"CustomEliminates,omitempty"` + Pay float64 `json:"Pay,omitempty"` + Multi int64 `json:"Multi,omitempty"` + SymbolsAbove []int64 `json:"symbols_above,omitempty"` + SymbolsBelow []int64 `json:"symbols_below,omitempty"` +} + +func (p *SugarRushPlayerData) init() { + p.SlotsSession = base.NewSession(uint64(p.SnId), p.Coin*sugarrush.NowByte) +} +func (p *SugarRushPlayerData) Clear() { + p.taxCoin = 0 + p.winCoin = 0 + p.currentLogId = "" + p.LabaLog.Clear() +} + +// 需要带到world上进行数据处理 +func (p *SugarRushPlayerData) PushPlayer() map[string]string { + cache := slots.SlotsMgrSington.PushPlayer(p.SlotsSession) + return cache +} + +// 进房的时候需要带进来 +func (p *SugarRushPlayerData) PullPlayer(data map[string]string) { + slots.SlotsMgrSington.PullPlayer(p.SlotsSession, data) +} diff --git a/gamesrv/sugarrush/scenedata_sugarrush.go b/gamesrv/sugarrush/scenedata_sugarrush.go new file mode 100644 index 0000000..5c4eab3 --- /dev/null +++ b/gamesrv/sugarrush/scenedata_sugarrush.go @@ -0,0 +1,45 @@ +package sugarrush + +import ( + "mongo.games.com/game/gamesrv/base" + "mongo.games.com/game/gamesrv/slotspkg/assemble" +) + +type SugarRushSceneData struct { + *base.Scene //场景 + players map[int32]*SugarRushPlayerData //玩家信息 + BetConfig *assemble.BetConfig +} + +func NewSugarRushSceneData(s *base.Scene) *SugarRushSceneData { + sceneEx := &SugarRushSceneData{ + Scene: s, + players: make(map[int32]*SugarRushPlayerData), + } + sceneEx.Init() + return sceneEx +} +func (s *SugarRushSceneData) Init() { + +} + +func (s *SugarRushSceneData) Clear() { + //应该是水池变一次就判断修改一次 + //s.slotRateWeight = s.slotRateWeightTotal[0] +} +func (s *SugarRushSceneData) SceneDestroy(force bool) { + //销毁房间 + s.Scene.Destroy(force) +} + +func (s *SugarRushSceneData) delPlayer(SnId int32) { + if _, exist := s.players[SnId]; exist { + delete(s.players, SnId) + } +} +func (s *SugarRushSceneData) OnPlayerLeave(p *base.Player, reason int) { + if /*playerEx*/ _, ok := p.ExtraData.(*SugarRushPlayerData); ok { + + } + s.delPlayer(p.SnId) +} diff --git a/gamesrv/sugarrush/scenepolicy_sugarrush.go b/gamesrv/sugarrush/scenepolicy_sugarrush.go new file mode 100644 index 0000000..92decd1 --- /dev/null +++ b/gamesrv/sugarrush/scenepolicy_sugarrush.go @@ -0,0 +1,585 @@ +package sugarrush + +import ( + "encoding/json" + "mongo.games.com/game/common" + "mongo.games.com/game/gamerule/sugarrush" + "mongo.games.com/game/gamesrv/base" + "mongo.games.com/game/gamesrv/slotspkg/assemble" + "mongo.games.com/game/gamesrv/slotspkg/slots" + "mongo.games.com/game/model" + "mongo.games.com/game/proto" + "mongo.games.com/game/protocol/server" + protocol "mongo.games.com/game/protocol/sugarrush" + "mongo.games.com/goserver/core" + "mongo.games.com/goserver/core/logger" + "time" +) + +// //////////////////////////////////////////////////////////// +var ScenePolicySugarRushSington = &ScenePolicySugarRush{} + +type ScenePolicySugarRush struct { + base.BaseScenePolicy + states [sugarrush.SugarRushStateMax]base.SceneState +} + +// 创建场景扩展数据 +func (this *ScenePolicySugarRush) CreateSceneExData(s *base.Scene) interface{} { + sceneEx := NewSugarRushSceneData(s) + if sceneEx != nil { + if sceneEx.GetInit() { + s.SetExtraData(sceneEx) + } + } + return sceneEx +} + +// 创建玩家扩展数据 +func (this *ScenePolicySugarRush) CreatePlayerExData(s *base.Scene, p *base.Player) interface{} { + playerEx := &SugarRushPlayerData{Player: p} + p.SetExtraData(playerEx) + return playerEx +} + +// 场景开启事件 +func (this *ScenePolicySugarRush) OnStart(s *base.Scene) { + logger.Logger.Trace("(this *ScenePolicySugarRush) OnStart, sceneId=", s.GetSceneId()) + sceneEx := NewSugarRushSceneData(s) + if sceneEx != nil { + if sceneEx.GetInit() { + s.SetExtraData(sceneEx) + s.ChangeSceneState(sugarrush.SugarRushStateStart) + } + } +} + +// 场景关闭事件 +func (this *ScenePolicySugarRush) OnStop(s *base.Scene) { + logger.Logger.Trace("(this *ScenePolicySugarRush) OnStop , sceneId=", s.GetSceneId()) +} + +// 场景心跳事件 +func (this *ScenePolicySugarRush) OnTick(s *base.Scene) { + if s == nil { + return + } + if s.GetSceneState() != nil { + s.GetSceneState().OnTick(s) + } +} + +// 玩家进入事件 +func (this *ScenePolicySugarRush) OnPlayerEnter(s *base.Scene, p *base.Player) { + if s == nil || p == nil { + return + } + logger.Logger.Trace("(this *ScenePolicySugarRush) OnPlayerEnter, sceneId=", s.GetSceneId(), " player=", p.Name) + if sceneEx, ok := s.GetExtraData().(*SugarRushSceneData); ok { + playerEx := &SugarRushPlayerData{Player: p} + + playerEx.init() + + d := p.GameData[sugarrush.GameDataKey] + if d != nil { + m := make(map[string]string) + json.Unmarshal(d.Data.([]byte), &m) + playerEx.PullPlayer(m) + } else { + m := make(map[string]string) + //json.Unmarshal(d.Data.([]byte), &m) + playerEx.PullPlayer(m) + } + + playerEx.SlotsSession.SetCoin(playerEx.Coin * sugarrush.NowByte) + + playerEx.Clear() + + sceneEx.players[p.SnId] = playerEx + + p.SetExtraData(playerEx) + SugarRushSendRoomInfo(s, sceneEx, playerEx) + + s.FirePlayerEvent(p, base.PlayerEventEnter, nil) + } +} + +// 玩家离开事件 +func (this *ScenePolicySugarRush) OnPlayerLeave(s *base.Scene, p *base.Player, reason int) { + if s == nil || p == nil { + return + } + logger.Logger.Trace("(this *ScenePolicySugarRush) OnPlayerLeave, sceneId=", s.GetSceneId(), " player=", p.SnId) + if playerEx, ok := p.ExtraData.(*SugarRushPlayerData); ok { + playerEx.LabaLog.Save(2) // 没有收到结束消息,算2秒游戏时长 + m := playerEx.PushPlayer() + if m != nil && len(m) > 0 { + b, err := json.Marshal(m) + if err != nil { + logger.Logger.Error("OnPlayerLeave, json.Marshal error:", err) + } else { + p.GameData[sugarrush.GameDataKey] = &model.PlayerGameData{ + Platform: p.Platform, + SnId: p.SnId, + Id: sugarrush.GameDataKey, + Data: b, + } + } + } + } + if sceneEx, ok := s.ExtraData.(*SugarRushSceneData); ok { + s.FirePlayerEvent(p, base.PlayerEventLeave, nil) + sceneEx.OnPlayerLeave(p, reason) + } +} + +// 玩家掉线 +func (this *ScenePolicySugarRush) OnPlayerDropLine(s *base.Scene, p *base.Player) { + if s == nil || p == nil { + return + } + logger.Logger.Trace("(this *ScenePolicySugarRush) OnPlayerDropLine, sceneId=", s.GetSceneId(), " player=", p.SnId) + s.FirePlayerEvent(p, base.PlayerEventDropLine, nil) +} + +// 玩家重连 +func (this *ScenePolicySugarRush) OnPlayerRehold(s *base.Scene, p *base.Player) { + if s == nil || p == nil { + return + } + logger.Logger.Trace("(this *ScenePolicySugarRush) OnPlayerRehold, sceneId=", s.GetSceneId(), " player=", p.SnId) + if sceneEx, ok := s.GetExtraData().(*SugarRushSceneData); ok { + if playerEx, ok := p.GetExtraData().(*SugarRushPlayerData); ok { + SugarRushSendRoomInfo(s, sceneEx, playerEx) + } + } +} + +// 返回房间 +func (this *ScenePolicySugarRush) OnPlayerReturn(s *base.Scene, p *base.Player) { + if s == nil || p == nil { + return + } + logger.Logger.Trace("(this *ScenePolicySugarRush) OnPlayerReturn, GetSceneId()=", s.GetSceneId(), " player=", p.Name) + if sceneEx, ok := s.GetExtraData().(*SugarRushSceneData); ok { + if playerEx, ok := p.GetExtraData().(*SugarRushPlayerData); ok { + //if p.IsMarkFlag(base.PlayerState_Auto) { + // p.UnmarkFlag(base.PlayerState_Auto) + // p.SyncFlag() + //} + //发送房间信息给自己 + SugarRushSendRoomInfo(s, sceneEx, playerEx) + s.FirePlayerEvent(p, base.PlayerEventReturn, nil) + } + } +} + +func SugarRushSendRoomInfo(s *base.Scene, sceneEx *SugarRushSceneData, playerEx *SugarRushPlayerData) { + pack := SugarRushCreateRoomInfoPacket(s, sceneEx, playerEx) + logger.Logger.Trace("RoomInfo: ", pack) + playerEx.SendToClient(int(protocol.SugarRushPID_PACKET_SUGARRUSH_SCSUGARRUSHROOMINFO), pack) +} +func SugarRushCreateRoomInfoPacket(s *base.Scene, sceneEx *SugarRushSceneData, playerEx *SugarRushPlayerData) interface{} { + //房间信息 + pack := &protocol.SCSugarRushRoomInfo{ + 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.SugarRushPlayerData{ + 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 + } + + //get data + Response, err := slots.SlotsMgrSington.Enter(playerEx.SlotsSession, int64(s.GameId)) + if err == nil { + data := assemble.DataToCli(Response).(assemble.TableInfo) + pi, _ := json.Marshal(data) + pack.PlayerInfo = string(pi) + if sceneEx.BetConfig == nil { + sceneEx.BetConfig = &data.BetConfig + } + } else { + logger.Logger.Error("slots enter err:", err) + } + proto.SetDefaults(pack) + return pack +} +func (this *ScenePolicySugarRush) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool { + if s == nil || p == nil { + return false + } + logger.Logger.Trace("(this *ScenePolicySugarRush) 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 *ScenePolicySugarRush) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) { + if s == nil || p == nil { + return + } + logger.Logger.Trace("(this *ScenePolicySugarRush) OnPlayerEvent, sceneId=", s.GetSceneId(), " player=", p.SnId, " eventcode=", evtcode, " params=", params) + if s.GetSceneState() != nil { + s.GetSceneState().OnPlayerEvent(s, p, evtcode, params) + } +} + +// 当前状态能否换桌 +func (this *ScenePolicySugarRush) 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 SceneBaseStateSugarRush struct { +} + +func (this *SceneBaseStateSugarRush) GetTimeout(s *base.Scene) int { + if sceneEx, ok := s.GetExtraData().(*SugarRushSceneData); ok { + return int(time.Now().Sub(sceneEx.GetStateStartTime()) / time.Second) + } + return 0 +} + +func (this *SceneBaseStateSugarRush) CanChangeTo(s base.SceneState) bool { + return true +} + +// 当前状态能否换桌 +func (this *SceneBaseStateSugarRush) CanChangeCoinScene(s *base.Scene, p *base.Player) bool { + return true +} +func (this *SceneBaseStateSugarRush) OnEnter(s *base.Scene) { + if sceneEx, ok := s.GetExtraData().(*SugarRushSceneData); ok { + sceneEx.SetStateStartTime(time.Now()) + } +} + +func (this *SceneBaseStateSugarRush) OnLeave(s *base.Scene) {} +func (this *SceneBaseStateSugarRush) OnTick(s *base.Scene) { + if time.Now().Sub(s.GameStartTime) > time.Second*3 { + if sceneEx, ok := s.ExtraData.(*SugarRushSceneData); ok { + 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() + } +} +func (this *SceneBaseStateSugarRush) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool { + return false +} +func (this *SceneBaseStateSugarRush) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) { +} + +// //////////////////////////////////////////////////////////// +// 开始状态 +// //////////////////////////////////////////////////////////// +type SceneStateStartSugarRush struct { + SceneBaseStateSugarRush +} + +func (this *SceneStateStartSugarRush) GetState() int { + return sugarrush.SugarRushStateStart +} + +func (this *SceneStateStartSugarRush) CanChangeTo(s base.SceneState) bool { + return false +} + +// 当前状态能否换桌 +func (this *SceneStateStartSugarRush) CanChangeCoinScene(s *base.Scene, p *base.Player) bool { + if playerEx, ok := p.GetExtraData().(*SugarRushPlayerData); ok { + if playerEx.isFree { + return false + } + } + return true +} + +func (this *SceneStateStartSugarRush) GetTimeout(s *base.Scene) int { + return 0 +} + +func (this *SceneStateStartSugarRush) OnEnter(s *base.Scene) { + this.SceneBaseStateSugarRush.OnEnter(s) + if sceneEx, ok := s.GetExtraData().(*SugarRushSceneData); ok { + sceneEx.SetGameNowTime(time.Now()) + } +} + +// 状态离开时 +func (this *SceneStateStartSugarRush) OnLeave(s *base.Scene) { + this.SceneBaseStateSugarRush.OnLeave(s) + logger.Logger.Tracef("(this *SceneStateStartSugarRush) OnLeave, sceneid=%v", s.GetSceneId()) +} + +// 玩家操作 +func (this *SceneStateStartSugarRush) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool { + logger.Logger.Tracef("(this *SceneStateStartSugarRush) OnPlayerOp, sceneid=%v params=%v", s.GetSceneId(), params) + if this.SceneBaseStateSugarRush.OnPlayerOp(s, p, opcode, params) { + return true + } + if sceneEx, ok := s.GetExtraData().(*SugarRushSceneData); ok { + if playerEx, ok := p.GetExtraData().(*SugarRushPlayerData); ok { + switch opcode { + case sugarrush.SugarRushPlayerOpStart: + playerEx.Clear() + if len(params) < 4 { + pack := &protocol.SCSugarRushBilled{ + OpRetCode: proto.Int32(1), + } + proto.SetDefaults(pack) + logger.Logger.Trace("SCSugarRushBilled", pack.String()) + playerEx.SendToClient(int(protocol.SugarRushPID_PACKET_SUGARRUSH_SCSUGARRUSHBILLED), pack) + return true + } + playerEx.BetSizeIndex = params[0] + playerEx.BetLevelIndex = params[1] + playerEx.BetLineIndex = params[2] + playerEx.BetMode = params[3] + needCoin := sceneEx.BetConfig.BetSize[params[0]] * float64(sceneEx.BetConfig.BetLevel[params[1]]) * + float64(sceneEx.BetConfig.BetLines[params[2]]) * float64(sceneEx.BetConfig.BaseBet[params[2]]) + if needCoin > float64(playerEx.Coin) && !playerEx.isFree { + pack := &protocol.SCSugarRushBilled{ + OpRetCode: proto.Int32(1), + } + proto.SetDefaults(pack) + logger.Logger.Trace("SCSugarRushBilled:", pack.String()) + playerEx.SendToClient(int(protocol.SugarRushPID_PACKET_SUGARRUSH_SCSUGARRUSHBILLED), pack) + return true + } + + //playerEx.SlotsSession.SetCoin(playerEx.Coin * sugarrush.NowByte) + //logger.Logger.Trace("=============init dif coin", playerEx.Coin-playerEx.SlotsSession.Coin()/sugarrush.NowByte) + + //get data + Response, err := slots.SlotsMgrSington.Play(playerEx.SlotsSession, &base.SpinReq{ + GameId: int64(sceneEx.GameId), + BetSizeIndex: playerEx.BetSizeIndex, + BetLevelIndex: playerEx.BetLevelIndex, + BetLineIndex: playerEx.BetLineIndex, + BetMode: playerEx.BetMode, + Ts: time.Now().Unix(), + }) + var gameEndStr string + var data assemble.GameEnd + if err == nil { + s.SetGameNowTime(time.Now()) + data = assemble.DataToCli(Response).(assemble.GameEnd) + + data.BetSizeIndex = playerEx.BetSizeIndex + data.BetLevelIndex = playerEx.BetLevelIndex + data.LinesIndex = playerEx.BetLineIndex + //data.BaseBetIndex = 1 + + data.Results[0].BetMode = playerEx.BetMode + if data.Results[0].FreeStatus == 1 || data.Results[0].FreeNumMax == 0 { + //logger.Logger.Trace("=====================AddCoin=====TotalBet===", -data.TotalBet) + //第一次触发或者正常模式 + playerEx.AddCoin(int64(-data.TotalBet), common.GainWay_HundredSceneLost, base.SyncFlag_ToClient, "system", s.GetSceneName()) + playerEx.totalBet = int64(data.TotalBet) + } + var taxCoin float64 + if data.RoundReward > 0 { + //税收比例 + taxRate := sceneEx.GetDBGameFree().GetTaxRate() + if taxRate < 0 || taxRate > 10000 { + taxRate = 500 + } + taxCoin = data.RoundReward * float64(taxRate) / 10000 + data.RoundReward = data.RoundReward - taxCoin + playerEx.AddServiceFee(int64(taxCoin)) + playerEx.taxCoin = int64(taxCoin) + playerEx.winCoin = int64(data.RoundReward) + } + pi, _ := json.Marshal(data) + gameEndStr = string(pi) + + if data.Results[0].FreeStatus == 3 || data.Results[0].FreeNumMax == 0 { + //logger.Logger.Trace("=====================AddCoin=====RoundReward===", data.RoundReward) + playerEx.AddCoin(int64(data.RoundReward), common.GainWay_HundredSceneWin, 0, "system", s.GetSceneName()) + //免费游戏结束或者正常模式 + sceneEx.StaticsLaba(&base.StaticLabaParam{ + SnId: playerEx.SnId, + Gain: int64(data.RoundReward - data.TotalBet), + GainTax: int64(taxCoin), + IsAddTimes: true, + }) + } + if data.Results[0].FreeNum > 0 { + playerEx.isFree = true + } else { + playerEx.isFree = false + } + } else { + logger.Logger.Error("slots Play err:", err) + } + + playerEx.SlotsSession.SetCoin(int64(data.FinalCoin) * sugarrush.NowByte) + //logger.Logger.Trace("=====================end===== playerEx.Coin===", playerEx.Coin) + //logger.Logger.Trace("=====================end===== data.FinalCoin===", data.FinalCoin) + + pack := &protocol.SCSugarRushBilled{ + OpRetCode: proto.Int32(0), + GameEndStr: proto.String(gameEndStr), + } + proto.SetDefaults(pack) + logger.Logger.Trace("SCSugarRushBilled", pack.String()) + playerEx.SendToClient(int(protocol.SugarRushPID_PACKET_SUGARRUSH_SCSUGARRUSHBILLED), pack) + + if playerEx.Coin != int64(data.FinalCoin) { + logger.Logger.Error("==========playerEx.Coin != Response.Coin==============", playerEx.Coin, data.FinalCoin) + } + + // 记录本次操作 + SugarRushAndSaveLog(sceneEx, playerEx, data) + case 1000: + playerEx.Save(0) + } + } + } + return true +} + +// 玩家事件 +func (this *SceneStateStartSugarRush) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) { + logger.Logger.Trace("(this *SceneStateStartSugarRush) OnPlayerEvent, sceneId=", s.GetSceneId(), " player=", p.SnId, " evtcode=", evtcode) + this.SceneBaseStateSugarRush.OnPlayerEvent(s, p, evtcode, params) +} + +func (this *SceneStateStartSugarRush) OnTick(s *base.Scene) { + this.SceneBaseStateSugarRush.OnTick(s) +} + +// ////////////////////////////////////////////////////////////////////////////// +func (this *ScenePolicySugarRush) RegisteSceneState(state base.SceneState) { + if state == nil { + return + } + stateid := state.GetState() + if stateid < 0 || stateid >= sugarrush.SugarRushStateMax { + return + } + this.states[stateid] = state +} + +func (this *ScenePolicySugarRush) GetSceneState(s *base.Scene, stateid int) base.SceneState { + if stateid >= 0 && stateid < sugarrush.SugarRushStateMax { + return this.states[stateid] + } + return nil +} +func SugarRushAndSaveLog(sceneEx *SugarRushSceneData, playerEx *SugarRushPlayerData, data assemble.GameEnd) { + if !playerEx.IsRob { + data.SnId = playerEx.SnId + if data.Results[0].FreeStatus != 1 && data.Results[0].FreeNumMax != 0 { + data.TotalBet = 0 + } + info, err := model.MarshalGameNoteByROLL(data) + if err == nil { + logid, _ := model.AutoIncGameLogId() + playerEx.currentLogId = logid + var totalin, totalout int64 + if data.Results[0].FreeStatus == 1 || data.Results[0].FreeNumMax == 0 { + totalin = playerEx.totalBet + } + if data.Results[0].FreeStatus == 3 || data.Results[0].FreeNumMax == 0 { + totalout = int64(data.RoundReward) + playerEx.taxCoin + } + playerEx.Cache(sceneEx.Scene, &base.SaveGameDetailedParam{ + LogId: logid, + Detail: info, + }, &base.SaveGamePlayerListLogParam{ + LogId: logid, + Platform: playerEx.Platform, + Snid: playerEx.SnId, + PlayerName: playerEx.Name, + TotalIn: totalin, + TotalOut: totalout, + TaxCoin: playerEx.taxCoin, + BetAmount: totalin, + WinAmountNoAnyTax: totalout - totalin - playerEx.taxCoin, + IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player), + IsFree: playerEx.isFree, + }) + } + } + + //统计输下注金币数 + if !sceneEx.Testing && !playerEx.IsRob { + playerBet := &server.PlayerData{ + SnId: proto.Int32(playerEx.SnId), + Bet: proto.Int64(playerEx.CurrentBet), + Gain: proto.Int64(int64(data.RoundReward) + playerEx.taxCoin), + Tax: proto.Int64(playerEx.taxCoin), + Coin: proto.Int64(playerEx.GetCoin()), + GameCoinTs: proto.Int64(playerEx.GameCoinTs), + } + gwPlayerBet := &server.GWPlayerData{ + SceneId: sceneEx.SceneId, + GameFreeId: proto.Int32(sceneEx.GetDBGameFree().GetId()), + } + gwPlayerBet.Datas = append(gwPlayerBet.Datas, playerBet) + sceneEx.SyncPlayerDatas(&base.PlayerDataParam{ + HasRobotGaming: false, + Data: gwPlayerBet, + }) + } + + playerEx.taxCoin = 0 + playerEx.winCoin = 0 + + if sceneEx.CheckNeedDestroy() && data.Results[0].FreeNum <= 0 { + sceneEx.SceneDestroy(true) + } +} +func init() { + //主状态 + ScenePolicySugarRushSington.RegisteSceneState(&SceneStateStartSugarRush{}) + core.RegisteHook(core.HOOK_BEFORE_START, func() error { + base.RegisteScenePolicy(common.GameId_SugarRush, sugarrush.RoomMode_Classic, ScenePolicySugarRushSington) + return nil + }) +}