package entertainment import ( "crypto/rand" "errors" "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/sys/event" "go_dreamfactory/lego/sys/timewheel" "go_dreamfactory/pb" "go_dreamfactory/sys/configure" cfg "go_dreamfactory/sys/configure/structs" "math/big" "time" "go.mongodb.org/mongo-driver/bson/primitive" "google.golang.org/protobuf/proto" ) const ( MaxPs = 2 // 最大体力 ) //游戏房间 type Room struct { Id string // 房间id szSession []comm.IUserSession player1 *pb.PlayerData // 玩家1 player2 *pb.PlayerData // 玩家2 chessboard *MapData // 地图数据 module *Entertainment round int32 // 当前轮数 closeRoomTimer *timewheel.Task //房间解散倒计时定时器 curPower string // 当前操作的玩家 NexPower string // 下一个操作的玩家 MaxRound int32 // 最大回合数 rd1 bool // 玩家1 是否准备 rd2 bool // 玩家2 是否准备 Status int32 //房间游戏状态 0未开始 1 已开始 2 已结束 RoomType int32 // 房间类型 1 是好友创房 0对战 2 AI 对战 MaxTime int32 // 操作时间 Playtype int32 //当前房间玩法 offline string // 谁离线 } func (this *Room) CloseRoomTimeOut(task *timewheel.Task, args ...interface{}) { this.module.Errorf("解散房间超时+++++%d\n", time.Now().Unix()) //倒计时结束还没结束基本是游戏异常 直接清理房间 this.Status = 2 // 游戏解散 this.ModifyUserRoomInfoData() } // 随机一个玩法 func (this *Room) RandomPlayType() (itype int32) { var weight []int32 // 权重 // 开始随机玩法 list := this.module.configure.GetGameConsumeIntegral() for _, v := range list { weight = append(weight, v.Weight) } itype = list[comm.GetRandW(weight)].Key return } func (this *Room) InitRoom(module *Entertainment, p1 *pb.PlayerData, p2 *pb.PlayerData, itype int32) (room *Room, err error) { this.module = module this.chessboard = new(MapData) if itype == -1 { this.Playtype = this.RandomPlayType() } else { if itype == 0 { itype = 1 // 测试数据 后面删 } this.Playtype = itype // 校验类型 if _, err = this.module.configure.GetGameConsumeIntegralByKey(this.Playtype); err != nil { return } } this.chessboard.InitMap(module, this.Playtype) // 初始化棋盘 if s1, ok := this.module.GetUserSession(p1.Userinfo.Uid); !ok { this.module.PutUserSession(s1) } else { this.szSession = append(this.szSession, s1.Clone()) } if p2.Userinfo.Uid != "999" { // 是否是机器人 if s2, ok := this.module.GetUserSession(p2.Userinfo.Uid); !ok { this.module.PutUserSession(s2) } else { this.szSession = append(this.szSession, s2.Clone()) } } else { this.RoomType = 2 } this.MaxRound = module.ModuleTools.GetGlobalConf().ConsumeRounds room = &Room{ Id: primitive.NewObjectID().Hex(), szSession: this.szSession, player1: p1, player2: p2, chessboard: this.chessboard, module: module, round: 1, MaxRound: this.MaxRound, Status: 0, Playtype: this.Playtype, RoomType: this.RoomType, } if err = this.module.SendMsgSyncToSession(string(this.module.GetType()), "enterroom", &pb.EntertainEnterRoomPush{ Rooid: room.Id, Servepath: fmt.Sprintf("%s/%s", this.module.service.GetType(), this.module.service.GetId()), User1: room.player1, User2: room.player2, Itype: itype, }, this.szSession...); err != nil { this.module.Errorln(err) } return } // AI 操作了 func (this *Room) ReceiveMessage(session comm.IUserSession, stype string, msg proto.Message) (errdata *pb.ErrorData) { switch stype { case "operator": // 操作消息 var ( curScore int32 // 该次操作的得分 oid1 int32 // 唯一id oid2 int32 color int32 // 校验消除的颜色 bAddPs bool curPlayer *pb.PlayerData ) var szMap []*pb.MapData req := msg.(*pb.EntertainOperatorReq) if session.GetUserId() != this.curPower { // 校验是不是你的权限 errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoPower, Title: pb.ErrorCode_EntertainNoPower.ToString(), } return } if this.curPower == this.player1.Userinfo.Uid { color = 1 curPlayer = this.player1 } else { color = 2 curPlayer = this.player2 } if req.Itype == "cardskill" { //释放技能 if errdata = this.UserSkillUp(color, req.Curid); errdata != nil { return } return } else if req.Itype != "swap" { //玩家卡牌技能 if conf, err := this.module.configure.GetGamePlaySkill(req.Itype); err == nil { if curPlayer.Skill[conf.Key] <= 0 { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoSkillCard, // 技能卡不足 Title: pb.ErrorCode_EntertainNoSkillCard.ToString(), } return } curPlayer.Skill[conf.Key] -= 1 if errdata = this.UserCardSkill(curPlayer, color, conf.Key, req.Curid); errdata != nil { return } } return } if req.Itype == "swap" && req.Curid == 0 && req.Targetid == 0 { if this.curPower == this.player1.Userinfo.Uid { this.NexPower = this.player2.Userinfo.Uid this.player2.Ps = 2 this.player1.Ps = 0 } if this.curPower == this.player2.Userinfo.Uid { this.NexPower = this.player1.Userinfo.Uid this.player1.Ps = 2 this.player2.Ps = 0 } } else { bCanChange := false oid1 = this.chessboard.Plat[req.Curid].Oid oid2 = this.chessboard.Plat[req.Targetid].Oid if b, m := this.chessboard.CheckSpecialElemChange(req.Curid, req.Targetid, color); !b { // 交换元素 if b = this.chessboard.SwapGirde(req.Curid, req.Targetid); !b { // 交换格子 errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainCantSwap, // 不能交换 直接返回 Title: pb.ErrorCode_EntertainCantSwap.ToString(), } return } } else { bCanChange = true szMap = append(szMap, m...) } if m, b := this.chessboard.CheckMap(color, true); len(m) > 0 { szMap = append(szMap, m...) bAddPs = b bCanChange = true } if !bCanChange { // 不能消除 this.chessboard.SwapGirde(req.Targetid, req.Curid) // 换到原来的位置 errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainCantSwap, // 不能交换 直接返回 Title: pb.ErrorCode_EntertainCantSwap.ToString(), } return } // 校验下次是不是消除 if !this.chessboard.CheckAndRefreshPlat() { this.chessboard.RedsetPlatData() szMap = append(szMap, &pb.MapData{ Data: this.chessboard.GetPalatData(), ChangeType: 1, }) } if this.curPower == this.player1.Userinfo.Uid { //权限校验 this.player1.Score += curScore this.player1.Ps-- if bAddPs { this.player1.Ps++ if this.player1.Ps > MaxPs { this.player1.Ps = MaxPs } } if this.player1.Ps <= 0 { this.NexPower = this.player2.Userinfo.Uid this.player2.Ps = MaxPs } } else { // this.curPower == this.player2.Uid this.player2.Score += curScore this.player2.Ps-- if bAddPs { this.player2.Ps++ if this.player2.Ps > MaxPs { this.player2.Ps = MaxPs } } if this.player2.Ps <= 0 { this.NexPower = this.player1.Userinfo.Uid this.player1.Ps = MaxPs } } for _, v := range szMap { // curScore += v.CurSocre if color == 1 { this.player1.Score += v.CurSocre v.CurSocre = this.player1.Score this.player1.Energy += v.CurEnergy v.CurEnergy = this.player1.Energy } else { this.player2.Score += v.CurSocre v.CurSocre = this.player2.Score this.player2.Energy += v.CurEnergy v.CurEnergy = this.player2.Energy } } } if this.NexPower == this.player1.Userinfo.Uid && this.NexPower != this.curPower { this.round++ } // 广播消息 if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{ Mpadata: szMap, Power: this.NexPower, Curpower: this.curPower, Score: curScore, Round: this.round, User1: this.player1, User2: this.player2, Itype: req.Itype, Curid: oid1, Targetid: oid2, }, this.szSession...); err != nil { this.module.Errorln(err) } if this.round > this.MaxRound { // 游戏结束 if this.player1.Score == this.player2.Score { this.MaxRound += 1 // 增加一回合 } else { this.GameOver(nil) } return } // 变更权限 this.curPower = this.NexPower case "ready": var bStartGame bool // 可以开始游戏 this.NexPower = this.player1.Userinfo.Uid this.curPower = this.player1.Userinfo.Uid this.player1.Ps = MaxPs this.player2.Ps = 0 if this.RoomType == 2 { // AI对战的话直接开始游戏 bStartGame = true } else { if this.player1.Userinfo.Uid == session.GetUserId() { this.rd1 = true } else if this.player2.Userinfo.Uid == session.GetUserId() { this.rd2 = true } if this.player1.Userinfo.Uid != session.GetUserId() || this.RoomType != 1 { // 房主 if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "gameready", &pb.EntertainGameReadyPush{ P1Ready: this.rd1, P2Ready: this.rd2, }, this.szSession...); err != nil { this.module.Errorln(err) } } if this.rd1 && this.rd2 { // 两个玩家都准备好了 那么就开始游戏 bStartGame = true this.rd1 = false this.rd2 = false } } if bStartGame { // 初始化规则相关 if this.RoomType == 2 { this.MaxTime = this.module.ModuleTools.GetGlobalConf().ConsumePveTime } else { this.MaxTime = this.module.ModuleTools.GetGlobalConf().ConsumePvpTime } this.Status = 1 this.round = 1 if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "startgame", &pb.EntertainStartGamePush{ User1: this.player1, User2: this.player2, Mpadata: &pb.MapData{Data: this.chessboard.Plat}, Power: this.NexPower, Round: this.round, Roomid: this.Id, // 房间ID Playtype: this.Playtype, // 通过权重随机一个玩法 }, this.szSession...); err != nil { this.module.Errorln(err) } this.ModifyUserRoomInfoData() // 游戏开始开启一个定时器 1小时如果还不结束 自动清理 this.closeRoomTimer = timewheel.Add(time.Hour, this.CloseRoomTimeOut) } case "reconnect": // 重连 this.offline = "" session.SendMsg(string(this.module.GetType()), "reconnect", &pb.EntertainReconnectResp{ Roomid: this.Id, Mpadata: &pb.MapData{ Data: this.chessboard.GetPalatData(), CurSocre: 0, CurEnergy: 0, }, Power: this.NexPower, Curpower: this.curPower, Score: 0, Round: this.round, User1: this.player1, User2: this.player2, }) case "dissolve": // 房主解散房间 req := msg.(*pb.EntertainDissolveRoomReq) if this.player1.Userinfo.Uid != req.Roomid { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNotMaster, // 不是房主 Title: pb.ErrorCode_EntertainNotMaster.ToString(), } return } // 游戏中不允许解散 if this.Status == 1 { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainDissolveFailed, // 游戏中不能解散 Title: pb.ErrorCode_EntertainDissolveFailed.ToString(), } return } if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "dissolvemasterroom", &pb.EntertainDissolveMasterRoomPush{ Roomid: this.Id, }, this.szSession...); err != nil { this.module.Errorln(err) } this.Status = 2 this.ModifyUserRoomInfoData() case "operatorover": // 操作完成 开启一个定时器 if this.player1.Userinfo.Uid == session.GetUserId() { this.rd1 = true } else if this.player2.Userinfo.Uid == session.GetUserId() { this.rd2 = true } if this.RoomType == 2 || this.offline != "" { if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "startimer", &pb.EntertainStarTimerPush{ Time: this.MaxTime, Power: this.curPower, }, this.szSession...); err != nil { this.module.Errorln(err) } if this.offline != "" && this.curPower == this.offline { this.AutoOperator(this.offline) // 托管 } else { if this.curPower == this.player2.Userinfo.Uid { this.AutoOperator(this.curPower) } } } else { if this.rd1 && this.rd2 { // 两个玩家都准备好了 那么就开始游戏 this.rd1 = false this.rd2 = false if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "startimer", &pb.EntertainStarTimerPush{ Time: this.MaxTime, Power: this.curPower, }, this.szSession...); err != nil { this.module.Errorln(err) } } } //this.operatetimer = timewheel.Add(time.Second*time.Duration(this.MaxTime), this.operateTimeOut) case "offline": req := msg.(*pb.RPCGeneralReqA2) fmt.Printf("useroffline: %v\n", req) if this.RoomType == 2 { // AI 对战直接结束 this.Status = 2 // 解散 this.ModifyUserRoomInfoData() return } if this.offline == "" { this.offline = req.Param2 // 如果当前权限是自己开启托管 if this.curPower == this.offline { this.AutoOperator(this.offline) } } else { if this.offline != req.Param2 { // 两个都离线 游戏直接结束 this.Status = 2 // 解散 this.ModifyUserRoomInfoData() } } case "surrender": if this.Status != 1 { // 不是游戏中 直接返回 errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoGamePlayering, Title: pb.ErrorCode_EntertainNoGamePlayering.ToString(), } return } var winner *pb.PlayerData if this.player1.Userinfo.Uid == session.GetUserId() { winner = this.player2 } else { winner = this.player1 } this.GameOver(winner) } return } // 游戏结束 func (this *Room) GameOver(winner *pb.PlayerData) (errdata *pb.ErrorData) { var ( atno []*pb.UserAtno winindex int32 res []*cfg.Gameatn lostPlayer *pb.PlayerData // 输的玩家 box *pb.BoxData // 是否可以获得宝箱奖励 pl []*pb.XxlPlayer winScore int32 // 胜利获得的积分 lostScore int32 // 失败扣的积分 bDestruction bool ) if winner == nil { if this.player1.Score < this.player2.Score { winner = this.player2 winindex = 1 } else { winner = this.player1 } } if this.player1 != winner { lostPlayer = this.player1 } else { lostPlayer = this.player2 } if winner.Userinfo.Uid != "999" { var ( list *pb.DBXXLData err error update map[string]interface{} ) update = make(map[string]interface{}) if list, err = this.module.model.getEntertainmList(winner.Userinfo.Uid); err != nil { return } if conf, err := this.module.configure.GetGameConsumeintegral(list.Consumeexp); err == nil { for _, v := range conf.Rewards { if v.A == "attr" && v.T == "consumeexp" { list.Consumeexp += v.N winScore = v.N update["consumeexp"] = list.Consumeexp winner.Consumeexp = list.Consumeexp if list.Consumeexp > list.Maxconsumeexp { // 写最高积分 list.Maxconsumeexp = list.Consumeexp update["maxconsumeexp"] = list.Maxconsumeexp } if list.Maxsocre < winner.Score { list.Maxsocre = winner.Score update["maxsocre"] = list.Maxsocre } } else { res = append(res, v) } } if errdata, atno = this.module.DispenseAtno(this.szSession[winindex], res, true); errdata != nil { return } this.szSession[winindex].Push() } // 修改连胜 list.Liansheng += 1 update["liansheng"] = list.Liansheng if len(list.Box) < 3 { // 可以获得一个宝箱 if c, err := this.module.configure.GetGameRandomConsumeBoxConf(); err == nil { if c.Color != 0 { box = &pb.BoxData{ Boxid: c.Boxid, Opentime: int64(c.Cd) + configure.Now().Unix(), } list.Box = append(list.Box, box) update["box"] = list.Box } } } this.module.model.modifyEntertainmList(winner.Userinfo.Uid, update) if user, err := this.module.ModuleUser.GetUser(winner.Userinfo.Uid); err == nil { p := &pb.XxlPlayer{ Uinfo: comm.GetUserBaseInfo(user), Maxconsumeexp: list.Maxconsumeexp, Consumeexp: list.Consumeexp, Maxsocre: list.Maxsocre, } pl = append(pl, p) } } else { if conf, err := this.module.configure.GetGameConsumeintegral(winner.Consumeexp); err == nil { for _, v := range conf.Rewards { if v.A == "attr" && v.T == "consumeexp" { winScore = v.N break } } } } if lostPlayer.Userinfo.Uid != "999" { if conf, err := this.module.configure.GetGameConsumeHero(lostPlayer.Cardid); err == nil { update := map[string]interface{}{} if list, err := this.module.model.getEntertainmList(lostPlayer.Userinfo.Uid); err == nil { if list.Liansheng != 0 { list.Liansheng = 0 // 修改连胜 update["liansheng"] = list.Liansheng } if conf.Type != 1 { //卡片类型不为1 if list.Card[lostPlayer.Cardid] >= 1 { //删除卡片 var star int32 for _, v := range this.module.ModuleHero.GetHeroList(lostPlayer.Userinfo.Uid) { if v.HeroID == lostPlayer.Cardid { star = v.Star break } } if c, err := this.module.configure.GetGameConsumeHero(lostPlayer.Cardid); err == nil { if len(c.Lost) == 0 { // 容错处理 bDestruction = false } else { if star >= int32(len(c.Lost)) { star = c.Lost[len(c.Lost)-1] } else { star = c.Lost[star] } } // 概率验证 n, _ := rand.Int(rand.Reader, big.NewInt(1000)) if star > int32(n.Int64()) { bDestruction = true } } if bDestruction { list.Card[lostPlayer.Cardid] -= 1 update["card"] = list.Card } } } if conf, err := this.module.configure.GetGameConsumeintegral(list.Consumeexp); err == nil { // 战败扣除积分 for _, v := range conf.Deductrewards { if v.A == "attr" && v.T == "consumeexp" { lostScore = v.N list.Consumeexp -= v.N if list.Consumeexp <= 0 { list.Consumeexp = 0 } lostPlayer.Consumeexp = list.Consumeexp update["consumeexp"] = list.Consumeexp } } } if list.Maxsocre < winner.Score { // 单局最大积分 list.Maxsocre = winner.Score update["maxsocre"] = list.Maxsocre } if len(update) > 0 { this.module.model.modifyEntertainmList(lostPlayer.Userinfo.Uid, update) } if user, err := this.module.ModuleUser.GetUser(winner.Userinfo.Uid); err == nil { p := &pb.XxlPlayer{ Uinfo: comm.GetUserBaseInfo(user), Maxconsumeexp: list.Maxconsumeexp, Consumeexp: list.Consumeexp, Maxsocre: list.Maxsocre, } pl = append(pl, p) } } } } else { if conf, err := this.module.configure.GetGameConsumeintegral(winner.Consumeexp); err == nil { for _, v := range conf.Deductrewards { if v.A == "attr" && v.T == "consumeexp" { lostScore = v.N break } } } bDestruction = true } if this.RoomType != 1 { //好友对战无需记录对战记录 go func() { // 更新排行榜数据 this.module.modelRank.updateXxlRank(pl...) // 写记录 recode1 := &pb.DBXxlRecord{ Id: primitive.NewObjectID().Hex(), P1: this.player1.Userinfo.Uid, P2: this.player2.Userinfo.Uid, Uinfo1: this.player1.Userinfo, Uinfo2: this.player2.Userinfo, P1Score: this.player1.Score, P2Score: this.player2.Score, Win: winner.Userinfo.Uid, Winscore: winScore, Lostscore: lostScore, P1Card: this.player1.Cardid, P2Cards: this.player2.Cardid, P1Totlascore: this.player1.Consumeexp, P2Totlascore: this.player2.Consumeexp, Createtime: configure.Now().Unix(), } this.module.modelRecode.updateXxlRecord(recode1) }() } // 修改房间状态 this.Status = 2 this.module.SendMsgSyncToSession(string(this.module.GetType()), "gameover", &pb.EntertainGameOverPush{ User1: this.player1, User2: this.player2, Mpadata: &pb.MapData{Data: this.chessboard.Plat}, Power: "", Round: this.round, Win: winner.Userinfo.Uid, Reward: atno, Box: box, BDestruction: bDestruction, }, this.szSession...) this.ModifyUserRoomInfoData() if this.closeRoomTimer != nil { // 游戏结束 清理定时器 timewheel.Remove(this.closeRoomTimer) this.closeRoomTimer = nil } this.curPower = "" return } // 加入房间 func (this *Room) JoinRoom(module *Entertainment, p *pb.PlayerData) (room *Room, err error) { // 该房间是个空的 if this.player1 == nil { this.player1 = p this.module = module this.chessboard = new(MapData) this.Playtype = this.RandomPlayType() this.chessboard.InitMap(module, this.Playtype) // 初始化棋盘 if s1, ok := this.module.GetUserSession(p.Userinfo.Uid); !ok { this.module.PutUserSession(s1) } else { this.szSession = append(this.szSession, s1.Clone()) } this.Id = p.Userinfo.Uid // 房主ID 作为房间id this.RoomType = 1 this.MaxRound = this.module.ModuleTools.GetGlobalConf().ConsumeRounds room = this } else if this.player2 == nil { //异常处理 if this.player1.Userinfo.Uid == p.Userinfo.Uid { err = errors.New("重复加入") } this.player2 = p // 玩家2 赋值 if s1, ok := this.module.GetUserSession(p.Userinfo.Uid); !ok { this.module.PutUserSession(s1) } else { this.szSession = append(this.szSession, s1.Clone()) } // 推送消息 if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "joincreateroom", &pb.EntertainJoinCreateRoomPush{ Roomid: this.Id, User1: this.player1, User2: this.player2, }, this.szSession...); err != nil { this.module.Errorln(err) } } else { // 房间满了 加不进来 err = errors.New("房间已满") return } return } // 修改玩家的房间信息 func (this *Room) ModifyUserRoomInfoData() { var ( roomid string path string ) if this.Status == 1 { roomid = this.Id path = fmt.Sprintf("%s/%s", this.module.service.GetType(), this.module.service.GetId()) } else { event.TriggerEvent(comm.EventCloseRoom, this.Id) // 释放房间 } // 修改房间记录信息 if this.player1 != nil && this.player1.Userinfo != nil { this.module.model.modifyEntertainmList(this.player1.Userinfo.Uid, map[string]interface{}{ "roomid": roomid, "servicePath": path, }) } if this.RoomType != 2 && this.player2 != nil && this.player2.Userinfo != nil { this.module.model.modifyEntertainmList(this.player2.Userinfo.Uid, map[string]interface{}{ "roomid": roomid, "servicePath": path, }) } return } // 自动操作 func (this *Room) AutoOperator(uid string) { var ( curScore int32 szMap []*pb.MapData bAddPs bool oid1 int32 oid2 int32 p *pb.PlayerData ) if uid == this.player1.Userinfo.Uid { p = this.player1 } else if uid == this.player2.Userinfo.Uid { p = this.player2 } else { this.module.Errorf("cant found user:%s", uid) return } conf, err := this.module.configure.GetGameConsumeHero(p.Cardid) if err != nil { return } // 交换元素 if p.Energy >= conf.Skillload { var color int32 if this.curPower == this.player1.Userinfo.Uid { color = 1 } else { color = 2 } this.UserSkillUp(color, 0) if this.RoomType == 2 && this.curPower == p.Userinfo.Uid { this.AutoOperator(this.curPower) } return } szMap, oid1, oid2, bAddPs = this.chessboard.AiSwapGirde() p.Ps-- if bAddPs { p.Ps++ if p.Ps > MaxPs { p.Ps = MaxPs } } if p.Ps <= 0 { // 权限给下一个人 this.ChangePower() this.round++ } // 校验下次是不是消除 if !this.chessboard.CheckAndRefreshPlat() { this.chessboard.RedsetPlatData() szMap = append(szMap, &pb.MapData{ Data: this.chessboard.GetPalatData(), ChangeType: 1, }) } for _, v := range szMap { curScore += v.CurSocre p.Score += v.CurSocre v.CurSocre = p.Score p.Energy += v.CurEnergy v.CurEnergy = p.Energy } // 广播消息 if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{ Mpadata: szMap, Power: this.NexPower, Curpower: this.curPower, Score: curScore, Round: this.round, User1: this.player1, User2: this.player2, Itype: "swap", Curid: oid1, Targetid: oid2, }, this.szSession...); err != nil { this.module.Errorln(err) } this.curPower = this.NexPower if this.round > this.MaxRound { // 游戏结束 if this.player1.Score == this.player2.Score { this.MaxRound += 1 // 增加一回合 } else { this.GameOver(nil) } return } if this.RoomType == 2 && this.curPower == p.Userinfo.Uid { this.AutoOperator(this.curPower) } } // 玩家释放技能 func (this *Room) UserSkillUp(color int32, curid int32) (errdata *pb.ErrorData) { var ( curScore int32 // 该次操作的得分 oid1 int32 // 唯一id oid2 int32 ) var szMap []*pb.MapData // 能量校验 if color == 1 { // 玩家1 放技能 conf, err := this.module.configure.GetGameConsumeHero(this.player1.Cardid) if err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoHeroSkill, Title: pb.ErrorCode_EntertainNoHeroSkill.ToString(), } return } if this.player1.Energy >= conf.Skillload { this.player1.Energy = 0 // 清零 if _, m := this.chessboard.SkillUp(curid, color, conf.Skilleffect, conf.Skillvalue, true); len(m) > 0 { szMap = append(szMap, m...) } else { szMap = append(szMap, &pb.MapData{ Data: this.chessboard.GetPalatData(), }) } for _, v := range szMap { curScore += v.CurSocre this.player1.Score += v.CurSocre v.CurSocre = this.player1.Score } } else { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoEnergy, Title: pb.ErrorCode_EntertainNoEnergy.ToString(), } return } this.NexPower = this.curPower } else { conf, err := this.module.configure.GetGameConsumeHero(this.player2.Cardid) if err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoHeroSkill, Title: pb.ErrorCode_EntertainNoHeroSkill.ToString(), } return } if this.player2.Energy >= conf.Skillload { this.player2.Energy = 0 // 清零 if _, m := this.chessboard.SkillUp(curid, color, conf.Skilleffect, conf.Skillvalue, true); len(m) > 0 { szMap = append(szMap, m...) } else { szMap = append(szMap, &pb.MapData{ Data: this.chessboard.GetPalatData(), }) } for _, v := range szMap { curScore += v.CurSocre this.player2.Score += v.CurSocre v.CurSocre = this.player2.Score } } else { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoEnergy, Title: pb.ErrorCode_EntertainNoEnergy.ToString(), } return } this.NexPower = this.curPower } if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{ Mpadata: szMap, Power: this.NexPower, Curpower: this.curPower, Score: curScore, Round: this.round, User1: this.player1, User2: this.player2, Itype: "cardskill", Curid: oid1, Targetid: oid2, }, this.szSession...); err != nil { this.module.Errorln(err) } return } // 交换玩家权限 func (this *Room) ChangePower() { if this.curPower == this.player1.Userinfo.Uid { this.NexPower = this.player2.Userinfo.Uid this.player2.Ps = MaxPs this.player1.Ps = 0 } if this.curPower == this.player2.Userinfo.Uid { this.NexPower = this.player1.Userinfo.Uid this.player1.Ps = MaxPs this.player2.Ps = 0 } } // 玩家释放技能 func (this *Room) UserCardSkill(curPlayer *pb.PlayerData, color int32, skillid string, curid int32) (errdata *pb.ErrorData) { var ( curScore int32 // 该次操作的得分 oid1 int32 // 唯一id oid2 int32 conf *cfg.GamePlayerSkillData err error szMap []*pb.MapData ) if curid >= int32(len(this.chessboard.Plat)) { return } conf, err = this.module.configure.GetGamePlaySkill(skillid) if err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_EntertainNoHeroSkill, Title: pb.ErrorCode_EntertainNoHeroSkill.ToString(), } return } if conf.Skilltouch == 101 { // 技能类型为1 szMap = this.chessboard.HitElem(color, curid) } else if conf.Skilltouch == 102 { this.chessboard.ShuffleElem() szMap = append(szMap, &pb.MapData{ Data: this.chessboard.Plat, }) } else if conf.Skilltouch == 103 { this.chessboard.HitCrossElem(color, curid) // 消除十字 szMap = append(szMap, &pb.MapData{ Data: this.chessboard.Plat, }) } for _, v := range szMap { // curScore += v.CurSocre if color == 1 { this.player1.Score += v.CurSocre v.CurSocre = this.player1.Score this.player1.Energy += v.CurEnergy v.CurEnergy = this.player1.Energy } else { this.player2.Score += v.CurSocre v.CurSocre = this.player2.Score this.player2.Energy += v.CurEnergy v.CurEnergy = this.player2.Energy } v.ChangeType = 1 } this.NexPower = this.curPower if conf.Number == 2 { // 只有2类型扣除 if list, err := this.module.model.getEntertainmList(curPlayer.Userinfo.Uid); err == nil { if _, ok := list.Skill[skillid]; ok { list.Skill[skillid] -= 1 if list.Skill[skillid] < 0 { list.Skill[skillid] = 0 } this.module.model.modifyEntertainmList(curPlayer.Userinfo.Uid, map[string]interface{}{ "skill": list.Skill, }) } } } if err := this.module.SendMsgSyncToSession(string(this.module.GetType()), "operatorrst", &pb.EntertainOperatorRstPush{ Mpadata: szMap, Power: this.NexPower, Curpower: this.curPower, Score: curScore, Round: this.round, User1: this.player1, User2: this.player2, Itype: conf.Key, Curid: oid1, Targetid: oid2, }, this.szSession...); err != nil { this.module.Errorln(err) } return }