go_dreamfactory/modules/entertainment/room.go

1087 lines
30 KiB
Go

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 {
pro := this.LianShengAdd(list.Liansheng) // 连胜加成
for _, v := range conf.Rewards {
if v.A == "attr" && v.T == "consumeexp" {
list.Consumeexp += int32(v.N*pro) / 1000
winScore = int32(v.N*pro) / 1000
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) LianShengAdd(liansheng int32) (permillage int32) {
var (
result []*cfg.GameConsumeTxtData
err error
)
if result, err = this.module.configure.getLianShengReward(); err == nil {
for pos, v := range result {
if len(result) > pos+1 {
if result[pos+1].Winningstreak >= liansheng { // 下一等级小于当前值
permillage = result[pos].Rewarddata
return
}
} else {
permillage = v.Rewarddata
}
}
}
if permillage == 0 {
permillage = 1
}
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
bAddps bool
)
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 {
szMap, bAddps = this.chessboard.ShuffleElem()
} 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
if bAddps {
this.player1.Ps++
if this.player1.Ps > 2 {
this.player1.Ps = 2
}
}
} else {
this.player2.Score += v.CurSocre
v.CurSocre = this.player2.Score
this.player2.Energy += v.CurEnergy
v.CurEnergy = this.player2.Energy
if bAddps {
this.player2.Ps++
if this.player2.Ps > 2 {
this.player2.Ps = 2
}
}
}
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
}