mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 15:52:27 +08:00
601 lines
20 KiB
Go
601 lines
20 KiB
Go
package game
|
|
|
|
import (
|
|
"hk4e/gdconf"
|
|
"hk4e/gs/model"
|
|
"hk4e/pkg/logger"
|
|
"hk4e/pkg/random"
|
|
"hk4e/protocol/cmd"
|
|
"hk4e/protocol/proto"
|
|
"math/rand"
|
|
"time"
|
|
)
|
|
|
|
// ControllerType 操控者类型
|
|
type ControllerType uint8
|
|
|
|
const (
|
|
ControllerType_None ControllerType = iota
|
|
ControllerType_Player // 玩家
|
|
ControllerType_AI // AI
|
|
)
|
|
|
|
// GCGCardInfo 游戏对局内卡牌
|
|
type GCGCardInfo struct {
|
|
cardId uint32 // 卡牌Id
|
|
guid uint32 // 唯一Id
|
|
faceType uint32 // 卡面类型
|
|
tagList []uint32 // Tag
|
|
tokenMap map[uint32]uint32 // Token
|
|
skillIdList []uint32 // 技能Id列表
|
|
skillLimitList []uint32 // 技能限制列表
|
|
isShow bool // 是否展示
|
|
}
|
|
|
|
type ControllerLoadState uint8
|
|
|
|
const (
|
|
ControllerLoadState_None ControllerLoadState = iota
|
|
ControllerLoadState_AskDuel
|
|
ControllerLoadState_InitFinish
|
|
)
|
|
|
|
// GCGController 操控者
|
|
type GCGController struct {
|
|
controllerId uint32 // 操控者Id
|
|
cardList []*GCGCardInfo // 卡牌列表
|
|
loadState ControllerLoadState // 加载状态
|
|
allow uint32 // 是否允许操控 0 -> 不允许 1 -> 允许
|
|
selectedCharCard *GCGCardInfo // 选择的角色卡牌
|
|
controllerType ControllerType // 操控者的类型
|
|
player *model.Player // 玩家对象
|
|
ai *GCGAi // AI对象
|
|
}
|
|
|
|
// GetCardByGuid 通过卡牌的Guid获取卡牌
|
|
func (g *GCGController) GetCardByGuid(cardGuid uint32) *GCGCardInfo {
|
|
for _, info := range g.cardList {
|
|
if info.guid == cardGuid {
|
|
return info
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GCGManager 七圣召唤管理器
|
|
type GCGManager struct {
|
|
gameMap map[uint32]*GCGGame // 游戏列表 uint32 -> guid
|
|
gameGuidCounter uint32 // 游戏guid生成计数器
|
|
}
|
|
|
|
func NewGCGManager() *GCGManager {
|
|
gcgManager := new(GCGManager)
|
|
gcgManager.gameMap = make(map[uint32]*GCGGame)
|
|
return gcgManager
|
|
}
|
|
|
|
// CreateGame 创建GCG游戏对局
|
|
func (g *GCGManager) CreateGame(gameId uint32, playerList []*model.Player) *GCGGame {
|
|
g.gameGuidCounter++
|
|
game := &GCGGame{
|
|
guid: g.gameGuidCounter,
|
|
gameId: gameId,
|
|
roundInfo: &GCGRoundInfo{
|
|
roundNum: 1, // 默认以第一回合开始
|
|
firstController: 1, // 1号操控者为先手
|
|
diceSideMap: make(map[uint32][]proto.GCGDiceSideType, 2),
|
|
},
|
|
controllerMap: make(map[uint32]*GCGController, 2),
|
|
msgPackList: make([]*proto.GCGMessagePack, 0, 10),
|
|
historyMsgPackList: make([]*proto.GCGMessagePack, 0, 50),
|
|
historyCardList: make([]*GCGCardInfo, 0, 100),
|
|
}
|
|
// 初始化游戏
|
|
game.InitGame(playerList)
|
|
// 记录游戏
|
|
g.gameMap[game.guid] = game
|
|
return game
|
|
}
|
|
|
|
type GCGGameState uint8
|
|
|
|
const (
|
|
GCGGameState_None GCGGameState = iota
|
|
GCGGameState_Waiting // 等待玩家加载
|
|
GCGGameState_Running // 游戏运行中
|
|
GCGGameState_Stoped // 游戏已结束
|
|
)
|
|
|
|
// 阶段对应的处理函数
|
|
var phaseFuncMap = map[proto.GCGPhaseType]func(game *GCGGame){
|
|
proto.GCGPhaseType_GCG_PHASE_TYPE_START: PhaseStartReady,
|
|
proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE: PhaseSelectChar,
|
|
proto.GCGPhaseType_GCG_PHASE_TYPE_DICE: PhaseRollDice,
|
|
proto.GCGPhaseType_GCG_PHASE_TYPE_PRE_MAIN: PhasePreMain,
|
|
}
|
|
|
|
// PhaseStartReady 阶段开局准备
|
|
func PhaseStartReady(game *GCGGame) {
|
|
// 客户端更新操控者
|
|
game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, game.GCGMsgUpdateController())
|
|
// 分配先手
|
|
game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_PHASE_EXIT, game.GCGMsgClientPerform(proto.GCGClientPerformType_GCG_CLIENT_PERFORM_TYPE_FIRST_HAND, []uint32{game.roundInfo.firstController}))
|
|
// 游戏绘制卡牌阶段 应该
|
|
game.GameChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_DRAW)
|
|
// 游戏选择角色卡牌阶段
|
|
game.GameChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE)
|
|
}
|
|
|
|
// PhaseSelectChar 阶段选择角色卡牌
|
|
func PhaseSelectChar(game *GCGGame) {
|
|
// 该阶段确保每位玩家都选择了角色
|
|
for _, controller := range game.controllerMap {
|
|
if controller.selectedCharCard == nil {
|
|
// 如果有没选择角色卡牌的则不执行后面
|
|
return
|
|
}
|
|
}
|
|
// 回合信息
|
|
game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_SEND_MESSAGE, game.GCGMsgDuelDataChange())
|
|
// 游戏投掷骰子阶段
|
|
game.GameChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_DICE)
|
|
}
|
|
|
|
// PhaseRollDice 阶段投掷骰子
|
|
func PhaseRollDice(game *GCGGame) {
|
|
// 给每位玩家投掷骰子
|
|
for _, controller := range game.controllerMap {
|
|
diceSideList := make([]proto.GCGDiceSideType, 0, 8)
|
|
rand.Seed(time.Now().UnixNano()) // 随机数种子
|
|
// 玩家需要8个骰子
|
|
for i := 0; i < 8; i++ {
|
|
diceSide := proto.GCGDiceSideType(random.GetRandomInt32(1, 8))
|
|
diceSideList = append(diceSideList, diceSide)
|
|
}
|
|
// 存储该回合玩家的骰子
|
|
game.roundInfo.diceSideMap[controller.controllerId] = diceSideList
|
|
game.AddMsgPack(controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_ROLL, game.GCGMsgDiceRoll(controller.controllerId, uint32(len(diceSideList)), diceSideList))
|
|
}
|
|
game.GameChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_REROLL)
|
|
// g.controllerMap[1].allow = 1
|
|
// g.controllerMap[2].allow = 0
|
|
// msgPackInfo := g.CreateMsgPackInfo()
|
|
// msgPackInfo.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, g.GCGMsgPVEIntention(&proto.GCGMsgPVEIntention{CardGuid: g.controllerMap[2].cardList[0].guid, SkillIdList: []uint32{g.controllerMap[2].cardList[0].skillIdList[1]}}, &proto.GCGMsgPVEIntention{CardGuid: g.controllerMap[2].cardList[1].guid, SkillIdList: []uint32{g.controllerMap[2].cardList[1].skillIdList[0]}}))
|
|
// g.BroadcastMsgPackInfo(msgPackInfo, false)
|
|
// msgPackInfo1 := g.CreateMsgPackInfo()
|
|
// msgPackInfo1.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, g.GCGMsgUpdateController())
|
|
// msgPackInfo1.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_SEND_MESSAGE, g.GCGMsgPhaseContinue())
|
|
// g.BroadcastMsgPackInfo(msgPackInfo1, false)
|
|
}
|
|
|
|
// PhasePreMain 阶段战斗开始
|
|
func PhasePreMain(game *GCGGame) {
|
|
game.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_TRIGGER_SKILL, game.GCGMsgUseSkill(195, 33024), game.GCGMsgUseSkillEnd(195, 33024))
|
|
}
|
|
|
|
// GCGRoundInfo 游戏对局回合信息
|
|
type GCGRoundInfo struct {
|
|
roundNum uint32 // 游戏当前回合数
|
|
phaseType proto.GCGPhaseType // 现在所处的阶段类型
|
|
firstController uint32 // 当前回合先手的操控者
|
|
diceSideMap map[uint32][]proto.GCGDiceSideType // 操控者骰子列表 uint32 -> controllerId
|
|
}
|
|
|
|
// GCGGame 游戏对局
|
|
type GCGGame struct {
|
|
guid uint32 // 唯一Id
|
|
gameId uint32 // 游戏Id
|
|
gameState GCGGameState // 游戏运行状态
|
|
gameTick uint32 // 游戏tick
|
|
serverSeqCounter uint32 // 请求序列生成计数器
|
|
controllerIdCounter uint32 // 操控者Id生成器
|
|
cardGuidCounter uint32 // 卡牌guid生成计数器
|
|
roundInfo *GCGRoundInfo // 游戏回合信息
|
|
controllerMap map[uint32]*GCGController // 操控者列表 uint32 -> controllerId
|
|
msgPackList []*proto.GCGMessagePack // 消息包待发送区
|
|
historyMsgPackList []*proto.GCGMessagePack // 历史消息包列表
|
|
historyCardList []*GCGCardInfo // 历史卡牌列表
|
|
}
|
|
|
|
// AddPlayer GCG游戏添加玩家
|
|
func (g *GCGGame) AddPlayer(player *model.Player) {
|
|
// 创建操控者
|
|
g.controllerIdCounter++
|
|
controller := &GCGController{
|
|
controllerId: g.controllerIdCounter,
|
|
cardList: make([]*GCGCardInfo, 0, 50),
|
|
loadState: ControllerLoadState_None,
|
|
controllerType: ControllerType_Player,
|
|
player: player,
|
|
}
|
|
// 生成卡牌信息
|
|
g.GiveCharCard(controller, 1301)
|
|
g.GiveCharCard(controller, 1103)
|
|
// 记录操控者
|
|
g.controllerMap[g.controllerIdCounter] = controller
|
|
player.GCGCurGameGuid = g.guid
|
|
}
|
|
|
|
// AddAI GCG游戏添加AI
|
|
func (g *GCGGame) AddAI() {
|
|
// 创建操控者
|
|
g.controllerIdCounter++
|
|
controller := &GCGController{
|
|
controllerId: g.controllerIdCounter,
|
|
cardList: make([]*GCGCardInfo, 0, 50),
|
|
loadState: ControllerLoadState_InitFinish,
|
|
controllerType: ControllerType_AI,
|
|
ai: &GCGAi{
|
|
game: g,
|
|
controllerId: g.controllerIdCounter,
|
|
},
|
|
}
|
|
// 生成卡牌信息
|
|
g.GiveCharCard(controller, 3001)
|
|
g.GiveCharCard(controller, 3302)
|
|
// 记录操控者
|
|
g.controllerMap[g.controllerIdCounter] = controller
|
|
}
|
|
|
|
// GameChangePhase 游戏更改阶段
|
|
func (g *GCGGame) GameChangePhase(phase proto.GCGPhaseType) {
|
|
beforePhase := g.roundInfo.phaseType
|
|
// 修改游戏的阶段
|
|
g.roundInfo.phaseType = phase
|
|
switch phase {
|
|
case proto.GCGPhaseType_GCG_PHASE_TYPE_ON_STAGE, proto.GCGPhaseType_GCG_PHASE_TYPE_DICE:
|
|
// 该阶段允许所有玩家行动
|
|
for _, controller := range g.controllerMap {
|
|
controller.allow = 1
|
|
}
|
|
case proto.GCGPhaseType_GCG_PHASE_TYPE_PRE_MAIN:
|
|
// 该阶段不允许所有玩家行动
|
|
for _, controller := range g.controllerMap {
|
|
controller.allow = 0
|
|
}
|
|
}
|
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NEXT_PHASE, g.GCGMsgPhaseChange(beforePhase, phase))
|
|
}
|
|
|
|
// GiveCharCard 给予操控者角色卡牌
|
|
func (g *GCGGame) GiveCharCard(controller *GCGController, charId uint32) {
|
|
// 读取角色卡牌配置表
|
|
gcgCharConfig, ok := gdconf.CONF.GCGCharDataMap[int32(charId)]
|
|
if !ok {
|
|
logger.Error("gcg char config error, charId: %v", charId)
|
|
return
|
|
}
|
|
// 生成卡牌信息
|
|
g.cardGuidCounter++
|
|
controller.cardList = append(controller.cardList, &GCGCardInfo{
|
|
cardId: charId,
|
|
guid: g.cardGuidCounter,
|
|
faceType: 0, // 1为金卡
|
|
tagList: gcgCharConfig.TagList,
|
|
tokenMap: map[uint32]uint32{
|
|
1: uint32(gcgCharConfig.HPBase), // 血量
|
|
2: uint32(gcgCharConfig.HPBase), // 最大血量(不确定)
|
|
4: 0, // 充能
|
|
5: uint32(gcgCharConfig.MaxElemVal), // 充能条
|
|
},
|
|
skillIdList: gcgCharConfig.SkillList,
|
|
skillLimitList: []uint32{},
|
|
isShow: true,
|
|
})
|
|
}
|
|
|
|
// ControllerSelectChar 操控者选择角色卡牌
|
|
func (g *GCGGame) ControllerSelectChar(controller *GCGController, cardInfo *GCGCardInfo, costDiceIndexList []uint32) {
|
|
// 判断选择角色卡牌消耗的点数是否正确
|
|
if controller.selectedCharCard != nil && len(costDiceIndexList) == 0 {
|
|
// 首次选择角色牌不消耗点数
|
|
return
|
|
}
|
|
// TODO 消耗骰子点数
|
|
// 设置角色卡牌
|
|
controller.selectedCharCard = cardInfo
|
|
// 设置操控者禁止操作
|
|
controller.allow = 0
|
|
// 广播选择的角色卡牌消息包
|
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, g.GCGMsgUpdateController())
|
|
g.AddMsgPack(controller.controllerId, proto.GCGActionType_GCG_ACTION_TYPE_SELECT_ONSTAGE, g.GCGMsgSelectOnStage(controller.controllerId, cardInfo.guid, proto.GCGReason_GCG_REASON_DEFAULT))
|
|
}
|
|
|
|
// onTick 游戏的Tick
|
|
func (g *GCGGame) onTick() {
|
|
// 判断游戏是否运行中
|
|
if g.gameState != GCGGameState_Running {
|
|
return
|
|
}
|
|
// 每10s触发
|
|
if g.gameTick%10 == 0 {
|
|
// GCG游戏心跳包
|
|
for _, controller := range g.controllerMap {
|
|
// 跳过AI
|
|
if controller.player == nil {
|
|
continue
|
|
}
|
|
gcgHeartBeatNotify := &proto.GCGHeartBeatNotify{
|
|
ServerSeq: g.serverSeqCounter,
|
|
}
|
|
GAME_MANAGER.SendMsg(cmd.GCGHeartBeatNotify, controller.player.PlayerID, controller.player.ClientSeq, gcgHeartBeatNotify)
|
|
}
|
|
}
|
|
// 仅在游戏处于运行状态时执行阶段处理
|
|
if g.gameState == GCGGameState_Running {
|
|
phaseFunc, ok := phaseFuncMap[g.roundInfo.phaseType]
|
|
// 确保该阶段有进行处理的函数
|
|
if ok {
|
|
phaseFunc(g) // 进行该阶段的处理
|
|
// 发送阶段处理后的消息包
|
|
g.SendAllMsgPack(false)
|
|
}
|
|
}
|
|
g.gameTick++
|
|
}
|
|
|
|
// InitGame 初始化GCG游戏
|
|
func (g *GCGGame) InitGame(playerList []*model.Player) {
|
|
// 初始化玩家
|
|
for _, player := range playerList {
|
|
g.AddPlayer(player)
|
|
}
|
|
// 添加AI
|
|
g.AddAI()
|
|
|
|
// // 先手允许操作
|
|
// controller, ok := g.controllerMap[g.roundInfo.firstController]
|
|
// if !ok {
|
|
// logger.Error("controller is nil, controllerId: %v", g.roundInfo.firstController)
|
|
// return
|
|
// }
|
|
// controller.allow = 1
|
|
|
|
// TODO 验证玩家人数是否符合
|
|
// 预开始游戏
|
|
g.GameChangePhase(proto.GCGPhaseType_GCG_PHASE_TYPE_START)
|
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_NONE, g.GCGMsgUpdateController())
|
|
g.AddMsgPack(0, proto.GCGActionType_GCG_ACTION_TYPE_SEND_MESSAGE, g.GCGMsgPhaseContinue())
|
|
g.SendAllMsgPack(true)
|
|
|
|
// 游戏状态更改为等待玩家加载
|
|
g.gameState = GCGGameState_Waiting
|
|
}
|
|
|
|
// StartGame 开始GCG游戏
|
|
func (g *GCGGame) StartGame() {
|
|
// 游戏开始设置所有玩家不允许操作
|
|
// for _, c := range g.controllerMap {
|
|
// c.allow = 0
|
|
// }
|
|
|
|
// 游戏状态更改为游戏运行中
|
|
g.gameState = GCGGameState_Running
|
|
}
|
|
|
|
// CheckAllInitFinish 检查所有玩家是否加载完成
|
|
func (g *GCGGame) CheckAllInitFinish() {
|
|
// 判断游戏是否已开始
|
|
if g.gameState == GCGGameState_Running {
|
|
logger.Error("gcg game is running")
|
|
return
|
|
}
|
|
// 检查所有玩家是否加载完成
|
|
for _, controller := range g.controllerMap {
|
|
if controller.loadState != ControllerLoadState_InitFinish {
|
|
return
|
|
}
|
|
}
|
|
// TODO 可能会玩家中途退了 超时结束游戏
|
|
// 正式开始游戏
|
|
g.StartGame()
|
|
}
|
|
|
|
// AddMsgPack 添加GCG消息包至待发送区
|
|
func (g *GCGGame) AddMsgPack(controllerId uint32, actionType proto.GCGActionType, msgList ...*proto.GCGMessage) {
|
|
pack := &proto.GCGMessagePack{
|
|
ActionType: actionType,
|
|
MsgList: make([]*proto.GCGMessage, 0, len(msgList)),
|
|
ControllerId: controllerId,
|
|
}
|
|
// 将每个GCG消息添加进消息包中
|
|
for _, message := range msgList {
|
|
pack.MsgList = append(pack.MsgList, message)
|
|
}
|
|
// 将消息包添加进待发送区
|
|
g.msgPackList = append(g.msgPackList, pack)
|
|
}
|
|
|
|
// SendAllMsgPack 发送所有待发送区的消息包
|
|
func (g *GCGGame) SendAllMsgPack(recordOnly bool) {
|
|
// 不发送空的消息包
|
|
if len(g.msgPackList) == 0 {
|
|
return
|
|
}
|
|
// 是否仅记录历史消息包
|
|
if !recordOnly {
|
|
g.serverSeqCounter++
|
|
for _, controller := range g.controllerMap {
|
|
GAME_MANAGER.SendGCGMessagePackNotify(controller, g.serverSeqCounter, g.msgPackList)
|
|
}
|
|
}
|
|
// 记录发送的历史消息包
|
|
for _, pack := range g.msgPackList {
|
|
g.historyMsgPackList = append(g.historyMsgPackList, pack)
|
|
}
|
|
// 清空待发送区消息包
|
|
g.msgPackList = make([]*proto.GCGMessagePack, 0, 10)
|
|
}
|
|
|
|
// GCGMsgPhaseChange GCG消息阶段改变
|
|
func (g *GCGGame) GCGMsgPhaseChange(beforePhase proto.GCGPhaseType, afterPhase proto.GCGPhaseType) *proto.GCGMessage {
|
|
gcgMsgPhaseChange := &proto.GCGMsgPhaseChange{
|
|
BeforePhase: beforePhase,
|
|
AfterPhase: afterPhase,
|
|
AllowControllerMap: make([]*proto.Uint32Pair, 0, len(g.controllerMap)),
|
|
}
|
|
if gcgMsgPhaseChange.AfterPhase != proto.GCGPhaseType_GCG_PHASE_TYPE_DRAW && gcgMsgPhaseChange.AfterPhase != proto.GCGPhaseType_GCG_PHASE_TYPE_PRE_MAIN {
|
|
// 操控者的是否允许操作
|
|
for _, controller := range g.controllerMap {
|
|
pair := &proto.Uint32Pair{
|
|
Key: controller.controllerId,
|
|
Value: controller.allow,
|
|
}
|
|
gcgMsgPhaseChange.AllowControllerMap = append(gcgMsgPhaseChange.AllowControllerMap, pair)
|
|
}
|
|
}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_PhaseChange{
|
|
PhaseChange: gcgMsgPhaseChange,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GCGMsgPhaseContinue GCG消息阶段跳过
|
|
func (g *GCGGame) GCGMsgPhaseContinue() *proto.GCGMessage {
|
|
gcgMsgPhaseContinue := &proto.GCGMsgPhaseContinue{}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_PhaseContinue{
|
|
PhaseContinue: gcgMsgPhaseContinue,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GCGMsgUpdateController GCG消息更新操控者
|
|
func (g *GCGGame) GCGMsgUpdateController() *proto.GCGMessage {
|
|
gcgMsgUpdateController := &proto.GCGMsgUpdateController{
|
|
AllowControllerMap: make([]*proto.Uint32Pair, 0, len(g.controllerMap)),
|
|
}
|
|
// 操控者的是否允许操作
|
|
for _, controller := range g.controllerMap {
|
|
pair := &proto.Uint32Pair{
|
|
Key: controller.controllerId,
|
|
Value: controller.allow,
|
|
}
|
|
gcgMsgUpdateController.AllowControllerMap = append(gcgMsgUpdateController.AllowControllerMap, pair)
|
|
}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_UpdateController{
|
|
UpdateController: gcgMsgUpdateController,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GCGMsgClientPerform GCG消息客户端执行
|
|
func (g *GCGGame) GCGMsgClientPerform(performType proto.GCGClientPerformType, paramList []uint32) *proto.GCGMessage {
|
|
gcgMsgClientPerform := &proto.GCGMsgClientPerform{
|
|
ParamList: paramList,
|
|
PerformType: performType,
|
|
}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_ClientPerform{
|
|
ClientPerform: gcgMsgClientPerform,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GCGMsgSelectOnStage GCG消息切换角色卡牌
|
|
func (g *GCGGame) GCGMsgSelectOnStage(controllerId uint32, cardGuid uint32, reason proto.GCGReason) *proto.GCGMessage {
|
|
gcgMsgClientPerform := &proto.GCGMsgSelectOnStage{
|
|
Reason: reason,
|
|
ControllerId: controllerId,
|
|
CardGuid: cardGuid,
|
|
}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_SelectOnStage{
|
|
SelectOnStage: gcgMsgClientPerform,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GCGMsgPVEIntention GCG消息PVE意向
|
|
func (g *GCGGame) GCGMsgPVEIntention(pveIntentionList ...*proto.GCGMsgPVEIntention) *proto.GCGMessage {
|
|
gcgMsgPVEIntention := &proto.GCGMsgPVEIntentionInfo{
|
|
IntentionMap: make(map[uint32]*proto.GCGMsgPVEIntention),
|
|
}
|
|
for _, intention := range pveIntentionList {
|
|
gcgMsgPVEIntention.IntentionMap[intention.CardGuid] = intention
|
|
}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_PveIntentionInfo{
|
|
PveIntentionInfo: gcgMsgPVEIntention,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GCGMsgDuelDataChange GCG消息切换回合
|
|
func (g *GCGGame) GCGMsgDuelDataChange() *proto.GCGMessage {
|
|
gcgMsgDuelDataChange := &proto.GCGMsgDuelDataChange{
|
|
Round: g.roundInfo.roundNum,
|
|
}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_DuelDataChange{
|
|
DuelDataChange: gcgMsgDuelDataChange,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GCGMsgDiceRoll GCG消息摇骰子
|
|
func (g *GCGGame) GCGMsgDiceRoll(controllerId uint32, diceNum uint32, diceSideList []proto.GCGDiceSideType) *proto.GCGMessage {
|
|
gcgMsgDiceRoll := &proto.GCGMsgDiceRoll{
|
|
ControllerId: controllerId,
|
|
DiceNum: diceNum,
|
|
DiceSideList: diceSideList,
|
|
}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_DiceRoll{
|
|
DiceRoll: gcgMsgDiceRoll,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GCGMsgUseSkill GCG消息使用技能
|
|
func (g *GCGGame) GCGMsgUseSkill(cardGuid uint32, skillId uint32) *proto.GCGMessage {
|
|
gcgMsgMsgUseSkill := &proto.GCGMsgUseSkill{
|
|
SkillId: skillId,
|
|
CardGuid: cardGuid,
|
|
}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_UseSkill{
|
|
UseSkill: gcgMsgMsgUseSkill,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GCGMsgUseSkillEnd GCG消息使用技能结束
|
|
func (g *GCGGame) GCGMsgUseSkillEnd(cardGuid uint32, skillId uint32) *proto.GCGMessage {
|
|
gcgMsgMsgUseSkillEnd := &proto.GCGMsgUseSkillEnd{
|
|
SkillId: skillId,
|
|
CardGuid: cardGuid,
|
|
}
|
|
gcgMessage := &proto.GCGMessage{
|
|
Message: &proto.GCGMessage_UseSkillEnd{
|
|
UseSkillEnd: gcgMsgMsgUseSkillEnd,
|
|
},
|
|
}
|
|
return gcgMessage
|
|
}
|
|
|
|
// GetControllerByUserId 通过玩家Id获取GCGController对象
|
|
func (g *GCGGame) GetControllerByUserId(userId uint32) *GCGController {
|
|
for _, controller := range g.controllerMap {
|
|
// 为nil说明该操控者不是玩家
|
|
if controller.player == nil {
|
|
continue
|
|
}
|
|
if controller.player.PlayerID == userId {
|
|
return controller
|
|
}
|
|
}
|
|
return nil
|
|
}
|