game_sync/gamesrv/clawdoll/scene_clawdoll.go

389 lines
9.6 KiB
Go

package clawdoll
import (
"container/list"
"mongo.games.com/game/common"
rule "mongo.games.com/game/gamerule/clawdoll"
"mongo.games.com/game/gamesrv/base"
"mongo.games.com/game/proto"
"mongo.games.com/game/protocol/clawdoll"
"mongo.games.com/game/protocol/machine"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib"
"mongo.games.com/goserver/srvlib"
)
type PlayerData struct {
SnId int32
Head int32 //头像框
VIP int32 //VIP帐号 等级
Name string //名字
Sex int32 //性别
IsRob bool
Coin int64
gainCoin int64 //本局赢的金币
taxCoin int64 //本局税收
isBilled bool //是否结算
CurIsWin int64 //当局输赢 负数:输 正数:赢
InviterId int32 //邀请人Id
BeUnderAgentCode string //隶属经销商(推广人)
IsPlayerFirst bool
Platform string //平台
Channel string //渠道信息
PackageID string //推广包标识 对应客户端的packagetag
flag int
}
type SceneEx struct {
*base.Scene // 场景
logic *rule.Logic //
players map[int32]*PlayerEx // 玩家信息
PlayerBackup map[int32]*PlayerData // 本局离场玩家数据备份
seats []*PlayerEx // 本局游戏中的玩家状态数据
waitPlayers *list.List
playingSnid int32 // 正在玩的玩家snid
RoundId int // 局数,第几局
robotNum int // 参与游戏的机器人数量
logid string
machineId int //娃娃机ID
machineConn *netlib.Session //娃娃机链接
machineStatus int32 //娃娃机链接状态 0:离线 1:在线
}
// 游戏是否能开始
func (this *SceneEx) CanStart() bool {
//人数>=1自动开始
if len(this.players) >= 1 && (this.GetRealPlayerNum() >= 1 || this.IsPreCreateScene() || this.IsHasPlaying()) {
return true
}
return false
}
// 从房间删除玩家
func (this *SceneEx) delPlayer(p *base.Player) {
if p, exist := this.players[p.SnId]; exist {
//this.seats[p.GetPos()] = nil
delete(this.players, p.SnId)
this.RemoveWaitPlayer(p.SnId)
}
}
// 广播玩家进入
func (this *SceneEx) BroadcastPlayerEnter(p *base.Player, reason int) {
pack := &clawdoll.SCCLAWDOLLPlayerEnter{}
pack.Data = &clawdoll.CLAWDOLLPlayerDigestInfo{}
pack.Data.SnId = p.GetSnId()
pack.Data.Head = p.Head
pack.Data.HeadUrl = p.HeadUrl
pack.Data.Name = p.Name
proto.SetDefaults(pack)
this.Broadcast(int(clawdoll.CLAWDOLLPacketID_PACKET_SC_PlayerEnter), pack, p.GetSid())
}
// 广播玩家离开
func (this *SceneEx) BroadcastPlayerLeave(p *base.Player, reason int) {
scLeavePack := &clawdoll.SCCLAWDOLLPlayerLeave{
SnId: proto.Int32(p.SnId),
}
proto.SetDefaults(scLeavePack)
this.Broadcast(int(clawdoll.CLAWDOLLPacketID_PACKET_SC_PlayerLeave), scLeavePack, p.GetSid())
}
// 玩家进入事件
func (this *SceneEx) OnPlayerEnter(p *base.Player, reason int) {
this.BroadcastPlayerEnter(p, reason)
}
// 玩家离开事件
func (this *SceneEx) OnPlayerLeave(p *base.Player, reason int) {
this.delPlayer(p)
this.BroadcastPlayerLeave(p, reason)
}
func (this *SceneEx) SceneDestroy(force bool) {
//销毁房间
this.Scene.Destroy(force)
}
func (e *SceneEx) playerOpPack(snId int32, opcode int, opRetCode clawdoll.OpResultCode, params []int64) *clawdoll.SCCLAWDOLLOp {
pack := &clawdoll.SCCLAWDOLLOp{
SnId: proto.Int32(snId),
OpCode: proto.Int32(int32(opcode)),
Params: params,
OpRetCode: opRetCode,
}
proto.SetDefaults(pack)
return pack
}
// OnPlayerSCOp 发送玩家操作情况
func (e *SceneEx) OnPlayerSCOp(p *base.Player, opcode int, opRetCode clawdoll.OpResultCode, params []int64) {
pack := e.playerOpPack(p.SnId, opcode, opRetCode, params)
p.SendToClient(int(clawdoll.CLAWDOLLPacketID_PACKET_SC_PLAYEROP), pack)
logger.Logger.Tracef("OnPlayerSCOp %s", pack)
}
// 房间信息打包
func (this *SceneEx) ClawdollCreateRoomInfoPacket(s *base.Scene, p *base.Player) interface{} {
pack := &clawdoll.SCCLAWDOLLRoomInfo{
RoomId: proto.Int(s.GetSceneId()),
GameId: proto.Int(s.GetGameId()),
RoomMode: proto.Int(s.GetSceneMode()),
Params: common.CopySliceInt64ToInt32(s.Params),
State: proto.Int(s.GetSceneState().GetState()),
TimeOut: proto.Int(s.GetSceneState().GetTimeout(s)),
TotalPlayer: proto.Int(len(this.players)),
RoundId: proto.Int(this.RoundId),
ParamsEx: nil,
GameFreeId: 0,
BaseScore: proto.Int32(this.GetBaseScore()),
}
// 玩家信息
for _, playerEx := range this.players {
if p.SnId == playerEx.SnId {
pd := &clawdoll.CLAWDOLLPlayerData{
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),
Flag: proto.Int(playerEx.GetFlag()),
HeadOutLine: proto.Int32(playerEx.HeadOutLine),
VIP: proto.Int32(playerEx.VIP),
WinCoin: proto.Int64(playerEx.gainCoin),
ClawDollState: proto.Int32(playerEx.clawDollState),
}
pack.Players = append(pack.Players, pd)
}
}
proto.SetDefaults(pack)
if p != nil {
p.SyncFlag()
}
return pack
}
func NewClawdollSceneData(s *base.Scene) *SceneEx {
sceneEx := &SceneEx{
Scene: s,
logic: new(rule.Logic),
players: make(map[int32]*PlayerEx),
PlayerBackup: make(map[int32]*PlayerData),
waitPlayers: list.New(),
}
return sceneEx
}
func (this *SceneEx) init() bool {
this.Clear()
return true
}
// 检查上分投币是否合法
func (this *SceneEx) CheckPayCoinOp(p *PlayerEx) bool {
if p == nil {
return false
}
if p.SnId == this.playingSnid {
return true
}
return false
}
// 检查移动是否合法
func (this *SceneEx) CheckMoveOp(p *PlayerEx) bool {
if p == nil {
return false
}
if p.SnId == this.playingSnid {
return true
}
return false
}
// 下抓是否合法
func (this *SceneEx) CheckGrapOp(p *PlayerEx) bool {
if p == nil {
return false
}
if p.SnId == this.playingSnid {
return true
}
return false
}
func (this *SceneEx) Clear() {
this.robotNum = 0
this.PlayerBackup = make(map[int32]*PlayerData)
this.RoundId = 0
for e := this.waitPlayers.Front(); e != nil; e = e.Next() {
if e != nil {
p := e.Value.(*PlayerEx)
p.Clear(0)
}
}
}
// 是否有玩家正在玩
func (this *SceneEx) IsHasPlaying() bool {
if this.playingSnid == 0 {
return false
}
return true
}
// 等待下一个玩家
func (this *SceneEx) ReStartGame() {
this.playingSnid = 0
}
func (this *SceneEx) BackupPlayer(p *PlayerEx, isBilled bool) {
this.PlayerBackup[p.SnId] = &PlayerData{
SnId: p.SnId,
gainCoin: p.gainCoin,
taxCoin: p.taxCoin,
isBilled: isBilled,
IsRob: p.IsRob,
Coin: p.Coin,
Head: p.Head,
flag: p.GetFlag(),
Platform: p.Platform,
Channel: p.Channel,
PackageID: p.PackageID,
CurIsWin: p.CurIsWin,
Name: p.Name,
Sex: p.Sex,
VIP: p.VIP,
InviterId: p.InviterId,
IsPlayerFirst: this.IsPlayerFirst(p.Player),
BeUnderAgentCode: p.BeUnderAgentCode,
}
}
func (this *SceneEx) GetPlayGrabType(player *PlayerEx) int32 {
if player == nil {
return rule.ClawWeak
}
if this.RoundId%100 == 0 && this.RoundId != 0 {
return rule.ClawStrong
}
return rule.ClawWeak
}
func (this *SceneEx) AddWaitPlayer(player *PlayerEx) {
if player == nil {
return
}
this.waitPlayers.PushBack(player)
}
func (this *SceneEx) RemoveWaitPlayer(SnId int32) bool {
l := this.waitPlayers
for e := l.Front(); e != nil; e = e.Next() {
if p := e.Value.(*PlayerEx); p.SnId == SnId {
this.waitPlayers.Remove(e)
return true
}
}
return false
}
func (this *SceneEx) GetPlayingEx() *PlayerEx {
if this.playingSnid == 0 {
return nil
}
return this.players[this.playingSnid]
}
func (this *SceneEx) SetPlayingState(state int32) {
if this.playingSnid == 0 {
return
}
playerEx := this.players[this.playingSnid]
if playerEx != nil {
oldState := playerEx.GetClawState()
if oldState != state {
if oldState == rule.ClawDollPlayerStateWait && (state >= rule.ClawDollPlayerStateStart && state <= rule.ClawDollPlayerWaitPayCoin) {
ClawdollBroadcastPlayingInfo(this.Scene)
}
if state == rule.ClawDollPlayerStateWait && (oldState >= rule.ClawDollPlayerStateStart && oldState <= rule.ClawDollPlayerWaitPayCoin) {
ClawdollBroadcastPlayingInfo(this.Scene)
}
}
playerEx.SetClawState(state)
}
}
// 时间到 系统开始下抓
func (this *SceneEx) TimeOutPlayGrab() bool {
this.OnPlayerSMGrabOp(this.playingSnid, int32(this.machineId), rule.ClawWeak)
return true
}
// OnPlayerSMGrabOp 下抓 //1-弱力抓 2 -强力抓 3-必出抓
func (this *SceneEx) OnPlayerSMGrabOp(SnId, Id, GrabType int32) {
pack := &machine.SMDollMachineGrab{
Snid: proto.Int32(SnId),
Id: proto.Int32(Id),
TypeId: proto.Int32(GrabType),
}
this.SendToMachine(int(machine.DollMachinePacketID_PACKET_SMDollMachineGrab), pack)
}
// OnPlayerSCOp 发送玩家操作情况 1-前 2-后 3-左 4-右 5-投币
func (this *SceneEx) OnPlayerSMPerateOp(SnId, Id, Perate int32) {
pack := &machine.SMDollMachineoPerate{
Snid: proto.Int32(SnId),
Id: proto.Int32(Id),
Perate: proto.Int32(Perate),
}
this.SendToMachine(int(machine.DollMachinePacketID_PACKET_SMDollMachinePerate), pack)
}
// 向娃娃机主机发送消息
func (this *SceneEx) SendToMachine(pid int, msg interface{}) {
this.machineConn = srvlib.ServerSessionMgrSington.GetSession(1, 10, 1001)
if this.machineConn != nil {
this.machineConn.Send(pid, msg)
} else {
logger.Logger.Error("MachineConn is nil !")
}
}